Debianにおけるファイアウォール設定の詳細解説
はじめに
現代のインターネット環境において、ファイアウォールはサーバーやクライアントコンピュータを不正アクセスや悪意のあるトラフィックから守るための最も基本的なセキュリティ機構の一つです。特に、サーバーとして公開されているDebianシステムでは、適切なファイアウォール設定が必須となります。
ファイアウォールは、ネットワークを流れるパケットを検査し、あらかじめ定義されたルールに基づいて通信を許可、拒否、あるいは変更します。これにより、必要なサービスのみを外部に公開し、それ以外の不要な通信を遮断することができます。
Debian GNU/Linuxでは、Linuxカーネルのネットフィルタリングフレームワークを利用してファイアウォール機能を実現しています。このフレームワークを操作するための主要なユーザー空間ツールとして、古くから使われている iptables、その後継として開発された nftables、そしてこれらをより簡単に操作するためのフロントエンドである UFW (Uncomplicated Firewall) があります。
この記事では、Debianシステムにおけるファイアウォール設定について、これらの主要なツールである UFW、iptables、そして nftables を中心に、それぞれの特徴、基本的な使い方からより実践的な設定方法、そして共通の考慮事項やベストプラクティスまで、詳細に解説します。約5000語のボリュームで、Debianにおけるファイアウォール設定の全体像を把握し、自身の環境に合わせた適切なセキュリティ設定を行うための知識を提供することを目指します。
この記事を読むことで、以下のことを学ぶことができます。
- ファイアウォールの基本的な仕組みと概念
- Debianで利用できる主要なファイアウォールツールの違いと特徴
- UFW、iptables、nftablesを用いた具体的なファイアウォール設定手順
- よく使われるサービスに必要なポート番号
- ファイアウォール設定におけるセキュリティ上のベストプラクティス
- 設定のトラブルシューティング方法
対象読者としては、Debianサーバーの運用に携わるシステム管理者や、Linuxシステムのセキュリティに関心のある方を想定しています。基本的なLinuxコマンドライン操作の知識があることを前提としますが、ファイアウォールに関する専門的な知識は問いません。
さあ、Debianシステムを安全に保つためのファイアウォール設定について、深く掘り下げていきましょう。
ファイアウォールの基本概念
Debianにおける具体的な設定に入る前に、ファイアウォールがどのように機能するのか、いくつかの基本的な概念を理解しておくことが重要です。
パケットフィルタリング
ファイアウォールの最も基本的な機能は、パケットフィルタリングです。ネットワーク上を流れるデータは「パケット」と呼ばれる単位に分割されて送受信されます。ファイアウォールはこれらのパケットを一つずつ検査し、そのパケットに含まれる情報(送信元/宛先IPアドレス、送信元/宛先ポート番号、プロトコル種別など)を基に、事前に定義されたルールと照合します。
ルールに合致した場合、そのルールに定められたアクション(許可、拒否、破棄など)が実行されます。合致しない場合は、次のルールに移るか、最終的にはデフォルトポリシーが適用されます。
ステートフルインスペクション
現代のファイアウォールは、単純なパケットフィルタリングだけでなく、「ステートフルインスペクション(Stateful Inspection)」の機能を持ちます。これは、ファイアウォールが過去に通過したコネクションの状態(ステート)を記憶し、その状態に基づいてパケットを処理する機能です。
例えば、内部ネットワークから外部への接続(例:ウェブサイト閲覧)を開始した場合、そのコネクションの状態(ESTABLISHED: 確立済み)をファイアウォールが記憶します。そして、その応答として外部から戻ってくるパケットに対しては、たとえ外部からの通信であっても、確立済みのコネクションの一部であると判断して自動的に許可します。これにより、応答パケットのために明示的な許可ルールを記述する必要がなくなり、ファイアウォール設定が簡素化されるだけでなく、セキュリティも向上します。
ステートの主な種類としては、以下のものがあります。
- NEW: 新しいコネクションの開始を示すパケット。
- ESTABLISHED: 既に確立されているコネクションに属するパケット。
- RELATED: 既存のコネクションに関連する新しいコネクションの開始を示すパケット(例:FTPのデータコネクション)。
- INVALID: 不正な形式、あるいはどのコネクションにも属さないパケット。
ルールセット、チェーン、ターゲット
ファイアウォールの設定は、複数の「ルール」の集合である「ルールセット」として管理されます。これらのルールは「チェーン」と呼ばれる処理の順番で並べられています。パケットがファイアウォールを通過する際、特定のチェーンに入り、チェーン内のルールを順番に照合されていきます。
Linuxカーネルのネットフィルタリングでは、パケットの通過方向や処理段階に応じて、あらかじめ定義された標準的なチェーンが存在します。主要なチェーンには以下のようなものがあります。
- INPUT: ローカルのプロセス宛てのパケットが通過するチェーン。
- OUTPUT: ローカルのプロセスから送信されるパケットが通過するチェーン。
- FORWARD: そのシステムを経由して他のネットワークへ転送されるパケットが通過するチェーン(ルーターやゲートウェイとして機能する場合に関係)。
- PREROUTING: ルーティング判断より前にパケットを処理するチェーン(主にNATで使用)。
- POSTROUTING: ルーティング判断より後にパケットを処理するチェーン(主にNATで使用)。
各ルールに合致したパケットに対して実行されるアクションを「ターゲット」と呼びます。代表的なターゲットは以下の通りです。
- ACCEPT: パケットを通過させる。
- DROP: パケットを破棄する(送信元には何も通知しない)。
- REJECT: パケットを破棄し、送信元にエラーメッセージ(例: ICMP Port Unreachable)を返す。
- LOG: パケットに関する情報をシステムログに記録する(パケットは引き続き次のルールで処理されるか、ターゲットとして単独で使用されることもある)。
- JUMP (または GO TO): 別のチェーンに処理を移す。
ポリシー(デフォルトポリシー)
各チェーンには、そのチェーンのどのルールにも合致しなかったパケットに対する最終的なアクションとして、「デフォルトポリシー」が設定されています。例えば、INPUTチェーンのデフォルトポリシーがDROPに設定されている場合、ローカル宛てのパケットは、明示的に許可するルールがなければ全て破棄されます。
セキュリティの観点からは、デフォルトポリシーは「拒否」(DROPまたはREJECT)に設定し、必要な通信だけを明示的に許可する「ホワイトリスト方式」が推奨されます。これにより、未知のサービスポートへの攻撃を防ぐことができます。
TCP/IPプロトコルの基礎知識
ファイアウォールルールを設定する上で、TCP/IPプロトコルの基礎知識は不可欠です。特に以下の点を理解しておく必要があります。
- IPアドレス: 通信の送信元と宛先を識別する番号。IPv4 (例: 192.168.1.1) と IPv6 (例: 2001:db8::1) があります。
- プロトコル: 通信の種類を定義します。代表的なものに、TCP (Transmission Control Protocol) や UDP (User Datagram Protocol) があります。TCPは信頼性の高いコネクション指向の通信に、UDPは高速なコネクションレスの通信に使用されます。ICMP (Internet Control Message Protocol) は、ネットワーク診断などに使われます(例: ping)。
- ポート番号: 同じIPアドレスを持つシステム上で動作する複数のサービスを識別するために使用されます。TCPとUDPそれぞれに0〜65535のポート番号があり、well-known ports (0-1023, 例: HTTP 80, HTTPS 443, SSH 22)、registered ports (1024-49151)、dynamic/private ports (49152-65535) に分類されます。
ファイアウォールルールでは、これらの要素を組み合わせて、「送信元IPアドレス X から、宛先IPアドレス Y の、TCPプロトコル、宛先ポート番号 Z への通信を許可する」といった形で条件を指定します。
これらの基本概念を理解することで、これから解説する各ツールの設定がよりスムーズに進むでしょう。
Debianで利用可能なファイアウォールツール
Debianでは、前述の通り、Linuxカーネルのネットフィルタリングフレームワークを操作するためのいくつかの異なるツールが利用可能です。それぞれに特徴があり、使用する目的や習熟度に応じて選択できます。
iptables
iptables は、Linuxファイアウォールの設定ツールとして長年標準的に使われてきました。Linuxカーネル 2.4から採用されたnetfilterフレームワーク(IPv4向け)を操作するためのコマンドラインツールです。IPv6向けには ip6tables があります。
仕組み:
iptablesは、「テーブル」という概念でルールの種類を分けます。主要なテーブルには以下があります。
filter: パケットのフィルタリング(通過許可/拒否)を行う最も一般的なテーブル。INPUT, OUTPUT, FORWARDチェーンを持ちます。nat: ネットワークアドレス変換(NAT)を行うためのテーブル。PREROUTING, POSTROUTING, OUTPUTチェーンを持ちます。mangle: パケットヘッダの内容を変更するためのテーブル。様々なチェーンを持ちます。raw: ステートトラッキングよりも早い段階でパケットを処理するためのテーブル。PREROUTING, OUTPUTチェーンを持ちます。
それぞれのテーブル内で、前述の標準チェーン(INPUT, OUTPUT, FORWARDなど)やユーザー定義チェーンにルールを追加していきます。
コマンドライン構文:
iptables コマンドは複雑で、多くのオプションがあります。基本的な構文は以下のようになります。
bash
iptables -t <テーブル名> -A <チェーン名> <マッチ条件> -j <ターゲット>
-t <テーブル名>: 操作するテーブルを指定します(省略時はfilterテーブル)。-A <チェーン名>: 指定したチェーンの末尾にルールを追加します。-I <チェーン名> [<ルール番号>]: 指定したチェーンの先頭または指定した位置にルールを挿入します。-D <チェーン名> <ルール番号またはルール指定>: 指定したチェーンからルールを削除します。-L [<チェーン名>]: 指定したチェーン(または全チェーン)のルールを表示します。-F [<チェーン名>]: 指定したチェーン(または全チェーン)のルールをすべて削除します。-P <チェーン名> <ターゲット>: 指定したチェーンのデフォルトポリシーを設定します。
マッチ条件:
ルールにマッチさせるための条件指定には、以下のようなオプションがあります。
-s <送信元IPアドレス/ネットワーク>-d <宛先IPアドレス/ネットワーク>-p <プロトコル>(例: tcp, udp, icmp)--sport <送信元ポート>--dport <宛先ポート>-i <入力インターフェース>-o <出力インターフェース>-m <モジュール名> <モジュールオプション>(例:-m state --state NEW,ESTABLISHED)
設定の永続化:
iptables コマンドで設定したルールは、通常、システムを再起動すると失われます。設定を永続化するためには、現在のルールセットをファイルに保存し、システム起動時にそのファイルを読み込む必要があります。Debianでは iptables-persistent パッケージがこの目的でよく使われます。
“`bash
インストール
sudo apt update
sudo apt install iptables-persistent netfilter-persistent
現在の設定を保存
sudo netfilter-persistent save
保存された設定は /etc/iptables/rules.v4 (IPv4) および rules.v6 (IPv6) に保存されます。
これらは手動で編集することも可能ですが、構文ミスに注意が必要です。
システム起動時に設定が自動的に読み込まれるようになります。
手動で保存した設定を読み込む場合
sudo netfilter-persistent reload
“`
利点と欠点:
* 利点: 長年の実績があり、機能が豊富で非常に柔軟な設定が可能です。複雑なルーティングやNAT設定、詳細なパケット検査などに対応できます。ドキュメントや情報が豊富にあります。
* 欠点: コマンドライン構文が複雑で、初心者には難解です。IPv4とIPv6でコマンドが分かれている (iptablesとip6tables) ため、設定を二重に行う必要があります。大量のルールを扱う場合にパフォーマンスの問題が発生することがあります。
nftables
nftables は、iptables、ip6tables、arptables、ebtablesといった既存のネットフィルタリングツール群を置き換えるために開発された、Linuxカーネルの新しいサブシステムです。よりシンプルで統一された構文を持ち、パフォーマンスや機能面で改善が図られています。Debian 10 (Buster) 以降、デフォルトのファイアウォールバックエンドとして推奨されています。
仕組み:
nftables もテーブル、チェーン、ルールといった概念を持ちますが、その構造はiptablesよりも柔軟です。テーブルはアドレスファミリー(ipv4, ipv6, inet, arp, bridge)と任意の名前で定義されます。inet ファミリーを使用すると、IPv4とIPv6の両方に共通のルールを記述できます。
nftablesは、iptablesのように特定の用途に特化した固定的なテーブル(filter, natなど)を持つのではなく、ユーザーが任意の種類のチェーンをテーブル内に定義できます。チェーンはタイプ(filter, nat, routeなど)、フック(パケットが処理される場所:ingress, prerouting, input, forward, output, postrouting)、優先度を指定して定義されます。
ルールは、表現 (expressions) とステートメント (statements) の組み合わせで記述されます。表現はパケットの情報を参照し、ステートメントはアクション(許可、拒否、カウンタ、ログなど)や制御フロー(goto, jump)を定義します。
コマンドライン構文:
nft コマンドを使用します。構文はiptablesよりも構造的で、複数行に渡る記述も可能です。
“`bash
テーブルの追加
sudo nft add table inet filter
チェーンの追加 (タイプ: filter, フック: input, 優先度: 0, デフォルトポリシー: drop)
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
ルールの追加 (入力チェーンに、TCPポート22宛ての通信を許可するルールを追加)
sudo nft add rule inet filter input tcp dport 22 accept
ルールセットの表示
sudo nft list ruleset
ルールセット全体をファイルに保存
sudo nft list ruleset > /etc/nftables.conf
ファイルからルールセットを読み込み
sudo nft -f /etc/nftables.conf
“`
設定の永続化:
nftables の設定は、/etc/nftables.conf ファイルに記述し、システム起動時に nftables.service によって読み込まれるのが標準的な方法です。
“`bash
設定ファイルを編集
sudo nano /etc/nftables.conf
設定ファイルをテスト (構文チェック)
sudo nft -c -f /etc/nftables.conf
設定ファイルを読み込み
sudo systemctl enable nftables.service
sudo systemctl start nftables.service
あるいは手動で読み込み: sudo nft -f /etc/nftables.conf
“`
/etc/nftables.conf の基本的な構造は以下のようになります。
“`nft
!/usr/sbin/nft -f
ルールセットをクリア
flush ruleset
テーブル定義
table inet filter {
# チェーン定義
chain input {
type filter hook input priority 0; policy drop; # デフォルトポリシーをドロップに設定
# 既に確立/関連したコネクションからのパケットを許可
ct state established,related accept
# ループバックインターフェースからの通信を許可
iif "lo" accept
# SSH (TCP 22) への通信を許可
tcp dport 22 accept
# HTTP (TCP 80) への通信を許可
tcp dport 80 accept
# HTTPS (TCP 443) への通信を許可
tcp dport 443 accept
# ICMP (Ping) を許可 (任意)
# ip protocol icmp accept
}
chain forward {
type filter hook forward priority 0; policy drop; # ルーターとして使わないならドロップ
}
chain output {
type filter hook output priority 0; policy accept; # 基本的に出力は許可 (必要に応じて制限)
}
}
“`
利点と欠点:
* 利点: iptablesよりも統一され、柔軟で表現力の高い構文を持ちます。IPv4/IPv6共通のルールを記述できます。ルール更新のパフォーマンスが向上し、アトミックなルールセットの置き換えが可能です。セットやマップといった高度な機能により、大量のIPアドレスやポート番号を効率的に扱えます。
* 欠点: iptablesに比べて歴史が浅く、情報が少ない場合があります。新しい概念を学習する必要があります。
UFW (Uncomplicated Firewall)
UFW は、iptables または nftables をバックエンドとして使用し、より直感的で分かりやすいコマンドラインインターフェースを提供するツールです。複雑なルールを意識することなく、基本的なファイアウォール設定を素早く行うことができます。Debianでは標準でインストールされていない場合がありますが、簡単に導入できます。
仕組み:
UFW自体は、ファイアウォールルールを直接カーネルに設定するわけではありません。UFWコマンドで設定された内容は、内部的にiptablesまたはnftablesのルールセットに変換されて適用されます。Debianの新しいバージョンでは、デフォルトでnftablesをバックエンドとして使用します。
コマンドライン構文:
UFWのコマンドは、 iptablesやnftablesに比べて非常にシンプルです。
“`bash
UFWの有効化
sudo ufw enable
UFWの無効化
sudo ufw disable
現在のルールの表示
sudo ufw status
sudo ufw status verbose # 詳細表示
デフォルトポリシーの設定 (例: 着信拒否、送信許可)
sudo ufw default deny incoming
sudo ufw default allow outgoing
特定のポートを許可
sudo ufw allow <ポート番号>[/<プロトコル>] (例: sudo ufw allow 22/tcp, sudo ufw allow 80)
sudo ufw allow <サービス名> (例: sudo ufw allow ssh, sudo ufw allow http) – /etc/services に定義されたサービス名を使用
ポート範囲を許可
sudo ufw allow <開始ポート>:<終了ポート>/<プロトコル> (例: sudo ufw allow 10000:20000/tcp)
特定のIPアドレスからのアクセスを許可
sudo ufw allow from
特定のIPアドレスからのアクセスを拒否
sudo ufw deny from
ルールの削除
sudo ufw delete allow <ルール指定> (例: sudo ufw delete allow 22/tcp)
sudo ufw status numbered # ルール番号を表示し、番号で削除: sudo ufw delete <ルール番号>
設定のリセット (すべてのルールを削除し、デフォルトポリシーをリセット)
sudo ufw reset
“`
設定の永続化:
UFWで設定した内容は、自動的に永続化され、システム起動時に読み込まれます。
利点と欠点:
* 利点: 非常に簡単で直感的な操作が可能です。基本的な設定を素早く行うのに適しています。アプリケーションプロファイル(特定のサービスに必要なポート設定の定義)機能があります。IPv4とIPv6の両方に自動的に対応します。
* 欠点: iptablesやnftablesに比べて、設定の柔軟性や表現力に限界があります。複雑なルーティングやNAT、詳細なパケット検査など、高度な設定には向いていません。背後のiptables/nftablesルールを完全に制御したい場合には不向きです。
どのツールを選択すべきか?
どのファイアウォールツールを選択するかは、あなたの目的と経験レベルによって異なります。
- 初心者で、基本的なサービス(SSH, HTTP, HTTPSなど)のアクセス制御だけを行いたい場合: UFW が最も簡単でおすすめです。コマンドが分かりやすく、設定ミスを起こしにくいです。
- より柔軟で高度な設定(特定のフラグを持つパケットの処理、複雑なNAT、レート制限など)を行いたい場合、あるいは iptables の経験がある場合: iptables または nftables を選択します。
- 最新の機能を利用したい、IPv4/IPv6を統一的に扱いたい、大量のルールを効率的に管理したい場合: nftables が将来性があり、より推奨されます。Debianの新しいバージョンを使用している場合、nftablesを学習するメリットは大きいです。
- 既存のシステムが iptables で構築されている場合: 引き続き iptables を使用するか、時間をかけて nftables への移行を検討します。
通常、一つのシステム上でUFWとiptables/nftablesを同時に使用することは避けるべきです。UFWはiptables/nftablesのラッパーであるため、設定の競合や意図しない動作を引き起こす可能性があります。どちらか一つのツールに絞って使用するようにしましょう。
この記事では、最も手軽な UFW を使った基本的な設定から始め、より詳細な設定が可能な iptables と nftables の設定方法についても詳しく解説していきます。
UFW によるファイアウォール設定詳解
UFWは、Debianシステムでファイアウォール設定を行うための最も簡単な方法の一つです。ここでは、UFWのインストールから基本的な設定、そしていくつかの応用的な設定までを詳しく見ていきます。
UFW のインストールと基本操作
UFWは、デフォルトではインストールされていない場合があります。以下のコマンドでインストールできます。
bash
sudo apt update
sudo apt install ufw
インストール後、UFWはデフォルトでは無効な状態です。現在の状態を確認するには ufw status コマンドを使用します。
“`bash
sudo ufw status
Status: inactive
“`
ファイアウォールを有効にする前に、必ずSSHポート(デフォルトはTCP 22番)を許可するルールを追加してください。これを忘れると、ファイアウォール有効化後にSSH接続ができなくなり、サーバーにログインできなくなる可能性があります。
“`bash
SSHポート (例: 22/tcp) を許可するルールを追加
sudo ufw allow 22/tcp
またはサービス名で指定 (推奨、/etc/services に基づく)
sudo ufw allow ssh
“`
ルールを追加したら、以下のコマンドでファイアウォールを有効化します。有効化時に、現在のSSH接続を切断する可能性があるという警告が表示されますが、先ほどSSHポートを許可したルールが正しく追加されていれば問題ありません。
“`bash
sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
“`
これでUFWが有効になり、システムの起動時にも自動的に起動するようになります。現在のルールセットを確認するには、再度 ufw status を実行します。
“`bash
sudo ufw status
Status: active
To Action From
— —— —-
22/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
“`
IPv4とIPv6の両方でルールが追加されていることが分かります。より詳細な情報を表示するには verbose オプションを付けます。
“`bash
sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
— —— —-
22/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
“`
ここで、Default: deny (incoming), allow (outgoing), disabled (routed) と表示されています。これは、着信(incoming)はデフォルトで拒否、送信(outgoing)はデフォルトで許可、転送(routed)はデフォルトで無効になっていることを示しています。このデフォルトポリシーは、後述する方法で変更できます。
ファイアウォールを無効にする場合は、sudo ufw disable コマンドを使用します。これにより、設定されたすべてのルールが無効になりますが、UFWの設定自体はクリアされません。再度 ufw enable とすれば元の設定で有効になります。
UFWの設定を完全に初期状態に戻すには、sudo ufw reset コマンドを使用します。このコマンドは、すべてのルールを削除し、デフォルトポリシーをリセットするため、実行には細心の注意が必要です。特にリモート接続中の場合は、接続が切断される可能性が高いです。
デフォルトポリシーの設定
ufw enable を実行した際のデフォルトポリシーは、通常 deny incoming と allow outgoing です。このポリシーを明示的に設定または変更するには、以下のコマンドを使用します。
“`bash
着信のデフォルトポリシーを拒否に設定 (推奨)
sudo ufw default deny incoming
送信のデフォルトポリシーを許可に設定 (通常はこちらで良い)
sudo ufw default allow outgoing
転送のデフォルトポリシーを設定 (ルーターとして使う場合など)
sudo ufw default deny routed
“`
セキュリティの観点から、着信はデフォルトで拒否しておき、必要なポートだけを明示的に許可する設定が最も安全です。
特定のポートを許可する
サービスを提供するために、外部から特定のポートへのアクセスを許可する必要があります。例えば、Webサーバー (HTTP: TCP 80, HTTPS: TCP 443) やメールサーバー (SMTP: TCP 25, POP3: TCP 110, IMAP: TCP 143など) です。
ポート番号とプロトコルで指定:
“`bash
HTTP (TCP 80) を許可
sudo ufw allow 80/tcp
HTTPS (TCP 443) を許可
sudo ufw allow 443/tcp
DNS (UDP 53) を許可
sudo ufw allow 53/udp
複数のポートを許可する場合 (スペース区切りで複数回実行)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
ポート範囲を許可 (例: TCP 10000番から20000番まで)
sudo ufw allow 10000:20000/tcp
“`
プロトコルを省略した場合、UFWはTCPとUDPの両方を許可するルールを追加します。例えば sudo ufw allow 53 とすると、TCP 53とUDP 53の両方が許可されます。通常はプロトコルを明示的に指定することをおすすめします。
サービス名で指定:
UFWは /etc/services ファイルに定義されている一般的なサービス名を認識します。サービス名を使用すると、ポート番号を覚えていなくてもルールを設定できます。
“`bash
SSH を許可 (通常 22/tcp)
sudo ufw allow ssh
HTTP を許可 (通常 80/tcp)
sudo ufw allow http
HTTPS を許可 (通常 443/tcp)
sudo ufw allow https
“`
使用できるサービス名は、/etc/services ファイルを参照するか、grep -i <サービス名> /etc/services などで確認できます。
特定のIPアドレスからのアクセスを制限/許可する
特定のIPアドレスやネットワークからのアクセスのみを許可したり、逆に特定のIPアドレスからのアクセスを拒否したりすることも可能です。
特定のIPアドレスからの特定ポートへのアクセスを許可:
“`bash
192.168.1.100 からの SSH (22/tcp) アクセスのみを許可
sudo ufw allow from 192.168.1.100 to any port 22 proto tcp
203.0.113.0/24 ネットワークからの HTTPS (443/tcp) アクセスのみを許可
sudo ufw allow from 203.0.113.0/24 to any port 443 proto tcp
“`
to any は、ローカルシステム上のどのIPアドレス(通常はシステムに割り当てられたIP)宛ての通信でもマッチすることを意味します。特定のインターフェースやローカルIPアドレス宛てを指定することも可能ですが、多くの場合 to any で十分です。
特定のIPアドレスからのすべてのアクセスを許可:
“`bash
192.168.1.100 からのすべての着信通信を許可
sudo ufw allow from 192.168.1.100
“`
このルールは、デフォルトポリシーが deny incoming の場合に有効です。
特定のIPアドレスからのアクセスを拒否:
“`bash
203.0.113.200 からのすべての着信通信を拒否
sudo ufw deny from 203.0.113.200
198.51.100.0/24 ネットワークからの SSH (22/tcp) アクセスを拒否
sudo ufw deny from 198.51.100.0/24 to any port 22 proto tcp
“`
これらのルールは、allow ルールよりも前に評価されるように追加する必要があります。UFWはルールの順序を自動的に管理しますが、必要に応じてルール番号を指定して挿入・削除することも可能です。
アプリケーションプロファイルの利用
UFWには「アプリケーションプロファイル」という便利な機能があります。これは、特定のサービスに必要なポート番号の定義をファイルとして管理し、サービス名でまとめて許可・拒否できるようにするものです。/etc/ufw/applications.d/ ディレクトリに定義ファイルが置かれています。
利用可能なアプリケーションプロファイルを確認するには:
“`bash
sudo ufw app list
Available applications:
CUPS
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
Postfix
Postfix SMTPS
Postfix Submission
samba
WWW Full
WWW HTTP
WWW HTTPS
“`
例えば、OpenSSHプロファイルを使用すると、SSHサービスに必要なポートがまとめて許可されます。
“`bash
sudo ufw allow OpenSSH
Rule added
Rule added (v6)
“`
これにより、allow 22/tcp と同じ効果が得られます。プロファイルの詳細を確認するには app info <プロファイル名> コマンドを使います。
“`bash
sudo ufw app info OpenSSH
Profile: OpenSSH
Title: Secure Shell server
Description: OpenSSH is the standard Linux secure shell server.
Ports:
22/tcp
“`
自分でアプリケーションプロファイルを作成することも可能です。例えば、Webサーバーとデータベースサーバーを組み合わせたアプリケーションに必要なポートをまとめて定義する、といった使い方ができます。
ログの設定と確認
ファイアウォールでどのような通信が許可・拒否されているかを確認するために、ログを有効にすることができます。
“`bash
ログレベルを低に設定 (デフォルト)
sudo ufw logging low
ログレベルを高に設定 (より詳細)
sudo ufw logging high
ログを無効にする
sudo ufw logging off
“`
ログは通常 /var/log/syslog または /var/log/kern.log に記録されます。ufw というキーワードでフィルタリングして確認できます。
“`bash
sudo grep ufw /var/log/syslog
または
sudo less /var/log/kern.log
“`
ログを確認することで、不正なアクセス試行や、意図せずブロックされている通信などを特定するのに役立ちます。
設定の確認と削除
設定したルールを確認するには ufw status を使用します。ルールの削除には ufw delete を使用します。削除には、ルールそのものを指定する方法と、ルール番号を指定する方法があります。
“`bash
現在のルールを表示
sudo ufw status
ルール番号付きで表示
sudo ufw status numbered
Status: active
To Action From
— —— —-
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
[ 4] 22/tcp (v6) ALLOW IN Anywhere (v6)
[ 5] 80/tcp (v6) ALLOW IN Anywhere (v6)
[ 6] 443/tcp (v6) ALLOW IN Anywhere (v6)
3番のルール (443/tcp) を削除
sudo ufw delete 3
Deleting rule
Rule deleted
ルール指定で 80/tcp を削除
sudo ufw delete allow 80/tcp
Rule deleted
Rule deleted (v6) # IPv6側も一緒に削除される
“`
ルールを削除した後は、ufw status で意図通りに削除されたか確認しましょう。
高度なUFW設定
UFWは簡単なインターフェースを提供しますが、いくつかの応用的な設定も可能です。
特定のインターフェースへのルール適用:
複数のネットワークインターフェースがあるシステムで、特定のインターフェースにのみルールを適用したい場合があります。
“`bash
eth0 インターフェースへの SSH (22/tcp) アクセスのみを許可
sudo ufw allow in on eth0 to any port 22 proto tcp
eth1 インターフェースからのすべての出力通信を拒否
sudo ufw deny out on eth1 to any
“`
in on <インターフェース名> で入力(着信)インターフェースを、out on <インターフェース名> で出力(送信)インターフェースを指定します。
特定のローカルIPアドレスへのルール適用:
システムに複数のIPアドレスが割り当てられている場合、特定のローカルIPアドレス宛ての通信にのみルールを適用できます。
“`bash
ローカルIP 192.168.1.10 宛ての HTTP (80/tcp) アクセスのみを許可
sudo ufw allow in to 192.168.1.10 port 80 proto tcp
“`
まとめ
UFWは、基本的なファイアウォール設定を手軽に行うのに最適なツールです。インストール、有効化、デフォルトポリシーの設定、ポートやIPアドレスによるルールの追加・削除といった一連の操作を、直感的で分かりやすいコマンドで行えます。まずSSHポートを許可してから有効化すること、そしてデフォルトポリシーを着信拒否に設定することが、安全な運用における重要なポイントです。UFWの機能で要件を満たせる場合は、このツールから始めるのが最もおすすめです。
iptables によるファイアウォール設定詳解
iptablesは、UFWよりも低レベルで、Linuxカーネルのnetfilterフレームワークを直接操作するための強力かつ柔軟なツールです。UFWでは実現できない複雑なルールや、NAT設定などを行う場合に利用されます。
iptables の基本操作
iptablesは通常、Debianシステムにデフォルトでインストールされています。IPv4のルールを操作するには iptables コマンド、IPv6のルールを操作するには ip6tables コマンドを使用します。以降、特別な断りがない限り iptables に焦点を当てますが、ip6tables もほぼ同様の構文で使用できます。
現在のルールの確認:
“`bash
現在のfilterテーブルの全チェーンのルールを表示
sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
verbose オプションで詳細情報 (パケット/バイト数など) を表示
sudo iptables -L -v
numeric オプションでポート番号やIPアドレスを名前に変換せず表示
sudo iptables -L -n
verbose と numeric を組み合わせて表示
sudo iptables -L -v -n
特定のテーブルのルールを表示 (例: natテーブル)
sudo iptables -t nat -L -v -n
“`
デフォルトポリシーが ACCEPT になっている場合、何もルールを追加しなければすべての通信が許可されることになります。セキュリティのためには、デフォルトポリシーを DROP に変更することが推奨されます。
デフォルトポリシーの設定
各チェーンのデフォルトポリシーは、-P オプションで設定します。
“`bash
INPUT チェーンのデフォルトポリシーを DROP に設定
sudo iptables -P INPUT DROP
FORWARD チェーンのデフォルトポリシーを DROP に設定
sudo iptables -P FORWARD DROP # ルーターとして使わないなら推奨
OUTPUT チェーンのデフォルトポリシーを ACCEPT に設定 (多くの場合これで良い)
sudo iptables -P OUTPUT ACCEPT
“`
重要: iptables -P INPUT DROP を実行する前に、SSH接続を維持するためのルール(後述)を必ず追加・確認してください。実行後、SSH接続が切断されると再接続できなくなる可能性があります。
デフォルトポリシーをDROPに変更すると、明示的に許可した通信以外はすべて遮断されるようになります。
基本的なルールの追加 (ACCEPT, DROP, REJECT)
ルールの追加には -A (末尾に追加) または -I (先頭または指定位置に挿入) オプションを使用します。
“`bash
例: INPUT チェーンに、すべての通信を ACCEPT するルールを追加 (通常はデフォルトポリシーで制御するので不要)
sudo iptables -A INPUT -j ACCEPT
例: INPUT チェーンに、すべての通信を DROP するルールを追加 (通常はデフォルトポリシーで制御するので不要)
sudo iptables -A INPUT -j DROP
例: INPUT チェーンに、すべての通信を REJECT するルールを追加
sudo iptables -A INPUT -j REJECT –reject-with icmp-port-unreachable
“`
ターゲットには ACCEPT, DROP, REJECT, LOG などを指定します。REJECT の場合は --reject-with オプションで送信元に返すエラーメッセージを指定できます。
マッチ条件の指定
-A や -I オプションでチェーンを指定した後、-j <ターゲット> オプションの前に、パケットにマッチさせるための条件を指定します。
“`bash
送信元IPアドレスを指定
sudo iptables -A INPUT -s 192.168.1.100 -j ACCEPT # 192.168.1.100 からのすべての着信を許可
sudo iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT # 192.168.1.0/24 ネットワークからのすべての着信を許可
宛先IPアドレスを指定
sudo iptables -A OUTPUT -d 203.0.113.50 -j ACCEPT # 203.0.113.50 へのすべての送信を許可
プロトコルを指定 (-p)
sudo iptables -A INPUT -p tcp -j ACCEPT # すべてのTCP着信を許可
sudo iptables -A INPUT -p udp -j ACCEPT # すべてのUDP着信を許可
sudo iptables -A INPUT -p icmp -j ACCEPT # すべてのICMP着信を許可 (例: pingに応答できるようにする)
ポート番号を指定 (–dport, –sport)
-p オプションと組み合わせて使用します。
sudo iptables -A INPUT -p tcp –dport 22 -j ACCEPT # TCP 22番ポートへの着信を許可 (SSH)
sudo iptables -A INPUT -p tcp –dport 80 -j ACCEPT # TCP 80番ポートへの着信を許可 (HTTP)
sudo iptables -A INPUT -p udp –sport 53 -j ACCEPT # UDP 53番ポートからの応答送信を許可 (DNSクライアントとして使う場合)
ポート範囲を指定 (–dports, –sports)
-m multiport モジュールを使用する必要があります。
sudo iptables -A INPUT -p tcp -m multiport –dports 10000:20000 -j ACCEPT # TCP 10000-20000 ポートへの着信を許可
入力/出力インターフェースを指定 (-i, -o)
sudo iptables -A INPUT -i eth0 -p tcp –dport 22 -j ACCEPT # eth0 インターフェースへの SSH 着信を許可
sudo iptables -A OUTPUT -o eth1 -j ACCEPT # eth1 インターフェースからのすべての送信を許可
“`
これらのオプションを組み合わせて、より具体的なルールを作成します。
ステートフルインスペクション
iptables でステートフルインスペクションを行うには、conntrack または古いバージョンの state モジュールを使用します。conntrack が推奨されます。
“`bash
-m conntrack –ctstate <ステート>
あるいは -m state –state <ステート> (古い形式)
例: 既に確立または関連付けられたコネクションからのすべての着信パケットを許可
sudo iptables -A INPUT -m conntrack –ctstate ESTABLISHED,RELATED -j ACCEPT
例: 新しいコネクションの開始パケットで、TCP 22番ポートへの通信を許可 (SSH)
sudo iptables -A INPUT -p tcp –dport 22 -m conntrack –ctstate NEW -j ACCEPT
“`
ステートフルインスペクションを利用したルールは、デフォルトポリシーをDROPにする場合に非常に重要です。通常、INPUTチェーンの先頭付近に ESTABLISHED,RELATED を許可するルールを置くことで、内部から開始した通信の応答が外部から戻ってくることを許可します。
典型的なINPUTチェーンのルール順序(デフォルトポリシーDROPの場合):
- ループバックインターフェースからの通信を許可 (
-i lo -j ACCEPT) - 既に確立/関連付けられたコネクションからの通信を許可 (
-m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT) - 新しいコネクションで許可したいサービスを指定 (
-p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT,-p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPTなど) - (必要に応じて)特定のIPアドレスからの通信を許可/拒否
- (必要に応じて)ICMP(pingなど)を許可
- どのルールにもマッチしないパケットはデフォルトポリシー(DROP)により破棄される。
設定の永続化 (iptables-persistent)
iptables コマンドで追加したルールは一時的なものです。システム再起動後も設定を維持するには、iptables-persistent パッケージを使用するのが一般的です。
“`bash
インストール
sudo apt update
sudo apt install iptables-persistent netfilter-persistent
インストール中に、現在の iptables/ip6tables の設定を保存するか尋ねられます。
はい と答えると、現在のルールが /etc/iptables/rules.v4 および /etc/iptables/rules.v6 に保存されます。
インストール後に手動で現在の設定を保存する場合
sudo netfilter-persistent save
または
sudo iptables-save > /etc/iptables/rules.v4
sudo ip6tables-save > /etc/iptables/rules.v6
保存された設定はシステム起動時に自動的に読み込まれます。
保存ファイルを手動で編集し、反映させる場合
sudo netfilter-persistent reload
または
sudo iptables-restore < /etc/iptables/rules.v4
sudo ip6tables-restore < /etc/iptables/rules.v6
“`
/etc/iptables/rules.v4 および /etc/iptables/rules.v6 ファイルは、iptables-save コマンドが出力する形式で記述されています。直接編集する際は、構文に誤りがないよう細心の注意が必要です。誤った設定ファイルを読み込むと、ファイアウォールが正しく機能しなくなったり、最悪の場合、サーバーにアクセスできなくなる可能性があります。編集後は、iptables-restore コマンドに -t オプションを付けてファイルをテストするか、本番環境に適用する前にステージング環境などで十分にテストすることをおすすめします。
NAT (Network Address Translation) の概要
iptablesはNAT機能も提供します。これは、パケットの送信元IPアドレスや宛先IPアドレスを変換する機能で、ルーターやゲートウェイとして機能するシステムでよく使用されます。NATは nat テーブルで設定します。
一般的なNATの例は、内部ネットワークからインターネットへの接続を、ルーターのグローバルIPアドレスを使って行う送信元NAT (SNAT)、あるいは単に マスカレード (MASQUERADE) です。
“`bash
内部ネットワーク (例: 192.168.1.0/24) から外部への通信に対して、
外部インターフェース (例: eth0) のIPアドレスに送信元IPを変換する (MASQUERADE)
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
“`
もう一つの一般的なNATは、外部からの特定ポートへのアクセスを内部ネットワークの特定のサーバーに転送する宛先NAT (DNAT) です。これはポートフォワーディングとも呼ばれます。
“`bash
外部インターフェース (例: eth0) への TCP 80番ポートへのアクセスを
内部IPアドレス 192.168.1.100 の TCP 80番ポートに転送する
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -j DNAT –to-destination 192.168.1.100:80
“`
NAT設定はより複雑になるため、ここでは基本的な例のみを示しました。詳細については、iptablesの公式ドキュメントや専門的なガイドを参照してください。
まとめ
iptablesは、非常に強力で柔軟なファイアウォール設定ツールですが、その分コマンドが複雑で、習得には時間がかかります。デフォルトポリシーをDROPに設定し、ステートフルインスペクションを活用しつつ、必要なサービスポートのみを明示的に許可するルールを記述することが、安全なiptables運用の基本です。設定の永続化には iptables-persistent を使用し、設定ファイルの編集や読み込みには細心の注意を払う必要があります。複雑な要件やNATが必要な場合に、iptablesはその真価を発揮します。
nftables によるファイアウォール設定詳解
nftablesは、iptablesの後継として開発された新しいネットフィルタリングツールです。より洗練された構文と改良された機能を提供し、Debian 10以降で推奨されています。
nftables の基本概念と構文
nftablesの設定は、nft コマンドを使用するか、/etc/nftables.conf ファイルに記述して行います。設定は、テーブル、チェーン、ルールという階層構造を持ちます。
テーブル:
ルールセットの最上位のコンテナです。アドレスファミリーとテーブル名を指定して作成します。
* add table <family> <table_name>
* <family>: ip (IPv4), ip6 (IPv6), inet (IPv4 & IPv6), arp, bridge
* list tables: テーブル一覧を表示
チェーン:
パケットが通過する処理の順番です。テーブル内に定義され、タイプ、フック、優先度、デフォルトポリシーを指定します。
* add chain <family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }
* <type>: filter, route, nat
* <hook>: ingress, prerouting, input, forward, output, postrouting
* <priority>: 処理順序の優先度 (数値が小さいほど優先度が高い)
* <policy>: accept または drop
* list chains [<family> <table_name>]: チェーン一覧を表示
ルール:
パケットにマッチさせる条件と、実行するアクション(ステートメント)の集まりです。チェーン内に定義されます。
* add rule <family> <table_name> <chain_name> <match_expressions> <statements>
* list ruleset [<family> <table_name>]: ルールセット全体または特定のテーブルのルールを表示
nftablesの構文は、iptablesと異なり、柔軟な記述が可能です。複数の条件をスペースで区切り、アクションを最後に記述します。
基本的なファイアウォール設定
ここでは、一般的なサーバーで必要となる基本的な設定を、nftablesの構文で見ていきます。デフォルトポリシーをDROPにし、必要なサービスのみを許可するホワイトリスト方式を前提とします。
設定ファイルの作成 (/etc/nftables.conf):
nftablesの設定は、/etc/nftables.conf ファイルに記述するのが最も一般的です。このファイルはシステム起動時に nftables.service によって読み込まれます。
“`nft
!/usr/sbin/nft -f
ルールセットをクリア (既存のルールを全て削除)
flush ruleset
—– テーブルとチェーンの定義 —–
IPv4とIPv6共通のフィルタリング用テーブルとチェーンを定義
アドレスファミリーに ‘inet’ を使うことで、IPv4とIPv6両方のパケットがこのチェーンを通過します。
table inet filter {
# input チェーン: ローカルシステム宛てのパケット
chain input {
type filter hook input priority 0; policy drop; # デフォルトポリシー: DROP
# 既に確立/関連付けられたコネクションからのパケットを許可
# 'ct state' は iptables の '-m conntrack --ctstate' に相当
ct state established,related accept
# ループバックインターフェースからの通信を許可
# 'iifname' は入力インターフェース名にマッチ
iifname "lo" accept
# ICMP (Ping) を許可 (任意 - ネットワーク診断に便利)
# protocol icmp accept # IPv4 ICMP
# meta l4proto icmpv6 accept # IPv6 ICMP
# ----- 許可するサービスポートの定義 -----
# SSH (TCP 22) への通信を許可
# tcp dport は TCP宛先ポートにマッチ
tcp dport 22 accept
# HTTP (TCP 80) への通信を許可
tcp dport 80 accept
# HTTPS (TCP 443) への通信を許可
tcp dport 443 accept
# 例: 別のサービス (UDP 123 - NTP) を許可
# udp dport 123 accept
# 例: 特定のIPアドレス (192.168.1.100) からのSSHアクセスのみを許可
# ip saddr 192.168.1.100 tcp dport 22 accept
# 例: 特定のネットワーク (192.168.1.0/24) からのHTTP/HTTPSアクセスのみを許可
# ip saddr 192.168.1.0/24 tcp dport { 80, 443 } accept
# 例: 複数のポートをまとめて許可
# tcp dport { 22, 80, 443 } accept
# 例: ポート範囲を許可
# tcp dport 10000-20000 accept
# 例: 特定のインターフェース (eth0) へのアクセスのみに限定
# iifname "eth0" tcp dport 22 accept
# ----- ルールにマッチしなかったパケット -----
# ここより下にルールを追加しなければ、policy drop が適用される。
# 必要に応じて、ログを残すルールなどを追加できる。
# counter log prefix "NFTABLES_DROP: " # ドロップされるパケットをログに記録
}
# forward チェーン: このシステムを経由するパケット (ルーターとして使う場合)
chain forward {
type filter hook forward priority 0; policy drop; # ルーターとして使わないなら DROP
# 必要に応じて転送ルールを追加
}
# output チェーン: ローカルシステムから送信されるパケット
chain output {
type filter hook output priority 0; policy accept; # 通常は送信を許可
# 必要に応じて送信ルールを制限
# Examples:
# 外部DNSサーバー (UDP 53) への送信のみ許可
# ip daddr { 8.8.8.8, 8.8.4.4 } udp dport 53 accept
# それ以外のUDP送信は拒否
# udp reject
}
}
必要に応じて、他のアドレスファミリー (arp, bridge) や他のテーブル (nat, route) を定義
table ip nat { … }
table ip6 nat { … }
table ip route { … }
“`
設定の適用と永続化:
設定ファイルを編集したら、まず構文に誤りがないかテストします。
bash
sudo nft -c -f /etc/nftables.conf
-c オプションはチェックのみを行い、ルールは適用されません。問題がなければ、設定を適用します。
bash
sudo nft -f /etc/nftables.conf
このコマンドで設定を読み込むと、現在のルールセットがファイルの内容で置き換えられます。
システム起動時に自動的にこの設定が適用されるようにするには、nftables.service を有効化します。
bash
sudo systemctl enable nftables.service
sudo systemctl start nftables.service
これにより、システムの起動時に /etc/nftables.conf ファイルが自動的に読み込まれるようになります。
ステートフルインスペクション (ct)
nftablesでは、ct オブジェクトを使用してステートフルインスペクションを行います。iptablesの state または conntrack モジュールに相当します。
“`nft
既に確立または関連付けられたコネクションからのパケットを許可
ct state established,related accept
新しいTCPコネクションの確立パケットを許可
ct state new tcp dport 22 accept # TCP 22番への新規コネクションのみ許可
“`
一般的な設定では、input チェーンの先頭に ct state established,related accept のルールを置き、その後に ct state new と目的のポート番号を組み合わせたルールを配置します。
セットとマップ
nftablesの強力な機能の一つに、セット(sets)とマップ(maps)があります。これらを使用すると、複数のIPアドレスやポート番号を効率的にグループ化し、ルールを簡潔に記述できます。特に、大量のIPアドレスからのアクセスを許可/拒否する場合にパフォーマンスが向上します。
セットの例:
特定のIPアドレス群からのSSHアクセスを許可する場合。
“`nft
テーブル内にセットを定義
table inet filter {
set allowed_ssh_ips {
type ipv4_addr; # 格納する要素の型 (IPv4アドレス)
flags constant; # 要素は静的であることを示す (パフォーマンス向上)
elements = { 192.168.1.10, 192.168.1.11, 192.168.2.0/24 } # 許可するIPアドレス/ネットワーク
}
chain input {
...
# セットを使ってルールを記述
ip saddr @allowed_ssh_ips tcp dport 22 accept
...
}
}
“`
セットを使用することで、ルールの数を減らし、管理を容易にできます。
マップの例:
宛先ポート番号に応じて、異なるターゲットにジャンプする場合。
“`nft
table ip filter {
map service_chain {
type inet_service : verdict; # 入力: ポート番号、出力: アクション
elements = {
22 : jump ssh_chain,
80 : jump http_chain,
443 : jump https_chain
}
}
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
# 宛先ポート番号をマップで検索し、対応するチェーンにジャンプ
tcp dport . verdict map @service_chain counter
# マップにマッチしないTCPパケットはここでドロップされる (デフォルトポリシー)
}
# 各サービス用のユーザー定義チェーン
chain ssh_chain {
# SSH サービスに固有のルール (例: レート制限など)
accept
}
chain http_chain {
accept
}
chain https_chain {
accept
}
}
“`
マップを使用すると、複雑な条件分岐を含むルールセットをより構造的に記述できます。
iptables から nftables への移行
既存のiptables設定をnftablesに移行する場合、iptables-translate コマンドを使用すると、iptablesのルールをnftablesの構文に変換できます。
“`bash
iptablesのルールをnftables構文に変換
sudo iptables-translate -A INPUT -p tcp –dport 22 -j ACCEPT
nft add rule ip filter INPUT tcp dport 22 accept
現在のiptablesルールセット全体をnftables構文に変換 (ファイルに出力)
sudo iptables-save | iptables-translate > /tmp/nft_rules.conf
“`
ただし、iptables-translate は全てのiptablesルールを正確に変換できるわけではありません。変換されたルールセットは、そのまま使用するのではなく、内容を十分に確認し、必要に応じて手動で修正する必要があります。特に複雑なモジュールやNAT設定は注意が必要です。
まとめ
nftablesは、iptablesに比べてモダンで柔軟なファイアウォールツールです。統一された構文、IPv4/IPv6共通のルール記述、セットやマップといった高度な機能により、大規模で複雑なルールセットも効率的に管理できます。学習コストはかかりますが、今後のLinuxファイアウォールの主流となることが予想されるため、習得する価値は十分にあります。設定は /etc/nftables.conf ファイルに記述し、nft コマンドや systemctl で管理するのが標準的な方法です。
共通の考慮事項とベストプラクティス
ファイアウォールを設定する際には、使用するツールに関わらず考慮すべき共通の事項と、推奨されるベストプラクティスがあります。
SSH ポートの重要性
最も重要な注意点の一つは、SSH ポート(デフォルトはTCP 22番)へのアクセスを誤って遮断しないことです。特にリモートで作業しているサーバーの場合、SSHアクセスを失うと、物理的にサーバーにアクセスしない限り復旧が困難になる可能性があります。
- ファイアウォールを有効化したり、デフォルトポリシーをDROPに変更したりする前に、必ずSSHポートを許可するルールが正しく設定されていることを確認してください。
- 可能であれば、リモート作業とは別のセッション(例えば、別のターミナルやコンソール)で作業し、設定変更後にSSH接続が維持されていることを確認します。あるいは、設定ミスで接続が失われた場合に備えて、一定時間後にファイアウォール設定を自動的にリセットするスクリプトなどを準備しておくことも有効です。
- SSHポートをデフォルトの22番から変更する、鍵認証を使用する、Fail2banなどの侵入検知システムと組み合わせるなど、SSH自体のセキュリティ対策も併せて行うことを強く推奨します。
ファイアウォールルールのテスト方法
設定したファイアウォールルールが意図通りに機能しているかを確認することは非常に重要です。
- 疎通確認:
pingコマンドでICMP通信、telnet <ホスト名またはIP> <ポート番号>やnc -zv <ホスト名またはIP> <ポート番号>コマンドで特定のポートへのTCP/UDP通信が可能か確認します。 - サービスからの確認: 設定したサービス(Webサーバー、SSHサーバーなど)に、別のシステムから実際に接続して、正常に利用できるか確認します。
- ファイアウォールログ: ログ機能を有効にし、想定外のパケットがブロックされていないか、あるいはブロックされるべきパケットが通過していないかログを監視します。
- ルールセットの確認:
ufw status,iptables -L -v -n,nft list rulesetコマンドで、設定したルールが正しくリストアップされているか確認します。特にiptablesやnftablesでは、ルールの順序が重要になるため、意図した順序でルールが並んでいるか確認します。
ログの監視と分析
ファイアウォールのログは、システムのセキュリティ状態を把握する上で貴重な情報源です。
- ファイアウォールログを有効にし、定期的に確認する習慣をつけましょう。
- 大量のブロックログがある場合は、不正なアクセス試行が行われている可能性を示唆します。特定の送信元IPアドレスからの不審なアクセスが多い場合は、そのIPアドレスからの通信を明示的に拒否するルールを追加することも検討できます。
- システムのログ管理システム(rsyslog, journaldなど)と連携させ、ログの集約や分析を行うと、より効果的にセキュリティ状況を把握できます。
サービスごとの必要なポート確認
サーバー上で稼働している各サービスが、外部からのアクセスや外部への接続のためにどのポートを使用しているかを正確に把握する必要があります。一般的なサービスのポート番号は以下の通りですが、設定によっては変更されている場合もあります。
- SSH: TCP 22
- HTTP (Web): TCP 80
- HTTPS (SSL/TLS付きWeb): TCP 443
- SMTP (メール送信): TCP 25 (サーバー間), TCP 587 (クライアント送信), TCP 465 (SMTPS)
- POP3 (メール受信): TCP 110, TCP 995 (POP3S)
- IMAP (メール受信): TCP 143, TCP 993 (IMAPS)
- DNS (名前解決): TCP/UDP 53
- FTP: TCP 21 (制御), TCP 20 または動的ポート範囲 (データ) – FTPは状態管理が特殊なため、ファイアウォール設定に注意が必要
- NTP (時刻同期): UDP 123
- Samba/CIFS (ファイル共有): TCP 139, 445, UDP 137, 138
不明な場合は、サービスのドキュメントを確認するか、netstat -tulnp コマンドなどで現在リッスンしているポートを確認します。
デフォルトポリシーは DROP が安全
セキュリティの基本的な考え方として、「必要なものだけを許可し、それ以外は全て拒否する(ホワイトリスト方式)」が推奨されます。ファイアウォールにおいては、各チェーンのデフォルトポリシーを DROP に設定し、その上で明示的に許可するルールを追加するというアプローチがこれに該当します。
デフォルトポリシーが ACCEPT の場合、「拒否したい通信だけを明示的に拒否する(ブラックリスト方式)」となりますが、これは未知の攻撃や新しいサービスへのアクセスを防ぐことが難しいため、一般的に非推奨です。
定期的なルールセットの見直しと更新
システムの運用状況は変化します。新しいサービスを導入したり、不要になったサービスを停止したりする際には、ファイアウォールルールセットも併せて見直し、必要に応じて更新する必要があります。不要なポートが開いたままになっていると、セキュリティリスクとなります。
IPv4 と IPv6 の両方に対応する
現代のインターネットでは、IPv4とIPv6の両方が使用されています。ファイアウォール設定を行う際には、IPv4だけでなくIPv6のトラフィックについても適切に制御する必要があります。UFWはIPv4/IPv6の両方に自動的に対応しますが、iptablesを使用する場合は iptables と ip6tables の両方でルールを設定する必要があります。nftablesの inet ファミリーを使用すると、一つのルールでIPv4/IPv6両方に対応できます。
Docker や他のコンテナ環境との連携
Dockerなどのコンテナ環境を使用している場合、コンテナのネットワーク設定がホストのファイアウォールルールに影響を与えることがあります。Dockerはデフォルトで独自のiptablesルールを追加/変更することがあり、これが手動で設定したルールと競合したり、意図しないポートが公開されたりする可能性があります。
Docker環境でファイアウォールを設定する際は、Dockerのドキュメントを確認し、ホストのファイアウォール(UFW/iptables/nftables)とDockerがどのように連携するかを理解することが重要です。UFWにはDockerとの連携に関する設定オプションが用意されている場合があります。iptables/nftablesを使用する場合は、Dockerが追加するチェーンやルールを理解し、それらに影響を与えない、あるいは連携するようなルールを記述する必要があります。
クラウド環境でのセキュリティグループとの関係
AWSのセキュリティグループやGCPのファイアウォールルールなど、クラウドプロバイダーが提供する仮想ファイアウォール機能を使用している場合、Debianシステム上のファイアウォールはこれらの外側のファイアウォールと組み合わせて使用することになります。
クラウドの仮想ファイアウォールは、サーバーに到達する前の段階でトラフィックをフィルタリングします。これにより、不要なトラフィックがサーバーに到達する前にブロックされ、サーバーのリソース負荷を軽減し、攻撃対象領域を減らすことができます。
Debianシステム上のファイアウォールは、クラウドの仮想ファイアウォールを通過した後のトラフィックに対して、より詳細なフィルタリングやローカルでのルール適用(例: 特定のプロセスやユーザーへの制限)を行います。両方のファイアウォールを連携させて設定することが、多層防御の観点から推奨されます。一般的には、クラウド側のファイアウォールで大まかなアクセス制御を行い、OS側のファイアウォールでより細かい制御を行うという役割分担が考えられます。
トラブルシューティング
ファイアウォール設定は、設定ミスがシステムへのアクセス障害に直結するため、トラブルシューティングの手順を事前に理解しておくことが重要です。
アクセスできない場合の切り分け手順
特定のサービスにアクセスできなくなった場合、原因がファイアウォールであるかを切り分けるための一般的な手順です。
- ファイアウォール以外の要因を確認:
- サービス自体が実行されているか (
systemctl status <サービス名>) - サービスが正しいポートでリッスンしているか (
netstat -tulnp) - ネットワーク経路に問題がないか (
ping,traceroute) - サーバー側のサービス設定(設定ファイル、仮想ホストなど)に問題がないか
- クライアント側の設定に問題がないか
- サービス自体が実行されているか (
- ファイアウォールの状態を確認:
- UFW:
sudo ufw status verbose - iptables:
sudo iptables -L -v -n,sudo ip6tables -L -v -n - nftables:
sudo nft list ruleset
ファイアウォールが有効になっているか、目的の通信を許可するルールが存在するか、ルールが正しい順序になっているかなどを確認します。デフォルトポリシーが適切かどうかも確認します。
- UFW:
- ファイアウォールログを確認:
- ログが有効になっている場合、ログファイル (
/var/log/syslog,/var/log/kern.logなど) に、目的の通信がファイアウォールによってブロックされたことを示すログが出力されていないか確認します。
- ログが有効になっている場合、ログファイル (
- ファイアウォールを一時的に無効にする:
- 注意: これはセキュリティリスクを伴うため、トラブルシューティング目的以外では行わないでください。可能であれば、物理的にアクセスできる環境で行うか、安全な時間帯に行ってください。
- UFW:
sudo ufw disable - iptables:
sudo iptables -F,sudo iptables -X,sudo iptables -t nat -F,sudo iptables -t nat -X,sudo iptables -P INPUT ACCEPT,sudo iptables -P FORWARD ACCEPT,sudo iptables -P OUTPUT ACCEPT(iptables-persistent を使用している場合は、保存された設定を読み込まないようにサービスを停止することなども検討) - nftables:
sudo nft flush ruleset
ファイアウォールを無効にした状態でアクセスできるようになった場合、原因はファイアウォール設定にある可能性が高いです。
- 設定を慎重に見直す:
ファイアウォール設定が原因であると特定できた場合、有効にした状態でアクセスできないサービスに必要なポートやプロトコル、IPアドレスなどの条件を、設定ファイルやコマンド出力と照らし合わせて慎重に見直します。ルールの順序も確認が必要です。
ファイアウォールログの確認
ログはトラブルシューティングの強力なツールです。
- UFW:
sudo grep ufw /var/log/syslogなどでログを確認します。ufw loggingコマンドでログレベルを調整できます。 - iptables:
iptables -A <チェーン> ... -j LOGのようにLOGターゲットを持つルールを追加することで、特定のパケットをログに記録できます。ログは通常/var/log/syslogや/var/log/kern.logに出力されます。 - nftables: ルールに
log prefix "..."ステートメントを追加することでログを記録できます。ログはiptablesと同様にシステムログに出力されます。
ログには、ブロックされたパケットの情報(送信元/宛先IP、ポート、プロトコル、インターフェースなど)が含まれており、どの通信がなぜブロックされたのかを特定するのに役立ちます。
デバッグ目的での一時的なファイアウォール停止
前述の通り、ファイアウォールの一時的な停止はセキュリティリスクを伴いますが、トラブルシューティングの最終手段として有効な場合があります。停止する際は、その期間を最小限にし、原因特定後は速やかに適切な設定に戻すことが重要です。
UFW の停止と再開:
“`bash
sudo ufw disable # 停止
… トラブルシューティング …
sudo ufw enable # 再開 (元の設定が復元される)
“`
iptables の全ルール削除とデフォルトポリシーの変更:
“`bash
sudo iptables -F # filterテーブルのルールをクリア
sudo iptables -X # ユーザー定義チェーンを削除
sudo iptables -t nat -F # natテーブルのルールをクリア (NATを使用している場合)
sudo iptables -t nat -X # natテーブルのユーザー定義チェーンを削除
必要に応じて他のテーブル (mangle, raw) も同様にクリア/削除
sudo iptables -P INPUT ACCEPT # INPUTチェーンのデフォルトポリシーを許可に
sudo iptables -P FORWARD ACCEPT # FORWARDチェーンのデフォルトポリシーを許可に
sudo iptables -P OUTPUT ACCEPT # OUTPUTチェーンのデフォルトポリシーを許可に
ip6tables も同様に行う
元の設定に戻す (iptables-persistent を使用している場合)
sudo netfilter-persistent reload
“`
この手順は、現在の全ルールを削除するため、実行には十分な注意が必要です。
nftables の全ルールクリア:
“`bash
sudo nft flush ruleset # 全てのテーブルとチェーン、ルールをクリア
元の設定に戻す (/etc/nftables.conf を読み込む)
sudo nft -f /etc/nftables.conf
“`
ルールのバックアップとリストア
設定ミスに備えて、ファイアウォールルールのバックアップを定期的に取ることは非常に重要です。
- UFW: UFWの設定ファイルは
/etc/ufw/ディレクトリ以下にありますが、これらを直接編集するよりも、ufw status > ufw_rules.txtのように現在のルールセットをテキストファイルに保存しておく方が、内容の把握には便利です。設定を復元するにはufw resetで初期化後、テキストファイルを見ながらコマンドを再実行する必要があります。 - iptables:
sudo iptables-save > iptables_rules.v4およびsudo ip6tables-save > iptables_rules.v6でルールセットをファイルに保存します。復元はsudo iptables-restore < iptables_rules.v4およびsudo ip6tables-restore < iptables_rules.v6で行います。iptables-persistentパッケージを使用している場合は、/etc/iptables/rules.v4および/etc/iptables/rules.v6が自動的に使用されます。 - nftables:
sudo nft list ruleset > nftables_rules.confでルールセットをファイルに保存します。復元はsudo nft -f nftables_rules.confで行います。設定ファイルとして/etc/nftables.confを使用している場合は、そのファイルを適切にバックアップします。
定期的にバックアップを作成し、安全な場所に保管しておきましょう。
まとめ
この記事では、Debianシステムにおけるファイアウォール設定について、主要なツールであるUFW、iptables、そしてnftablesの詳細な設定方法を解説しました。
- UFW は、最も手軽で分かりやすいインターフェースを提供します。基本的なサービス公開やIPアドレス制限など、複雑でない要件であればUFWが最適です。まずSSHポートを許可し、デフォルトポリシーをDROPに設定してから有効化することが安全な使い始めのポイントです。
- iptables は、長年の実績があり、非常に柔軟かつ詳細な設定が可能です。NATや高度なパケットマッチングなど、UFWでは実現できない複雑な要件に対応できます。コマンド構文は難解ですが、ステートフルインスペクションを活用し、デフォルトポリシーをDROPにするのが基本的な安全な設定アプローチです。設定の永続化には
iptables-persistentが役立ちます。 - nftables は、iptablesの後継として開発され、よりモダンで統一された構文、優れたパフォーマンス、そしてセットやマップといった強力な機能を提供します。IPv4とIPv6を統一的に扱える
inetファミリーは大きな利点です。今後の主流となることが予想され、複雑なルールを効率的に管理したい場合に推奨されます。設定は/etc/nftables.confに記述し、nftコマンドで管理します。
どのツールを選択するにしても、ファイアウォールは多層防御の一部であり、これだけでシステムが完全に安全になるわけではないことを理解しておく必要があります。OSやアプリケーションのセキュリティパッチ適用、安全なパスワードポリシー、サービスごとのセキュリティ設定、侵入検知システム(IDS/IPS)、定期的なセキュリティ監査など、他のセキュリティ対策と組み合わせて実施することが重要です。
また、ファイアウォール設定はシステムの可用性にも直接影響を与えるため、設定変更は慎重に行い、必ず変更内容をテストし、問題発生時の復旧手順を事前に確認しておく必要があります。特にリモートで作業している場合は、SSH接続を失わないように細心の注意を払ってください。
ファイアウォール設定は一度行えば終わりではなく、システムの構成や運用状況の変化に合わせて、定期的に見直し、更新していく必要があります。この記事が、Debianシステムをより安全に運用するための第一歩となることを願っています。継続的な学習と実践を通じて、あなたのシステムのセキュリティレベルを維持・向上させていきましょう。
付録
よく使われるポート番号リスト
| ポート番号 | プロトコル | サービス名 | 説明 |
|---|---|---|---|
| 20 | TCP | ftp-data | FTPデータ接続 |
| 21 | TCP | ftp | FTP制御接続 |
| 22 | TCP | ssh | Secure Shell |
| 25 | TCP | smtp | Simple Mail Transfer Protocol (サーバー間) |
| 53 | TCP/UDP | domain | Domain Name System (DNS) |
| 80 | TCP | http | Hypertext Transfer Protocol (Web) |
| 110 | TCP | pop3 | Post Office Protocol version 3 |
| 143 | TCP | imap | Internet Message Access Protocol |
| 443 | TCP | https | HTTP over TLS/SSL (HTTPS) |
| 465 | TCP | smtps | SMTP over TLS/SSL |
| 587 | TCP | submission | メール送信クライアント |
| 993 | TCP | imaps | IMAP over TLS/SSL |
| 995 | TCP | pop3s | POP3 over TLS/SSL |
これは一部の例です。より詳細なリストは /etc/services ファイルを参照してください。
参考文献・公式ドキュメント
- Debian Wiki – iptables: https://wiki.debian.org/iptables
- Debian Wiki – nftables: https://wiki.debian.org/nftables
- Debian Wiki – UFW: https://wiki.debian.org/UFW
- netfilter.org (iptables, nftables, conntrackなど): https://www.netfilter.org/
- nftables Wiki: https://wiki.nftables.org/
- UFW Documentation (Ubuntu DocumentationですがDebianでも参考になります): https://ubuntu.com/server/docs/security-firewall
公式ドキュメントは最新かつ正確な情報源ですが、専門的であるため、まずは基本的なガイドや記事で概要を掴み、詳細を確認する際に参照するのが良いでしょう。