AzureのPoint-to-Site VPNでLinuxクライアントをVNetへ接続する方法|証明書認証とazコマンドによるVPN Gateway構築の実践

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Azure > AzureのPoint-to-Site VPNでLinuxクライアントをVNetへ接続する方法|証明書認証とazコマンドによるVPN Gateway構築の実践
AzureのプライベートVNet内のLinux VMへ、自分のPCからSSHしたい——そう思ったとき、パブリックIPを付けるのはセキュリティ上好ましくありません。かといってAzure Bastionを使うと月額固定費がかさみます。

Point-to-Site(P2S)VPNを使えば、LinuxクライアントがAzure VNetへ証明書認証で安全に接続でき、プライベートIPのままVMへSSHできます。開発や検証機からプライベートサブネット内のリソースへ直接アクセスしたい場面に最適です。

この記事では、azコマンドを使ってPoint-to-Site VPNをゼロから構築し、UbuntuクライアントからAzure VNetへ接続するまでの全手順を解説します。VPN Gateway作成・証明書生成・OpenVPN設定・接続確認まで一気通貫で進めます。

この記事のポイント

・ P2S VPNでLinux VMへパブリックIP不要でプライベート接続できる
・ GatewaySubnetとVPN Gatewayの作成にはazコマンドを使う(所要30~45分)
・ opensslで自己署名ルート証明書を生成しAzureへアップロードする
・ AWS Client VPNとの主な違いはコスト体系と同時接続数の上限にある


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Point-to-Site VPNとは|サイト間VPN・BastionとAWS Client VPNとの違い

Point-to-Site(P2S)VPNとは、個々のPC(クライアント)からAzure VNetへ直接VPN接続する仕組みです。Azure VPN GatewayのP2S機能として提供されており、同じゲートウェイでサイト間VPN(Site-to-Site)と共存させることもできます。

同じ用途で使われる他の接続方式との違いをまとめます。

接続方式 用途 月額コスト目安 主な制約
Point-to-Site VPN(本記事) 個人PCからVNetへ直接接続 VpnGw1約¥15,000(接続数に関わらず定額) P2S同時接続250まで(VpnGw1)
Azure Bastion(Basic) ブラウザからVMへSSH/RDP 約¥1,800 ポータル経由のため自動化が難しい
Site-to-Site VPN オンプレ拠点とVNetをIPsecで接続 VpnGw1約¥15,000+接続費 VPN機器または仮想NVAが必要
AWSにはAWS Client VPNという対応サービスがあります。OpenVPNプロトコルを使う点は同じですが、コスト体系が異なります。AWS Client VPNはVPNエンドポイント(約$0.10/時)+アクティブな接続1本ごと($0.05/時)の課金です。常時接続している人数が多いほど費用が膨らみます。Azure P2S VPNはVPN Gatewayの時間課金のみで、接続数が変わっても費用は変わりません。小規模チームが常時接続するならAzureの定額制が有利になりやすいです。

認証方式はAzureが「証明書認証」「Azure AD(Entra ID)認証」「RADIUS認証」の3種類に対応しており、AWSも「証明書認証」「Active Directory認証」を選べます。この記事では、ADアカウント不要で手軽に始められる証明書認証を使います。

全体構成と実行環境

この記事で構築する環境のネットワーク図を示します。

[Ubuntu 24.04 LTS(PC・クライアント側)] ↓ OpenVPN(P2S VPN、クライアントIP: 172.16.201.0/24から割当) [Azure VPN Gateway(VpnGw1)] ↓ [Azure VNet: 10.0.0.0/16] ├── GatewaySubnet: 10.0.255.0/27 ← VPN Gatewayが占有 ├── subnet-default: 10.0.1.0/24 │ └── Linux VM(10.0.1.4)← P2S VPN経由でSSHしたいVM └── subnet-backend: 10.0.2.0/24 ← 後続のDBや内部サービス用

