iptablesを使った、常時接続 linux firewall routerの設定
sorry Japanese only
最終更新日 2004/12/20
page size = Mbyte


関連するページ iptables iptables2 iptables3+brctl


最終目標は、以下の図のような構成を目指します。

(1) Bフレッツ用 ONUへは linux PCの eth1に接続
eth1では rp-pppoeを使って @niftyと IIJ4Uの切り替えが可能な常時接続を行う。
(2) internetから eth1へ入ってきた PORT80と 8080のパケットは linuxで動作している apacheへ振り分ける。(INPUTの部分許可)
(3) eth1から入ってきたパケットを eth0へは通さない。(FOWARDの禁止) (3) internetから eth1へ来たその他の通信は拒否(INPUTの原則拒否)
win機は HUB経由で linux PCの eth0へ接続
(4) win機からは linux PCを telnet,ftpなどフルコントロールできるようにする(eth0からの INPUTは ACCEPT)
(5) eth0から eth1へは無条件で通信を通す(FORWARDの許可)

要は、パケットフィルターが出来ます。
って市販の頭が悪いルーター程度のことをやりたいだけです、ハイ。

序文

私が installした linuxは vine2.6r4なんですが、ipchainsと iptablesが両方 installされているようでした。
[root]# rpm -q iptables
iptables-1.2.7a-0vl1
[root]# rpm -q ipchains
ipchains-1.3.10-0vl3
[root]#

使い方を internetで色々調べてみると、ipchainsは kernel2.2までの今まで使っていたコマンド。
これからは iptablesだ。どうせ悩むなら iptablesで悩んで物にしよう!
って書いてあるページが多く、私も iptablesで行くことにしました。

しかしどのページを見ても、ipchains,iptables,MASQUERADE,forward,UDP,TCP,PORT,etcetc・・・
当然のように出てきますが、win機で kerioを使って firewallのルールを作ったことがある私も、
はてさて、書いてある単語がまず分からないぞ?
現在 apacheサーバーを市販ルーター経由で公開していますから、portを開けると外から中へ通信が入ってこれる。
って事は分かっていますが、マスカレードって何?って状態からのスタートです。

で、半日このページを作っていてやっと分かったこと。
OUTPUTは、iptablesを設定している linux PCから出て行くパケットのこと。例えば linux PC上で Firefox使って internetやったりしたときが OUTPUT。
INPUTは、eth1から apacheにアクセスしてくる人。eth0から hpのページを書き換えたり確認したりする私。
FORWARDは、Win PCから eth0=>eth1へ通り抜けて internetを見ようとしている状態。

のことを言うのですね。特に FORWARDが分かりづらかったです。
ここの hpの絵を見て始めて分かりました。

iptablesを使える状態にする lsmod,modprobe,chkconfigコマンドを使って ipchainsは使わない、iptablesを使う。って状態にします。
(実行した後でコマンドを保存していたりしますので、話が前後していたりします)

[root]# lsmod
Module                  Size  Used by    Tainted: P
iptable_mangle          2880   0  (unused)
iptable_nat            25012   0  (unused)
ip_conntrack           30868   1  [iptable_nat]
iptable_filter          2432   0  (autoclean) (unused)
ip_tables              15712   5  [iptable_mangle iptable_nat iptable_filter]
それぞれが何を目的として組み込むモジュールだか不明なので何とも言えませんが(オイオイ)、上に書いた 5個が組み込まれていれば良いみたいです。
こういう状態とするため以下のコマンドを実行しました。

[root]# modprobe iptable_nat
[root]# modprobe iptable_mangle
ん?これだけじゃ組み込まれなかったよ。って人は

[root]# modprobe -l
とやると、モジュール名一覧が出ては来ますが、これまたいっぱい出てきますから、

[root]# modprobe -l | grep -i ip
とかやって ipなんとか。ってのに付いたモジュールの種類一覧を表示してみましょう。
関連ありそうなのが見付かったら組み込んでおきましょう。

