|Home|私のLinux活用記録-Home-|

私のLinux活用記録

-Page17-

項目

kh17-01[パケットフィルタリングとファイアーウォール]
kh17-02[bash シェルスクリプトの基礎知識]

 

[パケットフィルタリングとファイアーウォール]

作成:2004年02月22日
追記:2004年03月01日

1月中旬頃に、ルーター兼公開 Web Server として運転していた IBM Aptiva E-133 が突然異音を発しだしたため、他のマシンにルーター機能と公開 Web Server を移しました。その後しばらく様子を見た結果、CPU 冷却用のファンが異音を出していることが判ったので、ファンを交換して、もとのルーター兼公開 Web Server として使うことにしたのですが、これを機会に、今までの簡易なパケットフィルタリングで済ましていたファイアーウォール機能を見直しました。

iptables を用いたきめ細かいパケットフィルタリングと、/proc/sys/net/ipv4/ 配下のカーネルパラメーター設定を利用した、ネットワーク攻撃防御機能の使用について、実施した内容を掲載することにしました。

[参考]
http://www.linux.or.jp/JF/JFdocs/Security-Quickstart-HOWTO/
http://www.linux.or.jp/JF/JFdocs/packet-filtering-HOWTO.html
http://dellpcc.dyndns.org/report/linux3.shtml#iptables
http://www.kkoba.com/linuxrouter/iptables.shtml
http://yaguma.com/Server/linuxrouter.html
http://www.servj.com/pc/howto/rh73_3.html
http://search.luky.org/linux-users.8/msg07392.html
/usr/src/linux/Documentation/networking/ip-sysctl.txt

kh17-01.01 ネットワークの構成と通信経路の概略図
kh17-01.02 ネットワークの構成と通信経路の説明
kh17-01.03 パケットフィルタリングの基本方針
kh17-01.04 iptables を実行する bash シェルスクリプトとその説明
kh17-01.05 カーネルパラメーター設定による攻撃防御の方法

戻る

ネットワークの構成と通信経路の概略図

    │
internet│pannna.zive.net 192.168.1.3            192.168.1.2
    │  ppp0     eth0               eth0
    │  ┏━━━━━━━┓               ┏━━━━━━┓
┌───┼←─╂←──────╂←──────A───────╂←────┐┃
└───┼─→╂──────→╂───────A──────→╂────┐│┃
    │  ┃  ┌────╂←──────B───────╂←──┐││┃
    │  ┃  │┌──→╂───────B──────→╂──┐│││┃
        │  ┃  ││   ┃ ┌─────C───────╂←┐││││┃
    │  ┃  ││   ┃  │┌────C──────→╂┐│││││┃
    │  ┃  ││   ┃ ││ 192.168.1.1      ┃││││││┃
    │  ┃  ││   ┃ ││ eth0          ┠┼┼┼┼┼┼┨
    │  ┃  ││   ┃ ││ ┏━━━━━━┓   ┃↓↑↓↑↓↑┃
    │  ┃  ││   ┃ │└─╂←────┐┃   ┃      ┃
    │  ┃  ││   ┃ └─→╂────┐│┃   ┃Local Client┃
←E──┼←─╂←─│────╂←───╂←──┐││┃   ┗━━━━━━┛
─E──┼─→╂───│──→╂───→╂──┐│││┃      gw450
←D──┼←─╂←┐││┌──╂←─F─╂←┐││││┃    Linux & Windows
─D─→┼─→╂┐││││┌→╂──F→╂┐│││││┃
    │  ┃↓│↓│↓│ ┃    ┃││↓│↓│┃
    │  ┠┼┼┼┼┼┼─┨    ┠┼┼┼┼┼┼┨
    │  ┃│↑│↑│↑ ┃    ┃↓↑│↑│↑┃
    │  ┃└┘└┘└┘ ┃    ┃  └┘└┘┃
    │  ┃  Router   ┃    ┃SSH2 Server ┃
    │  ┃ Web Server  ┃    ┃Local Server┃
    │  ┃Local Server ┃    ┃(telnet,ftp,┃
    │  ┃(telnet,ftp) ┃    ┃nfs,smb,ppp)┃
    │  ┃    ┌┐ ┃    ┃   ┌┐ ┃
    │  ┃  ↓↑│↓ ┃    ┃ ↑↓│↓ ┃      Remote Host
    │  ┠──┼┼┼┼─┨    ┠─┼┼┼┼─┨     ┏━━━━━┓
┌─I─┼←─╂←─┘│↑│ ┃    ┃ ││↑└→╂──G──╂→    ┃
└─I─┼─→╂───┘││ ┃    ┃ ││└──╂←─G──╂← PPP  ┃
    │  ┃    │└→╂───→╂──│──→╂──H──╂→ Client ┃
    │  ┃    └──╂←───╂←│────╂←─H──╂←    ┃
┌─J─┼─→╂──────→╂───→╂─┘│   ┃     ┃     ┃
└─J─┼←─╂←──────╂←───╂←─┘   ┃     ┃     ┃
    │  ┗━━━━━━━┛    ┗━━━━━━┛     ┗━━━━━┛
    │  ppp0     eth0    eth0     ppp0    ppp
    │panna.zive.net 192.168.1.3 192.168.1.1 192.168.1.4 192.168.1.5
    │
    │     ibm133          ph700             gw350
    │   Vine Linux2.6      Vine Linux2.6      Linux & Windows

戻る

ネットワークの構成と通信経路の説明

■ibm133
ルーター兼公開 Web Server
■ph700
公開 SSH2 Server(必要時のみ限定稼働) 兼ローカルサーバー(Samba, NFS, PPP Server)
■gw450
ローカルクライアント
■gw350
遠隔地にあるクライアント、PPP 接続またはインターネット経由で SSH2 Server に接続。

