OpenSSLを使ったOpenVPN構築ガイド

2024年05月15日

TechOpenVPNOpenSSLセキュリティネットワーク自己署名証明書

OpenSSLを利用した中間証明書付きの実用的なOpenVPNサーバの構築方法を解説します。


OpenSSLを使ったOpenVPN構築ガイド

はじめに

OpenSSLを利用した中間証明書ありの実用化できるOpenVPNサーバの構築方法する手順について記載します。また、easyrsaは使用しないで自分で証明書の作成から行っていくため、easyrsaの場合は別のやり方をするほうがいいかもしれません。

※プロトコルやファイルの中身のことについてはあまり詳しく触れませんのでご了承ください

フォルダ・ファイルの作成

まずは必要なディレクトリとファイルを作成します。

cd /opt mkdir -p pki/{RootCA,InterCA}/newcerts mkdir -p pki/{configs,Server,Client} cd pki/RootCA echo "01" > serial echo "00" > crlnumber touch index.txt cd /opt/pki/InterCA echo "01" > serial echo "00" > crlnumber touch index.txt

ここまで出来たら、初期ファイル構成はとりあえずOKです。

OpenSSLのコンフィグファイル作成

次に、OpenSSLの設定ファイルを作成します。

[ ca ] default_ca = CA_default [ CA_default ] dir = ./ certs = $dir/certs crl_dir = $dir/crl database = $dir/index.txt new_certs_dir = $dir/newcerts serial = $dir/serial crlnumber = $dir/crlnumber crl = $dir/crl.pem RANDFILE = $dir/.rand name_opt = ca_default cert_opt = ca_default default_days = 365 default_crl_days= 30 default_bits = 2048 default_md = sha256 preserve = no policy = policy_match [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] default_bits = 2048 default_md = sha256 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca string_mask = nombstr [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [ v3_ca ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ v3_intermediate_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ server ] basicConstraints=CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer [ client ] basicConstraints=CA:FALSE keyUsage = digitalSignature extendedKeyUsage = clientAuth subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer

EC Private key作成スクリプト

以下のスクリプトを使用して、EC Private keyを作成します。

#!/bin/bash # EC Private key作成スクリプト CURVE="prime256v1" if [ $# -lt 2 ]; then echo "Usage: $0 <output_file> <name>" exit 1 fi OUTPUT_FILE=$1 NAME=$2 # Generate EC private key openssl ecparam -genkey -name ${CURVE} | openssl ec -out ${OUTPUT_FILE} -aes256 -passout pass:${NAME}

ルート証明書の作成

ルート証明書を作成するためのスクリプトを用意します。

#!/bin/bash cd /opt/pki/RootCA # Generate Root CA private key openssl genrsa -aes256 -out private/ca.key.pem 4096 # Generate Root CA certificate openssl req -config ../configs/openssl_sign.cnf \ -key private/ca.key.pem \ -new -x509 -days 7300 -sha256 -extensions v3_ca \ -out certs/ca.cert.pem

中間証明書の作成(任意)

セキュリティ強化のために中間証明書を作成します。

#!/bin/bash cd /opt/pki/InterCA # Generate Intermediate CA private key openssl genrsa -aes256 -out private/intermediate.key.pem 4096 # Generate Intermediate CA CSR openssl req -config ../configs/openssl_sign.cnf -new -sha256 \ -key private/intermediate.key.pem \ -out csr/intermediate.csr.pem # Sign Intermediate CA certificate with Root CA cd ../RootCA openssl ca -config ../configs/openssl_sign.cnf -extensions v3_intermediate_ca \ -days 3650 -notext -md sha256 \ -in ../InterCA/csr/intermediate.csr.pem \ -out ../InterCA/certs/intermediate.cert.pem

サーバ証明書の作成

OpenVPNサーバ用の証明書を作成します。

#!/bin/bash cd /opt/pki/Server # Generate Server private key openssl genrsa -out private/server.key.pem 2048 # Generate Server CSR openssl req -config ../configs/openssl_sign.cnf \ -key private/server.key.pem \ -new -sha256 -out csr/server.csr.pem # Sign Server certificate with Intermediate CA cd ../InterCA openssl ca -config ../configs/openssl_sign.cnf -extensions server \ -days 375 -notext -md sha256 \ -in ../Server/csr/server.csr.pem \ -out ../Server/certs/server.cert.pem

クライアント証明書の作成

OpenVPNクライアント用の証明書を作成します。

#!/bin/bash CLIENT_NAME=$1 if [ -z "$CLIENT_NAME" ]; then echo "Usage: $0 <client_name>" exit 1 fi cd /opt/pki/Client # Generate Client private key openssl genrsa -out private/${CLIENT_NAME}.key.pem 2048 # Generate Client CSR openssl req -config ../configs/openssl_sign.cnf \ -key private/${CLIENT_NAME}.key.pem \ -new -sha256 -out csr/${CLIENT_NAME}.csr.pem # Sign Client certificate with Intermediate CA cd ../InterCA openssl ca -config ../configs/openssl_sign.cnf -extensions client \ -days 375 -notext -md sha256 \ -in ../Client/csr/${CLIENT_NAME}.csr.pem \ -out ../Client/certs/${CLIENT_NAME}.cert.pem

証明書の配置

生成した証明書を適切に配置します。

#!/bin/bash # OpenVPN server configuration directory OPENVPN_DIR="/etc/openvpn" # Create necessary directories mkdir -p ${OPENVPN_DIR}/certs mkdir -p ${OPENVPN_DIR}/keys mkdir -p ${OPENVPN_DIR}/client-configs/files # Copy certificates and keys cp /opt/pki/Server/certs/server.cert.pem ${OPENVPN_DIR}/certs/ cp /opt/pki/Server/private/server.key.pem ${OPENVPN_DIR}/keys/ cp /opt/pki/InterCA/certs/intermediate.cert.pem ${OPENVPN_DIR}/certs/ cp /opt/pki/RootCA/certs/ca.cert.pem ${OPENVPN_DIR}/certs/ # Create certificate chain file cat /opt/pki/RootCA/certs/ca.cert.pem /opt/pki/InterCA/certs/intermediate.cert.pem > ${OPENVPN_DIR}/certs/ca-chain.cert.pem # Generate Diffie-Hellman parameters openssl dhparam -out ${OPENVPN_DIR}/dh2048.pem 2048 # Generate TLS authentication key openvpn --genkey --secret ${OPENVPN_DIR}/ta.key

OpenVPN Server設定

サーバーの設定ファイルを作成します。

# OpenVPN Server Configuration port 1194 proto udp dev tun ca /etc/openvpn/certs/ca-chain.cert.pem cert /etc/openvpn/certs/server.cert.pem key /etc/openvpn/keys/server.key.pem dh /etc/openvpn/dh2048.pem tls-auth /etc/openvpn/ta.key 0 server 10.8.0.0 255.255.255.0 ifconfig-pool-persist /etc/openvpn/ipp.txt push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 8.8.4.4" keepalive 10 120 cipher AES-256-CBC auth SHA256 user nobody group nobody persist-key persist-tun status /var/log/openvpn/openvpn-status.log verb 3

OpenVPN Client設定

クライアント設定ファイルのテンプレートを作成します。

# OpenVPN Client Configuration client dev tun proto udp remote your-server-ip-or-domain 1194 resolv-retry infinite nobind persist-key persist-tun remote-cert-tls server cipher AES-256-CBC auth SHA256 key-direction 1 verb 3 <ca> # CA chain certificate will be inserted here </ca> <cert> # Client certificate will be inserted here </cert> <key> # Client private key will be inserted here </key> <tls-auth> # TLS authentication key will be inserted here </tls-auth>

自動化の設定

クライアント設定ファイル生成を自動化するスクリプトを作成します。

#!/bin/bash # First argument is the client name CLIENT_NAME=$1 # Exit if client name is not provided if [ -z "$CLIENT_NAME" ]; then echo "Usage: $0 <client_name>" exit 1 fi # Variables BASE_DIR="/etc/openvpn" OUTPUT_DIR="${BASE_DIR}/client-configs/files" TEMPLATE_FILE="${BASE_DIR}/client-configs/base.conf" CA_CHAIN_FILE="${BASE_DIR}/certs/ca-chain.cert.pem" TA_KEY_FILE="${BASE_DIR}/ta.key" CLIENT_CERT_FILE="/opt/pki/Client/certs/${CLIENT_NAME}.cert.pem" CLIENT_KEY_FILE="/opt/pki/Client/private/${CLIENT_NAME}.key.pem" # Make sure output directory exists mkdir -p ${OUTPUT_DIR} # Generate client config cat ${TEMPLATE_FILE} \ <(echo -e '<ca>') \ ${CA_CHAIN_FILE} \ <(echo -e '</ca>\n<cert>') \ ${CLIENT_CERT_FILE} \ <(echo -e '</cert>\n<key>') \ ${CLIENT_KEY_FILE} \ <(echo -e '</key>\n<tls-auth>') \ ${TA_KEY_FILE} \ <(echo -e '</tls-auth>') \ > ${OUTPUT_DIR}/${CLIENT_NAME}.ovpn echo "Client config file created at: ${OUTPUT_DIR}/${CLIENT_NAME}.ovpn"

これで、OpenSSLを利用した中間証明書付きのOpenVPNサーバの構築が完了です。セキュリティ対策として、定期的に証明書を更新することをお勧めします。