Squidのアクセスコントロールは比較的広範囲で一般の人には難しいと思います。 これには2つのコンポーネントがあり、1つはACLとその要素、もう一つがACLとその要素に対する許可・不許可の動作です。
注:この情報はバージョン2.5におけるものです。
squidには以下のACL要素があります。
注意: すべてのACL項目がアクセスリストで使える訳ではありません。 例えば、snmp_community は snmp_access が使われた時に意味があります。 src_asとdst_as
は、cache_peer_access のアクセスリストで意味を持ちます。
arp を使うには、configure の際に --enable-arp-acl を使って構築する必要があります。ARP ACLコードはすべてのOSで利用可能な訳ではありません。 それは、Linux,
Solaris, *BSDにおいて有効です。
SNMP ACL項目とアクセスリストを使うためには、configure において --enable-snmp で構築する必要があります。
いくつかのACL項目を使う事で処理に遅延が発生することがあります。 例えば、src_domain や srcdom_regex_require
などは、クライアントのIPアドレスから DNS の lookup を行います。 これが遅延(ホスト名が存在しないなど場合に DNS での検索に時間がかかる場合がある)を発生させます。
各ACL項目は任意の名前を割り当てられます。 この名前は値を持ったACL項目にとなります。 値は複数指定でき、適合を検査する際は複数の値を持ったものはOR条件で検査します。 つまり、指定した条件が1つでも適合すれば条件にマッチしたと判断されます。
2つの異なるACLに同じ名前を与える事はできません。 これは構文エラーになります。
異なる値を持つ複数の名前のACLを指定できます。
たくさんの異なる アクセスリストがあります。
ノート:
アクセスリストのルールは allow と deny の2つのキーワードに続きACL項目を指示します。
アクセスリストは1つ以上のアクセスリストルールで構築されます。
アクセスリストルールに複数のACL項目が複数続くとき、これはANDのロジックとなります。 即ちすべてのACL条件が一致したときにそのアクセスルールが適用されます。 このことは、決してマッチしないACLを並べてはならないことを意味します。 例えばポート番号80と8080のACLを両方記述してはそのアクセスルールのリストが適用されることはあり得ません。
アクセスリストとACLのロジックを要約すると、
http_access allow|deny acl AND acl AND ..... OR http_access allow|deny acl AND acl AND .....
というロジックとなります。(ANDとORは実際のルールには記述しません)
どの規則にもマッチしなかった場合に備え、リストの一番最後にはどんな場合にも適合するルールを書いておくと良いでしょう。 尤もよい方法としては、最後にすべてを拒否するルールを記述することです。
あなたのクライアントにマッチするIPアドレスのACLを作成してください。
次にこのACLに対するアクセスルールを記述します。
例えば「cooking recipes」にアクセスするのを防止したいと仮定します。
これを実施する方法は、この"cooking"と"recipes"という単語を含むすべてのURLにアクセスを拒否することでしょう。
別の方法としては、この情報を持っているサイトが判っているなら、このサイトへのアクセスを拒否する方法もあります。
dstdomainはURLから"www.hogehoge.jp"の文字列を探し出します。 注意して欲しいのは、URLにホスト名ではなくIPアドレスを指定している場合や、Squid1.1でrelaxed制御をしている場合です。FQDNキャッシュ上にIPアドレスに対するドメイン名が存在するならアクセス制御は直ちに反応しますが、ない場合にはlookup検索を行ってからアクセス制御を行います。
特定のユーザからのアクセスを制御するために、ident_lookup を allow として許可する Ident による検索を可能にできます。この機能を使うにはキャッシュと同じマシン上で ident サーバのプロセスが動作している必要があります。 その上で、次のように制御を記述できます。
ident_lookup_access allow all
acl mygroup ident suzuki satou kimu jon
http_access allow mygroup
http_access deny all
別の方法としては、プロキシ認証を使うことです。 この方法では、ユーザ名とパスワードを個人毎に割り当てて、プロキシを使う為にはこの個人名とパスワードを入力させる事で、彼らを認証するようにします。
Squid V2ではこの認証は外部プロセスを使って実現できます。 この為の構成方法については、 「プロキシ認証の構成」をご覧ください。
Pedro L Orso は、chpasswd.cgiというCGIプログラムをアパッチのhtpasswd用に提供しています。
あなたは ident_access ディレクティブを使って、Squid から ident_lookup を行わせることができます。
その上、ident ACLを squid.conf の中で使うことで、ident_lookup_access を使っていなかったとしても ident
検索が可能です。
acl host1 src 10.0.0.1
acl host2 src 10.0.0.2
acl mygroup ident suzuki satou kimu jon
http_access allow host1
http_access allow host2 mygroup
10.0.0.1 からアクセス要求があった場合には直ちに許可されるでしょう。 10.0.0.2からの要求は ident の検索が完了し、そのユーザ名がsuzuki
satou kimu jonであった場合に許可されます。
アクセスルールを記述する際に、AND/ORの違いとその書き方にあなたは注意を払わなくてはいけません。
例えば、以下のアクセス制御は決して機能しないでしょう。
この要求はACLのMEとYOUを同時に満たす条件の場合にアクセスを許可しています。 しかし、IPアドレスのACLであるMEとYOUを同時に満たすことはあり得ないため、このアクセスルールが適用されることは無いでしょう。
これは以下のように書き直すことで機能させることができるでしょう。
あるは以下のように直すこともできます。
私はsquid.confに関するたくさんの資料を読んだのですが、どうしても以下のものが動かないのか理解できません。
私は、squidと同じマシンにWebサーバを用意し、SquidをMRTGによって管理したいのでcachemgr.cgiをWebサーバにおいたのですが、プロキシはいつも私からの要求を拒否します。使った制御は以下の通り。
ここでは、ローカルサーバとサーバからのキャッシュマネージャへのアクセスは許可し、それ以外のアクセスは拒否する為に、
というルールを作ってあります。
ここでの問題は、ローカルサーバとサーバからのアクセスに許可が無い事です。 もう一度、よくルールを見てください。 このルールでローカルアドレス(127.0.0.1)からのアクセスはどのように処理されるでしょう。 最初のルールではキャッシュオブジェクトでかつ、ローカルアドレスとサーバのアドレス以外であった場合には拒否するというルールです。 このためローカルアドレスからのアクセスであった場合には第1のルールは適用されません。
第2のルールはourhostsのサブネットからのアクセスはすべて許可しています。 この為、思わぬキャッシュマネージャへのアクセスを許してしまっています。
これらは以下のように直すべきでしょう
もし、miss_accessを使うなら、マネージャにmiss_accessルールを加えるのを忘れないでください。
複数のアクセスルールを規定することがパフォーマンスを悪化させると心配するかも知れません。 しかし経験上、これらはさほどパフォーマンスに影響を与えません。
srcdomainのACLでは、SquidはクライアントのIPアドレスからDNSのFQDNを検索し、その結果をaclで与えたドメイン名と照会します。src ACLでは、単にクライアントのIPアドレスとACLでのアドレスを照会するだけです。 src ACLはドメイン検索が不要なので良く利用されます。
ACLの問題を解決する場合、これをデバックするためにどのようにACLが機能しているか知る必要があります。 この為のヒントを得る為に次の方法があります。
squid.conf で、デバックオプションをレベル2-セクション33にして下さい。
debug_options ALL, 1 33,2
その後、Squidを再起動するかリコンフィグしてください。
こうすることで、cache.logにACLによって許可されたか拒否されたかの説明がリクエストとともに残ります。
もしこの情報でも不足であるなら、更に詳細なデバック情報を取るために
debug_options ALL, 1 33,2 28,9
を指定する事もできます。これにより、cache.logにはアクセスリストの詳細な処理が報告されます。 これはなかりの量の情報になる事に注意してください。
Squidにおけるユーザ認証に関してはこちら(FAQ-23)を最初にお読みください。
構成:
[親のキャッシュ] / \ / \ / \ [Proxy-A]---[Proxy-B] | | ユーザ
オブジェクトを探すためProxy-AにおいてIPCリクエストがProxy-Bに行われたとき、Proxy-Bでオブジェクトが見つかり、IPC_HITを返したとします。 このオブジェクトをProxy-BからProxy-Aが読もうとした際に、認証がかかっているとProxy-AはHTTP GETに失敗します。
Proxy-Authenticationリクエストは、1つのプロキシキャッシュの接続においてのみ利用できます。 この為、一旦ヘッダーが使われるとそのヘッダーが他のプロキシに使われることはありません。(この場合Proxy-Aにてユーザの認証が機能する)
故に、隣接のキャッシュでも認証の仕組みをもっているなら、プロキシサーバ管では認証を使わずにアクセスできるようにしておく必要がお互いにあります。
もし Squid 2.4以上を使っているなら dstdomain ACL によって完全なホスト名以外でもマッチさせることのできる名前が有る事を覚えているかも知れません。 www.example.comを指定した場合には当然ホスト名のwww.example.comとマッチします。しかし、example.com
を指定した場合には www.example.com を含む example.com全体の名前にマッチします。
もし、あなたの dstdomain ACLに完全なホスト名と同じドメイン名の2つが使われている場合(例えば www.example.com とexample.com)には、命令の方法によっては
www.example.com だけが使われるかも知れません。
ノート: 現在のSquid2.4以上では、このような構成が与えられた場合には警告が発せられるでしょう。
それにはドメイン名ベースのアクセス制御における微妙な問題が、サブドメイン名とその他のドメイン名の間にはあります。
例として:
acl foo dstdomain boulder.co.us vail.co.us co.us
まず第一に最初の2つの名前には意味がありません(boulder.co.us vail.co.us)し、誤った指定です。
どんなドメインも名も最後の1つ(co.us)びよってマッチします。 では、どんな問題が発生するでしょう。
Squidはドメイン名のリストを内部的に、Splay trees という構造でインデックス化しており、これはドメイン名によって広がったツリーベースの構造を持つようになっています。 他方、ツリーベースのデータ構造では、インデックスの比較の結果は-1,0または+1を返すようになっています。 これはstrcmp()関数に似ています。
問題はサブドメインと同じドメイン名を使った場合、それぞれにインデックスが作られ、この結果としてSplay trees構造では、片側のインデックスにないデータを発見できなくなる結果を引き起こします。
これは危険なポートへSquidから接続しようとした場合に起こります。 例えば誰かがSMTP(e-mail)リレーとしてSquidを使う事が考えられます。スパムメールの送信者がスパムメールをSquidを経由して発信するかも知れません。 これを妨げるために、Squidはポートの25番(SMTP)への要求を却下します。 用心の為、必要のないポートへのアクセスは塞ぐようにすべきでしょう。
ポート番号のフィルターには2つの方法があります。 : 指定したポートを許可または拒否する方法。 これはデフォルトでSquidはこれを最初に行います。 このACLはデフォルトでsquid.confにあります。
上記の設定では、このリストにないポートへのURLでのポート番号指定を拒否します。 上記では、通常のHTTP, FTP, HTTPS, Gopher, WAIS, および特権(サーバではない)ポートへのアクセスを許しています。
別のアプローチとしては、危険なポートを明示的に拒否するリストを作成することです。 以下のようになります。
どのようなサービスがどのポートを使っているかは、/etc/servicesをご覧ください。
Squid-2.2現在、
またサポートしていません。
次のような例では、spacial_client のアドレスのマシンは、special_url で指定されたURLのみ許可されそれ以外はすべて拒否されるでしょう。
例えば、8:30から17:30の時間帯においてのみ、アクセスを許可した2つのワークステーションがあったなら、次のような指定が可能です。
以下のACL参加は、一貫性がないまたは思いがけない結果を与えます。
これは、"splay"ツリー構造における問題で、同じ範囲をもつ2つのキーを指定した事によって混乱を引き起こします。
あなたが複雑な(あるいは非標準)ネット・マスク(255.0.0.128)を使用する場合、それは2つのアドレス/マスク・ペアを比較する機能を混同します。この問題を解決する尤も良い方法は、別々の名前を持つACLを使うことです。 例として上記の場合には以下のように修正してください。
もちろん、このACLを使うhttp_accessも書き直してください。
幾つかのオペレーティングシステムでは可能です。 Squidではこれを"ARP
ACLs"と呼び、Linux, Solaris, BSDライクのOSでサポートされます。
ノート: Squidは同じサブネットに存在するクライアントのみMACアドレスを知ることができます。 別のサブネットにクライアントが有る場合にはそのMACアドレスを知ることは出来ません。
ARP ACLsを使う為には、コンパイル時に--enable-arp-aclオプションでconfigureを行う必要があります。
これでコンパイルしたなら、以下のようのACLを追加することができます。
詳しくは、11.20 トラブルシューティング. を見てください。
maxconn ACLによって可能です。以下の例を見てください。
上記の場合、ソースのIPアドレスが1.2.3.0/24のサブネット範囲で、接続クライアント数が6以上では、エラーを返します。
maxconnを使うためには clieant_bd 機能が有効になっている必要があります。もしclieant_bdが無効(例えば、clieant_bd off)なら、maxconn ACLは働かないでしょう。
注意: maxconn ACLを使うのは一筋縄にはいきません。 ここで指定する数は確立した接続の数で、これはあなたの指定した数より多く必要です。 この為、maxconn
ACLをhttp_accessとともに使いたくなくなるでしょう。
IPアドレスタイプと一緒に使うよりもユーザタイプのコントロール(ident, proxy_auth)と一緒に使うと良いでしょう。
squid-2.3で私たちはSquidのサブドメインの扱いを変更しました。 .foo.com と foo.com では意味が違ってきます。 最初の指定では、 foo.com が含まれるすべてのドメイン名にマッチします。(ex. "abcfoo.com",
"www.xxxfoo.com")
一方、後者の場合には foo.com と完全に一致するドメイン名の場合にマッチします。
もし特定のドメインをすべて許可しないようにするなら、
としてください。
エラーメッセージのカスタマイズについては「エラーメッセージのカスタマイズ」で述べられています。あなたは、既存のエラーメッセージをカスタマイズしたり、新規のエラーメッセージを作成してdeny_infoオプションとともに使うことができます。
例えばユーザがポルノサイトにアクセスしたような場合に、特別な注意書きを表示したいなら(訳者注: 英語の場合には)/usr/local/squid/etc/errors
ディレクトリにERR_NO_PORNO というファイルを以下の内容で作成し、
<p> Our company policy is to deny requests to known porno sites. If you feel you've received this message in error, please contact the support staff ([email protected], 555-1234).
次に以下のようなアクセス制御を行います。
Squidはデフォルトで作成されるエラーメッセージのすべてでGMTを使います。これによりキャッシュの階層に参加する際、異なるタイムゾーンをもつキャッシュに混乱を与えることなく参加する事ができます。
Squidが作成するエラーメッセージで異なるタイムゾーンに変更する場合、あなたはSquidのシグネーチャを変更する必要があります。エラーメッセージのカスタマイズを参照してください。シグネーチャで標準はタイムスタンプに%Tが使われています。 しかしこの代わりにローカルのタイムスタンプの%tを使うことができます。
Squidが許可しないアクセスリクエストがあった場合に、専用のエラーページを表示させたい場合には、squid.confの中で「deny_info」を定義すると良いでしょう。
cache_peer_accessを使って、特定のサイトへのアクセスの場合にpeerアクセスをしないようにコントロールできます。
例、 subnetのサイトへは親キャッシュ(proxy1.domain)にpeerアクセスしない設定です。
external_acl_type は、認証の拡張として利用できます。 通常の認証において、ユーザのIDとパスワードによる認証が完了すればアクセスが可能になります。
しかし、認証において、例えばある各ユーザ毎にアクセス可能な時間帯を変えたり、特定のユーザが利用できるサブネットワークからのアクセスを制限させたりと、細かな認証制御を行いたい場合もある事でしょう。
このような場合、DBにユーザIDと共に「利用可能時間帯」や「利用可能サブネット」を登録しておき、external_acl_typeで指定するヘルパープログラムによってこのDBを検索させて、このヘルパープログラムがOKまたはERRを返すようにする事で単なるユーザIDによる認証以上の細かな制限が可能になってきます。
この良いサンプルがこちらにあります。
デフォルトではACLの名前は 32-1 即ち 31文字までです。これを変更する場合にはソースファイルのdefines.h の中で次のように指定します。
参考: