2019-05-25 / @syui

vpn

vpn serverを一瞬で立ち上げ、外出先から接続する方法

Free Wi-Fiなどを利用する際は、VPNに接続すると安全です。仕組みは、通信が暗号化されるトンネルのようなものを作り、そこにトラフィックを通すことで通信内容の傍受などを阻害する効果があります。つまり、Free Wi-Fiを利用して何らかのサービスにログインする際にidやpassを読み取られる危険などがあるわけですが、それを回避できます。

また、VPNを使うとVPN Serverを経由するため、IP AddressがそのServerのものに変わります。(ただし、使用するツールや環境変数に依存する場合あり)。

しかし、VPNはなかなか面倒で一番良いのは、サービスにインストールして使えるようにすることですが、費用がかかります。

今回は、Web UIから設定が行えるpritunlを使ってLocal NetworkにVPN Serverを立ててみようと思います。

https://github.com/Fridus/docker-pritunl

$ mkdir mongo
$ sudo docker-compose up -d

docker-compose.yml

network:
  image: busybox
  ports:
    - "9700:443"
    - "1194:1194/udp"
  restart: always
  tty: true
mongo:
  image: mongo
  volumes:
    - ./mongo:/data/db
  restart: always
  net: container:network
pritunl:
  image: fridus/pritunl
  privileged: true
  environment:
    - MONGO_URI=mongodb://127.0.0.1:27017/pritunl
  restart: always
  net: container:network

もしくはjippi/pritunlを使います。

#!/bin/bash

datadir="$(dirname $(readlink -f "$0"))/data"
echo "datadir=$datadir"

mkdir -p $datadir/{mongodb,pritunl}
touch $datadir/pritunl.conf

sudo docker run \
    --name=pritunl \
    --detach \
    --cap-add NET_ADMIN \
    --network=bridge \
    --restart=always \
    -v $datadir/mongodb:/var/lib/mongodb \
    -v $datadir/pritunl:/var/lib/pritunl \
    -v $datadir/pritunl.conf:/etc/pritunl.conf \
    -p 1194:1194/udp \
    -p xxxxxx:xxxxx/tcp \
    jippi/pritunl

次に、web UIから設定を行います。

$ ifconfig
192.168.1.4

$ chromium https://192.168.1.4:9700
$ chromium https://localhost:9700
	user,password:pritunl

# IP : 192.168.1.4
# User -> Add Organization, Add User
# Server -> Add Server(Port 1194/udp), Attach Organization, Start Server
# User -> download profile

SSLのエラーが出る場合などは、Portを443から80にする、Safariでアクセスすると回避できるかも。

あとは、clientをインストールして、DLしたprofileをインポートするだけです。clientは、Tunnelblickでもpritunlでもどちらでもいいです。osによっていろいろなものがあります。

WANからアクセスする際は、ルーターにてポートフォワーディングなどをします。例えば、ルーターのGlobal IPが1.1.1.1だったとしましょう。そこで、1.1.1.1への特定のポートのアクセスを、ローカルネットワークの特定のポートに転送する設定です。(なお、現実では1.1.1.1はcloudflareのdnsです)

# global ipを調べる
$ curl -sL ipinfo.io

ただ、downloadしたprofile(xxx.opvn)は、Local IPを指定していますので、設定ファイルを書き直さなければなりません。

$ aunpack default.tar
$ vim vpn_default.ovpn
- remote 192.168.1.4 1194 udp
+ remote 1.1.1.1 xxxxxx udp

xxxxxxのところは、特定されにくそうな番号を指定すると良いです。それをdockerで指定しているポート、ここでは1194ですが、そこに転送する設定を保存します。これは、ルーターのポート転送などの項目になります。つまり、WAN側からの特定のポートへのアクセスに対して、LAN側の特定ポートに転送する処理です。

1.1.1.1:xxxxx/udp -> 192.168.1.4:1194/udp

このようにすることで、例えば、iOSのOpenVPNというアプリでvpn_default.ovpnを開き、キャリア回線(WAN)からVPN Serverに接続できるようになります。これはルータのポートを開放するため、比較的危険な設定になりますので注意してください。ただし、Global IPからLocal Networkにアクセスするにはこの方法が最も安全だと思います。通常、WAN側からLocal NetworkにSSHするような場合も多くの人はこういう方法を使ってるはず。

なお、pritunlの設定もルーターのGlobal IPを指定して、Restart Serverします。そうしないと、Virtual Networkが起動せず、Local IPで接続しているうちはVirtual Networkが立ち上がっているので、Globalからもアクセスできますが、それが切断されるとGlobalからの接続もできなくなってしまいます。

Local NetworkにVPN Serverを立ち上げるメリット

先程、WANからSSHする場合、通常はルータのポート転送を利用すると言いました。

しかし、Local NetworkにVPN Serverを立てている場合は別です。

WANから自前のVPN Serverを通すと、自宅ルータのGlobal IPのみならずLocal IPも取得することになります。これを利用して、Local Networkにつながっている各Serverにもいつもどおりアクセスできることになります。つまり、以下のようなSSHが通ります。

~/.ssh/config

Host usb
    HostName 192.168.1.33
    Port 22
    IdentityFile ~/.ssh/usb
    User syui

通常、WAN側からSSHするには、以下のような内容になります。わざわざ自宅のルータIP(Global IP)をHostNameに変更して、ポート転送の設定までしなければなりません。

Host usb
    HostName 1.1.1.1 # Global IP
    Port 22222 # ポート転送のポート番号(22222 -> 192.168.1.33:22)
    IdentityFile ~/.ssh/usb
    User syui

なお、DDNSを利用している場合は別です。DDNSは、例えばルータ(自宅)のGlobal IP(変動する数字)を特定のドメイン名(固定の文字列)に変換します。よって、HostNameにはDDNSを書けばいいだけになります。VPNの設定ファイルでも同じ。

Host usb
    HostName github.com.ddns.syui # DDNS
    Port 22222 # ポート転送のポート番号(22222 -> 192.168.1.33:22)
    IdentityFile ~/.ssh/usb
    User syui

xxx.opvn

- remote 1.1.1.1 1194 udp
+ remote github.com.ddns.syui 22222 udp

しかし、DDNSサービスは有料であることも多いので、私はGlobal IPを使うことが多いです。Global IPの変動は、privateのチャンネルなどを用意し、IPの変動があれば教えるようなcronを実行しておけばいいでしょう。

DDNS

DDNSには例えば以下のようなものがあります。ただ、安全性などは調査していません。ddns.pboehm.deではnameは10日間更新がないと自動削除されます。

https://github.com/pboehm/ddns

https://ddns.pboehm.de/

# example
myowntest.d.pboehm.de

ddns is built around a small webservice, so that you can update your IP address simply by calling an URL periodically through curl. Hosts that haven’t been updated for 10 days will be automatically removed. This can be configured in your own instance.