本来、ルーターと公開 Web Server は分離すべきなのですが、限られた機械台数ではこの選択がベターであると判断しています。ibm133 をルーター機能だけにした場合、ph700 で公開 Web Server を稼働することになりますが、ph700 はローカルサーバーとして、Samba や NFS Server などセキュリティー上リスクの大きいサーバーを稼働しているので、これに公開 Web Server をのせるのは危険性がさらに増大すると判断しました。また、ibm133 に侵入された場合と、ph700 に侵入された場合の被害の大きさは、圧倒的に後者の方が大きいのもこの判断の理由です。

次に、上図の各ルート(A〜J) について説明します。その前に各マシンのルーティングがどうなっているかを簡単に紹介します。各マシンのターミナル上で、$ netstat -r を実行すると、現在のルーティングテーブルが表示されます。下記がその結果です(一部表示項目を省略)。

ibm133
受信先サイト    ゲートウェイ     ネットマスク    フラグ    インターフェース
ISP_GATE_WAY    *                255.255.255.255 UH        ppp0
192.168.1.0     *                255.255.255.0   U         eth0
127.0.0.0       *                255.0.0.0       U         lo
default         ISP_GATE_WAY     0.0.0.0         UG        ppp0

ph700
受信先サイト    ゲートウェイ     ネットマスク    フラグ    インターフェース
192.168.1.0     *                255.255.255.0   U         eth0
127.0.0.0       *                255.0.0.0       U         lo
default         ibm133.LOCAL_NET 0.0.0.0         UG        eth0

ph700(PPP 接続時)
受信先サイト    ゲートウェイ     ネットマスク    フラグ    インターフェース
192.168.1.5     *                255.255.255.255 UH        ppp0
192.168.1.0     *                255.255.255.0   U         eth0
127.0.0.0       *                255.0.0.0       U         lo
default         ibm133.LOCAL_NET 0.0.0.0         UG        eth0

gw450
受信先サイト    ゲートウェイ     ネットマスク    フラグ    インターフェース
192.168.1.0     *                255.255.255.0   U         eth0
127.0.0.0       *                255.0.0.0       U         lo
default         ibm133.LOCAL_NET 0.0.0.0         UG        eth0

このローカルネットワークのデフォルトゲートウェイは ibm133 で、ibm133 からは ppp0 を通じてプロバイダーのゲートウェイマシンにつながっていることが判ります。

デフォルトゲートウェイとは、ルーティングテーブルに受信先として定義されていない宛先に対して、その通信を中継するための中継機です(私のネットワークでは、外部との通信は全て ibm133 を中継して行われます)。

また、ph700(PPP Server) に gw350(Remote Host) から PPP 接続があった場合、ph700 から gw350 宛の通信は ph700 の ppp0 を通じて行われます。

各ルートA〜B について説明します。

■A route
ローカルネットワーク内の全てのホストからインターネットに出ていくためのものです。
■B route
ibm133(Router & 公開 Web Server) を管理するため、特定のローカルホストから、ftp と telnet の通信だけを行うルートです。
■C route
ローカルネットワーク内の全てのホストが、ph700(Local Sever) の Samba, NFS Server にアクセスするためのルートであると同時に、ph700 を管理するため特定のローカルホストから、ftp と telnet の通信をおこなうルートでもあります。
■D route
インターネット側に ibm133 の Web Server を開放するするためのものです。
■E route
外部からインターネット経由で、ph700(公開 SSH2 Sever) に SSH2 による通信を行うためのものです。遠隔地の gw350(Remote Host) から ph700 の管理と sftp によるファイル転送に使います。
■F route
上記 E route と併用して、遠隔地からインターネット経由で ibm133(Router & 公開 Web Server) を管理するためのものです。すなわち、インターネットから SSH2 で ph700(公開 SSH2 Server) に接続し、さらに、ph700 から ftp or telnet で ibm133 と通信するようにします。
■G route
遠隔地の gw350(Remote Host) から PPP 接続で ph700(PPP Server) と通信するルートです。ftp と telnet を使って、ph700 を管理します。
■H route
上記 G route と基本的には同じですが、ph700(PPP Server) を経由して ibm133(Router & 公開 Web Server) と通信するルートです。ftp と telnet を使って、ibm133 を管理します。
■I route
本来、このルートは使用すべきではないのですが、DiCE および ibm133(Router & 公開 Web Server) のメンテナンス(apt-get)のため、dns, http, https による外部への通信に使います。
■J route
I route と同様、このルートも定常的に使用すべきではありませんが、ph700 のメンテナンスのため、apt-get を行うときのみ使用します。

戻る

パケットフィルタリングの基本方針

  • 基本ポリシーを DROP として、必要なパケットだけを ACCEPT します。
    • ICMP のパケットは、明示的に全て DROP (安全のため)
    • 双方向接続の確立したパケットは、全て ACCEPT
  • パケットの適合ルールは、可能なかぎり、インターフェース、アドレス、プロトコル、ポート番号、ステータスを記述して限定することとします。

このポリシーを採用するメリットは、自分が必要とするサービスを可能にするためには、どのような性質のパケットを通す必要があるのかを理解して設定する必要があり、厳密なパケットフィルタリングが実現できることにあります。根気のいる作業を伴いますが、より安全なファイアーウォール実現のためには、有効な方針だと思います。

ibm133 (Router & 公開 Web Server)

