開発

格安ルータ「EdgeRouter」でフレッツNGN網折り返し拠点間L2VPN(L2TPv3/IPSec over IPv6)を構築する

2016年10月19日
erpoe-5

Ubiquiti Networks社が販売する格安ルータ「EdgeRouter」を使ってフレッツ網折り返しのレイヤ2 VPN(L2TPv3/IPSec over IPv6)を構築する方法について解説します。

このルータにはソフトウェア上のバグが(特にIPv6とIPSecで)多数あるため、修正パッチを投稿しました。しかしUbiquiti Networks社でEdgeOS(EdgeMAX)を開発していた人が退職してしまい、開発が止まっているようです。次のファームウェアがいつリリースされるのかわかっていないため、開発コミュニティも混乱しています。僕が投稿したパッチがいつマージされるかもわからず、このまま開発が停滞すればいつまで経っても理想の方法でL2VPNを構成できません。そこで修正した内容とともに、ファームウェアを書き換えなくても(ちょっと手間だけど)バグを回避してL2VPNを構成する方法を本記事でお伝えします。

EdgeRouter について

EdgeRouterは、Ubiquiti Networksという会社が販売するルータ機器で、MIPSを搭載しており小型・低消費電力ながら高い性能を持っています。VyOS互換のEdgeOSと呼ばれるOSが搭載されています。

Vyatta/VyOSの運用経験がある方は、同じコマンドライン体系で学習コストなく触れるはずです。

購入方法

EdgeRouter Lite(ERL-3)を購入する場合、Amazon.co.jpでおよそ1万9000円前後で購入できますが、Amazon.comだと更に安く購入できます。Amazon.comの場合、Amazonが公式に発送してくれて送料・関税込みで「$89.95 + $16.02 Shipping & Import Fees Deposit to Japan」となっています。日本円にして合わせておよそ1万1000円前後です。複数台購入する際はAmazon.comがいいと思います。

もっと格安な EdgeRouter X(ER-X)ですとおよそ$49.57ほどのようです。2台買ってVPNを張っても1万円くらいということですね。

ファームウェア開発の動向

冒頭のようにフォーラムでは混乱が生じています。Ubiquiti Networks社によりますと、「退職した人の代わりに開発ができる人を探している最中で、開発や販売を終了することは考えていない」ということです。ファームウェアの更新が遅延しているということは、今後、使用しているライブラリやミドルウェアに脆弱性が発見された場合に対応があるのか不透明な点が懸念されます。現段階では業務利用などはせずに遊びたい人が使うべきルータだと思います。

注意事項

  • 本記事は、ファームウェアの改変を推奨するものではありません。
  • 今回パッチを当てている部分は、Ubiquiti Networks社のライセンスを越権する(元はVyattaがオープンソースで公開している)GPLが適用された部分です。GPLが適用されていない部分を改変するとライセンス違反になるおそれがあります。
  • Ubiquiti Networks社のファームウェアライセンスをよくお確かめください。
  • 本記事で解説する内容は、完全性を保証するものではありません。また設定や環境によって動作しなかったり、セキュリティホールとなったりすることがあるかもしれません。自己責任において本記事をご参照ください。本記事で生じた損害について何ら責任を負いません。
  • つまり、よくわからない場合には諦めてください。

事前準備

  • (当たり前ですが)EdgeRouterを2台準備するか、VyOS・RTXルータなど L2TPv3/IPSec over IPv6できる機器が必要です。
  • 「フレッツ・v6オプション」の申込みが必要です。「フレッツ光ネクスト」(「フレッツ 光ネクスト プライオ1」、「フレッツ 光ネクスト プライオ10」、「フレッツ 光ネクスト ギガファミリー・スマートタイプ」、「フレッツ 光ネクスト ギガマンション・スマートタイプ」、「フレッツ 光ネクスト ファミリー・ギガラインタイプ」、「フレッツ 光ネクスト マンション・ギガラインタイプ」を含む)では通常、契約直後から利用できるようになっており申し込み手続きは必要ありません。
  • わからない場合には契約書を確認するかNTTに電話してみましょう。

