カテゴリー
Ubuntu

WireGuardでVPN接続を動的に追加する

前回の記事で、WireGuardを導入してみたが、接続用の端末が増えたときにどうするか手順メモ。

/etc/wireguard/wg0.conf には、サーバの秘密鍵と、クライアントの公開鍵がずらっと羅列されている。端末が増えたときは、この[Peer]句を増やしていくことになる。

単純に実施するには、wg-quick down wg0 → wg0.confを編集 → wg-quick up wg0 とすると良いのだが……、こうすると接続中のVPN接続がダウンしてしまう。

そのため、動作中にコンフィグを追加するには wg addconf コマンドを利用する。なお、addconfコマンドで動的に追加されたコンフィグが設定ファイルに書き戻されるためには、SaveConfig = true があらかじめ設定されている必要がある。

では、追加するコンフィグを作成してファイルに保存し、インターフェースに適用してみる。

vim example.conf
[Peer]
PublicKey = abcdefghijealkjlgooewewu9oisduf0w9809ew=
AllowedIPs = 192.168.255.15/32

sudo wg addconf wg0 example.conf

(上記の実行例は、適当すぎる鍵文字列をセットしたので怒られている)

実際に適用されているかは、wgコマンドで確認出来る。

sudo wg showconf wg0
カテゴリー
Ubuntu

UbuntuにWireGuardを入れてVPN接続してみる

ASDK上で仮想ネットワークを作って直接アクセスするためにVPN Gatewayを立てるのが普通ですが、ちょっと思い立ってUbuntuにWireGuardを入れてVPNサーバとして構成してみました。

VPN GatewayでIPsecとか構成し始めるといろいろと面倒くさいので、UDPポートを1個開放するだけで使えるWireGuardは手軽かなと。

WireGuardをインストールする

https://www.wireguard.com/install/ に記載されている手順でパッケージを追加する。今回の追加対象となるUbuntuは18.04なのでリポジトリ追加してからインストールになる。

sudo add-apt-repository ppa:wireguard/wireguard
sudo apt-get update
sudo apt-get install wireguard

サーバ(Ubuntu)側でトンネルを設定する

まずはVPN越しのトラフィックを転送するため、ip_forwardをオンにする。

sudo vim /etc/sysctl.d/98-wireguard.conf
net.ipv4.ip_forward = 1
sudo sysctl -p /etc/sysctl.d/98-wireguard.conf 

次にサーバ側の公開鍵・秘密鍵を生成する。
ここで作った鍵はこの後のトンネル設定で利用するので、無くさないようにしておく。

mkdir wgkeys
umask 077 wgkeys
cd wgkeys
wg genkey > private.key
wg pubkey > public.key < private.key

クライアント(Windows)側でトンネルを設定する

Windows版のクライアントソフトウェアは、 https://www.wireguard.com/install/ からダウンロードできる。

セットアップすると以下のような画面が表示される。

メイン画面下部の[Add Tunnel]メニューから[Add empty tunnel…]を実行する。

[Create new tunnel]画面に、Private key/Private key (公開鍵・秘密鍵)のペアが表示されるので適当な名前を付けてSaveしておく。

サーバ~クライアント間のトンネルを設定する

まずはサーバ側の設定から。wg0デバイスとして構成してみる。

sudo vim /etc/wireguard/wg0.conf
sudo wg-quick up wg0

wg0の内容は以下の通り。

[Interface]
Address = 192.168.255.1/24
ListenPort = <サーバのPort番号>
PrivateKey = <サーバの秘密鍵>
SaveConfig = true
# クライアント側からのトラフィックをIPマスカレード(NAPT)して、このサーバのIPアドレスに変換して内部ネットワークに流すためのiptablesコマンド。
# (IPマスカレードしないと、クライアントのIPアドレスのまま内部ネットワークにパケットが流れてくるので、内部ネットワークの中で適切に戻りのルーティングを追記しないといけなくなる)
PostUp = iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# 以下はIPv6も通すときの設定
# PostUp = iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 
# PostDown = iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# クライアント1
[Peer] 
PublicKey = <クライアントの公開鍵>
# クライアント側のIPアドレスを指定する
AllowedIPs = 192.168.255.11/32

# クライアント2
[Peer]
PublicKey = <クライアントの公開鍵>
# クライアント側のIPアドレスを指定する
AllowedIPs = 192.168.255.12/32

最後にサーバのwg0サービスを自動起動するように設定しておく。

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

次に、クライアント側の設定を行う。

サーバに流し込んだコンフィグと同様に、アプリケーション上で文字列を設定していく。

