不正な通信に対して,通信の自動遮断(portsentry を使用)(Ubuntu 上)

Portsentryはポートスキャンを検知し,検知元IPアドレスを自動遮断するツールである.Ubuntu 24.04 LTSではuniverseリポジトリのportsentry 1.2 を使用する.監視ポートと遮断コマンドは/etc/portsentry/portsentry.confで設定し,検知モードは/etc/default/portsentryで設定し,除外IPアドレスは/etc/portsentry/portsentry.ignore.staticで指定する.遮断コマンドはiptables(nftバックエンド)またはnftablesに合わせて記述する.動作確認はログとテストスキャンで行い,遮断解除はブロックリストの削除とファイアウォールルールの削除で行う.

前準備

Ubuntu のシステム更新

Ubuntu で OS のシステム更新を行う際には, 次のコマンドを実行する.

Ubuntu のインストールは別ページ »で説明する.

# パッケージリストの情報を更新
sudo apt update
# インストール済みのパッケージを包括的に更新 (依存関係も考慮)
sudo apt full-upgrade
# (オプション) 必要に応じてシステムを再起動
sudo shutdown -r now

インストールと設定(Ubuntu 上)

  1. インストール
    # パッケージリストの情報を更新
    sudo apt update
    sudo apt -y install portsentry
    
  2. インストール中に,設定ファイルの編集が必要であることを知らせるメッセージが表示される.表示を読み,[Enter] キーで進める.インストール直後は既定の設定で動作するため,続く手順で設定ファイルを編集する.
  3. /etc/portsentry/portsentry.conf の設定

    このファイルでは,監視対象ポートと遮断方法を設定する.編集にはテキストエディタを使用する.

    sudo nano /etc/portsentry/portsentry.conf
    

    監視対象ポートの設定

    TCP_PORTS および UDP_PORTS の行で,監視対象とするポート番号をカンマ区切りで指定する.空白を含めてはいけない.既定では一般的なポートが指定されているため,必要に応じて追記または変更する.監視できるポート数は 64 までである.なお,後述の高度モード(atcp, audp)では,この 2 つの設定は使用されず,ADVANCED_PORTS_TCP および ADVANCED_PORTS_UDP で指定した番号より小さいポートが監視対象になる.

    検知の頻度の設定

    SCAN_TRIGGER は,遮断するまでに許容する接続回数である.既定値は 0 で,1 回目の接続で遮断する.1 または 2 に設定すると,誤検知による遮断が減る.

    UDP の遮断の設定

    BLOCK_UDP を 0 に設定すると,UDP に対する遮断を行わず,ログの記録のみを行う.UDP は送信元IPアドレスの偽装が容易であり,偽装したパケットにより無関係なホストが遮断されることがある.インターネットに直接接続するホストでは 0 を設定する.

    遮断コマンドの設定

    不正通信を検知した際に実行するコマンドを KILL_ROUTE で設定する.$TARGET$ は検知元のIPアドレスに置き換えられる.既定の設定ファイルには iptables を使う次の行がコメントとして記載されているため,コメント記号 (#) を外して有効にする.

    KILL_ROUTE="/sbin/iptables -I INPUT -s $TARGET$ -j DROP"
    

    Ubuntu 24.04 LTS の iptables コマンドは nftables をバックエンドとして動作する(iptables-nft)ため,上記の設定でも nftables のルールとして登録される.iptables コマンドが未インストールの場合は,sudo apt -y install iptables でインストールする.

    nftables のコマンドで直接記述する場合は,あらかじめ専用のテーブルとチェインを作成し,そこにルールを追加する.

    sudo nft add table inet portsentry
    sudo nft add chain inet portsentry input '{ type filter hook input priority -10 ; policy accept ; }'
    

    その上で KILL_ROUTE を次のように設定する.

    KILL_ROUTE="/usr/sbin/nft add rule inet portsentry input ip saddr $TARGET$ drop"
    

    なお,iptables でも nftables でも,追加されたルールは再起動時に消える.再起動後も遮断を維持したい場合は,iptables-persistentnftables.service の設定ファイルにルールを保存する.

  4. /etc/default/portsentry の設定(検知モード)

    検知モードは /etc/default/portsentryTCP_MODE および UDP_MODE で設定する.編集にはテキストエディタを使用する.

    sudo nano /etc/default/portsentry
    

    指定できるモードは次の通りである.TCP と UDP それぞれについて 1 つのモードを選ぶ.

    • tcp / udp(基本モード): TCP_PORTS, UDP_PORTS で指定したポートへの接続を検知する.
    • stcp / sudp(ステルススキャン検知): 上記に加え,接続を完了しないステルススキャンを検知する.
    • atcp / audp(高度なステルススキャン検知): ADVANCED_PORTS_TCP, ADVANCED_PORTS_UDP で指定した番号より小さい未使用ポートすべてを監視する.監視範囲が広く誤検知が起きやすいため,ADVANCED_EXCLUDE_TCP, ADVANCED_EXCLUDE_UDP で除外ポートを指定する.

    設定例は次の通りである.

    TCP_MODE="atcp"
    UDP_MODE="audp"
    
  5. 監視対象から除外する IP アドレスの設定

    内部ネットワークのホストなど,監視対象から除外したいIPアドレスやネットワークを /etc/portsentry/portsentry.ignore.static に記載する.除外しない場合,正当な通信も不正通信と判定され,自動で遮断される.編集にはテキストエディタを使用する.

    sudo nano /etc/portsentry/portsentry.ignore.static
    

    次のように設定する.「XXX.YYY」は自身の環境のネットワークアドレスに読み替える.CIDR表記 (例: 192.168.1.0/24, 127.0.0.1/32) が使用できる.

    XXX.YYY.0.0/24
    127.0.0.1/32
    0.0.0.0
    

    実際に参照されるファイルは /etc/portsentry/portsentry.ignore であり,サービスの起動時に portsentry.ignore.static の内容と自ホストの各インタフェースのIPアドレスから自動生成される.そのため,編集するのは portsentry.ignore.static である.

  6. サービスの再起動

    設定ファイルを書き換えたため,portsentryサービスを再起動する.Ubuntu 24.04 LTS の portsentry パッケージは /etc/init.d/portsentry スクリプトで起動するが,systemd の SysV 互換機能により systemctl で操作できる.

    sudo systemctl restart portsentry
    sudo systemctl status portsentry
    

設定の確認と運用

設定の確認

別のホストから,監視対象のポートへ意図的にポートスキャンを実行し,動作を確認する.スキャンには nmap を使用する.スキャンを行ったホストは遮断されるため,あらかじめ遮断されても支障のないホストを使用する.

nmap -sT サーバのIPアドレス

検知と遮断の記録は,次のコマンドでログを確認する.

sudo journalctl -t portsentry

遮断されたホストのIPアドレスは /var/lib/portsentry/portsentry.blocked.tcp などのファイル(モードごとに作成される)に記録され,検知の履歴は /var/lib/portsentry/portsentry.history に記録される.追加されたファイアウォールルールは次のコマンドで確認する.

sudo iptables -L INPUT -n
sudo nft list ruleset

運用時は,遮断されたIPアドレスの記録を定期的に確認し,誤検知による遮断が無いかを確認する.

設定ミスの復旧

設定に誤りがあり,正当な通信まで遮断される場合は,次のコマンドでportsentryサービスを停止する.

sudo systemctl stop portsentry

サービス停止後,設定ファイルを修正し,次のコマンドで再度サービスを起動する.

sudo systemctl start portsentry

サービスを停止しても,すでに追加されたファイアウォールルールは残る.通信を復旧するには,次項の手順でルールを削除する.

遮断の解除

誤ってIPアドレスが遮断された場合は,ファイアウォールのルールと,遮断済みリストの両方を削除する.

iptables を使用している場合は,行番号を確認してルールを削除する.

sudo iptables -L INPUT -n --line-numbers
sudo iptables -D INPUT 行番号

nftables のコマンドで設定した場合は,ハンドル番号を確認してルールを削除する.

sudo nft -a list table inet portsentry
sudo nft delete rule inet portsentry input handle ハンドル番号

遮断済みリストは /var/lib/portsentry/portsentry.blocked.* であり,サービスの再起動時に消去される.そのため,ルールを削除した後にサービスを再起動する.同じIPアドレスを今後遮断しないようにするには,/etc/portsentry/portsentry.ignore.static にそのIPアドレスを追記してから,サービスを再起動する.

sudo systemctl restart portsentry