サーバには一般に、 /
, /boot
, /var
, /tmp
, /home
などの個別のファイルシステムが設定されています。それぞれ別々のパーティション内に配置することで、 /var
や /tmp
のディレクトリ内にあるログや一時ファイルなどが容量を大きく浪費して、ルートパーティションに書き込めなくなってしまうような事態を防ぐことができます。場合によっては、サードパーティ製のアプリケーションを配置する /opt
ディレクトリを別のパーティションに配置する必要がある場合もあります。
このようにファイルシステムを分けることにより、もう 1 つの利点が生まれます。別々のマウントとして処理されることから、それぞれ別々のマウントオプションを設定できる、という点です。たとえば下記のようなマウントオプションがあります:
noexec
: プログラムの実行を禁止します。
nodev
: キャラクタデバイスやブロックデバイスを使用できないようにします。
nosuid
: set-user-ID
や set-group-ID
の効果を無効化します。
ro
: ファイルシステムを 読み込み専用
にします。
それぞれのオプションの設定は注意して行ってください。アプリケーションによっては動作しなくなってしまうことがあるほか、保守を受けられなくなってしまう場合もあります。マウントオプションは、適切な設定を行うことで、セキュリティに関わる攻撃を防いだり、設定の誤りによる予期しない動作を防いだりすることができます。たとえば /tmp
に保存されるファイルには set-user-ID
フラグの付いたプログラムを配置する必要は無いはずです。
また、 システムの動作に合わせてパーティションを設計することも重要です。たとえば /var/log
ディレクトリ内にログが大量に出力されるような環境の場合、 /
パーティションと /var
パーティションを別々にしたほうがよいことになります。もう 1 つ知っておくべきこととしては、一般的な PC システムではプライマリパーティションが最大 4 つまでに制限されるため、 LVM やその他のボリューム管理の仕組みを活用する必要があるかもしれません。
openSUSE Leap ではそのほかに、パーティションや単一のディレクトリを暗号化することができほか、ファイルをコンテナとして利用して暗号化することもできます。詳しくは 第12章 「パーティションやファイルの暗号化」 をお読みください。
特に /etc
ディレクトリ内に存在するファイルがそれに該当しますが、システム内の多数のファイルが読み取り可能な状態になっています。これは言い換えると、特権を持たないユーザでも自由に内容を読むことができる、ということを意味しています。一般的に、これは特に大きな問題とはなりませんが、システムの運用上の都合等の様々な理由で、機密情報を持つファイルを保護しておきたいという要件が存在することがあります。
openSUSE Leap では permissions パッケージで、ファイルのパーミッションを簡単に制御できるようになっています。このパッケージには 3 種類のシステムプロファイルが用意されています:
ユーザにとって扱いやすいグラフィカルユーザシステムを構築するためのプロファイルです。こちらが既定のプロファイルです。
グラフィカルユーザインターフェイスを持たない、サーバシステム向けのプロファイルです。
最大限にセキュリティを確保するためのプロファイルです。 secure
(厳格) プロファイルに加えて、 setuid/setgid のようなフラグやケーパビリティフラグなどの特殊なパーミッションが 全て 削除されます。
パスワードの変更などの簡単な作業を除き、特権を持たないユーザには使い物にならないシステムになってしまうことに注意してください。
そのため、 paranoid
(偏執) プロファイルはそのまま使用するのではなく、独自の許可設定を追加するためのテンプレートとしてのみお使いください。詳しい情報は permissions.paranoid
ファイル内に英語にて記述があります。
独自のファイルアクセス許可を設定したい場合は、 /etc/permissions.local
ファイルを編集するか、もしくは /etc/permissions.d/
ディレクトリ内に新しくファイルを作成してください。
# 追加の設定 /etc/security/access.conf root:root 0400 /etc/sysctl.conf root:root 0400 /root/ root:root 0700
最初の列はファイル名を表しています。ただし、ディレクトリを表したい場合は、必ずスラッシュ (/) で終わらせてください。 2 つめの列には所有者とグループを、 3 つめの列にはモードを指定します。設定ファイルの書式についての詳細は、 man permissions
をお読みください。
あとは /etc/sysconfig/security
ファイル内で、使用したいプロファイルを選択します。 easy
プロファイルと /etc/permissions.local
ファイルの内容を適用したい場合は、下記のように指定します:
PERMISSION_SECURITY="easy local"
設定を適用するには、 chkstat --system --set
コマンドを実行します。
パーミッションは zypper
によるパッケージ更新でも適用されます。そのため、 cron
もしくは systemd
タイマーを利用して、定期的に chkstat
を実行するようにしてください。
システムが提供するプロファイルは細部に至るまでよくテストされて構築されていますが、独自のファイルパーミッションを指定してしまうと、アプリケーションによっては正しく動作しなくなってしまう場合があります。 SUSE ではそのような構成でご利用の場合、サポートを提供できませんのであらかじめご了承ください。
また、 chkstat
で独自のファイルパーミッションを適用するにあたっては、事前に必ずテストを実施して、普段の作業が想定通りに動作することを確認しておいてください。
既定では、ユーザのホームディレクトリはシステム内の誰にでもアクセス (読み込み、実行) 可能な状態になります。これは潜在的な情報漏洩につながることから、所有者自身だけがホームディレクトリにアクセスできるようにする必要があります。
下記のようなコマンドを入力して実行すると、 /home
ディレクトリ以下にある既存のホームディレクトリに対して、 700
というパーミッション (所有者のみがアクセスできる) を設定します:
>
sudo
chmod 755 /home>
sudo
bash -c 'for dir in /home/*; do \ echo "Changing permissions of directory $dir"; chmod 700 "$dir"; done'
なお、このパーミッションを新しく作成するホームディレクトリに対して適用したい場合は、 /etc/login.defs
ファイルを編集して、 HOME_MODE
を 700
に設定してください。
# HOME_MODE is used by useradd(8) and newusers(8) to set the mode for new # home directories. # If HOME_MODE is not set, the value of UMASK is used to create the mode. HOME_MODE 0700
HOME_MODE
を指定しない場合、パーミッションは既定の umask 値から自動的に計算されます。なお、 HOME_MODE
は設定するパーミッションを指定するものであって、 umask のように与えたくないフラグを指定するものではないことに注意してください。 umask に関する詳細は、 11.4項 「既定の umask」 をお読みください。
この設定変更をテストするには、 useradd -m testuser
のようにして新しいユーザを作成してみてください。あとは ls -l /home
を実行して、作成されたディレクトリのパーミッションを確認してください。テストが終わったらユーザは削除してかまいません。
ここまでの手順を実行することで、一般ユーザは他のユーザのホームディレクトリにアクセスできなくなります。ユーザやソフトウエアによっては、これが予期しない結果となる可能性もあります。
そのため、これを本番環境で適用する場合は、あらかじめテストをしておく必要があるほか、ユーザに対しても変更を周知しておく必要があります。
umask
(ユーザがファイルを作成する際のモードマスク値) コマンドはシェルの内蔵コマンドで、新しく作成するファイルやディレクトリに対して、そのパーミッションを制御するためのものです。この値はシステムコールを利用することで変更することができますが、多数のプログラムやユーティリティでは umask
コマンドを呼び出しています。
既定では、 umask
の値は 022
に設定されています。この umask の値は 「許可を与えたくない」 ビットを指定する仕組みです。
現在の umask 値を表示するには、 umask
コマンドに何もパラメータを付けずに実行します:
>
umask
022
既定の umask 値はほとんどのユーザにとって十分な値になっています。たとえば下記のようになります。
>
touch a>
mkdir b>
ls -on 合計 16 -rw-r--r--. 1 17086 0 11月29 15:05 a drwxr-xr-x. 2 17086 4096 11月29 15:05 b
必要であれば umask 値を変更することもできます。
>
umask 111>
touch c>
mkdir d>
ls -on 合計 16 -rw-rw-rw-. 1 17086 0 11月29 15:05 c drw-rw-rw-. 2 17086 4096 11月29 15:05 d
不用意なデータ漏洩を防ぐため、さらに厳しい制限を行いたい場合は、 037
のような値を設定することもできます。
>
umask 037>
touch e>
mkdir f>
ls -on 合計 16 -rw-r-----. 1 17086 0 11月29 15:06 e drwxr-----. 2 17086 4096 11月29 15:06 f
最大限の保護を設定したい場合は、 077
という umask 値を設定してください。これにより、新しく作成されたファイルやディレクトリは、自分自身しかアクセスできなくなり、グループ内に対してもその他のユーザに対しても、全てのアクセスが禁止されるようになります。
ただし、このような設定を行うことで、他のユーザに不便を強いる可能性があったり、ソフトウエアが予期しない動作をしてしまったりすることがあるかもしれません。また、サポートチームに余計な負担をかけてしまう可能性にも注意してください。
全てのユーザに対する umask 値を調整したい場合は、 /etc/login.defs
ファイル内にある UMASK
の値を変更してください。
# Default initial "umask" value used by login(1) on non-PAM enabled systems. # Default "umask" value for pam_umask(8) on PAM enabled systems. # UMASK is also used by useradd(8) and newusers(8) to set the mode for new # home directories. # 022 is the default value, but 027, or even 077, could be considered # for increased privacy. There is no One True Answer here: each sysadmin # must make up their mind. UMASK 022
個別のユーザに対して設定したい場合は、 /etc/passwd
ファイル内の 'gecos' フィールドに umask 値を設定します。たとえば下記のようになります:
tux:x:1000:100:Tux Linux,UMASK=022:/home/tux:/bin/bash
上記の設定は yast users
でも行うことができます。ユーザの › 内に、 UMASK=022
のような形式で設定してください。
なお、 /etc/login.defs
や /etc/passwd
に設定した値は、 pam_umask.so
という PAM モジュールが読み込んで適用します。その他の設定オプションについての詳細は、 man pam_umask
で表示されるマニュアルページをお読みください。
また、設定値を反映させるためには、ユーザがログインし直す必要もあります。ログインし直したあと、 umask
コマンドで正しく設定されたかどうかを確認してください。
SUID (set user ID) や SGID (set group ID) のビットを実行可能なファイルに設定すると、そのプログラムを起動したユーザではなく、その実行可能なファイルを所有しているユーザもしくはグループとしてプログラムを起動することができます。たとえば SUID ビットが設定され、 root
が所有するプログラムがあった場合、誰がそのプログラムを起動しても、プログラムは root
の UID で実行されることになります。よくある例は passwd
コマンドで、 root
が所有する /etc/shadow
ファイルのパスワード欄に書き込みを行うために設定されています。
SUID/SGID のビットを誤って他のプログラムに設定したりしてしまうと、それはセキュリティホールとなってしまいます。そのため、システム全体を調べて、予期せず SUID/SGID のビットが設定されているものが無いかどうかを調べる必要があります。具体的には、下記のようなコマンドを入力して実行します:
#
find /bin /boot /etc /home /lib /lib64 /opt /root /sbin \
/srv /tmp /usr /var -type f -perm '/6000' -ls
ファイルシステムの構造によっては、上記にさらにディレクトリを追加する必要があるかもしれません。
SUSE では、どうしても必要なプログラムにのみ SUID/SGID ビットを設定しています。また、コードの開発者に対しても、どうしても必要な理由がある場合を除いて、 SUID/SGID のビットを設定しないように求めています。また、全てのユーザからは実行できないようにすることで、 SUID/SGID ビットの悪影響を防ぐこともできます。もちろんソフトウエア側の設計改善やケーパビリティの使用などで、 SUID/SGID ビットの使用を回避できるほうが望ましいです。
openSUSE Leap ではファイルのケーパビリティ機能に対応し、 root
に与えられる権限の一部のみをプログラムに許可することもできます:
#
getcap -v /usr/bin/ping
/usr/bin/ping = cap_new_raw+eip
上記の例では、 ping
を実行するユーザに対して CAP_NET_RAW
のケーパビリティを許可しています。この場合、たとえ ping
に脆弱性が存在していても、攻撃者は CAP_NET_RAW のケーパビリティのみが許可され、 root
の全権限を得ることはありません。また可能であれば、 SUID ビットとともにファイルのケーパビリティを設定しておくことをお勧めします。ただし、これは root
が所有者の SUID プログラムにのみ当てはまるもので、それ以外の news
, lp
などのシステムユーザが所有するプログラムには当てはまりません。
誰にでも書き込み可能なファイルは、システム内の任意のユーザが書き込めるファイルであることから、セキュリティリスクとなりうるものです。これに加えて、誰にでも書き込めるディレクトリは、誰にでもファイルの作成や削除ができてしまいます。これらのファイルやディレクトリを検索するには、下記のようなコマンドを入力して実行します:
#
find /bin /boot /etc /home /lib /lib64 /opt /root /sbin \
/srv /tmp /usr /var -type f -perm -2 ! -type l -ls
ファイルシステムの構造によっては、上記にさらにディレクトリを追加する必要があるかもしれません。
なお、上記では ! -type l
パラメータを指定していますが、これはシンボリックリンクを読み飛ばすための設定で、シンボリックリンクは通常全てのユーザが書き込めるファイルになっているためです。シンボリックリンクが指し示すファイルやディレクトリへの書き込みは、その示した先のファイルやディレクトリのパーミッションに従って処理されますし、そのファイルやディレクトリは上記のコマンドでチェック対象となるので、特に問題はありません。
また、 /tmp
ディレクトリなどのようにスティッキー (sticky) ビットが設定されたディレクトリに対しては、全てのユーザへの書き込みが許可されていても、そのファイルやディレクトリの所有者のみが削除もしくは名前変更を行うことができます。スティッキービットは、そのファイルやディレクトリを作成したユーザに "ベタベタ貼り付く" (sticky) ことで、他のユーザからの削除や名前変更を防ぐ意味を持ちます。そのため、ディレクトリの用途によっては、スティッキービットが設定されていれば、全てのユーザからの書き込みを許しても問題ない場合があります。
>
ls -ld /tmp
drwxrwxrwt 18 root root 16384 Dec 23 22:20 /tmp
上記の t
表示がスティッキービットを表しています。
どのユーザやグループにも所有されていないファイルは、現時点ではセキュリティ上の問題となることはありません。ですが、このようなファイルは将来的にセキュリティ上の問題となる場合があります。たとえば新しいユーザを作成した際、偶然にもその UID を持つファイル (つまり、以前はどのユーザも所有していなかったファイル) があると、そのファイルに対する所有権を得てしまうことになります。
所有者や所有グループのいないファイルを検索するには、下記のコマンドを入力して実行します:
#
find /bin /boot /etc /home /lib /lib64 /opt /root /sbin /srv /tmp /usr /var -nouser -o -nogroup
ファイルシステムの構造によっては、上記にさらにディレクトリを追加する必要があるかもしれません。
もう 1 つ発生しうる問題としては、パッケージシステム経由でインストールしていないプログラムがある場合、そのプログラムに対しては自動では更新できないという問題があります。このようなファイルを検索するには、下記のようなコマンドを入力して実行します:
>
find /bin /lib /lib64 /usr -path /usr/local -prune -o -type f -a -exec /bin/sh -c "rpm -qf {} &> /dev/null || echo {}" \;
なお、上記のコマンドは権限を持たないユーザ (例: nobody) で実行してください。これは、ファイル名をうまく加工することで、コマンドそのものを実行してしまうことがあり得るためです。通常、これらのディレクトリは root
のみに書き込み権限がありますので、特に問題となることはありませんが、念のため注意してください。
上記のコマンドは、 /bin
, /lib
, /lib64
, /usr
の各ディレクトリ内にある全てのファイル (ただし /usr/local
を除く) を列挙し、パッケージマネージャで管理されていないファイルを出力するものです。これらのファイルはすぐにセキュリティ問題になるとは言い切れませんが、どのファイルが追跡対象外なのかを把握しておき、あらかじめ注意しておくことが重要です。