【FreeBSD】ipfw ファイアウォール設定(ConoHa VPS/14.3-RELEASE)

本記事は、FreeBSD の設定手順を解説するシリーズの一部です。
ここでは、ipfw によるファイアウォールの基本設定を記録します。

検証環境は FreeBSD 14.3-RELEASE(ConoHa VPS)を使用しています。
前回の初期設定・セキュリティ設定は以下の記事を参照してください。

【FreeBSD】初期設定とセキュリティ設定(ConoHa VPS/14.3-RELEASE)

本記事で扱う範囲は以下のとおりです。

  • ipfw の有効化と基本的なルール設定
  • SSH(変更後ポート)の許可、ICMP の制御
  • アウトバウンド通信のホワイトリスト制御
  • NetBIOS / SMB の明示的な拒否
  • 拒否パケットのログ設定

Web やmail 関連のルールは、各サービスの導入時に追加するため含めていません。

設定内容は筆者の環境と運用方針に基づく一例です。あくまで参考としてご覧ください。


ipfw の概要

ipfw は FreeBSD 標準のパケットフィルタです。カーネルレベルで動作し、通過するパケットをルールに従って許可・拒否します。

ルールには番号が割り当てられ、番号が小さい順に評価されます。
最初にマッチしたルールが適用され、どのルールにもマッチしなかったパケットは 65535 番(デフォルト deny)で拒否されます。

また、keep-statecheck-state によるステートフルなフィルタリングが可能です。
keep-state を付けたルールは通信の状態を記録し、check-state で戻りの通信を自動的に許可します。
これにより、応答パケット用のルールを個別に書く必要がなくなります。


ipfw の有効化

ipfw を有効にする前に、重要な注意点があります。

ipfw を有効化した時点で、デフォルトではすべての通信が拒否されます。
SSH 接続中に有効化すると、即座にロックアウトされる可能性があります。
必ず VNC コンソールからアクセスできる状態で作業してください。

まず、安全に進めるため /etc/rc.conf に以下を追記します。

# sysrc firewall_enable="YES"
# sysrc firewall_type="open"
# sysrc firewall_logging="YES"

firewall_type="open" はすべての通信を許可する一時的な設定です。
この状態で ipfw を起動し、ルールスクリプトの作成・テストが済んでから本番の設定に切り替えます。

ipfw を起動します。

# service ipfw start

起動後、現在のルールを確認します。

# ipfw list

open の場合、以下のように全許可のルールが表示されます。

00100 allow ip from any to any via lo0
00200 deny ip from any to 127.0.0.0/8
00300 deny ip from 127.0.0.0/8 to any
00400 deny ip from any to ::1
00500 deny ip from ::1 to any
65000 allow ip from any to any
65535 deny ip from any to any

この状態が確認できたら、次のセクションでルールスクリプトを作成していきます。


ルールスクリプトの作成

ipfw のルールはシェルスクリプトとして記述し、起動時に読み込ませます。
本記事では /usr/local/etc/ipfw.rules にルールスクリプトを作成します。

まず、/etc/rc.conffirewall_typeopen からスクリプトのパスに変更します。

# sysrc firewall_type="/usr/local/etc/ipfw.rules"

※ この時点ではまだ反映しません。スクリプトの作成とテストが完了してから適用します。

ルール番号の設計方針:

ルールは番号順に評価されるため、用途ごとに番号帯を分けておくと管理しやすくなります。
本記事では以下の番号体系を使用します。

番号帯用途
00100〜00199ループバック・ステートフル
00200〜00299明示的な拒否(NetBIOS 等)
00300〜00399アウトバウンド許可
00400〜00499インバウンド許可
00500〜ログ・デフォルト deny

番号の間隔に余裕を持たせているため、今後 HTTP/HTTPS やメール関連のルールを追加する際にも対応できます。

スクリプトの雛形:

# vi /usr/local/etc/ipfw.rules
#!/bin/sh

fwcmd="/sbin/ipfw"

# ルール初期化
${fwcmd} -q flush

# --- 00100: ループバック・ステートフル ---
# (次セクションで記述)

# --- 00200: 明示的な拒否 ---
# (次セクションで記述)

# --- 00300: アウトバウンド許可 ---
# (次セクションで記述)

# --- 00400: インバウンド許可 ---
# (次セクションで記述)

# --- 00500: ログ・デフォルト deny ---
# (次セクションで記述)

以降のセクションで、各ブロックのルールを順に記述していきます。


