最近、Qiufu がクライアントの Web サイトを保守していたとき、クライアントは海外 IP からのアクセスをブロックするよう要求しました。ログによると、攻撃している IP のほとんどは海外からのもので、ターゲット ユーザーは国内であったため、国内 IP のみがアクセスを許可されていました。 Web サイトでは、ほとんどの CC および DDoS 攻撃をブロックできます。実際にテストした結果、効果は依然として良好であり、再攻撃のコストが大幅に増加していることがわかりました。
しかし、Cloudflare CDN を使用した後、Web サイトが取得する IP アドレスはすべて Cloudflare の CDN ノードから取得できず、防御効果が大幅に低下するという問題が判明しました。幸いなことに、Cloudflareは、訪問者のIPアドレスを X-Forwarded-ForヘッダーとCF-Connecting-IPヘッダーに含めることで、すでにこれを考えてくれています。
X-Forwarded-For ヘッダーを使用すると、Nginx の場合は ngx_http_realip_module モジュールを使用し、Apache の場合は mod_remoteip モジュールを使用してユーザーの実際の IP を取得できます。この記事では、ngx_http_realip_module モジュールと mod_remoteip モジュールをコンパイルして有効にして、ユーザーの実際の IP アドレスを取得する方法を共有します。
一般に、CDN ベンダーは X-Forwarded-For や X-Real_IP などの標準プロトコルを採用しているため、この記事で紹介するユーザーの実際の IP を取得するアクセスは、基本的に他の CDN ベンダーにも適用できます。 CDN アクセラレーション、サーバーの最適化、およびアクセラレーション方法の詳細については、次を参照してください。
- Cloudflare パートナーのアクセス管理 Cloudflare CDN 対応 Railgun 動的アクセラレーション
- Youpaiyun CDN アクセラレーション アプリケーション チュートリアル - ワンクリック ミラーリング、静的動的 CDN、無料 SSL
- WordPress で Nginx fastcgi_cache キャッシュ アクセラレーション メソッドを有効にする - Nginx 構成例
1. Nginx が ngx_http_realip_module をコンパイルします
1.1 Oneinstack コンパイル
Oneinstack ワンクリック パッケージを使用している場合は、次のコマンドを使用して ngx_http_realip_module をコンパイルできます。
#下编译安装nginx的时候,都编译安装的哪些模块 [root@wzfoume ~]# nginx -V nginx version: nginx/1.14.2 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC) built with OpenSSL 1.1.1a 20 Nov 2018 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-openssl=../openssl-1.1.1a --with-pcre=../pcre-8.42 --with-pcre-jit --with-ld-opt=-ljemalloc #进入到oneinstack的nginx安装目录下,如果没有请先解压 [root@wzfoume src]# cd /root/oneinstack/src [root@wzfoume src]# tar xzf nginx-1.14.2.tar.gz [root@wzfoume src]# cd /root/oneinstack/src/nginx-1.14.2 [root@wzfoume nginx-1.14.2]# ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-openssl=../openssl-1.1.1a --with-pcre=../pcre-8.42 --with-pcre-jit --with-ld-opt=-ljemalloc --with-http_realip_module make #如果出现错误,应该是依赖路径不对,请cd ..到上一个目录解压相应的软件 tar xzf pcre-8.42.tar.gz tar xzf openssl-1.0.2q.tar.gz tar xzf openssl-1.1.1a.tar.gz #编译完成,备份原先配置,然后替换nginx二进制文件 mv /usr/local/nginx/sbin/nginx{,_`date +%F`} #备份nginx cp objs/nginx /usr/local/nginx/sbin #查看是否已经把http_realip_module模块加入进去 nginx -V
1.2 LNMP コンパイル
LNMP ワンクリック パッケージを使用している場合は、lnmp インストール ディレクトリで lnmp.conf を見つけて編集し、realip を Nginx_Modules_Options
に追加し、./upgrade.sh nginx
を保存して実行します。 Nginxをアップグレードするだけです。コマンドは次のとおりです。
Nginx_Modules_Options='--with-http_realip_module'
1.3 BT パゴダ パネル
BT Pagoda パネルを使用している場合は、次のコマンドを使用して ngx_http_realip_module をコンパイルできます。
#宝塔面板安装模块 #先查看一下本机的Nginx配置情况 [root@cs ~]# nginx -V nginx version: nginx/1.14.2 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) built with OpenSSL 1.0.2l 25 May 2017 TLS SNI support enabled configure arguments: --user=www --group=www --prefix=/www/server/nginx --with-openssl=/www/server/nginx/src/openssl --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --add-module=/www/server/nginx/src/nginx-http-concat --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-stream --with-stream_ssl_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-pcre=pcre-8.40 --with-ld-opt=-ljemalloc #开始下载Nginx,这里用的是1.15.1,你也可以下载其它的版本 wget http://nginx.org/download/nginx-1.15.1.tar.gz tar -xzvf nginx-1.15.1.tar.gz cd nginx-1.15.1 #下面的命令只是在上面的Nginx -v得到的配置详情后加上了--with-http_realip_module,目的是为了保持原来的配置不变同时又增加新的模块 ./configure --user=www --group=www --prefix=/www/server/nginx --with-openssl=/www/server/nginx/src/openssl --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --add-module=/www/server/nginx/src/nginx-http-concat --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-stream --with-stream_ssl_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-pcre=pcre-8.40 --with-ld-opt=-ljemalloc --with-http_realip_module #只编译不安装 make #先停用Nginx,然后替换新的Nginx并查看模块是否已经加载。命令如下: mv /www/server/nginx/sbin/nginx /www/server/nginx/sbin/nginx-wzfou.backup cp objs/nginx /www/server/nginx/sbin/nginx nginx -V #重启Nginx
2. Nginx 設定 set_real_ip_from
ngx_http_realip_module をコンパイルした後は、set_real_ip_from コードを Nginx 構成ファイルに追加するだけです。例は次のとおりです。
set_real_ip_from 222.222.222.222; #这里是需要填写具体的CDN服务器IP地址,可添加多个 set_real_ip_from 222.222.111.111; real_ip_header X-Forwarded-For; real_ip_recursive on;
CloudFlare の無料 CDN を使用している場合は、次のコードを Nginx 構成ファイルに追加してください。
location / { set_real_ip_from 103.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 104.16.0.0/12; set_real_ip_from 108.162.192.0/18; set_real_ip_from 131.0.72.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 162.158.0.0/15; set_real_ip_from 172.64.0.0/13; set_real_ip_from 173.245.48.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 190.93.240.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; set_real_ip_from 199.27.128.0/21; set_real_ip_from 2400:cb00::/32; set_real_ip_from 2606:4700::/32; set_real_ip_from 2803:f800::/32; set_real_ip_from 2405:b500::/32; set_real_ip_from 2405:8100::/32; set_real_ip_from 2c0f:f248::/32; set_real_ip_from 2a06:98c0::/29; # use any of the following two real_ip_header CF-Connecting-IP; #real_ip_header X-Forwarded-For; } #不要忘记重启nginx service nginx restart
通常、CloudFlare の IP アドレスは変更されません: https://www.cloudflare.com/ips/ ですが、念のため、wzfou.com では CloudFlare を自動的に更新する IP アドレスを設定することをお勧めします。スケジュールされたタスクは、最新の IP を Nginx 構成ファイルに自動的に追加します。コードは以下のように表示されます。
#在nginx配置目录创建cloudflare_ip.conf文件 touch /usr/local/nginx/conf/cloudflare_ip.conf #修改原有的vhost配置,将原来第五步配置的信息改为 include cloudflare_ip.conf; #创建自更新脚本update_cloudflare_ip.sh(假定该文件放在 /root 目录下),内容如下: #!/bin/bash echo "#Cloudflare" > /usr/local/nginx/conf/cloudflare_ip.conf; for i in `curl https://www.cloudflare.com/ips-v4`; do echo "set_real_ip_from $i;" >> /usr/local/nginx/conf/cloudflare_ip.conf; done for i in `curl https://www.cloudflare.com/ips-v6`; do echo "set_real_ip_from $i;" >> /usr/local/nginx/conf/cloudflare_ip.conf; done echo "" >> /usr/local/nginx/conf/cloudflare_ip.conf; echo "# use any of the following two" >> /usr/local/nginx/conf/cloudflare_ip.conf; echo "real_ip_header CF-Connecting-IP;" >> /usr/local/nginx/conf/cloudflare_ip.conf; echo "#real_ip_header X-Forwarded-For;" >> /usr/local/nginx/conf/cloudflare_ip.conf; #配置crontab 每周一的上午5点更新 0 5 * * 1 /bin/bash /root/update_cloudflare_ip.sh
3. Apache 設定 mod_remoteip モジュール
3.1 apache 2.4
Apache 2.4 に付属する mod_remoteip モジュールをインストールする必要はありません。以下の手順に従います。
#启用模块 vim /usr/local/apache/conf/httpd.conf Include conf/extra/httpd-remoteip.conf #添加如下内容 vim /usr/local/apache/conf/extra/httpd-remoteip.conf LoadModule remoteip_module modules/mod_remoteip.so RemoteIPHeader X-Forwarded-For RemoteIPInternalProxy 127.0.0.1/24 #CloudFlare IP Ranges RemoteIPInternalProxy 103.21.244.0/22 RemoteIPInternalProxy 103.22.200.0/22 RemoteIPInternalProxy 103.31.4.0/22 RemoteIPInternalProxy 104.16.0.0/12 RemoteIPInternalProxy 108.162.192.0/18 RemoteIPInternalProxy 131.0.72.0/22 RemoteIPInternalProxy 141.101.64.0/18 RemoteIPInternalProxy 162.158.0.0/15 RemoteIPInternalProxy 172.64.0.0/13 RemoteIPInternalProxy 173.245.48.0/20 RemoteIPInternalProxy 188.114.96.0/20 RemoteIPInternalProxy 190.93.240.0/20 RemoteIPInternalProxy 197.234.240.0/22 RemoteIPInternalProxy 198.41.128.0/17 #你的CDN的IP,可以重复添加 #修改日志格式,在日志格式中加上%a,然后重启apache即可 LogFormat "%h %a %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined LogFormat "%h %a %l %u %t "%r" %>s %b" common LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i" %I %O" combined
3.2 apache 2.2
Apache 2.2 では mod_remoteip モジュールをインストールする必要があります。方法は次のとおりです。
wget https://github.com/ttkzw/mod_remoteip-httpd22/raw/master/mod_remoteip.c /usr/local/apache/bin/apxs -i -c -n mod_remoteip.so mod_remoteip.c #启用模块 vim /usr/local/apache/conf/httpd.conf Include conf/extra/httpd-remoteip.conf #添加如下内容,然后重启apache即可 vim /usr/local/apache/conf/extra/httpd-remoteip.conf LoadModule remoteip_module modules/mod_remoteip.so RemoteIPHeader X-Forwarded-For RemoteIPInternalProxy 127.0.0.1 #你的CDN的IP,可以重复添加
4. WebサイトではCloudflare CDNからのIPアクセスのみが許可されています
上記では、ngx_http_realip_module および mod_remoteip モジュールをインストールすることでユーザーの実際の IP アドレスを取得しましたが、CC または DDoS 攻撃を防ぐために Cloudflare のセキュリティ保護機能を使用する必要がある場合があります。つまり、Cloudflare CDN IP のみにアクセスを許可する必要があります。
IP アクセスを直接拒否および許可する Nginx のコード例は次のとおりです。
location / { deny 192.168.1.1; allow 192.168.1.0/24; allow 10.1.1.0/16; allow 2001:0db8::/32; #Railgun IP deny all; }
Cloudflare CDN の IP のみがウェブサイトにアクセスできるようにする場合は、Cloudflare CDN の IP を nginx 設定の許可範囲に直接追加できます。
#直接加入 # https://www.cloudflare.com/ips # IPv4 allow 103.21.244.0/22; allow 103.22.200.0/22; allow 103.31.4.0/22; allow 104.16.0.0/12; allow 108.162.192.0/18; allow 131.0.72.0/22; allow 141.101.64.0/18; allow 162.158.0.0/15; allow 172.64.0.0/13; allow 173.245.48.0/20; allow 188.114.96.0/20; allow 190.93.240.0/20; allow 197.234.240.0/22; allow 198.41.128.0/17; # IPv6 allow 2400:cb00::/32; allow 2405:8100::/32; allow 2405:b500::/32; allow 2606:4700::/32; allow 2803:f800::/32; allow 2c0f:f248::/32; allow 2a06:98c0::/29;
Cloudflare CDN IP を自動的に更新します。 Cloudflare CDN IP を Nginx 構成に手動で追加するのは簡単で便利ですが、Cloudflare CDN IP が変更されると、Cloudflare CDN IP を定期的に自動的に更新するスクリプトを作成する必要があります。これを Nginx 構成に追加すると、コードは次のようになります。
touch /usr/local/nginx/conf/allow_ip.conf #修改网站nginx配置,加入以下代码: include /usr/local/nginx/conf/allow_ip.conf; vim /data/script/allow_cf_ip.sh #!/bin/bash echo "#Cloudflare" > /usr/local/nginx/conf/allow_ip.conf; for i in `curl https://www.cloudflare.com/ips-v4`; do echo "allow $i;" >> /usr/local/nginx/conf/allow_ip.conf; done for i in `curl https://www.cloudflare.com/ips-v6`; do echo "allow $i;" >> /usr/local/nginx/conf/allow_ip.conf; done #添加定时任务 0 5 * * 1 /bin/bash /data/script/allow_cf_ip.sh
5. まとめ
CDN アクセラレーションを使用した後、Web サイトで取得したユーザー IP が CDN IP になります。ユーザーの実際の IP を取得したい場合は、Nginx と Apache のモード機能を使用する必要があります。もちろん、WordPress などの PHP を使用している場合は、次のコードを WordPress 構成ファイルに直接追加するだけです。
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $list = explode(‘,’,$_SERVER['HTTP_X_FORWARDED_FOR']); $_SERVER['REMOTE_ADDR'] = $list[0]; }
ここでの特別な注意事項は、Cloudflare Railgun 動的アクセラレーションを有効にする場合 (マイニング ステーションの Cloudflare パートナー アクセス管理がこの無料サービスを提供します)、Railgun サーバー IP を構成に忘れずに追加することです。これは、Railgun を有効にした後、Web サイトが IP を取得するためです。取得されるアドレスはすべて Railgun サーバーから取得されます。