iOSデバイスからAzure上の仮想ネットワークにP2S接続する

# 背景

iPhoneやiPadから、Azure上の仮想ネットワークにP2S接続（ポイント対サイト接続）したくなったのだが、Microsoftのドキュメントは要点が掴みづらくてわかりにくいし（機械翻訳の影響か？）、Google先生に聞いてもドンピシャな回答が見つけられなかったので、その手順を記す。

# 調査

## そもそも、iOSデバイスでAzureにP2S接続できるのか？

[公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/vpn-gateway/point-to-site-about)には、

> ポイント対サイト VPN では、次のいずれかのプロトコルを使用できます。
> 
> * SSL/TLS ベースの VPN プロトコルである OpenVPN® プロトコル。 ほとんどのファイアウォールは、TLS で使用されるアウトバウンド TCP ポート 443 を開いているため、TLS VPN ソリューションはファイアウォールを通過できます。 OpenVPN は、Android、iOS (バージョン 11.0 以上)、Windows、Linux、および Mac デバイス (OSX バージョン 10.13 以上) から接続する際に使用できます。

とあるので、`iOS 11.0以降`なら`OpenVPN`が使えるのでP2S接続が可能。

## 制限は？

上記の情報から、iOSデバイスをP2S接続するにはOpenVPNを使用することがわかった。

