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.