في الآونة الأخيرة، عندما كان Qiufu يحتفظ بموقع الويب الخاص بالعميل، طلب العميل حظر الوصول من عناوين IP الأجنبية، وفقًا للسجلات، جاءت معظم عناوين IP المهاجمة من الخارج، وكان المستخدمون المستهدفون محليين، لذلك تم السماح فقط لعناوين IP المحلية بالوصول. يمكن لموقع الويب حظر الغالبية العظمى من هجمات CC وDDoS. وبعد الاختبار الفعلي، وجد أن التأثير لا يزال جيدًا، وأن تكلفة الهجوم مرة أخرى زادت كثيرًا.

ومع ذلك، تم اكتشاف مشكلة لاحقًا بعد استخدام Cloudflare CDN، وكانت جميع عناوين IP التي حصل عليها موقع الويب من عقد CDN الخاصة بـ Cloudflare. ولم يكن من الممكن الحصول على عناوين IP للمستخدمين الحقيقيين، وتم تقليل تأثير الدفاع بشكل كبير. لحسن الحظ، لقد فكرت Cloudflare بالفعل في هذا الأمر من خلال تضمين عنوان IP الخاص بالزائر في رأس   X-Forwarded-For ورأس CF-Connecting-IP.

باستخدام الرأس X-Forwarded-For، يمكنك استخدام الوحدة ngx_http_realip_module إذا كانت Nginx، أو الوحدة mod_remoteip إذا كانت Apache للحصول على عنوان IP الحقيقي للمستخدم. ستشارك هذه المقالة كيفية تجميع وتمكين وحدة ngx_http_realip_module ووحدة mod_remoteip للحصول على عنوان IP الحقيقي للمستخدم.

بشكل عام، اعتمد بائعو CDN بروتوكولات قياسية مثل X-Forwarded-For وX-Real_IP، وبالتالي فإن الوصول للحصول على عنوان IP الحقيقي للمستخدم المقدم في هذه المقالة ينطبق بشكل أساسي على بائعي CDN الآخرين. لمزيد من المعلومات حول تسريع CDN وتحسين الخادم وطرق التسريع، إليك:

  1. إدارة وصول الشركاء Cloudflare Cloudflare CDN-تمكين التسريع الديناميكي Railgun
  2. البرنامج التعليمي لتطبيق تسريع Youpaiyun CDN - النسخ المتطابق بنقرة واحدة، وCDN الديناميكي الثابت وSSL المجاني
  3. يمكّن 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.conf في دليل تثبيت lnmp وقم بتحريره، وأضف 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;

إذا كنت تستخدم CDN مجاني لـ CloudFlare، فيرجى إضافة الكود التالي إلى ملف تكوين 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

بشكل عام، لن يتغير عنوان IP الخاص بـ CloudFlare، ويمكنك العثور عليه هنا: https://www.cloudflare.com/ips/، ولكن في حالة حدوث ذلك، يوصي موقع wzfou.com بتعيين عنوان IP يقوم بتحديث CloudFlare تلقائيًا تضيف المهمة المجدولة تلقائيًا أحدث عنوان 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. وحدة تكوين أباتشي mod_remoteip

3.1  أباتشي 2.4

لا يلزم تثبيت وحدة mod_remoteip التي تأتي مع Apache 2.4، اتبع الخطوات التالية:

#启用模块

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  أباتشي 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. يسمح موقع الويب بالوصول إلى IP فقط من Cloudflare CDN

أعلاه، حصلنا على عنوان IP الحقيقي للمستخدم عن طريق تثبيت وحدتي ngx_http_realip_module وmod_remoteip، ولكن في بعض الأحيان نحتاج إلى استخدام وظيفة الحماية الأمنية في Cloudflare لمنع هجمات CC أو DDoS، أي السماح فقط لـ Cloudflare CDN IP بالوصول إلى وصولنا.

أمثلة التعليمات البرمجية لـ Nginx التي ترفض وتسمح بالوصول إلى IP هي كما يلي:

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;
}

إذا سمحنا فقط لعنوان IP الخاص بـ Cloudflare CDN بالوصول إلى موقع الويب، فيمكننا إضافة عنوان IP الخاص بـ Cloudflare CDN مباشرةً إلى النطاق المسموح به في تكوين 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، يصبح عنوان IP الخاص بالمستخدم الذي حصل عليه موقعنا هو عنوان IP الخاص بـ CDN. إذا أردنا الحصول على عنوان IP الحقيقي للمستخدم، فيجب علينا استخدام وظائف الوضع الخاصة بـ Nginx وApache. بالطبع، إذا كنت تستخدم PHP، مثل WordPress، فما عليك سوى إضافة الكود التالي مباشرة إلى ملف تكوين WordPress الخاص بك.

if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$list = explode(‘,’,$_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $list[0];
}

تذكير خاص هنا هو أنه إذا قمت بتمكين التسريع الديناميكي لـ Cloudflare Railgun (توفر إدارة وصول شركاء Cloudflare لمحطة التعدين هذه الخدمة المجانية)، تذكر إضافة عنوان IP لخادم Railgun إلى التكوين، لأنه بعد تمكين Railgun، سيحصل موقع الويب على IP العناوين التي تم الحصول عليها كلها من خادم Railgun.

اترك رد