■FORWARD
FORWARD に対するパケットフィルタリングは、ルーター機能の要です。以下の方針でフィルタリングします。

  • ローカルホストから外部への FORWARD は、ftp(passive), smtp, dns, http, pop-3, https に限定します。
    • http と https は外部ホームページへのアクセス
    • ftp(passive) は外部 FTP サイトへのアクセス
    • smtp と pop-3 は、メールの送受信
    • dns は、上記を実行するのに必要なインターネット側の名前解決
    に必要です。
  • ph700(Local Server) から外部への FORWARD は、通常禁止しますが、apt-get 実行時のみ許可します。
  • インターネット経由で ph700 および ibm133 を管理するため、外部から 公開 SSH2 Server への接続は ph700 に PREROUTING した上で、FORWARD を許可します。

[注意]
ftp の扱いについて、若干補足します。ftp には、active mode と passive mode があります。ルーター越えをする場合に、active mode では、IP マスカレードによってデータ受信用のポート番号が正しく変換されない問題があるため、passive mode を使用する必要があります。

通常ブラウザーで FTP サイトに接続していると気がつきませんが、FTP 専用ソフト(例えば、gFTP など)で接続すると、passive mode に設定しないとうまく接続できないことが判ります。このことについては、
http://www.rtpro.yamaha.co.jp/RT/FAQ/TCPIP/ftp-passive-mode.html
に判りやすく解説されていますので参照してください。

■INPUT
外部からの接続は、http のみ許可します。
内部からの接続は、特定のローカルホストに対して、ftp, telnet, http の接続を許可します。

■OUTPUT
原則は、外部に対しても、内部に対しても接続開始パケットを出さないこと。とはいえ、下記例外を認めています。

  • DiCE を有効にするため、dns と http の外部への接続を許可します。
  • apt-get を実行するために、https も外部への接続を許可します。

ph700 (公開 SSH Server 兼ローカルサーバー)

実のところ、私のネットワークはあまり安全なものではありません。外部に公開するサーバーを持った標準的なネットワークは下記のような構成で、公開サーバーが存在する場所は DMZ(De-Militarized Zone) と呼ばれます。

        (DMZ)
      ┌公開サーバー
ルーター1─┤      ┌ローカルサーバー
      └ルーター2─┤
             └ローカルホスト(Client)
ルーター1、ルーター2とも、本来はパケットを内部処理することはなく、単にパケットの FORWARD を管理するだけです。ルーター1は、公開サーバーとインターネットの間、およびルーター2内部のネットワークとインターネット間の通信を中継するだけです。また、ルーター2は、内部からの接続開始は許可するが、外部からの接続開始は拒否することにより、内部ネットワークの安全を確保します。これによって DMZ が仮に攻撃されても、内部ネットワークの安全が確保できます。

残念ながら、私のネットワークではこれだけの機器が準備できません。

       (DMZ)
     ┌公開サーバー
ルーター─┼ローカルサーバー
     └ローカルホスト(Client)
よりさらに簡略になった
            ┌ローカルサーバー
ルーター(公開サーバー)─┤
            └ローカルホスト(Client)
が私のネットワークで、、疑似 DMZ(と言えるかどうかも?) の状態にあります。ph700(Local Server) は特にセキュリティ上危険度の高いサービス(Samba, NFS) を稼働していますので、厳重なパケットフィルタリングを行う必要があります。以下、パケットフィルタリングの方針です。

■FORWARD
通常 I/F は eth0 だけですが、gw350(Remote Host) からの PPP 接続を想定し、ibm133(Router & 公開 Wevb Server) への FORWARD を許可します(遠隔地から PPP 接続による ibm133 の管理を可能にします)。

■INPUT
ph700 は、公開 SSH2 Server とローカルサーバの機能を兼ねていますので、以下のルールを適用します。

原則 ibm133(Router) からの接続は、許可しませんが、下記例外を認めています。

  • 外部から ibm133 経由で FORWARD された ssh の接続は許可します。

ibm133(Router) を除く内部からの接続については、以下のルールを適用します。

  • Samba と NFS Server への接続は全てのローカルクライアントに対して許可します。
  • ftp と telnet への接続は、PPP 接続の gw350(Remote Host) を含めて、特定のローカルクライアントからのみ許可します。

■OUTPUT
原則は、外部に対しても、内部に対しても接続開始パケットを出さないこと。しかし、以下の例外を認めています。

  • ibm133(公開 Web Server) をインターネット経由で管理するために、gw350(Remote Host) から SSH2 接続を経由して ibm133 への ftp と telnet の接続を許可します。
  • apt-get を実行するときのみ外部への接続を許可します。

gw450 (ローカルクライアント)

■OUTPUT
全ての OUTPUT を許可します。

■INPUT
ESTABLISHED のパケットのみ許可します。

■FORWARD
FORWARD すべきインターフェースはないので、全て拒否します。

戻る

iptables を実行する bash シェルスクリプトとその説明

上記の方針に基づいて、iptables コマンドを用いた bash シェルスクリプトファイルを作成します。bash シェルスクリプトについては別項で説明していますが、普通に bash シェルコマンドを実行するのと基本的には同じです。ファイルの一行目は特別な意味を持った記述ですが、二行目から順次コマンドが実行されます。ルールは、その順番で追加されていき、ルールの適用もその順番でチェックされます。
DROP の対象範囲と ACCEPT の対象範囲に重なりがある場合、ルールの順番によって異なったフィルタリングになることに注意が必要です。
行頭に "#" が付いている行は、コメントですので処理されません。

ibm133 (Router & Web Server)

setiptables_rw.sh for router & web server

