読者です 読者をやめる 読者になる 読者になる

Carpe Diem

備忘録。https://github.com/jun06t

ELB+nginxでbasic認証をかける方法

AWS Nginx

概要

開発環境では外部に見られないようにbasic認証をかけることが良くあります。
一方でELBのHealthCheckはbasic認証がかかったパスだと401エラーが返り、そのままだとOutOfServiceとなって接続することができません。
今回はそんな時の対応方法です。Nginxをリバースプロキシにしている場合も同様にできます。

環境

方法

結論から述べると以下の2つです。

  1. ELBのHealth Checkのポートを別にする
  2. NginxでVirtualHostを設定してHealth Checkと別にする

前提条件

a, bどちらも別のserverディレクティブを用意するので、ファイル自体も以下のように別にします。

sites-availableに書き、

sites-available/
├── default
└── service.conf

sites-enabledシンボリックリンクを貼っておきます。

# ln -s /etc/nginx/sites-available/service.conf /etc/nginx/sites-enabled/service.conf 

a) ELBのHealth Checkのポートを別にする

default

8080ポートをヘルスチェックに使います。

server {
    listen 8080;
    server_name localhost;
 
    location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    }
}

service.conf

server {
    listen 80;
    server_name localhost;

    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
 
    location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    }
}

設定後はnginxを再起動してください。

この状態でELBのヘルスチェック先を8080にします。 f:id:quoll00:20160726152320p:plain

こうすれば通常のアクセスは80ポートを経由し、8080でヘルスチェックしてくれるので外れることもありません。
当然ELBは8080ポートを閉じているので、外部からアクセスすることは出来ないです。

b) NginxでVirtualHostを設定してHealth Checkと別にする

ELBのヘルスチェックはIPベースで行われるので、デフォルトのVirtualHostに対して行われます。なのでサービスのFQDNhogehoge.example.comであれば

default

server {
    listen 80 default_server;
    server_name localhost;

    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
 
    location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    }
}

service.conf

server {
    listen 80;
    server_name hogehoge.example.com;

    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
 
    location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    }
}

と設定すれば、hogehoge.example.comでアクセスしてきたリクエストはservice.confの方に流され、basic認証がかかります。一方ヘルスチェックは認証のないdefaultの方に流されるので問題ありません。

またこれはELBがL4(TCP)でもL7(HTTP)でも大丈夫でした。

ソース