注意点
この質問は、既に行った方法と、これからやろうと試みているが、理解が足りず進んでいない部分を並列して載せているので、読みづらいかと思います。
ご了承ください。
##前提・実現したいこと
2つの回線があり、メインの回線とは別に、特定の操作をした時に通信がサブ回線を経由するようにしたい。
今、以下のようなネットワーク構成であるとする。
(subnet-A : 192.168.0.0/24) clien-pc(192.168.0.2)ー main-gw(192.168.0.1)ーwan1 | | | rpi-eth0 (192.168.0.3) | (rpi内部) rpi-eth1 (192.168.1.3) | sub-gw (192.168.1.1)ーwan2 (subnet-B : 192.168.1.0/24)
client-pc : ubuntu 18.04 (client-pcは今後増える可能性あり)
rpi : raspberry pi stretch
main-gw,sub-gw : 市販のルータで、dhcpサーバ機能を持つ
rpiには、lanケーブルとusb-lanアダプタの2つのnicがついており、それぞれeth0,eth1である。また、ip割当は各ルータのdhcp機能により行った。rpiがルータの役割をする事はない。
特定の操作をしたときに、client-pcの通信がsub-gwを経由してwan2を利用できればよいので、
どんな方法でも良いが、client-pcのip routeの変更やvpn設定はしたくない。
プログラムの通信を経由させる事を考えると、プログラム上でも人間でも簡単な操作により、wan2が利用できることが望ましいので、方法はプロキシあたりになると思います。
そして、大きな変更はプロキシとなるrpiに対して行うものとして、
client機器には負担をかけたくない。
自分が考えている方法は、rpi-eth0にプロキシ接続をして、ルーティングされる方法です。
やった方法は、 「dante socks proxy」で、
途中で諦めて、再び試しているのは、「squid + iptables」です。
できていないので、経緯を詳しく書きます。
使用したツールについての動作や概念を正しく理解している自信がないため、
自分の理解を提示しつつ、説明を書いていきます。
発生している問題・エラーメッセージ(その1)
danteについて
・subnet-B宛の通信はeth1を経由するが、それ以外はeth0経由となる。
該当のソースコード
「danted.conf」の設定
・入口と出口のnicを別々にした
・カーネルパニック対策にローカルアドレスに対しても、client passを設定した。(https://qiita.com/hirohiro77/items/087c4d9e6b03050f70ad)
# $Id: sockd.conf,v 1.52.10.2 2014/09/03 14:49:13 michaels Exp $ logoutput: syslog stdout /var/log/sockd.log debug: 1 internal: eth0 port = 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
