月 5 ドルくらいで Docker で簡単に OpenVPN 環境を手に入れる

# 月 5 ドルくらいで Docker で簡単に OpenVPN 環境を手に入れる

DigitalOcean はとても安い感じでサーバーを使わせてくれます．
しかも学生なら GitHub Student Developer Pack から $100 もらえるので，20ヶ月くらい無料でサーバーを使えます．
多くの企業や大学ではポートが制限されていたり，検閲があったりするので VPN は便利です．
さらに野良 AP などに接続する時でも，VPN 環境では安心感があります．
また，CoreOS は始めから Docker が使えるので簡単で OS 自体が小さいので安全っぽい感じがあります．

ここでは DigitalOcean と CoreOS を使って，簡単に全てのトラフィックを VPN に通す OpenVPN 環境を手に入れます．
Ubuntuなどでセットアップを行いたい場合は，適当にセットアップして 5 からスタートしてください．

最後に注意があるので必ず目を通してください．

## 1. DigitalOcean のアクセストークンを取得する．
アカウントを登録してアクセストークンを取得します．

``` sh
export DIGITALOCEAN_ACCESS_TOKEN=TOTTATOKEN
```

## 2. ssh の公開鍵を DigitalOcean に登録して ID をとる．
DigitalOcean の 設定から クライアント側の ssh の公開鍵を登録します．
以下のコマンドでその公開鍵の ID を取得します．これは後で使います．

``` sh
curl --request GET "https://api.digitalocean.com/v2/account/keys" \
     --header "Authorization: Bearer $DIGITALOCEAN_ACCESS_TOKEN"
```

## 3. cloud-config.yaml で最低限の設定と iptables を定義しておく
CoreOS は `iptables` 以外の方法で，FW を設定することを薦めています（AWS の FW など）．
大丈夫そうですが `iptables` を設定しておきます．
地味に一行目のコメントを入れないと怒られるので注意です．

``` yaml
#cloud-config

coreos:
  units:
    - name: docker.service
      command: start
    - name: timezone.service
      command: start
      content: |
        [Unit]
        Description=timezone
        [Service]
        Type=oneshot
        RemainAfterExit=yes
        ExecStart=/usr/bin/ln -sf ../usr/share/zoneinfo/Japan /etc/localtime
    - name: iptables-restore.service
      enable: true
write_files:
  - path: /var/lib/iptables/rules-save
    permissions: 0644
    owner: 'root:root'
    content: |
      *filter
      :INPUT DROP [0:0]
      :FORWARD DROP [0:0]
      :OUTPUT ACCEPT [0:0]
      -A INPUT -i lo -j ACCEPT
      -A INPUT -i eth1 -j ACCEPT
      -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
      -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
      -A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
      -A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT
      -A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT
      COMMIT
```

## 4. Droplet を作る．
DigitalOcean は Droplet を保持している間だけお金を取られます．
以下のコマンドを実行した時点でお金がかかり始めます．

アメリカの IP を使えた方が色々便利なので，アメリカに作る（人によります）．
サンフランシスコの方がニューヨークより近い感じがするのでサンフランシスコで．
（実際に ping が 70 くらい違ったので少し近そうです）

`/path/to/cloud-config.yaml`には 3 で作成したファイルのパスを入れる．
`ssh_keys` は DigitalOcean に登録した ssh の公開鍵を使う（さっき取ったIDを入れる）．

``` sh
curl --request POST "https://api.digitalocean.com/v2/droplets" \
     --header "Content-Type: application/json" \
     --header "Authorization: Bearer $DIGITALOCEAN_ACCESS_TOKEN" \
     --data '{"region":"'sfo1'",
        "image":"coreos-stable",
        "size":"'"512mb"'",
        "user_data": "'"$(cat /path/to/cloud-config.yaml)"'",
        "ssh_keys":["'"SAKKITOTTAID"'"],
        "name":"KAKKOIISERVERNAME"}'
```

## 5. サーバーでドカドカする
ここからのコマンドは以下のリポジトリから取ってきた物で，URL 先に詳細が書いてあります．
ありがたく使わせていただきます．
https://github.com/kylemanna/docker-openvpn
`README.md`に色々書かれているので，よく読みます．

作成した Droplet に ssh `ssh core@$IP`でアクセスして，以下のコマンドを実行していきます．
CLIENTNAME には好きなクライアントの名前を入れる．
VPN.SERVERNAME.COM にはそのサーバーのドメインを入れる（IP で指定してもいいけど，おすすめしないらしいです）．

``` sh
# データコンテナの名前（好きなので良い）
export OVPN_DATA='ovpn-data'

docker run --name $OVPN_DATA -v /etc/openvpn busybox
docker run --volumes-from $OVPN_DATA --rm kylemanna/openvpn ovpn_genconfig -u tcp://VPN.SERVERNAME.COM:443
docker run --volumes-from $OVPN_DATA --rm -it kylemanna/openvpn ovpn_initpki
docker run --volumes-from $OVPN_DATA -d -p 443:1194/tcp --cap-add=NET_ADMIN kylemanna/openvpn
docker run --volumes-from $OVPN_DATA --rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass
docker run --volumes-from $OVPN_DATA --rm kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
```

パスフレーズなどを聞かれるので，よしなにする．
（一部の環境では OpenVPN のポートすら制限されているかもしれないので HTTPS 443 のポートを使わせていただく．）

## 6. CLIENTNAME.ovpn を sftp などしてクライアントにダウンロード
`sftp core@$IP`でログインして，`get CLIENTNAME.ovpn` します．

## 7. クライアントで `sudo openvpn --config CLIENTNAME.ovpn` を実行して気持ちよくなる．
クライアント側の OS や ツール などはたぶん何でも良いです．
今回は `brew install openvpn`でインストールした物を使った．
IPが変わっていれば気持ちいい．
（名前解決できない感じがした場合は，パブリックな DNS `8.8.8.8` などを使ってください）

## 諸注意
1. この記事では，このリポジトリ https://github.com/kylemanna/docker-openvpn を使用しています．
2. 作者が作成した解説記事があります． https://www.digitalocean.com/community/tutorials/how-to-run-openvpn-in-a-docker-container-on-ubuntu-14-04?utm_source=githubreadme
3. リポジトリのページには How does it work? や Security Discussion があります．目を通しましょう．
4. 今回作成したサイズの Droplet では月 1TB までが料金の範囲内です．範囲を超えると通信料に応じて料金が発生します．
5. DigitalOcean は Droplet を放棄しない限り料金が発生し続けます．