[Interface]
PrivateKey = <クライアントの秘密鍵>
# クライアント側で利用するIPアドレスを指定する
Address = 192.168.255.11/24
# DNS設定をしないと、DHCP等で持っているDNSサーバがVPNトンネル越しに(普通はそんなアクセス出来ない)DNSサーバを使って名前解決をしようとして、各種のアクセスがトラフィックが名前解決エラーになってしまう。
# ここでは、接続先のAzure VMで共通して利用可能なDNSサーバを指定している。
DNS = 168.63.129.16

[Peer]
PublicKey = <サーバの公開鍵>
# VPNトンネルに流すトラフィックのIPアドレスレンジを指定する。0.0.0.0/0だと全てのトラフィックがVPN越しになる。
AllowedIPs = 0.0.0.0/0
# IPv6も通すならこっち
# AllowedIPs = 0.0.0.0/0, ::0/0
# サーバのIPアドレス:ポート番号を指定する
Endpoint = <サーバのIPアドレス>:<サーバのPort番号>

WireGuard VPNトンネルを開始する

で、繋いでみるとこんな感じ。

VPN接続のLANアダプタが一個増えてそこにトラフィックが流れるようになる。

参考にしたURL

Quick Start – WireGuard
https://www.wireguard.com/quickstart/

WireGuard – ArchWiki
https://wiki.archlinux.jp/index.php/WireGuard

WireGuard をつかってみる – Qiita
https://qiita.com/kjm/items/4344e5ccaaf9f02e5d69

WireGuardでVPNごしに自宅サーバ開発できる環境を作った
https://blog.koh.dev/2020-01-01-vpn/

カテゴリー
Azure

ASDK上の仮想マシンに直接アクセスするためにNAT設定を追加する

ASDK上に立てた仮想マシンへのアクセス方式として、公式にドキュメントに記載されているのは以下のやり方がある。

  • ASDKホストマシンにリモートデスクトップして、その上でSSH/RDP接続する。
    ただし、ASDKホストマシンはWindows Serverベースのため、標準だと最大2セッションしか接続できないので、多数のユーザから同時にはアクセス出来ない。
  • Azure Stack PowershellおよびAzure Stack ToolsをセットアップしたPCから、ASDKホストマシンにVPN接続する。
    この場合は、リモートデスクトップの2セッション接続制限には引っかからないが、接続元となるPCに上記のツールをセットアップしてVPNを設定する必要がある。(ASDKをデプロイする度にこの設定をユーザにやり直してもらう)

その他、Azureと同様にVPN GatewayをセットアップしてP2S VPNを構成するとかは当然出来る。

ただ、いずれも、オンプレミスっぽい雰囲気でASDK上の仮想マシンを使いたいだけのユーザからするとちょっと……、ハードルが高い。

そのため、お手軽にオンプレミスっぽい感じで接続できるようにASDKホストマシン上でNATを設定して、さもその辺に仮想マシンが居るように見せかけることにした。

Fig. ASDKでNATを構成する概念図

ASDKホストマシンで実施する手順は以下の通り。

  1. NATオブジェクトを作成する
  2. NATオブジェクトに、接続用IPアドレスを追加する
  3. NATルールを作成し、仮想マシンのIPアドレス&Port番号と、接続用IPアドレス&Port番号のマッピングを設定する

NATオブジェクトを作成する

デフォルトで、ASDKとBGPルータの間でVPN接続するための”BGPNAT”という名前のNATオブジェクトが作成されているが、これは華麗に無視して別のNATオブジェクトを作成するのが吉。

New-NetNat -Name global -ExternalIPInterfaceAddressPrefix 192.168.1.0/24

NATオブジェクトに、接続用IPアドレスを追加する

ASDKホストマシンに割り当てられているIPアドレスとは別に、NAT専用のIPアドレスを設定するのが分かりやすいはず。もしASDKが接続されているセグメントに余裕があるなら、仮想マシンと1対1で設定してしまっても良いだろう。

Add-NetNatExternalAddress -NatName global -IPAddress 192.168.1.6 -PortStart 0 -PortEnd 65535

NATルールを作成し、仮想マシンのIPアドレス&Port番号と、接続用IPアドレス&Port番号のマッピングを設定する

Add-NetNatStaticMapping -NatName global -ExternalIPAddress 192.168.1.6 -Protocol TCP -ExternalPort 22 -InternalIPAddress 192.168.102.32 -InternalPort 22

後は、NATルールを作成するだけ。

で、繋いでみると、繋がる!!!
(ちなみにPingに応答しているのはASDKホストマシンのほう。NATルールにないのでASDKホストマシン側に着信している)