最終更新日: 2014年1月13日
Squid Home / FAQトップ

10. アクセスコントロール(ACL)

10.1 概要

Squidのアクセスコントロールは比較的広範囲で一般の人には難しいと思います。 これには2つのコンポーネントがあり、1つはACLとその要素、もう一つが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を指定できます。 

■ Access List(アクセスリスト)

たくさんの異なる アクセスリストがあります。

ノート:

アクセスリストのルールは 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は実際のルールには記述しません)
どの規則にもマッチしなかった場合に備え、リストの一番最後にはどんな場合にも適合するルールを書いておくと良いでしょう。 尤もよい方法としては、最後にすべてを拒否するルールを記述することです。

例:

acl all src 0/0
http_access deny all

10.2 クライアントがキャッシュを使えるように許可したいのですが?

あなたのクライアントにマッチするIPアドレスのACLを作成してください。

例: 
acl mynetwork src 192.168.1.0/24

次にこのACLに対するアクセスルールを記述します。

例:
http_access allow mynetwork

10.3 特定のWebサーバはキャッシュしたくないのですがどう構成しますか?

acl noncache-servers dstdomain .hogehoge.org
no_cache deny noncache-servers

10.4 ACLによる禁止リストをどのように実施すればよいですか?

例えば「cooking recipes」にアクセスするのを防止したいと仮定します。
これを実施する方法は、この"cooking"と"recipes"という単語を含むすべてのURLにアクセスを拒否することでしょう。

acl Cooking1 url_regex cooking
acl Recipe1 url_regex recipe
http_access deny Cooking1
http_access deny Recipr1
http_access allow all

別の方法としては、この情報を持っているサイトが判っているなら、このサイトへのアクセスを拒否する方法もあります。

acl Cooking2 dstdomain www.hogehoge.jp
http_access deny Cooking2
http_access allow all

dstdomainはURLから"www.hogehoge.jp"の文字列を探し出します。 注意して欲しいのは、URLにホスト名ではなくIPアドレスを指定している場合や、Squid1.1でrelaxed制御をしている場合です。FQDNキャッシュ上にIPアドレスに対するドメイン名が存在するならアクセス制御は直ちに反応しますが、ない場合にはlookup検索を行ってからアクセス制御を行います。

10.5 どうやって指定したユーザやグループからのアクセスをブロックしますか?

■ Ident

特定のユーザからのアクセスを制御するために、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

■ Proxy Authentication(Proxy認証)

別の方法としては、プロキシ認証を使うことです。 この方法では、ユーザ名とパスワードを個人毎に割り当てて、プロキシを使う為にはこの個人名とパスワードを入力させる事で、彼らを認証するようにします。
Squid V2ではこの認証は外部プロセスを使って実現できます。 この為の構成方法については、 「プロキシ認証の構成」をご覧ください。

10.6 プロキシのパスワードを変更するCGIはありますか?

Pedro L Orso は、chpasswd.cgiというCGIプログラムをアパッチのhtpasswd用に提供しています。

10.7 あるサイトへのアクセスのみidentを使いたいのですがどのようにsquid.confを設定しますか?

あなたは 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であった場合に許可されます。

10.8 よくあるミス

■ AND/OR ロジック

アクセスルールを記述する際に、AND/ORの違いとその書き方にあなたは注意を払わなくてはいけません。 

例えば、以下のアクセス制御は決して機能しないでしょう。

acl ME src 10.0.0.1
acl YOU src 10.0.0.2
http_access allow ME YOU

この要求はACLのMEとYOUを同時に満たす条件の場合にアクセスを許可しています。 しかし、IPアドレスのACLであるMEとYOUを同時に満たすことはあり得ないため、このアクセスルールが適用されることは無いでしょう。

これは以下のように書き直すことで機能させることができるでしょう。

acl ME src 10.0.0.1
acl YOU src 10.0.0.2
http_access allow ME
http_access allow YOU

