すべてのプロダクト
Search
ドキュメントセンター

:Nginx Web サーバーのセキュリティ向上

最終更新日:Dec 17, 2025

このトピックでは、Nginx Web サーバーのセキュリティを向上させる方法について説明します。

背景情報

Nginx は、軽量でパフォーマンスに優れた Web サーバー、リバースプロキシ、およびメール (IMAP または POP3) プロキシサーバーです。UNIX、GNU/Linux、BSD、Mac OS X、Solaris、Windows のさまざまなバージョンで動作します。調査によると、Nginx は全 Web サイトの 6% で使用されています。Nginx は、C10k 問題を処理できる数少ないサーバーの 1 つです。従来のサーバーとは異なり、Nginx はリクエストの処理をスレッドに依存しません。代わりに、よりスケーラブルなイベント駆動 (非同期) アーキテクチャを使用します。Nginx は、WordPress、Renren、Tencent、NetEase など、トラフィックが非常に多い Web サイトの一部で利用されています。このトピックでは、Linux または UNIX システムで実行される Nginx Web サーバーのセキュリティ強化について説明します。

操作手順

このセクションでは、Nginx のデフォルトの設定ファイルとポートについて説明します。

  • /usr/local/nginx/conf/ は Nginx の設定ディレクトリです。/usr/local/nginx/conf/nginx.conf はメインの設定ファイルです。

  • /usr/local/nginx/html/ は Web サイトファイルのデフォルトの場所です。

  • /usr/local/nginx/logs/ はログファイルのデフォルトの場所です。

  • デフォルトの Nginx HTTP ポートは TCP 80 です。

  • デフォルトの Nginx HTTPS ポートは TCP 443 です。

  1. 次のコマンドを実行して、Nginx 設定ファイルを検証します。

    /usr/local/nginx/sbin/nginx -t

    次のような出力が表示されます。

    the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    configuration file /usr/local/nginx/conf/nginx.conf test is successful
  2. 次のコマンドを実行して、設定ファイルを再読み込みします。

    /usr/local/nginx/sbin/nginx -s reload
  3. 次のコマンドを実行して、サーバーを停止します。

    /usr/local/nginx/sbin/nginx -s stop

ステップ 1:SELinux の設定

説明

Elastic Compute Service (ECS) インスタンスについては、「ECS インスタンスの注意事項」をご参照ください。互換性と安定性を確保するため、SELinux は有効にしないでください。

Security-Enhanced Linux (SELinux) は、アクセス制御をサポートするセキュリティポリシーメカニズムを提供し、ほとんどの攻撃から防御できる Linux カーネルの機能です。以下の手順では、CentOS または RHEL システムで SELinux を有効にする方法を説明します。

  1. 次のコマンドを実行して SELinux をインストールします。

    rpm -qa | grep selinux

    出力が返されない場合、SELinux はインストールされていません。次のような出力が返された場合、SELinux はインストールされています。

    libselinux-1.23.10-2
    selinux-policy-targeted-1.23.16-6
  2. `getsebool -a` コマンドを使用してシステムをロックダウンします。以下に例を示します。

    getsebool -a | less
    getsebool -a | grep off
    getsebool -a | grep o

ステップ 2:パーティションのマウントによる最小権限の付与

/html/php ファイルなど、Web ファイル用に別のパーティションを作成します。たとえば、新しいパーティション /dev/sda5 (最初の論理パーティション) を作成し、それを /nginx にマウントできます。/nginx パーティションが `noexec`、`nodev`、および `nosuid` 権限でマウントされていることを確認してください。以下は、/etc/fstab ファイル内の /nginx エントリの例です。

LABEL=/nginx /nginx ext3 defaults,nosuid,noexec,nodev 1 2
説明

fdisk および mkfs.ext3 コマンドを使用して新しいパーティションを作成します。

ステップ 3:/etc/sysctl.conf の設定による Linux セキュリティの強化

次の例に示すように、/etc/sysctl.conf ファイルを編集して、Linux カーネルとネットワーク設定を制御および設定します。

# smurf 攻撃の回避
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 不正な icmp エラーメッセージに対する保護を有効化
net.ipv4.icmp_ignore_bogus_error_responses = 1
# SYN フラッド攻撃保護のために syncookies を有効化
net.ipv4.tcp_syncookies = 1
# なりすまし、ソースルーティング、リダイレクトパケットを有効化してログに記録
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# ここではソースルーティングされたパケットはなし
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# リバースパスフィルタリングを有効化
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# ルーティングテーブルを誰も変更できないようにする
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# ルーターとして機能させない
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# execshild を有効化
kernel.exec-shield = 1
kernel.randomize_va_space = 1
# IPv6 を有効化
net.ipv6.conf.default.router_solicitations = 0
net.ipv6.conf.default.accept_ra_rtr_pref = 0
net.ipv6.conf.default.accept_ra_pinfo = 0
net.ipv6.conf.default.accept_ra_defrtr = 0
net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.default.dad_transmits = 0
net.ipv6.conf.default.max_addresses = 1
# LB のポート使用の最適化
# システムファイル記述子の制限を増やす
fs.file-max = 65535
# より多くの PID を許可 (ロールオーバーの問題を減らすため); 一部のプログラムが壊れる可能性あり 32768
kernel.pid_max = 65536
# システム IP ポートの制限を増やす
net.ipv4.ip_local_port_range = 2000 65000
# setsockopt() を使用して設定可能な TCP 最大バッファサイズを増やす
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 87380 8388608
# Linux 自動チューニング TCP バッファ制限を増やす
# 使用するバイト数の最小値、デフォルト値、最大値
# 非常に高い BDP パスを使用する場合は、最大値を少なくとも 4MB 以上に設定
# Tcp Windows など
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_window_scaling = 1

ステップ 4:不要な Nginx モジュールの削除

ソースコードから Nginx をコンパイルして、モジュールの数を最小限に抑えます。リスクを最小限に抑えるために、Web サーバーが必要とするモジュールのみにアクセスを制限します。必要な Nginx モジュールのみを設定およびインストールします。

  1. 次のコマンドを実行して、SSL および autoindex モジュールを無効にします。

    ./configure -without-http_autoindex_module -without-http_ssi_module
    make
    make install
  2. 次のコマンドを実行して、Nginx サーバーのコンパイル時に有効または無効にできるモジュールを確認します。

    ./configure -help | less
  3. 使用しない Nginx モジュールを無効にします。

  4. 必要に応じて、Nginx のバージョン名を変更できます。これを行うには、`/http/ngx_http_header_filter_module.c` ファイルを編集し、次の行を見つけます。

    static char ngx_http_server_string[] = “Server: nginx” CRLF;
    static char ngx_http_server_full_string[] = “Server: ” NGINX_VER CRLF;

    これらを次のように変更します。

    static char ngx_http_server_string[] = “Server: Ninja Web Server” CRLF;
    static char ngx_http_server_full_string[] = “Server: Ninja Web Server” CRLF;
  5. ファイルを保存して閉じます。次に、サーバー設定を編集します。`nginx.conf` ファイルに次のコードを追加して、Nginx のバージョン番号を非表示にします。

    server_tokens off

ステップ 5:mod_security の使用

mod_security は Apache 用のアプリケーションレベルのファイアウォールです。バックエンドの Apache Web サーバーに mod_security をインストールして、多くのインジェクション攻撃を防ぐことができます。

説明

このステップは、バックエンドの Apache サーバーにのみ適用されます。

ステップ 6:SELinux ポリシーのインストールによる Nginx Web サーバーの強化

デフォルトの SELinux ポリシーは Nginx Web サーバーを保護しませんが、ポリシーをインストールしてコンパイルすることで保護できます。

  1. 次のコマンドを実行して、SELinux ポリシーのコンパイルに必要な環境をインストールします。

    yum -y install selinux-policy-targeted selinux-policy-devel
  2. 次のコマンドを実行して、Nginx 用の SELinux ポリシーをダウンロードします。

    cd /opt
    wget http://downloads.sourceforge.net/project/selinuxnginx/se-ngix_1_0_10.tar.gz?use_mirror=nchc&rsquo
  3. 次のコマンドを実行して、ファイルを解凍します。

    tar -zxvf se-ngix_1_0_10.tar.gz
  4. 次のコマンドを実行して、ファイルをコンパイルします。

    cd se-ngix_1_0_10/nginx
    make

    次のような出力が表示されます。

    Compiling targeted nginx module
    /usr/bin/checkmodule: loading policy configuration from tmp/nginx.tmp
    /usr/bin/checkmodule: policy configuration loaded
    /usr/bin/checkmodule: writing binary representation (version 6) to tmp/nginx.mod
    Creating targeted nginx.pp policy package
  5. 次のコマンドを実行して、一時ファイルを削除します。

    rm tmp/nginx.mod.fc tmp/nginx.mod
  6. 次のコマンドを実行して、生成された nginx.pp SELinux モジュールをインストールします。

    /usr/sbin/semodule -i nginx.pp

ステップ 7:Iptables ファイアウォールによる制限

次のファイアウォールスクリプトは、明示的に許可されているリクエストを除くすべてのリクエストをブロックします。

  • HTTP (TCP ポート 80) からのリクエスト

  • ICMP ping からのリクエスト

  • NTP (ポート 123) へのアウトバウンドリクエスト

  • SMTP (TCP ポート 25) へのアウトバウンドリクエスト

#!/bin/bash

IPT=”/sbin/iptables”

#### IPS ######
# サーバーのパブリック IP を取得
SERVER_IP=$(ifconfig eth0 | grep ‘inet addr:’ | awk -F’inet addr:’ ‘{ print $2}’ | awk ‘{ print $1}’)
LB1_IP=”204.X.X.1″
LB2_IP=”204.X.X.2″

# LB2 でも同じスクリプトを使用できるように、スマートなロジックを実装
OTHER_LB=”"
SERVER_IP=”"
[[ "$SERVER_IP" == "$LB1_IP" ]] && OTHER_LB=”$LB2_IP” || OTHER_LB=”$LB1_IP”
[[ "$OTHER_LB" == "$LB2_IP" ]] && OPP_LB=”$LB1_IP” || OPP_LB=”$LB2_IP”


### IPs ###
PUB_SSH_ONLY=”122.xx.yy.zz/29″

