プロローグ
iptables。得意技はパケットフィルタとネットワークアドレス変換だ。
RH系の話になりますが、/etc/sysconfig/iptablesに記述するか、iptablesコマンドを使う方法の2通りがあり、スクリプト化するならヒアドキュメントでもエコー&リダイレクトでもコマンドでもいい。
Ubuntuはufwというツールがあって、設定ファイルは/etc/iptables.rulesになるけどここでは触れないにょ。
Lpic3の問題集を見ているとコマンド式のようなので、コマンドでの確認をしていこうと思いまっする!
コマンドで設定する場合、最後にiptables-saveで保存する事と、「/etc/init.d/iptables save」をしておかないと再起動したら戻っちゃうので注意だ。
逆にそれを利用した裏技もあるけど、それもここではやらないにょ。
基本
ベーシックな記述式は
iptables -t filter -I INPUT -p tcp -s 192.168.0.100 --dport 80 -j DROP
こんな感じです(多分見たことあるでしょう)。Manから拝借しますとだいたい以下のような形式にのっとります。
・iptables [-t table] -[AD] チェイン ルールの詳細 [オプション]
・iptables [-t table] -I チェイン [ルール番号] ルールの詳細 [オプション]
主なテーブル
- filter その名の通りフィルター。パケットの許可や破棄、フィルタリングの設定をします。
チェインはINPUT/FORWORD/OUTPUT。 - nat 冒頭にも述べたネットワークアドレス変換のこと。たとえば8080で来たものを80に繋いだりとか。
チェインはPREROUTING/OUTPUT/POSTROUTING。 - mangle これは未だに使ったことがありませんが、TTLの設定/変更、パケットの内容を変更するとか。
チェインはINPUT/FORWARD/POSTROUTING。
チェインについて
- INPUT 受信パケットに適用します。
- OUTPUT 送信パケットに適用します。
- FORWARD 転送パケットに適用します。
- POSTROUTING ルーティング後に適用します。
- PREROUTING ルーティング前に適用します。
主なオプション
- -A(–append)<チェイン><ルール>選択したチェインにルールを追加する。
- -D(–delete)<チェイン><ルール>選択したチェインのルールを削除する。
- -R(–replace)<チェイン><ルール>選択したチェインのルールを変更します。
- -F(–flush)<チェイン><ルール>選択したチェイン(指定なしでテーブル内すべて)のルールを削除します。
- -I(–insert)<チェイン><ルール番号><ルール>選択したチェインに指定した番号にルールを挿入する。
- -L(–list)<チェイン>選択したチェインのルール一覧表示。指定がなければすべてのルールを表示する。
- -N(–new-chain)<チェイン>ユーザー定義のチェインを作成します。
- -X(–delete-chain)<チェイン>定義したチェインを削除します。
- -Z(–zero)<チェイン>パケットカウント、バイトカウントをリセットします。
主なパラメータ
- -t(–table) テーブルを指定。
- -d(–destination)<アドレス>送信先アドレス。
- -s(–source)<アドレス>送信元アドレス。
- -i(–in-interface)<インターフェース>インターフェースを指定(受信側)。
- -o(–out-interface)<インターフェース>インターフェースを指定(送信側)。
- -j(–jump)<ターゲット>マッチした場合の処理を指定。
- -p(–protocol)<プロトコル>プロトコルを指定する。
- -sport(–source-port)<ポート>tcp/udpを指定した場合、受信元ポートを指定する。
- -dport(–destination-port)<ポート>tcp/udpを指定した場合、送信先ポートを指定する。
- -m(–match)<モジュール>指定したモジュールを利用する。
ターゲット
- ACCEPT 許可します。
- DROP ”破棄”します。
- REJECT ”破棄”して送信元にICMPエラーを送信する。
- MASQUERADE IPマスカレード。
よく使われるモジュール(とりあえず名前だけ)
- limitモジュール DoS対策に用います。
- stateモジュール ステートフルパケットインスペクション。
設定例
基本編は終わったのでたとえの設定例を載せていきたいと思います。
あー、123.456.789.0 うぜーって時。※例なのでこんなIPですが、エラーになります。
iptables -A INPUT -s 123.456.789.0 -j DROP
さっきの基本に当てはめると、「INPUTに送信元IPアドレスが123.456.789.0のパケットを破棄する。」となります。
あと注意点ですが、iptables -Lならば拒否した状態が確認できますが、cat /etc/sysconfig/iptablesには出ません!よってこのままサービスが再起動されると設定は消えます。
試験範囲ではないですが(多分)fail2banで拒否したIPはiptablesをリロードすると消えます。
IPアドレスを拒否したい時はまた後で出しますが、テキストを読み込むスクリプトを作っておいて、テキストにはlogwatchで抽出されたIPアドレスをテキストに吐いてブラックリスト化する方が良いと思います。そこまでやってないですけどねw
いいかげんにしいやーっていうIPがあれば手動でテキストに書いています。
保存するには
# iptables-save # iptables-save > /var/iptables.bak # /etc/rc.d/init.d/iptables save
ロールバックの場合
# iptables-restore < /etc/sysconfig/iptables.bak001
なんてことも可能です。
スプーフィング対策。
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
うちではeth1がローカルなので、eth0は外向きなのですが、外から送信元IPアドレスがローカルはありえませんので拒否します。
ローカルネットワークからのパケットを外部にマスカレードする。
-A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE -A RH-Firewall-1-INPUT -i eth1 -j ACCEPT # cat /proc/sys/net/ipv4/ip_forward 1
試験範囲はおそらく一番上のものだけかな。
2個目はうちの設定ですが、eth1からは許可しますというもので、一番上のだけでもパケットは抜けるけれど、名前解決できません。
3個目はローカル接続のためのものでこれを許可しておかないとそもそもパケットが抜けてくれません。
この下の2個を忘れていて嵌ってたりとかよくやってました。
/proc/sys以下にはカーネルのパラメタやOSのパラメタなどがありますが、これはまた別のお話し。
こんなとこですかね。モジュールをロードしてDoS対策の内容とかは出題されるのでしょうか。海外のLPICサイトを見ていると出題されるようですね~。もし出題されなくても知っておいた方がいいのは当たり前ですし、最後はブログでも出しているスクリプトを載せて一括で見てみます。
#!/bin/zsh iptables -F iptables -P INPUT DROP iptables -P OUTPUT ACCEPT iptables -P FORWARD DROP #BroadCast Guard iptables -A INPUT -d 255.255.255.255 -j DROP iptables -A INPUT -d 224.0.0.1 -j DROP iptables -A INPUT -d 192.168.0.255 -j DROP iptables -N RH-Firewall-1-INPUT iptables -A INPUT -j RH-Firewall-1-INPUT iptables -A FORWARD -j RH-Firewall-1-INPUT iptables -A RH-Firewall-1-INPUT -i lo -j ACCEPT iptables -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT iptables -A RH-Firewall-1-INPUT -p 50 -j ACCEPT iptables -A RH-Firewall-1-INPUT -p 51 -j ACCEPT iptables -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #SMTP HTTP SNMP POP SSH Guard iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 25 --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -m limit --limit 5/second --limit-burst 5 -j ACCEPT iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 25 --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j LOG --log-prefix "[FW SMTPATTACK] : " iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 25 --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP iptables -A RH-Firewall-1-INPUT -p tcp -m state --state NEW --dport 80 -j ACCEPT iptables -A RH-Firewall-1-INPUT -p tcp -m state --state NEW --dport 162 -j ACCEPT iptables -A RH-Firewall-1-INPUT -p tcp -m state --state NEW --dport 465 -j ACCEPT iptables -A RH-Firewall-1-INPUT -p tcp -m state --state NEW --dport 993 -j ACCEPT iptables -A RH-Firewall-1-INPUT -p tcp -m state --state NEW --dport 995 -j ACCEPT iptables -A RH-Firewall-1-INPUT -p tcp -m state --state NEW --dport 10022 -j ACCEPT iptables -A RH-Firewall-1-INPUT -m limit --limit 1/s -j LOG --log-prefix "[FW DROP] : " iptables -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited /etc/rc.d/init.d/iptables save /etc/rc.d/init.d/iptables start #Static BlockList if [ -s /root/fw_list ]; then for ip in `cat /root/fw_list`; do iptables -A INPUT -s $ip -j DROP done fi echo settings complete
基盤はサーバーを触りだした時に参考にしていた
さくらインターネット創業日記
CentOSをサーバーとして活用するための基本的な設定
こちらのiptablesの設定がベースになっています。
最後のループで最初の方に言ってたブラックリストを作っています。このスクリプトも随分前にやりましたが、ここ数か月ちゃんとしたプログラムを触っていないので随分と忘れ気味なのは自分でもびびってしまいます。試験が終わったらまたバリバリ(のつもり)やりたいなぁと思います。しかし、寒くなったらプログラムがやりたくなるのかw
パッと見て何しているか分かればいいかなぁ程度に思ってるんだけど、どうかな。
では、次回はNagiosで。
3周年企画もやるのでどっちが先になるかは不明です。