あるは以下のように直すこともできます。

acl US src 10.0.0.1 10.0.0.2
http_access allow US


■ Aallow/denyの混合

私はsquid.confに関するたくさんの資料を読んだのですが、どうしても以下のものが動かないのか理解できません。

私は、squidと同じマシンにWebサーバを用意し、SquidをMRTGによって管理したいのでcachemgr.cgiをWebサーバにおいたのですが、プロキシはいつも私からの要求を拒否します。使った制御は以下の通り。

acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl server src 1.2.3.4/255.255.255.255
acl all src 0.0.0.0/0.0.0.0
acl ourhosts src 1.2.0.0/255.255.0.0

http_access deny manager !localhost !server
http_access allow ourhosts
http_access deny all

ここでは、ローカルサーバとサーバからのキャッシュマネージャへのアクセスは許可し、それ以外のアクセスは拒否する為に、

http_access deny manager !localhost !server

というルールを作ってあります。

ここでの問題は、ローカルサーバとサーバからのアクセスに許可が無い事です。 もう一度、よくルールを見てください。 このルールでローカルアドレス(127.0.0.1)からのアクセスはどのように処理されるでしょう。 最初のルールではキャッシュオブジェクトでかつ、ローカルアドレスとサーバのアドレス以外であった場合には拒否するというルールです。 このためローカルアドレスからのアクセスであった場合には第1のルールは適用されません。
第2のルールはourhostsのサブネットからのアクセスはすべて許可しています。 この為、思わぬキャッシュマネージャへのアクセスを許してしまっています。
これらは以下のように直すべきでしょう

http_access allow manager localhost
http_access allow manager server
http_access deny manager
http_access allow ourhosts
http_access deny all

もし、miss_accessを使うなら、マネージャにmiss_accessルールを加えるのを忘れないでください。

miss_access allow manager

複数のアクセスルールを規定することがパフォーマンスを悪化させると心配するかも知れません。 しかし経験上、これらはさほどパフォーマンスに影響を与えません。

■ srcとsrcdomainのACLの違い

srcdomainのACLでは、SquidはクライアントのIPアドレスからDNSのFQDNを検索し、その結果をaclで与えたドメイン名と照会します。src ACLでは、単にクライアントのIPアドレスとACLでのアドレスを照会するだけです。 src ACLはドメイン検索が不要なので良く利用されます。


10.9 私の設定したアクセスコントロールが働きません。

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にはアクセスリストの詳細な処理が報告されます。 これはなかりの量の情報になる事に注意してください。

10.10 プロキシ認証と隣接キャッシュ

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にてユーザの認証が機能する)

故に、隣接のキャッシュでも認証の仕組みをもっているなら、プロキシサーバ管では認証を使わずにアクセスできるようにしておく必要がお互いにあります。

acl proxy-A src 10.0.0.1
acl proxy-B src 10.0.0.2
acl user_passwords proxy_auth /tmp/user_passwds

http_access allow proxy-A
http_access allow proxy-B
http_access allow user_passwords
http_access deny all


10.11 特定の1台以外はすべてのアクセスを許可しない方法はありますか?

acl GOOD dst 10.0.0.1
acl BAD dst 0.0.0.0/0.0.0.0
http_access allow GOOD
http_access deny BAD


10.12 ポルノサイトなどの禁止リストはどこにありますか。

10.13 Squidがサブドメイン名を正しくマッチしません。

もし 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構造では、片側のインデックスにないデータを発見できなくなる結果を引き起こします。

10.14 Squidが幾つかのポート番号を使えません。

これは危険なポートへSquidから接続しようとした場合に起こります。 例えば誰かがSMTP(e-mail)リレーとしてSquidを使う事が考えられます。スパムメールの送信者がスパムメールをSquidを経由して発信するかも知れません。 これを妨げるために、Squidはポートの25番(SMTP)への要求を却下します。 用心の為、必要のないポートへのアクセスは塞ぐようにすべきでしょう。

