【Squid FAQ】 最終更新日:2005年9月9日

D-netプランページへ】【Squid Homeへ】 【FAQトップへ】

17. 透過プロキシ/キャッシュ(Interception Caching/Proxying)

どのようにすれば、ユーザに設定させる事無くブラウジングの際に私のプロキシキャッシュを使わせることができますか?

最初に、まずはsquid.confのコメントを読んでください。 それがもっとも信頼すべき情報です。 しかし以下に示す方法は1999/7現在では正しい筈です。

透過プロキシ/キャッシュを構成するには以下の4つの手順を踏む必要があります:

  1. 他のアドレスであっても受け付けるバージョンのSquidをコンパイルして実行してください。
    幾つかのオペレーティングシステムでは、接続をハイジャックして宛先アドレスを見分けるようにシステムを構成する必要があります。 Linuxではこれは自動的に行われます。 *BSDベースのシステムではおそらく --enable-ipf-transparent オプションをつけて Squid を構成する必要があります。 (以前に Squid をこ構成しているなら make clean で構成をきれいにしてから実行してください)

  2. Squid の設定で接続を受け入れるようにします。
    あなたはSquidの設定を変更して接続をハイジャックして宛先アドレスを見分けるようにしなくてはいけません。 Squid.conf での重要な設定項目は:

    http_port 8080
    httpd_accel_host virtual
    httpd_accel_port 80
    httpd_accel_with_proxy on
    httpd_accel_uses_host_header on

  3. あなたのキャッシュサーバでパケットを受けられるようにしてください。 
    あなたのキャッシュホストはどんな宛先であってもポート80のパケットを受け入れるように構成しなくてはなりません。 もしかするとIPフィルタリングがカーネルに組み込まれていて、これを使ってすべてのポート80のパケットを受け入れるようできるかも知れません。 Linuxではこれはiptables(カーネル2.4)、ipchains(2.2)またはipfwadm(2.0)、FreeBSDではipfwyaと呼ばれています。 他のBSDベースのシステムではip filter ipnat と云われているかもしれません。(FreeBSD3.xからはipfwでなくip filter ipnat がサポートされています)

  4. キャッシュサーバにパケットを送ってください。
    これには幾つかの方法があります。 第1に、もしあなたのプロキシマシン常にパケットが通る位置(パケットパス)にある(例えばプロキシマシンがインターネットへのルータとして機能している)ならあなたは何もしなくて構いません。
    もし、プロキシがパケットパス上にないなら、ルータやスイッチをつかってパケットをプロキシへ集める必要があります。 あなたがCISCOのルータを使っているなら、IOSの"route maps"機能で実現できるかも知れません。 また、あなたは Alteon ACE-director や Foundry Networks 社等の Layer-4 と呼ばれるスイッチを使うことで集めることもできます。 最後として、スタンドアロンのルータやロードバランサ製品やルーティング機能を持ったアクセスサーバなどを使うこともできるでしょう。

注意:

17.1 Solaris, SunOS, BSDシステムによる透過プロキシ/キャッシュ

メモ: FreeBSD3.x以前ではip filterではなく代わりに内蔵の ipfw 機能を使ってください。 後述のFreeBSD節を参照してください。FreeBSD3.0以上では、以下のように設定できます。

IPフィルターのインストール

もし既に、 IP Filter パッケージ がインストールされていないならこれを入手してインストールしてください。(FreeBSDを普通にインストールするとipフィルターはインストールされています)

ip-filter の設定

ip-filterを設定して、プロキシマシンでポート80のパケットを受け取れるように設定してください。 以下ではテストの為、すべてのパケットを受け入れるルールを設定します。
/etc/ipf.rules に対する設定
#
pass in all
pass out all


なお実際のフィルタルールは使う環境に合わせて安全な設定を行ってください。
ip-filterがシステム起動時に設定されるように起動スクリプトを設定してください。
FreeBSD3.x以降では、/etc/rc.conf ファイで以下のように記述します。

ipfilter_enable="YES"
ipfilter_rules="/etc/ipf.rules"
ipfilter_flags=""


ipnatの設定

/etc/ipnat.rules に対する設定:
# Redirect direct web traffic to local web server.
rdr de0 192.168.1.2/32 port 80 -> 192.168.1.2 port 80 tcp
# Redirect everything else to squid on port 8080
rdr de0 0.0.0.0/0 port 80 -> 192.168.1.2 port 8080 tcp
ここで、de0 はLANインターフェース名なのでifconfigコマンドで、インターフェース名は確認してください。 