#### FILES #####
BLOCKED_IP_TDB=/root/.fw/blocked.ip.txt
SPOOFIP=”127.0.0.0/8 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 169.254.0.0/16 0.0.0.0/8 240.0.0.0/4 255.255.255.255/32 168.254.0.0/16 224.0.0.0/4 240.0.0.0/5 248.0.0.0/5 192.0.2.0/24″
BADIPS=$( [[ -f ${BLOCKED_IP_TDB} ]] && egrep -v “^#|^$” ${BLOCKED_IP_TDB})

### Interfaces ###
PUB_IF=”eth0″   # パブリックインターフェイス
LO_IF=”lo”      # ループバック
VPN_IF=”eth1″   # vpn / プライベートネット

### ファイアウォールを開始 ###
echo “Setting LB1 $(hostname) Firewall…”
# すべてを DROP して閉じる
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP

# 無制限の lo アクセス
$IPT -A INPUT -i ${LO_IF} -j ACCEPT
$IPT -A OUTPUT -o ${LO_IF} -j ACCEPT
# 無制限の vpn / pnet アクセス
$IPT -A INPUT -i ${VPN_IF} -j ACCEPT
$IPT -A OUTPUT -o ${VPN_IF} -j ACCEPT
# sync をドロップ
$IPT -A INPUT -i ${PUB_IF} -p tcp ! -syn -m state -state NEW -j DROP
# フラグメントをドロップ
$IPT -A INPUT -i ${PUB_IF} -f -j DROP
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags ALL FIN,URG,PSH -j DROP
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags ALL ALL -j DROP

# NULL パケットをドロップ
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags ALL NONE -m limit -limit 5/m -limit-burst 7 -j LOG -log-prefix ” NULL Packets “
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags ALL NONE -j DROP
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags SYN,RST SYN,RST -j DROP
# XMAS をドロップ
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags SYN,FIN SYN,FIN -m limit -limit 5/m -limit-burst 7 -j LOG -log-prefix ” XMAS Packets “
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags SYN,FIN SYN,FIN -j DROP

# FIN パケットスキャンをドロップ
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags FIN,ACK FIN -m limit -limit 5/m -limit-burst 7 -j LOG -log-prefix ” Fin Packets Scan “
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags FIN,ACK FIN -j DROP
$IPT  -A INPUT -i ${PUB_IF} -p tcp -tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
# ブロードキャスト / マルチキャストと無効なものをログに記録して破棄
$IPT  -A INPUT -i ${PUB_IF} -m pkttype -pkt-type broadcast -j LOG -log-prefix ” Broadcast “
$IPT  -A INPUT -i ${PUB_IF} -m pkttype -pkt-type broadcast -j DROP
$IPT  -A INPUT -i ${PUB_IF} -m pkttype -pkt-type multicast -j LOG -log-prefix ” Multicast “
$IPT  -A INPUT -i ${PUB_IF} -m pkttype -pkt-type multicast -j DROP
$IPT  -A INPUT -i ${PUB_IF} -m state -state INVALID -j LOG -log-prefix ” Invalid “
$IPT  -A INPUT -i ${PUB_IF} -m state -state INVALID -j DROP
# なりすまし IP をログに記録してブロック
$IPT -N spooflist
for ipblock in $SPOOFIP
do
$IPT -A spooflist -i ${PUB_IF} -s $ipblock -j LOG -log-prefix ” SPOOF List Block “
$IPT -A spooflist -i ${PUB_IF} -s $ipblock -j DROP
done
$IPT -I INPUT -j spooflist
$IPT -I OUTPUT -j spooflist
$IPT -I FORWARD -j spooflist

# 選択されたパブリック IP からのみ ssh を許可
for ip in ${PUB_SSH_ONLY}
do
$IPT -A INPUT -i ${PUB_IF} -s ${ip} -p tcp -d ${SERVER_IP} -destination-port 22 -j ACCEPT
$IPT -A OUTPUT -o ${PUB_IF} -d ${ip} -p tcp -s ${SERVER_IP} -sport 22 -j ACCEPT
done

# 受信 ICMP ping pong を許可
$IPT -A INPUT -i ${PUB_IF} -p icmp -icmp-type 8 -s 0/0 -m state -state NEW,ESTABLISHED,RELATED -m limit -limit 30/sec  -j ACCEPT
$IPT -A OUTPUT -o ${PUB_IF} -p icmp -icmp-type 0 -d 0/0 -m state -state ESTABLISHED,RELATED -j ACCEPT
# 受信 HTTP ポート 80 を許可
$IPT -A INPUT -i ${PUB_IF} -p tcp -s 0/0 -sport 1024:65535 -dport 80 -m state -state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o ${PUB_IF} -p tcp -sport 80 -d 0/0 -dport 1024:65535 -m state -state ESTABLISHED -j ACCEPT
# 送信 ntp を許可
$IPT -A OUTPUT -o ${PUB_IF} -p udp -dport 123 -m state -state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i ${PUB_IF} -p udp -sport 123 -m state -state ESTABLISHED -j ACCEPT
# 送信 smtp を許可
$IPT -A OUTPUT -o ${PUB_IF} -p tcp -dport 25 -m state -state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i ${PUB_IF} -p tcp -sport 25 -m state -state ESTABLISHED -j ACCEPT

### ここに他のルールを追加 ###
#######################
# 他のすべてをドロップしてログに記録
$IPT -A INPUT -m limit -limit 5/m -limit-burst 7 -j LOG -log-prefix ” DEFAULT DROP “
$IPT -A INPUT -j DROP
exit 0

ステップ 8:バッファオーバーフロー攻撃の制御

`nginx.conf` ファイルを編集し、すべてのクライアントのバッファサイズ制限を設定します。

vi /usr/local/nginx/conf/nginx.conf

すべてのクライアントのバッファサイズ制限を次のように設定します。

## Start: Size Limits & Buffer Overflows ##
client_body_buffer_size  1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
## END: Size Limits & Buffer Overflows ##
説明
  1. client_body_buffer_size 1k;:(デフォルト:8 KB または 16 KB) このディレクティブは、リクエストボディのバッファサイズを指定します。リクエストボディがバッファより大きい場合、ボディ全体またはその一部が一時ファイルに書き込まれます。

  2. client_header_buffer_size 1k;:このディレクティブは、リクエストヘッダーのバッファサイズを指定します。ほとんどの場合、1 KB のバッファでリクエストヘッダーには十分です。ただし、リクエストに大きな Cookie が含まれている場合や、WAP クライアントからのリクエストの場合、ヘッダーが 1 KB を超えることがあります。この場合、Nginx はより大きなバッファを割り当てます。これは `large_client_header_buffers` ディレクティブで設定されます。

  3. client_max_body_size 1k;:このディレクティブは、`Content-Length` リクエストヘッダーフィールドで示される、リクエストボディの最大許容サイズを指定します。リクエストのサイズが指定された値より大きい場合、クライアントは「413 Request Entity Too Large」エラーを受け取ります。ブラウザはこのエラーを正しく表示できないことに注意してください。

  4. large_client_header_buffers 2 1k;:このディレクティブは、大きなクライアントリクエストヘッダーの読み取りに使用されるバッファの数とサイズを指定します。リクエストラインは 1 つのバッファのサイズを超えることはできません。超えた場合、クライアントは「414 Request URI Too Large」エラーを受け取ります。リクエストヘッダーフィールドも 1 つのバッファのサイズを超えることはできません。超えた場合、クライアントは「400 Bad Request」エラーを受け取ります。バッファはオンデマンドでのみ割り当てられます。デフォルトでは、バッファサイズはページサイズと同じで、プラットフォームに応じて 4 KB または 8 KB です。リクエストが処理された後、接続が keep-alive 状態に移行すると、これらのバッファは解放されます。

また、サーバーのパフォーマンスを向上させ、クライアントを切断するためにタイムアウトを制御する必要があります。設定を次のように構成します。

## Start: Timeouts ##
client_body_timeout   10;
client_header_timeout 10;
keepalive_timeout     5 5;
send_timeout          10;
## End: Timeouts ##
説明
  • client_body_timeout 10;:このディレクティブは、リクエストボディの読み取りタイムアウトを設定します。タイムアウトは、連続する 2 つの読み取り操作の間の期間にのみ適用され、リクエストボディ全体の送信には適用されません。この時間内にクライアントが何も送信しない場合、Nginx は「408 Request Time-out」エラーを返します。

  • client_header_timeout 10;:このディレクティブは、リクエストヘッダーの読み取りタイムアウトを設定します。タイムアウトは、連続する 2 つの読み取り操作の間の期間にのみ適用され、ヘッダー全体の送信には適用されません。この時間内にクライアントが何も送信しない場合、Nginx は「408 Request Time-out」エラーを返します。

  • keepalive_timeout 5 5;:最初のパラメーターは、keep-alive クライアント接続がサーバー側で開いたままになるタイムアウトを設定します。この時間が経過すると、サーバーは接続を閉じます。オプションの 2 番目のパラメーターは、`Keep-Alive: timeout=time` レスポンスヘッダーフィールドに値を設定します。この値は、一部のブラウザに接続を閉じるタイミングを通知できるため、サーバーが閉じる必要がなくなります。このパラメーターが設定されていない場合、Nginx は `Keep-Alive` ヘッダーを送信しません。2 つのパラメーターは異なる値を持つことができます。

  • send_timeout 10;:このディレクティブは、クライアントへのレスポンス送信のタイムアウトを設定します。タイムアウトは、連続する 2 つの書き込み操作の間にのみ適用され、レスポンス全体の送信には適用されません。この時間内にクライアントが何も受信しない場合、Nginx は接続を閉じます。

ステップ 9:同時接続数の制御

`ngx_http_limit_conn_module` を使用して、指定されたセッションの同時接続数、または特別な場合には単一の IP アドレスからの同時接続数を制限できます。`nginx.conf` ファイルを編集して、単一のクライアント IP アドレスからの同時接続数を 5 に制限します。

# セッション状態が保存されるゾーンを記述します。この例では、slimits に保存されます。
# 1 MB のゾーンは、セッションあたり 32 バイトで約 32,000 セッションを処理できます。この例では、ゾーンサイズを 5 MB に設定します。
limit_conn_zone $binary_remote_addr zone=slimits:5m;

# 1 つのセッションの最大同時接続数を制御します。
# 単一の IP アドレスからの接続数を制限します。
limit_conn slimits 5;

ステップ 10:自ドメイン名からのアクセスのみを許可

ボットがサーバー上のすべてのドメイン名をランダムにスキャンしている場合、それらのリクエストを拒否できます。設定済みの仮想ドメインまたはリバースプロキシへのリクエストを許可する必要があります。リクエストを拒否するために IP アドレスを使用する必要はありません。以下に例を示します。

## nixcraft.in、images.nixcraft.in、www.nixcraft.in など、当社のホストへのリクエストのみが許可されます
if ($host !~ ^(nixcraft.in|www.nixcraft.in|images.nixcraft.in)$ ) {
return 444;
}
##

ステップ 11:利用可能なリクエストメソッドの制限

GET と POST は、インターネットで最も一般的なメソッドです。Web サーバーのメソッドは RFC 2616 で定義されています。Web サーバーが利用可能なすべてのメソッドを必要としない場合は、不要なメソッドを無効にする必要があります。次の設定は、他のメソッドをフィルタリングし、GET、HEAD、POST メソッドのみを許可します。

## これらのリクエストメソッドのみを許可 ##
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
## DELETE、SEARCH、その他のメソッドは受け付けない ##

HTTP メソッドに関する詳細情報は以下のとおりです:

  • GET メソッドは、http://www.moqifei.com/index.php のファイルなど、リソースをリクエストするために使用されます。

  • HEAD メソッドは GET メソッドと同じですが、サーバーはレスポンスでメッセージボディを返しません。

  • POST メソッドは、データの保存や更新、製品の注文、フォームの送信によるメール送信など、多くの目的で使用されます。このメソッドは通常、PHP、Perl、Python スクリプトなどのサーバーサイドスクリプトによって処理されます。ファイルをアップロードしたり、サーバー上でデータを処理したりするには、このメソッドを使用する必要があります。

ステップ 12:特定のユーザーエージェントのブロック

サーバーを悪用するスキャナー、ボット、スパマーなどのユーザーエージェントを簡単にブロックできます。

## ダウンロードエージェントをブロック ##
if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
return 403;
}
##

