Cisco 891FJにWindowsで使えるIKEv2 VPNを作る
前回IKEv1ベースで設定し常時接続出来なかったのでIKEv2で再チャレンジしました。最終的にWindowsでは繋がるもののMacでは繋がりませんでした。悲しみ。
事前調査
- IKEv2の認証方式はいろいろあるが、事前共有鍵は動かないっぽいので証明書ベースを使う
- Solved: Remote Access IKEv2 Auth exchange failed - Cisco Community
You cannot use PSK for authentication of a Remote Access FlexVPN
- Solved: Remote Access IKEv2 Auth exchange failed - Cisco Community
- 証明書を作る際は色々制約があり、EKUにServerAuthをつけること、SANにサーバ側FQDNを書くことが要点っぽい。strongSwanのドキュメントが分かりやすい
- サーバー証明書の有効期限があまりに長い場合は弾かれるかもしれない
- iOS 13 および macOS 10.15 における信頼済み証明書の要件 - Apple サポート (日本)
TLS サーバ証明書の有効期間は 825 日以下である (証明書の NotBefore フィールドと NotAfter フィールドで明記)。
- 最終的にMacではIKEv2動かなかったので関係ない。つらい
- iOS 13 および macOS 10.15 における信頼済み証明書の要件 - Apple サポート (日本)
- CAサーバは891FJ内蔵の機能もあるが、クライアント証明書の発行にSCEPプロトコル対応のクライアントが必要で面倒なので使わなかった
DDNS準備
- 証明書のSAN指定が必要なので何かドメインを用意する。SANにはIPアドレスを直指定できるはずだが、なんか挙動が変わるらしい
- 無ければ適当なDDNSで取ってくる
- Duck DNS を使った
- 手持ちのドメインがあればそれでも良い
証明書準備
- 証明書の生成は
LibreSSL 3.3.6
で実施した。普通にOpenSSLでも大丈夫なはず openssl x509
コマンドはCSRの中にあるExtensionsを読んでくれないのでextfileで指定する
CA証明書
- 各種証明書を作るためのルートCA証明書にはbasicConstraintsが必要
- /docs/man3.0/man5/x509v3_config.html
A CA certificate must include the basicConstraints name with the CA parameter set to TRUE.
- /docs/man3.0/man5/x509v3_config.html
- 以下の内容で ext_ca.txt を作成(コメント部分は無くてもいい)
# critical は"重要"ぐらいの意味合いで、この属性の検証が必須になるらしい # CA:true はCA証明書であることの明示 # pathlen:0 は中間CAの作成を認めない設定 basicConstraints = critical, CA:true, pathlen:0
- 以下コマンドで鍵と証明書発行
# 鍵生成 openssl genrsa -out ca.key 4096 # リクエスト生成 openssl req -new -key ca.key -out ca.csr -subj "/CN=FlexVPN-RootCA" # 自己署名でCA証明書作成。有効期限は10年 openssl x509 -req -in ca.csr -out ca.crt -days 3650 -extfile ext_ca.txt -signkey ca.key
サーバ証明書
- 上の方にあるStrongSwanドキュメントに沿う
- 以下の内容で ext_server.txt を作成(コメント部分は無くてもいい)
# EKUの指定。ServerAuthが必須 extendedKeyUsage = serverAuth # SANの指定。CNに指定してもいいらしいが、SANの方が近代的な気がするのでSANでやる # server.example.comは用意したドメインに置き換える(DDNSなどで用意したやつ) # クライアント側で「接続先」に指定する値と一致させないとハマるのでよく考える subjectAltName = DNS:server.example.com
- 以下コマンドで鍵と証明書発行
# 鍵生成 openssl genrsa -out server.key 4096 # リクエスト生成 openssl req -new -key server.key -out server.csr -subj "/CN=FlexVPN-Server" # CA鍵で証明書作成。有効期限は1年 openssl x509 -req -in server.csr -out server.crt -days 365 -extfile ext_server.txt -CA ca.crt -CAkey ca.key -set_serial 10 # インポート用にpkcs#12でまとめる。展開用パスワードは雑に123456 openssl pkcs12 -export -in server.crt -inkey server.key -out server.pfx -CAfile ca.crt -chain -password pass:123456
クライアント証明書
- EKUはclientAuthが必要らしい
- FlexVPN での Windows 7 IKEv2 Agile VPN Client による IKEv2 と証明書認証 - Cisco
クライアント証明書には、次の要素が必要です。クライアント証明書に「Client Authentication」の EKU があります。また、CA は PKCS#12 証明書を提供します。
- FlexVPN での Windows 7 IKEv2 Agile VPN Client による IKEv2 と証明書認証 - Cisco
- 以下の内容で ext_client.txt を作成(コメント部分は無くてもいい)
# EKUの指定。serverAuth, clientAuth両方入れる # 891FJ=>Clientの向きでの認証も走るため、ServerAuthを入れる # ClientAuthは多分要らないが、Ciscoのドキュメント的には必要らしいのでとりあえず入れる。あっても困らない extendedKeyUsage = serverAuth, clientAuth
- 以下コマンドで鍵と証明書発行
# 鍵生成 openssl genrsa -out client.key 4096 # リクエスト生成 openssl req -new -key client.key -out client.csr -subj "/CN=FlexVPN-Client" # CA鍵で証明書作成。有効期限は1年 openssl x509 -req -in client.csr -out client.crt -days 365 -extfile ext_client.txt -CA ca.crt -CAkey ca.key -set_serial 20 # インポート用にpkcs#12でまとめる。展開用パスワードは雑に123456 openssl pkcs12 -export -in client.crt -inkey client.key -out client.pfx -CAfile ca.crt -chain -password pass:123456
証明書転送
- 適当なUSBメモリにserver.pfxをコピーして891FJにつなぐ
- うまく認識しない場合は
format usbflash0:
で一回USBメモリを空にしてから再チャレンジ
- うまく認識しない場合は
- 以下コマンドでインポート
# 中身確認 show usbflash0: # インポートする。完了したらUSBメモリは抜いて良い crypto pki import FLEXVPN_TRUSTPOINT pkcs12 usbflash0:SERVER.PFX password 123456 # 証明書をインポートするとデフォルトで revocation-check crl が入ってしまうので切る crypto pki trustpoint FLEXVPN_TRUSTPOINT revocation-check none exit # 良い感じに読まれたか見る。ルートCA証明書も入っているはず show crypto pki certificates verbose
891FJ設定
- 各種パラメータはMacのデフォルト値を参考にする
# FlexVPNで使う認可の設定
aaa new-model
aaa authorization network FLEXVPN_AUTHZ local
# クライアントに配るIPアドレス
ip local pool FLEXVPN_POOL 192.168.30.51 192.168.30.100
# IKEv2プロポーザルの定義
crypto ikev2 proposal FLEXVPN_PROPOSAL
# Macの場合は DiffieHellmanGroup Default: 14 とある
# Windowsの標準機能で作るとDH2になるのでそれも加える。ただ確実に弱い
# (変えるにはPowerShell経由のコマンドが必要で面倒)
group 2 14
# EncryptionAlgorithm Default: AES-256
encryption aes-cbc-256
# IntegrityAlgorithm Default: SHA2-256
integrity sha256
exit
# 上で作ったプロポーザルを使うポリシー。vrfを使っていればここで紐づける
crypto ikev2 policy FLEXVPN_POLICY
proposal FLEXVPN_PROPOSAL
# どのインターフェイスでも使えるようにする(絞る場合はVRFを作ったりmatch addressにしたりする)
match fvrf any
exit
# IKEv2の認証などが通った後に、クライアントに使わせる各種パラメータを指定するポリシー
crypto ikev2 authorization policy FLEXVPN_AUTHZ_POLICY
# クライアントに使わせるIPアドレスのプール
pool FLEXVPN-POOL
# クライアントに使わせるDNSサーバ。アドブロックDNSを使ってる場合はここらへんに指定する
dns 8.8.8.8 8.8.4.4
# クライアントに使わせるデフォルトドメイン名。無くてもいい気がする
def-domain myhome.test
exit
# 証明書マップ すぐ下で使う
crypto pki certificate map FLEXVPN_CERT_MAP 10
# issuerのCNがFlexVPN-RootCAの証明書全て
issuer-name eq cn=FlexVPN-RootCA
exit
# IKEv2のプロファイル 仮想インターフェースに紐づける
crypto ikev2 profile FLEXVPN_IKEV2_PROFILE
# 証明書マップに一致する場合このプロファイルを使わせる
match certificate FLEXVPN_CERT_MAP
# ローカル側ID。とりあえず証明書のSANと合わせておく
identity local fqdn server.example.com
# クライアントから891FJへの認証。証明書ベースでやる
authentication local rsa-sig
# 891FJからクライアントへの認証。これは無効化したりanyにしたりはできない。この1行のせいでMacで繋がらないはず(多分)
authentication remote rsa-sig
# どの証明書とCAを使うか
pki trustpoint FLEXVPN_TRUSTPOINT
# 認証が通った後、なにを使わせるか
aaa authorization group cert list FLEXVPN_AUTHZ FLEXVPN_AUTHZ_POLICY
# Dead Peer Detection。クライアントの死活監視
dpd 30 10 on-demand
# 接続した後クライアントが繋がる仮想インターフェイスのテンプレート。下の方でVirtual-Templateとして定義する
virtual-template 10
exit
# IPSecで使うセキュリティプロトコルやらアルゴリズムやらを決める
crypto ipsec transform-set FLEXVPN_IPSEC_TS esp-aes 256 esp-sha-hmac
mode tunnel
exit
# IPSecのパラメータ一式を決めるプロファイル
crypto ipsec profile FLEXVPN_IPSEC_PROFILE
# すぐ上で決めたトランスフォームセット
set transform-set FLEXVPN_IPSEC_TS
exit
# 仮想インターフェイスに紐づくIPアドレスを持つだけのLoopbackインターフェイス
interface loopback 10
ip address 192.168.30.1 255.255.255.255
exit
# 仮想インターフェイス。Templateとあるように、クライアントが接続する度にVirtual-Accessインターフェイスが増えていく
interface Virtual-Template 10 type tunnel
# loopbackを作らず直接指定したら動かなかった
ip unnumbered loopback 10
# 大抵の場合は891FJでNAPTしているはずなので書く。NAPTしてなければ不要
ip nat inside
# IPv4でトンネルを張る
tunnel mode ipsec ipv4
# トンネルにIKEv2とIPSecのプロファイルを紐づける
tunnel protection ipsec profile FLEXVPN_IPSEC_PROFILE ikev2-profile FLEXVPN_IKEV2_PROFILE
exit
# 既にWAN側INにACLがかかっている場合、UDPの500と4500を開ける。4500はNAT関連なので891FJがグローバルアドレス持っていれば不要なはず
# ESPは要らないらしい(UDPでカプセル化される)
ip access-list extended v4WanIn
permit udp any host 192.168.1.10 eq isakmp non500-isakmp
exit
# CEFを切らないとセグメント間通信の戻りパケットが届かなかった。どう考えてもおかしい
no ip cef
Windows11設定
普通に証明書をインポートする
- 作成した client.pfx をダブルクリック
- インポートウィザードが起動するのでローカルコンピュータを選んで次へ
- ファイルパスは入っているはずなので次へ
- パスワードに123456を入れて次へ
- 証明書の種類に基づいて自動的に証明書ストアを選択する の方を選んで次へ
その後、普通にVPNを作成する
- 設定 -> ネットワークとインターネット -> VPN -> VPNを追加
- VPNプロバイダー: ビルトイン
- 接続名: 適当に書く
- サーバー名またはアドレス: 事前に用意したドメイン 証明書のSANと必ず合わせる
- VPNの種類: IKEv2
- サインインの種類: 証明書
- 設定 -> ネットワークとインターネット -> ネットワークの詳細設定 -> ネットワークアダプターオプションの詳細 -> 作成したVPNを選んでから「この接続の設定を変更する」 -> セキュリティタブ
- 認証: コンピューターの証明書を使う を選ぶ
- 右下ネットワークアイコンからVPN接続
Mac設定
- どう設定しても繋がらなかった。かなしい
- mac側ログは
log stream --debug --predicate 'process == "NEIKEv2Provider"'
で出る- NO_PROPOSAL_CHOSEN とか出るので何か間違えている気がする
- なにもわからない
- 891FJ側ログは
debug crypto ikev2
で出る- Callback received for the validate proposal - FAILED. とか言っているのでやっぱりプロポーザルが正しく選択されていない
- なにもわからない