質問: 1080 external: eth1 socksmethod: none clientmethod: none user.privileged: root user.unprivileged: nobody timeout.connect: 30 client pass { from: 192.168.0.0/24 port 1-65535 to: 0.0.0.0/0 } client pass { from: 127.0.0.1/32 port 1-65535 to: 0.0.0.0/0 } socks pass { from: 192.168.0.0/24 to: 0.0.0.0/0 } ``` ### 試したこと まず、firefoxのプロキシ設定を protocol version : socks_v4 or v5 proxy server:eth0のipアドレス に設定した。 また、上記に記載したdanted.confの設定により、eth0からeth1に転送できるようにしたつもり。 #### client-pcからのsocks proxy接続の結果について、 sub-gw(192.168.1.1)の管理画面にはアクセスできる、つまり、 subnet-B(eth1を経由とは書かない)を経由しているが、 1.1.1.1 (dns無しでhttp/httpsアクセス可能なアドレスで試行) には、 subnet-Aを経由しています。 tcpdumpで確認すると、 subnet-B宛は、tcpdump -i eth1 で確認できるが、 1.1.1.1宛は、tcpdump -i eth0で、しかも送信元が192.168.1.3(eth1)のアドレスです。 つまり、danteの設定において、 宛先がsubnet-B以外だと、必ずeth0から出力されるが、送信元がexternalで設定したeth1のアドレスとなり、応答パケット受信できないです。 この意味は、danteの設定において、interanlとexternalが異なる事は、 送信先ネットワークセグメントの違いとは限らない、ということなので、 セグメント分けには利用できないです。 #### proxy server本体となるrpiを送信元とする結果について rpiにssh loginしてpingすると、 subnet-B宛はeth1を通るが、 それ以外はeth0を経由しており、 宛先選択には、danteの設定以前にosのルーティングテーブルが優先されているようです。(以下に貼り付けた) danteなら異なるnic間の転送ができると期待しましたが、異なるネットワークセグメント間の転送はできないようです。 ``` root@raspberrypi:/# ip route default via 192.168.0.1 dev eth0 src 192.168.0.3 metric 202 default via 192.168.1.1 dev eth1 src 192.168.1.3 metric 203 192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.3 metric 202 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.3 metric 203 ``` 発生している問題・エラーメッセージ(というより、方法を模索中)(その2) ------------------------------------- ### squid + iptablesについて 次に考えたことは、rpiにsquidを立て、client-pcからsquidに対する通信をiptablesによりsubnet-Bへルーティングする事です。http/httpsプロキシの挙動については知らないので、自分の理解を示しながら説明していきます。 http/httpsプロキシだと、本来の通信先サーバがどこでも、 client-pcがrpi-eth0 (192.168.0.3:3218)を宛先とする通信しかしない (client-pcからwiresharkで確認)ので、 squidで処理したあとの通信をどうにかしてsubnet-Bに向ける事が重要です。 #### 中継プロキシ-通信先サーバの間の通信について http/httpsのproxy接続では、中継プロキシ-通信先サーバの間の通信は、 メインの通信内容(layer5以上?)はclient-pcのもの、 tcpヘッダまでは中継プロキシのものになる。 よって、実質的には、中継プロキシであるrpiを発信元とする通信とみなして問題を考えれば良い。 そこで、このサイトの https://www.virment.com/iptables-outline/ 「各チェインがどのパケットを対象とするかを表したイメージ図」を参考にすると、 「squid」というローカルプロセスで処理された通信を、「OUTPUT」「POSTROUTING」で操作する必要があります。 そして、これらの説明には、 引用文: 「 OUTPUTとPOSTROUTINGの違い OUTPUTはローカルプロセスに処理されて出力されたパケット、すなわち送信元がホストマシンであるパケットを対象としているのに対し、POSTROUTINGは送信元がホストマシンであるとは限りません。例えば、FORWARDによって転送されたパケットも対象となります。 」 とあり、今回はrpi本体からの通信とみなして良いので、 説明文中の「ホストマシン」だけを考えており、実質的には、「OUTPUT」だけを考えれば良いです。 しかし、これでは、iptablesから見た時に、 src ipはrpi本体、src portはランダムなため、 squidからの通信かどうか判別不能です。 さらに、iptablesのsubnet-Bへの転送設定を弄ろうとしているので、 OUTPUTで変な設定をすると、 rpiへのssh accessも含め、全てsubnet Bへ転送されて、 ssh切断の危険性もあります。 となると、iptablesをやめて、squidの設定に、 client-pcからのsquid宛はsubnet-Bへ転送させる設定をする必要があります。 そのような設定があるか探しましたが、転送先を変更する方法として、「tcp_outgoing_address」というものがありましたが、 転送先nicではなく宛先ipが変更されるため、 通信先サーバへのアクセスができないです。 転送先nicとネットワークセグメントをうまく処理するツールがないため、 どうしようもありません。 自分でツール開発できるスキルはありません。 発生している問題・エラーメッセージ)(その3) ------------------------ rpiが起動しなくなり、再インストールしてから、squid + iptables で同様の設定までしたところ、何故かsub-gwへの転送ができなくなってしまいました。 やっていることは、「特定ユーザのip route変更」です。squidのユーザーであるproxyのip route変更のため、このサイトを参考にし、 (当該記事は、異なるnicの切り替えでなく、単純な同一ネットワーク内でのgw変更である) http://d.hatena.ne.jp/rti7743/20150320/1426880601 以下の操作をしました。 squidユーザのルーティングテーブル変更コード ``` #再起動で各nicのipが再dhcpリースにより変動するための自動的な取得方法 #https://askubuntu.com/questions/430853/how-do-i-find-my-internal-ip-address eth0_ip=$(ip addr show eth0 |grep -v inet6 | awk '/inet/ {print $2}' | cut -d/ -f1) && eth1_ip=$(ip addr show eth1 |grep -v inet6 | awk '/inet/ {print $2}' | cut -d/ -f1) proxy_route_tbl=proxygw && proxy_route_tbl_number=201 && echo 1 > /proc/sys/net/ipv4/ip_forward && echo "$proxy_route_tbl_number $proxy_route_tbl" >> /etc/iproute2/rt_tables && ip rule add fwmark 1 table $proxy_route_tbl && ip route add table $proxy_route_tbl default via 192.168.0.1 dev eth0 src $eth0_ip metric 203 && ip route add table $proxy_route_tbl default via 192.168.1.1 dev eth1 src $eth1_ip metric 202 && ip route add table $proxy_route_tbl 192.168.0.0/24 dev eth0 proto kernel scope link src $eth0_ip metric 203 && ip route add table $proxy_route_tbl 192.168.1.0/24 dev eth1 proto kernel scope link src $eth1_ip metric 202 && iptables -t mangle -P OUTPUT ACCEPT && iptables -t mangle -A OUTPUT -m owner --uid-owner proxy -j MARK --set-mark 1 # ip route,iptables 初期化用 ip rule del fwmark 1 table $proxy_route_tbl && ip route del table $proxy_route_tbl default via 192.168.0.1 dev eth0 src $eth0_ip metric 203 && ip route del table $proxy_route_tbl default via 192.168.1.1 dev eth1 src $eth1_ip metric 202 && ip route del table $proxy_route_tbl 192.168.0.0/24 dev eth0 proto kernel scope link src $eth0_ip metric 203 && ip route del table $proxy_route_tbl 192.168.1.0/24 dev eth1 proto kernel scope link src $eth1_ip metric 202 && iptables -F && iptables -F -t mangle ``` また、変更後のip route,iptablesの設定は、 ip routeの変更後の設定 ``` root@raspberrypi:/# ip route show table main default via 192.168.0.1 dev eth0 src 192.168.0.3 metric 202 default via 192.168.1.1 dev eth1 src 192.168.1.5 metric 203 192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.3 metric 202 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.5 metric 203 root@raspberrypi:/# ip route show table proxygw default via 192.168.1.1 dev eth1 src 192.168.1.5 metric 202 default via 192.168.0.1 dev eth0 src 192.168.0.3 metric 203 192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.3 metric 203 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.5 metric 202 ``` iptablesの変更後の設定 ``` root@raspberrypi:/# iptables -L 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 root@raspberrypi:/# iptables -L -t mangle Chain PREROUTING (policy ACCEPT) target prot opt source destination 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 MARK all -- anywhere anywhere owner UID match proxy MARK set 0x1 Chain POSTROUTING (policy ACCEPT) target prot opt source destination ``` また、rpi側から見たtcpdumpの結果としては、 client-rpi間は、普通に (eth0のip):3128 への通信 rpi-通信先サーバ間は、例えば1.1.1.1宛にすると、 物理nicがeth1でのdumpなのに、srcipがeth0のipとなり、 サーバからの応答を受信できません。 proxygwのルーティングテーブルは理解していますが、iptablesのmangleはまだ正しく理解していないところです。 ### 事前調査について よく「linuxルータを作ろう」などという記事があり、 異なるネットワーク間の通信を異なるnicでクリアしていますが、 今回はrpiをgwとする通常のルータの利用方法とは違うので、 それらの記事を参考にして、目標を達成することはできません。 また、英語の質問サイトで、本質問で挙げた3つのツールと「異なるnicに変更する方法」、「異なるネットワークに転送する方法」を調べても、これといったものはありませんでした。 普段のネット接続と別の通信にしたいなどの要望は多く、ip routeやvpnでの対応が多いが、設定を大幅に変更してしまい、普段のネットワーク環境を破壊する恐れがあるので、簡単な操作・変更で済みそうなプロキシーにより実現できると良い。 ### 続き 字数制限のため、新たな投稿をしました。 ### 補足情報(FW/ツールのバージョンなど) dante 1.52.10.2 iptables v1.6.0 squid3-3.5.23
回答: すみません、 dante と squid の問題はおいておいて、 以下のような方法はだめですか? * client PC のデフォルトゲートウェイを rpi-eth0 の 192.168.0.3 にする * rpi のデフォルトゲートウェイを eth0 から入ってきたものは main-gw(192.168.0.1) にし、eth1から入ってきたものはsub-gw(192.168.0.2)にする * rpi でデフォルトゲートウェイ向けの通信には SNAT でパケットの送信元IPを rpi のものにつけかえる こうすると、Clinet-PC は最初に rpi にパケットを投げます。 rpi は自分宛てのパケットではないので、パケットを自分のルーティングテーブルに従って main-gw に転送します。このとき、帰りも自分を経由するように送信元IPを付け替えておきます(転送先と送信元が同じセグメントの場合、この処理は不要かも)。main-gw はパケットを WAN に投げます。 2番めの処理を切り替えるだけで、パケットの行き先を sub-gw にできるように思うのですが。 2番めの処理には iproute2 が必要で、 ip rule, ip route などを駆使する必要があります。 全く検証していないので、落とし穴があるかもしれません。