シスコルータでSIPでVPNを張ってみた

# ⭐️ はじめに
元音声・ビデオ系の SIP エンジニアがシスコルータを使って、SIP で IPSec-VPN を張ってみました。
きっかけは、先日リリースされた IOS 15.7(3)M1 で SIP Triggered VPN 機能をサポートしたと聞いたので、元 SIP 系エンジニアとして、動作に興味があり動作確認したいと思ったことでした。
(今回の動作確認では主にSIPの動作を中心に確認しています。)  

本機能や設定の詳細は、[SIP Triggered VPN の Configuration Guide](https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/sec_conn_vpnips/configuration/15-mt/sec-sec-for-vpns-w-ipsec-15-mt-book/sec-vpn-sip.html#reference_rdd_tkc_z) を参照してみて下さい。
（あくまで今回は、"やってみた" 系になっています。）

本機能により、シスコルータ単体でNTT東西が提供するひかり電話のデータコネクトのサービスを利用することが可能になりました。
NTT東西のデータコネクトの詳細は👇を参照して下さい。
[データコネクトサービス：NTT東日本](https://flets.com/hikaridenwa/office/service/dataconnect.html) 
[データコネクトサービス：NTT西日本](https://flets-w.com/hikaridenwa/service/dataconnect/)

実際に本機能を利用する場合は、サポートする機種やシステム要件をしっかり確認して頂き、
最新の情報に基づいて利用頂きますようお願いします。

ちなみに、今回のお試しでは諸事情により実網サービスではなく、株式会社 neix の [NGNシミュレータ II] (http://www.neix.co.jp/product/ngn_sim2/index.html) を使用しています。
（ちなみに本シミュレータでは、データコネクトはオプションで本体とは別売りです。）

# ・VPN-SIP 通信の仕組みの概要  
ご存知の通り、SIP は Session Initiation Protocol （セッション開始プロトコル）でセッションを確立するためのプロトコルで RFC3261で定義されています。
SIPエンドポイントは、このSIPで確立されたセッションを使って通信をします。
実際に使われるメディア情報は、 Session Description Protocol (セッション記述プロトコル/RFC4566）を使ってお互いの能力交換をして決定されます。 
このSIP Triggered VPN 機能では、SDPのメディア情報の m 行 (Media Descriptions)に "application" を使っています。 
" m = application を使って Transport として "udp" を利用して Media Format として "ike-esp-udpencap" を使用しています。こちらは RFC6193 (Media Description for the Internet Key Exchange Protocol (IKE) in the Session Description Protocol (SDP))で定義されています。
この SIP/SDP を使って確立したセッションを利用して IKEv2, IPSec のネゴシエーションをして IP-Secトンネルを確立しています。

・SDP OFFER 例

```
<一部省略>
m=application 50004 udp ike-esp-udpencap
b=AS:1000
a=ike-setup:active
a=psk-fingerprint:SHA-1 7A:F7:8C:91:1D:5B:48:BE:A1:DC:24:49:D9:D8:95:13:AB:EB:4B:E5
・・・
```

・SDP ANSWER 例  

```
<一部省略>
m=application 13014 udp ike-esp-udpencap
b=AS:1000
a=ike-setup:passive
a=psk-fingerprint:SHA-1 7A:F7:8C:91:1D:5B:48:BE:A1:DC:24:49:D9:D8:95:13:AB:EB:4B:E5
・・・
```

ちなみに音声、ビデオでは、m=audio, m=video がそれぞれ使われています。 
また余談ではありますが、10年以上前は、"m = application" は "m = data" と言っていたのは懐かしい話です。

# ・VPN-SIP の通信方法・手順
## 1. DHCP で IP アドレスや SIP サーバアドレスの取得
- SIP 端末が DHCP で IP アドレスや SIP サーバアドレス、ドメイン名、電話番号等の情報を取得。  
- オプション例  

  - Option 120 : SIP Server Address.
  - Option 125 : Vendor-specific-information  
     - sub-option(201,202,203,204 : MACアドレス、契約番号、追加番号、ドメイン名）     
<img width="618" alt="DHCP.png" src="https://qiita-image-store.s3.amazonaws.com/0/199936/a42d79db-2b46-078b-a726-026577594089.png">  

## 2. エンドポイントの登録
- SIP 端末は、DHCP で取得してきた情報を元に網へ SIP 登録(SIP Register) を行う。

<img width="1142" alt="Register-flow.png" src="https://qiita-image-store.s3.amazonaws.com/0/199936/7f266af2-a7db-090e-d210-abaf05cb8a5e.png">

SIP 登録が完了すれば、網内で電話番号(0ABJ番号）を使っての通信が可能な状態になります。

## 3. SIP で確立したセッションを使った IPSec 通信
- トンネル先への通信が発生した際に SIP 端末は、SIP でセッションを開始をして、そのセッション確立後に確立されたセッションを使って IPSec トンネルを構築します。  
下図のフローでは、192.168.1.1のPC(EP1側)から 192.168.2.1のPC(EP2側)へ通信を開始した場合になっています。

<img width="847" alt="Call-flow.png" src="https://qiita-image-store.s3.amazonaws.com/0/199936/16d019ad-1cae-2b92-5216-7a50da8d0160.png">

# ⭐️ シスコルータでの基本的な設定
VPN-SIP 機能を使うには以下の設定をします。
## ・インタフェース設定 その1 (WAN 及び、ループバック・インターフェイス)
##### ・WAN 側インターフェイス設定 (DHCP 利用)  
WAN 側のインターフェイス（本例では GE0/4 ) で DHCP を有効にして、option 120,125 も使えるように設定します。 

```
interface GigabitEthernet0/4
ip dhcp client request sip-server-address
ip dhcp client request vendor-identifying-specific
ip address dhcp
ip nat outside
ip virtual-reassembly in
duplex auto
speed auto
```

##### ・ループバック・インターフェイス設定  
VPN-SIPでトンネル・インターフェイス用にループバック・インターフェイスを作成。

```
interface Loopback1
ip address 10.255.255.1 255.255.255.0
ip nat inside
ip virtual-reassembly in
```

## ・VPN SIP グローバル設定
VPN-SIP機能を有効にします。 local-number (自分の電話番号)の設定や利用する WAN 側インターフェイスやトンネルソースに使う loopback インターフェイスの設定を行います。

```  
vpn-sip enable
vpn-sip local-number 0388881001 address ipv4 GigabitEthernet0/4
vpn-sip logging
vpn-sip tunnel source Loopback1
```
## ・自己証明書設定
自己証明書を設定します。  

```
crypto pki trustpoint self
enrollment selfsigned
serial-number
revocation-check none
rsakeypair peer
```

## ・IPSec 設定
```
crypto ikev2 keyring keys
peer p1
  identity key-id 0388882001
  pre-shared-key cisco
!
crypto ikev2 profile IPROF
match identity remote any
identity local key-id 0388881001
authentication remote pre-share
authentication local pre-share
keyring local keys
pki trustpoint self
nat force-encap
!
crypto ipsec profile IPROF
set security-association idle-time 300
```
***crypto ipsec profile*** の idle-time の設定でトンネルを切断をするタイミングを設定。
こちらの例では 300秒（5分) IPSecトンネルの通信がないとSIP的にもBYEが送信されて 
SIPセッションも切断されます。

## ・インタフェース設定 その2 (トンネル・インターフェイス）
#### ・トンネル・インターフェイスの設定
VPN-SIPで使うトンネル・インターフェイスで IPSec 設定や VPN-SIP 周りの設定します。
 
```  
interface Tunnel0    
ip address 11.11.11.11 255.255.255.255
tunnel source Loopback1
tunnel mode ipsec ipv4
tunnel destination dynamic
tunnel protection ipsec profile IPROF ikev2-profile IPROF
vpn-sip local-number 0388881001 remote-number 0388882001 bandwidth 1000                      
```  
***vpn-sip*** コマンドで自身の電話番号や対向の電話番号、利用する帯域幅を設定します。  

## ・ルーティング設定（スタティック・ルート設定)
VPN の先のネットワークへのスタティック・ルートを設定します。 
 
```
ip route 192.168.2.0 255.255.255.0 Tunnel0
```

# 🌟 動作確認
## 動作確認構成図
<img width="796" alt="evaluation.png" src="https://qiita-image-store.s3.amazonaws.com/0/199936/e9ef2f59-e669-ee91-ddbd-bf9155bd18ea.png">

* SIP-EP1, SIP-EP2 : IOS 15.7(3)M1

## ✅ WAN 側インターフェイスの情報の確認
#### ・DHCP より割り振られたIPアドレスの確認 (GigabitEthernet0/4 を WAN 側で使用)
```  
SIP-EP1#show ip interface brief gigabitEthernet 0/4
Interface                  IP-Address      OK? Method Status                Protocol
GigabitEthernet0/4         111.80.101.2    YES DHCP   up                    up   
```  
IP アドレスとして、111.80.101.2 が割り振られている事が確認出来ます。  
#### ・ DHCP で割り振られた SIP 関連の情報の確認  
```  
SIP-EP1#show vpn-sip sip dhcp
SIP DHCP Info
SIP-DHCP interface:  GigabitEthernet0/4
SIP server address:  ipv4:111.80.200.2
Domain name:         dns:ntt-east.ne.jp
``` 
SIP サーバのアドレスとして 111.80.200.2、Domain-name として ntt-east.ne.jp が割り振られたのが確認出来ます。

## ✅ SIP 登録(Registration)の状況確認
```  
SIP-EP1#show vpn-sip registration-status 
 SIP registration of local number 0388881001 : registered 111.80.101.2
```
***0388881001*** という電話番号(契約番号) で SIP サーバ ***111.80.101.2*** に SIP 登録出来ているのが確認出来ます。  

```  
SIP-EP1#show vpn-sip sip registrar 
Line          destination      expires(sec)  contact
transport     call-id
============================================================
0388881001    ntt-east.ne.jp   1716          111.80.101.2
UDP           FBCAEE0A-DFD111E7-8007B324-6EBE00F2@111.80.101.2    
```  
SIP の登録情報の詳細が確認出来ます。　（ 次の登録までの時間 *expires(sec)* など）

## ✅ ping で通信確認
まずは、VPN-SIP のセッション情報を確認。  

```
SIP-EP1#show vpn-sip session detail 
VPN-SIP session current status

Interface: Tunnel0
   Session status: READY_TO_CONNECT  
   Remote number : 0388882001
   Local number  : 0388881001
   Remote address:port: 0.0.0.0:0
   Local address:port : 111.80.101.2:0
   Crypto conn handle: 0x8000000C
   SIP Handle        : 0x0
   SIP callID        : --
   Configured/Negotiated bandwidth: 1000/0 kbps
```
まだ、"Session Status"* が *"READY_TO_CONNECT"* になっていて、まだ VPN-SIP のセッションが張られていません。

ここで 対向のルータの　LAN側　インターフェイス(VLAN10:192.168.2.1) に ping をします。　　

```
SIP-EP1#ping 192.168.2.1 source 192.168.1.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.2.1, timeout is 2 seconds:
Packet sent with a source address of 192.168.1.1
 
*Dec 15 00:34:35.894: %LINEPROTO-5-UPDOWN: Line protocol on Interface Tunnel0, changed state to down
*Dec 15 00:34:35.894: %LINEPROTO-5-UPDOWN: Line protocol on Interface Tunnel0, changed state to up.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 1/2/4 ms
```
すると、192.168.2.0/24 は、Tunnel Interface0 の先にあるので、Tunnel Interface0 を立ち上げて、SIP で　VPN セッションを張りにいきます。  対向への ping も成功しています。  

ここで再び、VPN-SIP のセッション情報を確認。  

```
SIP-EP1#show vpn-sip session detail 
VPN-SIP session current status

Interface: Tunnel0
   Session status: SESSION_UP (I) 
   Uptime        : 00:00:14
   Remote number : 0388882001
   Local number  : 0388881001
   Remote address:port: 111.80.200.2:13014
   Local address:port : 111.80.101.2:50004
   Crypto conn handle: 0x8000000D
   SIP Handle        : 0x80000005
   SIP callID        : 40
   Configured/Negotiated bandwidth: 1000/1000 kbps  
``` 
"Session Status"* が *"SESSION_UP (I)"* になって VPN-SIP セッションがアップしたのが確認出来ます。
これで無事に SIP で　IPSec-VPN を張って通信出来ていることが出来ました。

## ⭐️さいごに
最後まで読んで頂いて有難うございました。　
今回はプログラミングとは直接は関係がなかったですが、通信の仕組みをより理解すれば、更にプログラミングで出来る幅も広がるかなと思ってます。
今後はSIP系の通信ネタとプログラミングの組み合わせのネタもいろいろと試してみようと思います。