wiki:TipAndDoc/network/iptables

Version 10 (modified by mitty, 15 years ago) (diff)

--

iptables

  • 応用例
    • 連載記事 「習うより慣れろ! iptablesテンプレート集」
    • junoのへたれサーバ管理日記: iptablesのログをとる
      • デフォルトでは「kern.=warning」で振り分けが出来る
        Jul  4 01:54:03 ubuntu-napt kernel: [118136.424992] [UFW BLOCK FORWARD]: IN=eth0 OUT=eth2 SRC=192.168.100.197 DST=130.xyz.68.26 LEN=58 TOS=0x00 PREC=0x00 TTL=63 ID=3740 DF PROTO=UDP SPT=40966 DPT=53 LEN=38
        
      • iptable側では「--log-level err」などとしてpriorityを変更できる
      • kern.=warningには他にも様々なログが来るので、なるべく混ざらないようにしたければ「kern.=notice」「kern.=err」あたりが妥当か。
        • /etc/syslog.conf
          kern.=warn			-/var/log/kern.warn.log
          kern.=err			-/var/log/kern.err.log
          
        • (少なくともUbuntuでは)errに設定するとコンソールにも出力されるので注意

設定ファイル

  • Ubuntu => ufw
  • CentOS
    • /etc/sysconfig/iptables
      # Firewall configuration written by system-config-securitylevel
      # Manual customization of this file is not recommended.
      *filter
      :INPUT ACCEPT [0:0]
      :FORWARD ACCEPT [0:0]
      :OUTPUT ACCEPT [0:0]
      :RH-Firewall-1-INPUT - [0:0]
      -A INPUT -j RH-Firewall-1-INPUT
      -A FORWARD -j RH-Firewall-1-INPUT
      -A RH-Firewall-1-INPUT -i lo -j ACCEPT
      -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
      -A RH-Firewall-1-INPUT -p 50 -j ACCEPT
      -A RH-Firewall-1-INPUT -p 51 -j ACCEPT
      -A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
      -A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
      -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
      -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
      -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
      -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
      COMMIT
      
      • sshのみListen可

table

raw

raw テーブルはiptablesで最初に評価される PREROUTING と OUTPUT で使用出来る

rawテーブルはNOTRACKを使用する事でconntrack、NATを適用せずに通過させる その分、高速になる、TRACE でトレース出来る また conntrackやstateモジュールは使用出来ない

iptablesで最初に評価されるので、QUEUEやIMQなどにパケットを転送する前に おかしなパケットを廃棄出来る

  • PREROUTINGが使えることにより、INPUT/FORWARD双方に回る予定のパケットを前もって制御できる
    • POSTROUTINGもあれば良いのだが…

巨大 icmp packet の拒否

  • デフォルト
    • ping 202.12.27.33 -c 1
      PING 202.12.27.33 (202.12.27.33) 56(84) bytes of data.
      64 bytes from 202.12.27.33: icmp_seq=1 ttl=241 time=5.95 ms
      
    • ping 202.12.27.33 -c 1 -s 10240
      PING 202.12.27.33 (202.12.27.33) 10240(10268) bytes of data.
      10248 bytes from 202.12.27.33: icmp_seq=1 ttl=241 time=13.3 ms
      
  • 自ホストから外へのlarge packetの拒否
    • sudo iptables -t raw -A OUTPUT -p icmp --icmp-type echo-request -m length --length 85: -j DROP
    • ping 202.12.27.33 -c 1
      PING 202.12.27.33 (202.12.27.33) 56(84) bytes of data.
      64 bytes from 202.12.27.33: icmp_seq=1 ttl=241 time=10.5 ms
      
    • ping 202.12.27.33 -c 1 -s 57
      PING 202.12.27.33 (202.12.27.33) 57(85) bytes of data.
      ping: sendmsg: Operation not permitted
      
  • ログを取る場合
    sudo iptables -t raw -A PREROUTING -p icmp --icmp-type echo-request -m length --length 85: -j LOG --log-prefix "[IPTABLES BAD-ICMP]: " --log-level err -m limit --limit 3/min --limit-burst 10
    sudo iptables -t raw -A PREROUTING -p icmp --icmp-type echo-request -m length --length 85: -j DROP
    
    • 「-m limit」について => パケットサイズが異常なicmp requestが一分間に10回を超えた場合は、一分間に3回のみログを取るように制限する
      • 無いと膨大なログになる可能性がある