実行環境(この記事で確認済み)
クライアントOS:Ubuntu 24.04 LTS(Azure CLIとopenvpnをインストール済み)
Azure CLI:2.61.0(az --versionで確認)
VPN Gateway SKU:VpnGw1 Generation1(P2S同時接続最大250)
VPNプロトコル:OpenVPN
認証方式:証明書認証(openssl生成の自己署名ルート証明書)

VPN Gatewayの作成には30~45分かかります。次のステップで証明書を先に用意しておき、待ち時間を有効活用しましょう。

リソースグループ・VNet・サブネットをazコマンドで作成する

まずリソースグループと仮想ネットワーク(VNet)を準備します。GatewaySubnetはVPN Gatewayが専用で使うサブネットで、名前は必ず「GatewaySubnet」でなければなりません(大文字・小文字も含めて完全一致)。

1. ログインとサブスクリプションの確認

# Azure CLIでインタラクティブログイン az login # 使用するサブスクリプションを確認する az account show --query "{Name:name, ID:id}" --output table # 出力例 # Name ID # ------------------- ------------------------------------ # My Azure Sub aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa

2. リソースグループを作成する

# リソースグループを東日本リージョンに作成する az group create --name rg-p2s-vpn --location japaneast # 出力例(provisioningState: Succeeded で完了) # { # "id": "/subscriptions/.../resourceGroups/rg-p2s-vpn", # "location": "japaneast", # "name": "rg-p2s-vpn", # "properties": { "provisioningState": "Succeeded" } # }

3. VNetとサブネットを作成する

# VNetを作成する(デフォルトサブネットを同時作成) az network vnet create --resource-group rg-p2s-vpn --name vnet-p2s --address-prefix 10.0.0.0/16 --subnet-name subnet-default --subnet-prefix 10.0.1.0/24 # バックエンド用サブネットを追加する az network vnet subnet create --resource-group rg-p2s-vpn --vnet-name vnet-p2s --name subnet-backend --address-prefix 10.0.2.0/24 # GatewaySubnetを作成する(名前は必ず "GatewaySubnet"・推奨は /27) az network vnet subnet create --resource-group rg-p2s-vpn --vnet-name vnet-p2s --name GatewaySubnet --address-prefix 10.0.255.0/27 # サブネット一覧を確認する az network vnet subnet list --resource-group rg-p2s-vpn --vnet-name vnet-p2s --query "[].{Name:name, Prefix:addressPrefix}" --output table # 出力例 # Name Prefix # --------------- --------------- # subnet-default 10.0.1.0/24 # subnet-backend 10.0.2.0/24 # GatewaySubnet 10.0.255.0/27

GatewaySubnetのCIDRプレフィックスは/27(32アドレス)を推奨します。/28(16アドレス)でも動作しますが、VPN Gatewayは複数のIPを確保するため、/29以下の小さいサブネットは使わないでください。

VPN Gatewayを作成する(VpnGw1)

VPN Gatewayの作成はこの手順の中で最も時間がかかるステップです。--no-waitオプションを付けてバックグラウンドで実行し、完了を待つ間に証明書の準備を進めます。

1. VPN Gateway用パブリックIPを作成する

# Standard SKUの静的パブリックIPを作成する az network public-ip create --resource-group rg-p2s-vpn --name pip-vpngw --allocation-method Static --sku Standard --zone 1 2 3

2. VPN Gatewayを作成する(バックグラウンドで実行)

# VPN Gatewayを作成する(30~45分かかる・--no-waitで即座に制御を返す) az network vnet-gateway create --resource-group rg-p2s-vpn --name vpngw-p2s --vnet vnet-p2s --gateway-type Vpn --vpn-type RouteBased --sku VpnGw1 --generation Generation1 --public-ip-address pip-vpngw --no-wait # 完了確認(Succeeded になるまで繰り返す) az network vnet-gateway show --resource-group rg-p2s-vpn --name vpngw-p2s --query "provisioningState" --output tsv # 完了前: Updating # 完了後: Succeeded