[root]# chkconfig --list
network         0:off   1:off   2:on    3:on    4:on    5:on    6:off
inet            0:off   1:off   2:off   3:on    4:on    5:on    6:off
ipchains        0:off   1:off   2:off   3:off   4:off   5:off   6:off
iptables        0:off   1:off   2:off   3:off   4:off   5:off   6:off
routed          0:off   1:off   2:off   3:off   4:off   5:off   6:off
adsl            0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root]#
関係のありそうなのだけ抜き出してみましたが、ipchainsも iptablesも offとします。
ん?サービスで起動しなくても良いのか?って疑問もありますが良いんです。
起動しないと iptables -nLとか使えないような気がするんだけど、起動しなくても使えてます。
どういう仕組みで起動せずとも動作するのかを、分かったら追加します。

[root]# chkconfig --del ipchains
とやれば offに出来ます。

逆に onにしたいんだったら
[root]# chkconfig --add ipchains
[root]# chkconfig --level 2345 ipchains on
とかやれば所定の run-levelの時に起動させるか、止めるかの設定が出来ます。

rp-pppoeの組み込み

vine linux組み込みの時に一緒に組み込めたような気がしますが、組み込まなかったのか、以下の方法で組み込みました。

[root]# apt-get install rp-pppoe
この後 configure => make => make install => adsl-setupの順で設定していきます。
ここら辺は、他に詳しく書かれていたページが沢山あって、そのまま同じように出来ましたので省略します。

設定終了したら接続してみます。

[root]# adsl-start
.. Connected!
[root]# adsl-status
adsl-status: Link is up and running on interface ppp0
ppp0      リンク方法:Point-to-Pointプロトコル
          inetアドレス:202.233.233.125 P-t-P:133.160.135.246 マスク:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1454  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          衝突(Collisions):0 TXキュー長:3
          RX bytes:30 (30.0 b)  TX bytes:30 (30.0 b)

[root]# adsl-stop
Killing pppd (2819)
Killing adsl-connect (2791)
[root]# adsl-status
adsl-status: Link is down (can't read pppoe PID file /var/run/pppoe.conf-adsl.pid.pppoe)
[root]#
接続して adsl-start
確認して adsl-status
切断して adsl-stop
もう一度確認 adsl-status

エラー無く通ったら、linuxを起動しただけで接続して欲しいので、
[root]# chkconfig --add adsl
[root]# chkconfig --level 2345 adsl on
[root]# chkconfig --list adsl
adsl            0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root]#
の状態にします。

もし linux起動したけど loginしていない状態で pppoe接続が始まっていなかったら、
[root]# chkconfig --del adsl
[root]# chkconfig --add adsl
[root]# chkconfig --level 2345 adsl on
一度 --delで削除してからもう一度 --addすると、うまくいくようです。
私も一度削除しないとうまく繋がりませんでした。

iptablesの設定

まあ良く分かってません。
色々な説明してくれているページを拝見して、自分にあった設定を引っ張ってきてみました。

まずは設定の初期化。
[root]# iptables -F
[root]# iptables -X

さあ、いきなり linuxにアクセスできなくなったあなた。私と同じです。
そのままアクセスできている人はラッキーでした。
INPUTの基本ルールが DROPになっていると、通過の許可をしていたルールを -Fでクリアーしたとたん telnetとかで入っていた人は拒絶されて端末フリーズします。

linux本体のキーボードを引っ張り出して
iptables -P INPUT ACCEPT
で INPUTの基本ルールを許可にしておきましょう・・(前途多難を予想させる出来事)

クリアーされたのを確認します。
[root]# iptables -nL
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
[root]#
全て ACCEPTで firewallの機能無しの状態です。

この状態から、目指すルールを作っていきます。

で、出来上がったのがこのルールです。

#!/bin/sh

#iptablesコマンド使った firewallの設定スクリプト

LOCAL_NET='192.168.0.0/16'
CLIENT_A='192.168.0.2'

#基本ポリシー (-Pオプション)の設定
#INPUTは拒否 DROP
#OUTPUTは許可 ACCEPT
#FORWARDは拒否 DROP
#
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT (DROPが基本というサイトが大多数です、念のため)
iptables -P FORWARD DROP

