7.1. ホストセキュリティの強化

7.1.1. システム起動とコア防御の強化

BIOSとブートローダーのセキュリティ

最近のLinuxではブートローダにGRUB2が使われている。
GRUB2の設定(/boot/grub2/grub.cfg)変更は、/etc/default/grubなどのファイル編集後にgrub2-mkconfigコマンドを使用して行う。

GRUB2のセキュリティ強化として、システム起動時にブートパラメータの編集(Eキーを押したとき)にパスワード入力が必要になる設定は以下のように行う。

# /etc/default/grubを編集
vi /etc/default/grub
:
set superuser="superuser1"
password superuser1 xxxxxxxxxxxx
# grub2-mkconfigコマンドで設定を反映
grub2-mkconfig -o /boot/grub2/grub.cfg

Grubの制御

GRUB はパスワード機能を提供し、管理者だけが対話型操作を開始できるようにすべきものといえる。
これはGrubが構成を変更したり、実行時に任意のコマンドを実行したりできる機能があるためユーザレベルの制御としては強すぎるためである。

不要な機能とサービスの無効化

実行中のすべてのプログラムには、セキュリティ上の脅威が存在する可能性があるため、使用されていないサービスを無効にすることは、セキュリティ上の良い設定となる。

サービスの無効化にはsystemctlおよびchkconfigを使用することで可能。 一般的に無効化するサービスには、atd、ava hi-daemon、cups がある。

systemctlとchkconfigの比較は以下の通り。

機能chkconfigsystemctl
サービスの自動起動有効化chkconfig [サービス名] onsystemctl enable [サービス名].servive
サービスの自動起動無効化chkconfig [サービス名] offsystemctl disbale [サービス名].service
サービスの自動起動状態確認chkconfig --list [サービス名]systemctl is-enabled [サービス名].servive
すべてのサービスの自動起動状態確認chkconfig --listsystemctl list-unit-files --type service

内部的にはchkconfigコマンドはsystemctlコマンドに変換されて実行される。

メモリ保護とカーネルパラメータ

ASLR

ASLR (Address Space Layout Randomization)は、攻撃者が悪意のあるコードを実行するためのメモリ上のアドレスを予測することを困難にする防御機構のこと。 プログラムがロードされるたびに、メモリ内の異なる場所にロードされるようにする仕組みといえる。 システムのライブラリ、スタック、ヒープなどのメモリレイアウトをランダムに配置する。

  • 設定: sysctlを通じて有効化・無効化が可能。
    • /proc/sys/kernel/randomize_va_space の値を操作する。

各値毎の動作は以下の通り。

  • 0 … ALSR が無効
  • 1 … ALSR が保守モードで動作
  • 2 … ALSR が完全に機能して動作

EDP/Exec-Shield

DEP (Data Execution Prevention) やExec-Shieldは、データ領域に配置されたコードが実行されることを防ぐメモリ保護機構のこと。
バッファオーバーフロー攻撃などにより、攻撃者がデータ領域に挿入した悪意のあるコードの実行を防ぐことを目的とする。

  • NXビット (No-Execute): ハードウェア(CPU)レベルでデータ実行不可を実現する技術であり、DEPの主要な基盤となる。
  • Exec-Shield: Linuxカーネルのセキュリティ機能の一つで、特に古いカーネルや環境でDEP/NXビットと同様の保護を提供するために利用されていた。
NXビット

NXビットはCPUの機能で保護されたメモリ領域からの実行を防ぐことができるもの

この機能の利用により実行可能なメモリ空間を制限することできる。そのため悪意のあるプログラムによる任意のコードの実行が困難にすることが可能。
NXビットは CPUレベルの機能であるため、CPU 情報を確認して確認する必要がある。

grep -Fw nx /proc/cpuinfo
Exec-Shield