ファームウェア更新

最新版のファームウェアにアップデートしておいてください。本記事ではEdgeMAX v1.9.0を対象に作業を進めていきます。最新のファームウェアのダウンロードは https://www.ubnt.com/download/edgemax から。

EdgeRouterは初期状態では、eth0に192.168.1.1が当たっています。LANケーブルを繋いでブラウザで開いてみてください。初期パスワードは、ID・パスワードともに「ubnt」です。のちほど必ず変更しましょう。

製品を開封して電源を初めて入れた直後の状態でファームウェアをアップグレードすると失敗することがあります。その場合には一旦ルータを再起動してから試すとうまくいくと思います。

i.open.ad.jp の登録

SoftEther社が提供する「OPEN IPv6 ダイナミック DNS for フレッツ・光ネクスト」を利用すると非常にかんたんにルータに割り当てられたIPv6を名前で解決できるようになります。

好きなホスト名とメールアドレスを登録します。「初期 IPv6 アドレス」の部分は空欄のままで問題ありません。

次の画面で表示されたホストキーと専用更新ホスト名をメモします。

EdgeOSでは、CronはありますがDDNSクライアントがありません。そこで、i.open.ad.jpの独自の仕組みを頼ることにします。

控えた「専用更新ホスト名」をNTPサーバとして指定します。時刻を同期する際のパケットに反応して、レコード情報がリクエスト元のアドレスに書き換わります。

これで仮にIPv6アドレスのprefixが変動した場合でも追従しやすくなります。

初期設定

タイムゾーン

set system time-zone Asia/Tokyo

ハードウェアオフロード

set system offload ipsec enable
set system offload ipv4 forwarding enable
set system offload ipv4 pppoe enable
set system offload ipv6 forwarding enable

NTP

ここで先程のi.open.ad.jpの更新用ホスト名を設定するとDDNSされるようになる。

delete system ntp
set system ntp server ntp.nict.jp
set system ntp server update-917342d2adcf044320.i.open.ad.jp

サービス

必要に応じて判断してください。

set service dns forwarding cache-size 150
set service dns forwarding listen-on eth1
set service dns forwarding listen-on eth2
set service dns forwarding listen-on br0

set service gui http-port 80
set service gui https-port 443

set service nat

set service ssh port 22
set service ssh protocol-version v2

DHCP

set service dhcp-server disabled false
set service dhcp-server hostfile-update disable
set service dhcp-server shared-network-name LAN1 authoritative disable
set service dhcp-server shared-network-name LAN1 subnet 10.1.0.0/16 default-router 10.1.0.1
set service dhcp-server shared-network-name LAN1 subnet 10.1.0.0/16 dns-server 10.1.0.1
set service dhcp-server shared-network-name LAN1 subnet 10.1.0.0/16 lease 86400
set service dhcp-server shared-network-name LAN1 subnet 10.1.0.0/16 start 10.1.0.101 stop 10.1.0.199

ファイアウォールの設定

IPv4でルータ自体に着信するパケットフィルタルール

set firewall name WAN_LOCAL default-action drop
set firewall name WAN_LOCAL description 'WAN to router'
set firewall name WAN_LOCAL rule 10 action accept
set firewall name WAN_LOCAL rule 10 description 'Allow established/related'
set firewall name WAN_LOCAL rule 10 state established enable
set firewall name WAN_LOCAL rule 10 state related enable
set firewall name WAN_LOCAL rule 20 action drop
set firewall name WAN_LOCAL rule 20 description 'Drop invalid state'
set firewall name WAN_LOCAL rule 20 state invalid enable

IPv4でインターフェイスを通過するパケットへの透過フィルタルール

set firewall name WAN_IN default-action drop
set firewall name WAN_IN description 'WAN to internal'
set firewall name WAN_IN rule 10 action accept
set firewall name WAN_IN rule 10 description 'Allow established/related'
set firewall name WAN_IN rule 10 state established enable
set firewall name WAN_IN rule 10 state related enable
set firewall name WAN_IN rule 20 action drop
set firewall name WAN_IN rule 20 description 'Drop invalid state'
set firewall name WAN_IN rule 20 state invalid enable