#個別ルールを全削除
#
iptables -F
iptables -t nat -F

#ユーザー定義チェインを削除
#
iptables -X

#ループバックに関してはすべて許可
#
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT

#自分が発するコマンドを許可
#
#iptables -A INPUT -i lo -j ACCEPT
#(この設定はセキュリティー上良くなかった?)
#(次の行の設定に変更しました)
iptables -A INPUT -s 192.168.0.25 -d 192.168.0.25 -j ACCEPT

#eth0から入ってくる LOCAL NET PCからの通信を許可
#
iptables -A INPUT -i eth0 -p all -s $LOCAL_NET -j ACCEPT

# 発信元が loop back private addressのパケットを拒否
#
iptables -A INPUT -i ppp0 -s 127.0.0.0/8 -j DROP
iptables -A INPUT -i ppp0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i ppp0 -s 176.16.0.0/12 -j DROP
iptables -A INPUT -i ppp0 -s 192.168.0.0/16 -j DROP

# TCP PORT 80,8080の通過を許可
#
iptables -A INPUT -i ppp0 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i ppp0 -p tcp --dport 8080 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# PORT 135 rpc
#      137 netbios
#      138 netbios
#      139 file/printer共有
#      445 file/printer共有
# ppp0へ向けて出て行く以上のパケットは DROP
#
iptables -A FORWARD -p udp -i eth0 -o ppp0 --dport 135:139 -j DROP
iptables -A FORWARD -p tcp -i eth0 -o ppp0 --dport 135:139 -j DROP
iptables -A FORWARD -p udp -i eth0 -o ppp0 --dport 445 -j DROP
iptables -A FORWARD -p tcp -i eth0 -o ppp0 --dport 445 -j DROP

# 送信先が LOCAL ADDRESSの物が ppp0へ向けて出て行ったら DROP
#
iptables -A FORWARD -o ppp0 -d 192.168.0.0/16 -j DROP

#eth0からeth1へ向けてのパケットは許可
#
iptables -A FORWARD -i eth0 -o ppp0 -s $LOCAL_NET -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# LANから外に出て行くパケットの送信元IPを書き換え
#
iptables -t nat -A POSTROUTING -o ppp0 -s $LOCAL_NET -j MASQUERADE
 
# ループバック宛、プライベートアドレス宛のパケットが漏れるのを防ぐ
#
iptables -A OUTPUT -o ppp0 -d 127.0.0.0/8 -j DROP
iptables -A OUTPUT -o ppp0 -d 10.0.0.0/8 -j DROP
iptables -A OUTPUT -o ppp0 -d 176.16.0.0/12 -j DROP
iptables -A OUTPUT -o ppp0 -d 192.168.0.0/16 -j DROP

# NetBIOS over TCP/IP の流出パケットを遮断
#
iptables -A OUTPUT -o ppp0 -p tcp --dport 135:139 -j DROP
iptables -A OUTPUT -o ppp0 -p udp --dport 135:139 -j DROP
iptables -A OUTPUT -o ppp0 -p tcp --dport 445 -j DROP
iptables -A OUTPUT -o ppp0 -p udp --dport 445 -j DROP
これをもしもの時のために /etc/ppp/firewall-setting.shという名前で保存します。
実行できるよう
chmod 744 firewall-setting.sh
と実行しておきましょう。

最後に忘れてはならないコマンドが
[root]# iptables-save > /etc/sysconfig/iptables
これをやらないと、次に bootしたときに設定が反映されません。

re-pppoeを使っていて、adsl-setupにて Firewallの設定を
2 - MASQUERADE: Appropriate for a machine acting as an Internet gateway
に設定した人は /etc/sysconfig/iptablesに書き込んでも立ち上げ時に設定が反映されません。
上で作成した iptables-setting.shを /etc/ppp/firewall-masqへ cpしましょう。
立ち上げ時 firewall-masqが実行されます。

ちなみに、WIN PCから internetで調べながら FORWARDの検査などを行う時に便利だったコマンドは、WIN PCの Default Gatewayを一発で切り替えられる routeコマンドです。
以下のようにコマンドを打つと、一発で Default Gatewayが切り替えられます。

