概要
以前このような記事を書きました。
しばらくして次のような問題が出てきました。
- iproute2 4.xでこの書式を受け付けなくなった (Debian jessie->stretchでメジャーバージョンが上がった)
- キャリアグレードNATは提供する側の都合で仕様がかわる
- 長時間張りっぱなしのセッションは、データが流れないとCGN側で切られるけどこちら側からは切れたように見えない
- IMAPクライアント立ち上げっぱなしとかで困る
- sshに関しては特別扱いされるようになったっぽい
- 長時間張りっぱなしのセッションは、データが流れないとCGN側で切られるけどこちら側からは切れたように見えない
- 出口IPがサービスによってはBANされてることがある
これに対し、「80, 443以外はDS-Lite使うのをやめたら」という助言を知人よりいただいたので、それを実践してみました。
トンネルインターフェースの作成
以前の記事にあるままです。そちらを参考にしてください。できあがったインターフェースはip5tnl1という名前とします。
Netfilterのmark機能
Linux Advanced Routing & Traffic Control HOWTOのChapter 11が詳しいです。
-
https://linuxjf.osdn.jp/JFdocs/Adv-Routing-HOWTO/lartc.netfilter.html
- (注意: ネット上にある古い記事の中には linux.or.jp ドメイン上にLinux JF(Japanese FAQ) Projectへのリンクを張っているものが多くありますが、それらを見かけたときは linuxjf.osdn.jp に読みかえてください)
特定のルールにマッチするパケットに対し、記号を付けることができます。32bitの値でビット単位に意味を持たせることができます(CONFIG_IP_ROUTE_FWMARK)。今回はこの機能を活用します。
送信先ポート番号が80, 443のパケットにマークを付ける
iptables -A PREROUTING -i br0 -t mangle -p tcp --dport 80 -j MARK --set-mark 2
iptables -A PREROUTING -i br0 -t mangle -p tcp --dport 443 -j MARK --set-mark 2
物理デバイスbr0のPREROUTINGチェイン、mangleテーブルにMARKモジュールを使って0x002(2ビット目)を立てます。送信先ポート80, 443に対してこれらを適用します。
マークとテーブル、ルーティングの定義
# mark 0x02に対しポリシールーティングテーブル3番を適用
ip rule add fwmark 2 table 3
# ポリシールーティングテーブル3番のデフォルトゲートウェイをトンネリングデバイスに設定
ip route add default dev ip6tnl1 table 3
これで80, 443ポートへのすべての通信はip6tnl経由で出ていくことになります。
例外を設定する
ただ、すべての通信がうまくはいかないことがあります。先に述べた「アドレスがBANされている」ようなケースです。
自分の場合、DHCPで特定のMACアドレスを持つハードウェアに対し固定アドレスを割り当てているので、そういった機器が利用するサービスがBANされているようなケースに、次のようなルールの追加で対処しています。
iptables -A PREROUTING -i br0 -t mangle -p tcp -s 192.168.xx.yy \
-j MARK --set-mark 0
このルールは先の--set-mark 2の後に来るように記述します。ルールは-Aオプションで追加した順序で適用されるので、すべてのソースIPアドレスが2とマーキングされたあと、指定したソースIPアドレスのパケットすべてのマーキングを0に設定しなおします。
これにより、ここで指定したIPアドレスの通信のみ、通常のルーティングに従うことになります。
雑感
なんだかんだでThe Linux Documentation Project(LDP)とその翻訳(JF)は頼りになります。JFはここ何年もアクティビティが非常に低いですが、今でも役に立つ情報はあります。ただ、リンク切れにだけ気を付けてください。