システム奮闘記:その21

iptablesの設定入門



Tweet

(2003年8月15日に掲載)
はじめに

  パケットフィルタリングとNATの設定。
  ipchainsやiptablesを使って、LAN内のプライベートアドレスから、
グローバルアドレスへパケットを橋渡しする仕組み。
  私の場合、ipchainsを使っていた。

  さて、設定に関する知識を問われると、いつものように正直に事を書きます。
  
  今まで、本の丸写しで設定していました (^^;;

  なぜ、丸写しだったのか?
  「勉強せんかい!」と言われそうだが、パケットフィルタリングや
ルーティングの知識がなかったため、勉強したくても、全く理解できなかった。
  それに、丸写しでもええやないかという気持ちでいた (^^;  ← 管理者失格!

  「丸写しでええやないか」という気持ちだったら、この章が生まれなかったが
しかし、真剣に勉強せざるえない事件が起こった。

サーバーダウンした上、起動しない

それは、2003年6月5日だった。 この日、私は有給をとって大阪へ出ていた。15時くらいに会社から連絡が入った。 停電のためサーバーがダウンした!  だった (--;; 予定を変更して会社へ駆けつける。 会社に着くと、サーバーの画面が、BIOS設定の画面になっていた。 これくらい対応してくれよ (TT)   と思いながら、立ち上げた。 しかし、1つのサーバーがやられていた。 DNS & NATのマシンだった。
社内のサーバー構成
サーバ構成

  サーバー自体は立ち上がって、DNSは動いていたが、ipchainsが動かない。
動かそうとするとエラーを吐く。
  設定ファイルが破損しているのでは・・・。

  もちろん、設定は本の丸写しのため、何をどうして良いのかわからない。

  そこで、ipchainsの起動を諦め、iptablesをインストールを試みるが、
初めての設定なのと、ipchainsを動かしていたためか、それが悪さをしている
可能性もあってか、うまくいかない。
  1時間半くらい格闘したが、ダメだった。

  上司に「NATという部分に障害が出ています。それがダメですと
社内からメールとWebの閲覧が不可能です」と報告した。

  メールが読めないと、お客さんから来たメールに対応できない。

 部長は以下の事を言った。

部長の発言
だったら、メールを止めたらどうやろ。
今のままやったら、お客さんが送信したメールが読めないから、
それの対応ができず届いた届いてないのトラブルが起こるやろ。
それだったら、メールを止めてたらお客さんが送信したメールが戻ってくるから、
ネットに障害があることが、わかるやろ

  私はマズイと思った。
 メールサーバーを止めても、相手のメールサーバーが何度か再送を
試みるため、すぐに配送先不明で戻るとは限らない。
 数日間、再送を試みる場合も考えられる。

 そこで私は部長に言った。

私の発言
必ずしも、メールを止めていたからといって
すぐにお客さんの所に届かなかったという知らせが
くるとは限らないです。数日かかる場合もありますから
それはマズイですよ

  OSの再インストールが手っ取り早いが、DNSを止めるわけにいかない。
  DNSを止めると、メールが届かない、外部に公開しているWebや
検索サイトがダメになる・・・。

  しかも、Pentium133MHz RAM48M。インストールに時間がかかる。
  2003年2月のようなADSL移行時の時の、悲惨なトラブルが起こってもマズイ。
  詳しくは「システム奮闘記:その19」をご覧ください。
 (ISDNからADSL回線切り換えでトラブル噴出)

セカンダリーDNSサーバーについて
  自社のDNS(プライマリー)がダメになっても、セカンダリ─があれば、
DNSは問題ないのではと突っ込まれる方がおられます。
  実は、この時、DNSのセカンダリ─サーバーを、ADSL回線を契約している
通信会社(N社)に持っていた。
  契約時に、N社に連絡しているのは、うちのDNSサーバーのみだった。

  私は、ゾーン転送という事があるのを知らなかった。
  そのため、N社のセカンダリ─には、うちのDNSサーバーの情報しか
登録されていないと思い込んでいたし、うちの会社のDNSが
ダメになると、セカンダリ─があっても役に立たないと思い込んでいた。

ゾーン転送などの話は「システム奮闘記:その22」をご覧ください。
(DNSサーバー構築 BIND入門)

  DNSサーバーを止めた上で、影響を最小限しての復旧作業を考えると
どうしても夜中になる。
  しかも、設定時にトラブル発生を考えれば、かなりの余裕が欲しい。
  そこで、夜中の復旧作業しかないと考えた。

  上司に「DNSを止めたら、ネット関連が全てストップしてしまいます。
最小限に押さえるには、夜中の作業しかないです」と言った。
  部長が「あんまりムチャしたらアカンけど、仕方がないなぁ」と言った。

  今回の場合は、私の有給休暇で起こった上、徹夜作業。
  周囲も「彼には負担をかけさせて悪い」という感じだったため、
  部長が「今日は、一旦、切り上げて、明日の晩、頑張ってくれ」と言った。
  そして、私は帰宅した。


  6月6日。朝、のんびり起きた。
  家で、どういう方法で復旧作業をするか考えることにした。
  とにかく泥沼にハマって抜けられなくなると、2月の地獄の二の舞になる。
  色々、考えを巡らしていたら、一つの方法を思いついた。

  そういえば、2月に購入した予備の実験サーバーがある。それを使えないか。
  この実験サーバーには、RedHat7.3とWindows200Proの2つのOSが入っている。
  どちらかのOSでNATを仮復旧させてから、本来のサーバーの復旧をさせる。
  例え、実験サーバーの設定が変になっても、問題なく再インストールできる上、
Celeron 1GHzなので、インストール作業も早くできる。
  もし、仮復旧できれば、例え、本格復旧中にトラブルが起こっても、
ネットが使えないなどの問題からは避けられる。
  そう考えると、慌てる必要はなかった。緊張感もなかった。

Windowsと私
最近、Windows2000proにハマっている。
マイクロソフトは大嫌いだが、MS製品を遊びで触るのは嫌いではない。
ふと、Windows2000proでNATができないかという浮気心が出た。
しかし、浮気心のために、復旧作業が泥沼にハマるのもマズイので
いつもの感じで、仮復旧のOSもLinuxにした。

  夕方出社。
  まずは、自分のパソコンにグローバルIPを割り振って、ネット使用を可能にした。

  NATをする場合、ipchainsとiptablesの2種類のソフトがある。
  3年前にサーバー導入した際、ipchainsしかなかったため、ipchainsを使っていた。
  iptablesは、Kernel-2.4から標準装備されるようになった。

  実は出社する前、ipchainsとiptablesのどちらを使うか迷っていた。
  今後の事を考えると、iptablesが主流になる。
  しかし、使い慣れたipchainsの方が安心。
  それに、どこかで仕入れてた知識で、ipchainsの方が、きめ細かい設定ができる。
  きめ細かい設定ができるのも捨てがたい。どっちにしようか、悩んでいた。

  しかし、本の丸写し程度の知識で、きめ細かい設定が、できるわけがない。
  ましてや、その程度のレベルで、使い慣れて安心というのも、おかしな話。

  実に、くだらん事で迷っていたのだった (--;;

  「どうせ、きめ細かい設定なんてできるわけない!」と正しい判断に辿り着いた。
  結論として、iptablesを使うことにした。そして、ネットで検索。
  iptablesについて調べることにした。

  それとは並行に、DNS & NATのマシンの仮復旧をすることにした。
  まずは、実験サーバーに、DNSをインストールして、DNSを立ち上げた。

この時のDNSの知識について
実は、この時点では、DNSも本の丸写しに毛が生えた程度でした。
DNSに関しましては、「システム奮闘記:その22」をご覧ください。
(DNSサーバー構築 BIND入門)

  1つコマンドを打つ必要がある。

入力する必要があるコマンド
echo "1" >/proc/sys/net/ipv4/ip_forward
この設定がないと、iptablesの設定が正しくてもNATが動かない。
これは、パケットを転送するための設定だからだ。

こういう設定も必要! (2005年3月12日に追加)
この編集をしていた時は知らなかった事なのですが、
/proc/sys/net/ipv4/ip_forwardのファイルだが
実は、このファイルはメモリのイメージを、人間の目で見える形した物で、
実体のないファイルだ。そのため、コマンドで中身を書き換えても
再起動をかければ、メモリの中身なので、消えてしまう。

RedHatの場合、/etc/sysctl.confファイルの記述を
net.ipv4.ip_forward = 1に変更する必要がある。

そうする事により、起動時にメモリの中身が書き換えられるのため
わざわざ再起動の度に、コマンドを打つ必要がなくなる。

  私は次のファイルも編集していた。
  /etc/sysconfig/network のファイルで「 FORWARD_IPV4=yes 」にした。
  後で、編集時に、本などと照らし合わせると、この設定は、
RedHat6.0までで、RedHat6.1以降は、触らなくて良いみたい。
  (ただし、未検証です)


  モジュールの組み込み。だが、その前に・・・

  モジュールって何??
  
  だった。よく考えると、モジュールが何かを知らない。
  今まで、知らずに本の丸写しで設定していたのだった (^^;;
  しかし、この時点では、また、本の丸写しをした。

/etc/rc.localに追加したモジュールの記述
/sbin/modprobe  ip_conntrack
/sbin/modprobe  ip_conntrack_ftp
/sbin/modprobe  ip_conntrack_irc
/sbin/modprobe  ip_nat_ftp
/sbin/modprobe  ip_nat_irc
/sbin/modprobe  ipt_LOG
/sbin/modprobe  ipt_MASQUERADE
/sbin/modprobe  ipt_REDIRECT
/sbin/modprobe  ipt_REJECT

  こんな風に本にあった内容を /etc/rc.local に書き加えた。
  モジュールの内容については、後述しています


  さて、うちの会社のNATマシンのネットワークカード。

ネットワークカード
ネットワークカードを2枚差してルーターの役目をさせる

  eth0がグローバル側、eth1がプライベート側にしている。
  まぁ、大抵は、そういう設定をしている場合が多いし、本などでも、
設定方法などで、そうしている場合が大半だ。


  さて、本の内容だと設定方法が、わかりにくかったので、そこでお得意の
Webサイトの記述を丸写しをした。

Webサイトの記述にあったコマンド
iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -j MASQUERADE

  たった、この1コマンドだけ打った。
  この設定に対して・・・

 固定IPでのNAT設定は別の方法!

 と突っ込まれる方がおられると思いますので、この事は後述しています。

  iptablesの初期設定だと、全てのパケットを受け入れるになっている。
  そのため、この1行だけで、NATができてしまう!

  もちろん、他のコマンド設定なども載っていた。

Webサイトに掲載されていた他のコマンド
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -d 0/0 -j DROP
これの内容は、eth0からやってきたパケットで送信元が
192.168.X.Y(X,Yは任意)で送信先が任意のパケットは
破棄するという意味だ。
  
  でも、この設定は、この時点ではしなかった。

  実は、だいぶ前、ipchainsの設定時に、本に同じような記述があった。

本に書いてあったipchainsの設定
ipchains -A input 192.168.3.0/24 -d 0.0.0.0/0 -j DENY -i eth0
その当時、セキュリティーを向上させようという事で真似したが
ネットがつながらなくなってしまった。
そのため、設定を初期化して、本の丸写しで設定を
やりなおした経験があった。

そのため、慎重に復旧させたい気持ちと、当時のトラウマから
何も設定しない事にした。

  今なら、例え、本の丸写しでも、ネットマスクの部分を書き換えたりして
うちの会社のネットワークに対応する事が可能だが、当時は、ネットマスクの
意味すら知らなかった。

たぶん、この設定でも動かなかったと思う
ipchains -A input 192.168.0.0/24 -d 0.0.0.0/0 -j DENY -i eth0

  ちなみに、うちの会社の場合の正しい設定は「24」と「16」を入れ替えた

サブネットマスクを「24」を「16」にした場合
ipchains -A input 192.168.0.0/16 -d 0.0.0.0/0 -j DENY -i eth0

  だけど、これでネットが止まるとは考えにくい。当時の記憶がないだけに、
なぜ、うまくいかなかったのか、真相は謎のままになっている (^^;;


  さて、時計の針は晩8時になっていた。
  無事、実験用サーバーでDNSとNATが稼働。仮復旧することができた。
  これで、サーバーの復旧作業が困難を極めても、業務に支障がない。
  残業していた同僚に復旧を知らせる。営業所にも通達を流した。

  さて、本格復旧を行なう前に、近くのダイエーへ夜食の買い出しに出る。
  半額セールなので、思わず、多めに買ってしまう。
  おやつにアイスクリームも買った。

  さて、買い物から戻り、復旧作業。
  焦る必要はないし、復旧作業が終わらなくても、仮復旧はできているため、
安心感で一杯だった。
  これで、本格復旧に失敗しても、周りから文句を言われる事はない。

  本格的な復旧作業。Pentium133MHzのマシンにLinuxのインストールは
1時間半かかる。まして、あやしいCD-ROMを使っての作業だから、
失敗した時は、長丁場になると思った。
  でも、仮復旧はできていたので、焦る事はなく、のんびりしていた。

  晩11時くらい、暑いので、アイスクリームを取り出す。
  ネットサーフィンをしながら食べる。冷たいので美味しい。
  メチャクチャだらけた復旧作業だったが、順調に進んだ  (^^)V

  深夜1時半。予想以上に早く、復旧作業が完了。
  何事も、不気味なくらい、順調に作業が進んだからだった。
  普段から、トラブルの雨・嵐の私にとっては、不気味な感じがした。

  そして、片付け作業を始めた。2時すぎ、片付けが終わった。
  机の書類の処理を始めたが、復旧作業が完全に終わり、安心しきっていたせいか、
睡魔が襲ってきた。

  睡魔さえ襲わなければ、冷蔵庫のビールでも飲んでいたのだが、
睡魔に勝てずに、応接室のソファーで仮眠することにした。
  そして、6時くらいに、目が覚めて、事務の仕事をこなした。

  朝の8時近くに本部長が出社。
  「ごくろうさん」と言われて、缶コーヒを、ごちそうしてくれた!

  8時半に退社することにした。

iptablesの設定方法について

 無事、サーバーの復旧作業を終えたし、iptablesの設定もできたので ここで「まとめ」と行きたいのだが、設定方法について理解していない。 普通なら、これで終わりにしたいが、そうはいかない。 だって、iptablesの設定を理解していないもん (^^;;) それに、これで終わりとなれば、私自身、本の丸写しの段階から 全く技術力向上になっていない。 単なる、夜中に、のんびりアイスクリームを食べながら復旧しただけの話になる!! このままでは、次回、iptablesの設定をする際も、本の丸写しになる上、 障害が起こった際には、お手上げのままだ。 過去に、ipchainsを使っていた時代、サーバーをrebootすると、 ftpができなくなったりで、往生した事がある。 幸い、本の内容を適当に触っていたら、なんとかなっていた (^^;; それだけでなく、この設定の状態だと、パケットを何でも受け入れるため、 セキュリティー的にも問題が出てくる (--;; そこで「ネタを書くのらー!!」という感じで、iptablesの勉強する事になった。 さて、本を読んだり、ネットで検索したりしてみた。 ポリシーという言葉が出てきた。 ポリシーって何やねん? 「RedHat7.3対応で作るLinux7ネットワークサーバー構築ガイド」 (サーバー構築研究会:秀和システム)のP287を見た。 「ポリシー(policy)とは、チェインに設定されているデフォルトのターゲットです」 だから、ポリシーって何やねん! 意気揚々と勉強しようと立ち向かったが、すぐにコケてしまった・・・(^^;; ところで「ポリシー」をWebで調べても、わかりやすい説明が書いていない。 「ポリシー」の意味を考えると、方針とか理念などの意味になるが、 iptablesで使われる「ポリシー」で納得する意味が思い浮かばない。 しばらく、考えるのを保留した。 次に「ターゲット」の言葉が出てきた。 ターゲットって何やねん? でも、Webサイトの説明を読むと、ターゲット値は、ACCEPT、DROP、QUEUE・・・ と書いてあった。 「ターゲット」は標的などの意味を表す。 そう考えると、ターゲットが「パケットを、どうするか」という意味だとわかった。  そしてターゲットの種類は以下のようになる。
ターゲットの種類
ACCEPT パケットを受け入れるという意味
DROP パケットを払い除けるという意味

  そして、ターゲットの前には「-j」の印をつける。

  少し、iptablesの設定方法が見えてきた。

iptablesの設定方法
オプション 設定の内容
-i eth0 eth0からやってくるパケット
-o eth1 eth1から出ていくパケット
-s 192.168.1.130 パケットの発信源が192.168.1.130
-d 192.168.1.60 パケットの送信先が192.168.1.60

  さて、グローバル側から送信元が「192.168.0.0/16」のパケットなど
飛んでくるわけがない。もし、やってきたら「なりすまし」だ。

 そこで外部から、なりすましのパケットを弾くために以下の設定を行なう。

なりすまし防御の設定
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
インターネット側(eth0)から、プライベートIPでの接続は
ありえないので、それらのパケットを弾く設定を行なう。

 そして同様にプライベート側から外へ出るのに
プライベートIP当てのパケットは、おかしいので以下の設定を行なう。

中から外へのパケットを弾く設定
iptables -A INPUT -i eth1 -s ! 192.168.0.0/16 -j DROP
LANからインターネットへ出るパケットで、プライベートIP当ては
おかしいので、そのパケットを弾く設定を行なう。

 ところで、上の設定を行なう際の注意事項がある。
 「!」とIPアドレスとの間に、1コマ空ける必要がある。

  最初、私は1コマ空けなかったので、以下のエラーが出た。

1コマ開け忘れると、こんなエラーが出る
[root@server] # iptables -A INPUT -i eth1 -s !192.168.0.0/16 -j DROP
iptables -A INPUT -i eth1 -s more test.txt.168.0.0/16 -j DROP
最初、入力した覚えのない文字列「more test.txt」が
出たのかが謎だった。
15分ぐらい考えた末、原因がわかった。

「!192」は命令(コマンド)の履歴の中で、192番目に打った命令を
再度、実行するという意味なのだ。
この時、192番目に実行した命令が「more test.txt」だったので
上のような表示になった。

  INPUT、FORWARD、OUTPUTの3つの違い。
 次の通りだ。

検査する場所
INPUT マシンの中に入るパケット
FORWARD パケットの転送
OUTPUT マシンの外へ出るパケットの

  本に書いてあるiptablesの内容を見てみる。
  「RedHat7.3対応で作るLinux7ネットワークサーバー構築ガイド」
(サーバー構築研究会:秀和システム)のP267を見た。

本に掲載されている図
本に掲載されていたiptablesでのパケット検査の流れ

  この図を見て私は、FORWARD(転送)されるパケットは
FORWARDの検査だけで、INPUTなどの検査はされないと思った。
  そこで、INPUTでパケット拒否の設定をしても、FORWARDで許可すれば、
そのパケットは通過できると正しい理解をしていたのだが・・・。

  そこで、INPUT側の設定は、全てパケットを破棄にして、FORWARDだけ
通す設定にした。

こんな設定をしてみた
iptables -P INPUT  DROP
iptables -P FOWARD ACCEPT
iptables -P OUTPUT DROP
iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -j MASQUERADE
パケット転送だけを行なうため、このような設定をしてみた。

 そして、プライベート側からグローバルのマシンに接続してみた。

  パケットが通過せぇへん (TT)

 なぜ、パケットが通過できないのか、全くわからなかった。

iptablesの設定:誤解が招いた混乱  なぜパケットが通らなかったのか。  先に答えを書くと・・・  DNS検索ができなかったから!  だった。  サーバー構成に問題があったからだ。
社内のサーバー構成
サーバ構成
NATのサーバーは、DNSの役目を果たしている。
iptablesの実験は、NATサーバーで実験しているため
DNSの事を考慮する必要があった

 なので、INPUT(入力)側のパケットを全て弾いてしまうと
以下のような問題が発生してしまう。

発生する問題
DNS問い合わせのパケットを全て弾くため、行き先を知る事ができない
DNSの問い合わせのパケットを全て弾くため
名前解決ができず、ドメインで行き先を指定した場合
パケットの行き先がIPアドレスに変換できず
パケットの行き先が導けないのだ。

 だが、そんな事に気づかなかったため

 本の内容を疑った私!

 だった。

  パケットが通過しない。となれば、本の図が誤っているのでは・・・。
  最近、奮闘記を書くため、資料を調べたりしていると
本が間違えている事もあるため、自然に本の内容も疑うようになっている。


  本の内容を疑った私は、FOWARD(転送)させるパケットも、入口(INPUT)、
出口(OUTPUT)で、検査がされているのではないかと思った。
  そこで、パケットのフィルタリングは、実は、次の図のようになっていると考えた。

私が考えたフィルタリングの処理の流れ
私が考えた、iptablesのフィルタリングの処理の流れ
転送の場合、マシンを経由させるため
マシンの入口(INPUT)、転送そのもの(FORWARD)
そしてパケットの出口(OUTPUT)の3つの検問を通過すると考えた。

 実際の所、本に描かれているパケットの流れが正しいのだが
この時点では、上図のような誤解をしてしまった。
  どうやって誤解を解いたのかは、後述しています。


  こんな感じで、どのパケットを、どうしようかで、色々、触っている間に、
最初に、つまずいたポリシーの意味がわかってきた。

  内容的には、ルーターの設定でも出てきた。
  パケットフィルターをする時、2つの考え方がある。

パケットフィルタリングの2つの考え方
(1) 最初は全て閉じていて、必要な物だけを開けていく
(2) 最初は全て開けていて、不要な物だけ閉じていく

  そういえば、iptables(ipchainsも)の設定を見てみる。

iptablesの設定を見てみる
最初は全て閉じる iptables -P INPUT DROP
最初は全て開ける iptables -P OUTPUT ACCEPT

 ふと思った。

  最初に全て開けるか、閉めるかの

 基本方針をポリシーと呼ぶ!

  そう考えると「なるほど!」と思った。これで納得 (^^)V


  IPアドレスの変換。
 社内のプライベートアドレス領域から発信されたパケットが
グローバルアドレスの領域へ行く際は、発信元のIPアドレスが
NATのマシンのグローバルIPに変換されないといけない。

 いわゆるIPマスカレード。
 なので以下の設定を行なっていた。

IPマスカレードの設定で私がやっていた設定
iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -j MASQUERADE
この設定だが、説明書などを読んでいるとNATマシンの
グローバルのIPアドレスが自動取得(DHCP)の場合の設定だった。

NATマシンのグローバルIPが固定IPでも
この設定で支障はなかったのだが、保証はできませんので (^^;;

 もし、NATマシンのグローバルIPが固定IPの場合だと
次の設定になるのだ。

IPマスカレードの設定
NATマシンのグローバルIPが固定IPの場合
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -j SNAT --to-source XXX.YYY.ZZZ.RRR
XXX.YYY.ZZZ.RRR は、NATのグローバルIPなのだ。
  

iptablesの初期化と「-t」オプション

さて、iptablesの設定の初期化。  まずはNATの設定の初期化を行なう事にした。 最初、他のフィルターリングの設定初期化を行なう際 以下のように行なう。
iptabolesの設定の初期化
iptables -F INPUT
「-F」の後ろにポリシーをつければ、該当のポリシーについて
設定が初期化される。

そのため、「-F」オプションをつければ良いと思った。

 そこでNATの設定を初期化する際は、以下のようにすれば
良い思い、行なってみた。

以下のコマンドを打ってみた
iptables -F nat

 すると・・・

 エラーが出た (--;;

  そこで、次のコマンドを打ってみた。

以下のコマンドを打ってみた
iptables -F MASQUERADE

 これもエラーやん・・・ (--;;

  なぜ、エラーが出るのか理解できなかった

  その日の晩、帰宅途中の書店で、Linuxの本を見ていると
正しい、NATの設定の初期化が載っていた。

iptables 正しいNATの設定の初期化
iptables -t nat -F
「nat」の前に「-t」オプションが必要なのだ。

  さて、翌日、iptablesのWebサイトの解説の「-t」のオプションを読んでみた。
 すると以下の事が書いていた。

 「-t」オプションとは・・・

 パケットフィルター時のみ省略可能

 なのだ。
 つまり、こういう事なのだ。

「-t」オプションが省略可能な例
省略前 iptables -t filter -A INPUT ・・・
省略後 iptables -A INPUT ・・・

  しかし、NATの設定は、パケットフィルターじゃないので
「-t テーブル名」が省略できない。
 そのため、以下の記述になるのだ。

iptables 正しいNATの設定の初期化
iptables -t nat -F

  ようやくNATの初期化できた (^^;;


パケット受け入れ許可 DNSの場合

iptablesの解説を読んでいると、色々な事ができるのがわかってきた。 例えば、パケットの発信元や送信先のポート番号や プロトコルの判断(TCP、UDP)の判断ができたりするのだ。  なので以下のような設定ができるのだ。
iptablesの設定
ポート番号の指定やプロトコルの判断が可能
iptables -F INPUT -p tcp --dport 80 -j ACCEPT
上の場合、マシンに入るパケットの中でtcpであり
ポート80宛てのパケットは受け入れるという内容だ。
ポート80を使うWebサーバーに使われる設定だ。

  さて、うちの会社のNATはDNSサーバーも兼ねている。
  そこで、DNS関連のパケット(UDP、TCP)は通す必要があるので、
次の設定が必要だった。

DNSパケットを通す設定
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p tcp --sport 53 -j ACCEPT

  どっかで仕入れた知識で

 iptablesよりもipchainsの方が細かい設定ができる

 が頭にあった。その時は、まさに思考の停止だった。
 だが、iptablesの設定を覚えていくにつれ

 iptablesは、何でもできるやん!

 という感じになっていった。

iptables設定 SYN信号、ACK信号の判定

そう思った矢先、Webの説明書きで「凄い」と思った事が書かれていた。 なんと、TCPのへッダーの中を見て、SYN信号や、ACK信号を判別できる。 そこで、転送するパケットのフィルタリングを追加してみた。
転送パケットのフィルタリング
グローバルからプライベート側へ入るパケット
iptables -A FORWARD -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
グローバルからプライベート側へ入るパケットの設定だ。

「-m」はモジュールの意味のオプションで、stateは接続状態の意味。
ESTABLISHEDは接続確立中のパケット(飛ばしたパケットの返答パケット)
RELATEDはftpデータ転送やICMPエラーのパケットの意味だ。

  ところで、RELATEDは、ICMPエラーを通すための設定だが
なぜ、それが必要なのか。その理由がわからなかった。

 その前に・・・

 ICMPエラーって何やねん?

 だった。
 ICMPエラーのパケットについては、後述しています。


  プライベートからグローバルへは、基本的に何でも通せば良いので、
以下の設定になる。

iptablesの設定
プライベートIP領域からグローバルへパケットが転送の場合
iptables -A FORWARD -i eth1 -s 192.168.0.0/16 -d 0/0 -j ACCEPT
基本的に何でも通せば良いので上の設定になる。

iptablesのモジュールと設定

さて、iptablesの勉強していていくとモジュールが出てきた。  ところで・・・  モジュールって何やねん?  だった。 調べてみると、以下のような事だという。
モジュールとは
モジュールとは本体に付ける付属部品の事
モジュールとはオプションという説明の仕方がある。
でも、それだけだったら「だから何やねん」となる。

上の図のように、本体の付属部品をモジュールと説明できるが
それでも、わかりやすい説明とは思えない。
モジュールにせんでも、最初から組み込まば、ええやんと突っ込みたくなる。

私は、こう解釈した。本体は軽くするため最小の装備にしている。
組み込まれなかった機能は、必要な時だけ、取り外しが可能な物を使って選択する。
それをモジュールだと考えれば、合点がいく。

(2011/11/14追加)
最初から色々な機能を組み入れると大きくなる上
開発も大変になる。そのため、本体は身軽にして
必要な機能だけ付属部品として付ければ、重たくならない上
開発がしやすくなったり、バグ取りがしやすくなるのだ。

 ftpやIRCを使う場合、モジュールが使われる。

 IRCは使わないので割愛するが、ftpについて説明します。
 ftpでPORTモードの場合、ややこしい方法で接続している。

PORTモードの場合のFTPの通信
ftpでのデータ通信。PORTモードの場合
ポート21で制御関連の接続確立を行なう。
そして、データ送信の接続確立を行なう場合、サーバーから
クライアントへ接続許可のパケットを送る仕組みになっている。
サーバーのポート20から発信されたパケットは許可していないので
通常の場合だと、弾かれてしまう。

そこで、パケットを通すために細工が必要なのだ。
その細工を行なってくれるもモジュールを取り込む必要がある。
/sbin/modprobe  ip_nat_ftpを記述する。


 次に、接続確立の場合、パケットの追跡が必要になってくる。
  なぜなら、単に、ACKを含んだパケットを通過させる設定だと、
悪意のあるパケットを、ACK信号を付けて送られてる危険性がある。

  恐らく、シーケンス番号と受信確認番号などで検査をしていると思う。

ACK信号で通過の有無の判断をしてしまう場合の問題点
ACK信号での判断の場合、悪意のあるパケットを送られると防ぎようがない
ACK信号のみで、外部に送ったパケットの応答だと判定すると危険だ。
悪意のあるパケットの中にACK信号を忍ばせると
簡単に通過してしまうからだ。

  さてさて、接続確立のフィルタリングの設定の場合、
次のモジュールを付け加える。

接続確立の場合
パケット追跡のモジュールの設定
通常通信の場合 /sbin/modprobe ip_conntrack
ftpの場合 /sbin/modprobe ip_conntrack_ftp

フィルタリングとsendmailの問題点

話を戻して、これは立派なファイヤーウォールができると思った。 そこで、大雑把だがフィルタリングの設定を行なった。
大雑把な設定
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -j SNAT --to-source XXX.YYY.ZZZ.RRR

iptables -P FORWARD DROP
iptables -A FORWARD -i eth1 -s 192.168.0.0/16 -d 0/0 -j ACCEPT
iptables -A FORWARD  -m state --state ESTABLISHED,RELATED -j ACCEPT 

iptables -P INPUT DROP
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p tcp --sport 53 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 
iptables -A INPUT -i eth1 -s 192.168.0.0/16 -d 0/0 -j ACCEPT

iptables -P OUTPUT ACCEPT

  プライベート側のマシンからWebを見たりしても、問題なく動いていたので
「この設定で良し!」と思った。

  しかし、メールの送信時・・・

 送信が20〜30秒くらいかかるようになった (TT)

  最初、何故か、わからなかった。
  もしかして、追跡モジュールがNATマシンに負担をかけているのではと推測した。
  なにせ、Pentium133MHz RAM48M。考えられない事はない。

  そこで、追跡機能を取り外して、SYN信号のみのパケットを破棄する設定にした。

SYN信号のみのパケットの転送を拒否する設定
iptables -A FORWARD -i eth0 -p tcp --syn -j DROP

  しかし、事態は変わらなかった。これで追跡機能の負担が原因という候補が消えた。
  20秒ぐらいだったら、別に、ええやないかと思いたくなる。

  しかし、今まで問題なくメールを送信できていたのに、
iptablesの設定を行なっただけで、送信に20秒以上かかるとなれば、
何か原因があるはず。
 原因をハッキリさせないと、何か障害が起こった時、対処なんぞできない。
  それに、原因がわかれば、奮闘記のネタになる (^^)

  そこで、次のDNSの逆引きができない事を疑ってみた。
  DNSの逆引きができないと、メールの取り込み、送信が遅くなったりするからだ。
  しかし、DNSの逆引きは問題なく行なえる。
  そのため、DNSの逆引きという候補も消えた。

  原因として考えられる候補が、全く思いつかない。
  ハッキリしている事は、SYN信号のみのパケットを破棄すると、
メールの送信が遅くなる事だけ、全く手がかりが掴めなかった。

  そこで少し冷静になって考えてみた。
  SYNを拒否すれば、サーバーからクライアントに接続ができなくなるので、
何かのサービスがクライアントに接続をしようとしていると推測できる。
  しかし、ネットなどで調べたが、見当すらつかず、だんだん頭が混乱してきた。

  そこで、困った時のBLUEで、MLに質問することにした。

  質問したら、すぐに、今野さんからお返事がやってきた。

今野さんのお返事
メイルの送信のどの部分で遅くなるのか判らないのですが、auth(113)を通して
いないからと言うことはないですか?

  実は、私はauth(113)が何かを知らなかった (--;;

  でも、とりあえずポート113を開けてみた。
  そうすると、メールの送信がうまくいった。原因は、ポート113にあった!

  早速、今野さんの方法で、うまくいった事をBLUEのMLに報告すると、
YamYasさんから、次のお返事がやってきた。

YamYasさんお返事
ちなみに、authは使ってますか?
使っていないのであれば、やはり閉じた方が良いと思います。
で、基本ポリシーがDROPなので、authだけをREJECTにする。
DROPとREJECTの違いは、がんばって調べて下さい。

  この時、初めてREJECTがある事を知った。見落としていただけだった (^^;;
  私は「DROPとREJECTの違いは大丈夫です」と返答した。

実は違いを知らなかった
私は勘違いをしていた。
REJECTは、TCPパケットの受信拒否(RST)信号を送ることだと思っていた。
しかし、実際は、ICMPのエラーを送る事だった。
勘違いのため意図しない「知ったかぶり」をしてしまったのだった。

  さて、ICMPについて調べてみると、到達不能コードがある。(13種類ほどある)
  それを使うと、通信拒否の返答ができる。

  ICMPでのエラー信号。そういえば、こういう設定があったのを思い出す。

ICMPエラーを通す設定
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
RELATEDは、ICMPのエラーを通す処理だ。

もし、どこかで接続不能の信号を送り返す際、この設定がないと、
返答すらできない事になる。
ここにきて、この設定をする理由がわかった。

  さて「Auth(113)って何やねん」という事になる。
  全く知らないだけに、何の事か、わからない。そこで調べてみる事にした。

  Authについて、次の説明があった

Authについての説明
Sendmailやwu-ftpなどのプログラムは設定によっては
TCPコネクションが張られた時に、発信元のホストに
auth/IDENT(TCP#113 RFC1413)というプロトコルを使って
そのセションを張ったのは誰か特定(identify)しようとします。
(引用ページ)http://unixluser.org/techmemo/ident/より

  要するに、Auth(113)は、メールの送信をしてきたクライアントが
本物かどうか確認するための物だ。

メール送信時の接続確立の様子
メール送信時の接続確立の様子
最初は、3Wayシェイクハンドで、接続確立を行なう。


クライアントを確認する作業
sendmailのサーバーがクライアントを確認する作業
接続確立ができたら、サーバーからクライアントへ
「アンタ、何者なんや?」と確認作業を行なう。
ここでも、3Wayシェイクハンドで、接続確立を行なう。
そして、クライアント認証を行なう。

 もし、途中に経由マシンがあり、そこでポート113宛てのパケットが
通せない状態だと、以下の問題が発生するのだ。

パケットの経由マシンで
iptablesでポート113が閉じていると
パケットの経由マシンでiptablesでポート113が閉じていると
もし、途中でNATがあり、ポートの113が閉じている場合を考える。
DROPの場合、パケットの破棄だけで、接続拒否を行なっていない。
そのため、サーバーは接続を何度も試みる。
一定以上の時間を過ぎたら、サーバーは諦めて、メール送信の作業に戻る。
サーバーが諦めるまでの時間、メールの送信ができない。
うちの会社の場合、それが20〜30秒だった。

 そこでポート113へ接続するパケットを接続拒否の設定を行なうと
NATから接続拒否信号がサーバーへ送られるのだ。

接続拒否の設定をすると
ポート113宛てのパケットの転送拒否を行なうと、接続拒否信号がサーバーへ送られる
サーバーがクライアントの確認のために、SYN信号を送っても
NATが拒否信号を送り返すと、サーバーは確認作業を諦める。
この時、TCPのへッダーにあるRST信号でも、ICMPのエラーでもOK!
そこで、次のようなフィルタリングの設定をすれば良いのだ。

iptables -A INPUT -p tcp --dport 113 -j REJECT

  こんな厄介な問題が隠れていたとは知らなかった。
  この手の問題の解決方法は、他にもある。
  今野さんは、別の方法を使ったとメールで書かれていた。

今野さんに教えていただいた他の方法
前にsendmailの設定で同じようにはまりました。(^^;
Postfixでは問題になったことはありません。
私の時は113を開かずに、sendmailでauthの待ちを0秒にして逃げました。

  ネットで調べてみると、今野さんの方法も問題解決の1つとして書いていた。
  sendmail.cfファイルを書き換えたらできるみたいだが、
手を出したくない部分だけに、まだ、会社のsendmail.cfの設定を見ていない (^^;;

  postfixだと、今野さんが書かれておられる通り、この手の問題にハマる事はない。
  postfixだと、Auth(113)の、クライアント認証がないためとか。
  ネットには、そういう記述を見つけましたが、私自身は未検証です (^^;;

  「検証しろ!」と言う人がいるかと思いますが、それには反論します。
  だって、予備のサーバーがないんだもん (^^)
  
Postfixだったら大丈夫! (2005年3月12日 追加)
2004年に、sendmailからPostfixに乗り換えた際、auth認証の事は
すっかり忘れていましたが、問題なく稼働しました。

Postfixを採用すれば、この手の問題にハマる心配はありません (^^)

  Auth(113)は、クライアント認証だが、立派な物とは言いがたい。
  結構、お人好しの所があり、クライアントがウソつくと簡単にダマされる。
  また、認証ができなくても、メールサーバーは送信拒否しないため、
認証ができないと、わかったら、クライアントの認証を諦めて、
メールの送信作業に移る。

  そう考えると、何のためにあるのか理解できない・・・ (--;;
  元々、ポート113は、Windowsにはないサービスなので、UNIXだけだと思う。
これはUNIXの歴史的背景を調べていかないと、答えが見つからないと思う。


  さて、Webのiptablesの設定方法を見ていると、感心する内容があった。
  MACアドレスのチェックができたりする。
  思わず「ここまでできるか」と思った。


  しかし、さらに驚く事があった。
  なんと、DoS攻撃防止機能まであるという。

  単位時間あたりの受け入れパケット数の制限できるため、
DoS攻撃を防ぐ事ができる。
  今回の場合、グローバルからローカルへのSYN信号のみのパケットは
全て拒否しているため、この機能は必要なかった。でも、便利だと思う。
  もし、LinuxでADSLルーターを構築する場合、この機能が有用なる。
  ただ、単位時間あたりのパケット数などを、どう決めるのかが問題で、
私のようなタダの事務員が、おいそれと手が出せる分野ではない・・・ (^^;;


  さてさて、最後まで残した iptables のチェック機能の仕組み。
  私は下の図のようなフィルタリングがかかっていると思っていた。

私が考えたiptablesでの
パケットフィルタリングの流れ
私が考えたiptablesでのパケットフィルタリングの流れ
INPUT、FORWARD、OUTPUTのそれぞれの部分で、
フィルタリングのチェックが行なわれると思った。

  実は、最後の最後まで、これを信じてしまっていたが、
この奮闘記の最終段階で、Webで、iptablesとipchainsの違いを見ていると
「iptablesの場合、転送パケットは、FORWARDしかフィルタリングがない」と
書かれていた。
 上にある私が思っていたのとは全然違う。
 「RedHat7.3対応で作るLinux7ネットワークサーバー構築ガイド」
(サーバー構築研究会:秀和システム)のP267の図が正しい事になる。

本に掲載されているiptablesの処理の流れ図
本に掲載されているiptablesの処理の流れ図

  だが、私が検証した時は、INPUT、OUTPUTの両方が閉じられると
FORWARDのフィルタリングが開いていても、パケットは転送されない。

 一体、何が正しいねん (@o@)

 と思った。

  しかし、時間が経つと人間は不思議と冷静になれるのだ。
 そこで、図の中にある「PREROUTING」と「POSTROUTING」と
「ROUTING」の記述に目をつけた。

本に掲載されているiptablesの処理の流れ図
本に掲載されているiptablesの処理の流れ図
上図の「PREROUTING」と「POSTROUTING」と
「ROUTING」との違い
PREROUTING パケットがマシンに入ってきた時
IP変換を行なう場合に使う。
POSTROUTING パケットがマシンから外に出る時に
IP変換を行なう場合に使う。
ROUTING パケットの行き先で、自分宛か転送かを振り分ける
(補足)

NATの設定を行なう際に、「PREROUTING」と
「POSTROUTING」を使う場合があります。
詳細は、後述しています。

 ところで設定事例などで出てくるパケットをプライベートから
グローバルへ転送する際のNATの設定は、以下のようになっている。

よく言われるNATの設定
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -j SNAT --to-source XXX.YYY.ZZZ.RRR
これはグローバル側からプライベート側にパケットが入る際の
IP変換に使われる設定だ。

  そこで、次のような推測を行なった。
  プライベートからグローバルへパケットが転送される時は、
ROUTINGで、NAT以外のマシンへの転送なので、FORWARDのチェックがかかる。
そして、IP変換されて、パケットが外へ出る。

  逆に、グローバルからプライベートへのパケットの転送だが
POSTROUTINGのため、この時点でのパケットの宛先が
NATのマシンになっているため、INPUTが適応される。
そして、OUTPUTが適応されてから、PREROUTINGでIP変換が行なわれる。

私が思いついたパケット転送の仕組み
プライベートからグローバルグローバルからプライベート
プライベートからグローバルへパケットが転送される仕組み グローバルからプライベートへパケットが転送される仕組み

  そこで、次のようなフィルタリングを設定した。

これならパケットが通ると思った設定
# ポリシーの設定
iptables -P INPUT DROP
iptables -P FOWARD DROP
iptables -P OUTPUT DROP

# プライベートからグローバル
iptables -A INPUT -i eth1 -j DROP
iptables -A FORWARD -i eth1 -j ACCEPT
iptables -A OUTPUT -o eth0 -j DROP

# グローバルからプライベート

iptables -A INPUT -i eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -j DROP
iptables -A OUTPUT -o eth1 -j ACCEPT

  私の推測が合っているかどうかワクワクしながら、
プライベート側からWebで外部のホームページを見てみると

 接続できへん (TT)

  私の推測は大外れだった (--;;

  普段なら、ここで混乱していまうのだが、今回は冷静だった。
  フィルタリングの設定を眺めていると、ふと大事な事を忘れていた。

  DNSのパケット受け入れしてへんかった!

  NATマシンは、DNSサーバーを兼ねているため、DNS検索を行なう際、
NATマシンに問い合わせを行なう。

社内のサーバー構成
サーバ構成
NATのサーバーは、DNSの役目を果たしている。
実験機がなかったため、稼働しているDNSサーバーを
実験機代わりでiptablesの実験をした。

 なので、INPUT(入力)側のパケットを全て弾いてしまうと
以下のような問題が発生してしまう。

発生する問題
DNS問い合わせのパケットを全て弾くため、行き先を知る事ができない
DNSの問い合わせのパケットを全て弾くため
名前解決ができず、ドメインで行き先を指定した場合
パケットの行き先がIPアドレスに変換できず
パケットの行き先が導けないのだ。

  しかし、検証時のフィルタリングを見ると、プライベート側からの
INPUTのパケットが全てDROPのままになっている。
  これだと、DNS検索ができないため、相手のホストに、接続できなくなる。

  そこで、本の内容が正しいとして、次の検証を行なった。

DNSのパケットだけINPUT(マシン内)への
受け入れを許可してみた
# FORWARDだけ通過のポリシー

iptables -P INPUT DROP
iptables -P FOWARD ACCEPT
iptables -P OUTPUT DROP

# DNSのパケットのみ、INPUTで受け入れ

iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p tcp --sport 53 -j ACCEPT

  この設定で、プライベート側から外部のWebサイトを見てみると
見事に閲覧する事ができた!!  (^^)

  本の内容が正しかった!!

  基本的な部分の見落としで、メチャクチャ遠回りしてしまった。

  でも、なんとか、自力で誤解を解くことができて良かった。
  編集の最終段階だったため、この問題に気づかずに
この章を公開していたら、大恥をかくところだった (^^;;

iptablesで各種パケットの設定や制御

さて、FORWARD(転送)されるパケットは、INPUT、OUTPUTを通過する前提で、 フィルタリングをしていたため、いくつかの設定の変更を余儀なくされた。

NetBISOのパケットを遮断

NetBIOS over TCP/IPのパケットを通過させないための設定だ。 私はポート137〜139までを通過させない設定にしている。
パケットの受け入れ、転送を遮断
# 受け入れ遮断
iptables -A INPUT -p tcp --sport 137:139 -j DROP
iptables -A INPUT -p tcp --dport 137:139 -j DROP

# 転送を遮断  
iptables -A FORWARD -p tcp --sport 137:139 -j DROP
iptables -A FORWARD -p tcp --dport 137:139 -j DROP

 Windowsネットワークの場合、ブラウジング機構などのため
パケットが飛び交う問題がある。
 そのため、少しでも無駄なパケットを遮断する必要がある。

 ブラウジングの話については「システム奮闘記:その17」をご覧ください。
 (Microsoftネットワーク入門)

NATの設定

ところで、NATの設定は次の通りにしていた。
NATの設定
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -j SNAT --to-source XXX.YYY.ZZZ.RRR

 ところでNATの場合、IP変換の方法に2種類ある。
  
2種類のIP変換の方法
POSTROUTING パケットがマシンの外で出る際、IP変換を行う
PREROUTING パケットがマシンに入ってきた時にIP変換を行う

 本の知識の受け売りなら簡単にできるが、実際に、どう違うのか、わからない。
 一体、何の違いがあるのか。確かめてみたくなった。
 そこで、次の設定をしてみた。

PREROUTINGの設定を行なってみた
iptables -t nat -A PREROUTING -i eth1 -s 192.168.0.0/16 -j SNAT --to-source XXX.YYY.ZZZ.RRR
実験としてはプライベート側からグローバル側に
パケットを飛ばしてみた。

 だが・・・
  
 でも、エラーが出る(TT)

  色々、PREROUTINGの設定例を探したが見つからず
どんな違いがあるのか、調べることを断念した (--;;


(2003年11月4日に追加) 初版の時PREROUTINGの設定例がわからず断念したが ひょんな事で設定例がわかった。 それは、ふと、SoftwareDesignの2002年11月号を見た時だった。 iptablesの設定の説明が書いてあった。  その中にお目当てのPREROUTINGの設定例があった。 そこで、POSTROUTINGPREROUTINGの違いを書くことにした。
POSTROUTINGの場合
POSTROUTINGの設定は、プライベートからグローバルへパケットを飛ばす際に行なわれる
これこそ、今まで思っていたNATの設定。
プライベートからグローバルへパケットを送信する際、
発信元をNATのマシンのIPに変換する設定だ。

 そして、もう一方の場合は、パケットの転送方向が
逆向きの場合に行なう。

PREROUTINGの場合
PREROUTINGの設定は、グローバル側からプライベート側へパケットを転送する場合に使われる
今回、私が知ったNATの設定。
グローバルからプライベートへパケットを送信する際、
送信先をNATのマシンからプライベートのIPに変換する設定だ。
この設定は、プライベートの中に、外部向けのホームページなどを
公開している際に使われる設定だ。
具体的なコマンドの使い方は以下の通りです。
iptables -t nat -A PREROUTING -d 10.20.30.40 -i eth0 -j DNAT --to 192.168.1.2
ちなみに、eth0は、NATのマシンのグローバル側のデバイスを表します。

  あまりにも簡単に違いがわかってしまった。
  雑誌は「積む読」ではなく、キチンと読まないとと思った今日この頃。

iptablesでファイヤーウォールの設定

2004年現在では以下のような設定をしています。
2004年5月現在のiptables設定内容
########  セキュリティーポリシー #########

iptables -P INPUT   DROP
iptables -P FORWARD DROP
iptables -P OUTPUT  DROP

##########  パケットフィルタリング  ###########

# SYNフラッド対策

iptables -N syn-flood
iptables -A syn-flood -m limit --limit 1/s --limit-burst 8 -j RETURN
iptables -A syn-flood -j LOG --log-prefix "iptables syn-flood : "
iptables -A syn-flood -j DROP
iptables -A INPUT -p tcp --syn -j syn-flood
iptables -A FORWARD -p tcp --syn -j syn-flood

Halfopenスキャン対策

iptables -N hopen-scan
iptables -A hopen-scan -m limit --limit 1/s --limit-burst 4 -j RETURN
iptables -A hopen-scan -j LOG --log-prefix "iptables hopen-scan : "
iptables -A hopen-scan -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j hopen-scan
iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j hopen-scan


#特定ポート(ウェルノンポート)同士の通信は破棄

iptables -N wn-port
iptables -A wn-port -j LOG --log-prefix "iptables wn-port : "
iptables -A wn-port -j DROP
iptables -A INPUT -p tcp   --sport :1023 --dport :1023 -j wn-port
iptables -A FORWARD -p tcp --sport :1023 --dport :1023 -j wn-port
iptables -A OUTPUT -p tcp  --sport :1023 --dport :1023 -j wn-port

分割パケットで、2個目以降の物だけを受け取った場合は破棄

iptables -A INPUT -f -j DROP
iptables -A FORWARD -f -j DROP

#ループバックのパケットはOK

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT


#外部からのパケットで発信元がプライベートアドレスの場合、破棄
#NATと同じIPアドレスも破棄

iptables -N spoofing
iptables -A spoofing -j LOG --log-prefix "iptables spoofing : "
iptables -A spoofing -j DROP

iptables -A INPUT -i eth0 -s 127.0.0.0/8    -j spoofing
iptables -A INPUT -i eth0 -s 10.0.0.0/8     -j spoofing
iptables -A INPUT -i eth0 -s 172.16.0.0/12  -j spoofing
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j spoofing
iptables -A INPUT -i eth0 -s (NATのグローバルIP) -j spoofing

iptables -A FORWARD -i eth0 -s 127.0.0.0/8     -j spoofing
iptables -A FORWARD -i eth0 -s 10.0.0.0/8      -j spoofing
iptables -A FORWARD -i eth0 -s 172.16.0.0/12   -j spoofing
iptables -A FORWARD -i eth0 -s 198.168.0.0/16  -j spoofing

# AUTH 認証には TCPのRSTで返答する。

iptables -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset

# Windows DCE RPC , NetBIOS , Direct Hosting SMB パケットの転送は拒否

iptables -A FORWARD -p tcp -m multiport --sport 135,137,138,139,445 -j DROP
iptables -A FORWARD -p udp -m multiport --sport 135,137,138,139,445 -j DROP
iptables -A FORWARD -p tcp -m multiport --dport 135,137,138,139,445 -j DROP
iptables -A FORWARD -p udp -m multiport --dport 135,137,138,139,445 -j DROP

#NATはDNSも兼ねているので、DNSのパケットは受け入れる。

iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p tcp --sport 53 -j ACCEPT

#PPTP接続のパケットは外部から内部への接続でも認める

iptables -A FORWARD -i eth0 -p tcp --dport 1723 -d 192.168.XXX.YYY -j ACCEPT 
iptables -A FORWARD -i eth0 -p 47 -d 192.168.XXX.YYY -j ACCEPT 

#プライベートのマシンから外部へ出るパケットをNAT経由させる。
#そして、その応答パケットも経由させる。

iptables -A FORWARD -i eth1 -s 192.168.0.0/16 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT 
iptables -A FORWARD -i eth0 -m state --state  ESTABLISHED,RELATED -j ACCEPT 

#NATマシンから外へ出るパケットと、それ対する応答パケットは受け入れる

iptables -A INPUT -i eth0 -m state --state  ESTABLISHED,RELATED -j ACCEPT 
iptables -A OUTPUT  -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT 

#######  NAT の設定部分  ##########

#内部から外部へ

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -j SNAT --to-source XXX.YYY.ZZZ.RRR

#PPTPについて

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1723 -j DNAT --to 192.168.XXX.YYY
iptables -t nat -A PREROUTING -i eth0 -p 47 -j DNAT --to 192.168.XXX.YYY


まとめ ipchainsとiptablesの違い。 最初は、どこかで仕入れた知識で、ipchainsの方が、きめ細かい設定ができると 思い込んでいたため、ipchainsに、こだわっていました。 しかし、実際に、iptablesの設定をしたり、ipchainsと比較したりすると、 どっちが優れているか、わからなくなりました。甲乙付け難しといった所です。 知識は、鵜呑みにしないで、自分で確かめる事が大事という教訓です。 本などの記述が「おかしい」と思ったら、「おかしい」と言う前に、 検証する事をお勧めします。でないと、大恥じをかく場合があります (^^;; 機能面では、相当な充実しているため、立派なファイヤウォールになると思います。 LinuxでADSLルーターを構築される方には、iptables(または、ipchains)の 利用をお勧めします。 iptablesですが、ある程度のパケット通信の知識が必要です。 TCPのへッダーの中に、ACK信号があるか、ポートは何番などです。 私の場合はヤマハのルーターで設定の勉強をしたおかげで 比較的、iptablesの設定に慣れたと思います。(かなり怪しいけど・・・)  「システム奮闘記:その18」(ヤマハルーターRTA52iとRTA55iの設定)  お勧めの、パケット通信の話や、TCP/IP関係の入門書を紹介します。  「最新TCP/IPハンドブック」(若林 宏:秀和システム)

次章:「DNS設定入門」を読む
前章:「RealVNCでパソコンの遠隔操作」を読む
目次:システム奮闘記に戻る

Tweet