Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

WordPressでWebサイトを運営している場合、WordPressの管理ページにはアクセス制限などのセキュリティ対策を施すのが大切です。

Nginx上のWordPress環境で、管理ページへのアクセスをNginxで制限する方法としては、IPアドレスで制限したり、Basic認証を設定する方法が一般的ですが、これ以外の方法としてクライアント証明書を利用した認証方法があります。

そこでここでは、Nginx上のWordPress環境で、WordPressのログインページにクライアント証明書を利用した認証を設定する方法を紹介します。

Nginx上のWordPressでログインページにBasic認証(基本認証)を設定する方法
ここでは、Nginx上のWordPress環境で、WordPressのログインページにBasic認証(基本認証)を設定する方法を紹介します。

動作環境

この記事は、以下の環境での動作結果を基にしています。他のディストリビューションやバージョンでは、動作結果が異なる場合があることをご了承ください。

ソフトウェアバージョン
CentOS Linux7.9.2009
Nginx1.21.3

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

CA相当証明書の作成

まず、証明書を作成するディレクトリに移動します。

#cd /etc/ssl

つぎに、CA相当の秘密鍵ファイルを作成します。

# openssl genrsa 4096 > ca.key

つぎに、CSRファイルを作成します。

ここでは、最低限「Organization Name」だけは設定しておきます。

# openssl req -new -key ca.key > ca.csr

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

つぎに、CA相当の自己署名証明書を作成します。

「-days」オプションでは証明書の有効期間を設定でき、以下のコマンドでは「3650日=10年」で設定しています。

# openssl x509 -days 3650 -req -signkey ca.key < ca.csr > ca.crt

つぎに、シリアル番号を生成します。

# echo 01 > ca.srl

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

つぎに、クライアント向けの秘密鍵を作成します。

# openssl genrsa 4096 > client1.key

つぎに、CSRファイルを作成します。

ここでは、最低限「Organization Name」だけは設定する必要があり、CA相当証明書と異なる名前に設定する必要があります。

# openssl req -new -key client1.key > client1.csr

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

つぎに、クライアント証明書を作成します。

# openssl x509 -req -days 3650 -CA ca.crt -CAkey ca.key < client1.csr > client1.crt

つぎに、作成したクライアント認証をPkcs12形式に変換します。(パスワードは未設定でもOKです。)

# openssl pkcs12 -export -out client1.pfx -inkey client1.key -in client1.crt -certfile ca.crt

作成したclient.pfxは、クライアント環境にダウンロードしておきます。

Nginxの設定

つぎに、Nginxの設定ファイルにクライアント証明書を使用した認証設定を追記します。

server {
<省略>
  ssl_verify_client optional;
  ssl_client_certificate /etc/ssl/ca.crt;
<省略>
  location ~* /wp-login\.php|/wp-admin/((?!admin-ajax\.php).)*$ {
    if ($ssl_client_verify != SUCCESS) {return 403;}
    <省略>
  }
}
Memo

上の設定ファイルでは、locationディレクティブでWordPressのログインページを指定していますが、他のパスを指定すれば、指定したパスでクライアント認証を設定できます。

設定ファイルを更新したら、以下のコマンドを実行して設定ファイルに問題がないか確認します。

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

最後に、設定を反映させるために以下のコマンドでnginxを再起動します。

# systemctl restart nginx

以上で、サーバー側の作業完了です。

クライアント証明書のインポート

ここでは例として、Windows 10でクライアント認証をインポートする手順を紹介します。

まずは、サーバー上で作成したクライアント証明書をWindows 10にダウンロードし、ダブルクリックします。

すると「証明書のインポートウィザード」が開くので「保存場所」で「現在のユーザー」を選択した状態で「次へ」をクリックします。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

「インポートする証明書ファイル」では、すでに「ファイル名」欄にインポートする証明書ファイルが入力されているので、そのまま「次へ」をクリックします。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

「秘密キーの保護」では、クライアント証明書作成時にパスワードを設定した場合は、パスワードを入力し、そのほかのオプションはデフォルトのままで「次へ」をクリックします。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

「証明書ストア」では、証明書の保存先を指定でき、ここでは「証明書の種類に基づいて、自動的に証明書ストアを選択する」を選択した状態で「次へ」をクリックします。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

「証明書のインポートウィザードの完了」では、設定内容を確認して「完了」をクリックします。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

「セキュリティ警告」が表示されるので「はい」をクリックします。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

「正しくインポートされました。」と表示されたら「OK」をクリックし、インポート完了です。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

インポートした証明書を削除したいときは

インポートした証明書を削除したいときは、スタートボタン右の検索ボックスなどに「certmgr.msc」を入力してエンターキーを押し、現在のユーザーの証明書画面を開きます。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

証明書画面の左側のメニューから「個人」>「証明書」を選択すると、画面右側にインポートしたクライアント証明書を確認できるので、右クリックから「削除」を選択することで削除できます。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

証明書画面の左側のメニューから「信頼されたルート証明機関」>「証明書」を選択すると、画面右側にインポートしたクライアント証明書のルート証明書を確認できまるので、右クリックから「削除」を選択することで削除できます。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

動作確認

最後に、Webブラウザを再起動して、クライアント認証を設定したWebページにアクセスすれば、以下のように証明書の選択画面が表示されるので、インポートしたクライアント証明書を選択することでアクセスできるようになります。

Nginx上のWordPressでログインページにクライアント証明書による認証を設定する方法

クライアント証明書を利用する場合の注意点

Nginxの設定をご覧いただくとわかるように、クライアント証明書を利用した認証では、証明書の認証自体は、Webサイト全体に対してしか設定できないため、Webサイトのどのページを表示しても、上の画像のようにクライアント証明書の選択画面が表示されます。

ここで、正しい証明書を選択すると「$ssl_client_verify」に「SUCCESS」という値が格納されます。

特定のWebページにアクセス制限をかけるときは、この「$ssl_client_verify」に格納される値に応じて動作を指定することになります。

上記のNginxの設定では、WordPressのログインページで「$ssl_client_verify」に格納される値を確認し、正しい証明書が選択されなかった場合には、HTTPステータスコード「403」を返すように設定しています。

あとがき

Webサイト全体に対してアクセス制限をかけたいときには、クライアント証明書を利用した方法も選択肢の一つとして十分ありだと思いますが、Webサイトの一部のページにだけアクセス制限をかけたい場合では、制限をかけていないページにも証明書の選択画面が表示されるのがちょっと気になります。