nginx

nginx 特定IPアドレス以外からのアクセスにクライアント認証をかける

公開していない管理サーバなどにアクセス制限したいときがあると思います。
その対応策の1つとして

  • 社内(内部)IPアドレスからはクライアント認証なしでアクセスOK
  • 社外(外部)からはクライアント証明書をもっている端末(ブラウザ)のみアクセスOK

の制限をnginxでかけてみます。

※apacheでの設定は こちらの記事 をご参照ください。

手順

事前確認

geoipモジュールが組み込まれているか確認します。

【静的組み込み】

$ nginx -V 2>&1 | grep -oP '[a-z_]+_module'
〜〜
http_geoip_module
〜〜

【動的組み込み】

### モジュールパスの確認
$ nginx -V 2>&1 | egrep -o modules-path=.+ | awk '{print $1}'
modules-path=/usr/lib64/nginx/modules
$ 
### ライブラリがあるか確認
$ ls /usr/lib64/nginx/modules
ngx_http_geoip_module-debug.so  ngx_http_geoip_module.so  ngx_stream_geoip_module-debug.so  ngx_stream_geoip_module.so
$ 

### この例ではrpm パッケージとしてインストールしている状態
$ rpm -qf /usr/lib64/nginx/modules/ngx_http_geoip_module.so
nginx-module-geoip-1.15.8-1.el7_4.ngx.x86_64
$ 

どちらもなければインストールの必要があります。Linuxであれば nginx: Linux packages のパッケージの利用が便利かと思います。

クライアント証明書作成

長くなるのでここでは割愛させていただきますmm
例えば 参考:クライアント用証明書 を実施して作成します。

nginx設定ファイル修正

$ cat /etc/nginx/nginx.conf 
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;

〜〜〜

# httpディレクティブで宣言する
http {

    # 許可IPリスト
    # allow_ip_listやallow はただの変数名です
    geo $allow_ip_list {
       default deny;
       127.0.0.1 allow;
       # 社内IP CIDR表記が可能です
       10.1.1.0/24 allow;
       # 協力会社IP
       10.1.2.1 allow;
       10.1.3.1 allow;
    }
    include /etc/nginx/conf.d/*.conf;
}
$
$
$ cat /etc/nginx/conf.d/hogehoge.com.conf 
server {
        listen       443 ssl;
        server_name hogehoge.com;

〜〜
        ssl                       on;
        # サーバ証明書配置
        ssl_certificate           /etc/nginx/ssl_crt/hogehoge.com.crt; 
        ssl_certificate_key       /etc/nginx/ssl_crt/hogehoge.com.key;

〜〜

        # クライアント認証設定
        # クライアント証明書作成の際に使用したCA証明書
        ssl_client_certificate /etc/nginx/ssl_crt/cacert.pem; 

        # クライアント証明書の検証を有効化。検証結果は $ssl_client_verify変数に格納される。
        ssl_verify_client optional; 

       # 証明書の階層をたどる深さ(中間証明書があると2らしい)。default=1。
        ssl_verify_depth 1;                                       

        # クライアント認証の判定。デフォルトngにしておく
        set $allow_ip_check ng;

        # クライアント認証結果OK
        if ($ssl_client_verify = SUCCESS) {
           set $allow_ip_check ok;
        }
        # nginx.conf 記載のallow_ip_list からもOK
        if ($allow_ip_list = "allow") {
           set $allow_ip_check ok;
        }
        # ここまでの判定でOKじゃなければエラーを返す
        if ($allow_ip_check != "ok") {
            return 403;
        }

        location / {
〜〜
$ 

動作確認

参考:プライベート認証局を登録(インポート)する の手順でブラウザにクライアント証明書をインポートします。(Chromeは証明書をPCにダウンロードして証明書をダブルクリックしてポチポチすればいけます)

インポート後、当該サイトにアクセスすると

とクライアント証明書の選択画面になるので適切な証明書を選択してください。
証明書を持っていない場合や異なる証明書を選択した場合は 403 Forbidden となります。

参考

プライベート認証局の証明書、サーバー証明書、クライアント証明書の作成方法について
Nginxでgeoモジュールを使ってメンテナンス中にIP制限をかける – Qiita
Nginxで読み込まれているモジュールの一覧を取得する | 俺的備忘録 〜なんかいろいろ〜

タイトルとURLをコピーしました