line| ------------------------------start------------------------------
 01 | #!/bin/sh
 02 |
 03 | # Clear rule
 04 | /sbin/iptables -F
 05 | /sbin/iptables -t nat -F
 06 |
 07 | # Policy
 08 | /sbin/iptables -P FORWARD DROP
 09 | /sbin/iptables -P INPUT DROP
 10 | /sbin/iptables -P OUTPUT DROP
 11 |
 12 | # IP Masquerade
 13 | /sbin/iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ppp0 -j MASQUERADE
 14 |
 15 | # DROP specific IP in INPUT Chain
 16 | /sbin/iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP
 17 |
 18 | # ACCEPT lo
 19 | /sbin/iptables -A INPUT -i lo -s 127.0.0.1 -j ACCEPT
 20 | /sbin/iptables -A OUTPUT -o lo -d 127.0.0.1 -j ACCEPT
 21 |
 22 | # Drop ICMP packet
 23 | /sbin/iptables -A FORWARD -p icmp -j DROP
 24 | /sbin/iptables -A INPUT -p icmp -j DROP
 25 | /sbin/iptables -A OUTPUT -p icmp -j DROP
 26 |
 27 | # ACCEPT ESTBLISHED Packet
 28 | /sbin/iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
 29 | /sbin/iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
 30 | /sbin/iptables -A OUTPUT -m state --state ESTABLISHE -j ACCEPT
 31 |
 32 | # E route: internet-->[router]-->ssh2 server(192.168.1.1)-->[router]-->internet
 33 | # (ssh: 22)
 34 | #/sbin/iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 22 -j DNAT →
    |               →--to-destination 192.168.1.1:22
 35 | #/sbin/iptables -A FORWARD -i ppp0 -d 192.168.1.1 -p tcp --dport 22 →
    |               →-m state --state NEW -j ACCEPT
 36 |
 37 | # A route: 192.168.1.0/24-->[router]-->internet-->[router]-->192.168.1.0/24
 38 | # J route: 192.168.1.1-->[router]-->internet-->[router]-->192.168.1.1
 39 | # (ftp passive: 21,1024-; smtp: 25; dns: 53; http: 80; pop3: 110; https: 443)
 40 | /sbin/iptables -A FORWARD -i eth0 -s 192.168.1.1 -j DROP
 41 | /sbin/iptables -A FORWARD -i eth0 -s 192.168.1.0/24 -p tcp --dport 21 →
    |              →-m state --state NEW -j ACCEPT
 42 | /sbin/iptables -A FORWARD -i eth0 -s 192.168.1.0/24 -p tcp --dport 1024: →
    |              →-m state --state NEW -j ACCEPT
 43 | /sbin/iptables -A FORWARD -i eth0 -s 192.168.1.0/24 -p tcp --dport 25 →
    |              →-m state --state NEW -j ACCEPT
 44 | /sbin/iptables -A FORWARD -i eth0 -s 192.168.1.0/24 -p udp --dport 53 →
    |              →-m state --state NEW -j ACCEPT
 45 | /sbin/iptables -A FORWARD -i eth0 -s 192.168.1.0/24 -p tcp --dport 80 →
    |              →-m state --state NEW -j ACCEPT
 46 | /sbin/iptables -A FORWARD -i eth0 -s 192.168.1.0/24 -p tcp --dport 110 →
    |              →-m state --state NEW -j ACCEPT
 47 | /sbin/iptables -A FORWARD -i eth0 -s 192.168.1.0/24 -p tcp --dport 443 →
    |              →-m state --state NEW -j ACCEPT
 48 |
 49 | # B route: 192.168.1.2-->[web, local server]-->192.168.1.2
 50 | # B route: 192.168.1.0/29-->[local server]-->192.168.1.0/29
 51 | # F route: 192.168.1.1-->[local server]-->192.168.1.1
 52 | # H route: remote host-->ppp server-->[local server]-->ppp server-->remote host
 53 | # (ftp passive: 21,1024-; telnet: 23; http: 80)
 54 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/29 -p tcp --dport 21 →
    |              →-m state --state NEW -j ACCEPT
 55 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/29 -p tcp --dport 1024: →
    |              →-m state --state NEW -j ACCEPT
 56 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/29 -p tcp --dport 23 →
    |              →-m state --state NEW -j ACCEPT
 57 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.2 -p tcp --dport 80 →
    |              →-m state --state NEW -j ACCEPT
 58 |
 59 | # D route: internet-->[web server]-->internet
 60 | # (http: 80)
 61 | /sbin/iptables -A INPUT -i ppp0 -p tcp --dport 80 →
    |              →-m state --state NEW -j ACCEPT
 62 |
 63 | # I route: [router]-->internet-->[router] for DiCE & apt-get
 64 | # (dns: 53; http: 80)
 65 | /sbin/iptables -A OUTPUT -o ppp0 -p udp --dport 53 →
    |              →-m state --state NEW -j ACCEPT
 66 | /sbin/iptables -A OUTPUT -o ppp0 -p tcp --dport 80 →
    |              →-m state --state NEW -j ACCEPT
 67 | /sbin/iptables -A OUTPUT -o ppp0 -p tcp --dport 443 →
    |              →-m state --state NEW -j ACCEPT
    | -------------------------------end-------------------------------

setiptables_rw.sh ファイルを例えば、/usr/local/sbin/ 配下に配置した場合、
# cd /usr/local/sbin/
# ./setiptables_rw.sh
とすれば、setiptables_rw.sh が実行されます。
設定した iptables のルールを保存し、コンピューターが再起動したときに このルールが適用されるようにするには、
# iptables-save > /etc/sysconfig/iptables
を実行しておきます。

[説明]

[パケットフィルタリングの基本方針] で説明した内容と重複しますが、以下簡単な説明を加えました。