しかし、[ゲートウェイの SKU](https://docs.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-about-vpngateways#gateway-skus)を確認すると、最も安価な`BasicではOpenVPNが使用できない`事がわかる。
ついでにいうと、Linuxを繋ぎたい場合もOpenVPN必須なので、BasicではNG。
また、Macを繋ぎたい場合はIKEv2が必要なので、BasicではNG。
つまり、BasicでつながるのはWindowsのみ。

ということで、`iOS/Mac/LinuxをP2S接続したい場合はVpnGw1以上を選択`する必要がある。

# 説明の前提とする環境

以下のクライアント環境から、仮想ネットワーク環境に対してP2S接続する前提で記載する。

|環境|アドレス範囲|
|---|---|
|仮想ネットワーク|172.16.1.0/24|
|クライアント (iOS)|10.0.0.0/24|

クライアント環境と仮想ネットワーク環境とで、使用しているアドレス範囲に重複があると接続できないので、あらかじめどちらかのアドレス範囲を変更しておく必要がある。

また、後ほど登場するゲートウェイサブネットや、仮想ネットワークゲートウェイのアドレスプールも、これらのアドレス範囲と重複することが許されないので要注意。

# 手順

## 1. 接続先の仮想ネットワークと仮想マシンをデプロイする

これについては迷うこともないと思うので、説明は割愛する。

仮想ネットワークについては、ほとんどが`既存の仮想ネットワークに接続したい`という要件だと思うので省略することになると思う。

仮想マシンは、P2S接続確立後にpingやsshなどで接続確認するときに使う。
既存の仮想マシンを流用して構わなければ省略。

## 2. 接続先の仮想ネットワークに`アドレス空間`を追加する

P2S接続を実現するには、ゲートウェイサブネットを置くためのアドレス空間が必要になる。
既存のアドレス空間に`/28`の範囲を確保できるだけの余力があれば省略可能。

例えば、

|アドレス空間|備考|
|---|---|
|172.16.1.0/24|← 既存のアドレス空間|
|172.16.2.0/24|← `追加`のアドレス空間|

## 3. `仮想ネットワークゲートウェイ`をデプロイする

1. Azure Portal上の`＋リソースの作成`をクリック
2. 検索バーに`vpn gateway`と入力
3. 候補の`仮想ネットワークゲートウェイ`を選択し、`作成`をクリック
4. 下記を参考に設定

    |設定|例|備考|
    |---|---|---|
    |名前||任意の名前を設定|
    |地域||接続先の仮想ネットワークと同じリージョンを選択|
    |ゲートウェイの種類|VPN|
    |SKU|VpnGw1|`Basic`以外を選択|
    |仮想ネットワーク||接続先の仮想ネットワークを選択|
    |ゲートウェイ サブネットのアドレス範囲|172.16.2.0/28|'/28'の範囲が確保できていれば十分|
    |パブリックIPアドレス||VPNゲートウェイに設定されるパブリックIP。<br />既存の余剰IPがなければ作る。|

5. デプロイ（待ち時間に次の手順を実施しておく）

## 4. 証明書の生成とエクスポート

公式ドキュメントの[PowerShell を使用したポイント対サイトの証明書の生成とエクスポート](https://docs.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-certificates-point-to-site)を参考に、別途別リージョンに構築しておいた Windows 10 の仮想マシン上で作業を行った。
手元に、 Windows 10 もしくは　Windows Server 2016 の環境があれば、そこで作業して構わない。
もし、Linux上で作業をする場合は[こちらの手順](https://docs.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-certificates-point-to-site-linux)らしい。（未検証）

実施すべき作業は、

1. 自己署名ルート証明書の作成
2. クライアント証明書の生成
3. ルート証明書の公開キー (.cer) のエクスポート
4. クライアント証明書 (.pfx) のエクスポート

## 5. `ユーザーVPN構成`の設定

1. Azure Portalに戻って、デプロイした仮想ネットワークゲートウェイを開く
2. 左側のメニューから`ユーザーVPN構成`をクリック
3. 下記を参考に設定

    |設定|例|備考|
    |---|---|---|
    |アドレスプール|192.168.0.0/24|他の登場人物と重複しないアドレス範囲を指定|
    |トンネルの種類|OpenVPN (SSL)||
    |認証の種類|Azure証明書|
    |ルート証明書 > 名前||任意の名前を設定|
    |ルート証明書 > 公開証明書データ||手順4−3で取得したルート証明書の公開キー文字列を貼り付け|

4. 保存

## 6. 構成ファイルのダウンロード

1. 同画面で`VPNクライアントのダウンロード`をクリック
2. Zipファイルを解凍

## 7. `vpnconfig.ovpn`の編集

1. `OpenVPN`フォルダ配下の、`vpnconfig.ovpn`をテキストエディタで開いておく
2. 手順4−4でエクスポートしておいた`pfxファイル`を使用して、WindowsかLinux上で下記のコマンドを実行する

```bash
openssl pkcs12 -in "filename.pfx" -nodes -out "profileinfo.txt"
```

3. `profileinfo.txt`を開き、クライアント証明書の`秘密鍵文字列`と`公開鍵文字列`を確認する
4. 以下のように、`秘密鍵文字列`と`公開鍵文字列`を`vpnconfig.ovpn`に上書きする

```text:vpnconfig.ovpn
　　　　：
　前半部分は省略
　　　　：

# P2S client certificate
# Please fill this field with a PEM formatted client certificate
# Alternatively, configure 'cert PATH_TO_CLIENT_CERT' to use input from a PEM certificate file.
<cert>
-----BEGIN CERTIFICATE-----
　　　　　　　　：
 クライアント証明書の公開鍵文字列
　　　　　　　　：
-----END CERTIFICATE-----
</cert>

# P2S client certificate private key
# Please fill this field with a PEM formatted private key of the client certificate.
# Alternatively, configure 'key PATH_TO_CLIENT_KEY' to use input from a PEM key file.
<key>
-----BEGIN PRIVATE KEY-----
　　　　　　　　：
　　　　　秘密鍵の文字列
　　　　　　　　：
-----END PRIVATE KEY-----
</key>

```

## 8. iOSデバイスに`OpenVPN Connect`アプリをインストールする

[OpenVPN Connect](https://apps.apple.com/jp/app/openvpn-connect/id590379981)

## 9. `vpnconfig.ovpn`をiOSデバイスにインストールする

1. 転送したファイルをiOSデバイスで開く
2. OpenVPN Connectアプリが開いて`Import Profile`画面になるので`ADD`をタップ
3. `ImportedProfile`画面になるので、再度`ADD`をタップ

## 10. P2S接続の確立

OpenVPN ConnectアプリのProfile画面で、トグルボタンを有効に倒す。
これでP2SのVPN接続が確立する。
VPN接続中は、画面上部の電波マーク付近に`VPN`アイコンが表示される。

なお、複数のVPNプロファイルがインストールされている場合で、プロファイルを切り替えたいときは、OpenVPN Connectアプリからではなく、OSの設定画面(設定＞VPN)から直接プロファイルの切り替えが必要になる場合もある。

## 10. 動作確認

接続先の仮想ネットワーク上の仮想マシンに対して、pingやssh接続をしてみる。

iPhoneやiPadには標準のターミナルアプリが無いが、[a-Shell](https://apps.apple.com/jp/app/a-shell/id1473805438)というアプリを使うとシェルを使用できるようになる。