図解！UbuntuでOpenVPNを使う：2. 証明書と認証鍵の作成

# はじめに
[図解！UbuntuでOpenVPNを使う：1. 準備](http://qiita.com/MoriKen/items/7fe17fda8442adb599d9)の続きです．認証局と認証鍵の作成をしていきます^^

![openvpntech_logo.png](https://qiita-image-store.s3.amazonaws.com/0/110138/fd9bca2d-a8e7-a627-e496-5dc62025b06d.png)

# 図解！UbuntuでOpenVPNを使う：目次
1. [準備](http://qiita.com/MoriKen/items/7fe17fda8442adb599d9)
  2. VPNの接続方式
  1. `OpenVPN` のインストール
  2. ファイアウォール設定
  2. VPNサーバ側のルータのグローバルIP確認
  3. ルータからVPNサーバへのポートフォワード設定
2. ***証明書と認証鍵の作成　←　イマココ***
  1. 簡易認証局(`easy-rsa`)関連
  2. VPNサーバ関連
  3. VPNクライアント関連
3. [設定](http://qiita.com/MoriKen/items/75587fd862b3ce93e4eb)
  2. `OpenVPN` サーバ設定
  3. `OpenVPN` クライアント設定
4. [接続確認](http://qiita.com/MoriKen/items/682d31496fd0d2476af7)
  5. `OpenVPN`の起動
  6. 仮想`tun`デバイスの確認
  6. `ping` 確認
  7. `netcat` 確認

# 環境
- VPNサーバ/クライアント共に Ubuntu 14.04
- VPNアプリケーション：OpenVPN 2.3.2 

# 証明書と認証鍵の作成
`VPN`を使うには，セキュリティを担保するためにいくつかの証明書と認証鍵が必要となります．

一気通貫でイメージするなら，下図が大変参考になります．

> ![openvpn](http://image.off-soft.net/sakura/openvpn/openvpn.png)

> - 参考: [SSL 認証 の仕組みと OpenVPN の認証の仕組み](http://server-setting.info/blog/ssl-openvpn-authentication.html)

各鍵と証明書がどのように処理されるのかについての説明は上記サイトに譲り，本エントリでは`OpenVPN`のセッテイングに必要な処理と出力されるファイルに着目して話を進めていきます．なお，ここでの設定ではTLS認証鍵は使用しません．

ここでの手順は下記の通りです．これらの作業は全て***「VPNサーバ」***で実施します．

1. 簡易認証局(`easy-rsa`)関連
  1. 簡易認証局(`easy-rsa`)の作成
  2. `easy-rsa`の環境変数の設定
  3. 認証局証明書/認証鍵の作成
4. VPNサーバ関連
  5. DHパラメータの作成
  5. VPNサーバ証明書/認証鍵の作成
  6. VPNサーバ証明書/認証鍵の移動
4. VPNクライアント関連
  5. VPNクライアント証明書/認証鍵の作成
  6. VPNクライアント証明書/認証鍵の移動
  
順番に見て行きましょう．

以降の作業では`/etc/openvpn/`で作業するので，基本的に管理者権限が必要です．いちいち`sudo`するのが面倒なら，下記のコマンドをしておくと便利です．ただし，作業には注意してください．

```bash:command
$ sudo -i
```

## 簡易認証局(`easy-rsa`)関連

![01_easy-rsa.png](https://qiita-image-store.s3.amazonaws.com/0/110138/40da2c39-1d96-92bc-0617-844d36e24f37.png)

### 簡易認証局(`easy-rsa`)を作成する
```bash:command
$ make-cadir /etc/openvpn/easy-rsa
$ cd /etc/openvpn/easy-rsa
```

これで簡易認証局が出来ました．

### `easy-rsa`の環境変数の設定
認証局に関する情報を入力します．基本的にはデフォルト設定で動くはずです．任意に設定して下さい．

設定ファイルを開きます．

```bash:(command)
$ vim ./vars
```

```bash:vars
export EASY_RSA="`pwd`"                       # 作業ディレクトリ
export KEY_DIR="$EASY_RSA/keys"               # 証明書の出力先
export KEY_SIZE=2048                          # 暗号化キーサイズ

export KEY_COUNTRY="JP"                       # 国
export KEY_PROVINCE="Fukuoka"                 # 都道府県
export KEY_CITY="Kitakyusyu"                  # 市区町村
export KEY_ORG="Kyutech"                      # 組織
export KEY_EMAIL="hogehoge@mail.kyutech.jp"   # メールアドレス
export KEY_OU="Nishida-Lab"                   # 組織単位
```

編集した設定を読み込みます．

```bash:(command)
$ source ./vars
```

### 認証局証明書/認証鍵の作成

```bash:(command)
$ ./pkitool --initca
```

```bash:(output)
Using CA Common Name: Kyutech CA
Generating a 2048 bit RSA private key
..............................................................+++
........................................+++
writing new private key to 'ca.key'
-----
```

これにより，ファイル所有者の関係は下図のような状態となります．

![02_easy_rsa_apear.png](https://qiita-image-store.s3.amazonaws.com/0/110138/0cf35b0c-556d-0518-6ad7-b7145bd0f423.png)


大事な出力ファイルは下記の2つです．

-  `ca.crt`：認証局証明書
  - 概要：VPNサーバ/クライアントが不審者ではないことを確認するための証明書．
  - 所有者：VPNサーバ/クライアント
  - 秘密の有無：有
- `ca.key`：認証局秘密鍵
  - 概要：VPNサーバ/クライアントの証明書を発行するための鍵．
  - 所有者：認証局
  - 秘密の有無：有

これで認証局の準備は完了です．

## VPNサーバ関連
![03_vpn_server_related.png](https://qiita-image-store.s3.amazonaws.com/0/110138/6ebc3b5d-10df-cc37-aaff-31d6e2c52a8d.png)

### DHパラメータの作成
暗号化に必要な乱数パラ江メータを作成します．考案者のDiffie Hellmanにちなみ，DHパラメータと呼ぶようです．

```bash:(command)
$ ./build-dh
```

```bash:(output)
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
...........................................................................+..
以下しばらーく続く
```

ファイル所有者の関係図です．

![04_dhparam.png](https://qiita-image-store.s3.amazonaws.com/0/110138/ffb3c7ed-745e-bc2d-455a-ffdf96da589f.png)


ここで生成されるファイルは以下の通りです．

- `dh2048.pem`：DHパラメータ
  - 概要：鍵交換時に暗号化用乱数を生成するためのパラメータ．
  - 所有者：VPNサーバ
  - 秘密の有無：無

デフォルトの2048bitだと，少し時間がかかります．ひとまずデモで動かすだけなら，1024bitでも良いと思います．

### VPNサーバ証明書/認証鍵の作成
ここでは，名前を指定してVPNサーバになりたいと，認証局にお伺いを立てに行きます．晴れて信頼できると判断されれば，サーバ用の証明証と認証鍵をゲットできるというわけです．

ここでは`easy-rsa`を使っているので，名前さえ書けば通ってしまう出来レースが展開されるのですが笑．

本来認証局は第三者になるべきですよね．でも，今は個人利用の範囲なので，サーバ候補のPC内に認証局を立てて，認証のフローを模擬していることになります．

さて，VPNサーバ名を`mysrv`とします．

```bash:(command)
$ ./pkitool --server mysrv
```

コマンド実行後のファイル所有者の関係図です．
![05_server_auth.png](https://qiita-image-store.s3.amazonaws.com/0/110138/07975220-2b93-7199-0e52-4ad656ac13e3.png)

ここで重要となるファイルは下記の2つです．

- `mysrv.crt`：VPNサーバ証明書
  - 概要：VPNサーバが不審者ではないことを裏付ける証明書．VPNクライアント側で先の`ca.crt`と照合して信頼性を確認する．
  - 所有者：VPNサーバ
  - 秘密の有無：無
- `mysrv.key`：サVPNーバ秘密鍵
  - 概要：VPNサーバ用共通鍵を作成するための鍵．
  - 所有者：VPNサーバ
  - 秘密の有無：有

まだ認証局がVPNサーバ用の証明書と鍵を持っています．役所に行って申請手続きをしたような状態です．

### サーバ証明書/認証鍵の移動
これらのファイルは全て，認証局用のディレクトリである`/etc/openvpn/easy-rsa/keys`に存在します．

今回はVPNサーバが作業するためのディレクトリとして`/etc/openvpn/`を採用するので，こちらにコピーします．VPNサーバ君は証明書完成の連絡を受け，役所にそれを取りに行く、そんなイメージですね．

コピー対象のファイルは下記の通りです．

- `ca.crt`：認証局証明書
- `mysrv.crt`：VPNサーバ証明書
- `mysrv.key`：VPNサーバ秘密鍵
- `dh2048.pem`：DHパラメータ

コピーコマンドです．

```bash:(command)
$ cp ca.crt server.crt server.key dh2048.pem /etc/openvpn
```

こんな形になります．

![06_server_auth_copy.png](https://qiita-image-store.s3.amazonaws.com/0/110138/4be13dc1-d779-a8f2-2883-17ba77e955a8.png)

### VPNクライアント関連
今度はクライアント側の証明書と鍵を取得します．後日VPNサーバが認証局に行き，VPNクライアント増やしたいんですが，と手続きに行く形です．

![07_clientpart.png](https://qiita-image-store.s3.amazonaws.com/0/110138/917d9405-17f8-163c-34a6-daca54231358.png)

#### VPNクライアント証明書/認証鍵の作成
VPNクライアント名を`mycli`とします．

```bash
$ cd /etc/openvpn/easy-rsa
$ source ./vars
$ ./pkitool mycli
```

ここで，特にサーバ側の証明書と認証鍵を要求されないようでした．クライアントファイル下さい！と第三者が申請しても作れてしまうようです．本来なら，サーバ証明書を先に提示して不審者でないことを確認してから，クライアントの証明書を発行するべきプロセスだと思います．

まぁ，`easy-rsa`だから簡易に設定できる方が良いと思いますので，先に進みます．

ここで重要となるファイルは下記の2つです．

- `mycli.crt`：VPNクライアント証明書
  - 概要：VPNクライアントが不審者ではないことを裏付ける証明書．サーバ側で先の`ca.crt`と照合して信頼性を確認する．
  - 所有者：VPNクライアント
  - 秘密の有無：無
- `mycli.key`：VPNクライアント秘密鍵
  - 概要：VPNクライアント用共通鍵を作成するための鍵．
  - 所有者：VPNクライアント
  - 秘密の有無：有

![08_client_auth.png](https://qiita-image-store.s3.amazonaws.com/0/110138/9606de95-c2d3-0e85-17ac-9daece3dd223.png)

#### VPNクライアント証明書/認証鍵の移動
下記のファイルをUSB等でコピーして下さい．秘密ファイルについては取り扱いに注意が必要です．

- `ca.crt`：認証局証明書
- `mycli.crt`：VPNクライアント証明書
- `mycli.key`：VPNクライアント秘密鍵

クライアントでのコピー先はおなじみの`/etc/openvpn/`で良いです．

![01_review.png](https://qiita-image-store.s3.amazonaws.com/0/110138/dc3c12e0-1240-984b-babc-edcbd54912f6.png)

ここまで来れば，以後認証局`easy-rsa`は不要です．直接VPNサーバ/クライアント間で通信をすることとなります．

# おわりに
ここまでで，VPN接続に最低限必要な証明書，認証鍵ファイルの作成が完了しました，

![10_all_files.png](https://qiita-image-store.s3.amazonaws.com/0/110138/34176600-d9bd-8a02-98b3-3ebfd47272e8.png)

ここが`OpenVPN`の一連の作業の中でも，初見で地味に紛らわしい部分かと思います^^;

次回は[図解！UbuntuでOpenVPNを使う：3. 設定](http://qiita.com/MoriKen/items/75587fd862b3ce93e4eb)で実際につなぐための設定をしていきます．

# 参考文献
- [ケイズプロダクション，OpenVPNで構築する超簡単VPN入門，ラトルズ，2006.](http://www.amazon.co.jp/OpenVPN%E3%81%A7%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B%E8%B6%85%E7%B0%A1%E5%8D%98VPN%E5%85%A5%E9%96%80%E2%80%95Windows-Mac-OS-X-Linux%E5%AF%BE%E5%BF%9C/dp/4899771673)
- [OpenVPN を使って仮想LAN接続してみる](http://server-setting.info/centos/openvpn-setting.html)
- [BLOG EX MACHINA, Ubuntu 14.04 で OpenVPN](http://felis-silvestris-catus.hatenablog.com/entry/2015/05/27/222434)
- [Blog on fuketch, OpenVPNの設定（その1：認証用ファイルの生成）](https://fuketch.wordpress.com/2013/02/19/openvpn%E3%81%AE%E8%A8%AD%E5%AE%9A%EF%BC%88%E3%81%9D%E3%81%AE1%EF%BC%9A%E8%AA%8D%E8%A8%BC%E7%94%A8%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E7%94%9F%E6%88%90%EF%BC%89/)
- [How to, OpenVPN.jp](http://www.openvpn.jp/document/how-to/)
- [Fujitsu, 第2回  SSL-VPN の基本動作と実現方法その1(リバースプロキシ), SSL-VPN入門](http://www.fujitsu.com/jp/products/network/security-bandwidth-control-load-balancer/ipcom/material/data/2/2.html)