VPN Gatewayを用いてAzureとVPN接続する

外部のクライアントとAzure内のリソースを通信させるためには、
外部クライアントがVPNもしくはExpress RouteでAzureに接続されている必要があります。
今回はAzureにVirtual Network Gatewayを構築し、WindowsクライアントがAzureとVPN接続できるように設定します。

## 目次 <!-- omit in toc -->
- [使用環境](#使用環境)
- [実装手順](#実装手順)
  1. [Virtual Network Gateway(VNG)のリソース作成](#virtual-network-gatewayvngのリソース作成)
  2. [自己ルート証明書を作成しVNGに登録](#自己ルート証明書を作成しvngに登録)
  3. [Open VPNの設定](#open-vpnの設定)


## 使用環境
- Azure 
  - Virtual Network Gateway
- Windows 11 
- Open VPN

## 実装手順

### [1. Virtual Network Gateway(VNG)のリソース作成](https://learn.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-howto-point-to-site-resource-manager-portal)
- **Azure portalで[仮想ネットワーク]->[作成]でVNetを作成**
   1. サブスクリプション、リソースグループ、VNet名、
デプロイ地域、セキュリティ、ネットワークなどを適切な値に設定

   2. [確認および作成]->[作成]でVNetインスタンスを作成
- **Azure poralで[仮想ネットワークゲートウェイ]->[作成]でVNGを作成**
   1. サブスクリプション、リソースグループ、VNG名、
デプロイ地域、SKU、作成したVNet、パブリックIPなどを適切な値に設定

   2. [確認および作成]->[作成]でVNetインスタンスを作成

### [2. 自己ルート証明書を作成しVNGに登録](https://learn.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-certificates-point-to-site)


-  管理者権限でpowershellを開いて以下のコマンドを入力し、ルート証明書を作成
    ```
      $params = @{
        Type = 'Custom'
        Subject = 'CN=P2SRootCert'
        KeySpec = 'Signature'
        KeyExportPolicy = 'Exportable'
        KeyUsage = 'CertSign'
        KeyUsageProperty = 'Sign'
        KeyLength = 2048
        HashAlgorithm = 'sha256'
        NotAfter = (Get-Date).AddMonths(24)
        CertStoreLocation = 'Cert:\CurrentUser\My'
    }
    $cert = New-SelfSignedCertificate @params
    ```

-  同じPowerShellの画面で以下のコマンドを打ちクライアント証明書作成

    ```
    $params = @{
          Type = 'Custom'
          Subject = 'CN=P2SChildCert'
          DnsName = 'P2SChildCert'
          KeySpec = 'Signature'
          KeyExportPolicy = 'Exportable'
          KeyLength = 2048
          HashAlgorithm = 'sha256'
          NotAfter = (Get-Date).AddMonths(18)
          CertStoreLocation = 'Cert:\CurrentUser\My'
          Signer = $cert
          TextExtension = @(
            '2.5.29.37={text}1.3.6.1.5.5.7.3.2')
      }
      New-SelfSignedCertificate @params
    ``` 

-  **ルート証明書のcerファイルをエクスポート([参考リンク](https://learn.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-certificates-point-to-site#cer))**
    1. Windowsの検索欄から[ユーザー証明書の管理]へ移動

    2. [個人]->[証明書]->[自身が作成したルート証明書]を選択

    3. 右クリックを押し、[すべてのタスク]->[エクスポート]をクリック

    4. 証明書に関するウィザードが出現するため[次へ]をクリック

    5. [いいえ、秘密キーをエクスポートしません]->[Base 6. encoded X.509 (.CER)]と進み、出力先とファイル名を入力後、[次へ]->[保存]で証明書をエクスポート

-  **Azureにルート証明書を登録([参考リンク](https://learn.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-howto-point-to-site-resource-manager-portal#uploadfile))**
   1. 先ほどエクスポートした証明書をメモ帳などのエディタで開く

   2. ---BEGIN CERTIFICATE---と---END CERTIFICATE---の間の内容をコピー

   3. Azure portalから[仮想ネットワークゲートウェイ]->[作成したNGW]->[ポイント対サイトの構成]に進み、ルート証明書セクションに名前と公開証明書データの場所に先ほどコピーした内容を入力し、[保存]を押下

-  **クライアント証明書をエクスポート([参考リンク](https://learn.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-certificates-point-to-site#clientexport))**
    1. Windowsの検索欄から[ユーザー証明書の管理]へ移動

    2. [個人]->[証明書]->[自身が作成したクライアント証明書]を選択

    3. 右クリックを押し、[すべてのタスク]->[エクスポート]をクリック

    4. 証明書に関するウィザードが出現するため[次へ]をクリック

    5. [はい、秘密キーをエクスポートします]を選択し[次へ]をクリック

    6. [Personal Information Exchange - PKCS #12 (.PFX)]を選択し、[証明のパスにある証明書を可能であればすべて含む]、[証明書のプライバシーを有効にする]オプションを選んだ状態で[次へ]をクリック

    7. パスワードを入力後、[次へ]をクリック

    8. 出力先とファイル名を入力後、[次へ]->[保存]で証明書をエクスポート

### [3. Open VPNの設定](https://learn.microsoft.com/ja-jp/azure/vpn-gateway/point-to-site-vpn-client-cert-windows#openvpn)

-  **OpenVPNクライアントのインストール**
     1. [公式サイト](https://openvpn.net/community-downloads/)から自身の環境にあったインストーラーをダウンロードし、インストール

-  **AzureからVPN設定情報をダウンロード**
   1. Azure portalから[仮想ネットワークゲートウェイ]->[作成したNGW]->[ポイント対サイトの構成]上で[VPNクライアントのダウンロード]を押し、ファイルをダウンロード・解凍

   2. 解凍するとOpenVPNフォルダが存在するので、その中の**vpnconfig**ファイルをメモ帳などのエディタで開いておく

   3. 先ほどエクスポートしたクライアント証明書(.pfx)から秘密キーなどの情報を取得するために以下のコマンドをpowershell上で入力し情報を出力
       ```
       openssl pkcs12 -in "filename.pfx" -nodes -out "profileinfo.txt"
       ```
   4. 先ほど出力したファイルの中の情報を**vpnconfig**ファイルに以下のように記載
       ```
        // <cert>
        // $CLIENTCERTIFICATE
        // </cert>
    
        // の$CLIENTCERTIFICATEを消去し、クライアント証明書、ルート証明書の順番で記載する。
        // クライアント証明書とルート証明書の見分け方はsubject = CN = <クライアント証明書名>が書かれているか、<ルート証明書名>かで見分ける。
        // 今回は---BEGIN CERTIFICATE---から---END CERTIFICATE---の全てをコピーする。
        // 上記のことに注意し、以下のように記載する。
    
        <cert>
        ---BEGIN CERTIFICATE---
        // クライアント証明書の内容
        ---END CERTIFICATE---
    
        ---BEGIN CERTIFICATE---
        // ルート証明書の内容
        ---END CERTIFICATE---
        </cert>
    
        // 同様にプライベートキーも記載する
        <key>
        ---BEGIN PRIVATEKEY---
        // プライベートキーの内容
        ---END PRIVATEKEY---
        </key>
       ```
    5. vpnconfig.ovpnファイルをC:\Program Files\OpenVPN\config フォルダーにコピー
    6. デスクトップ右下のシステムトレイからOpenVPNアイコン見つけ、右クリックし[接続]をクリックすることで、VPN接続が可能となる