mangle

  • どのようなときに使うべきなのかよく分からない。調査中。
  • INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING の全てのchainが使える

misc

  • interfacesのpost-upコマンドでスクリプトを呼び出してiptablesを設定するという手法も考えられる(この場合、ipコマンド等を使ってIP/Netmask等を取得できるので、スクリプト中にWANやLANのアドレスを埋め込まなくて良いという利点が考えられる)が、その場合NICが活性化してからiptablesの設定がされることになり、瞬間的にではあるがLinkUPしたにも関わらずFWが未設定という状態になるのでよろしくないと思われる。
  • eth0がLAN側で192.168.100.254/24、eth1~ethNがWAN(マルチホーム等)の時、条件の逆転「!」を使うことで、iptablesのルール数を減らすべく、以下のようにIP Spoofing防御設定まとめられる思えるが、実際には問題がある。
    sudo iptables -t raw -N LOG_SPOOF
    sudo iptables -t raw -A LOG_SPOOF -j LOG --log-prefix "[IP-SPOOFING]: "
    sudo iptables -t raw -A LOG_SPOOF -j DROP
    sudo iptables -t raw -A PREROUTING -i !   lo -s    127.0.0.0/8 -j LOG_SPOOF
    sudo iptables -t raw -A PREROUTING -i ! eth0 -s     10.0.0.0/8 -j LOG_SPOOF
    sudo iptables -t raw -A PREROUTING -i ! eth0 -s  172.16.0.0/12 -j LOG_SPOOF
    sudo iptables -t raw -A PREROUTING -i ! eth0 -s 192.168.0.0/16 -j LOG_SPOOF
    
    • ping 192.168.100.254 (=eth0)が通らない
      Jul  4 07:07:28 ubuntu-napt kernel: [136737.367943] [IP-SPOOFING]: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.100.254 DST=192.168.100.254 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=40230 SEQ=1
      Jul  4 07:07:29 ubuntu-napt kernel: [136738.366434] [IP-SPOOFING]: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.100.254 DST=192.168.100.254 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=40230 SEQ=2
      
      • 「IN=lo」となっていることから考えると、192.168.100.254=eth0だが実際にはloopbackに送られているためおかしくなる。
    • WANの数だけルールを列挙するしかなさそう?
  • filter table以外を/etc/ufw/*.rulesに書くと、ufw startで反映はされるがufw stopで消去されないので設定が累積していく
    • interfaces pre-upとかに入れるのがよさそう… => スクリプトを作成 => #setfilter

sample script

setnapt.sh

  • for Ubuntu
  • WANデバイス毎にIP MASQUERADEを設定
  • /etc/network/interfaces にて、LANデバイスの活性化時に自動呼び出しされるようにして使用
    auto eth0
    iface eth0 inet static
            address 192.168.100.254
            netmask 255.255.255.0
            post-up /root/setnapt.sh eth1 eth2
            post-down /root/setnapt.sh
    
    • 上の例ではWANはeth1,2ということになる

setfilter

  • for Ubuntu
  • raw, mangle tableを使って不要・異常なパケットを落とすポリシーを起動時自動登録
  • /etc/init.d/setfilter start/stop
  • source:/trunk/iptables/ufw と併せて使用
  • sudo update-rc.d setfilter start 39 S .
    • /etc/rcS.d/S39setfilter -> ../init.d/setfilter

ufw/

  • for Ubuntu
  • /etc/ufw/*.rules に配置
  • see [12]
    • LANがeth0, WANがeth1という想定
    • LAN => 192.168.100.0/24
    • IP MASQUERADEについては#setnapt.shで設定
    • LAN -> GW ->WAN の通信は通過
    • WAN -> GW は拒否
    • after.rules, before.rules については既存のルールに追加