ループバックとステートフルの基本ルール

ループバック(lo0)はサーバ内部の通信に使用されます。
これを許可しないと、localhost を使うサービスが正常に動作しません。

また、check-state を早い段階に配置することで、確立済みの通信を効率よく処理できます。

# --- 00100: ループバック・ステートフル ---
${fwcmd} -q add 00100 allow ip from any to any via lo0
${fwcmd} -q add 00101 deny ip from any to 127.0.0.0/8
${fwcmd} -q add 00102 deny ip from 127.0.0.0/8 to any
${fwcmd} -q add 00110 check-state
ルール内容
00100ループバックインターフェース経由の通信をすべて許可
00101〜00102lo0 以外での 127.0.0.0/8 通信を拒否
00110確立済みセッションに属するパケットを許可

明示的な拒否

不要なことが明らかな通信を早い段階で拒否しておきます。

プライベート IP アドレスは、インターネット側から届くことはないため、なりすまし防止として拒否します。
NetBIOS / SMB 関連のポートはインターネット上から狙われやすく、VPS 環境で使うことはまずありません。

# --- 00200: 明示的な拒否 ---

# プライベート IP アドレス
${fwcmd} -q add 00200 deny ip from 10.0.0.0/8 to any
${fwcmd} -q add 00201 deny ip from any to 10.0.0.0/8
${fwcmd} -q add 00202 deny ip from 172.16.0.0/12 to any
${fwcmd} -q add 00203 deny ip from any to 172.16.0.0/12
${fwcmd} -q add 00204 deny ip from 192.168.0.0/16 to any
${fwcmd} -q add 00205 deny ip from any to 192.168.0.0/16

# NetBIOS / SMB
${fwcmd} -q add 00210 deny tcp from any to any 135
${fwcmd} -q add 00211 deny tcp from any to any 137-139
${fwcmd} -q add 00212 deny udp from any to any 137-139
${fwcmd} -q add 00213 deny tcp from any to any 445
${fwcmd} -q add 00214 deny udp from any to any 445
ルール内容
00200〜00205プライベート IP アドレス(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)の送受信を拒否
00210RPC(135/TCP)を拒否
00211〜00212NetBIOS(137-139/TCP, UDP)を拒否
00213〜00214SMB(445/TCP, UDP)を拒否

※ VPS 環境では内部ネットワークにプライベート IP を使用しているケースがあります。ConoHa VPS でプライベートネットワーク機能を利用している場合は、該当するアドレス帯を拒否ルールから除外してください。


アウトバウンドルール

ホワイトリスト方式のため、サーバから外部への通信も必要なものだけを明示的に許可します。
keep-state を付けることで、応答パケットは check-state(00110)で自動的に許可されます。

# --- 00300: アウトバウンド許可 ---

# DNS
${fwcmd} -q add 00300 allow tcp from me to any 53 out setup keep-state
${fwcmd} -q add 00301 allow udp from me to any 53 out keep-state

# NTP
${fwcmd} -q add 00310 allow udp from me to any 123 out keep-state

# HTTP/HTTPS(pkg, freebsd-update 等)
${fwcmd} -q add 00320 allow tcp from me to any 80 out setup keep-state
${fwcmd} -q add 00321 allow tcp from me to any 443 out setup keep-state
ルール内容
00300〜00301DNS の名前解決(53/TCP, UDP)を許可
00310NTP の時刻同期(123/UDP)を許可
00320〜00321HTTP/HTTPS(80, 443/TCP)を許可。pkg updatefreebsd-update で必要

アウトバウンドの HTTP/HTTPS は、Web サーバとしてのインバウンド許可とは別です。
ここではサーバ自身がパッケージの取得やアップデートを行うために必要な通信を許可しています。

今後、メールサーバを導入する際には、SMTP の送信(25/TCP)などをこの番号帯に追加します。


インバウンドルール

現時点では ICMP と SSH のみ許可します。

# --- 00400: インバウンド許可 ---

# ICMP
${fwcmd} -q add 00400 allow icmp from any to me in icmptypes 0,3,8,11

# SSH
${fwcmd} -q add 00410 allow tcp from any to me 10022 in setup keep-state
ルール内容
00400ICMP の必要な型を許可
00410SSH(変更後ポート 10022)への接続を許可

ICMP で許可している型の内訳は以下のとおりです。