この例では、自分宛のhttpパケット(80)はそのまま自分自身のWebサーバに渡して以外のパケットを8080へ渡すように設定しています。 それ以外のアドレス宛の80ポートへのパケットは8080へリダイレクトします。
(もしかしたら、apacheなどの受付ポートを81とかにして、最初のルールを
rdr de0 192.168.1.2/32 port 80 -> 192.168.1.2 port 81 tcp
とかにする方がより良いかも知れません。)
スタートアップスクリプトを編集してipnatを有効にします。 例えばFreeBSDでは/etc/rc.confで次のように指定します:
ipnat_enable="YES"
ipnat_program="/sbin/ipnat -CF -f" file
ipnat_rules="/etc/ipnat.rules"
ipnat_flags=""

ip-filterとipnatの設定が終わった一度リブートして設定を有効にしてください。 設定ができているかは、

# ipfstat -i
# ipfstat -o
# ipnat -l

で確認できます。

Squidの設定

■Squid-2の場合

Squid-2(beta25以降)ではIPフィルターをサポートします。 この為には configure を次のように実行します。
./configure --enable-ipf-transparent
そして squid.conf で次のように指定しいます:
http_port 8080
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on

ノート: ポートは8080でなくても構いませんが、必ず/etc/ipnat.rules での指定を合わせてください。

■Squid-1.1の場合

Quinton Dolan's Squid page.によるパッチを適用することでSquid-1.Xも利用できます。 squid.conf では次のように指定します:
http_port 8080
httpd_accel virtual 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on

Quinton Dolan.、ありがとう。

17.2 Linux 2.0 と ipfwadm での透過プロキシ/キャッシュ

Rodney van den Oever による

注意: 透過プロキシ/キャッシュはLinux 2.0.30では動かない。 Linux 2.0.29で十分に動作する。もしあなたが最近の 2.2.xのカーネルを使うなら ipchains で構成すべきです。 これについては後述します。
警告: このテクニックにはいくつかの欠陥があります。
  1. メソッドとしてHTTPプロトコルしかサポートしません。 FTPやgopherはサポートしません。
firewallingとリダイレクションをサポートする為のカーネルコンパイルオプションがあります。 これらの重要なパラメータは/usr/src/linux/.configの中で、
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
#
# Networking options
#
CONFIG_FIREWALL=y
# CONFIG_NET_ALIAS is not set
CONFIG_INET=y
CONFIG_IP_FORWARD=y

# CONFIG_IP_MULTICAST is not set
CONFIG_IP_FIREWALL=y
# CONFIG_IP_FIREWALL_VERBOSE is not set
CONFIG_IP_MASQUERADE=y
CONFIG_IP_TRANSPARENT_PROXY=y
CONFIG_IP_ALWAYS_DEFRAG=y

# CONFIG_IP_ACCT is not set
CONFIG_IP_ROUTER=y
とします。 また、IPフォワードを有効にする為に、スタートアップスクリプトで次のように指定してください。
echo 1 > /proc/sys/net/ipv4/ip_forward
Linux IP Firewall and Accounting ページに行って、ipfwadmのソースを入手してインストールしてください。ipfwadmはバージョン2.3.0よりも小さいバージョンでないと働かないかもしれません。 あなたは、ipfwadmを使ってリダイレクションを設定します。 私はブート時にインターフェースを整える/etc/rc.d/rc.inet1(Slackware)から走るスクリプトにこの規則を加えました。 

/etc/rc.d/rc.firewall

        #!/bin/sh
        # rc.firewall   Linux kernel firewalling rules
        FW=/sbin/ipfwadm

        # Flush rules, for testing purposes
        for i in I O F # A      # If we enabled accounting too
        do
                ${FW} -$i -f
        done

        # Default policies:
        ${FW} -I -p rej         # Incoming policy: reject (quick error)
        ${FW} -O -p acc         # Output policy: accept
        ${FW} -F -p den         # Forwarding policy: deny

        # Input Rules:

        # Loopback-interface (local access, eg, to local nameserver):
        ${FW} -I -a acc -S localhost/32 -D localhost/32

        # Local Ethernet-interface:

        # Redirect to Squid proxy server:
        ${FW} -I -a acc -P tcp -D default/0 80 -r 8080

        # Accept packets from local network:
        ${FW} -I -a acc -P all -S localnet/8 -D default/0 -W eth0

        # Only required for other types of traffic (FTP, Telnet):

        # Forward localnet with masquerading (udp and tcp, no icmp!):
        ${FW} -F -a m -P tcp -S localnet/8 -D default/0
        ${FW} -F -a m -P udp -S localnet/8 -D default/0
これでLANからのどんな宛先のポート80へのパケットはローカルホスト(自分自身)のポート8080に転送されます。 規則を表示させると次のように見えます。:
        IP firewall input rules, default policy: reject
        type  prot source               destination          ports
        acc   all  127.0.0.1            127.0.0.1            n/a
        acc/r tcp  10.0.0.0/8           0.0.0.0/0            * -> 80 => 8080
        acc   all  10.0.0.0/8           0.0.0.0/0            n/a
        acc   tcp  0.0.0.0/0            0.0.0.0/0            * -> *
