aws clientvpnを使って個人VPNを構築する

2022/07/10

aws clientvpnを使って個人VPNを構築する

はじめに

awsのclient vpnを用いて自分だけのVPN環境を構築したいと思います なぜClient VPNを構築私用と思ったか...は話すと長くなりますが...

忘れもしない2021/11/27日土曜日。一体インターネッツで何が起こったのかを...
休日の朝。普段のようにベッドから起きた自分は、今日もネッツゲームをやる気満々だった。まずはdis〇〇サーバへJOIN!
と思いきや...接続できない...

まぁ焦らない焦らない。Dis〇〇もこんなことはたまにはあるやんな。と思い原〇を起動...つながらない...
あれ...ネットワーク死んだか?怪しんだ自分はまずpingが通るか確認...問題なし
え...サイトとかも普通に見える...どうなっていやがる...

俺のインターネッツは一体...今...どうなってやがるんだああああああ(半日経過)

っとまぁそんな感じで半日一部通信のインターネッツが通信できなくなってしまいました...

11/27日に上位ISPで特定通信がFilterされてしまい通信できない状態となってしまいました。

https://matomebu.com/news/ntt20211127/

この回避方法として有名な方法がVPNがあるため(某countryでネット規制がかかった際にアプリDL一位がVPNアプリだったとかなんとか)VPNなんかいいのないかなぁと調べていました。

ただ、普段使いはしない為、数時間のためだけにVPNを契約なんてしたくないなぁと思い、探していたらAWSにVPNサービスがあり、それを用いてVPN構築した備忘録です。

環境

  • windows10
  • Open VPN
  • aws cli/2.7.12
  • python 3.9.1
  • EasyRSA 3.1.0

前準備

上記環境についてのインストール等は特に述べていないので、適宜インストールしてください

AWS Client vpnについて

AWSではVPNを提供しています。種類は調べたところ以下2種類ありました

  • Site-to-Site VPN
  • Client VPN

Site-to-Site VPNはルータで完結するサイト間VPN、Client VPNがソフトを入れて通信するリモートアクセスVPNのイメージです 今回はOpen VPNをインストールし、Client VPNを用いてVPN化していきます

また、Client VPNの構築内容はAWS公式にありますインターネットへのアクセスを参考に、CDK化し構築していこうと思います。

Client VPNには認証方法が3種類あるのですが、相互認証を用います

Client VPN作成

公式テンプレート を使用します

$ cdk init app --language python
$ source .venv/bin/activate
$ python -m pip install -r requirements.txt

ディレクトリ名/ディレクトリ名_stack.pyとなっているファイルを開き、VPCとVPNを記載していきます。 自分の場合はaws_cdk_vpn_stack.pyで作成されていました

aws_cdk_vpn_stack.py
from aws_cdk import (
    # Duration,
    Stack,
    # aws_sqs as sqs,
    aws_ec2
)
from constructs import Construct


class AwsCdkVpnStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, certificate_arn: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        vpc = aws_ec2.Vpc(
            self,
            "Vpc_CDK",
            cidr="172.31.0.0/16",
            max_azs=1,
            subnet_configuration=[
                aws_ec2.SubnetConfiguration(
                    name='Public-Subent',
                    subnet_type=aws_ec2.SubnetType.PUBLIC,
                    cidr_mask=20
                ),
            ],
        )

        isubnet = vpc.public_subnets

        client_vpn = aws_ec2.ClientVpnEndpoint(
            scope=self,
            id="Client_VPN",
            vpc=vpc,
            cidr="10.0.0.0/22",
            authorize_all_users_to_vpc_cidr=False,
            split_tunnel=False,
            server_certificate_arn=certificate_arn,
            client_certificate_arn=certificate_arn,
        )

        client_vpn.add_authorization_rule(
            id="auth",
            cidr="0.0.0.0/0",
        )

        for isub in isubnet:
            client_vpn.add_route(
                id="routing",
                cidr='0.0.0.0/0',
                target=aws_ec2.ClientVpnRouteTarget.subnet(subnet=isub)
            )

不要なコメント等があるので適宜削除してください

VPC, VPN等CDKで作成に困った際はこちらこちらを参考に作成しました