型番号名称用途
0Echo Replyping の応答
3Destination Unreachable到達不能通知(経路やポートの問題把握に必要)
8Echo Requestping の受信(死活監視に使用)
11Time Exceededtraceroute の応答やTTL超過通知

外部からの死活監視を行わない場合は、型番号 8(Echo Request)を除外しても構いません。

※ SSH のポート番号は sshd_config で設定した値に合わせてください。

HTTP/HTTPS(80, 443)やメール関連(25, 587, 993 等)のインバウンドルールは、各サービスの導入時にこの番号帯に追加していきます。


ログとデフォルト deny

ここまでのルールにマッチしなかったパケットを、ログに記録したうえで拒否します。

# --- 00500: ログ・デフォルト deny ---
${fwcmd} -q add 00500 deny log ip from any to any

log を付けることで、拒否されたパケットの情報が syslog に出力されます。
不正アクセスの兆候や設定漏れの発見に役立ちます。

ログ出力先の設定:

デフォルトでは ipfw のログは /var/log/security に出力されます。
専用のログファイルに分離したい場合は、/etc/syslog.conf に以下を追記します。

# vi /etc/syslog.conf
security.* /var/log/ipfw.log

ログファイルを作成し、syslogd を再起動します。

# touch /var/log/ipfw.log
# service syslogd restart

ログローテーションの設定:

ログが肥大化しないよう、/etc/newsyslog.conf にローテーション設定を追加しておきます。

# vi /etc/newsyslog.conf

以下の行を追加します。

/var/log/ipfw.log 600 7 1000 * JC
項目内容
600ファイルのパーミッション(root のみ読み書き)
7保持する世代数
1000ローテーションするサイズ(KB)
*時間指定なし(サイズのみで判定)
JCbzip2 圧縮、存在しなければ作成

なお、/etc/rc.conffirewall_logging="YES" は ipfw の有効化のセクションで設定済みです。


ルールの適用と動作確認

ルールスクリプトが完成したら、まずスクリプトに実行権限を付与します。

# chmod 700 /usr/local/etc/ipfw.rules

重要:適用前に VNC コンソールからアクセスできることを確認してください。
ルールに問題があると SSH 接続が即座に切断され、復旧は VNC 経由でしか行えません。

ルールの適用:

# service ipfw restart

現在のルールを確認:

# ipfw list

スクリプトに記述したルールが番号順に表示されることを確認します。

通信カウンタの確認:

# ipfw show

各ルールにマッチしたパケット数とバイト数が表示されます。
しばらく運用した後に確認すると、どのルールが実際に使われているか把握できます。

接続テスト:

適用後、以下の順で確認します。

  1. 新しい Tera Term ウィンドウを開き、変更後のポートで SSH 接続できることを確認
  2. 外部から ping を実行し、応答があることを確認
  3. サーバ側から freebsd-update fetchpkg update を実行し、アウトバウンド通信が正常に動作することを確認

すべて問題なければ、ファイアウォールの設定は完了です。

万が一接続できなくなった場合は、VNC コンソールからログインし、一時的にルールを全許可に戻して原因を調査します。

# ipfw -q flush
# ipfw -q add 65000 allow ip from any to any

この時点での状態まとめ

ここまでの設定で、ipfw によるファイアウォールが有効になっています。

現在のルール構成:

番号帯内容
00100〜00110ループバック許可、偽装拒否、ステートフル検査
00200〜00214プライベート IP アドレスの拒否、NetBIOS / SMB の拒否
00300〜00321アウトバウンド許可(DNS, NTP, HTTP/HTTPS)
00400〜00410インバウンド許可(ICMP, SSH)
00500ログ記録+デフォルト deny

通信ポリシー:

方向方針
インバウンドSSH と ICMP のみ許可、それ以外はすべて拒否
アウトバウンドDNS, NTP, HTTP/HTTPS のみ許可(ホワイトリスト方式)

今後、各サービスの導入に合わせて以下のルールを追加していく想定です。

サービス追加するルール
Web サーバインバウンド 80, 443/TCP の許可
メールサーバ(Postfix)インバウンド 25, 587/TCP の許可、アウトバウンド 25/TCP の許可
メールサーバ(Dovecot)インバウンド 110, 143, 993, 995/TCP の許可

次回以降は、以下の内容を予定しています。

  • pkg / ports の導入と使い方:ソフトウェアのインストール方法を整理します
  • Postfix 設定編:メール送信側の構築に進みます

これらが完了すれば、Postfix や Dovecot などのアプリケーション導入に進む準備が整います。

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