次の例は、Soso と Youdao のボットをブロックする方法を示しています。

## 一部のロボットをブロック ##
if ($http_user_agent ~* Sosospider|YoudaoBot) {
return 403;
}

ステップ 13:画像のホットリンクの防止

画像のホットリンクとは、誰かがあなたの Web サイト上の画像の URL を使用して、自分の Web サイトにそれを表示することです。これにより、余分なブロードバンド費用を支払うことになります。この行為は、フォーラムやブログで一般的です。ホットリンクをブロックすることを強く推奨します。

# ディープリンクまたはホットリンクを停止
location /images/ {
valid_referers none blocked www.example.com example.com;
if ($invalid_referer) {
return   403;
}
}

例:リクエストをリダイレクトし、特定の画像を表示します。

valid_referers blocked www.example.com example.com;
if ($invalid_referer) {
rewrite ^/images/uploads.*.(gif|jpg|jpeg|png)$ http://www.examples.com/banned.jpg last
}

ステップ 14:ディレクトリの制限

特定のディレクトリへのアクセス権限を設定できます。各 Web サイトのディレクトリを個別に設定し、必要なアクセス権限のみを付与します。

IP アドレスによるアクセス制限

次の例に示すように、IP アドレスによって /admin/ ディレクトリへのアクセスを制限できます。

