それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

wireguardのwg-quickにルーティング・テーブルを触らせない。Table=off

wireguard は便利なんだけどwg-quickに問題が。

wireguard は手軽でそこそこ速く、使いやすい。iOSからも使えるので、ここ一年CellularData通信は、ずっとwireguardしてる。

ほとんどの人は、wg-quick を使ってると思う。でも、私は今まで使ってない。

wg-quick は、ルーティングを書き換えすぎて困ってた。

問題点 wg-quick がルーティングを書き換えすぎる

次のように、wq-quick で wg0 を起動すると、一気に route を書き換えに来る。

takuya@ubuntu01:~$ sudo wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 172.16.3.3/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] iptables-restore -n

対応 table=offを書く。

iproute を使ってルーティングを書き変えないように、テーブル利用(書き換え)を制限します。

[Interface]
PrivateKey = XXXXXXXXXXXXXXXXX
Address =  172.16.3.3/32

Table=off # これを書く。
AllowIPs=0.0.0.0/0 

セカンドベストな対応 table=mainを書く。

table をmain テーブルと同じに書かせることで、ミスを防げます。

[Interface]
PrivateKey = XXXXXXXXXXXXXXXX
Address =  172.16.3.3/32

Table=main # これを書く。
# AllowIPs=0.0.0.0/0 # main 時はできない

テーブルにmainを指定すると、ip route と同じものが出てきます。

ただし、main を使う場合は、AllowIPs=0.0.0.0/0を指定すると、デフォルトルートが衝突して RTNETLINK answers: File exists になります。

[#] ip -4 route add 0.0.0.0/0 dev wg0 table main
RTNETLINK answers: File exists
[#] ip link delete dev wg0

これが、個人的に困っていた問題です。仕方ないので wq-quick を諦めて、wgコマンドでちまちま接続していました。

個人的に困ってた問題

2点ある。個人的に困っていた問題点がある。

  1. デフォルト・ルートを上書きされる。
  2. 知らない名前のiproute でテーブルを使われる。

それが、先程の例ではこの箇所として接続ログに出力されている。

[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820

デフォルトルートを上書きされる。

AllowedIPs に すべて(0.0.0.0/0) を指定すると、デフォルトルートが書かれる。

AllowedIPs でガッツリ許可(0.0.0.0/0)をすると

テーブル未指定で、0.0.0.0/0を許可する

[Interface]
## 略
[Peer]
## 略
AllowedIPs =  0.0.0.0/0

この状態で接続する

[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820

このように、デフォルト・ルートを書き換えられてしまう。

そして、そのルーティングはルーティングテーブル表示 ip route show には出てこない。wg-quick がtable名を指定してルーティングを入れるためである。

さらなる問題点:table名

wg-quick はiproute のテーブル指定を使っている。テーブルにはポート番号が使われる。

[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820

テーブルを使うのを知っていたらいいのだけれど。知らないとルートが見つからず泥沼にはまり込むことになる。

普段からテーブル指定を省略してると「うっかり見逃す」事が多い

テーブル指定なしでルート一覧

$ sudo ip route list table all
default via 192.168.1.1 dev br0 metric 99
192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.240

テーブル指定してルートを一覧

テーブル名がポート番号と知ってないと色々とめんどくさい。

$ sudo ip route list table 51820
default dev wg0 scope link

ルーティングテーブルの全テーブルを表示

sudo ip -4 route list table all

実際にやってみると、様々なテーブルがあることがわかる。

$ sudo ip -4 route list table all
default dev wg0 table 51820 scope link
default via 192.168.1.1 dev br0 metric 99
192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.240
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
local 172.16.3.3 dev wg0 table local proto kernel scope host src 172.16.3.3
broadcast 192.168.1.0 dev br0 table local proto kernel scope link src 192.168.1.240
local 192.168.1.240 dev br0 table local proto kernel scope host src 192.168.1.240
local 192.168.1.244 dev br0 table local proto kernel scope host src 192.168.1.240
broadcast 192.168.1.255 dev br0 table local proto kernel scope link src 192.168.1.240

テーブル(main/local/default/all) の指定を知らないと、ただただ、wq-quick は謎のルーティングを書いているようにしか見えない。

そして、それはip route show だけを普段使ってると、ミスを誘発する。

table=main の場合

先述したとおり、ルーティングはip route で表示される。table=main だからip route で表示が可能

しかし、mainのデフォルトルートが衝突して接続できないとなり、エラーに。

個人的には、メトリック入れてほしい。と思っていたのですが、できないようです。

wg-quick は怖い

以上のことから、wq-quick を使う前に、ip route と iproute table を知っておく必要があると思います。

ちゃんと知っておかないと、ルーティングが意図通りにならなくて困ると思います。

仮に、知っていても、ip route(main) の方をよく使うため、意図しないとチェックが漏れます。

無意識なチェック漏れが発生するので、とても怖いと思うのです。

AllowIPsやPre/Post を工夫する前にテーブルの確認

Pre/Post Up/Down でルーティングをしたりフォワードを書き換える前に、一度 ip route show table all で 「ルーティング・テーブル」の「テーブル」確認したほうがいいと思うのです。ルーティング・テーブルにはテーブル名という「名前空間」らしきものがあるのです。

そして、テーブルが本当に必要ない(試験的につなぐだけ)のようなときと、PCを全転送するするとき、AllowIPsでガッツリ指定するけどiptablesでFORWARDはまだ書いてないとき、など状況で使い分ける必要があるのでした。

懲りずに同じミスで2回もハマったのです。

約1年前にも同じ現象でルーティングを見失ってハマったのです。そして記事に書いたのに、忘れて同じミスをして、1年前と同じスタックをしたのです。

wq-qucik 怖いよ。

参考URL