あるとき、LANからのアクセスでWebサーバとしてプロキシを指定した時に、ループに入ってしまいました。これはクライアントからの要求を拒否することで避けられるかもしれません。
        ${FW} -I -a rej -P tcp -S localnet/8 -D hostname/32 80

        IP firewall input rules, default policy: reject
        type  prot source               destination          ports
        acc   all  127.0.0.1            127.0.0.1            n/a
        rej   tcp  10.0.0.0/8           10.0.0.1             * -> 80
        acc/r tcp  10.0.0.0/8           0.0.0.0/0            * -> 80 => 8080
        acc   all  10.0.0.0/8           0.0.0.0/0            n/a
        acc   tcp  0.0.0.0/0            0.0.0.0/0            * -> *



17.3 Linux 2.2 と ipchainsでの透過プロキシ/キャッシュ

Martin Lyonsによる、

あなたは ipchains が機能するようにカーネルを構築する必要があります。カーネルの構築に関してはこのFAQの範疇を越えていますので詳しい情報は Linux JFLinux HQ とかを参考にすると良いでしょう。カーネルの再構成の一般的な手順は:
# cd /usr/src/linux
# make menuconfig
を実行して以下のよう機能を組み込むことが必要です。
        [*] Network firewalls
        [ ] Socket Filtering
        [*] Unix domain sockets
        [*] TCP/IP networking
        [ ] IP: multicasting
        [ ] IP: advanced router
        [ ] IP: kernel level autoconfiguration
        [*] IP: firewalling
        [ ] IP: firewall packet netlink device
        [*] IP: always defragment (required for masquerading)
        [*] IP: transparent proxy support
あなたは、 IP: always defragment (required for masquerading) を組み込む必要があります。さもないとリダイレクトの機能が使えません。
以下は、ipchainsを構成する為のスクリプト(rc.firewall)の例です。
        #!/bin/sh
        # rc.firewall   Linux kernel firewalling rules
        # Leon Brooks (leon at brooks dot fdns dot net)
        FW=/sbin/ipchains
        ADD="$FW -A"

        # Flush rules, for testing purposes
        for i in I O F # A      # If we enabled accounting too
        do
                ${FW} -F $i
        done

        # Default policies:
        ${FW} -P input REJECT   # Incoming policy: reject (quick error)
        ${FW} -P output ACCEPT  # Output policy: accept
        ${FW} -P forward DENY   # Forwarding policy: deny

        # Input Rules:

        # Loopback-interface (local access, eg, to local nameserver):
        ${ADD} input -j ACCEPT -s localhost/32 -d localhost/32

        # Local Ethernet-interface:

        # Redirect to Squid proxy server:
        ${ADD} input -p tcp -d 0/0 80 -j REDIRECT 8080

        # Accept packets from local network:
        ${ADD} input -j ACCEPT -s localnet/8 -d 0/0 -i eth0

        # Only required for other types of traffic (FTP, Telnet):

        # Forward localnet with masquerading (udp and tcp, no icmp!):
        ${ADD} forward -j MASQ -p tcp -s localnet/8 -d 0/0
        ${ADD} forward -j MASQ -P udp -s localnet/8 -d 0/0
カーネル2.0では不要でしたが、カーネル2.1、2.2では、ipフォワーディングを有効にするために次のコマンドが必要です。
echo 1 > /proc/sys/net/ipv4/ip_forward


17.4 Linux 2.4 と netfilterでの透過プロキシ/キャッシュ

注:この情報は Daniel Kiracofe's の Transparent Proxy with Squid mini-HOWTO. によります。

Linux2.4上で--enable-linux-netfilter をつけて構成されたSquidはnetfilter transparent interceptionをサポートします。

netfilterをサポートする為にカーネルを再構築する場合には次のオプションが有効になっている事を確認してください。

また、

"Fast switching"にはNoを指定しなくてはいけません。 カーネルの再構築が終わってインストールできたなら再起動してください。

パケットフォワードも(起動スクリプトなどで)有効にする必要があります。そのためには、
echo 1 > /proc/sys/net/ipv4/ip_forward
を実行します。
iptablesコマンドを使ってあなたのカーネルにHTTPコネクションを捕まえさせて、Squidにそれらを送ってください。
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080


17.5 CISCOルータによる透過プロキシ/キャッシュへのルート

John Saundersによる、

以下の説明はIOS11.1よりも新しい場合に機能します。 でもその前に、私はCISCOの専門家ではないので私のいう事は完全に信頼しないでください。 