line 01
このファイルが、bash シェルスクリプトであることを宣言する文です。
line 04-05
filter table と nat table をクリアーします。
line 08-10
FORWARD, INPUT, OUTPUT 各 Chain のデフォルトポリシー(全てのフィルタリングルールに適合しないパケットに対して適用されるルール) を DROP にします。
line 13
ローカルホスト(192.168.1.0/24) から外部に出るパケットを、IP Masquerade します。
line 16
特定の外部 IP Address からの接続を拒否します。
line 19-20
localhost(127.0.0.1) の内部インターフェース(lo) の INPUT と OUTPUT を許可します。
line 23-25
ICMP プロトコルのパケットを明示的に拒否します。ICMP プロトコルは、本来通信エラーが発生したときに、相手にエラーを通知するためのプロトコルですが、各種攻撃(ping of death や Smuff 攻撃、ポートスキャン、ブロードキャスト宛エコー要求など) に悪用されるプロトコルでもあり、全面的に拒否することにしています。通信エラーが発生した場合に、相手にエラー通知できないというデメリットがありますが、実質的には大きな不都合にはならないようです。
line 28-30
ESTABLISHED なパケットは、FORWARD, INPUT, OUTPUT とも許可します。ESTABLISHED は、単に ACK フラグをチェックするだけでなく、パケットの履歴をチェックして、双方向接続が確立したパケットに適用されます。従って、以降のフィルタリングルールでは、NEW のパケットに対してのみルールを記述しています。
line 34-35
ph700(公開 SSH2 Server) を稼働するときだけ使用します。nat table を使って ph700 に PREROUTING した後、FORWARD を許可します。
line 40-47
内部ローカルホスト(Client) から外部への ftp(passive), smtp, dns, http, pop-3, https のパケットの FORWARD を許可します。ただし、ph700(Local Server) から外部への FORWARD は許可しません。
line 54-57
特定ローカルホスト(192.168.1.0/29) からの ftp と telnet の INPUT を許可します。
私のネットワークでは、実質的には全てのマシンが 192.168.1.0/29 の範囲にありますが、ルーター、サーバー、および管理用ホストを 192.168.1.0/29 とし、その他一般のローカルホスト(ルーターから見た場合、FORWARD するだけの Client) を含める場合(実際には存在していませんが) は、192.168.1.0/24 としています。
ftp(passive) では、通信の制御に port 21 が使われ、データの送信には、1024-65535 の不特定ポートが使用されます。クライアントからの送信要求を不特定ポートで受け取り、そのポートからデータが送信されます。不特定ポートが INPUT ポートに使用されるというのはあまり好ましくはありませんが、内部の特定ローカルホストに対してのみ許可することで、安全を確保しています。
内部から公開 Web Server へのアクセスは、192.168.1.2(管理用ローカルホスト) にのみ許可します。
[2004.03.01 追記]
ftp(active) では、データ送信に port 20 が使用されます。サーバー側 port 20 からデータ送信開始要求がクライアントに送られるので、クライアントでは、それを受け取る必要があります。そのためのパケットフィルタリングは、以下のようになります。
サーバー側(ibm133 / line 55)
/sbin/iptables -A OUTPUT -o eth0 -d 192.168.1.0/29 -p tcp --sport 20 →
             →-m state --state NEW -j ACCEPT
クライアント側(gw450 / 追加)
/sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/29 -p tcp --sport 20 →
             →-m state --state NEW -j ACCEPT
passive を使うか、active を使うかは迷うところですが、サーバー側の安全性を重視すれば active, クライアント側の安全性を重視すれば passive ということになるでしょう。
line 61
外部から Web Server へのアクセス(http の INPUT) を許可します
line 65-67
ルーター自身から外部へ、dns, http, https の OUTPUT を許可します。前述したように、DiCE と apt-get を有効にするために必要です。

ph700 (公開 SSH2 Server & Local Server)

setiptables_sl.sh for ssh server & local server

