CentOS 7サーバーでTPROXYをSquidとIPv6で動作させるのに問題があります。以前は一般的なインターセプトセットアップをNATで使用していましたが、IPv4のみに制限されていました。 TPROXYにIPv6を含めるようにセットアップを拡張しています。
私はこの件に関する公式のSquid wiki記事を使用してすべてを構成しています:
http://wiki.squid-cache.org/Features/Tproxy4
これまでのところ、TPROXY構成はIPv4で問題なく機能しているようです。ただし、IPv6を使用すると、接続がタイムアウトになり、正しく機能しません。理解を深めるために、セットアップを細かく説明します。
すべてのファイアウォールとルーティングルールはIPv4でもまったく同じであることに注意してください。以下の例でIPv6ベースのルールを構成する場合の唯一の違いは、inet6
とip6tables
です。
IPv6接続は現在、ハリケーンエレクトリックを介した6in4トンネルを介して行われ、これはDD-WRTルーターで構成され、割り当てられたプレフィックスがradvd
を介してクライアントに委任されます。 Squidボックスには、いくつかの静的IPv6アドレスが構成されています。
Squidボックスは、サービスを提供しているメインLAN内にあります。ポート80でトラフィックが傍受されているクライアント(主にワイヤレスクライアント)は、ポリシールーティングウィキの記事とDD-WRTウィキから変更された次のファイアウォールとルーティングルールを使用して、DD-WRTルーター経由でSquidボックスにプッシュされます
http://www.dd-wrt.com/wiki/index.php/Squid_Transparent_Proxy
ip6tables -t mangle -A PREROUTING -i "$CLIENTIFACE" -s "$PROXY_IPV6" -p tcp --dport 80 -j ACCEPT
ip6tables -t mangle -A PREROUTING -i "$CLIENTIFACE" -p tcp --dport 80 -j MARK --set-mark $FWMARK
ip6tables -t mangle -A PREROUTING -m mark --mark $FWMARK -j ACCEPT
ip6tables -t filter -A FORWARD -i "$CLIENTIFACE" -o "$CLIENTIFACE" -p tcp --dport 80 -j ACCEPT
ip -f inet6 rule add fwmark $FWMARK table 2
ip -f inet6 route add default via "$PROXY_IPV6" dev "$CLIENTIFACE" table 2
これは、トラフィックをSquidボックスに渡すことに関しては問題なく動作しているようです。上記に加えてDD-WRTルーターに追加しなければならない1つの追加のルールは、Squidボックスで構成された発信IPv4およびIPv6アドレスの例外ルールでした。 3128
でSquidを使用するメインLAN。
ip6tables -t mangle -I PREROUTING -p tcp --dport 80 -s "$OUTGOING_PROXY_IPV6" -j ACCEPT
Squidボックスでは、次のルーティングルールとDIVERTチェーンを使用して、トラフィックを適切に処理しています。テスト中に既存のチェーンのエラーを防ぐために、ルールを追加する必要がありました。私のファイアウォールはCSF
です。csfpre.sh
に以下を追加しました
ip -f inet6 route flush table 100
ip -f inet6 rule del fwmark 1 lookup 100
ip -f inet6 rule add fwmark 1 lookup 100
ip -f inet6 route add local default dev eno1 table 100
ip6tables -t mangle -F
ip6tables -t mangle -X
ip6tables -t mangle -N DIVERT
ip6tables -t mangle -A DIVERT -j MARK --set-mark 1
ip6tables -t mangle -A DIVERT -j ACCEPT
ip6tables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
ip6tables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 3129
squid.conf
は2つのポート用に構成されています:
http_proxy 3128
http_proxy 3129 tproxy
さらに、Privoxyも使用しており、no-tproxy
をcache_peer行に追加する必要がありました。そうしないと、両方のプロトコルですべてのトラフィックを転送できませんでした。
cache_peer localhost parent 8118 7 no-tproxy no-query no-digest
Privoxyのため、tcp_outgoing_address
ディレクティブを使用していません。代わりに、CentOSとバインド順序を介して送信アドレスを制御しています。
sysctl値:
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.eno1.rp_filter = 0
rp_filter
の変更が必要かどうかは不明です。セットアップはIPv4で動作してもしなくても機能し、IPv6でも同じ結果になります。
SELINUXはSquidボックスで有効になっていますが、ポリシーがTPROXYセットアップを許可するように構成されているため、ブロックされていません(IPv4が機能していることが示されています)。 grep squid /var/log/audit/audit.log | audit2allow -a
で確認し、<no matches>
を取得しました
#============= squid_t ==============
#!!!! This avc is allowed in the current policy
allow squid_t self:capability net_admin;
#!!!! This avc is allowed in the current policy
allow squid_t self:capability2 block_suspend;
#!!!! This avc is allowed in the current policy
allow squid_t unreserved_port_t:tcp_socket name_connect;
次のブール値も設定しました:
setsebool squid_connect_any 1
setsebool squid_use_tproxy 1
最終的に、TPROXYクライアントのIPv6接続は完全に切断されます(WPAD/PACファイルを使用するポート3128
のLANクライアントは、完全に機能するIPv6を持っています)。トラフィックが何らかの方法でSquidボックスにルーティングされているように見えますが、access.log
にはTPROXY経由のIPv6経由のリクエストは表示されていません。すべてのIPv6は、リテラルIPv6とDNSの両方、タイムアウトを要求します。内部IPv6クライアントにアクセスできますが、このトラフィックもログに記録されません。
Test-ipv6.comを使用していくつかのテストを行ったところ、発信Squid IPv6アドレスが検出されましたが、IPv6テストはbad/slowまたはタイムアウトとして表示されました。 viaヘッダーを一時的に有効にしたところ、Squid HTTPヘッダーが表示されていたため、トラフィックは少なくともSquidボックスに到達していますが、そこに到達すると正しくルーティングされていません。
私はこれをしばらく動作させるように努めてきましたが、問題が何であるかを見つけることができません。Squidメーリングリストでさえ尋ねましたが、実際の問題を診断したり解決したりすることはできませんでした。私のテストに基づいて、私はそれが次の領域の1つとSquidボックスが問題であることをかなり確信しています:
TPROXYとIPv6を機能させるために私が実行できるアイデアや追加の手順は、大歓迎です。
ip6tablesルール:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DIVERT tcp ::/0 ::/0 socket
TPROXY tcp ::/0 ::/0 tcp dpt:80 TPROXY redirect :::3129 mark 0x1/0x1
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
Chain DIVERT (1 references)
target prot opt source destination
MARK all ::/0 ::/0 MARK set 0x1
ACCEPT all ::/0 ::/0
IPv6ルーティングテーブル(不明瞭なプレフィックス)
unreachable ::/96 dev lo metric 1024 error -101
unreachable ::ffff:0.0.0.0/96 dev lo metric 1024 error -101
2001:470:xxxx:xxx::5 dev eno1 metric 0
cache mtu 1480
2001:470:xxxx:xxx:b451:9577:fb7d:6f2d dev eno1 metric 0
cache
2001:470:xxxx:xxx::/64 dev eno1 proto kernel metric 256
unreachable 2002:a00::/24 dev lo metric 1024 error -101
unreachable 2002:7f00::/24 dev lo metric 1024 error -101
unreachable 2002:a9fe::/32 dev lo metric 1024 error -101
unreachable 2002:ac10::/28 dev lo metric 1024 error -101
unreachable 2002:c0a8::/32 dev lo metric 1024 error -101
unreachable 2002:e000::/19 dev lo metric 1024 error -101
unreachable 3ffe:ffff::/32 dev lo metric 1024 error -101
fe80::/64 dev eno1 proto kernel metric 256
default via 2001:470:xxxx:xxxx::1 dev eno1 metric 1
私はこれが古いことを理解しており、私自身はこれに対する完全な答えはありませんが、私はあなたと非常によく似たことをしており、ほぼ同じ症状を持っています。
最初に、test-ipv6.comは、新しいタイプのエラーを処理できるように、最近更新されたようです(今年の初めに壊れました)。もう一度テストしてください。
私の場合、私が抱えていると思われる問題を説明するURL Path MTU Detection FAQ に私を送りました。これらは、cURLで使用してPMTUDテストを実行できるURLを提供し、tpcdump
またはWiresharkを使用してトラフィックを確認できます。
トラフィックがSquid経由でプロキシされている場合、IPv6パスMTU検出がホストで完全に機能していません。 (私はまだそれがmyホストで機能しない理由に取り組んでいるので、明確な解決策はありません)。
簡単な説明:
したがって、ファイアウォールルールがICMPv6メッセージを受け入れるように設定されていることを確認する必要がある場合があります(「必要な」ICMPタイプのリストについては、RFC4890を参照してください)。
私の場合、ICMPメッセージを許可していますが、まだ問題があります。タオルを投入する準備がまだ十分ではなく、ネットワークのMTU(核のオプション)を減らすだけです。