AWSと自宅をVPNで接続したら便利そうなので、VPNを理解していないけど調べながらやってみました。
注意
この記事の記載はセキュリティのベストプラクティスについては考慮していません。セキュリティリスクが存在している可能性があるのでご注意ください。
やりたいこと
ネットワーク要件を書き出してみると以下のような感じでしょうか…
- 自宅のWindows PCから友人宅のWindows PCにリモートデスクトップ接続できる。逆も可
- 自宅のWindows PCから友人宅のUbuntuサーバにSSHやNFSで接続できる
- 自宅および友人宅からAWSのパブリックサブネットのEC2インスタンスにSSHで接続できる
- 自宅および友人宅からAWSのプライベートサブネットのEC2インスタンスにSSHで接続できる
- 自宅および友人宅からインターネットを経由しないでAWSの各サービスにアクセスできる
- EC2インスタンスからはもちろんAWSの各サービスにアクセスできる
- インターネットには(どこからでもいいんだけど)AWSのインターネットゲートウェイから抜ける
- 速度はあんまり気にしない
ググってみるとAWS Client VPNで簡単にできるよ!ということのようなのですが、
AWS Client VPN エンドポイントアソシエーション 0.15USD/時間
AWS Client VPN 接続 0.05USD/時間
利用料がまあまあかかる。趣味で使うには痛い…
セルフマネージドなら、(安全性や運用性は不安ですが)お財布には優しいのでは?というのが今回の趣旨です。
構築の流れ
構築の流れは以下の通りです。
- EC2インスタンスを準備して
- VPNサーバをインストール・設定して
- VPNクライアントを接続する
VPNサーバにするインスタンスの準備
最初の工程はEC2インスタンスの準備です。
Elastic IPアドレスを紐付けたインスタンスを用意します。
利用料を極限までケチるために、今回はt3a.nano
を選んでみました。
また、VPNサーバとVPNクライアントの間の通信にはL2TP/IPsecというプロトコルを用いるので、これに対応したポートのインバウンドトラフィックをセキュリティグループで許可します。
ポートは以下の2つです。
- UDP/500
- UDP/4500
SSHで接続して初期設定をしていきます。
# メモリ不足でyum updateできないことがあるのでスワップ領域を増やす
sudo dd if=/dev/zero of=/swap.extended bs=1M count=512
sudo mkswap /swap.extended
sudo chmod 0600 /swap.extended
sudo swapon /swap.extended
sudo sh -c "echo '/swap.extended swap swap defaults 0 0' >> /etc/fstab"
# yum update
sudo yum update
# 次の工程で使うパッケージの導入
sudo yum install gcc
SoftEther VPN Serverのインストール
次の工程はVPNサーバのインストールです。
今回は導入が簡単そうなSoftEtherでチャレンジします!
とりあえずバージョン更新履歴で最新バージョンを確認したら、ソースコードをダウンロードします。
ソースコードは https://ja.softether.org/5-download/src から指示通りにリンクを辿ればダウンロードできます。
今回はsoftether-vpnserver-v4.42-9798-rtm-2023.06.30-linux-x64-64bit.tar.gz
がよさそうなので、そのダウンロードリンクを取得します。
ソースコードからインストールしていきます。
# ダウンロード
wget https://www.softether-download.com/files/softether/v4.42-9798-rtm-2023.06.30-tree/Linux/SoftEther_VPN_Server/64bit_-_Intel_x64_or_AMD64/softether-vpnserver-v4.42-9798-rtm-2023.06.30-linux-x64-64bit.tar.gz
# 解凍
tar zxvf softether-vpnserver-v4.42-9798-rtm-2023.06.30-linux-x64-64bit.tar.gz
# make
cd vpnserver
make
cd ..
# インストール先のディレクトリに配置してファイル権限を付与
sudo mv vpnserver /opt/vpnserver
sudo chown root:root -R /opt/vpnserver
コマンドラインでVPNサーバの設定
次の工程はVPNサーバの設定です。
まず、この後の設定で使うEC2インスタンスのNICの名前と、VPCのネットワークアドレスをそれぞれ確認しておきます。
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
2: ens5: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
inet 10.0.4.95/20 metric 512 brd 10.0.15.255 scope global dynamic ens5
自分が選んだOSと設定だとens5
という名前みたいです。
また、自分が設定したVPCのネットワークアドレスは10.0.0.0/20
みたいです。
SoftEther VPN Serverはまず起動してから設定するそうです。
サービスとして登録して起動させます。
サービスの登録はこちらを参考にしました。
sudo vi /etc/systemd/system/vpnserver.service
sudo systemctl daemon-reload
sudo systemctl start vpnserver
sudo systemctl status vpnserver
sudo systemctl enable vpnserver
/etc/systemd/system/vpnserver.service
の内容は以下のようになっています。
[Unit]
Description=SoftEther VPN Server Service
After=network.target
[Service]
Type=forking
User=root
ExecStartPre=/sbin/ip link set dev (ここはNICの名前にする) promisc on
ExecStart=/opt/vpnserver/vpnserver start
ExecStop=/opt/vpnserver/vpnserver stop
Restart=on-abort
WorkingDirectory=/opt/vpnserver/
[Install]
WantedBy=multi-user.target
SoftEther VPN Serverが起動するとvpncmd
というツールで設定できるようになります。
上記の手順そのままだとパスが通っていないので、フルパス/opt/vpnserver/vpncmd
でツールを実行しましょう。
vpncmd
のヘルプは?
で見れます。
この設定もこちらを参考にしました。
設定値として以下のことをあらかじめ決めておくとサクサク進められそうです。
- 仮想Hub名
- 仮想Hubパスワード。仮想Hubの設定を確認・変更するときに必要になる
- ユーザ名。同じユーザ名で複数端末から同時にVPNに接続することはできないので端末ごとに決める
- ユーザパスワード
- IPsecの暗号化で使う事前共有鍵。できるだけ長いものを用意する
- VPNで接続したときに割り振られるIPアドレス。AWSや自宅と被らないようにする
1
[空のままでEnter]
HubCreate my-hub
Hub my-hub
UserCreate my-pc /GROUP:none /REALNAME:none /NOTE:none
UserCreate tomo-pc /GROUP:none /REALNAME:none /NOTE:none
UserCreate tomo-server /GROUP:none /REALNAME:none /NOTE:none
UserPasswordSet my-pc /PASSWORD:hogehoge
UserPasswordSet tomo-pc /PASSWORD:hogehoge
UserPasswordSet tomo-server /PASSWORD:hogehoge
IPsecEnable /L2TP:yes /L2TPRAW:no /ETHERIP:no /DEFAULTHUB:my-hub
[事前共有鍵を入力]
SecureNatEnable
DhcpSet /START:192.168.30.10 /END:192.168.30.200 /MASK:255.255.255.0 /EXPIRE:7200 /GW:192.168.30.1 /DNS:192.168.30.1 /DNS2:none /DOMAIN:none /LOG:yes /PUSHROUTE:"10.0.0.0/255.255.0.0/192.168.30.1"
exit
DHCP機能を設定するときの/PUSHROUTE:"10.0.0.0/255.255.240.0/192.168.30.1"
については以下のように決めました。
- 1つ目のIPアドレス:VPCのネットワークアドレス
- 2つ目のIPアドレス:VPCのネットワークアドレスのサブネットマスク
- 3つ目のIPアドレス:
/GW
に指定したIPアドレス
VPNで接続すると仮想NAT(SecureNat)の内側に収容されるので、EC2インスタンスなど(10.0.x.x)にアクセスしたいときは、/GW
から外側に出る…ということかな?
VPNクライアントの接続:Windows
最後の工程はVPNクライアントの接続です。まずはWindowsの設定から。
今回用いているL2TP/IPsecというプロトコルは標準的なものなので、Windowsの標準機能でVPNに接続できます。
設定>ネットワークとインターネット>VPN>VPNを追加、で出てくるダイアログに設定値を入力すれば完了です。
VPNクライアントの接続:Ubuntu
Ubuntuの設定もやってみます。
UbuntuのバージョンはUbuntu Desktop 22.04.3 LTSです。
コマンドラインで設定する自信がないので、GUI(NetworkManager)から設定していきます。
残念ながらデフォルトのNetworkManagerにはL2TP/IPsecの設定画面が用意されていません。そこで、L2TP/IPsecの設定画面を追加するパッケージを導入します。
sudo apt install network-manager-l2tp-gnome
ここで出てくるダイアログに設定値を入力すれば完了です。
NTドメイン
は入力不要です。また、IPsec Settings...
から事前共有鍵を入力する必要があります。
NetworkManagerから一回設定してしまえば、後はnmcli
コマンドで接続・切断できます。
# ユーザパスワードと事前共有鍵をファイルに書いておく必要がある。ファイル名はなんでもいい
vi ~/.secrets/vpn
# VPN接続のプロファイル名を調べる
sudo nmcli connection show
# VPN接続のプロファイル名が仮に"AWS"だとすれば
sudo nmcli connection up id AWS passwd-file ~/.secrets/vpn
上記の~/.secrets/vpn
には以下のようなフォーマットでユーザパスワードと事前共有鍵を書いておきます。
vpn.secrets.password:(ユーザパスワード)
vpn.secrets.ipsec-psk:(事前共有鍵)
nmcli
を実行するコマンドをスクリプト化すれば、サーバを再起動したときに自動的にVPNに接続できそうですね。
rc.local
に書いてもいいのかな?
# スクリプトを作成
vi /home/user1/connect-vpn.sh
chmod 755 /home/user1/connect-vpn.sh
# スクリプトをサービスとして登録して起動させる
sudo vi /etc/systemd/system/connect-vpn.service
sudo systemctl daemon-reload
sudo systemctl start connect-vpn.service
sudo systemctl enable connect-vpn.service
#!/bin/sh
sudo nmcli connection up id AWS passwd-file /home/user1/.secrets/vpn
[Unit]
Description=Connect VPN
[Service]
ExecStart=/home/user1/connect-vpn.sh
Restart=no
Type=simple
[Install]
WantedBy=multi-user.target
試しにサーバを再起動してみて、自動的にVPNに接続されればOK!