OpenVPN構築メモ

[基本的なOpenVPNの構築手順](https://qiita.com/makisyu/items/2ac579c0e169970b1609)を書いてから1年以上経って、状況が少し変わってきているので追記することにした。

#インストール
RPMを作るのが相変わらず推奨されているが、FedoraなどUpstreamへの追従が早いディストリビューションの場合、そのディストリビューションのリポジトリにあるパッケージで問題ないと思う。Fedoraの場合はsystemdのUnitファイルも置いてくれるので、ディストリビューションリポジトリのパッケージを使うと楽。

なのだが、systemdのtemplateという機能を使っているので注意。

[systemd: Template unit files](https://fedoramagazine.org/systemd-template-unit-files/)

便利っちゃー便利なんだけど、タイプ量が増えてつらい。

# Easy RSA
1年前はなんともβ感のあったEasy RSAスクリプト群だが、最近はすっかり定位置に付いている。ディストリビューションパッケージでの提供もあり、 `dnf install easy-rsa` などでインストールできる。 `/usr/share/easy-rsa` 下に配置されるのだが、知らないとインストールしてもコマンドが使えないというハイパー不親切設計。なお `find` で検索した模様。

証明書の作成設定ファイルが必要なので、証明書を作るディレクトリに`/usr/share/easy-rsa/3/openssl-1.0.cnf`と`/usr/share/easy-rsa/3/x509-types`をコピーしておく。cnfに書く内容はオプションでも指定できるし、必要なら`easyrsa`がプロンプトで聞いてくる。

# ECC
OpenVPN 2.4からは楕円曲線暗号がエモい。是非使おう。

`easyrsa help options`で設定方法が出てくる。`help`をよく読まないとこのヘルプコマンド自体を見落とす。

```
/usr/share/easy-rsa/3/easyrsa help options

Easy-RSA Global Option Flags

The following options may be provided before the command. Options specified
at runtime override env-vars and any 'vars' file in use. Unless noted,
non-empty values to options are mandatory.

General options:

--batch         : set automatic (no-prompts when possible) mode
--pki-dir=DIR   : declares the PKI directory
--vars=FILE     : define a specific 'vars' file to use for Easy-RSA config

Certificate & Request options: (these impact cert/req field values)

--days=#        : sets the signing validity to the specified number of days
--digest=ALG    : digest to use in the requests & certificates
--dn-mode=MODE  : DN mode to use (cn_only or org)
--keysize=#     : size in bits of keypair to generate
--req-cn=NAME   : default CN to use
--subca-len=#   : path length of signed sub-CA certs; must be >= 0 if used
--subject-alt-name : Add a subjectAltName. For more info and syntax, see:
                     ./easyrsa help altname
--use-algo=ALG  : crypto alg to use: choose rsa (default) or ec
--curve=NAME    : for elliptic curve, sets the named curve to use

Organizational DN options: (only used with the 'org' DN mode)
  (values may be blank for org DN options)

--req-c=CC        : country code (2-letters)
--req-st=NAME     : State/Province
--req-city=NAME   : City/Locality
--req-org=NAME    : Organization
--req-email=NAME  : Email addresses
--req-ou=NAME     : Organizational Unit

Deprecated features:

--ns-cert=YESNO       : yes or no to including deprecated NS extensions
--ns-comment=COMMENT  : NS comment to include (value may be blank)
```

`--use-algo=ec`とすればいいのはわかるが、肝心の曲線を選ぶ`--curve`に何を設定すればいいのか分からない。こういうところはいつものOpenVPNのノリで、まったく使わせる気がない。ここでの正解は「OpenVPNに聞く」で、なぜならOpenVPNが使うSSLライブラリがOpenSSLかLibreSSLかによって対応している曲線とその名前が異なることがあるかららしい。あー辛ぇ……。

```
openvpn --show-curves
Available Elliptic curves:
secp224r1
secp256k1
secp384r1
secp521r1
prime256v1
```

どれを選ぶかは信仰がDJB教かOpen教か、あるいはその信心の度合いよって異なるが、とりあえず一番下を選んでおけばいいんでねーのか。よってコマンドは以下のようになる。`build-ca`や`build-client-full`の時にも共通してこのオプションを与えればOK。

`easyrsa --use-algo=ec --curve=prime256v1 build-server-full`

ちなみにDJB氏による楕円曲線の選び方講座がこちら:

[2014.03.23: How to design an elliptic-curve signature system](http://blog.cr.yp.to/20140323-ecdsa.html)

えこれ読む奴いるの?誰も読まねーだろ?って思った僕とかのために、DJBさんが親切に選んでくれたよ!!!

[SafeCurves: choosing safe curves for elliptic-curve cryptography](http://safecurves.cr.yp.to)

なるほどわからん。

# クライアント設定
v2.4から挙動が異なるらしいので、使用するブロック暗号を明示的に指定。あとサーバー証明書の検証を設定。

```
cipher AES-256-GCM
ncp-ciphers AES-256-GCM
remote-cert-tls server
```

サーバー側の設定ファイルサンプルには「v2.4からこれがデフォで使われるから古いクライアントがいる奴は注意な」ってコメントが書いてある。クライアントが古いと安全性の低い暗号にフォールバックするか、フォールバック先がサーバー側で許可されていなくて接続エラーになるだろうと思う。