ポート番号のフィルターには2つの方法があります。 : 指定したポートを許可または拒否する方法。 これはデフォルトでSquidはこれを最初に行います。 このACLはデフォルトでsquid.confにあります。

acl Safe_ports port 80 21 443 563 70 210 1025-65535
http_access deny !Safe_ports

上記の設定では、このリストにないポートへのURLでのポート番号指定を拒否します。 上記では、通常のHTTP, FTP, HTTPS, Gopher, WAIS, および特権(サーバではない)ポートへのアクセスを許しています。

別のアプローチとしては、危険なポートを明示的に拒否するリストを作成することです。 以下のようになります。

acl Dangerous_ports 7 9 19 22 23 25 53 109 110 119
http_access deny Dangerous_ports

どのようなサービスがどのポートを使っているかは、/etc/servicesをご覧ください。

10.15 ACLのリストを保管するのにMySQLのようなデータベースを使えますか?

Squid-2.2現在、
またサポートしていません。

10.16 特定のURLにアクセスできる特定のアドレスを許可したいのです。

次のような例では、spacial_client のアドレスのマシンは、special_url で指定されたURLのみ許可されそれ以外はすべて拒否されるでしょう。

acl special_client src 10.1.2.3
acl special_url url_regex ^http://www.squid-cache.org/Doc/FAQ/$
http_access allow special_client special_url
http_access deny special_url

10.17 あるアドレスから特定の時間帯のみキャッシュを使えるようにしたいのです。

例えば、8:30から17:30の時間帯においてのみ、アクセスを許可した2つのワークステーションがあったなら、次のような指定が可能です。

acl FOO src 10.1.2.3 10.1.2.4
acl WORKING time MTWHF 08:30-17:30
http_access allow FOO WORKING
http_access deny FOO

10.18 あるユーザを特定の時間帯のみSquidを使えるようにしたいのです。

acl USER1 proxy_auth Dick
acl USER2 proxy_auth Jane
acl DAY time 06:00-18:00
http_access allow USER1 DAY
http_access deny USER1
http_access allow USER2 !DAY
http_access deny USER2

10.19 IP ACLにおける複雑なサブネットマスクの問題。

以下のACL参加は、一貫性がないまたは思いがけない結果を与えます。

acl restricted src 10.0.0.128/255.0.0.128 10.85.0.0/16

これは、"splay"ツリー構造における問題で、同じ範囲をもつ2つのキーを指定した事によって混乱を引き起こします。
あなたが複雑な(あるいは非標準)ネット・マスク(255.0.0.128)を使用する場合、それは2つのアドレス/マスク・ペアを比較する機能を混同します。この問題を解決する尤も良い方法は、別々の名前を持つACLを使うことです。 例として上記の場合には以下のように修正してください。

acl restricted1 src 10.0.0.128/255.0.0.128
acl restricted2 src 10.85.0.0/16


もちろん、このACLを使うhttp_accessも書き直してください。

10.20 IPアドレスではなくMACアドレスでACLを指定したいのです。

幾つかのオペレーティングシステムでは可能です。 Squidではこれを"ARP ACLs"と呼び、Linux, Solaris, BSDライクのOSでサポートされます。

ノート: Squidは同じサブネットに存在するクライアントのみMACアドレスを知ることができます。 別のサブネットにクライアントが有る場合にはそのMACアドレスを知ることは出来ません。

ARP ACLsを使う為には、コンパイル時に--enable-arp-aclオプションでconfigureを行う必要があります。

% ./configure --enable-arp-acl ...
% make clean
% make

これでコンパイルしたなら、以下のようのACLを追加することができます。

acl M1 arp 01:02:03:04:05:06
acl M2 arp 11:12:13:14:15:16
http_access allow M1
http_access allow M2
http_access deny all

10.21 デバックのためのACLは?