Windows2000の CMDプロンプトから実行した結果です。
最初の状態。
WIN PCの Networkアドレスは 192.168.0.2
通常使っている routerのアドレスは 192.168.0.1
テスト中の linux pcのアドレスは 192.168.0.5

> route print
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.0.1     192.168.0.2       1
        127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1       1
      192.168.0.0    255.255.255.0      192.168.0.2     192.168.0.2       1
      192.168.0.2  255.255.255.255        127.0.0.1       127.0.0.1       1
    192.168.0.255  255.255.255.255      192.168.0.2     192.168.0.2       1
        224.0.0.0        224.0.0.0      192.168.0.2     192.168.0.2       1
  255.255.255.255  255.255.255.255      192.168.0.2     192.168.0.2       1
Default Gateway:       192.168.0.1
===========================================================================

> route DELETE 0.0.0.0
とやると Default Gatewayが消える
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
        127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1       1
      192.168.0.0    255.255.255.0      192.168.0.2     192.168.0.2       1
      192.168.0.2  255.255.255.255        127.0.0.1       127.0.0.1       1
    192.168.0.255  255.255.255.255      192.168.0.2     192.168.0.2       1
        224.0.0.0        224.0.0.0      192.168.0.2     192.168.0.2       1
  255.255.255.255  255.255.255.255      192.168.0.2     192.168.0.2       1
===========================================================================

> route ADD 0.0.0.0 192.168.0.5 MASK 0.0.0.0
とやると
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.0.5     192.168.0.2       1
        127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1       1
      192.168.0.0    255.255.255.0      192.168.0.2     192.168.0.2       1
      192.168.0.2  255.255.255.255        127.0.0.1       127.0.0.1       1
    192.168.0.255  255.255.255.255      192.168.0.2     192.168.0.2       1
        224.0.0.0        224.0.0.0      192.168.0.2     192.168.0.2       1
  255.255.255.255  255.255.255.255      192.168.0.2     192.168.0.2       1
Default Gateway:       192.168.0.5
===========================================================================
コマンド一発で Default Gatewayの設定を変えることが出来る。

あと、こんなコマンドも作っておきました。
ワケ分からなくなった時、安全に iptablesの設定を元に戻すコマンド。
#!/bin/sh

iptables -P INPUT ACCEPT
iptables -F
iptables -X
iptables -nL

INPUTを ACCEPTした後、テーブル全削除、表示をして終了します。
ipclrって名前で保存しました。
パスの通った所へ保存して chmod 700 ipclr


参考にさせていただいたサイトの方、ありがとうございました。(順不同)
ネットワークサーバ構築記
Manpage of IPTABLES
Linuxで作るファイアウォール[NAT設定編]
iptablesクイックスタート
PCルーター構築完全マニュアル(iptables編)
iptables でファイヤウォール - Linux で自宅サーバ [ Home Server Technical. ]
Linux/iptablesでルータを作る - Dream-Seed -Wiki版-
naoya.dyndns.org

疑問点

iptables -P INPUT DROP にて、INPUTは基本ポリシーで DROPにしていますが、個別設定部分では DROPを記述していません。
シマンテックのセキュリティーチェックSygate Security Scanをやっても PORT80以外は全てステルスで安全。ってなっていますが、本当のところはどうなんでしょうか。

windows用 Firewallソフト kerio(ver2)のように、上の方からパケット通過させたい条件を書いていき、どれにも当てはまらなかったら一番下で ALL DENYで弾く。
と言うのが、視覚的にも分かりやすくて良いと思います。

iptablesのように、こんな設定が難しく難解では、間違ったセキュリティーを設定してしまい、全くセキュリティー用ツールの意味をなさないと思うなぁ。

見慣れれば kerioと同じように視覚的にも分かるようになるのかも知れないけど。

色々なページを読んだ所によると、上から順番にルールを実行していき、どれにも引っかからなかったらポリシーを実行する。って事らしいです・・・

26119
戻る