line| ------------------------------start------------------------------
 01 | #!/bin/sh
 02 |
 03 | # Clear rule
 04 | /sbin/iptables -F
 05 | /sbin/iptables -t nat -F
 06 |
 07 | # Policy
 08 | /sbin/iptables -P FORWARD DROP
 09 | /sbin/iptables -P INPUT DROP
 10 | /sbin/iptables -P OUTPUT DROP
 11 |
 12 | # Drop specific IP in INPUT Chain
 13 | /sbin/iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP
 14 |
 15 | # ACCEPT lo
 16 | /sbin/iptables -A INPUT -i lo -s 127.0.0.1 -j ACCEPT
 17 | /sbin/iptables -A OUTPUT -o lo -d 127.0.0.1 -j ACCEPT
 18 |
 19 | # Drop ICMP packet
 20 | /sbin/iptables -A FORWARD -p icmp -j DROP
 21 | /sbin/iptables -A INPUT -p icmp -j DROP
 22 | /sbin/iptables -A OUTPUT -p icmp -j DROP
 23 |
 24 | # ACCEPT ESTABLISHED Packet
 25 | /sbin/iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
 26 | /sbin/iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
 27 | /sbin/iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
 28 |
 29 | # C route: 192.168.1.0/29-->[local server]-->192.168.1.0/29 \
    |            for telnet, ftp, samba & nfs
 30 | # C route: 192.168.1.0/24-->[local server]-->192.168.1.0/24 for samba & nfs
 31 | # (ftp passive: 21,1024-; telnet: 23; smb:137-139; nfs: 111,2049,32769-32770)
 32 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.3 \
    |                -m state --state NEW,INVALID -j DROP
 33 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/29 -p tcp --dport 21 →
    |              →-m state --state NEW -j ACCEPT
 34 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/29 -p tcp --dport 1024: →
    |              →-m state --state NEW -j ACCEPT
 35 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/29 -p tcp --dport 23 →
    |              →-m state --state NEW -j ACCEPT
 36 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/24 -p tcp --dport 139 →
    |              →-m state --state NEW -j ACCEPT
 37 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/24 -p udp --dport 137:138 →
    |              →-m state --state NEW -j ACCEPT
 38 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/24 -p tcp --dport 111 →
    |              →-m state --state NEW -j ACCEPT
 39 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/24 -p udp --dport 111 →
    |              →-m state --state NEW -j ACCEPT
 40 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/24 -p udp --dport 2049 →
    |              →-m state --state NEW -j ACCEPT
 41 | /sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/24 -p udp --dport 32769:32770 →
    |              →-m state --state NEW -j ACCEPT
 42 | /sbin/iptables -A OUTPUT -o eth0 -d 192.168.1.0/24 -p udp --sport 137:138 →
    |              →-m state --state NEW -j ACCEPT
 43 |
 44 | # F route: [local client]-->router-->[local client] for telnet & ftp
 45 | # (ftp passive: 21,1024-; telnet: 23)
 46 | /sbin/iptables -A OUTPUT -o eth0 -d 192.168.1.3 -p tcp --dport 21 →
    |              →-m state --state NEW -j ACCEPT
 47 | /sbin/iptables -A OUTPUT -o eth0 -d 192.168.1.3 -p tcp --dport 1024: →
    |              →-m state --state NEW -j ACCEPT
 48 | /sbin/iptables -A OUTPUT -o eth0 -d 192.168.1.3 -p tcp --dport 23 →
    |              →-m state --state NEW -j ACCEPT
 49 |
 50 | # J route: [local client]-->router-->internet-->router-->[local client] →
    |               →for apt-get
 51 | #/sbin/iptables -A OUTPUT -o eth0 -m state --state NEW -j ACCEPT
 52 |
 53 | # E route: internet-->router-->[ssh2 server]-->router-->internet
 54 | # (ssh: 22)
 55 | /sbin/iptables -A INPUT -i eth0 -p tcp --dport 22 →
    |              →-m state --state NEW -j ACCEPT
 56 |
 57 | # H route: remote host-->[ppp server]-->remote host
 58 | /sbin/iptables -A FORWARD -i ppp0 -j ACCEPT
 59 | /sbin/iptables -A FORWARD -o ppp0 -j ACCEPT
 60 | /sbin/iptables -A INPUT -i ppp0 -j ACCEPT
 61 | /sbin/iptables -A OUTPUT -o ppp0 -j ACCEPT
    | -------------------------------end-------------------------------

setiptables_sl.sh ファイルを例えば、/usr/local/sbin/ 配下に配置した場合、
# cd /usr/local/sbin/
# ./setiptables_sl.sh
とすれば、setiptables_sl.sh が実行されます。
設定した iptables のルールを保存し、コンピューターが再起動したときに このルールが適用されるようにするには、
# iptables-save > /etc/sysconfig/iptables
を実行しておきます。

[説明]

[パケットフィルタリングの基本方針] で説明した内容と重複しますが、以下簡単な説明を加えました。

line 01, 04-05, 08-10, 13, 16-17, 20-22, 25-27 は、ibm133(Router & 公開 Web Server) での説明と同じです。

line 32-42
ローカルホストから内部サーバーへのアクセスを許可するルールです。ftp と telnet は、192.168.1.0/29(ルーターとサーバーの管理に使うローカルホスト) からの接続だけ許可しています。Samba, NFS Server への接続は、全てのローカルホストに対して許可します。ただし、ibm133(Router) からの接続は、全て拒否します。
Samba, NFS Server への接続に使われるプロトコルと port は、テストによって必要性が確認できたものに絞りこんでいます。
特に、NFS Server は複雑です。NFS Server 上で # rpcinfo -p コマンドを実行し、使用しているプロトコルと port 番号を確かめます。下記が私の環境での結果です。
プログラム バージョン プロトコル ポート
100000     2          tcp          111  portmapper
100000     2          udp          111  portmapper
100024     1          udp        32768  status
100024     1          tcp        32768  status
100011     1          udp          738  rquotad
100011     2          udp          738  rquotad
100005     1          udp        32769  mountd
100005     1          tcp        32769  mountd
100005     2          udp        32769  mountd
100005     2          tcp        32769  mountd
100005     3          udp        32769  mountd
100005     3          tcp        32769  mountd
100003     2          udp         2049  nfs
100003     3          udp         2049  nfs
100021     1          udp        32770  nlockmgr
100021     3          udp        32770  nlockmgr
100021     4          udp        32770  nlockmgr
これらのプロトコルと port 番号について、本当に必要なものをテストして確認します。テストの結果、udp port 738(rquotad), tcp port 32768(status), udp port 32768(status), tcp port 32769(mountd) の INPUT は許可する必要がないことが判りました。
また、Samba では、udp port 137-138 の OUTPUT を ACCEPT する必要があるのが要点ですが、tcp port 137-138, udp port 139 の INPUT を許可する必要はありませんでした。
line 46-48
これは少し複雑なルートを想定したルールです。まず、gw350(Remote Host) から ph700(SSH2 Sever) に SSH2 プロトコルによる接続が成立しているとします。このルールは、その ph700 からさらに ibm133(Router & 公開 Web Server) に ftp or telnet 接続することを許可するルールです。ここでは、ph700 から ibm133 への ftp と telnet パケットの OUTPUT を許可しています。
[参考]
コンピューターが現在開いていて、監視しているプロトコルとポートは、
# netstat -tuap または # netstat -tuapn で確認できます。開かれているポートで、不要なものはそのポートを使用しているサービスを停止するか、停止できなければ全て DROP にしておくべきです。
line 55
ibm133(Router) から FORWARD された ssh パケット の INPUT を許可します。
line 58-61
gw350(Remote Host) からの PPP 接続を介したパケットに対して、FORWARD, INPUT, OUTPUT を許可します。FORWARD の許可は、ibm133(Router & 公開 Web Server) への ftp と telnet の接続を許可するためです。