詳しくは、11.20 トラブルシューティング. を見てください。

10.22 接続できるクライアントの数を制限したのです。

maxconn ACLによって可能です。以下の例を見てください。

acl losers src 1.2.3.0/24
acl 5CONN maxconn 5
http_access deny 5CONN losers

上記の場合、ソースの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)と一緒に使うと良いでしょう。

10.23 foo.comへの接続を拒否したいが出来ません。

squid-2.3で私たちはSquidのサブドメインの扱いを変更しました。  .foo.comfoo.com では意味が違ってきます。 最初の指定では、 foo.com が含まれるすべてのドメイン名にマッチします。(ex. "abcfoo.com", "www.xxxfoo.com")
一方、後者の場合には foo.com と完全に一致するドメイン名の場合にマッチします。
もし特定のドメインをすべて許可しないようにするなら、

acl yuck dstdomain .foo.com
http_access deny yuck

としてください。

10.24 エラーメッセージをカスタマイズしたいです。

エラーメッセージのカスタマイズについては「エラーメッセージのカスタマイズ」で述べられています。あなたは、既存のエラーメッセージをカスタマイズしたり、新規のエラーメッセージを作成して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).

次に以下のようなアクセス制御を行います。

acl porn url_regex "/usr/local/squid/etc/porno.txt" --- porno.txtで実際の許否URLを定義する
deny_info ERR_NO_PORNO porn
http_access deny porn
(additional http_access lines ...)

10.25 エラーメッセージの中でローカルのタイムゾーンを使いのですが?

Squidはデフォルトで作成されるエラーメッセージのすべてでGMTを使います。これによりキャッシュの階層に参加する際、異なるタイムゾーンをもつキャッシュに混乱を与えることなく参加する事ができます。 

Squidが作成するエラーメッセージで異なるタイムゾーンに変更する場合、あなたはSquidのシグネーチャを変更する必要があります。エラーメッセージのカスタマイズを参照してください。シグネーチャで標準はタイムスタンプに%Tが使われています。 しかしこの代わりにローカルのタイムスタンプの%tを使うことができます。

10.30 アクセス不可の時に、専用のエラーページにしたいのですが。

Squidが許可しないアクセスリクエストがあった場合に、専用のエラーページを表示させたい場合には、squid.confの中で「deny_info」を定義すると良いでしょう。 

10.31 特定のサイトには親・兄弟キャッシュではなく子キャッシュのみアクセスできるようにしたいのですが。

cache_peer_accessを使って、特定のサイトへのアクセスの場合にpeerアクセスをしないようにコントロールできます。

例、 subnetのサイトへは親キャッシュ(proxy1.domain)にpeerアクセスしない設定です。

cache_peer proxy1.domain parent 8080 3130
acl subnet dst 10.0.0.1/8
cache_peer_access proxt1.domain deny subnet

10.32 external_acl_typeの使い方が良く判りません。

external_acl_type は、認証の拡張として利用できます。 通常の認証において、ユーザのIDとパスワードによる認証が完了すればアクセスが可能になります。
しかし、認証において、例えばある各ユーザ毎にアクセス可能な時間帯を変えたり、特定のユーザが利用できるサブネットワークからのアクセスを制限させたりと、細かな認証制御を行いたい場合もある事でしょう。

このような場合、DBにユーザIDと共に「利用可能時間帯」や「利用可能サブネット」を登録しておき、external_acl_typeで指定するヘルパープログラムによってこのDBを検索させて、このヘルパープログラムがOKまたはERRを返すようにする事で単なるユーザIDによる認証以上の細かな制限が可能になってきます。

この良いサンプルがこちらにあります。

10.33 ACLで使う名前は最大何文字ですか?

デフォルトではACLの名前は 32-1 即ち 31文字までです。これを変更する場合にはソースファイルのdefines.h の中で次のように指定します。

#define ACL_NAME_SZ 32
Squid Home / FAQトップ

参考: