【nginx】セキュリティ
クライアントの IP アドレスでアクセスを制限する
code:nginx
location / {
# 192.168.1.1 からのアクセスを拒否
deny 192.168.1.1;
# サブネット単にでの拒否
deny 192.168.2.0/24 ;
# 特定の IP アドレスを許可
allow 192.168.3.1;
# サブネット単位で許可
allow 192.168.4.0/24;
# 他はすべて拒否
deny all;
}
複数の IP を 1 行で指定することは不可
最初に deny all; を指定してしまうと 2 行目の allow 以降は評価されない
code:conf
location / {
deny all;
allow 192.168.3.1;
...
}
ホスト名やドメイン名を指定することは不可
CORS 許可
code:nginx
map $request_method $cors_method {
OPTIONS 11;
GET 1;
POST 1;
default 0;
}
server {
location / {
if ($cors_method ~ '1') {
add_header 'Access-Control-Allow-Methods'
'GET,POST,OPTIONS';
add_header 'Access-Control-Allow-Origin'
'*.example.com';
add_header 'Access-Control-Allow-Headers'
'DNT,
Keep-Alive,
User-Agent,
X-Requested-With,
If-Modified-Since,
Cache-Control,
Content-Type';
}
if ($cors_method ~ '11') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}
}
SSL/TLS
code:nginx
http {
server {
listen 8443 ssl;
ssl_certificate /etc/nginx/ssl/example.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
}
}
code:nginx
http {
server {
listen 8443 ssl;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_certificate /etc/nginx/ssl/example.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
ssl_certificate $ecdsa_cert;
ssl_certificate_key data:$ecdsa_key_path;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
}
}
ssl_protocols TLSv1.2 TLSv1.3;
TLSv1.2, TLSv1.3 を受け付ける
ssl_certificate, ssl_certificate_key
複数の証明書キー形式を提供可能
クライアントに最適な証明書が利用できるので、新しいクライアントも古いクライアントもサービスを提供することができる
ssl_session_cache
所定の時間だけキャッシュを保存
アップストリーム通信の暗号化
code:nginx
location / {
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_protocols TLSv1.2;
}
proxy_ssl_verify_depth
セキュアリンク
code:nginx
location /resources {
secure_link_secret mySecret;
if ($secure_link = "") {return 403;}
rewrite ^ /secured/$secure_link;
}
location /secured/ {
internal;
root /var/www;
}
/resources はリクエスト URI に secure_link_secret ディレクティブで与えられた秘密で検証可能な MD5 ハッシュ文字列が含まれていない限り 403 を返す
セキュアリンクモジュールは MD5 ハッシュ化された文字列の 16 進数ダイジェストを受け入れる
生成
code:shell
$ echo -n 'index.htmlmySecret' | openssl md5 -hex
(stdin)= a53bee08a4bf0bbea978ddf736363a12
www.example.com が /var/www/secured/index.html というファイルを /resources にリクエスト
完全な URL はこちら
www.example.com/resources/a53bee08a4bf0bbea978ddf736363a12/index.html
有効期限切れ
code:nginx
location /resources {
root /var/www;
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri$remote_addrmySecret";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
}
セキュリティ強化のため remote_addr や http_x_forwarded_for などの変数やアプリケーションによって生成されたセッションクッキーヘッダーなどを利用するのが良い
HTTPS
- ユーザエージェントタイプでアクセスを制限する
- ★
HTTP メソッドを制限する
GET と HEAD と POST に限定してみる。それ以外は 444 を返してクライアントには応答せずコネクションを閉じる
code:conf
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 444;
}
ユーザ認証を設定
複数のアクセス制限を組み合わせる
ホットリンク(直リンク) を禁止する
不要なモジュールの見直し
バージョン情報を隠蔽
code:conf
server_tokens
DoS / DDoS 攻撃によるメモリ枯渇に備える
client_body_buffer_size
client_header_buffer_size
client_max_body_size
large_client_header_buffers
CRS(ModSecurity Core Rule Set)
無効
code:shell
# sysctl -w net.ipv4.tcp_syncookies=0
ブロードキャスト ping に応えない(Smurf 攻撃対策) code:shell
# sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1
準拠させると TIME_WAIT 状態の時に RST を受信した場合、TIME_WAIT 期間の終了を待たずにそのコネクションをクローズできるようになりたい
code:shell
# sysctl -w net.ipv4.tcp_rfc1337=1
TIME-WAIT ソケットを高速にリサイクルする
code:shell
# sysctl -w net.ipv4.tcp_tw_recycle=1
TIME_WAIT 状態のコネクションを再利用すると、TIME_WAIT 状態を管理するためのキャッシュがオーバーフローするのを防ぎ、TIME_WAIT 状態のコネクションを減らすことができる
TIME_WAIT 状態のコネクションが大量に残るような場合、最終 FIN パケットを待つ時間を短くすることで解消することができる
code:shell
# sysctl -w net.ipv4.tcp_fin_timeout=15
ICMP リダイレクトパケットを送信することで、ルーティング情報を変更することができるようになる
不正な ICMP リダイレクトパケットによりネットワーク経路を強制的に変更され、パケットの盗聴や改ざんされると言った危険にさらされる可能性がある
code:shell
# sysctl -w net.ipv4.conf.*.accept_redirects=0
設定は全ネットワークインタフェースに対して行なう必要がある
起動時には次のようなシェルスクリプトを実行し有効化する
送信元ホストの IP アドレスを偽装したパケットによる攻撃
対策としては、Linux で送信元ホストの IP アドレスが正しいかどうかを確認するようにする
code:shell
# sysctl -w net.ipv4.conf.*.rp_filter=1
設定は全ネットワークインタフェースに対して行なう必要がある
起動時には次のようなシェルスクリプトを実行し有効化する
ソースルーティングされたパケットを拒否
ソースルーティングを使うと、中継ルータを指定することができる
これを悪用すると、送信元の IP アドレスを詐称して送信先ホストと IP 通信を行なうことが可能になる
SSR オプションがついたパケットを拒否することで、ソースルーティングされたパケット無効化できる code:shell
# sysctl -w net.ipv4.conf.*.accept_source_route=0
設定は全ネットワークインタフェースに対して行なう必要がある
起動時には次のようなシェルスクリプトを実行し有効化する
HTTPS を強制する
暗号化プロトコルの設定
使用する TLS/SSL のバージョンを限定する
SSLv2, SSLv3 を使用しない
使用されているかどうかは curl コマンドで確認できる 使用する暗号化スイートを限定する
サーバ側が指定した暗号スイートを優先する