VPN GatewayはBasic SKUではPoint-to-Site VPNのOpenVPNプロトコルをサポートしていません。必ずVpnGw1以上を選んでください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Azure対応セミナーの詳細を見る >>

ルート証明書と個人証明書をopensslで生成する

P2S VPNの証明書認証では次の2種類が必要です。

ルート証明書(CA証明書):Azureにアップロードして「信頼できる発行元」として登録する
クライアント証明書:ルート証明書で署名した個人用証明書。VPN接続時に提示する

opensslコマンドがインストールされていれば追加パッケージは不要です(Ubuntu 24.04 LTSには標準で入っています)。

1. ルートCA証明書を生成する

# 作業ディレクトリを作成する mkdir ~/azure-p2s-certs && cd ~/azure-p2s-certs # ルートCA秘密鍵を生成する(4096ビット RSA) openssl genrsa -out ca.key 4096 # ルートCA自己署名証明書を生成する(有効期間10年) openssl req -new -x509 -key ca.key -out ca.crt -days 3650 -subj "/CN=AzureP2SRootCert/O=MyOrg/C=JP" # 証明書の内容を確認する openssl x509 -in ca.crt -noout -subject -dates # 出力例 # subject=CN=AzureP2SRootCert, O=MyOrg, C=JP # notBefore=Aug 23 00:00:00 2026 GMT # notAfter=Aug 22 00:00:00 2036 GMT

2. クライアント証明書を生成する

# クライアント秘密鍵を生成する openssl genrsa -out client.key 4096 # クライアント証明書署名要求(CSR)を作成する openssl req -new -key client.key -out client.csr -subj "/CN=AzureP2SClientCert/O=MyOrg/C=JP" # ルートCAでクライアント証明書に署名する openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 3650 # 発行者(issuer)を確認する(CAと一致していること) openssl x509 -in client.crt -noout -subject -issuer # 出力例 # subject=CN=AzureP2SClientCert, O=MyOrg, C=JP # issuer=CN=AzureP2SRootCert, O=MyOrg, C=JP

複数のエンジニアが同じVPNを使う場合は、同一のCAで人数分のクライアント証明書(client2.crt、client3.crtなど)を発行します。失効させる場合はCRL(証明書失効リスト)をVPN Gatewayにアップロードします。

ルート証明書をVPN Gatewayにアップロードする

AzureへアップロードするルートCA証明書はDER形式をBase64エンコードした文字列が必要です。PEM形式のままでは受け付けません。

1. ルート証明書をBase64変換してアップロードする

# PEMをDER形式に変換してBase64エンコードする(改行なし1行に連結) ROOT_CERT_DATA=$(openssl x509 -in ca.crt -outform DER | base64 | tr -d ' ') # VPN GatewayにルートCA証明書を登録する az network vnet-gateway root-cert create --resource-group rg-p2s-vpn --gateway-name vpngw-p2s --name AzureP2SRootCert --public-cert-data "$ROOT_CERT_DATA" # 登録されたルート証明書を確認する az network vnet-gateway show --resource-group rg-p2s-vpn --name vpngw-p2s --query "vpnClientConfiguration.vpnClientRootCertificates[].name" --output tsv # 出力例 # AzureP2SRootCert

2. P2Sクライアントアドレスプールを設定する

VPNクライアントが接続時に払い出されるIPアドレス範囲を設定します。VNetのアドレス空間(10.0.0.0/16)と重複しないプライベートアドレスを指定してください。

# P2S設定をVPN Gatewayに追加する az network vnet-gateway update --resource-group rg-p2s-vpn --name vpngw-p2s --address-prefixes 172.16.201.0/24 --vpn-auth-types Certificate --vpn-client-protocols OpenVPN # 設定を確認する az network vnet-gateway show --resource-group rg-p2s-vpn --name vpngw-p2s --query "vpnClientConfiguration.{Pool:vpnClientAddressPool, Protocol:vpnClientProtocols}" --output json # 出力例 # { # "Pool": { "addressPrefixes": ["172.16.201.0/24"] }, # "Protocol": ["OpenVPN"] # }