最初にproxy-redirectという名前(名前はどんな名前でも良い)のルートマップを定義し、次のホップ先をSquidマシンとした指定を行います。

        !
        route-map proxy-redirect permit 10
         match ip address 110
         set ip next-hop 203.24.133.2
        !

続いてアクセスリストを作成してHTTPリクエストをトラップします。 2番目の行ではルーティングループを避ける為にSquidマシンへの直接アクセスパケットを拒否するようにしています。 

        !
        access-list 110 deny   tcp any any neq www
        access-list 110 deny   tcp host 203.24.133.2 any
        access-list 110 permit tcp any any
        !

そして、イーサネットインターフェースにルールを適用します。

        !
        interface Ethernet0
         ip policy route-map proxy-redirect
        !

起こりうるバグ:

ブルース・モーガンは、CiscoにおいてIPポリシールートマップを利用し透過プロシキをお行った場合に関連するバグを報告しています。それは、NFS並びに他のアプリケーションによて引き起こされます。


17.6 Linux2.0.29とCISCO IOS 11.1でのように透過プロキシを実現しますか

ドンピシャリ。いまここに、Squid-userメーリングリストにポストしたCiscoルータとLinux上のSquidを使った透過プロキシについてのメッセージがあります。

Brian Feeny による:

いま私の手元にIOS 11.1のCisco2501とLinux2.0.33上の環境で動作している透過プロキシがあります。 
以下の方に感謝します。Squid-usersメーリングリストで助けてくれたことで私のCisco/Linuxボックスでリダイレクションと透過プロキシが機能するようになりました。

最初に、私のCiscoはIOS11.1で動作しています。 IOS 11.1におけるroute-mapコマンドは"プロセス スイッチ"で、IOS 11.2以上での速度の速い"fast-switched"のroute-mapとは違うものです。 あなたは、IOS11.2 を使いたいかもしれませんが、私の11.1でもSquidに同時に150の接続を行っても全く問題は発生していません。私のIOS11.1の設定は:

        !
        interface Ethernet0
         description To Office Ethernet
         ip address 208.206.76.1 255.255.255.0
         no ip directed-broadcast
         no ip mroute-cache
         ip policy route-map proxy-redir
        !
        access-list 110 deny   tcp host 208.206.76.44 any eq www
        access-list 110 permit tcp any any eq www
        route-map proxy-redir permit 10
         match ip address 110
         set ip next-hop 208.206.76.44

基本的には、上の設定では"route-map"での定義を行い、それをint e0での"ip policy route-map proxy-redir"で使うようにしています。

判りますか。 これがCiscoにおける設定のポイントです。この設定においての、208.206.76.44はSquidの動いているホストのIPアドレスです。

私のSquidの動くLinuxでは次のような指定を行いました。
尚、私のカーネルは(2.0.33)です:

        Networking options
        #
        CONFIG_FIREWALL=y
        # CONFIG_NET_ALIAS is not set
        CONFIG_INET=y
        CONFIG_IP_FORWARD=y
        CONFIG_IP_MULTICAST=y
        CONFIG_SYN_COOKIES=y
        # CONFIG_RST_COOKIES is not set
        CONFIG_IP_FIREWALL=y
        # CONFIG_IP_FIREWALL_VERBOSE is not set
        CONFIG_IP_MASQUERADE=y
        # CONFIG_IP_MASQUERADE_IPAUTOFW is not set
        CONFIG_IP_MASQUERADE_ICMP=y
        CONFIG_IP_TRANSPARENT_PROXY=y
        CONFIG_IP_ALWAYS_DEFRAG=y
        # CONFIG_IP_ACCT is not set
        CONFIG_IP_ROUTER=y

Firewalling と Transparent Proxy に対する指定は最低限必要です。そして、ipfwadmでの指定は

そして、イーサネットインターフェースにルールを適用します。

        # Accept all on loopback
        ipfwadm -I -a accept -W lo
        # Accept my own IP, to prevent loops (repeat for each interface/alias)
        ipfwadm -I -a accept -P tcp -D 208.206.76.44 80
        # Send all traffic destined to port 80 to Squid on port 3128
        ipfwadm -I -a accept -P tcp -D 0/0 80 -r 3128

この設定によって、ポートは80で受け取った(これはCiscoからリダイレクトされてきます)パケットを、Squidプロセスで指定したポート3128へリダイレクトしています。 上記の設定は/etc/rc.d/rc.localで行いました。

私はSquid V1.1.20に Henrik's patch のパッチをインストールして使いました。 あなたが同じようなものを使うならパッチを適用すると良いでしょう。

D-netプランページへ】【Squid Homeへ】 【FAQトップへ】

Copyright© 1998-2003 ROBATA.ORG