location /docs/ {
## 1 つのワークステーションをブロック
deny    192.168.1.1;
## 192.168.1.0/24 内のすべてを許可
allow   192.168.1.0/24;
## 残りのすべてをドロップ
deny    all;
}

パスワードによるディレクトリの保護

  1. 次のコマンドを実行してパスワードファイルを作成し、ユーザー `user` を追加します。

    mkdir /usr/local/nginx/conf/.htpasswd/
    htpasswd -c /usr/local/nginx/conf/.htpasswd/passwd user
  2. nginx.conf ファイルを編集して、保護したいディレクトリを追加します。

    ### /personal-images/ および /delta/ ディレクトリをパスワードで保護 ###
    location ~ /(personal-images/.|delta/.) {
    auth_basic  “Restricted”;
    auth_basic_user_file   /usr/local/nginx/conf/.htpasswd/passwd;
    }
  3. パスワードファイルが生成された後、次のコマンドを使用してさらにユーザーを追加できます。

    htpasswd -s /usr/local/nginx/conf/.htpasswd/passwd userName

ステップ 15:Nginx SSL の設定

HTTP はテキストベースのプロトコルであり、受動的な監視に対して脆弱です。ユーザーコンテンツを暗号化するために SSL を使用する必要があります。

  1. 次のコマンドを実行して SSL 証明書を作成します。

    cd /usr/local/nginx/conf
    openssl genrsa -des3 -out server.key 1024
    openssl req -new -key server.key -out server.csr
    cp server.key server.key.org
    openssl rsa -in server.key.org -out server.key
    openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
  2. nginx.conf ファイルを編集し、次のように更新します。

    server {
    server_name example.com;
    listen 443;
    ssl on;
    ssl_certificate /usr/local/nginx/conf/server.crt;
    ssl_certificate_key /usr/local/nginx/conf/server.key;
    access_log /usr/local/nginx/logs/ssl.access.log;
    error_log /usr/local/nginx/logs/ssl.error.log;
    }
  3. 次のコマンドを実行して Nginx を再起動します。

    /usr/local/nginx/sbin/nginx -s reload

ステップ 16:Nginx と PHP のセキュリティ推奨事項

PHP は人気のあるサーバーサイドスクリプト言語です。`/etc/php.ini` ファイルを次の設定で編集します。

# 危険な関数の無効化
disable_functions = phpinfo, system, mail, exec
## リソースの制限を試みる ##
# 各スクリプトの最大実行時間 (秒)
max_execution_time = 30
# 各スクリプトがリクエストデータの解析に費やす最大時間
max_input_time = 60
# スクリプトが消費できる最大メモリ量 (8MB)
memory_limit = 8M
# PHP が受け入れる POST データの最大サイズ
post_max_size = 8M
# HTTP ファイルアップロードを許可するかどうか
file_uploads = Off
# アップロードされるファイルの最大許容サイズ
upload_max_filesize = 2M
# PHP エラーメッセージを外部ユーザーに公開しない
display_errors = Off
# PHP 環境への外部アクセスを制限
safemode_allowed_env_vars = PHP
# PHP 情報の漏洩を制限
expose_php = Off
# すべてのエラーをログに記録
log_errors = On
# 許容される PHP post サイズを最小化
post_max_size = 1K
# PHP が適切にリダイレクトすることを確認
cgi.force_redirect = 0
# 必要でない限りアップロードを許可しない
file_uploads = Off
# リモートファイルのオープンを回避
allow_url_fopen = Off

