Debian(Linux)のiptables
iptablesはLinuxのパケットフィルタリングおよびアドレス変換アプリです。前者はファイアウォールという言葉で置き換えるとわかりやすいと思います。不要な通信を遮断することによりPCのセキュリティを向上させます。後者は市販のIPv4ルーターにおいて、NATやNAPTと呼ばれる機能に相当します。
追記
Debian10から iptables にかえて nftables の利用が推奨されています。 nftabls については別記事でまとめていますのでそちらも合わせて参照していただけると幸いです。
iptablesのインストール
多くの環境でOSと同時にインストールされていることが多いですが、まず、iptablesをインストールするところから始めます。
また、通常iptablesの設定はPCの電源を切ると消えてしまいます。それを永続させるためのツールにiptables-persistentがありますので同時にインストールします。
# apt update ... # apt install iptables iptables-persistent ...
現在のiptableの状態の確認
ファイアウォールの状態は次のコマンドで確認できます。何も設定していないと初期段階では次の3行が表示されると思います。
# 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
上記はIPv4のポリシーですが、コマンドのiptablesの部分をip6tablesにするとIPv6におけるポリシーが表示されます。このコマンドの置き換えのルールはほとんどの入力において有効です。
iptablesのポリシー
iptablesにはポリシーと呼ばれる基本設定があります。 先の例示で出力されたのはそのポリシーの部分です。すべて「ACCEPT」で「許可」になっているのが確認できます。つまり、初期段階ではなにも制限をしていません。
- INPUT(PCに入ってくるデータを受け入れるか否か)
- OUTPUT(PCから出ていくデータを受け入れるか否か)
- FORWARD(転送データを受け入れるか否か)
このINPUT、OUTPUT、FOWARDによる区分けをチェインと呼びます。
このiptablesのポリシーを変更します。使用環境によって設定は違いますが、一般的な設定はINPUTとFORWARDのポリシーはDROP、OUTPUTがACCEPTです。
iptablesでポリシーを設定するには-Pオプションを利用します。オプションのあとの引数は、チェイン(INPUT,OUTPUT,FORWARD)と、ターゲット(DROP,ACCEPT,他)となります。
デフォルトでACCEPTが設定されていますので、ここであはFORWRDとINPUTにDROPを設定します。
【注意】リモート環境でINPUTのポリシーをDROPにすると接続が失われますので注意してください。先にリモートアドレスや、SSH(22)などのポート番号で許可のルールを設定しておくか、慣れないうちは実機で操作するのをお勧めします。
# iptables -P FORWARD DROP # iptables -P INPUT DROP
ルール
iptablesはポリシーと、ルールによって成り立っています。ルールはINPUTやOUTPUT等のチェイン単位でチェックされます。ひとつのチェーンに複数のルールを設定することができます。
INPUT、OUTPUT、FOWARDのチェイン別にルールを設定します。設定したルールにひとつも当てはまらなかった場合に、先に設定したデフォルトのターゲットが採用されます。
たとえば、INPUTのポリシーをDROPにしても接続が失われないよう、プライベートアドレスからのINPUTはすべて許可するには次のようにルールを設定します。-sオプションは送信元指定するもので、それにプライベートアドレスのネットワークアドレスを設定しています。-jオプションはターゲットの指定でここではACCEPT(許可)にしています。
# iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT # iptables -A INPUT -s 172.16.0.0/12 -j ACCEPT # iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
先の例だと、クラウドサービス等でリモート接続している場合は効果がありません。実際の運用には向かない設定ですが、インターネット上のサーバーとSSH接続を許可するには-pオプションでプロトコルをtcpに指定し、--dportで宛先のポート(SSHのデフォルトは22)を指定します。
--dportオプションは、「-p tcp(またはudp)」指定時に利用可能です。もしポートの範囲を指定したい場合は10:20等コロンで区切ることで可能です。複数指定したい場合は、-mでmultiport拡張モジュールを指定した上で,で区切ります。(例 -p tcp -m multiport --sport 137,138,139)
-mで指定する拡張モジュールは指定した内容に一致するかをboolean値で返します。
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
実運用を考えているなら、筆者がクラウドサーバーで利用しているファイアウォールの設定をリンク先で紹介していますのでよろしかったら合わせてご覧ください。iptablesのtableやチェインのチェックが行われるかという図表も紹介しています。
別の例として、iptableを設定したPCに、enp1s0、enp2s0というIPフォワードするNICがあり、特定のPC(192.168.102.252)との送受信データの転送を許可する場合は次のように入力します。
-Aオプションでポリシーの追加、そのあとにチェイン、-iオプションはNICを指定するオプション、-dオプションは送信先です。
# iptables -A FORWARD -i enp1s0 -s 192.168.102.252 -j ACCEPT # iptables -A FORWARD -i enp2s0 -d 192.168.102.252 -j ACCEPT
-Aで追加したルールはそのチェーンの一番最後に加わります。チェックする際は上からチェックしていき最初に合致したものが採用されます。なので-Aの代わりに-Iオプションを使って特定のルールの間に挿入することもできます。-Iオプションは順序をチェインの後の引数に持てます。省略した場合は最初を意味する1を設定したのと同じになります。
# # FORWARDチェインの2番目に挿入 # iptables -I FORWARD 2 -i enp2s0 -d 192.168.102.253 -j ACCEPT
ルールを削除したい場合は、-Aのかわりに-Dオプションを指定します。以降に設定した引数と合致するルールがあった場合は削除されます。
削除時に行番号を指定したい場合は「iptables -L [チェイン] --line-numbers」とすると行番号が付与された状態でルールが表示されるので、それを利用できますが、ひとつ削除すると以降のルール番号は切り詰められますので注意してください。
-Lオプションでの表示時はチェインを省略すると、全てのチェインを対象にチェイン毎の番号が表示されますが、削除を指定する場合はチェインの指定は必須です。
iptables -L --line-numbers Chain INPUT (policy DROP) num target prot opt source destination 1 ACCEPT all -- anywhere anywhere 2 DROP tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,PSH,ACK ... Chain FORWARD (policy DROP) ... Chain OUTPUT (policy ACCEPT) ... # iptables -D INPUT 17
また、-Aオプションでの追加時に既存のものと同じ設定が存在した場合も新規に追加されてしまいます。入力したいルールが存在するかどうかをチェックするには-Cオプションを使います。引数は-Aや-Dと同じです。存在すれば合致したルールが戻り、存在しない場合はエラーが戻ります。
さらに、-Lオプションで表示した一覧は、インターフェース等の情報が省略されています。表示するには-vオプションで詳細モードにすることで表示されます。
iptables-persistentとの連携
iptables-persistentをインストールすると、/etc/iptablesディレクトリにrules.v4とrules.v6というファイルができます。v4とv6はバージョンです。PC起動時はここからデータを取得してファイアウォールが設定されます。
iptables-save(ip6tables-save)コマンドでデータを標準出力に出力します。このコマンドからのリダイレクトでiptables-persistent用のファイルに出力することで、現在のiptablesの設定を保存できます。再起動時に読み込む必要がなければ、任意の場所にファイルとして保存しておくことも可能です。
# iptables-save>/etc/iptables/rules.v4 # #保存した内容表示 # cat /etc/iptables/rules.v4 # Generated by iptables-save v1.8.7 on Mon Jan 24 19:13:55 2022 *filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] COMMIT # Completed on Mon Jan 24 19:13:55 2022
[0:0]の部分が気になるかもしれません。これは順にパケット数と、バイト数を表します。それぞれのポリシーに対してルールを設定しましたが、その記述されたルールに一致した通信パケット数とバイト数が入ります。
保存済みデータからiptalbesにデータを戻す時はiptables-restore(ip6tables-restore)を使います。こちらは標準入力からの復元となっているので、ファイルを指定する際は<を使います。
# iptables-restore</etc/iptables/rules.v4
また「netfilter-persistent reload」とコマンドを入力することで、/etc/rules.v*にある設定済みファイルからの復元ができますが、こちらはIPv4、IPv6同時に復元されます。
いままでiptablesで始まっていたコマンドが唐突に、netfilterになってしまいましたが、インフラまわりのプロになりたい:「Nmap の前に iptables を知る」によれば、iptablesはnetfilterのフロントエンドなんだそうです。
rules.v4やrules.v6ファイルは直接編集することもでき、そうした場合には「netfilter-persistent reload」を修正結果の反映に利用します。
nat
前述の「cat /etc/iptables/rules.v4」コマンドの表示結果の中に*filterという表記があったと思います。これは、filterテーブルという意味です。
filterとは今まで設定してきたファイアウォールの機能を指します。
最初に述べたようにiptableにはNATの機能もあります。それにあたるのがnatテーブルになります。デフォルトでPREROUTING(ルーティング前)、INPUT、OUTPUT、POSTROUTING(ルーティング後)のチェーンがあります。
このほかテーブルには、mangleやrawやsecurityなどがあります。
ここまでiptablesの設定は-tオプションを省略した書き方になっていました。-tオプションではテーブルを指定しますが、省略した時はfilterとなります。
ここでは、-tオプションにnatを指定して、EZ-NET:「NAPT を使ってインターネットへの接続環境を提供する」を参考にして、家庭用のIPv4ルーターによくあるようなNAPT(-j MASQUERADE)の設定をしてみます。
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ppp0 -j MASQUERADE
natの設定を確認する際もテーブルオプションを付与します。
# iptables -t nat -L Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 192.168.1.0/24 anywhere
オリジナルのチェイン
-jオプションで設定可能なターゲットはACCEPTとDROPの他、RETURNというものがあります。この説明には「チェインをたどるのを中止して、呼び出し元のチェインに戻る」とあります。
どういうことかというと、通常存在するINPUTやOUTPUTなどの他にオリジナルのチェインを作ることができ、そのチェインはターゲットとして設定することが可能です。チェインがターゲットとなっている場合は、そこに設定されたルールのチェックをするのですが、その途中でチェックを中断して元のチェックに戻るのがRETURNです。
# DEBUGというチェインを作成 # iptables -N DEBUG # # ルールに追加 送信元が 192.168.1.1だったら戻る # # (ネットワーク単位のDROPに例外を設けています) # iptables -A DEBUG -s 192.168.1.1 -j RETURN # iptables -A DEBUG -s 192.168.1.0/24 -j DROP # iptables -A FORWARD -d 192.168.101.0/24 -j DEBUG # #リストの確認 # iptablse -L ... Chain DEBUG (1 references) target prot opt source destination RETURN all -- 192.168.1.1 anywhere DROP all -- 192.168.1.0/24 anywhere
オリジナルのチェインがある状態で、-Lオプションでリストを表示させると、「n references」という形でオリジナルチェインを参照している数が表示されます。
オリジナルのチェインにはポリシーは設定できません。また削除する場合は-Xオプションで可能ですが、どこからも参照されていないことと、ルールが空になっていることが条件です。
チェインのルールを全削除する場合は、-Fオプションを使うと便利です。
ちなみにiptablesの全設定を初期化したい場合は先にINPUT、OUTPUT、FORWARDのポリシーををすべてACCEPTにしてから、それぞれのチェインを-Fオプションで初期化していかないと、ルールでACCEPTとなっている接続が失われる可能性があるので、場合によってはリモートからの接続が不可能になります。気を付けてください。
参考にさせていただきましたサイトの皆様、ありがとうございました。