2011/03/20 CentOS5.5





二つ以上のプロキシールーティングをする(多段プロキシ)

他のパターンはプロキシーサーバを構築する(解説)を参照してください。

宛先により別のプロキシーへルーティングするのと変わりませんが、想定したように動かないことがあります。
ちょっとしたテクニックが必要です。この場合も少しコンフィグがトリッキーになります。


コンフィグの動作が複雑になりやすいです。頭の中がこんがらがってきますから、一度フローを整理して書いてからコンフィグに起こしたほうが間違いが少ないです。

インストール
コンフィグの編集
動作試験


インストール
インストールは特に苦労することはありません。
比較的大人しい部類に入ります。

GUIからのインストール
「ソフトウェアの追加と削除」からインストールする場合


コマンドからのインストール

#yum install squid

インストールしたら、GUIかコマンドにてファイアウォールを解放します。
ここでは80ポートか8080ポートを使用するので、ポートを解放します。



コマンドの場合は/etc/sysconfig/iptablesを編集し、

-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 8080 -j ACCEPT

という行を最終の「Reject」行の前に挿入します。
その後、iptablesサービスを再起動します。

コンフィグの編集
/etc/squid/squid.confを編集します。
コンフィグは前方参照の性質があるので、呼び出される情報は先に宣言されていなくてはなりません。
それぞれの設定項目は例が示してあるセクションに記述するのが無難です。
squid.confは非常に長いのですが、面倒でもそのセクションまで移動しましょう。
「TAG: cache_peer」などとすると検索しやすいです。