ステップ 17:可能であれば chroot jail で Nginx を実行

Nginx を chroot jail に配置することで、他のディレクトリへの不正アクセスの可能性を減らすことができます。Nginx のインストールで従来の chroot 設定を使用できます。可能であれば、FreeBSD jails、Xen、OpenVZ コンテナーなどの仮想化技術を使用してください。

ステップ 18:ファイアウォールレベルでの IP ごとの接続制限

Web サーバーは、1 秒あたりの接続を監視および制限する必要があります。PF と Iptables の両方で、エンドユーザーが Nginx サーバーに到達する前にブロックできます。次の例では、IP アドレスが 60 秒以内にポート 80 への接続を 15 回以上行うと、その IP アドレスをブロックします。接続制限は、特定のニーズに基づいて設定できます。

/sbin/iptables -A INPUT -p tcp -dport 80 -i eth0 -m state -state NEW -m recent -set
/sbin/iptables -A INPUT -p tcp -dport 80 -i eth0 -m state -state NEW -m recent -update -seconds 60  -hitcount 15 -j DROP
service iptables save

ステップ 19:Web サーバーを保護するためのオペレーティングシステムの設定

前述のように、SELinux を有効にし、/nginx ドキュメントルートディレクトリの権限を正しく設定します。Nginx はユーザー `nginx` として実行されます。ただし、ルートディレクトリ (たとえば /nginx/usr/local/nginx/html) は、ユーザー `nginx` が所有したり、書き込み可能であってはなりません。次のコマンドを実行して、不正な権限を持つファイルを見つけます。

find /nginx -user nginx
find /usr/local/nginx/html -user nginx

次のコマンドを実行して権限を表示します。

ls -l /usr/local/nginx/html/

システムは次のような出力を表示します。

-rw-r-r- 1 root root 925 Jan  3 00:50 error4xx.html
-rw-r-r- 1 root root  52 Jan  3 10:00 error5xx.html
-rw-r-r- 1 root root 134 Jan  3 00:52 index.html

次のコマンドを使用して、vi または他のテキストエディターによって作成されたバックアップファイルを見つけます。次に、`find` コマンドの `-delete` オプションを使用してこれらのファイルを削除します。

find /nginx -name ‘.?’ -not -name .ht -or -name ‘~’ -or -name ‘.bak’ -or -name ‘.old*’
find /usr/local/nginx/html/ -name ‘.?’ -not -name .ht -or -name ‘~’ -or -name ‘.bak’ -or -name ‘.old*

ステップ 20:Nginx のアウトバウンド接続の制限

ハッカーは `wget` などのツールを使用して、サーバーからローカルファイルをダウンロードする可能性があります。Iptables を使用して、`nginx` ユーザーからのアウトバウンド接続をブロックできます。`ipt_owner` モジュールは、ローカルで生成されたパケットの作成者と一致させようとします。次の例では、ユーザー `vivek` のみがポート 80 でのアウトバウンド接続を行うことを許可します。

/sbin/iptables -A OUTPUT -o eth0 -m owner -uid-owner vivek -p tcp -dport 80 -m state -state NEW,ESTABLISHED  -j ACCEPT

これらの設定を完了すると、Nginx サーバーははるかに安全になり、Web ページを公開する準備が整います。ただし、WordPress やその他のサードパーティプログラムなど、ご使用の Web アプリケーションに固有のセキュリティ情報も確認する必要があります。