IPv6でルータに着信するパケットフィルタルール

使用しないルールは適宜抜いてください。DS-Liteしない人はrule10を削除してください。IPSecを直接張る人はGREトンネルが不要なのでrule11を削除してください。反対にover GREしてeth0でIPSecを張らない人は、rule12、13、14、15を削除してください。

set firewall ipv6-name WAN_LOCAL_V6 default-action drop
set firewall ipv6-name WAN_LOCAL_V6 description 'WAN to router'
set firewall ipv6-name WAN_LOCAL_V6 rule 1 action accept
set firewall ipv6-name WAN_LOCAL_V6 rule 1 description 'ICMPv6 Enabled'
set firewall ipv6-name WAN_LOCAL_V6 rule 1 protocol icmpv6
set firewall ipv6-name WAN_LOCAL_V6 rule 3 action accept
set firewall ipv6-name WAN_LOCAL_V6 rule 3 description 'Allow established/related'
set firewall ipv6-name WAN_LOCAL_V6 rule 3 state established enable
set firewall ipv6-name WAN_LOCAL_V6 rule 3 state related enable
set firewall ipv6-name WAN_LOCAL_V6 rule 4 action drop 
set firewall ipv6-name WAN_LOCAL_V6 rule 4 description 'Drop invalid state'
set firewall ipv6-name WAN_LOCAL_V6 rule 4 state invalid enable
set firewall ipv6-name WAN_LOCAL_V6 rule 10 action accept
set firewall ipv6-name WAN_LOCAL_V6 rule 10 description 'DS-Lite Enabled'
set firewall ipv6-name WAN_LOCAL_V6 rule 10 protocol 4
set firewall ipv6-name WAN_LOCAL_V6 rule 11 action accept
set firewall ipv6-name WAN_LOCAL_V6 rule 11 description 'Allow GRE Tunnel'
set firewall ipv6-name WAN_LOCAL_V6 rule 11 protocol 47
set firewall ipv6-name WAN_LOCAL_V6 rule 12 action accept
set firewall ipv6-name WAN_LOCAL_V6 rule 12 description 'IKE'
set firewall ipv6-name WAN_LOCAL_V6 rule 12 protocol udp
set firewall ipv6-name WAN_LOCAL_V6 rule 12 destination port 500
set firewall ipv6-name WAN_LOCAL_V6 rule 13 action accept
set firewall ipv6-name WAN_LOCAL_V6 rule 13 description 'NAT-T'
set firewall ipv6-name WAN_LOCAL_V6 rule 13 protocol udp
set firewall ipv6-name WAN_LOCAL_V6 rule 13 destination port 4500
set firewall ipv6-name WAN_LOCAL_V6 rule 14 action accept
set firewall ipv6-name WAN_LOCAL_V6 rule 14 description 'ESP'
set firewall ipv6-name WAN_LOCAL_V6 rule 14 protocol esp
set firewall ipv6-name WAN_LOCAL_V6 rule 15 action accept
set firewall ipv6-name WAN_LOCAL_V6 rule 15 description 'L2TPv3'
set firewall ipv6-name WAN_LOCAL_V6 rule 15 protocol udp
set firewall ipv6-name WAN_LOCAL_V6 rule 15 source port 1701
set firewall ipv6-name WAN_LOCAL_V6 rule 15 destination port 1701

L2VPN拠点間のパケットフィルタ

拠点間VPNで接続すると同じネットワークにいるように見えますが、双方のネットワークですでにDHCPを運用してしまっている場合などには、お互いのパケットを透過的にフィルタします。

set firewall name L2FW default-action accept
set firewall name L2FW rule 10 action drop
set firewall name L2FW rule 10 description 'Drop DHCP'
set firewall name L2FW rule 10 destination port 67-68
set firewall name L2FW rule 10 protocol udp
set firewall name L2FW rule 10 source port 67-68

interfaces の設定

インターフェイスを定義していきます。

