質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Squid

Squidは、TCP/IPネットワークでのユーザーとサーバの通信を中継するオープンソースのプロキシサーバソフト。リバースプロキシやキャッシュサーバとして使用することも可能です。

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

ネットワーク

ネットワークとは、複数のコンピューター間を接続する技術です。インターネットが最も主流なネットワークの形態で、TCP/IP・HTTP・DNSなどの様々なプロトコルや、ルータやサーバーなどの様々な機器の上に成り立っています。

proxy

proxy(プロキシー)は、企業などの内部コンピュータとインターネットの中間に位置し、例えば直接インターネットに接続できない内部コンピュータの代理としてインターネットに接続する等をするシステム、もしくは代理として機能を実行するソフトウェアです。内部ネットワークへのアクセスを一元管理し、内部からの特定の種類の接続以外を遮断すること、外部からの不正アクセスを拒否することなどに用いられます。

Q&A

1回答

3019閲覧

プロキシー接続による異なるネットワーク間のルーティングができない

minsuke54

総合スコア4

Squid

Squidは、TCP/IPネットワークでのユーザーとサーバの通信を中継するオープンソースのプロキシサーバソフト。リバースプロキシやキャッシュサーバとして使用することも可能です。

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

ネットワーク

ネットワークとは、複数のコンピューター間を接続する技術です。インターネットが最も主流なネットワークの形態で、TCP/IP・HTTP・DNSなどの様々なプロトコルや、ルータやサーバーなどの様々な機器の上に成り立っています。

proxy

proxy(プロキシー)は、企業などの内部コンピュータとインターネットの中間に位置し、例えば直接インターネットに接続できない内部コンピュータの代理としてインターネットに接続する等をするシステム、もしくは代理として機能を実行するソフトウェアです。内部ネットワークへのアクセスを一元管理し、内部からの特定の種類の接続以外を遮断すること、外部からの不正アクセスを拒否することなどに用いられます。

0グッド

0クリップ

投稿2018/07/15 06:21

編集2018/09/07 11:52

注意点

この質問は、既に行った方法と、これからやろうと試みているが、理解が足りず進んでいない部分を並列して載せているので、読みづらいかと思います。
ご了承ください。

##前提・実現したいこと

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2018/07/15 12:32

「左側のaはスペースを反映させるための装飾で、特に意味はない。」全体を```と```で囲むと書いたとおりに等幅で表示されます。
TaichiYanagiya

2018/07/15 14:02

rpi のデフォルトゲートウェイを eth1 側(192.168.1.1)に変更すればいいと思うのですが、それは許可されないのでしょうか?
minsuke54

2018/07/15 15:42 編集

lanを2つのネットワークに分ける目的でrpiを使用しており、また、rpiをwan側にさらすつもりはありません。あくまでも、「特定操作の時に、subnet-Bを経由する事」が重要です。 また、おっしゃるとおりの、rpiのeth1をsub-gw(192.168.1.1)に対応させる方法でも、eth1側がsubnet-Bにあるという事実は変わらず、rpiを送信元とし宛先をsubnet-B以外とする通信はmain-gw経由になると思います。
TaichiYanagiya

2018/07/16 01:52

よくわかりませんが、metric を変更して eth1 を優先する、または、eth0 側のデフォルトルートを削除することはポリシー的に無理ということですか?
minsuke54

2018/07/16 16:49 編集

結論から言うと、squidによりsub-gwを経由できました。 ただ、これを毎回やるのかと思うと、もう少し良い方法がないものかと思います。 だから、解決済みにはしたくない。 まず、自分の理解を確認すると、そもそもルータがどうやって異なる物理nicにパケットを転送するかというと、物理nicではなく、物理nicの先のネットワークセグメントから判断して、宛先と流すべき物理nicを決定しているのでした。それは通常のosのルーティングテーブルも同様で、物理nicだけで判断する機能はないということです(??)。 (インテリジェントl2,l3スイッチ・ハブではどうだろう) そういうわけで、物理nicだけで転送を判断する方法がない以上はルーティングテーブルをいじるしかありません。そして、squidという特定プロセスだけのルーティングテーブルを変更できれば良いので、 特定プロセスのルーティングテーブルを変更する方法として、http://d.hatena.ne.jp/rti7743/20150320/1426880601 にあるように、squidのユーザーであるproxyの生成パケットにマークをつけ、そして、はじめの質問文に書いたraspbian osのip routeとはmetricのみ逆にしたところ、無事、sub-gwを経由してwan2へ出られました
guest

回答1

0

すみません、 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 などを駆使する必要があります。

全く検証していないので、落とし穴があるかもしれません。

投稿2018/07/17 10:52

mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

minsuke54

2018/07/18 16:58 編集

tcp_outgoing_addressで解決しました。
mit0223

2018/07/19 00:26

それは良かったです。では、自分で回答してベストアンサーにしてください。
minsuke54

2018/09/07 11:53

「まだ回答を求めています」 としましたが、返信ではない元の投稿の最後に、新たな投稿へのリンクを貼りました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問