gw450 (Local Client)

setiptables_lc.sh for local client

line| ------------------------------start------------------------------
 01 | #!/bin/sh
 02 |
 03 | # Clear rule
 04 | /sbin/iptables -F
 05 | /sbin/iptables -t nat -F
 06 |
 07 | # Policy
 08 | /sbin/iptables -P INPUT DROP
 09 | /sbin/iptables -P FORWARD DROP
 10 | /sbin/iptables -P OUTPUT DROP
 11 |
 12 | # ACCEPT lo
 13 | /sbin/iptables -A INPUT -i lo -s 127.0.0.1 -j ACCEPT
 14 | /sbin/iptables -A OUTPUT -o lo -d 127.0.0.1 -j ACCEPT
 15 |
 16 | # Drop ICMP packet
 17 | /sbin/iptables -A INPUT -p icmp -j DROP
 18 | /sbin/iptables -A OUTPUT -p icmp -j DROP
 19 | 
 20 | # A route: [local client]-->router-->internet-->router-->[local client]
 21 | # B route: [local client]-->web server & local ssever-->[local client]
 22 | /sbin/iptables -A OUTPUT -o eth0 -m state --state NEW,ESTABLISHED -j ACCEPT
 23 | /sbin/iptables -A INPUT -i eth0 -m state --state ESTABLISHED -j ACCEPT
    | -------------------------------end-------------------------------

setiptables_lc.sh ファイルを例えば、/usr/local/sbin/ 配下に配置した場合、
# cd /usr/local/sbin/
# ./setiptables_lc.sh
とすれば、setiptables_lc.sh が実行されます。
設定した iptables のルールを保存し、コンピューターが再起動したときに このルールが適用されるようにするには、
# iptables-save > /etc/sysconfig/iptables
を実行しておきます。

[説明]

[パケットフィルタリングの基本方針] で説明した内容と重複しますが、以下簡単な説明を加えました。

line 04-05, 08-10, 13-14, 17-18 は ibm133(Router & 公開 Web Server) での説明と同じです。

line 22-23
OUTPUT は、特にプロトコル、ポートの指定はせず、NEW と ESTABLISHED を指定するだけです。INPUT は ESTABLISHED のみ許可します。

戻る

カーネルパラメーター設定による攻撃防御の方法

/proc/sys/net/ipv4/ 配下にある特殊ファイルはカーネル実行時のパラメーターを設定できるようになっています。これらのパラメーターの中には、外部からの攻撃を防御する機能が含まれているので、これを有効化または無効化します。
これらの設定は、以下のような bash シェルスクリプトファイルを作成し実行することにより行われますが、設定を定常的に有効にするには、/etc/sysctl.conf を編集するか、/etc/rc.d/rc.local ファイルに設定スクリプトを書き込んで、コンピュータ起動時に有効にする方法もあります。

[参考] /etc/sysctl.conf(カーネルのパラメータ設定ファイル)について
/etc/sysctl.conf は、カーネル実行時に、カーネルパラメータを修正する sysctl コマンドの設定ファイルです。
http://itpro.nikkeibp.co.jp/members/LIN/LIN_CONTENTS/20020531/3/sysctl.shtml を参照

anti_atack.sh : kernel parameter setting for anti-atack 
------------------------------start------------------------------
#!bin/sh

# Anti-spoofing blocks
if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] ; then
   for f in /proc/sys/net/ipv4/conf/*/rp_filter ; do
     echo 1 > $f
   done
fi

# Ensure source routing is OFF
if [ -e /proc/sys/net/ipv4/conf/all/accept_source_route ] ; then
   for f in /proc/sys/net/ipv4/conf/*/accept_source_route ; do
     echo 0 > $f
   done
fi

