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を利用してもらうとか・・・?
または、これらのコマンドを使うときは、制限したユーザになってから実行してもらうなど?
なかなかめんどくさそうです。