eth0(フレッツ側)

この例ではIPv4アドレスを持っていませんが、いずれ持ったときのためにIPv4用のファイアウォールも入れています。

delete interfaces ethernet eth0
set interfaces ethernet eth0 address dhcpv6
set interfaces ethernet eth0 address '2409:xx:xxxx:xxx:xxxx:xxxx:xxxx:xxxx/64'
set interfaces ethernet eth0 duplex auto
set interfaces ethernet eth0 firewall in name WAN_IN
set interfaces ethernet eth0 firewall local ipv6-name WAN_LOCAL_V6
set interfaces ethernet eth0 firewall local name WAN_LOCAL
set interfaces ethernet eth0 ipv6 address autoconf
set interfaces ethernet eth0 ipv6 disable-forwarding
set interfaces ethernet eth0 ipv6 dup-addr-detect-transmits 1
set interfaces ethernet eth0 speed auto

ブリッジ

ブリッジインターフェイスを作成します。eth1やl2tpeth0にはアドレスをアサインせず、ブリッジインターフェイスにローカルアドレスを付与します。

set interfaces bridge br0 address 10.1.0.1/16
set interfaces bridge br0 aging 300
set interfaces bridge br0 bridged-conntrack disable
set interfaces bridge br0 firewall in name L2FW
set interfaces bridge br0 hello-time 2
set interfaces bridge br0 max-age 20
set interfaces bridge br0 promiscuous disable
set interfaces bridge br0 stp false

eth1(ローカル側)

eth1 はただ br0 と接続するだけです。

set interfaces ethernet eth1 bridge-group bridge br0
set interfaces ethernet eth1 description Local
set interfaces ethernet eth1 duplex auto
set interfaces ethernet eth1 mtu 1500
set interfaces ethernet eth1 speed auto

L2TPv3インターフェイスの作成

l2tpeth0を作成し、br0とブリッジします。この例は、後述のGREトンネルを使用している場合のものです。対向側のルータでは、local-ip、remote-ip、tunnel-id、session-id、peer-session-id、peer-tunnel-idをそれぞれ入れ替えてください。

set interfaces l2tpv3 l2tpeth0 bridge-group bridge br0
set interfaces l2tpv3 l2tpeth0 encapsulation udp
set interfaces l2tpv3 l2tpeth0 local-ip 10.10.0.1
set interfaces l2tpv3 l2tpeth0 remote-ip 10.10.0.2
set interfaces l2tpv3 l2tpeth0 tunnel-id 1
set interfaces l2tpv3 l2tpeth0 session-id 1
set interfaces l2tpv3 l2tpeth0 peer-session-id 2
set interfaces l2tpv3 l2tpeth0 peer-tunnel-id 2
set interfaces l2tpv3 l2tpeth0 source-port 1701
set interfaces l2tpv3 l2tpeth0 destination-port 1701

IPSecの設定

auto-firewall-nat-excludeとipsec-interfacesを設定します。

set vpn ipsec auto-firewall-nat-exclude disable
set vpn ipsec ipsec-interfaces interface eth0

ESP

ESPを設定します。IPSecはトンネルモードとトランスポートモードがありますが、L2TPv3のインターフェイス間、つまりルータ間で終端しますのでトランスポートモードにします。

set vpn ipsec esp-group ESP1 compression disable
set vpn ipsec esp-group ESP1 lifetime 3600
set vpn ipsec esp-group ESP1 mode transport
set vpn ipsec esp-group ESP1 pfs enable
set vpn ipsec esp-group ESP1 proposal 1 encryption aes128
set vpn ipsec esp-group ESP1 proposal 1 hash sha1

IKE

set vpn ipsec ike-group IKE1 dead-peer-detection action restart
set vpn ipsec ike-group IKE1 dead-peer-detection interval 15
set vpn ipsec ike-group IKE1 dead-peer-detection timeout 90
set vpn ipsec ike-group IKE1 ikev2-reauth no
set vpn ipsec ike-group IKE1 key-exchange ikev2
set vpn ipsec ike-group IKE1 lifetime 28800
set vpn ipsec ike-group IKE1 proposal 1 dh-group 2
set vpn ipsec ike-group IKE1 proposal 1 encryption aes128
set vpn ipsec ike-group IKE1 proposal 1 hash sha1

