とおあすの技術雑記帳

トラブったところとか色々まとめ

CiscoルータとFortigate間でVPN IPSecトンネルを張る(IKEv2 動的IP対応)

はじめに

Cisco 891FJとFortigate 50EとのIKEv2を利用したIPSecトンネル接続(IPSec VTIを利用)を行う方法です。
IKEv2はv1に比べ、複雑さが減ったらしいですが、まだポピュラーではない方法なのか設定方法のドキュメントはあまりまとまっていないように感じます。
相変わらずパラメータの数は多いです。双方でしっかり合わせていかなければ接続できません。
色々ハマった部分もあるのでまとめておきたいと思います。
なおここではIPv4接続を前提としています。IPv6でトンネルを張るには多少設定が異なる程度で、多分できると思います。(接続側がIPv6アドレスが降ってこないので検証できません)

シナリオ

Cisco 891FJとFortigate 50Eが以下の図のようにWANを介しIPSec 仮想トンネルを確立する。
待ち受け側(Responder,Cisco)はPPPoEによりISPからグローバルIPアドレスを取得し、WANとの通信が行える状態である。(IPoEでも可)
今、設定でファイアウォールのポートを開放し、接続を待つ。
2つのルータはIKEv2、PSK方式による認証を行う。
トンネルを確立後、2つのルータ間でOSPFによりルート情報の交換を行う。
接続側(Initiator)はIPアドレス不定(Dynamic)なので、それを考慮した設定を行う。なおこの設定を行うことで、拠点間接続が増えるときにも役立つ。

前提条件

待ち受け側(Responder)はグローバルIPアドレスを持っていることが必須だが、ドメインを取得していれば固定IPである必要はない。(待ち受け側でDDNSを利用して、IPアドレスの登録を行うこと。私はmydnsを使ってます)
接続側(Initiator)はNATの内側にあってもよい(NATトラバーサル)。(ファイアウォールにより場合によってはパケットドロップが発生するかもしれない)
なお実際自分の環境では接続側はグローバルとプライベート間の境界ではありません。接続側もWANとの境界にある方が本当は望ましいのですが、私の管轄外ですのでどうにもできません。

VPN接続のための情報

2つのルータ間で絶対に合わせなければいけない設定です。適宜変更してください。

項目
接続先 example.com
NATトラバーサル 有効
IKEバージョン IKEv2
PSK hogehoge
Phase1(Proposal)暗号化(encryption) AES256(aes-cbc-256)
Phase1(Proposal)認証(integrity) SHA256
Phase1(Proposal)DH Group 14(2048bit)
ローカルID(Type:key-id) vpn-fortigate
lifetime(Phase1) 86400秒(1日)(デフォルト)
Phase2暗号化 AES256(aes-cbc-256)
Phase2認証 SHA256(sha256-hmac)
lifetime(Phase2) 43200(12時間)(デフォルト)
Cisco側のトンネルインターフェースIP Unnumbered(Loopback1:100.100.100.100/32)
Fortigate側のトンネルインターフェースIP 172.16.5.2/32
OSPFエリアID 0.0.0.2
OSPF Hello Interval 10秒
OSPF Dead Interval 40秒

PSKは実際は複雑で長めに設定しておくことを強くお勧めします。

Ciscoルータ側の設定

CiscoルータではVPN接続要求を受信したとき、設定が次の順に評価され、接続要求に応答します。(間違ってたらすみません)
この流れに合うように設定していかなければなりません。 Ciscoのドキュメントによれば、Phase1は"IKE_SA_INIT"、Phase2は"IKE_AUTH"という名前でデバッグログに現れます。そこからもその様子が見て取れると思います。
1.Policyに関連付けられたProposalを確認する。
2.Proposalで設定した暗号化方式と認証方式、DH Groupが要求に合うかどうか確認する。合致すればPhase1は完了
3.IKEv2 Profileの"match"句の設定より接続側が提供する情報(address/key-id/e-mail/FQDN)に合うProfileを探す。
4.3.で条件に合うProfileが見つかれば、設定された認証方式に従い認証を行う。
(ここからはPSK認証の場合)
5.Profile内で設定されたkeyringを参照する。
6.keyring内に設定された"match"句を確認する。合致すれば次へ。
7.PSKが合っているかどうか確認する。PSKが合致すれば、認証完了を通知する。
8.IPSec Profileの設定に従い、transform-setとikev2-profileを確認する。
9.transform-setの設定から、tunnelを張ることを決定する。
10.IKEv2 Profileに関連付けされたvirtual-templateの設定を参照する。
11.virtual-templateの設定をもとに、virtual-accessトンネルインターフェースを設定する。(Tunnelインターフェースではありません。Tunnelモードのvirtual-accessです。やってみて初めて知りました)

