自宅ルーターの内側でPPTPサーバーを動かす:まず1723とGREを直す
自宅ルーターの内側でPPTPを動かす:TCP 1723、IPプロトコル47、パススルーのチェックボックスとMTUの計算、そしてL2TPやOpenVPNのほうが得な場面。
自宅ルーターの内側ではPPTPは無関係な二つの理由で失敗し、それを混同すると一晩が無駄になる。一つは転送の抜けで、ルーターはTCP 1723を通すがIPプロトコル47を落とすので、クライアントはエラー619で止まる。もう一つはサイズの問題で、トンネルは上がり認証も通るのに、フルサイズのパケットが通る段になって固まる。どちらなのかを切り分けるのが最初の本当の一歩で、残りはどのブランドが良いかではなく、自分のルーターが何を表現できるかの比較になる。
二つのトランスポート、ポートを持つのは片方だけ
PPTPは、TCP 1723の制御接続と、拡張GREに包まれたPPPフレーム(つまりIPプロトコル47)という二つのトランスポートに分かれる。GREにはポート番号がないので、Web画面がその欄をどう名付けていても、ポート1723の転送として書かれた規則ではカバーできない。家庭用ルーターは通常、プロトコル規則の代わりにPPTPパススルーというチェックボックスを用意しており、そのチェックボックスは、プロトコル47をファイアウォール越しに通すことと、NATにGREフローの追跡方法を教えることの二つの仕事をする。Linuxルーターではこの二つは別モジュールで別規則なので、半分だけ設定したパススルーでも制御チャネルは動いてしまう。何かを変える前に、どちらの半分があるのかを確かめよう。
サーバー自身のファイアウォールも、ルーターのアドレスからのプロトコル47を許可する必要がある。1723/tcpだけを受け入れるホスト側ファイアウォールは、LANの内側からエラー619を再現するので、転送の不備とホスト規則の不備が同じに見える。
sudo iptables -S FORWARD | grep -i gre
sudo nft list ruleset | grep -i gre
lsmod | grep -E 'nf_conntrack_proto_gre|nf_nat_proto_gre'
モジュールがなければ sudo modprobe nf_conntrack_proto_gre nf_nat_proto_gre で読み込み、ヘルパーを忘れる再起動が動いていたトンネルを再びエラー619に戻すので、その読み込みを永続化する。転送規則はプロトコル47をサーバーのアドレス宛だけに許可すればよく、LAN全体ではない。RFC 2637 の定義が制御経路とデータ経路を分けているため、単一のポート転送画面ではPPTPを完全には説明できない。
パススルーのチェックボックスか、明示的なプロトコル規則か
ファイアウォールを開くだけのパススルーのチェックボックスのほうが、呼識別子を書き換えるALGより正解に近い。ファイアウォール側は予測でき、プロトコル47は通すか捨てるかのどちらかで、カウンターがどちらかを示す。書き換え側はベンダーごとに違い、PPTPの呼識別子はトンネルごとで、それを編集するNATは触れた呼び出しをすべて追跡しなければならない。一方のクライアントはつながり、もう一方はつながらないとき、まずALGを疑う。
宛先NAT規則を1723に置くことにも所有者の問題がある。古い規則が、サーバーを止めたホストへ1723を送り続けていると、パケットは閉じたポートに落ち、ルーター自身のPPTPサービスも応答しなくなる。これはファイアウォール障害のように読めるが実体は古い宛先なので、次の規則を足す前に規則とその宛先を読むこと。PPTPを自分で終端するルーターでは、WAN規則が内蔵サービスと競合するので、1723とプロトコル47の所有者を一つに決めよう。
同じNATの内側にクライアントが二台いる場合が、素朴な転送と賢い転送を分ける。呼識別子を書き換えずにプロトコル47を転送するほうが、直そうとするヘルパーよりたいてい上手くいく。
ルーターを責める前にトンネルを測る
PPTPは使えるペイロードを小さくするが、その縮小は謎ではなく算術だ。トンネルの各パケットは外側IPヘッダー、拡張GREヘッダー、PPPヘッダー、暗号化時にはMPPEヘッダーを運ぶ。経路ができあがったフレームを運べないとき、小さなパケットは通り、ログインは完了し、ファイル転送やTLSハンドシェイクがフルサイズのパケットを送った最初の時点でセッションが止まる。
推測せずに計算しよう。拡張GREは8バイト、PPPは4バイト、MPPEは4バイト、外側IPヘッダーは20バイトなので、トンネルはペイロードの前に36バイトを食べる。1492で終わるPPPoE WANでは、収まる最大のPPP MTUは1492引く36、つまり1456だ。PPPのオプションで mtu と mru をその値に設定し、断片化しないpingで再試験する。
ping -M do -s 1464 198.51.100.7
grep -E '^(mtu|mru)' /etc/ppp/options.pptpd
pingが測るのは経路であってトンネルではなく、1464バイトのペイロードに28バイトのIPとICMPヘッダーを足すと1492バイトのフレームをちょうど満たす。そのpingが通らなければ通るまで数値を下げて結果から36を引く。経路の上限を超えたトンネルMTUは、サイズに触れるログ一行も出さずに固まりを生む。
同じルーターでPPTP、L2TP/IPsec、OpenVPN
同じルーターは三つの一般的なトンネルのどれでも運べるが、違いは何を表現しなければならないかだ。PPTPは異なる二つの層に二つの規則が要る。IPsec上のL2TPは鍵交換にUDP 500と4500、NAT-Tが運ばない場合はペイロードにプロトコル50が要る。OpenVPNはUDPポート一つで足り、ヘルパーはまったく要らない。
| Tunnel | What the router must allow | Practical note |
|---|---|---|
| PPTP | TCP 1723 and IP protocol 47 | Two transports, two rules |
| L2TP/IPsec | UDP 500, UDP 4500, protocol 50 without NAT-T | ESP has no port either |
| OpenVPN | UDP 1194 or a chosen TCP port | Single rule, no helper |
L2TPの列が自動的にGREより優しいわけではなく、ESPはIPプロトコル50でこれにもポートがない。だからプロトコル47で苦労するルーターは同じ理由でプロトコル50でも苦労しうる。NAT-TはESPをUDP 4500の中に包むためにあり、両端が対応していればプロトコル50の規則は不要になる。これは端点の性質で、ルーターのPPTPチェックボックスの性質ではない。両方の規則を書く前に、クライアントが実際に交渉したカプセル化を確認しよう。
OpenVPNはルーター側で可動部分が最も少ない選択肢だ。UDPポート一つ、転送一つ、接続追跡のヘルパーなし、呼識別子の書き換えもなし。代わりに、内蔵ダイヤラではなくインストールが必要なクライアントになり、それでもPPTPが話題に残る理由はたいていこれだけだ。
直すものと入れ替えるもの
転送とMTUを直すと動くトンネルは手に入るが、持ち続けるべきトンネルではない。PPTPのMSCHAPv2認証は何年も前から攻撃可能で、動くトンネルはオフラインで復元できる資格情報を運ぶ。遠端の機器がL2TP/IPsecやOpenVPNを動かせるなら、修理は期限付きの暫定措置と捉えよう。
判断は遠端が何に対応しているかと、その取り決めをいつまで維持するかで決まる。PPTPしか話せない旧機材は修理を受け、クライアントを入れられるものは移行する。
チケットを閉じる前に、クライアントがログインだけでなく大きな転送を耐えること、再起動後もルーターがプロトコル47の規則を保つことを確かめよう。ファイルコピーを一度通って次のファームウェア更新で死ぬトンネルは、そもそも完成していなかった。