バックボーンの節約などを目的とした外部ネットへの接続リソースを抑える手段として、HTTPのプロキシサービスがあります。しかし、この方法はクライアント側に設定の煩わしさが付きまといます(注)。
DNATを使用すると、Webブラウザ側で設定を行わなくても強制的にプロキシサーバを使用させることができます。まずはサーバの追加投資が掛からない方法として、Linuxルータにプロキシサービスを実装した透過型プロキシを実現します。
サーバとして
・外部からの接続パケットは基本的にすべて破棄
ただし接続済み通信のパケットは許可
・内部からの接続パケットは基本的にすべて許可
・ループバックアドレスに関してはすべて許可
・メンテナンスホストからのping、メンテナンスホストへのpingを許可
・メンテナンスホストからのssh(TCP 22)を許可
・内部ネットからのHTTPプロキシ(TCP 3128)を許可
ルータとして
・Linuxサーバを経由して外部へ出ていくパケットのソースアドレスを変換
・内部アドレス→外部アドレス
・内部アドレスやプライベートアドレスが外部に漏れないようにブロック
・内部から外部ネットに出ていくHTTPサービスのパケットを書き換え
ディスティネーションアドレスをプロキシサーバ(Linuxサーバ自身)のアドレスとサービスポート(TCP 3128)に
HTTPサービスのパケット:ディスティネーションポートTCP 80
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
なお、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の方法が参考になるでしょう。もちろん、プロキシサーバ側の実装も必要になります。
同じ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.