今回自分用のVPNかつ、全通信をインターネットに向けるだけなので、routing部分で全通信を指定のサブネットに流すように設定しましたが、awsリソースにVPNを用いてアクセスさせたい。等の場合はルーティング等をしっかりと設定してください

また、ClientVpnEndpointのsplit_tunnelはFalseに設定します。Trueにした場合インターネット側通信がVPNトンネルを通らなくなるroutingになるようです(ただ、夢系で言えばTrueにして、特定の通信のみのroutingを追加したほうが良いと思いますが、そんな根気はないのでやりません)

app.pyファイルも少し変更します

app.py
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from aws_cdk_vpn.aws_cdk_vpn_stack import AwsCdkVpnStack
from dotenv import load_dotenv

load_dotenv()

app = cdk.App()
certificate_arn = os.environ['CERTIFICATE_ARN']
client_vpn = AwsCdkVpnStack(app, "AwsCdkVpnStack", certificate_arn)

cdk.Tags.of(client_vpn).add('Name', 'Test_VPN')

app.synth()

後ほどインポートするACMのarn情報が必要なので、それをStackのリソースに対して適用できればどんな記述でもOKです

自分の場合はdotenvを用いて、.envファイルに記載しました

相互認証準備

公式ドキュメントに手順が載っているので、こちらを参考に作成していきます 先ほど作成したテンプレートの直下に

cd .\EasyRSA-3.1.0\
.\EasyRSA-Start.bat
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa build-server-full server nopass
./easyrsa build-client-full client1.domain.tld nopass
exit
mkdir ../certificate
copy pki\ca.crt ../certificate
copy pki\issued\server.crt ../certificate
copy pki\private\server.key ../certificate
copy pki\issued\client1.domain.tld.crt ../certificate
copy pki\private\client1.domain.tld.key ../certificate
cd ../certificate
aws acm import-certificate --certificate fileb://server.crt --private-key fileb://server.key --certificate-chain fileb://ca.crt

ACMに証明書をインポートするコマンドも入っているので必要に応じてaws cliをインストールしてください arn情報が必要なため、コピーしCDKリソースで使用できるようにしてください

CDK Deploy

CDKをデプロイしていきます

$ cdk deploy
...

 ✅  AwsCdkVpnStack

✨  Deployment time: 459.08s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:576272532983:stack/AwsCdkVpnStack/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

✨  Total time: 486.84s

結構デプロイに時間かかるなぁと...

Open VPN接続

最後に、client vpnエンドポイントのクライアント設定のダウンロードを行い、Open VPNの設定に記述します clientvpn.png

openvpn
client
dev tun
proto udp
remote cvpn-endpoint-xxxxxxxxxxxxxxxxxxx.prod.clientvpn.ap-northeast-1.amazonaws.com 443
remote-random-hostname
resolv-retry infinite
nobind
remote-cert-tls server
cipher AES-256-GCM
verb 3
<ca>
-----BEGIN CERTIFICATE-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END CERTIFICATE-----

</ca>

# これを追記する
cert C:\\Path\\client1.domain.tld.crt
key C:\\client1.domain.tld.key

reneg-sec 0

cert, keyを追記します。それぞれ相互認証時に作成したclient1.domain.tld.crtとclient1.domain.tld.keyを指定します

上記が完了し、接続を開始すればClient VPNを用いたVPN接続環境の完成です!

11/27日に行ってテストしたいところですが、それは行えないのでIPアドレスが変わっているか確認します clientvpn-ip.png

明らかAWSのIPになっていますが、不安であればVPNを切った後にIPアドレスが変化するか見ていただければと思います!

使ってみて所感

普段AWS使っていたり、慣れている人であれば一時的にVPNを使いたい際はかなり良い選択ではないかなと思います。特に契約等が存在しないのも良きですね。ただ、数日間単位で使うようでしたらどっかのVPN契約して使ったほうが安くつきそうです(やりたいことによりますが)

次は今回filterでブロックされた通信のみをルーティングに追加して、該当通信のみをVPN経由にする設定もして置きたいですね。(料金で眼球飛び出ないためにも)

今回の実際のソースコードを確認したい方が居ましたらGithubリポジトリを確認ください。

avatar

しがないWebエンジニアです。楽しいことをして生きていきたい。ゲームすることとお酒を飲むのが趣味!

項目


© 2022 takap