OpenVPNプロファイルをダウンロードしてLinuxクライアントに設定する

VPN Gatewayのプロビジョニングが完了し、証明書とP2S設定が入ったら、OpenVPN用のクライアント設定ファイルを生成します。

1. VPNクライアント設定パッケージを取得する

# VPNクライアント設定ZIPのダウンロードURLを生成する DOWNLOAD_URL=$(az network vnet-gateway vpn-client generate --resource-group rg-p2s-vpn --name vpngw-p2s --authentication-method EAPTLS --output tsv) # URLを確認してZIPをダウンロードする(URLの有効期限が短いため即座に実行) echo "$DOWNLOAD_URL" wget -O vpnclientconfig.zip "$DOWNLOAD_URL" unzip vpnclientconfig.zip -d vpnconfig/ # OpenVPNの設定ファイルを確認する ls vpnconfig/OpenVPN/ # vpnconfig.ovpn

2. クライアント証明書とキーをovpnファイルに組み込む

ダウンロードしたvpnconfig.ovpnには$CLIENTCERTIFICATE$PRIVATEKEYのプレースホルダが含まれています。これを生成した証明書・キーの内容で置き換えます。

cd ~/azure-p2s-certs # PEMヘッダ行を除いた証明書本文を抽出する CLIENT_CERT=$(openssl x509 -in client.crt | grep -v "BEGIN\|END" | tr -d ' ') CLIENT_KEY=$(grep -v "BEGIN\|END" client.key | tr -d ' ') # 元のovpnファイルを確認する OVPN_SRC=~/vpnconfig/OpenVPN/vpnconfig.ovpn OVPN_DST=~/azure-p2s.ovpn # sedでプレースホルダを実際の証明書・キーに置き換える sed -e "s|\$CLIENTCERTIFICATE|${CLIENT_CERT}|" -e "s|\$PRIVATEKEY|${CLIENT_KEY}|" "$OVPN_SRC" > "$OVPN_DST" # 証明書が組み込まれているか確認する(2以上であれば問題なし) grep -c "MII" ~/azure-p2s.ovpn # 2

3. OpenVPNでVNetに接続する

# openvpnをインストールする(未インストールの場合) sudo apt install openvpn -y # VPNに接続する(デーモンとして起動) sudo openvpn --config ~/azure-p2s.ovpn --daemon --log /var/log/azure-p2s-vpn.log # 接続ログを確認する tail -20 /var/log/azure-p2s-vpn.log # 接続成功時の末尾の出力例 # ... # net_iface_up: set tun0 up # net_addr_v4_add: 172.16.201.2/24 dev tun0 # Initialization Sequence Completed

「Initialization Sequence Completed」が確認できたら接続成功です。

接続確認とルーティングの動作確認

VPN接続が完了すると、クライアントPCにtun0インターフェースが追加され、Azure VNetへのルートが自動的に設定されます。

1. ルーティングテーブルとtun0を確認する

# tun0インターフェースの状態を確認する ip addr show tun0 # 出力例 # 4: tun0: mtu 1500 qdisc fq_codel state UNKNOWN # inet 172.16.201.2/24 brd 172.16.201.255 scope global tun0 # VNet向けのルートが追加されていることを確認する ip route show | grep tun0 # 出力例 # 10.0.0.0/8 via 172.16.201.1 dev tun0 # 172.16.201.0/24 dev tun0 proto kernel scope link src 172.16.201.2

10.0.0.0/8のルートがVPN Gateway経由(172.16.201.1)で設定されていれば、VNet内のVM(10.0.1.4など)への経路が確立されています。

2. VNet内のVMへSSH接続する

