Linuxでアプリケーションやユーザごとに、異なるdefault gateway を割り当てる変態ルーティングの方法
Linuxで、アプリケーションやユーザごとに、異なるデフォルトゲートウェイを割り当てたくなる時があります。
普通は、優先度とかで自動で切り替えとか、そーゆー感じですが、
そうではなくて、
ユーザAは、デフォルトゲートウェイ1を必ず使い、ユーザBは、デフォルトゲートウェイ2を絶対に使う。
プロセスAは、デフォルトゲートウェイ1を必ず使い、プロセスBは、デフォルトゲートウェイ2を絶対に使う。
そんな風にしたい時があります。
まあ、人生は長いですから、そういう時もあるのです。
ネッツ
PC 192.168.0.10 ---> HUB -->gateway1 192.168.0.100 -->gateway2 192.168.0.200
ユーザ user_proxygw は、192.168.0.200 を使い、
それ以外は、 192.168.0.100(default gw) を使うというのを考えてみます。
初期設定(前提条件)
adduser user_proxygw ifconfig eth0 192.168.0.10 route add defualt gw 192.168.0.100 route -n 受信先サイト ゲートウェイ ネットマスク フラグ Metric Ref 使用数 インタフェース 0.0.0.0 192.168.0.100 0.0.0.0 UG 0 0 0 eth0 192.168.0.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0
遊び方
# #まずはなにはともあれ、パケットを転送するように設定する. echo 1 > /proc/sys/net/ipv4/ip_forward # #ルーティングの名前を追加する。 #201とかの番号だけではわからなくなるので、 proxygw という名前を割り振ります。 #user_proxygw が使うルーティングルールだから、proxygw と命名します。 vi /etc/iproute2/rt_tables 201 proxygw # #ルーティングを設定します #パケットに1というフラグが立っているものは、 proxygw ルーティングルールを利用する。 #proxygwルーティングルールのデフォルトゲートウェイは 192.168.0.200 である。 ip rule add fwmark 1 table proxygw ip route add table proxygw default via 192.168.0.200 #間違ったら、 addをdelに変えて、 ip rule del fwmark 1 table proxygw とかすると消えます。 #現在の状態を確認するには、 ip rule show とか、 ip route show とか、やるといいらしいです。 # #パケットに1というマークを建てるために、変態御用達のiptableの mangleルールを使います。 #ユーザ user_proxygw が作成したパケットがきたら、 1というマークを建てる。 iptables -t mangle -P OUTPUT ACCEPT iptables -t mangle -A OUTPUT -m owner --uid-owner user_proxygw -j MARK --set-mark 1 #間違っちゃったら初期化してね #(iptablesを使うときは、コンソールへのアクセスができることを確認してからやろうね。ハマって真っ青にならないように) #iptables -F #iptables -F -t mangle
ようするに、以下の様なドミノ倒しが実行されます。
iptablesで、ユーザ user_proxygw が作ったパケットならば 1 というマークを立てます。
iptables -t mangle -A OUTPUT -m owner --uid-owner user_proxygw -j MARK --set-mark 1
1というマークがついていたら、proxygw というルーティングルールに移動します。
ip rule add fwmark 1 table proxygw
proxygw というルーティングルールのディフォルトゲートウェイは、192.168.0.200 です。
ip route add table proxygw default via 192.168.0.200
だから、 ユーザ user_proxygw が作成したパケットは、 192.168.0.200 を利用します。
逆に、それ以外のユーザが作ったパケットは、 iptables でマーク1を建てていないので、普通のデフォルトゲートウェイ 192.168.0.100 を利用します。
確認方法
su - root (or 適当なユーザ) traceroute -n 8.8.8.8 192.168.0.100を経由するはずです。 su - user_proxygw traceroute -n 8.8.8.8 192.168.0.200を経由するはずです。
プロセス単位で切り替える方法は?
実は、無理です。
セキュアOSとかだと lidsconf コマンドでフラグが建てられるそうです。
http://www.atmarkit.co.jp/fsecurity/rensai/lids12/lids02.html
普通のLinuxはそうはいきません。
ただし、uid単位(噂ではpid単位でもできるそうだが)、gid単位でできるそうなので、
制限したいプロセスを実行するユーザを限定すれば可能です。
例えば、squidは proxyユーザとかで動きますから、
proxyユーザのdefault gatewayをこの方法で閉じ込めてしまえば、squidを利用する人たちをこの方法で別のgatewayに転送できます。
問題は、curl などのユーザが特定できないコマンドです。
これは無理かもしれぬ。
方法を知っている人がいたら教えてください。
ローカルに、この方法で隔離したsquidを置いといて、そのsquidを利用してもらうとか・・・?
または、これらのコマンドを使うときは、制限したユーザになってから実行してもらうなど?
なかなかめんどくさそうです。