下位プロキシー(図中proxyA

cache_peer
上位プロキシーを指定します。コンフィグの末尾に追加したりせず、ちゃんとcache_peerセクションに記述するとトラブルが少ないでしょう。
上位プロキシーの待ち受けポート番号を指定します。以下のパラメータでは8080。
二つ指定しますが、これだけでは「どちらを使っても良い」という意味にしかなりません。
cache_peer  proxyB.example.local parent 8080 0 no-query
cache_peer  proxyC.example.local parent 8080 0 no-query

http_port
プロキシーとして待ち受けるポートです。
覚えにくい3128なんてデフォルトポートを使ってる状況はまずないでしょう。
80や8080がメジャーです。
http_port  8080

icp_port
ICPのポートなんてのも、兄弟プロキシを使わないので要りません。
デフォルトの
icp_port 0

visible_hostname
エラー画面を表示したとき、どこのサーバかを示します。複数のプロキシサーバを組む場合、どこでエラーが発生しているかを判断できます。
visible_hostname squidA.example.local

http_access
デフォルトではプロキシへアクセスできるセグメントはローカルホストに限定されています。
とりあえず全てのクライアントを許可します。「http_access deny all」行よりも前に追加します。
http_access allow all

もしプロキシー接続できるクライアントを制限したいのなら、「http_access allow all」の代わりに以下のACLを追加します。
Ver2.0以前
acl CLIENTS src 192.168.1.0/255.255.255.0
http_access  allow CLIENTS

Ver3.0以降
acl CLIENTS src 192.168.1.0/24
http_access  allow CLIENTS


acl
指定ドメインのプロキシールーティングで使用するACLです。
同じドメインのURL(example.local)は直接取得し、YahooドメインはProxyCへ転送し、その他のインターネットアクセスはProxyBへ転送します。
ドメイン名の指定は、ドメインの前にドットを忘れないよう「.yahoo.co.jp」という指定をします。
acl yahoo dstdomain .yahoo.ne.jp .yimg.jp
acl examole dstdomain .example.local

cache_peer_access
特定のドメインはサイドプロキシを使用するように指定します。
これがないと全てのインターネット閲覧がどちらかのプロキシへ転送されます。
この場合は、yahoo.co.jpで終わるドメイン全てを、インターネットプロキシへの転送を禁止する
example.localで終わるドメインはどちらのプロキシへの転送も禁止する、と設定します。
インターネット接続は直接取得とProxyCの利用を禁止する。と設定します。
cache_peer_access proxyB.example.local deny yahoo
cache_peer_access proxyB.example.local allow !example
cache_peer_access proxyC.example.local deny !yahoo
cache_peer_access proxyC.example.local allow yahoo

never_direct
ここまでに定義されていないドメイン以外へのアクセスは、最終的に暗黙の転送先へ転送されます。
意図として、プロキシを使用したい「exampleドメイン以外」は直接取得を禁止します。
「exampleドメイン以外」にYahooドメインも含まれるので、本来はYahoo行は必要ありませんが念のため。
never_direct allow yahoo
never_direct allow !example

always_direct
Exampleドメインだけは明示的に直接取得を許可します。さもないとプロキシーへ投げます。
always_direct allow example


ここまで、ちょっとわかりにくいので並び替えて書いてみます。

#キャッシュサーバを定義
cache_peer  proxyB.example.local parent 8080 0 no-query
cache_peer  proxyC.example.local parent 8080 0 no-query

#yahooドメインを定義し、proxyCのみ使用する。直接接続も禁止
acl yahoo dstdomain .yahoo.ne.jp .yimg.jp
cache_peer_access proxyB.example.local deny yahoo
cache_peer_access proxyC.example.local allow yahoo
never_direct allow yahoo

#exampleドメインを定義。直接接続を許可
acl example dstdomain .example.local
always_direct allow example

#proxyCはyahooドメインでないときだけ使用。proxyCはexampleドメインではないときだけ使用
cache_peer_access proxyC.example.local deny !yahoo
cache_peer_access proxyB.example.local allow !example

#exampleドメイン以外は、直接接続しないことを、許可する
never_direct allow !example

解説
インターネットアクセス(例えばGoogle)では
 ・proxyBの利用について、どこの行でも拒否されていない。(暗黙の許可)
 ・proxyCの利用について、「Yahoo以外のドメイン」によって拒否されている。
 ・直接取得について、「example.local以外のドメイン」によって拒否されている。
結果、インターネットアクセスはproxyBが利用されます。

Yahooドメインへのアクセスは
 ・proxyBの利用について、拒否されている。
 ・proxyCの利用について、許可されている。
 ・直接取得について、「example.local以外のドメイン」によって拒否されている。
結果、YahooドメインへのアクセスはproxyCが利用されます。

Exampleドメインへのアクセスは
 ・proxyBの利用について、「example.local以外のドメインを許可」されている。(暗黙の拒否)
 ・proxyCの利用について、「yahooドメイン以外」によって拒否されている。
 ・直接取得について、許可されている。
結果、Exampleドメインへのアクセスは直接取得が利用されます。


設定を保存したらサービスを再起動します。

#service squid restart



サイドプロキシ(図中proxyB、ProxyC)

http_access
通常、下位プロキシーをバイパスしてクライアントたちが直接上位プロキシーを指定しないよう、下位プロキシー以外は拒否するのが普通です。デフォルトで「http_access deny all」が指定されているので、許可端末を指定します。
Ver2.0以前
acl proxyserver src 192.168.1.100/255.255.255.255

http_access allow proxyserver

Ver3.0以降
acl proxyserver src 192.168.1.100/255.255.255.255
http_access allow proxyserver


http_port
待ち受けポートです。下位プロキシーのcache_peerで指定されるポートに記述します。
ファイアウォールでポート閉じてるとか、初歩的なミスに注意しましょう。
http_port  8080

visible_hostname
エラー画面を表示したとき、どこのサーバかを示します。複数のプロキシサーバを組む場合、どこでエラーが発生しているかを判断できます。それぞれのホスト名を記述します。
visible_hostname proxyB.example.local

設定を保存したらサービスを再起動します。

#service squid restart


動作試験
squidのアクセスログを監視します。

上位プロキシ、下位プロキシB・Cの全てで以下のコマンドを実行して、ログを監視します。

#tail -f /var/log/squid/access.log

YAHOOドメインを閲覧した場合はProxyBのログも流れ、その他のインターネットドメインを閲覧した場合はProxyAのみログが流れれば成功です。
すでにProxyAにキャッシュが溜まっていると、サイドプロキシを使うはずのドメインでもキャッシュで解決してしまいProxyBへアクセス形跡がないことがありますので、ときどきキャッシュをクリアします。

#service squid stop
#rm -rf /var/spool/squid/*
#squid -z
#service squid start

なお、アクセス拒否のキャッシュがされているとそれを返されるので、いろいろなURLでアクセステストをしてみましょう。

あまりコンフィグをあちこちイジっていると、always_directのアクセスを拒否とか、http_accessで下位サーバを拒否しているとか、許可されてクライアントでブラウジングはできるものの意図しない動作まで許可しているとか、チェック項目が増えます。
サーバが二台に増えたのでコンフィグの見通しも悪く、トラブルも複合要因になり、複雑化しやすいです。
コンフィグはその都度どこを編集したかこまめにメモを取るなどしないと、同じ設定を再現できなくなりますのでご注意を。






prev.gif