ITの窓辺から

三流IT技術者の日常

Squidをとりあえず動かす設定

HTTPプロキシといえばSquid、というほどでもないと思いますが、とりあえずHTTPプロキシが必要になったら立ててみるくらいには広く使われている製品です。過去記事のSplunk関連でSquidのログを活用しましたが、Squidの機能には全く触れていません。検証用にも非常に良いソフトウェアだと思うので、こねくり回していきます。

動作環境はCentOS7、Squid3.5.2です。

f:id:ReaLiZeZNSG:20180728221427p:plain

設定ファイル

Squidの設定ファイルは/etc/squid/squid.confです。squid.confはテキストファイルで、基本的に全ての設定はこのファイルから行います。設定をするといっても設定構文が分からないと話にならないですが、公式Webサイトのリファレンスが充実しているので、そこから探していく形になります。

squid : Optimising Web Delivery

逆にやりたいことから調べるのは少し大変そうです。メニューのDocumentation→Configure→Exampleに多少例があるのでそれを参考にやっていこうと思います。尚、squid.conf設定変更後はSquidのサービスを再起動しないと変更が反映されません。

systemctl restart squid.service

とりあえずSquidの待受TCPポートを設定しておきましょう。squid.confに以下の行があるので好きな番号にします。デフォルト値である3128でも動作状は問題ありません。8080とか18080とか81とかを指定するのがメジャーでしょうか。

http_port 3128

基本設定思想

Squidの基本設定動作は基本的に条件文(ACLと呼びます)を定義し、アクション設定時にアクションをさせるべき条件文を指定する形になります。アクションとは私が勝手に読んでいるだけで公式では特にこういう表記ではないのでご注意。これだけ聞くと簡単そうなんですが・・・、ファイアウォールやネットワーク機器のACLに慣れていると勘違いが多発します。というかしました。

まずACLを設定します。ACLの基本構文は以下の通りです。

acl <ACL NAME> <ACL TYPE> <ARGUMENT>

<ACL NAME> : ACL名です。任意でOK。最大32文字のようです。

<ACL TYPE> : ACLのタイプです。オフィシャルサイトによると多くのACLタイプがあるようですが、とりあえずはプロキシを利用するクライアントのネットワークアドレスを示すsrcと宛先URLを示すdstくらいを使用していきます。

<ARGUMENT> : ACLタイプに対応する値を指定します。

例えば192.168.0.0/28というクライアントネットワークを指定する場合は以下のように記します。

acl PrivateNetwork01 src 192.168.0.0/28

続いてアクションを設定します。今回設定するアクションはhttp_accessです。書式は以下の通りです。

http_access [allow | deny] <ACL>

先程設定したACLを使用すると例えば以下のような設定ができます。

http_access allow PrivateNetwork01

ACL「PrivateNetwork01」にマッチする通信はこのSquidを経由して通信して良いという意味になります。クライアントのIPアドレスが192.168.0.1であればPrivateNetwork01にマッチするのでSquidを経由して通信することができます。

続いて以下のようにdenyを指定してます。

http_access deny PrivateNetwork01

この状態でプロキシにアクセスすると、Webブラウザが(対応していれば)プロキシにアクセスを拒否されたことを示すエラーメッセージを表示します。

暗黙の動作

まず「http_access allow PrivateNetwork01」のみ設定されている場合にクライアントのIPアドレスが192.168.0.20だった場合はどうでしょう。試してみたところ、プロキシにアクセスを拒否されました。

f:id:ReaLiZeZNSG:20180728223839p:plain

どうでも良いですが、上記画像はSafariのエラーメッセージですが、Firefoxと比べると何が起きたか分かりにくいですね。エラーコードがあるので調べれば分かるのでしょうけど、プロキシサーバへのreachabilityがなかったのかプロキシサーバでのエラーにより接続できなかったのか分かりません。Firefoxだとこの辺りはわかりやすいのですが・・・。

では「http_access deny PrivateNetwork01」のみ設定されている場合にクライアントのIPアドレスが192.168.0.20だった場合はどうでしょうか。今度はエラー画面は表示されずにWebサイトに正しく接続されました。

次に新しく以下のACLを設定します。

acl PrivateNetwork02 src 192.168.0.16/28

続いてhttp_accessを以下のように設定します。

http_access allow PrivateNetwork01

http_access allow PrivateNetwork02

クライアントのIPアドレスを192.168.0.20に設定した場合、2行目のhttp_accessにマッチするので当然ながら正常にWebサイトに接続できます。クライアントのIPアドレスを192.168.0.40に設定してみます。すると何故かSquidに接続を拒否されます。

次はdenyを試します。以下のようにhttp_accessを設定します。

http_access deny PrivateNetwork01

http_access deny PrivateNetwork02

クライアントのIPアドレスが192.168.0.20であれば2行目のhttp_accessとマッチするのでSquidに接続を拒否されます。ところがIPアドレスが192.168.0.40の場合はWebサイトに正常に接続されます。

http_accessアクションはsquid.confの上から順に評価し、マッチするACLの条件が見つかった時点でその時のアクションを実行することがわかりました。しかし一番下のhttp_accessにもマッチしなかった場合は妙な動作をします。これらの実験からSquidには以下のルールがあると覚えておく必要があります。

  • http_accessは上から評価し、マッチするACLのallow動作が見つかった時点で動作が実行される。
  • 最後のhttp_accessがallowだった場合、全てのhttp_accessにマッチしなかった全ての通信がSquidに接続拒否される。
  • 最後のhttp_accessがdenyだった場合、全てのhttp_accessにマッチしなかった全ての通信がSquidに接続される。

というわけでファイアウォールやネットワーク機器と動きがだいぶ異なります。Squidに精通した人が多数いる組織であればまだ良いですが、誤解しないように最後にhttp_access deny allまたはhttp_access allow allを指定しておく方が良いと思われます。allを指定すると全ての条件がマッチするようになります。

 L4ポート番号

squid.confの初期設定にはプロキシの接続先TCPポート番号を示すACLがあります。接続先のWebサイトが所定のポート番号以外で接続を要求している場合には接続が拒否されます。具体的にはacl Safe_ports port <PORT NUMBER>が指定されています。Safe_portsACL名、portはACLタイプです。このACLタイプは名前の通り後ろにポート番号を指定します。

このACLに対応するアクションとして以下のhttp_accessが設定されています。

http_access deny !Safe_ports

よくある書式ですが、ビックリマークをつけるとSafe_portsでなければマッチするというような意味になります。この場合、Safe_portsとして指定したポート番号以外の接続は拒否するという設定になります。わざわざビックリマークを使っているのはSquidのhttp_accessの評価仕様のためです。allow Safe_portsと指定してしまうと、その時点で評価が終了し、その後に送信元ネットワークアドレスや宛先URLを限定していた場合でもその設定値が評価されません。

具体的には以下のようにした場合、2行目のhttp_accessアクションが評価されません。

http_access allow Safe_ports

http_access deny PrivateNetwork02

こうした動作を理解した上でhttp_accessを記述する必要があり厄介です。設定後はテストケースをきちんと整理する必要があるでしょう。

その他

初期ACLに「acl SSL_ports port443」と「acl CONNECT method CONNECT」というものと「http_access deny CONNECT !SSL_ports」があります。HTTPSを少し知っていれば想像つくと思いますが、この件は別記事で書きます。

 

そんなわけでSquidの設定を試しつつHTTPプロキシやHTTPプロトコルの一般論も書いていく流れを数回続けようと思います。