#はじめに
リモートワークでVPNを使っているんですけれども、Windowsで普通にVPNを設定するとすべての通信がVPNを経由してしまいます。
そこで、VPN先のネットワークへの通信だけVPNを経由し、普通にググったりツイッターで脱線情報収集したりするのは直接インターネットに出ていきたい。
しかしながら、特定のIPだけはVPNを経由したい。
そんな環境があって、特定の数個のIPアドレスだけ手動で登録して使ってました。
しかし、AWSのEC2スポットインスタンスをポコポコ立ち上げてアクセスする必要が出てきました。セキュリティ上、拠点以外からのアクセスは遮断しています。
スポットインスタンスを立ち上げるたびにいちいちパブリックIPを調べて手動でルーティング設定するのは面倒です。
そこで、AWS向けは全部VPN経由にする方法を考えました。
たまたまAWSが使われているサービスへの通信(例の52.68.96.58とか)もVPN経由になってしまいますが、まあ、許容範囲内でしょう。
#前提条件
・AWS Tools for Windows PowerShell がインストールされている
参考 AWS Tools for PowerShell ことはじめ
(今回の使い方では、Credential情報の設定は不要です。)
・通常の通信はVPNを経由しない指定は設定済み
参考 【Windows】指定した宛先の通信のみVPN経由にする
#AWSのIP範囲取得
AWSのIP範囲って変わっていくんじゃないかと思ったのですが、プログラマブルに取得する方法が用意されていました。
公式ドキュメントの AWS IP アドレスの範囲 をご覧ください。
だけだと不親切なので、とりあえず取得するコマンドを
Get-AWSPublicIpAddressRange -Region ap-northeast-1 -ServiceKey EC2 | Where-Object {$_.IpAddressFormat -eq "Ipv4"} | Select-Object IpPrefix
これを応用して、ルーティング設定コマンドに流し込みます。
#出来上がり
VPN接続をトリガにスクリプトを走らせられないかと調べたのですが、見つからなかったので、スクリプトを走らせると設定したうえでVPN接続をする方法にしました。
$vpnName = "MyVPN"
$vpnUser = "username"
$vpnPass = "password"
# 現状のルーティング設定を全部削除
(Get-VpnConnection $vpnName).Routes |
ForEach-Object {
Remove-VpnConnectionRoute $vpnName -DestinationPrefix $_.DestinationPrefix
}
# AWSのIP範囲を取得(東京リージョンのEC2だけ)
Get-AWSPublicIpAddressRange -Region ap-northeast-1 -ServiceKey EC2 |
#IPv4に絞る
Where-Object {$_.IpAddressFormat -eq "Ipv4"} |
#おのおのルーティング設定
ForEach-Object {
Add-VpnConnectionRoute $vpnName -DestinationPrefix $_.IpPrefix
}
#AWS以外でルーティングが必要ならここに記述
#Add-VpnConnectionRoute $vpnName -DestinationPrefix xxx.xxx.xxx.xxx
#VPN接続
C:\windows\system32\rasdial.exe $vpnName $vpnUser $vpnPass
実際に使うときは $vpnName
$vpnUser
$vpnPass
をご自身の環境に合わせて変更してください。
(WindowsのUIから接続するときはVPN名だけで接続できるので、スクリプトからもVPN名だけでいけないか調べたのですが、どうも出来ないようで、ユーザー名・パスワードもスクリプト内に記述しております)
また、自分の利用範囲ということでAWSの東京リージョン・EC2・IPv4に絞ってますが、ここもご自身が利用するAWSのサービスに合わせて書き換えましょう。
PowerShellのお作法として、BOM付UTF-8で保存しましょう。(←それがベストプラクティスなのかはよくわかってない)
ルーティングテーブルが大量にあると速度低下の懸念がありますが、上記設定(40件ぐらい)では目立った速度低下は無いようです。(NURO光で変わらず800Mbpsぐらいでてます。)