CDN または を利用したクライアントのリアル IP の取得
背景情報
CDN 高速化サービスを利用すると、ユーザーのアクセスパスは「クライアント → アクセラレーションノード → オリジンサーバー」に変わります。そのため、オリジンサーバーはデフォルトでクライアントのリアル IP アドレスではなく、CDN ノードの IP アドレスを取得します。これにより、アクセスデータ統計の精度に影響が出ます。
この問題を解決するには、クライアントのリアル IP アドレスを取得するようにオリジンサーバーを設定する必要があります。デフォルトでは、Alibaba Cloud CDN および は、ali-cdn-real-ip リクエストヘッダーでクライアントの IP アドレスをオリジンサーバーに転送します。
ali-cdn-real-ip ヘッダーは、CDN または ノードに直接接続するクライアントの IP アドレスを取得します。クライアントが別のプロキシサーバー経由で CDN または にアクセスする場合、このヘッダーにはプロキシサーバーの IP アドレスが含まれます。
操作手順
このトピックでは、Nginx オリジンサーバーでクライアントのリアル IP アドレスを取得する 3 つの方法を紹介します。
-
Nginx のアクセスログにクライアントのリアル IP アドレスを記録する。
-
クライアントのリアル IP アドレスを含むカスタムフィールドをレスポンスヘッダーに追加する。
-
特定の API エンドポイントを介して、レスポンスボディでクライアントのリアル IP アドレスを直接返す。
カスタムログフォーマットの設定
log_format ディレクティブを使用して、custom_log という名前の新しいログフォーマットを定義します。このフォーマットは、デフォルトのログ情報に $http_ali_cdn_real_ip 変数を追加して、ali-cdn-real-ip リクエストヘッダーの値を記録します。
log_format custom_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'ali_cdn_real_ip:"$http_ali_cdn_real_ip"';
テストエンドポイントの設定
location ディレクティブを使用して、クライアントのリアル IP アドレスを直接返す /api/ip エンドポイントを設定します。
location /api/ip {
# リクエストヘッダーからクライアントのリアル IP を取得
set $real_ip $http_ali_cdn_real_ip;
# リアル IP をレスポンスヘッダーに追加
add_header realip $real_ip;
# レスポンスのコンテンツタイプを設定
add_header Content-Type text/plain;
# レスポンスボディでリアル IP を返す
return 200 $real_ip;
}
完全な設定例
以下に Nginx の完全な設定例を示します。server_name などのパラメーターを要件に合わせて置き換えてください。
-
Nginx の設定を変更した後は、Nginx サービスを再起動する必要があります。
-
この設定を使用する場合、CDN または のデフォルトのオリジンホストを
server_nameの値と一致させるように設定する必要があります。
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# ali_cdn_real_ip フィールドを追加してログフォーマットをカスタマイズ
log_format custom_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'ali_cdn_real_ip:"$http_ali_cdn_real_ip"';
sendfile on;
keepalive_timeout 65;
# Gzip 設定
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
server {
listen 80;
# 高速化ドメイン名に置き換えてください
server_name localhost;
# カスタムログフォーマットを使用
access_log /var/log/nginx/access.log custom_log;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# クライアントのリアル IP アドレスを取得するためのエンドポイント
location /api/ip {
# リクエストヘッダーからクライアントのリアル IP を取得
set $real_ip $http_ali_cdn_real_ip;
# リアル IP をレスポンスヘッダーに追加
add_header realip $real_ip;
# レスポンスのコンテンツタイプを設定
add_header Content-Type text/plain;
# レスポンスボディでリアル IP を返す
return 200 $real_ip;
}
# エラーページの設定
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# HTTPS の場合は、以下の例をご参照ください
# server {
# listen 443 ssl;
# server_name localhost; # 高速化ドメイン名に置き換えてください
#
# ssl_certificate /path/to/cert.pem;
# ssl_certificate_key /path/to/privkey.pem;
#
# access_log /var/log/nginx/access.log custom_log;
#
# location /api/ip {
# set $real_ip $http_ali_cdn_real_ip;
# add_header realip $real_ip;
# add_header Content-Type text/plain;
# return 200 $real_ip;
# }
# }
}
検証
レスポンスヘッダーとレスポンスボディの検証
CDN の高速化ドメイン名経由で /api/ip インターフェイスにアクセスします。
-
レスポンスヘッダーには、クライアントのリアル IP アドレスを保持する
realipフィールドが含まれます。~ % curl -voa "http://nginx.xxx.com/api/ip" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Host nginx.xxx.com:80 was resolved. * IPv6: xxx * IPv4: * Trying xxx... * Connected to nginx.xxx.com (xxx) port 80 > GET /api/ip HTTP/1.1 > Host: nginx.xxx.com > User-Agent: curl/8.7.1 > Accept: */* > * Request completely sent off 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0< HTTP/1.1 200 OK < Server: Tengine < Content-Type: text/plain < Content-Length: 13 < Connection: keep-alive < Date: Tue, 27 Jan 2026 03:02:56 GMT realip: 140.xxx.21 < xxx ens-cache30.l2cn9026[898,0], cache11.cn3259[944,944,200-0,M], cache14.cn3259[976,0] < Ali-Swift-Global-Savetime: 1769482976 < X-Cache: MISS TCP_MISS dirn:-2:-2 < X-Swift-SaveTime: Tue, 27 Jan 2026 03:02:56 GMT < X-Swift-CacheTime: 0 < Timing-Allow-Origin: * < EagleId: xxx < { [13 bytes data] 100 13 100 13 0 0 11 0 0:00:01 0:00:01 --:--:-- 11 -
レスポンスボディには、クライアントのリアル IP アドレスが含まれます。
curl "http://nginx.xxx.com/api/ip" 140.xxx.21x
アクセスログの検証
オリジンサーバーで、Nginx のアクセスログ (デフォルトパス:/var/log/nginx/access.log) を確認します。ログには ali_cdn_real_ip フィールドとそれに対応する値が含まれます。
[root@xxx ~]# tail -1000f /var/log/nginx/access.log
123.xxx.25 - - [27/Jan/2026:11:02:56 +0800] "GET /api/ip HTTP/1.1" 200 13 "-" "curl/8.7.1xxx ali_cdn_real_ip:"140.xxx.21"
よくある質問
CDN のログインリダイレクト失敗に関するトラブルシューティング
現象
CDN で高速化されたウェブサイトで、ユーザーがバックエンドのログインページで正しい認証情報を入力した後、ページが期待どおりにリダイレクトされません。ログインページに留まるか、エラーページにリダイレクトされます。
原因
オリジンフェッチ中に、ログインページをロードするリクエストとログイン認証情報を送信するリクエストが、異なる L2 ノードを経由する場合があります。これにより、2 つのリクエスト間でオリジンフェッチの IP アドレスが一致しなくなる可能性があります。オリジンサーバーで IP 変更検知メカニズムや、セッションと IP のバインディングチェックなどの類似のセキュリティポリシーが有効になっている場合、IP アドレスの変更を検知してリクエストを拒否します。これにより、ログイン後のリダイレクトが失敗します。
解決策
-
オリジンサーバーにログインし、IP 変更検知や厳格なセッションと IP のバインディングチェックに関するセキュリティポリシーを確認します。
-
このような制限が有効になっている場合は、次のいずれかのアクションを実行してください。
-
オリジンサーバーのセキュリティポリシーで、CDN のバックトゥオリジン IP アドレスの CIDR ブロックを許可リストに追加します。これらの CIDR ブロックのリストを取得するには、関連ドキュメントをご参照ください。
-
オリジンサーバーで厳格な IP 一貫性チェック機能を無効にします。
-