以下に必要なconfig例を示します。CiscoのConfig内で新たに定義されているものの名前は次の通りです。

項目
Proposal名 ikev2-proposal
Policy名 ikev2-policy
keyring名 keyring-fg
keyring内のPeer名 fortigate
トンネルの設定テンプレートInterface Virtual-Template3
IPSec transform-set名 site-to-site-tunnel
IPSec Profile名 ipsec-fortigate
Dynamic Map名 vpn-dyn-map
WANインターフェースに関連付けるCrypto Map名 vpn-crypto-map
OSPF router-id 192.0.2.1

Config例

crypto ikev2 proposal ikev2-proposal 
 encryption aes-cbc-256
 integrity sha256
 group 14
!(これがPhase1の暗号化方式の設定に当たります)
!
crypto ikev2 policy ikev2-policy 
 proposal ikev2-proposal
!Proposalを紐づける必要があるのでProposalの設定が先です
!
crypto ikev2 keyring keyring-fg
 peer vpn-fortigate
  identity key-id vpn-fortigate
  pre-shared-key local hogehoge
  pre-shared-key remote  hogehoge
!match identity の後には接続側が提供する情報
!(address/key-id/e-mail/FQDN)の種別を選びます
!
crypto ikev2 profile ikev2-profile
 match identity remote key-id vpn-fortigate
 authentication remote pre-share
 authentication local pre-share
 keyring local keyring-fg
 virtual-template 3
!match identity remoteの後には接続側が提供する情報
!(address/key-id/e-mail/FQDN)の種別を選びます
!ここで設定を"any"とすることもでき、keyringで判断させるのもありです
!virtual-templateの後は数字を入力。
!virtual-templateをもとにtunnelを確立する
!
crypto ipsec transform-set site-to-site-tunnel esp-aes 256 esp-sha256-hmac 
 mode tunnel
!(これがPhase2の暗号化方式の設定に当たります)
!
crypto ipsec profile ipsec-fortigate
 set transform-set IPSec7 
 set ikev2-profile ikev2-profile
!
crypto dynamic-map vpn-dyn-map 1
 set nat demux
 set transform-set site-to-site-tunnel
! transform-setは複数設定可能。
!set transform-set <transform-set1> <transform-set2> ...のように記述
!
crypto map vpn-crypto-map 5 ipsec-isakmp dynamic vpn-dyn-map 
!"5"はシーケンス番号。任意の数字を指定
!vpn-crypto-mapは後でWAN側インターフェースに関連付ける
!
interface Loopback1
 ip address 100.100.100.100 255.255.255.255
!
router ospf 2
 router-id 192.0.2.1
 redistribute connected subnets
!
interface Virtual-Template3 type tunnel
 ip unnumbered Loopback1
 ip ospf hello-interval 10
 ip ospf dead-interval 40
(ip ospf mtu-ignore)
 ip ospf 2 area 0.0.0.2
 tunnel source Dialer1
 tunnel mode ipsec ipv4
 tunnel destination dynamic
 tunnel protection ipsec profile ipsec-fortigate
!初めてinterface Virtual-Template3 type tunnelを実行する際には、"type tunnel"を忘れずに
!トンネルのDestinationは接続側のWAN側IPアドレスとなる。
!接続側のIPは不定であるためにdynamicにする。

interface Dialer1
 crypto map vpn-crypto-map
!
ip access-list extended rules-ipv4
 permit esp any any
 permit udp any any eq isakmp
 permit udp any any eq non500-isakmp
!isakmp=500,non500-isakmp=4500
!(10/9追記)NATトラバーサルが利用されない場合、ESPを許可する必要があります。NATトラバーサルを必要とするクライアントはudp/4500を用います。抜けてたので修正。  

Fortigate側の設定