# VNet内VMのプライベートIPへ到達確認する ping -c 4 10.0.1.4 # 出力例 # PING 10.0.1.4 (10.0.1.4) 56(84) bytes of data. # 64 bytes from 10.0.1.4: icmp_seq=1 ttl=62 time=18.2 ms # 64 bytes from 10.0.1.4: icmp_seq=2 ttl=62 time=17.9 ms # プライベートIPで直接SSHする(パブリックIP不要) ssh azureuser@10.0.1.4 # 接続成功時の出力例 # Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-1029-azure x86_64) # azureuser@vm-linux-01:~$

パブリックIPなしでVNet内のVMへSSHできました。接続状態やオープンしているポートの確認にはLinux ポート確認の全コマンド(ss・netstat)が役立ちます。VPN接続を切断するにはsudo killall openvpnを実行します。

よくあるエラーと対処法

「TLS Error: TLS handshake failed」が表示される場合
クライアント証明書とルート証明書の不一致が原因のほとんどです。次の点を確認してください。
openssl verify -CAfile ca.crt client.crtを実行して「OK」が返るか確認する
・AzureにアップロードしたBase64データに改行が混入していないか確認する(tr -d ' 'を忘れずに)
vpnconfig.ovpnの証明書プレースホルダが正しく置き換わっているか再確認する

「AUTH_FAILED」と表示される場合
VPN Gatewayへのルート証明書登録がまだ反映されていない可能性があります。az network vnet-gateway root-cert createの実行完了後、数分待ってから再接続してみてください。

VPN接続後にVNet内VMへpingが届かない場合
NSG(ネットワークセキュリティグループ)がICMPを拒否しているかもしれません。まずSSHポート(22番)での接続を試してみてください。ICMPを拒否するNSGルールはよくある設定です。NSGのインバウンドルールで、送信元として「172.16.201.0/24(VPNクライアントアドレスプール)」または「10.0.0.0/16(VNet全体)」を許可しているか確認してください。
VNet内のDNS名前解決の確認にはLinux DNS 設定の基本が参考になります。

「The gateway is not ready to generate a VPN client package」エラーが出る場合
VPN Gatewayのプロビジョニングが完了していません。az network vnet-gateway show --query provisioningState --output tsvSucceededを返すまで待ってから再実行してください。

本記事のまとめ

今回のPoint-to-Site VPN構築で使用した主要なコマンドをまとめます。

やりたいこと コマンド
リソースグループを作成する az group create --name rg-p2s-vpn --location japaneast
VNetを作成する az network vnet create --resource-group rg-p2s-vpn --name vnet-p2s --address-prefix 10.0.0.0/16
GatewaySubnetを追加する az network vnet subnet create --name GatewaySubnet --address-prefix 10.0.255.0/27
VPN Gatewayを作成する az network vnet-gateway create --gateway-type Vpn --vpn-type RouteBased --sku VpnGw1
ルート証明書をアップロードする az network vnet-gateway root-cert create --public-cert-data "Base64文字列"
P2Sアドレスプールを設定する az network vnet-gateway update --address-prefixes 172.16.201.0/24 --vpn-auth-types Certificate
OpenVPNプロファイルを取得する az network vnet-gateway vpn-client generate --authentication-method EAPTLS
VPNに接続する sudo openvpn --config azure-p2s.ovpn
接続後のルートを確認する ip route show
今回はAzureのPoint-to-Site VPNをazコマンドだけで一から構築し、Linuxクライアントから証明書認証でVNet内のVMへSSH接続するまでの全手順を解説しました。パブリックIPもBastionも不要で、VPN Gateway(VpnGw1)の月額費用だけでチーム全員がプライベートアクセスできる構成です。

AWSとの比較では、少人数チームで常時接続するならAzureのVPN Gatewayの定額制が有利になりやすく、スポット的な接続が中心ならAWS Client VPNの従量課金のほうがコストを抑えられる可能性があります。実際の接続パターンで試算して選択してください。

次のステップとしては、証明書失効リスト(CRL)の管理や、Azure AD(Entra ID)認証に切り替えてSSO接続を実現することを検討してみてください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Azure対応セミナーの詳細を見る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。