拠点間接続の設定

いよいよ拠点間のIPSecの設定をするわけですが、落とし穴(バグ)があります。トランスポートモードの場合には、トンネルの設定はしなくていいはずですが、トンネルを設定しないと怒られます。また、トンネルにアドレスを振らない場合にはさらにバグった挙動をします。

このバグをファームウェアを改変せずに回避するには、ip6greトンネルを張ってトンネルインターフェースにIPv4アドレスを付けて、IPSecにはトンネルインターフェースについているアドレスと通信させることでごまかせるわけです。IPSec over GRE することでオーバーヘッドが生じます。

IPSec over GREによる方法(ファームウェアを改変しない方法)

バグ回避のために ip6gre トンネルを作ります。残念なことにこのトンネルはさっき作ったi.open.ad.jpドメインを指定することができないのでアドレスを直接指定します。
(side-a)

set interfaces ipv6-tunnel v6tun10 address 10.10.0.1/24
set interfaces ipv6-tunnel v6tun10 encapsulation ip6gre
set interfaces ipv6-tunnel v6tun10 local-ip '2409:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
set interfaces ipv6-tunnel v6tun10 multicast disable
set interfaces ipv6-tunnel v6tun10 remote-ip '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy'
set interfaces ipv6-tunnel v6tun10 ttl 255

(side-b)

set interfaces ipv6-tunnel v6tun10 address 10.10.0.2/24
set interfaces ipv6-tunnel v6tun10 encapsulation ip6gre
set interfaces ipv6-tunnel v6tun10 local-ip '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy'
set interfaces ipv6-tunnel v6tun10 multicast disable
set interfaces ipv6-tunnel v6tun10 remote-ip '2409:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
set interfaces ipv6-tunnel v6tun10 ttl 255

この設定で、 10.10.0.1と10.10.0.2が双方に通信できます。
side-a側からside-b側に拠点間IPSecの設定をします。SECRET1234は事前共有キーなので安全なものを設定してください。

set vpn ipsec site-to-site peer 10.10.0.2 authentication mode pre-shared-secret
set vpn ipsec site-to-site peer 10.10.0.2 authentication pre-shared-secret SECRET1234
set vpn ipsec site-to-site peer 10.10.0.2 connection-type initiate
set vpn ipsec site-to-site peer 10.10.0.2 default-esp-group ESP1
set vpn ipsec site-to-site peer 10.10.0.2 ike-group IKE1
set vpn ipsec site-to-site peer 10.10.0.2 ikev2-reauth inherit
set vpn ipsec site-to-site peer 10.10.0.2 local-address 10.10.0.1
set vpn ipsec site-to-site peer 10.10.0.2 tunnel 1 allow-nat-networks disable
set vpn ipsec site-to-site peer 10.10.0.2 tunnel 1 allow-public-networks disable

同じくside-b側からside-aにも次のように設定します。

set vpn ipsec site-to-site peer 10.10.0.1 authentication mode pre-shared-secret
set vpn ipsec site-to-site peer 10.10.0.1 authentication pre-shared-secret SECRET1234
set vpn ipsec site-to-site peer 10.10.0.1 connection-type initiate
set vpn ipsec site-to-site peer 10.10.0.1 default-esp-group ESP1
set vpn ipsec site-to-site peer 10.10.0.1 ike-group IKE1
set vpn ipsec site-to-site peer 10.10.0.1 ikev2-reauth inherit
set vpn ipsec site-to-site peer 10.10.0.1 local-address 10.10.0.2
set vpn ipsec site-to-site peer 10.10.0.1 tunnel 1 allow-nat-networks disable
set vpn ipsec site-to-site peer 10.10.0.1 tunnel 1 allow-public-networks disable

i.open.ad.jpでprefixに変動があっても自動で追従する構成

(2016年10月21日 追記)