Ciscoと呼び方が変わっている部分があります。また、設定は大体はGUIで可能ですが、一部の設定はCLIで設定する必要があります。
以下に設定後のConfigを示しますが、Configの部分以外に以下の設定が必要です。
・少なくとも1つ、VPNトンネルインターフェースが発信/着信インターフェースとなるポリシー。(定義しない場合はトンネルをつないでも通信しないので無意味と判断され行われません、デバッグログから)
ドメイン名を利用して接続する際はDNSサーバの設定。
VPNIPSecトンネルからトンネルを新規作成します。
「カスタム」を選び名前を入力します。こんな感じで設定します。

暗号化・認証方式は元々何個か入っているはずです。別に消さなくても接続できます。
ただ、実はこの設定だけでは足りない部分があります。CLIを利用し、さらに設定を行います。(以下参照)
具体的には「ローカルIDの種類」の設定です。接続の際に判別される部分になりますので注意してください。 設定が完了したら、インターフェースのIPアドレスを設定します。IPには接続側のトンネル内IPアドレスを入力します。 さらにVPNトンネルインターフェースが発信/着信インターフェースとなるポリシーを設定します。(設定しないと接続する意味がないとみなされ接続が開始されません)

Fortigate Config例

FortigateのConfig内で新たに定義されているものの名前は次の通りです。

項目
インターフェース名 site-cisco
phase1-interfaceの項目名 site-cisco
phase2-interfaceの項目名 site-cisco
OSPF router-id 192.0.2.2

恐らくGUIで設定するとすべての名前が同じになるはずです。
尚、wan1がwan側インターフェースです。 (ポリシーの部分は載せていません。)

config system interface
    edit "site-cisco"
        set vdom "root"
        set ip 172.16.5.2 255.255.255.255
        set allowaccess ping
        set type tunnel
        set remote-ip 100.100.100.100 255.255.255.255
        set interface "wan1"
   next
end
config vpn ipsec phase1-interface
    edit "site-cisco"
        set type ddns 
        set interface "wan1"
        set ike-version 2
        set peertype any
        set net-device disable
        set proposal  aes256-sha256 (複数記述可能)
        set localid "vpn-fortigate"
        set localid-type keyid (CLIのみ設定可能、GUIだけで設定するとFQDNと判断されます)
        set dhgrp 14
        set remotegw-ddns "example.com"
        set psksecret hogehoge
    next
end
config vpn ipsec phase2-interface
    edit "site-cisco"
        set phase1name "site-cisco"
        set proposal  aes256-sha256(複数記述可能)
        set dhgrp 14
        set keepalive enable
    next
end
config router ospf
    set router-id 192.0.2.2
    config area
        edit 0.0.0.2
        next
    end
    config ospf-interface
        edit "site-cisco"
            set interface "site-cisco"
            set dead-interval 40
            set hello-interval 10
            (set mtu-ignore enable)
            set network-type point-to-point
        next
    end
    config network
        edit 2
            set prefix 172.16.5.2 255.255.255.255
            set area 0.0.0.2
        next
    end
    (config redistribute "connected")
        (set status enable)
    (end)
end

他に気を付けたい部分・Note

トンネルインターフェースではサブネットは定義されません。 Cisco側でVirtual-Templateを設定する際は、ip unnumberedを利用しないとIPアドレスが上手く設定されません。(テンプレートなのでむしろIPアドレス設定がコピーされる方が困るのでしょうか)
また接続後Virtual-Accessが生成されますが、Virtual-Accessを設定するためにはVirtual-Templateをいじる必要があります。ただトンネルが確立しているとVirtual-Templateはロックされてしまうので、Virtual-Templateの設定は接続が1つもないときに行わなければなりません。
Ciscoルータ側の設定ではコマンドの省略をしがちですが、Virtual-Templateは"virtual-te"まで入力してください。viだけ入れるとvirtual-accessと認識されます。
OSPFについてはFortigateがIPアドレス形式のみ設定できるので、それに倣ってCiscoIPアドレス形式にしています(CiscoでもIPアドレス形式を使って設定可能です)。
OSPFパケットが来ているのにルートが登録されない場合は、mtu-ignoreやredistributionの設定を行えば多分うまく行くと思います。

最後に

keyringを追加するなどすれば、さらに拠点が増えても接続できるようになると思います。私はこれ以上拠点間接続を増やせるのか実験できる環境がないので、本当にできるかどうかは分からないですが参考にはなるかと。
接続できるまではdebugログとの長い戦いでした。