Exec-ShieldはNXビットの機能のない CPU をサポートするように設計された、同じ問題に対するソフトウェア手法のこと。
NXビットと同様に保護されたメモリ領域からの実行を防ぐことができる。

sysctlによるカーネルパラメータの設定

sysctlは実行中のLinuxカーネルのパラメータを表示および動的に設定するために使用されるコマンド。
これにより、セキュリティやネットワークパフォーマンスを調整できる。

sysctl [オプション] [変数]
オプション説明
-aすべてのカーネルパラメータの設定値を表示
-w指定したカーネルパラメータの値を反映
-pカーネルパラメータの設定を行ったファイルを反映
–system``/etc/sysctl.d/*などのファイルのカーネルパラメータの反映
# 設定の全表示
sysctl -a

# カーネルパラメータからの表示
sysctl -n

# 設定の検索
sysctl -ar [検索パターン]

procfs 

# 設定の保存
sysctl -w  <param>=<value>

# 恒久的な設定の記述ファイル
/etc/sysctl.conf

# /etc/sysctl.confからの反映(ファイルから読み込む)
sysctl -p

カーネルパラメータの恒久的な設定

セキュリティ設定を永続化するためには、設定ファイルに記述し、sysctl -pで読み込ませる必要がある。

  1. 設定ファイルの編集:
    • カーネルパラメータの設定は、通常/etc/sysctl.conf または /etc/sysctl.d/ 配下のファイルに記述します。
# 例:SYN Flood攻撃対策としてSYN Cookieを有効化する
vi /etc/sysctl.conf
net.ipv4.tcp_syncookies = 1
  1. 設定の反映:
    • ファイルを編集した後、以下のコマンドでシステムに即座に反映させます。
sysctl -p

カーネルパラメータのチューニング

カーネルパラメータを適切にチューニングすることで、DoS攻撃やバッファオーバーフロー攻撃などに対するセキュリティの向上につながる。

パラメータ設定値目的
net.ipv4.tcp_syncookies1SYN Cookieの有効化。SYN Flood攻撃によるサービス停止を防ぐ。
net.ipv4.conf.all.accept_source_route0ソースルーティングの無効化。攻撃者がネットワーク経路を操作するのを防ぐ。
net.ipv4.icmp_echo_ignore_broadcasts1ブロードキャストpingへの応答を無視。Smurf攻撃を防ぐ。
kernel.exec-shield1Exec-Shieldを有効化し、データ実行防御を強化する。(カーネルによっては非推奨またはASLRに含まれる)
ICMPのセキュリティ設定

ICMPの無効化はカーネルパラメータのnet.ipv4.icmp_echo_ignore_all=1で設定ができる。

sysctl -w net.ipv4.icmp_echo_ignore_all=1

このICMPの無効化はICMP(ping)応答の無効化やDDoSの軽減などホストの稼働状況に関する情報漏洩を防ぐことができる。

なお、ICMPエコーブロードキャストのみ無効化させる場合はnet.ipv4.icmp_echo_ignore_broadcasts=1で可能。

7.1.2. プロセスとリソースの制限

systemdユニットによるプロセスのサンドボックス化

systemdは、サービス定義ファイル内のセキュリティ関連ディレクティブを通じて、プロセス環境に強力な制約を課し、セキュリティのサンドボックス化を容易にする。

システムコールと機能の制限

プロセスの実行を許可するシステムコールやLinux Capabilities(機能)を制限することで、仮にプロセスが侵害された場合でも、攻撃者が実行できる操作を厳しく制限する。

  • SystemCallFilter= … 実行を許可するシステムコールを明示的に指定します(例: ~@aio @io)。すべてのシステムコールを拒否する~@allと組み合わせて、必要なものだけを許可するホワイトリスト形式が強力
  • CapabilityBoundingSet= … プロセスが継承できるLinux Capabilities(権限)のセットを制限します。デフォルトで不要な権限(CAP_SYS_ADMINなど)を削除することで、権限昇格を防ぐ
  • NoNewPrivileges=yes … Setuid/Setgidバイナリの実行による権限昇格を防ぎます。セキュリティを強化する上で常に有効にすべき設定

ファイルシステムおよびデバイスアクセスの隔離

サービスが不要なファイルシステムパスやデバイスにアクセスできないようにすることで、ホストシステム全体への影響を遮断する。

  • ProtectSystem= … /etc、/usr、/boot ディレクトリへの書き込みアクセスを禁止します。full、strict、trueなどの設定値があります。
  • ProtectHome=true … ユーザーのホームディレクトリ(/home、/root)へのアクセスを禁止し、機密データの漏洩を防ぎます。
  • ReadOnlyPaths=/ReadWritePaths= … 特定のパスへの読み取り専用/書き込みアクセスを細かく制御します。
  • PrivateTmp=true … プロセスに対して専用のテンポラリディレクトリ(/tmp, /var/tmp)を割り当てます。サービス固有の一時ファイルのみが見える状態になり、他のサービスの一時ファイルを悪用する攻撃を防ぎます。
  • PrivateDevices=true … プロセスに対して最小限の仮想的な /dev ディレクトリを割り当てます。ホスト側の実際の物理デバイスへのアクセスを遮断し、デバイスへの不正な操作を防ぎます。

ネットワークアクセスの制限

ネットワークサービスではないプロセスに対しては、ネットワーク接続を完全に無効にすることでセキュリティを強化する。

  • PrivateNetwork=true … プロセスに対してネットワークアクセスをできない状態にするために、専用のネットワーク名前空間を割り当てます。これにより、プロセスは外部ネットワークにもローカルホストにも接続できなくなります。
  • IPAddressDeny=anyPrivateNetwork=trueを使用できない場合でも、プロセスが特定のIPアドレス(またはすべて)へのアクセスを拒否できます。

システムリソースの制限

サービスが利用できるCPU時間、メモリ、プロセス数などのリソースに上限を設定することで、DoS攻撃や誤動作によるシステム全体の負荷を防ぐことができる。

  • LimitCPU=/LimitMEMLOCK= … プロセスが消費できるCPU時間や、ロックできるメモリ量など、システムリソースを制限します。
  • MemoryMax= … サービスが使用できるメモリの総量を制限します。
  • TasksMax= … サービスが生成できるプロセス(タスク)の最大数を制限し、フォーク爆弾攻撃を防ぎます。

ユニットファイルへの設定例

これらの設定は、サービスユニットファイル(例: /etc/systemd/system/my-service.service)の[Service]セクションに記述する。

# ----------------------------------------------------
# 1. システムコールと機能の制限
# ----------------------------------------------------
NoNewPrivileges=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
# 全てのシステムコールを拒否し、必要なものだけを許可する (@network-io, @socketはネット関連を許可)
SystemCallFilter=@system-service @network-io @socket

# ----------------------------------------------------
# 2. ファイルシステムおよびデバイスアクセスの隔離
# ----------------------------------------------------
# 専用の/tmpと/var/tmpを割り当てる (重要)
PrivateTmp=true
# ホストの/devディレクトリから隔離する (重要)
PrivateDevices=true
# ホームディレクトリへのアクセスを禁止する
ProtectHome=true
# /etcや/usrへの書き込みを禁止する
ProtectSystem=full

# ----------------------------------------------------
# 3. ネットワークアクセスの制限 (Webサービスでない場合)
# ----------------------------------------------------
# ネットワークに一切アクセスできないようにする
# PrivateNetwork=true

# ----------------------------------------------------
# 4. システムリソースの制限
# ----------------------------------------------------
# 最大メモリ使用量を512MBに制限
MemoryMax=512M
# 最大タスク数を256に制限
TasksMax=256

[Install]
WantedBy=multi-user.target

これらのディレクティブを適切に組み合わせることで、アプリケーションを最小限の権限とリソースで実行させ、セキュリティ上のリスクを大幅に軽減できる。

Linux Capabilitiesによる機能制限

プロセス機能

特定のプロセスの機能を確認するには/procディレクトリ内のステータスファイルを確認する。
cat /proc/self/statusで現在で実行中のプロセスを、capsh --printまたは/proc/<pid>/statusで他のユーザの実行中のプロセスを確認できる。

cat /proc/1234/status | grep Cap
cat /proc/$$/status | grep Cap

上記コマンドで表示される各行は以下内容を意味する。

  • CapInh … 継承された機能
  • CapPrm … 許可される機能
  • CapEff … 有効な能力
  • CapBnd … 境界セット
  • CapAmb … アンビエント機能セット

また、実行中のプロセスの機能を確認するには、getpcapsツールの後にプロセス ID (PID) を続けて使用することでできる。

バイナリ機能

バイナリには、実行中に使用できる機能を含めることができる。
たとえば、cap_net_rawのような機能をping持つバイナリを見つけるのは非常に一般的となる。

getcap /usr/bin/ping
/usr/bin/ping = cap_net_raw+ep

バイナリ検索はgetcap -r / 2>/dev/nullで行える。

capsh による機能の削除

pingのCAP_NET_RAW機能を削除すると、ping ユーティリティは機能しなくなる。

capsh --drop=cap_net_raw --print -- -c "tcpdump"

setcap によるバイナリ機能の削除

バイナリの機能を削除するには以下コマンドで行える。

setcap -r </path/to/binary>

chroot環境での作業

chrootは特定のユーザーおよびプロセスに対して設定される疑似的なルートファイルシステムのこと。 特徴は以下の通り。

  • 特権のないプロセスは、chroot 環境外のファイルにアクセスできない
  • chroot 環境ではハードリンクできないため、ファイル自体をコピーして配置しておく必要がある

最新のプロセス分離ではChroot環境ではなく、仮想化コンテナが使用される。

7.1.3. アクセス制御と外部接続の管理

USBGuardによるデバイス制御

USBGuard

USBGuard ソフトウェア は、デバイス属性に基づいた基本的なホワイトリスト機能とブラックリスト機能を実装することにより、USB デバイスに対するシステム保護を提供する。
ユーザー定義のポリシーを強制するために、USBGuard はLinux カーネルの USB デバイス認証機能を使用する。 USBGuardフレームワークは次のコンポーネントを提供する。

  • 動的対話とポリシー適用のためのプロセス間通信 (IPC) インターフェイスを備えたデーモンコンポーネント
  • 実行中のUSBGuardインスタンスと対話するためのCLI
  • USB デバイス認証ポリシーを記述するためのルール言語
  • 共有ライブラリに実装されたデーモンコンポーネントと対話するための C++ API
USBGuardの機能
# 初期ルールセットを作成する
usbguard generate-policy > /etc/usbguard/rules.conf

# USBGuard ルール セットをカスタマイズする
vi /etc/usbguard/rules.conf

# USBGuard デーモンを起動する
systemctl enable usbguard.service

# USBGuard によって認識されるすべての USB デバイスをリストする
usbguard list-devices

# デバイスがシステムと対話することを許可する
usbguard allow-device <device-num>

# デバイスを認証解除してシステムから削除する
usbguard reject-device <device-num>

# デバイスの認証を解除するだけ
usbguard block-device <device-num>

またUSBGuardでは、blockおよび拒rejectという用語を次の意味で使用する。

  • block … 現在このデバイスと通信しないようにする
  • reject … このデバイスを存在しないかのように扱う

ホワイトリスト/ブラックリストの作成

ホワイトリスト/ブラックリストはusbguard-daemon.confによりロードされ、デーモンの実行時パラメータの構成に使用される。

ホワイトリストまたはブラックリストを作成するには、/etc/usbguard/usbguard-daemon.confファイルを編集し、そのオプションを使用することで実現できる。

RedHat系におけるUSBGuard

USBGuardのデーモンはUSBGuardパブリックIPCインターフェイスを提供する。
このインターフェイスへのアクセスはRedHat系の場合、rootユーザーのみに制限されている。

アクセス制限にはIPCAccessControlFilesオプション、またはIPCAllowedUsersオプションの設定で制御できる。 なお必ずIPCAllowedGroupsオプションの設定も行う必要があり、これを行わない場合、IPCインターフェイスがすべてのローカルユーザーに公開され、USB デバイスの認証状態を操作したり、USBGuardポリシーを変更したりできるようになってしまう。

SSH証明書(CAベース認証)の利用

従来のSSH公開鍵認証の問題

SSH 接続が初めて確立されると、SSH サーバーは自分自身を識別するための公開キーをユーザーに送信する。この認証スキームは「初回使用時の信頼」または TOFU と呼ばれる。
この認証スキームはホストのIP、名前、または公開キーが変更されると、ユーザ側にホストが信頼できないようなメッセージが表示される。

SSH CAベースの認証

SSHの認証で認証局を使用してサーバーとクライアントを認証する機能を利用するとクライアントに対してホストを認証でき、ホストの信頼性を検証できないという混乱を招くSSH公開鍵認証の問題を回避できる

この構成を行い場合、接続先ホストとクライアントの2台だけではなく、認証局用のCAサーバが必要となる。

polkitによるシステムポリシー管理

PolKitは特権のないユーザセッションと特権のあるシステムとの間のネゴシエーターとして機能するアプリケーションのこと。 内部的にはユーザセッションのプロセスがシステムコンテキストでアクションを実行しようとするたびにPolkitがクエリされる。

Polkitの動作はsudoなどの従来の権限承認プログラムとは異なり、rootセッション全体に権限を付与するのではなく、特定のアクションにのみ権限を付与する。

7.1.4. 脆弱性対策と高度なセキュリティ

Linuxカーネル脆弱性対策

Spectre/Meltdown脆弱性

Spectre/Meltdown脆弱性はプロセッサまたは CPU のハードウェアの脆弱性のこと。
この脆弱性は発見されてはいるが、悪用するには非常に難しいとされている。 具体的にはIntel製のプロセッサに対する脆弱性で内容は以下の通り。

  • Spectre脆弱性
    • コンピュータにインストールされているアプリケーション間の分離が破壊されるもの
    • 攻撃者は安全性の低いアプリケーションをだまして、オペレーティング システムのカーネル モジュールから他の安全なアプリケーションに関する情報を朗詠させられる
  • Meltdown脆弱性
    • ユーザー、アプリケーション、オペレーティング システム間の分離を破壊するもの
    • 攻撃者は、そのプログラムや他のプログラムのメモリ位置にアクセスし、システムから機密情報を取得するプログラムを作成することができる

Linux マシンに Meltdown と Spectre に対するパッチが適用されているかどうかを確認するには以下プロジェクトのソフトウェアで可能。

git clone https://github.com/speed47/spectre-meltdown-checker.git
  1. cd spectre-meltdown-checker
  2. chmod u+x spectre-meltdown-checker.sh
  3. ./spectre-meltdown-checker.sh

仮想化とコンテナ化

仮想化

ハイパーバイザーを利用し、ホストOSとゲストOSを完全に分離することで、あるゲストOSでのセキュリティ侵害がホストOSや他のゲストOSへ波及するのを防ぐ強力な境界線を提供する。

コンテナ化

systemdユニットで説明されたような、chrootやLinux Capabilities、そして**名前空間(Namespace)**などの技術を利用してプロセスを分離(サンドボックス化)する。
これにより、コンテナ内のプロセスがホストシステムに与える影響を制限し、セキュリティリスクを低減できます。