docker上のVPNからしかアクセスできないサービスを作る

docker上のネットワークに接続しないとアクセスできないサービスを作りたかったので、pritunlを使ってVPNを作りました。
ほぼpritunlの話です。

## docker コンテナ

dockerで使うイメージは、VPN構築のためのPritunlと、説明のためのNginxです。Pritunlはホストマシンとの通信用に、ポートを空けておきますが、NginxはVPN接続時にのみ、アクセス出来るようにするため、portの設定はしません。

```docker-compose.yml
version: '3.7'

services:
  pritunl:
    image: jippi/pritunl
    container_name: pritunl
    privileged: true
    ports:
      - "1194:1194/udp"
      - "1194:1194/tcp"
      - "80:80/tcp"
      - "443:443/tcp"
    networks:
      bridge:
        ipv4_address: 172.16.20.2

  nginx:
    image: nginx
    container_name: nginx
    networks:
      bridge:
        ipv4_address: 172.16.20.3

networks:
  bridge:
    driver: bridge
    ipam:
      driver: default
      config: 
        - subnet: 172.16.20.0/24
```

`docker-compose.yml`が用意できたら、サクッとコンテナを立ち上げます。

```console
$ docker-compose up -d
```

この時点では、Nginxには繋がりません。

![access_to_nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/b207a987-370d-c10f-b8eb-d7131190092a.png)


# Pritunlへのログイン

dockerが起動したら、`localhost:443`でpritunlに接続してログインします。

デフォルトのUsernameとPasswordは、どちらもpritunlです。

![pritunl_login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/822353a1-b28e-dc50-7849-e65b19ea6070.png)

ログインしたら、Initial Setupの画面が表示されるので、とりあえずUsernameとPasswordを変更しておきましょう。Public Addressは、空欄にしておくとグローバルIPアドレスが自動入力されてしまうため、とりあえず手元で動かすために`localhost`に変更しておきます。

![pritunl_InitialSetup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/dbea245c-6eae-f9b6-9b87-4cca32fa6aa4.png)


# Pritunlの設定変更

ここからPritunlの設定をしていきます。`Users`タブからAdd Organizationをクリックし、適当な名前を入力したら、Addを押下して追加します。
![pritunl_AddOrganization.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/8cb08b9e-24da-98fa-5299-5bd7c602e636.png)

続いて、Userを追加します。Pinコードはoptionalなので、空欄でも構いません。

![pritunl_AddUser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/6640298d-5516-3c63-a06b-0eb721c54ba0.png)

今度は、Serversタブに移動し、Add ServerからServerを追加します。PortとProtocolは、docker-composeで設定したudpのポートを指定します。

Virtual Networkに設定したネットワークのipが、vpnクライアントに割り当てられます。
この値を、docker上のbridgeネットワークと同一にしてしまい、Pritunlコンテナに繋げなくなったミスをしたのは、ここだけの話。
なので、dockerのネットワークのサブネットとは全く異なる値にしておいたほうが、トラブルが少ないはず。

![pritunl_AddServer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/f7e88b05-c649-5f64-f65d-b18fff182d62.png)


サーバが作成できたら、Routeも追加しておきます。Add Routeをクリックし、docker composeで設定したネットワークを追加します。

![pritunl_AddRoute.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/15d67f0f-1a16-9178-2c52-0fe11cd420b9.png)


サーバが作成できたら、Attach Organizationをクリックして、作成したサーバにOrganizationを紐付けます。

![pritunl_AttachOrganization.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/ba5ccc9f-6655-971d-614c-0c5adb4966cc.png)

# VPNサーバの起動

Serversから作成したサーバのStart Severをクリックすると、VPNサーバが起動します。

![pritunl_StartServer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/36b62b7d-86c8-16bf-d8a0-c19c599cf887.png)

# Pritunlクライアントの設定

Usersタブに戻り、対象のユーザープロファイルをダウンロードします。

![pritunl_download-user-profile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/022d9bfc-6d89-7383-5190-cdb57d020bbb.png)

Pritunl Clientの[公式サイト](https://client.pritunl.com/)からクライアントをダウンロードし、起動します。
Import Profileをクリックし、先ほどダウンロードしたプロファイルを読み込みます。

![pritunl_client.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/6c865e1e-d2c0-617f-6840-7bddc3dccba9.png)

インポートできたら、メニューボタンより`Conect`を選択し、VPNに接続します。

![pritunl_clinet_connect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/5c7f8b95-eb74-fb23-4afa-d5c8db8c09a5.png)

![pritunl_vpn_connection.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/5e6dcf98-b73e-3b73-7b11-9a4efab877b5.png)

VPNに接続できると、先ほど繋がらなかった`172.16.20.3`でNginxにアクセスできるようになります。

![nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92115/ee4fbbd8-2fd7-7ceb-0bdd-0fe32dc104f2.png)