【実務・中級編】 Linuxにおける不要なネットワークプロトコルの無効化 – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

攻撃者の「隠れ家」を潰せ:Linuxのカーネル層から不要プロトコルを根絶する方法

現場で多くのインシデントを見てきたが、ハッカーがサーバーに侵入した後、一番最初にやることの一つが「ネットワークの列挙(Enumeration)」だ。彼らは nmap でポートを叩くだけではない。OSが内部で保持しているが、実は誰も使っていないプロトコルスタックを悪用し、ファイアウォールをすり抜けたり、特権昇格のトリガーを探したりする。

「IPv6は使っていないから大丈夫」なんて楽観は捨ててくれ。今日は、Linuxのカーネルレベルで不要なプロトコルを無効化し、攻撃者が「入り込む隙」すら作らないための実践的な要塞化手法を教える。

—

なぜ、使わないプロトコルを「殺す」必要があるのか?

例えば DCCP (Datagram Congestion Control Protocol) や SCTP (Stream Control Transmission Protocol)。これらがあなたのWebサーバーで稼働している理由は何か? おそらく「デフォルトで入っていたから」だろう。

攻撃者は、これらのプロトコルが有効なまま放置されていることを知っている。特定のカーネルバージョンでこれらのプロトコルに脆弱性が見つかった場合、外部からパケットを送り込むだけで、権限昇格(Local Privilege Escalation)を許す可能性すらある。「攻撃対象領域(Attack Surface)を最小化する」。これがセキュリティの鉄則だ。

—

実践:カーネルレベルでのプロトコル無効化

これらは、カーネルモジュールをブラックリストに登録することで、システムがそのプロトコルを読み込まないように設定する。/etc/modprobe.d/ 配下に設定ファイルを作成し、静かに封印する。

1. ブラックリスト設定ファイルの作成

/etc/modprobe.d/blacklist-custom.conf を作成し、以下を追記する。

# 不要なネットワークプロトコルの無効化
# これらはカーネルモジュールのロードを禁止する設定だ
install dccp /bin/true
install sctp /bin/true
install rds /bin/true
install tipc /bin/true

設定後、反映させるために再起動するか、現在ロードされているモジュールを modprobe -r で取り除いてくれ。

—

IPv6の無効化:慎重かつ大胆に

IPv6を無効化する際、単に「NICのプロパティをオフにする」だけでは不十分だ。カーネルパラメータ(sysctl)で完全に口を塞ぐ必要がある。

/etc/sysctl.d/99-disable-ipv6.conf を作成し、以下の設定を記述する。

# IPv6の全インターフェースでの無効化
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

# IPv6用のルーティングテーブルの無効化
net.ipv6.conf.all.forwarding = 0

設定を反映するには sudo sysctl -p /etc/sysctl.d/99-disable-ipv6.conf を実行する。これで、ifconfig や ip a を叩いても、IPv6アドレスは二度と表示されなくなるはずだ。

—

アプリケーション層での「守り」:不要な通信を弾く

インフラ層で絞り込んでも、アプリケーション層が不用意な通信を許しては意味がない。例えば、サーバーサイドで外部リクエストを行う際、不要なプロトコルを通さないバリデーションが必要だ。

以下は、PHPで外部URLを叩く際に「http/https以外」を弾くセキュアな設計例だ。

<?php
/**
 * 外部リクエストを許可するプロトコルをホワイトリストで管理する
 * 余計なプロトコル(file://, gopher://等)によるSSRF攻撃を防ぐ
 */
function is_allowed_protocol(string $url): bool {
    $allowed_protocols = ['http', 'https'];
    $parsed = parse_url($url);
    
    return isset($parsed['scheme']) && in_array($parsed['scheme'], $allowed_protocols, true);
}

$target_url = "http://api.example.com/data";

if (is_allowed_protocol($target_url)) {
    // 安全なリクエスト処理を実行
    echo "安全なプロトコルです。処理を続行します。";
} else {
    // ログに記録し、攻撃の試行を検知する
    error_log("不正なプロトコルへのアクセス試行: " . $target_url);
    die("アクセス拒否: 許可されていないプロトコルです。");
}

—

最後に:エンジニアへの提言

設定を変更した後は、必ず ss -tuln や netstat -plunt で、予期せぬポートが開いていないかを確認する癖をつけてほしい。

セキュリティとは、派手なファイアウォール製品を導入することではなく、こうした「泥臭い設定の積み重ね」にある。攻撃者は、我々が「面倒くさくて放置した場所」を一番知っている。今回紹介した設定は、明日からでも即座に適用できるはずだ。システムの堅牢性を高めることは、自分の作ったコードを守ることと同義だということを忘れないでくれ。

何か不明点があれば、またいつでも聞いてほしい。現場からは以上だ。

コメント

タイトルとURLをコピーしました