やりたいこと
- NECのIXシリーズのルーター前提
- ここで動作確認しているのは自宅の IX2105
- 他機種では動作確認していないが、おそらく類似のIXシリーズで似たアプローチがとれるはず
- MAP-EなIPoEとPPPoEの2つのアップリンクを両立
- IXシリーズルーターIPsec + L2TP VPNを構築
- 原則的にアウトバウンド通信はIPoE側を使いつつ、外からのVPN接続のときにはPPPoE側を使わせる
なぜ?
- 詳細はネット上に大量に話が転がってるので割愛するが、MAP-EなIPoEの場合、特定のポートしか自NWに貫通しない
- つまりIPsec + L2TPに必要なUDPポートの解放およびバインドがこの環境ではできない
- 任意のUDPポートを使ってIPsec + L2TPを構成し、かつクライアント側も同様に任意ポートでつなぎにいけるようなことができれば話は別だが、そんなことができる端末は世の中にほぼない
- 古典的なPPPoEなら当然フルにポートを触れるので、VPN側はそっちで運用してあげましょうというアプローチ
うまくいった方法
- ルーターとしてのデフォルトルートをPPPoE側に設定
- PBRでLAN側からの通信をIPoE側にねじ曲げる
PPPoEとIPoEの設定
ここは本題ではないのでさらりと。後述のメイン設定側ではここの設定ベースで話を進める。
- IPoE(MAP-E) :
Tunnel0.0 - PPPoE :
GigaEthernet0.1 - L2TP/IPsec終端 :
Tunnel1.0(tunnel mode l2tp-lns ipsec)
※ 別に全部のコンフィグのせてるわけではない
ppp profile pppoe
authentication myname your_username
authentication password your_username your_password
ppp profile vpn
authentication request chap
authentication password your_username your_password
lcp pfc
lcp acfc
ipcp ip-compression
ipcp provide-ip-address range 192.168.0.150 192.168.0.199
interface GigaEthernet0.1
encapsulation pppoe
auto-connect
ppp binding pppoe
ip address ipcp
ip napt enable
ip napt static GigaEthernet0.1 udp 500
ip napt static GigaEthernet0.1 udp 4500
ip napt static GigaEthernet0.1 50
no shutdown
interface Tunnel0.0
tunnel mode map-e ocn
ip address map-e
ip napt enable
no shutdown
interface Tunnel1.0
ppp binding vpn
tunnel mode l2tp-lns ipsec
ip unnumbered GigaEthernet1.0
ipsec policy transport ipsec-policy
no shutdown
デフォルトルートの変更
ここが今回のキモ。
最初「普段はIPoEで出したい」ので、IPv4のデフォルトをMAP-E側(Tunnel0.0)にしてた。
ip route default Tunnel0.0
これで何が起きるかというと、IPsec SA の “Outgoing interface” が Tunnel0.0 になってしまう
つまり、行きと帰りのルートが異なってしまい、そうなるとL2TPが制御チャネル確立手前で死ぬ。
症状はだいたいこんな:
- IKE Phase1/2 は通る(SAができる)
- L2TP は
wait-ctl-connで止まってRetransmissions exceededになる(SCCRQは見えるのにSCCRPが届かないっぽい)
この状態は show ipsec sa で一発で分かる。
show ipsec sa
ここで
Outgoing interface is Tunnel0.0
になってたら「VPN系の出し口がIPoE側に寄ってる」状態。今回ここで詰まってた。
解決策は、IPv4のデフォルトルートをPPPoE側にすること。
no ip route default Tunnel0.0
ip route default GigaEthernet0.1
これでIPsec + L2TPは常にPPPoE側でルーティングされることになりバッチリ成功するはず。
ルートマップの適用
でもデフォルトをPPPoEにすると、今度は普段のインターネット通信までPPPoEに流れてしまう。何のためにIPoEはってんねん!ってなってしまう。
そこで LANから出ていく通信だけPBRでIPoE側へ持っていく。
ポイントは「内部宛はPBR対象から外す(denyして通常ルーティングへ)」。
ip access-list pbr-to-ipoe
deny ip src any dest 192.168.0.0/16
permit ip src any dest any
route-map lan-via-ipoe permit 10
match ip address access-list pbr-to-ipoe
set interface Tunnel0.0
そしてLAN側IFにPBRを適用する。
interface GigaEthernet1.0
ip policy route-map lan-via-ipoe
この構成にすると、
- ルータ自身が処理するVPN関連(IKE/IPsec/L2TP)の外向きはPPPoE(デフォルトルート)
- LAN端末の普段の通信はIPoE(PBRで強制)
という「両立」ができる。
余談
なんで permit ip src 192.168.0.0/16 dest any だけじゃダメ?か。
一見シンプルで良さそうなんだけど、これだと LAN発の通信が全部PBR対象になってしまう。
つまり
- LAN → VPNクライアント(例:192.168.0.150)
- LAN → ルータ自身(192.168.0.254)
- LAN → 別の内部(172.24.4.0/24)
みたいな "本当はIPoEに投げちゃダメな通信" まで Tunnel0.0 に投げられてしまう。
なので内部宛は Deny で除外...という上述のACLにしておく。
(オプション) proxy-arp設定
直接的に今回の本題ではないのだが、一応気をつけましょうということで。
VPNは張れたのに、LAN内の通信が全然できない(ARPすら取れない)というのが起こり得る。
L2TPで同じL2セグメントに属する場合、 ip proxy-arp 設定をいれてルーターがARPを代理応答してくれないといけない。
そうじゃないと、たとえばスマホからVPNしたとして、本来存在する他デバイスがARPがとれずに全く通信できない状況に陥ってしまう。
VPNクライアントへ「LANと同一セグメント」のIPを振る場合、LAN側の端末はVPNクライアント宛を「同一セグメントの端末」だと思ってARPしにいく。
なので LAN側IF(例:GigaEthernet1.0) に ip proxy-arpをいれておくこと。
interface GigaEthernet1.0
ip proxy-arp
これ自体はIPoEとの両立とかそんなの関係ない話なのだがまぁ一応。
(オプション) DDNS設定
これもIPoEとの両立は関係ない話なのだが、まぁこういうことやりたくなるよねっていうことで一応。
いたって普通のPPPoE側のグローバルIPが変わる環境だと、やっぱりDDNS使いたくなる。VPNやるならなおさらね。
IXシリーズだと、簡単にやれる機能がある。
多くのDDNSサービスはHTTPのGETメソッド + クエリで更新できる機能がある。
IXシリーズは任意のURLと更新用のクエリを指定して、DDNS更新を自動化することができる。
ddns profile example.dip.jp
url https://...
query username=...&domain=...&password=...&updatehost=1
transport ip
source-interface GigaEthernet0.1
ちなみに、公式サービスの NetMeister を使うとめちゃくちゃ簡単にDDNSをやれるので、こっちのほうが良いかもしれない。
自分的には、以前から使っているDDNSをそのまま利用したかったので、こちらのコンフィグで実現している。
以前は ieserver, 今は乗り換えて Duck DNS を使っているのだが、どちらもこちらのコンフィグの使い方で問題なく運用できている。
最初に試してダメだったこと
当初はこの成功例とは逆の「ローカルPBRでIPsec関連だけPPPoEへ」を試した。
普段はIPoEを使いたいわけだから、必要なものだけPPPoEに流す...というほうが設計的にはキレイな気がするし、人間としてもイメージがしやすい。
が、自分で試した限りは、
- IKE Phase 1 は通るようになった(ログ上 Finish IKE phase 1 が出る)
- でも結局 show ipsec sa の Outgoing interface が Tunnel0.0 になったまま
- L2TPが wait-ctl-conn から進まず Retransmissions exceeded で落ちる
みたいな挙動になった。
というわけで、結局この "デフォルトPPPoE + LANだけPBR" が成功したし安定した。まぁちょっと気持ち悪い設計だなとぶっちゃけ思ってるんだけどね。
おまけ:詰まったときの確認コマンド
詳細ログを有効化して色々見る。だいたいはこれだけでほぼ何が起きているか?どう手を打つべきかは推測できる。
logging subsystem ike debug
logging subsystem l2tp debug
show logging
個別にIPsec SAの状態を見ることでもいろんなことがわかる。
たとえば、Outgoing interface がどっち向いてるかが超重要。
ここが Tunnel0.0 になってたら、まずルーティングが効いてない。
結果、パケットの行きと帰りが異なってしまいコケているはず。
show ipsec sa
例:
Outgoing interface is Tunnel0.0
同じくL2TPのStatistics系もつかえる。たとえば wait-ctl-conn で止まって retransmit が増え続けるなら、SCCRPが相手に届いてないかも。つまり上述の問題と同じくルーティングの問題の可能性が高い。
show l2tp active
例:
Tunnel is wait-ctl-conn
Retransmit count is 1 (→2→3…と増える)
参考資料
- まず大前提に公式のサンプルコンフィグが大変参考になるので、まずよく読むべし
- 以下のブログもめっちゃくちゃ参考になった, というかこの2つの偉大な先人たちの記録によってうまく構築できたと言っていい, ありがとうございました