さきほど、せっかくi.open.ad.jpに登録したので、これを使って動的にアドレスが変動するような環境でも使える構成を作ってみます。個人的には、良いとは言えないけれども、現状設定できるなかではこの設定が一番まともかなぁと思っています。

残念ながらEdgeOSのカーネルが古いため、IPv6なIPSecではVTIをバインドできません。本当はVTIが使えれば丸く収まるような気がしますが、VTIが使えないためにループバックインターフェイスにアドレスを振って、ESPをトンネルモードで(なかなか無意味に)L2TPv3を流す方法をとります。

しかしこの方法を使うにしても、ルータ起動時にIPSecのトンネルが張られる前にl2tpv3インターフェイスを作ろうとして失敗する既知のバグがあります。この既知のバグを修正するには、l2tpv3インターフェイスを作る順序(priority)を460から901にします。この値なのはVPNが900になっているためです。パッチはこちらです。

diff --git vyatta/share/vyatta-cfg/templates/interfaces/l2tpv3/node.def vyatta/share/vyatta-cfg/templates/interfaces/l2tpv3/node.def
index 0978ade..3d45675 100644
--- vyatta/share/vyatta-cfg/templates/interfaces/l2tpv3/node.def
+++ vyatta/share/vyatta-cfg/templates/interfaces/l2tpv3/node.def
@@ -1,5 +1,5 @@
 tag:
-priority: 460
+priority: 901
 type: txt
 help: L2TPv3 interface
 val_help: ; L2TPv3 interface name

パッチを適用したら、ESPをトンネルモードにします。ルータ間で終端しているのになぁという気もしますが・・・。

set vpn ipsec esp-group ESP1 mode tunnel

ループバックアドレスにトンネル用のアドレスを割り当てます。このアドレスはIPv6のULA(ユニークローカルアドレス)です。よくわからない場合にはジェネレータで作ってもいいです。あとは対向ルータのホスト名を使って設定していきます。

(side-a)

set interfaces loopback lo address 'fd1d:5f9c:b2b5::1/128'

set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' authentication mode pre-shared-secret
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' authentication pre-shared-secret SECRET1234
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' connection-type initiate
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' default-esp-group ESP1
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' ike-group IKE1
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' ikev2-reauth inherit
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' local-address 'shota-side-a.i.open.ad.jp'
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' tunnel 1 allow-nat-networks disable
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' tunnel 1 allow-public-networks disable
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' tunnel 1 local prefix 'fd1d:5f9c:b2b5::1/128'
set vpn ipsec site-to-site peer 'shota-side-b.i.open.ad.jp' tunnel 1 remote prefix 'fd1d:5f9c:b2b5::2/128'

set interfaces l2tpv3 l2tpeth0 bridge-group bridge br0
set interfaces l2tpv3 l2tpeth0 source-port 1701
set interfaces l2tpv3 l2tpeth0 destination-port 1701
set interfaces l2tpv3 l2tpeth0 encapsulation udp
set interfaces l2tpv3 l2tpeth0 local-ip 'fd1d:5f9c:b2b5::1'
set interfaces l2tpv3 l2tpeth0 remote-ip 'fd1d:5f9c:b2b5::2'
set interfaces l2tpv3 l2tpeth0 session-id 1
set interfaces l2tpv3 l2tpeth0 tunnel-id 1
set interfaces l2tpv3 l2tpeth0 peer-session-id 2
set interfaces l2tpv3 l2tpeth0 peer-tunnel-id 2

(side-b)

set interfaces loopback lo address 'fd1d:5f9c:b2b5::2/128'

set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' authentication mode pre-shared-secret
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' authentication pre-shared-secret SECRET1234
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' connection-type initiate
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' default-esp-group ESP1
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' ike-group IKE1
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' ikev2-reauth inherit
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' local-address 'shota-side-b.i.open.ad.jp'
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' tunnel 1 allow-nat-networks disable
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' tunnel 1 allow-public-networks disable
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' tunnel 1 local prefix 'fd1d:5f9c:b2b5::2/128'
set vpn ipsec site-to-site peer 'shota-side-a.i.open.ad.jp' tunnel 1 remote prefix 'fd1d:5f9c:b2b5::1/128'

