このチュートリアルでは、 OpenConnect VPNサーバー(ocserv)で証明書認証を設定する方法を説明します。 Debian / Ubuntu / CentOS/RHELで。 OpenConnect(ocserv)は、CiscoAnyConnectVPNプロトコルのオープンソース実装です。
前回の記事では、Let’sEncryptTLSサーバー証明書を使用してOpenConnectVPNサーバーをセットアップする手順について説明しました。 Let's Encryptはクライアント証明書を発行しないため、その記事ではパスワード認証を使用しました。毎回ユーザー名とパスワードを入力するのは面倒な場合があります。特に、iOSのCiscoAnyConnectアプリなどのクライアントソフトウェアにパスワードを記憶するオプションがない場合はなおさらです。多くのOpenConnectクライアントソフトウェアはユーザー証明書をインポートできます。これにより、ユーザーはユーザー名とパスワードを入力できなくなります。証明書認証は、パスワード認証よりも安全です。
要件
このチュートリアルに従うために、Let’sEncryptTLSサーバー証明書を使用してOpenConnectVPNサーバーを既にセットアップしていることを前提としています。そうでない場合は、次のチュートリアルのいずれかに従ってください。
- Let’sEncryptを使用してUbuntu20.04でOpenConnectVPNサーバー(ocserv)をセットアップする
- Let’sEncryptを使用してDebian11BullseyeにOpenConnectVPNサーバー(ocserv)をセットアップする
- Let’sEncryptを使用してCentOS8 / RHEL8にOpenConnectVPNサーバー(ocserv)をセットアップする
クライアント証明書に署名するために、独自のCA(認証局)を設定します。 ocserv
デーモンは、Let’s Encryptによって発行されたTLSサーバー証明書を引き続き使用する必要があるため、クライアントソフトウェアはセキュリティ警告を表示しません。
独自のCA(認証局)の設定
証明書認証を使用したいのですが、Let’s Encryptはクライアント証明書を発行しないため、独自のCAを作成する必要があります。 openssl
を使用できます 仕事をするために、しかしocservはGnuTLSを推奨しているので、GnuTLSの使い方を紹介します。
gnutls-bin
をインストールします Debian/Ubuntuサーバー上のパッケージ。
sudo apt install gnutls-bin
gnutls-utils
をインストールします CentOS/RHELのパッケージ。
sudo dnf install gnutls-utils
/etc/ocserv/
にサブディレクトリを作成します 秘密鍵と証明書を保持します。
sudo mkdir /etc/ocserv/ssl/
作業ディレクトリを変更します。
cd /etc/ocserv/ssl/
certtool
を使用してCAの秘密鍵を生成します gnutls-bin
によって提供されるコマンド またはgnutls-utils
パッケージ。デフォルトでは、3072ビットのRSAキーが生成されます。これで十分です。
sudo certtool --generate-privkey --outfile ca-privkey.pem
CA証明書を生成する前に、CA証明書テンプレートファイルを作成しましょう。テンプレートファイルの形式は、certtoolのマニュアル(man certtool
)に記載されています。 。
sudo nano ca-cert.cfg
次の行をファイルに追加します。プレースホルダーを適切な値に置き換えます。
# X.509 Certificate options # The organization of the subject. organization = "vpn.example.com" # The common name of the certificate owner. cn = "Example CA" # The serial number of the certificate. serial = 001 # In how many days, counting from today, this certificate will expire. Use -1 if there is no expiration date. expiration_days = -1 # Whether this is a CA certificate or not ca # Whether this certificate will be used to sign data signing_key # Whether this key will be used to sign other certificates. cert_signing_key # Whether this key will be used to sign CRLs. crl_signing_key
ファイルを保存して閉じます。次に、テンプレートファイルの構成を使用してCA証明書を生成します。
sudo certtool --generate-self-signed --load-privkey ca-privkey.pem --template ca-cert.cfg --outfile ca-cert.pem
これで、CA証明書ファイル(ca-cert.pem
)ができました。 。
クライアント証明書の生成
次に、次のコマンドを実行して、クライアントの秘密鍵を生成します。
sudo certtool --generate-privkey --outfile client-privkey.pem
クライアント証明書テンプレートファイルを作成します。
sudo nano client-cert.cfg
次の行をファイルに追加します。 uidは、/etc/ocserv/ocpasswd
のユーザー名である必要があります ファイル。
# X.509 Certificate options # The organization of the subject. organization = "vpn.example.com" # The common name of the certificate owner. cn = "John Doe" # A user id of the certificate owner. uid = "username" # In how many days, counting from today, this certificate will expire. Use -1 if there is no expiration date. expiration_days = 3650 # Whether this certificate will be used for a TLS server tls_www_client # Whether this certificate will be used to sign data signing_key # Whether this certificate will be used to encrypt data (needed # in TLS RSA ciphersuites). Note that it is preferred to use different # keys for encryption and signing. encryption_key
ファイルを保存して閉じます。次に、次のコマンドを実行して、CA秘密鍵によって署名されるクライアント証明書を生成します。
sudo certtool --generate-certificate --load-privkey client-privkey.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-privkey.pem --template client-cert.cfg --outfile client-cert.pem
PINで保護されているPKCS#12ファイルで、クライアントの秘密鍵と証明書を組み合わせます。
sudo certtool --to-p12 --load-privkey client-privkey.pem --load-certificate client-cert.pem --pkcs-cipher aes-256 --outfile client.p12 --outder>
これで、クライアントの秘密鍵と証明書が1つのファイルclient.p12
に結合されました。 。
iOSのCisoAnyConnectアプリは、AES-256暗号をサポートしていないことに注意してください。クライアント証明書のインポートを拒否します。ユーザーがiOSデバイスを使用している場合は、3des-pkcs12
を選択できます 暗号。
sudo certtool --to-p12 --load-privkey client-privkey.pem --load-certificate client-cert.pem --pkcs-cipher 3des-pkcs12 --outfile ios-client.p12 --outder
クライアントの秘密鍵と証明書を1つのファイルにまとめたios-client.p12
。
証明書署名要求
この手順は、複数のVPNユーザーがいて、ユーザーが自分の秘密鍵を使用したい場合にのみ必要です。
エンドユーザーの秘密鍵を秘密に保つために、ユーザーは自分の秘密鍵を使用して証明書署名要求(CSR)を生成し、証明書要求を管理者に送信して、管理者がクライアント証明書をユーザーに発行できます。まず、上記のコマンドを使用して秘密鍵とクライアント証明書テンプレートを生成する必要があります。次に、次のコマンドを使用してCSRを生成します。 request.pem
ファイルはユーザーの秘密鍵によって署名されています。
certtool --generate-request --load-privkey client-privkey.pem --template client-cert.cfg --outfile request.pem
次に、ユーザーはrequest.pem
を送信します およびclient-cert.cfg
管理者へのファイル。管理者は次のコマンドを実行してクライアント証明書を生成します。
sudo certtool --generate-certificate --load-ca-certificate ca-cert.pem --load-ca-privkey ca-privkey.pem --load-request request.pem --template client-cert.cfg --outfile client-cert.pem
その後、管理者はclient-cert.pem
を送信します ユーザーへの証明書ファイル。
ocservデーモンでの証明書認証の有効化
ocserv構成ファイルを編集します。
sudo nano /etc/ocserv/ocserv.conf
前のチュートリアルでは、パスワード認証を有効にするために次の行を追加しました。
auth = "plain[passwd=/etc/ocserv/ocpasswd]"
証明書認証を有効にするには、次の行のコメントを解除します。
auth = "certificate"
上記の2行が両方ともコメント化されていない場合、ユーザーはパスワード認証と証明書認証の両方に合格する必要があることを意味します。したがって、証明書認証でIDを証明するのに十分な場合は、最初の行をコメントアウトしてください。
ユーザーが証明書認証またはパスワード認証のいずれかを選択できるようにする場合は、代わりに次の行を使用する必要があります。
enable-auth = "plain[passwd=/etc/ocserv/ocpasswd]" auth = "certificate"
次に、ca-certパラメーターを見つけます。 Debian / Ubuntuでは、次のように設定されています
ca-cert = /etc/ssl/certs/ssl-cert-snakeoil.pem
CentOS 8 / RHEL 8では、次のように設定されています
ca-cert = /etc/ocserv/ca.pem
クライアント証明書を確認するには、独自のCA証明書を使用する必要があるため、この行を
に変更します。ca-cert = /etc/ocserv/ssl/ca-cert.pem
次に、次の行を見つけます。
cert-user-oid = 0.9.2342.19200300.100.1.1
変更する必要はありません。 0.9.2342.19200300.100.1.1
クライアント証明書に提出されたUIDを表します。上記の行はocserv
を示しています クライアント証明書のUIDフィールドからユーザー名を見つけるデーモン。クライアント証明書がCA証明書とocserv
によって正常に検証された場合 デーモンは、/etc/ocserv/ocpasswd
で一致するユーザー名を見つけることができます ファイルを作成すると、クライアントはログインできます。
ファイルを保存して閉じます。次に、ocservを再起動します。
sudo systemctl restart ocserv
Debian / Ubuntu / CentOS/RHELデスクトップでの証明書認証の使用
scp
を使用する client.p12
をダウンロードするコマンド ファイルをDebian/Ubuntu / CentOS/RHELデスクトップに保存します。
scp [email protected]:/etc/ocserv/ssl/client.p12 ~
次に、openconnect
をインストールします クライアントソフトウェア。
Debian / Ubuntu:
sudo apt install openconnect
CentOS / RHEL:
sudo dnf install epel-release sudo dnf install openconnect
証明書認証を使用するには、
を実行しますsudo openconnect -b vpn.example.com -c client.p12
このチュートリアルで設定したパスフレーズを使用して、クライアントの秘密鍵のロックを解除するように求められます。
パスフレーズが正しく入力されていれば、VPNサーバーに接続されているはずです。
WindowsおよびMacOSデスクトップでの証明書認証の使用
OpenConnectGUIGithubページからWindowまたはMacOS用のOpenConnectGUIクライアントをダウンロードします。次に、新しいVPN接続プロファイルを作成し、PKCS#12ファイルをユーザー証明書フィールドにインポートします。 [保存]ボタンをクリックします。秘密鍵のロックを解除するには、PINを入力する必要があります。インポートすると、ユーザー名とパスワードを入力する必要がなくなります。
iOSデバイスでの証明書認証の使用
iOSユーザーは、CiscoAnyConnectアプリを使用できます。 AnyConnectアプリにクライアント証明書をインポートするには、最初にPKCS#12ファイルを添付ファイルの電子メールアドレスに送信できます。次に、iOSでメールアプリを開きます。添付ファイルを数秒タップして、AnyConnectと共有します。次に、PINを入力してファイルをインポートします。
インポートしたら、AnyConnectでVPN接続を編集します。 Advanced
に移動します ->Certificate
クライアント証明書を選択します。設定を保存します。
これで、iOSデバイスでユーザー名とパスワードを入力する必要がなくなりました。 Cisco AnyConnectアプリはユーザ名とパスワードを記憶しないため、パスワード認証モードでは、電話機が使用されていないときにVPN接続が切断されます。証明書認証モードでは、接続が切断された場合、アプリはVPNサーバーに自動的に再接続します。
iOS上のAnyConnectクライアントの問題
iOS上のAnyConnectクライアントの最新バージョンでは、TLS1.3プロトコルで証明書認証を使用するときに問題が発生します。 ocservログに次のエラーが表示された場合(sudo journalctl -eu ocserv
)、これと同じ問題があります。
GnuTLS error (at worker-vpn.c:795): A TLS fatal alert has been received.
AnyConnect iOSクライアントでパスワード認証を使用するか、ocserv構成ファイルでTLS1.3を無効にする必要があります。 TLS1.3を無効にするには、tls-priorities
を見つけます /etc/ocserv/ocserv.conf
のパラメータ ファイルを追加し、:-VERS-TLS1.3
最後にTLS1.3を無効にします。
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-RSA:-VERS-SSL3.0:-ARCFOUR-128:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.3"
ファイルを保存して閉じます。次に、ocservを再起動します。
sudo systemctl restart ocserv
注 :SSL 3.3
が表示された場合 ocservログのフレーズ、慌てる必要はありません。 SSL 3.3は、TLS1.2の別名です。安全なTLS接続を使用しています。