# Ensure TCP SYN cookies protection
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# Ensure ICMP redirect are disabled
if [ -e /proc/sys/net/ipv4/conf/all/accept_redirects ] ; then
   for f in /proc/sys/net/ipv4/conf/*/accept_redirects ; do
     echo 0 > $f
   done
fi

# Ensure ICMP ECHO requests and broadcast/multicast are ignored
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
-------------------------------end-------------------------------

anti_atack.sh ファイルを例えば、/usr/local/sbin/ 配下に配置した場合、
# cd /usr/local/sbin/
# ./anti_atack.sh
とすれば、anti_atack.sh が実行されます。

[説明]

/proc/sys/net/ipv4/ 配下のファイルに、1 が echo されると、そのパラメータが有効になり、0 が echo されると無効となります。各ファイルがどのような機能のカーネルパラメーターを設定するものであるかは、 /usr/src/linux/Documentation/networking/ip-sysctl.txt に記述されています。

Anti-spoofing blocks
送信元 IP Address を内部アドレスに偽装して侵入する攻撃を防ぎます。
Ensure source routing is OFF
source routing とは、パケットの送信者がパケットのネットワーク内での伝送経路を指定する方法です。このようなパケットがきてもルーティングの指定を無効にします。
Ensure TCP SYN cookies protection
TCP プロトコルによる SYN パケットを大量に送りつけて、コンピューターをダウンさせる攻撃から防御します。
Ensure ICMP redirect are disabled
ICMP プロトコルによる ECHO 要求に応答しないようにします。ECHO 要求に応答すると、コンピューターの存在を相手に知らせることになり、攻撃対象の候補になります。
Ensure ICMP ECHO requests and broadcast/multicast are ignored
ICMP プロトコルによる ECHO 要求とブロードキャスト/マルチキャストを受け付けないようにします。ECHO 要求は、Ping of Death 攻撃に利用されます。ブロードキャスト/マルチキャストは、ネットワーク内部の全てのコンピューターにパケットを送りつける機能なので、ネットワークの負荷を増大させネットワークをダウンさせる攻撃を受けることになります。

戻る

[bash シェルスクリプトの基礎知識]

作成:2004年02月22日

bash シェルスクリプトファイルは、bash シェルコマンドが書き込まれたテキストファイルで、そのファイルを実行することによって、そこに書かれた bash シェルコマンドが順番に実行されます。サーバー管理等のために定期的な自動処理を行う場合などに大変重宝します。
さらに便利なのは、変数が使用できる(変数定義と入出力コマンドが用意されている)ことと、制御文が用意されているので、簡単なプログラムが作成できる点です。
iptables を用いた bash シェルスクリプトファイルの作成にあたって整理した必要最低限の基礎知識を掲載しました。

bash シェルスクリプトファイルの作成方法

ここでは、bash シェルスクリプトファイルを SCRIPT_NAME.sh とします。
以下は、ユーザー権限で実行する前提で記述していますが、root 権限でないと実行できないコマンドが含まれている場合は、当然 root 権限で実行する必要があります。

1. SCRIPT_NAME.sh の書き出し
#!/bin/sh <== 一行目に必ず記述する
 
2. 実行権限設定
$ chmod 755 SCRIPT_NAME.sh <== グループ、その他ユーザーにも実行権を与える。
$ chmod 744 SCRIPT_NAME.sh <== グループ、その他ユーザーに実行権を与えない。
 
3. 実行
$ ./SCRIPT_NAME.sh
 
4. ログのファイル出力
$ ./SCRIPT_NAME.sh > LOG_NAME
 
5. エラーログのファイル出力
$ ./SCRIPT_NAME.sh > LOG_NAME 2> ERR_LOG
 
6. ログとエラーログを同一ファイルに出力
$ ./SCRIPT_NAME.sh > LOG_NAME 2>&1
 
7. 文字列の出力
echo "STRING"
echo $VAR_NAME <== $VAR_NMAE は変数 VAR_NAME の値
 
8. ヒアドキュメントの出力
cat << EOS <== EOS と EOS の間に記述されたドキュメントがそのまま出力される。
DOCUMENT LINE_1
DOCUMENT LINE_2
・・・・・・・
EOS
 
9. 変数の定義と値設定
 
文字列変数
VAR_NAME=VALUE
 
数値変数
declare -i VAR_NAME <== VAR_NAME を整数型変数として定義
VAR_NAME=NUMBER
 
10. 変数値の各種入力方法
 
変数に直接、値を設定する
VAR_NAME=VALUE
VAR_NAME=NUMBER <== VAR_NAME は、数値変数として定義されている。
 
bash シェルスクリプト実行時に、変数値を引数として渡す
./SCRIPT_NAME.sh VALUE_1 VALUE_2 ...
SCRIPT_NAME.sh 内では、$1, $2, ... が、VALUE_1, VALUE_2, ... に対応する値となる。
$* は、$1, $2, ... 全てを意味する。$0 は、SCRIPT_NAME.sh そのものが値となる。
$1, $2, ... を特定の変数に読み込むには、
VAR_NAME_1=$1
VAR_NAME_2=$2
・・・・・・
とする。
 
ターミナルスクリーンより変数値を入力する
read VAR_NAME_1 VAR_NAME_2 ...
 
変数の値に、特定の処理の結果を与える
VAR_NAME=`処理コマンド`
 
変数の値をファイルから入力する
VAR_NAME=`cat FILE_NAME` <== FILE_NAME の1行目に、変数値が書き込まれている
 
11. 変数値の各種出力方法
 
ターミナルスクリーンに出力する
echo $VAR_NAME
 
ファイルに上書き出力する
echo $VAR_NAME > FILE_NAME
 
ファイルに追加書き込みで出力する
echo $VAR_NAME >> FILE_NAME
 
特定の処理に変数値を渡す
echo $VAR_NAME | 処理コマンド
 
12. 変数に対するパターンマッチ
 
${変数#パターン}
変数の内容について、最初の部分とパターンがマッチしたら、最も短く一致する部分を取り除いた残りの部分を返す。
 
${変数##パターン}
変数の内容について、最初の部分とパターンがマッチしたら、最も長く一致する部分を取り除いた残りの部分を返す。
 
${変数%パターン}
変数の内容について、最後の部分とパターンがマッチしたら、最も短く一致する部分を取り除いた残りの部分を返す。
 
${変数%%パターン}
変数の内容について、最後の部分とパターンがマッチしたら、最も長く一致する部分を取り除いた残りの部分を返す。
 
13. if 文
if 条件文
   then
   実行文

elseif 条件文 <== 使わなくてもよいし、何回使ってもよい
   実行文

else        <== 使わなくてもよいし、1回だけ使ってもよい
   実行文
fi

条件文:[ 条件式 ]
条件式
s1 = s2 :文字列s1とs2が等しい
s1 != s2 :文字列s1とs2が等しくない
n1 -eq n2:数値n1とn2が等しい
n1 -ne n2:数値n1とn2が等しくない
-e file :fileが存在する
-z s1  :s1の長さが0である
14. while 文
while 条件文
do
   実行文
done

条件文:if 構文の場合と同じ
15. for 文
for 識別子 in リスト
do
   $識別子 を使う文
done

識別子:リスト内の要素文字列を値とする変数
リスト:空白で区切られた文字列の並びで、ワイルドカード "*" や変数値を
        用いることもできる。リスト内の各要素文字列が識別子に代入される。

戻る

counter1counter2counter3counter4counter5counter6

|Home|
 
Valid XHTML 1.1 Valid CSS!