set interfaces l2tpv3 l2tpeth0 bridge-group bridge br0
set interfaces l2tpv3 l2tpeth0 source-port 1701
set interfaces l2tpv3 l2tpeth0 destination-port 1701
set interfaces l2tpv3 l2tpeth0 encapsulation udp
set interfaces l2tpv3 l2tpeth0 local-ip 'fd1d:5f9c:b2b5::2'
set interfaces l2tpv3 l2tpeth0 remote-ip 'fd1d:5f9c:b2b5::1'
set interfaces l2tpv3 l2tpeth0 session-id 2
set interfaces l2tpv3 l2tpeth0 tunnel-id 2
set interfaces l2tpv3 l2tpeth0 peer-session-id 1
set interfaces l2tpv3 l2tpeth0 peer-tunnel-id 1

正しいIPSecを設定する方法(ファームウェアを改変する方法)

diffはこちらです。/opt/vyatta/sbin/vpn-config.pl:559-564のあたりの「defined $leftsubnet_proto」を「$leftsubnet_proto != 0」に修正します。

diff --git vyatta/sbin/vpn-config.pl vyatta/sbin/vpn-config.pl
index fecd074..f28e43a 100755
--- vyatta/sbin/vpn-config.pl
+++ vyatta/sbin/vpn-config.pl
@@ -552,14 +552,14 @@ if ($vcVPN->exists('ipsec')) {
             vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "tunnel", $tunnel], "$vpn_cfg_err IPv6 over IPv4 IPsec is not supported")
                 if (
                 (not $conn_is_v6)
-                && (defined $leftsubnet_proto
+                && ($leftsubnet_proto != 0
                     and $leftsubnet_proto == 6)
                 );
 
             vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "tunnel", $tunnel], "$vpn_cfg_err IPv4 over IPv6 IPsec is not supported")
                 if (
                 $conn_is_v6
-                && (defined $leftsubnet_proto
+                && ($leftsubnet_proto != 0
                     and $leftsubnet_proto != 6)
                 );

これの原因は、/opt/vyatta/sbin/vpn-config.pl:534-539の部分で次のようなコードが記述されているためです。

if (!defined($leftsubnet_proto)) {
    $leftsubnet_proto = 0;
}

このコードによってこれより先の$leftsubnet_protoは必ずdefinedがtrueな状態になります。そして、$leftsubnet_protoには0が代入されているので、この部分に引っかかり、IPv4を使っていないにもかかわらず「IPv4 over IPv6 IPSec is not supported」というエラーが返るようになってしまっています。
この修正を行えば

set vpn ipsec site-to-site peer '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy' authentication mode pre-shared-secret
set vpn ipsec site-to-site peer '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy' authentication pre-shared-secret SECRET1234
set vpn ipsec site-to-site peer '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy' connection-type initiate
set vpn ipsec site-to-site peer '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy' default-esp-group ESP1
set vpn ipsec site-to-site peer '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy' ike-group IKE1
set vpn ipsec site-to-site peer '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy' ikev2-reauth inherit
set vpn ipsec site-to-site peer '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy' local-address '2409:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
set vpn ipsec site-to-site peer '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy' tunnel 1 allow-nat-networks disable
set vpn ipsec site-to-site peer '2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy' tunnel 1 allow-public-networks disable

と、IPv6アドレスでIPSecを構成できるようになります。

この場合には、l2tpeth0インターフェイスのlocal-ipとremote-ipも変更になるので注意が必要です。

set interfaces l2tpv3 l2tpeth0 bridge-group bridge br0
set interfaces l2tpv3 l2tpeth0 encapsulation udp
set interfaces l2tpv3 l2tpeth0 local-ip 2409:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
set interfaces l2tpv3 l2tpeth0 remote-ip 2408:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy:yyyy
set interfaces l2tpv3 l2tpeth0 tunnel-id 1
set interfaces l2tpv3 l2tpeth0 session-id 1
set interfaces l2tpv3 l2tpeth0 peer-session-id 2
set interfaces l2tpv3 l2tpeth0 peer-tunnel-id 2
set interfaces l2tpv3 l2tpeth0 source-port 1701
set interfaces l2tpv3 l2tpeth0 destination-port 1701

DS-Liteを使う

(ゲームじゃない方の)DS-Liteを使うにはipip6トンネルが必要になりますが、EdgeOSはipip6トンネルをサポートしていません。このパッチも開発コミュニティに僕が投稿したもので、ipip6トンネルをサポートするためのものです。

diff --git vyatta/share/vyatta-cfg/templates/interfaces/ipv6-tunnel/node.tag/encapsulation/node.def vyatta/share/vyatta-cfg/templates/interfaces/ipv6-tunnel/node.tag/encapsulation/node.def
index 755159e..7cd83c8 100644
--- vyatta/share/vyatta-cfg/templates/interfaces/ipv6-tunnel/node.tag/encapsulation/node.def
+++ vyatta/share/vyatta-cfg/templates/interfaces/ipv6-tunnel/node.tag/encapsulation/node.def
@@ -2,11 +2,12 @@ type: txt
 help: Encapsulation of this IPv6 tunnel interface [REQUIRED]
 default: "ip6gre"
 
-syntax:expression: $VAR(@) in "ip6gre"; "Must be (ip6gre)"
-allowed: echo ip6gre
+syntax:expression: $VAR(@) in "ip6gre", "ipip6"; "Must be (ip6gre, ipip6)"
+allowed: echo ip6gre ipip6
 
 create:expression: "true"
 update:expression: "false" ; \
                "Encapsulation can only be set at tunnel creation for $VAR(../@)"
 
 val_help: ip6gre; Generic Routing Encapsulation via IPv6
+val_help: ipip6; IPv4 Encapsulation via IPv6
diff --git vyatta/share/vyatta-cfg/templates/interfaces/ipv6-tunnel/node.tag/ttl/node.def vyatta/share/vyatta-cfg/templates/interfaces/ipv6-tunnel/node.tag/ttl/node.def
index f906ffe..195aefc 100644
--- vyatta/share/vyatta-cfg/templates/interfaces/ipv6-tunnel/node.tag/ttl/node.def
+++ vyatta/share/vyatta-cfg/templates/interfaces/ipv6-tunnel/node.tag/ttl/node.def
@@ -5,4 +5,4 @@ val_help: u32:0-255; Time to live (default 255)
 
 syntax:expression: $VAR(@) >= 0 && $VAR(@) <= 255; "Must be between 0-255"
 update: sudo ip -6 tunnel change $VAR(../@) ttl $VAR(@);
-delete: sudo ip -6 tunnel change $VAR(../@) ttl inherit; 
+delete: sudo ip -6 tunnel change $VAR(../@) ttl $VAR(@);

この修正を加えると、次のようにipip6トンネルを作れます。

set interfaces ipv6-tunnel v6tun0 encapsulation ipip6
set interfaces ipv6-tunnel v6tun0 firewall in name WAN_IN
set interfaces ipv6-tunnel v6tun0 local-ip '2409:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
set interfaces ipv6-tunnel v6tun0 multicast disable
set interfaces ipv6-tunnel v6tun0 remote-ip '2404:8e00::feed:100'
set interfaces ipv6-tunnel v6tun0 ttl 255

このトンネルインターフェースを作成したら、next-hop-interfaceを設定します。

set protocols static interface-route 0.0.0.0/0 next-hop-interface v6tun0

これでDS-Liteできます。

おわりに

昨年の11月にEdgeRouterを買ってからほぼ1年。やっとパッチを投稿したり設定をまとめたりできました。やろうやろうと思いつつなかなか筆(?)が進まず。IPSecの設定にわざとトンネルモードを使うとホスト名だけで接続できるトンネルを作れそうな気がしていますがまだ試していません。内容の誤りや、より良い方法がありましたらぜひ教えてください。

Pocket

You Might Also Like