連載
» 2005年05月17日 00時00分 公開

習うより慣れろ! iptablesテンプレート集(2):natテーブルを利用したLinuxルータの作成 (4/6)

[鶴長鎮一,@IT]

テンプレート8
透過型プロキシの実現(ルータと同一サーバ)

 バックボーンの節約などを目的とした外部ネットへの接続リソースを抑える手段として、HTTPのプロキシサービスがあります。しかし、この方法はクライアント側に設定の煩わしさが付きまといます()。

注:一部のWebブラウザにはプロキシの自動設定機能があります。

 DNATを使用すると、Webブラウザ側で設定を行わなくても強制的にプロキシサーバを使用させることができます。まずはサーバの追加投資が掛からない方法として、Linuxルータにプロキシサービスを実装した透過型プロキシを実現します。

テンプレート8の想定環境

サーバとして
・外部からの接続パケットは基本的にすべて破棄
 ただし接続済み通信のパケットは許可
・内部からの接続パケットは基本的にすべて許可
・ループバックアドレスに関してはすべて許可
・メンテナンスホストからのping、メンテナンスホストへのpingを許可
・メンテナンスホストからのssh(TCP 22)を許可
・内部ネットからのHTTPプロキシ(TCP 3128)を許可
ルータとして
・Linuxサーバを経由して外部へ出ていくパケットのソースアドレスを変換
・内部アドレス→外部アドレス
・内部アドレスやプライベートアドレスが外部に漏れないようにブロック
・内部から外部ネットに出ていくHTTPサービスのパケットを書き換え
 ディスティネーションアドレスをプロキシサーバ(Linuxサーバ自身)のアドレスとサービスポート(TCP 3128)に
 HTTPサービスのパケット:ディスティネーションポートTCP 80

テンプレート8の解説

 iptablesの設定を行う前に、Linuxルータでプロキシサービスを起動しておきます。今回はSquidを使用し、squid.confを下記のように設定しています。

acl our_networks src 192.168.0.0/24 #Proxyを利用する内部ネットの定義
http_access allow our_networks
httpd_accel_host virtual
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
squid.conf

 なお、Webブラウザでプロキシサーバを指定する方法で動作を確認できているとしても、設定によっては透過型プロキシとして動作しない場合もあります。

 上記以外はデフォルト値を利用しており、サービスポートもTCP 3128のままです。shスクリプトにその旨を定義しておきます。

 9  proxy_port='3128'

 LinuxルータでSquidを動作させるため、TCP 3128の解放が必要です。「eth1から入ってeth1へ出ていくパケットを無制限にする」などいろいろ方法はありますが、ここではsshの例を基に56、57行目を追加します。sshの50行目の設定は、サービスにかかわらず実行は1度でよいため、プロキシでは省いています。

56 iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -s $internal_ip -d $my_internal_ip --dport $proxy_port -j ACCEPT
57 iptables -A OUTPUT -p tcp -s $my_internal_ip --sport $proxy_port -d $internal_ip -j ACCEPT

 内部ネット各ホストのデフォルトルータがLinuxルータになっているため、外部へ出るパケットはすべてLinuxルータを経由します。そこで、パケットがLinuxルータを通る際に、ディスティネーションポートがTCP 80のものをLinuxルータのプロキシサービスポート(TCP 3128)に向けます。これで、ユーザーに意識させることなくプロキシサービスを利用させることができます。

67 iptables -t nat -A PREROUTING -i eth1 -s ! $my_internal_ip -p tcp --dport 80 -j DNAT --to-destination $my_internal_ip:$proxy_port

-A PREROUTING PREROUTINGチェインの使用
-j DNAT DNAT(ディスティネーションアドレスの書き換え)の使用
-s ! $my_internal_ip ソースアドレスがLinuxルータの内部ネット側(eth1)アドレス以外のもの
--to-destination $my_internal_ip:$proxy_port 書き換え先のディスティネーションアドレス(サービスポート番号付き)

 HTTP/HTTPS両サービスの透過型プロキシサーバを実現するには、ディスティネーションポートがTCP 443のパケットも考慮する必要があります。iptablesの設定については、ここで紹介したTCP 80の方法が参考になるでしょう。もちろん、プロキシサーバ側の実装も必要になります。

改造のヒント:REDIRECTを使う方法

 同じPREROUTINGチェインでも、REDIRECTを使った場合は次の1行のようになります。こちらでも透過型プロキシを実現できます。

iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port $proxy_port

-j REDIRECT REDIRECT(向け直し)の使用
--to-port $proxy_port REDIRECT先のポート

 「-j DNAT --to-destination」は、あて先としてIPアドレスとポート番号を指定できます。しかし、「-j REDIRECT」はあて先ポート番号しか変更できません。そのため、使えるオプションは「--to-port」のみになります。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。