OpenVPN サーバ構築

OpenVPN環境構築

OpenVPN環境構築手順。サーバ編です。自社向け備忘録兼ねてます。

はじめに

VPN 使ってますか?
私は家庭の都合などもありリモートワークをする事があるのですが、その際に利用しています。
( 会社承認の上、環境構築を実施 )

今回は OpenVPN を利用した VPN サーバ構築について書きます。
テーマとしては今更感もありますが、社内向けの備忘録も兼ねてます。
※触れられる事が少ない設定等に関しても書いたので、既にOpenVPN環境構築済みの場合にも参考になる箇所があるかも。

内容は数年前に書いた社内記事の焼き直しになります。

OpenVPN に関しては以下が詳しいので詳細に関してはこちらを参照して下さい。


写真 : 写真素材ぱくたそ
画像のフォント : 隼文字(Falcon Font)©霧風 隼

導入前に決めておくべき事

認証方式をどうするか

OpenVPN で利用可能な認証方式には大きく4通りあります。

  • 静的鍵(Static Key)
  • 証明書認証
  • ID/パスワード認証(プラグイン認証)
  • 二要素認証(PKCS#12)

それぞれの認証方式の詳細に関しては以下を参考にしてください。

弊社では上記認証方式のうち "証明書認証" を採用しています。( 利用者数が少ないため )
上記参考リンクにもあるように、ある程度までの規模の場合にはバランスの取れた方式だと思います。
当記事は "証明書認証" を利用した場合の構築手順になります。

ルーティング or ブリッジ?

弊社では VPN 接続を行うにあたってはルーティングを利用しています。
通常ルーティングを利用する方がセキュリティ面でも有利ですが、特殊な要件がある場合、ブリッジを採用する必要があるかもしれません。

参考 : 「ルーティング」と「ブリッジ」のどちらを使うか?

サブネットをどうするか?

特に中小規模のネットワークの場合、192.168.0.x/xx, 192.168.1.x/xx のサブネットを利用している場合も多いと思われますが、この場合、OpenVPNサーバ起動時に、以下ログが出力されます。

NOTE: your local LAN uses the extremely common subnet address 192.168.0.x or 192.168.1.x.  Be aware that this might create routing conflicts if you connect to the VPN server from public locations such as internet cafes that use the same subnet.

上記ログは 「192.168.0.x や 192.168.1.x だと インターネットカフェ等のパブリック・ロケーションからだと繋がらないかもよ」 と言っていますが、BCP 対策やリモートワークの手段として VPN 接続を導入する場合、利用者 ( 社員等 ) のネットワーク環境も 192.168.0.x や 192.168.1.x となっている可能性は高いです ( 一般向けのルータのデフォルトサブネット設定が 192.168.0.x や 192.168.1.x のため)。

この場合、VPNサーバを構築してもルーティングの問題で正しく利用できない可能性が出てきます。

こういった場合、

  • 利用者の個々のネットワーク環境をVPN接続可能な形に変更してもらう
    具体的には家庭内LANを構築しているような場合、そのLANのサブネットを VPNサーバ側のLANとは異なるサブネットにすれば問題ありません。
    (例)
    • 社内LAN 192.168.0.1/24
    • 家庭内LAN 192.168.2.1/24
    利用者が皆ある程度のコンピュータ/ネットワークに関する知識を有している場合、この形式でも大丈夫かと思われますが、この可能性は低いのではないかと思われます。
  • VPN側のサブネットを変更する
    上述のように個々の利用者がネットワーク設定を変更できるかどうか不明な場合、利用者のサブネットとバッティングしないように変更する事を検討すべきでしょう。
    既に運用中のネットワークの設定を変更する場合、それなりのリスクがあると思いますが、IPベースではなく、LAN内でもホストネームベースでの運用が行える環境になっていれば、変更のリスクはあまりないのではないかと思われます。
    それぞれのリスク・運用負荷等も踏まえて、導入前にきちんとネットワーク設計は行っておきましょう。

環境

環境は以下になります。

OS CentOS release 6.7
OpenVPN openvpn-2.3.8-1

ネットワーク構成

ネットワーク構成 ( 概要 ) は図のようになります。
OpenVPNサーバが接続されるLANのサブネットは 192.168.x.x/24 としています。
導入する環境に併せて適宜読み替えて下さい。

OpneVPN Network

インストール手順

インストール手順を示します。

epel リポジトリ登録

epel リポジトリを登録していない場合、登録します。

# rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm

yum update もしておきます。

# yum update

OpenVPN インストール

  1. yum を利用して openvpn をインストールします。
    # yum install openvpn
    
  2. easy-rsa を入手し、/etc/openvpn 以下にコピーします (2.3 から同梱されなくなったらしい)。
    以下は /tmp を展開先として作業したものとして書いています。

    ※現状 easy-rsa は3になっています、が、ここで説明するのは easy-rsa2 での方法になります。

    easy-rsa は GitHub上 で公開されています。

    リリース版のアーカイブは Releases ページから取得できます。

    # cd /tmp
    # wget https://github.com/OpenVPN/easy-rsa/releases/download/2.2.2/EasyRSA-2.2.2.tgz
    # tar xvzf EasyRSA-2.2.2.tgz
    # cp EasyRSA-2.2.2 /etc/openvpn/easy-rsa -r
    

CA証明書と鍵の作成

CA証明書と鍵を作成します。

  1. 先に作成した easy-rsa のディレクトリに移動します。
    # cd /etc/openvpn/easy-rsa/
    
  2. 環境変数を編集します。編集前に必要に応じてバックアップを作成しておきましょう。
    # vi vars
    

    以下を編集します。 ( 抜粋 )

    export KEY_COUNTRY="JP" # 国名
    export KEY_PROVINCE="Tokyo" # 都道府県名
    export KEY_CITY="Bunkyo-ku" # 市区町村名
    export KEY_ORG="agilegroup.co.jp" # 組織名
    export KEY_EMAIL="xxxxxxxx@agilegroup.co.jp" # メールアドレス(管理者)
    export KEY_OU = "" # 部署名(必要に応じ)
    

    ※KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, KEY_EMAIL は設定必須

    RSA鍵のサイズも var ファイルで設定可能です。
    easy-rsa2 では 2048 で設定されています。セキュリティレベルを上げるために4096に増やしてもよいでしょう。

    # Increase this to 2048 if you
    # are paranoid.  This will slow
    # down TLS negotiation performance
    # as well as the one-time DH parms
    # generation process.
    export KEY_SIZE=2048
    
  3. 環境変数をシステムに反映します。
    # source vars
    

    反映されたかどうかは以下で確認できます。

    # env | grep KEY
    ( 中略 )
    KEY_EMAIL=xxxxxxxx@agilegroup.co.jp
    KEY_OU=
    ( 中略 )
    
  4. CA証明書と鍵を作成します。
    # ./clean-all
    # ./build-ca
    

    いくつか返答を要求されますが、基本改行で返答します ( 上記設定が反映されている事 )。

  5. ca.crt ( ルートCA の証明書 ) と ca.key ( ルートCA の鍵 ) が生成されるので、CA証明書を OpenVPN 設定ディレクトリへコピーします。
    # cp keys/ca.crt /etc/openvpn
    

サーバ証明書と秘密鍵の作成

  1. サーバ証明書と秘密鍵を作成します。
    # ./build-key-server server
    

    以下に関して y を応答。それ以外はリターンで応答します。

    Sign the certificate? [y/n]:y # y で応答
    1 out of 1 certificate requests certified, commit? [y/n]y # y で応答
    
  2. 作成された証明書と秘密鍵を OpenVPN 設定ディレクトリへコピーします。
    # cp keys/server.crt /etc/openvpn
    # cp keys/server.key /etc/openvpn
    

※ここで作成した証明書、及び、秘密鍵に関しては、先日書いた SSL/TLS証明書の作成手順 (2015) にある確認手順と同じ方法で確認可能です。
RSA鍵長やSignature Algorithm等に問題がないか確認してみるとよいでしょう。

DHパラメータ生成

  1. DHパラメータを生成します。
    # ./build-dh
    
  2. 生成されたDHパラメータを OpenVPN設定ディレクトリへコピーします。
    # cp keys/dh2048.pem /etc/openvpn
    

証明書廃止リスト作成

利用しなくなったり、期限が切れたクライアント証明書を廃止できるようにするため、証明書廃止リストを作成します。

※証明書廃止リストは、実際にクライアント証明書を作成してから廃止を行わないと作成できないので、ダミーのクライアント証明書をいったん作成&廃止することにより作成。

  1. ダミーのクライアント証明書を作成します。
    # ./build-key dummy
    

    以下に関して y 応答。それ以外はリターンで応答します。

    Sign the certificate? [y/n]:y # y で応答
    1 out of 1 certificate requests certified, commit? [y/n]y # y で応答
    
  2. 上で作成したクライアント証明書を廃止します。
    # ./revoke-full dummy
    
  3. 証明書廃止リストを OpenVPN 設定ファイル格納ディレクトリへコピーします。
    # cp keys/crl.pem /etc/openvpn
    

OpenVPN 設定

昨年来からのOpenSSL関連の脆弱性 (Logjam や FREAK等) の影響を OpenVPN もある程度受けていますが、tls-auth を有効にしていれば、これら問題は回避できるとの事でした。
OpenVPNサーバを構築する場合、tls-auth は有効にするのをお勧めします。
tls-auth を有効にする場合、共有静的鍵の生成と tls-auth を利用する設定を行えばOKです。

※共有静的鍵はサーバ/クライアントの両方で必要になります。

参考 : Openvpn23ManPage

  1. 共有静的鍵を OpenVPN 設定ファイル格納ディレクトリへ作成します
    # openvpn --genkey --secret /etc/openvpn/ta.key
    
  2. OpenVPN設定ファイルをサンプルよりコピーします。
    # cp /usr/share/doc/openvpn-2.3.8/sample/sample-config-files/server.conf /etc/openvpn/
    
  3. 設定を編集します。
    # vi /etc/openvpn/server.conf
    

    以下内容で編集します。( 抜粋 )

    ※必要に応じてポート番号は変更して下さい。

    port 1194  # UDP 1194番ポートを利用
    proto udp
    dev tun  # tunを指定
    ca ca.crt       # 以下生成したファイル名と同じか確認
    cert server.crt
    key server.key
    dh dh2048.pem
    server 10.8.0.0 255.255.255.0 # VPNクライアントの割当てアドレス範囲
    ;push "route 192.168.20.0 255.255.255.0"
    push "route 192.168.x.0 255.255.255.0" # 192.168.x.0/24 へのルーティング設定追加
    tls-auth ta.key 0 # This file is secret # アンコメント(TLS認証有効化)
    max-clients 5  # 接続数の上限で設定
    user nobody # アンコメント
    group nobody # アンコメント
    log-append  /var/log/openvpn.log # ログファイルの設定
    crl-verify crl.pem # 証明書廃止リスト設定追加
    

よりセキュアな設定

よりセキュアにしたい場合、以下設定も行うとよいでしょう。
但しクライアントによっては、これら設定をサポートしない可能性もあるので、運用可能かどうかも含めて検討して下さい。

cipher AES-256-CBC  # 暗号化指定。デフォルトはBF-CBC
auth SHA256 # デフォルトはSHA1
tls-cipher  DEFAULT:!EXP:!LOW:!PSK:!SRP:!kRSA  # TLSのCipher設定

上記設定は既存のOpenVPNサーバ設定に対して行う事も可能です。
クライアント側にも適切な変更を施せば新たな暗号化、Cipher設定でVPN接続する事が可能になります。

設定が想定通りに行えたかどうかは、OpenVPN クライアント側の接続ログで確認できます。
上記設定を施した場合、接続時のログが以下のようになります。(抜粋)

Fri Dec XX xx:xx:xx 2015 Outgoing Control Channel Authentication: Using 256 bit message hash 'SHA256' for HMAC authentication
Fri Dec XX xx:xx:xx 2015 Incoming Control Channel Authentication: Using 256 bit message hash 'SHA256' for HMAC authentication
Fri Dec XX xx:xx:xx 2015 Data Channel Encrypt: Cipher 'AES-256-CBC' initialized with 256 bit key
Fri Dec XX xx:xx:xx 2015 Data Channel Encrypt: Using 256 bit message hash 'SHA256' for HMAC authentication
Fri Dec XX xx:xx:xx 2015 Data Channel Decrypt: Cipher 'AES-256-CBC' initialized with 256 bit key
Fri Dec XX xx:xx:xx 2015 Data Channel Decrypt: Using 256 bit message hash 'SHA256' for HMAC authentication

興味がある方は、変更前後のログを比較してみてください。

※cipher、及び、auth 設定に関してはクライアント側にも同じ記載が必要

※tls-cipher 設定では、FREAKで話題になった輸出グレードや弱い暗号設定を無効に

※利用可能な cipher, auth, tls-cipher の値はそれぞれ以下で確認可能

$ openvpn --show-ciphers
$ openvpn --show-digests
$ openvpn --show-tls

※2.3.3で有効になった(はずの) tls-version-min 指定は弊社環境では正しく機能しなかった。
参考 : OpenVPN 2.3.4 client fails when server uses tls-version-minimum 1.2 when 2.3.3 works fine

ログローテート設定

ログローテートのための設定を行います。

# vi /etc/logrotate.d/openvpn

以下内容で編集する。

/var/log/openvpn.log {
    missingok
    notifempty
    sharedscripts
    postrotate
    /etc/rc.d/init.d/openvpn restart 2>&1 > /dev/null || true
    endscript
}

スタートアップ / シャットダウン スクリプトの作成

/etc/openvpn/openvpn-startup、及び、/etc/openvpn/openvpn-shutdown を用意しておくと、それぞれ、サービス起動・終了時に実行されます。

ここにVPN用ファイアウォール設定/解除処理を記述します。

※ファイアウォールの設定は要件に従って適切に設定して下さい。
以下の例では Windows のリモートデスクトップ(3389番ポート)でのアクセスを許可するようにしています。
不用意にアクセスを許可した場合情報漏えい等のリスクを高める可能性があります。

参考 : VPNサーバー構築(OpenVPN)

openvpn-startup

# vi /etc/openvpn/openvpn-startup

以下内容で編集します。

#!/bin/bash

/etc/openvpn/openvpn-shutdown
iptables -I OUTPUT -o tun+ -j ACCEPT
iptables -I FORWARD -o tun+ -j ACCEPT
# VPNクライアントからLANへのアクセスを許可(Remote-Desktop)
iptables -I FORWARD -i tun+ -d 192.168.x.0/24 -p tcp --dport 3389 -j ACCEPT

openvpn-shutdown

# vi /etc/openvpn/openvpn-shutdown

以下内容で編集します。

#!/bin/bash

delete() {
    rule_number=`iptables -L $target --line-numbers -n -v|grep tun.|awk '{print $1}'|sort -r`
    for num in $rule_number
    do
        iptables -D $target $num
    done
}

# OpenVPN用ルールの削除
target='INPUT'
delete
target='FORWARD'
delete
target='OUTPUT'
delete

OpenVPN サーバ起動

設定が完了したらOpenVPNサーバを起動します。自動起動設定は適宜行ってください。

# /etc/rc.d/init.d/openvpn start

自動起動させる場合

# chkconfig openvpn on

ネットワーク設定

VPNサーバが無事に動作したら、外部からアクセス可能となるようにネットワーク設定を行います。
通常は WAN と LAN の間にあるルータの設定を行う事になります。

この部分の設定は利用しているルータによって異なります。
利用している機器の設定方法に従って適切な設定を行ってください。
 

まとめ

OpenVPNのサーバ側設定に関して記載しました。
クライアント側の設定に関してはこちら -> OpenVPN クライアント設定