原文地址

WordPress防CC攻击设置教程:https://www.hostloc.com/thread-750430-1-1.html

WordPress动静分离方法汇总:https://www.hostloc.com/thread-751158-1-1.html

做一个永不暴露真实IP的网站,防止DDoS:https://www.hostloc.com/thread-754357-1-1.html

备份镜像

WordPress防CC攻击设置教程

WordPress是一个功能强大的CMS,几乎可以通过插件和主题实现任意功能。功能强大的同时,WordPress因动态性而性能欠佳,不优化的情况下可能多刷新几次就挂了,更不用说恶意构造的CC攻击了。

cc攻击
cc攻击
前文 服务器简易防CC攻击设置 简要介绍了网站遇到CC攻击的通用解决办法,本文针对WordPress给出较为全面的WordPress防CC攻击设置。

WordPress的弱点
WordPress默认没有做静态化,所有请求都是动态生成内容再发送。访客少的情况下问题不大,流量起来了不使用缓存或者静态化基本上就GG了。所以WordPress性能优化中很重要的一条便是使用缓存/静态化插件。

开启了缓存/静态化插件,页面、文章访问一次后被缓存,下次请求不用再动态生成,性能极大改善,低配VPS也能轻松负载上万的ip,美滋滋。

但是对于WordPress的CC攻击,缓存远远不够,因为其致命弱点未解决:WordPress的动态性是其弱点,弱点中的弱点则是搜索。文章数量是固定的,但是搜索词无穷无尽,因此缓存对CC攻击不起作用。如果文章数上万,每一次搜索都很耗费资源,多来几次搜索型的CC攻击WordPress就趴下了。

总结一下:WordPress的弱点是动态化,致命弱点是搜索,必须解决这两个弱点才能防范住(缓解)CC攻击。

WordPress防CC攻击设置
了解了WordPress的弱点,接下来介绍WordPress防CC攻击设置。

安装缓存/静态化插件,解决WordPress动态生成网页的弱点。本站用的WordPress Super Cache,其配置简单,性能也好。安装、启用插件后主要设置为:1. “通用”中勾选“启用缓存功能 (推荐)”;2. 高级中做如下设置:
WP Super Cache设置
WP Super Cache设置
不勾选“不要为GET请求缓存”,理论上解决了搜索的攻击问题,但是会让你的网站不正常

2. 接着解决搜索的弱点。同通常CC攻击防范,主要手段是限制请求数和速率。假设我们用的Nginx,解决方法为:

2.1 在Nginx主配置文件(例如/etc/nginx/nginx.conf)的 http 段中分配限制计数区:

http {
# 一些其他配置

# 增加下面三行,作用分别是:1. 分配10MB大小的连接数计数区(能统计16万个ip);
# 2. 分配正常请求的限制区,每秒请求次数不能超过10(请按照自己需求更改)
# 3. 分配搜索限制区,每分钟搜索不能超过10次
limit_conn_zone $binary_remote_addr zone=limit_conn:10m;
limit_req_zone $binary_remote_addr zone=limit_req:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=limit_req_s:10m rate=10r/m;

# 其他设置
}
2.2 打开网站配置文件(例如/etc/nginx/conf.d/tlanyan.conf),在server段中增加防CC攻击设置:

server {
# 一些其他配置

# 增加以下配置行
limit_conn limit_conn 10; # 单个ip的并发连接数不能超过10(请按照自己情况修改)
limit_req zone=limit_req burst=10 nodelay; # 使用limit_req限制正常请求
location / {
# 注意:一定要在 location / 添加,否则后台功能可能不正常
if ($query_string ~ "s=") {
rewrite ^ /search.php?$query_string last; # 将搜索请求重定向
}
# location / 的其他设置
}
location = /search.php {
limit_req zone=limit_req_s burst=5 nodelay; # 限制搜索频率
fastcgi_pass php-fpm; # 这里请改成你php的设置
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}

# 其他设置
}
上面的配置中,最重要的设置从 if ($query_string ~ "s=")开始,将搜索重定向,然后使用我们自定义的搜索频率设置。超过这个搜索频率,直接503返回错误信息。

2.3 使用 nginx -t 命令检查有无配置错误,然后 systemctl restart nginx 重启Nginx。

于是,通过连接数限制,单个ip无法无限发起对服务器的连接;通过正常请求速率,限制单ip对普通文章页面的请求速率;通过搜索限制,大大限制搜索频率,从而有效防止CC攻击,提升服务器性能。

配置好重启Nginx后,打开自己的WordPress博客,多搜索几次试试,就会出现”503 Service Temporarily Unavailable”提示,说明我们的搜索限制起作用了。

delay参数、其他事项请参考 服务器简易防CC攻击设置

其他
除了WordPress使用缓存插件,也可以开启Nginx的缓存功能提升性能,操作请参考:Nginx配置fastcgi cache
“503 Service Temporarily Unavailable”这个页面可以修改,操作请参考:Nginx自定义错误页
可以结合fail2ban将恶意ip加入黑名单,操作请参考:使用fail2ban防止恶意扫描和CC攻击

WordPress动静分离方法汇总

现代网页不仅只有一个html,经常还包含了大量的js脚本、css样式表、图片、字体等资源文件。因浏览器对单域名有连接数限制,优化网页加载速度的一个重要手段是动静分离。前文 WordPress性能优化 介绍了常用的WordPress性能优化方法,本文详细介绍几种WordPress动静分离方法。

WordPress动静分离
WordPress动静分离
WordPress动静分离方法
动静分离,即将js脚本、css样式表、图片图标、字体等静态资源文件托管在不同的域名上,从而浏览器可以同时下载页面内容和静态文件,以达到网页加速的目的。以本站的 V2ray教程 文章为例,页面内容和下面的评论是动态生成的,文章里的图是静态的。通过动静分离,文章内容、评论和图片可以同时下载,从而加快了网页打开速度。

下面介绍本人所知的WordPress动静分离方法,并指出其优缺点。作为例子,下文中总是以 tlanyan.me 为WordPress博客主域名,static.tlanyan.me 为静态资源用的域名。

WordPress域名替换
我们可以在WordPress页面输出前,将静态资源url替换成静态域名,从而达到动静分离的目的。

具体操作为:

1. 创建动态域名的nginx配置文件,输入如下内容:

server {
listen 80;
server_name static.tlanyan.me; # 请替换成自己的域名

return 301 https://static.tlanyan.me$request_uri; # 请替换成自己的域名
}

server {
listen 443 ssl http2;
ssl_certificate ssl证书路径;
ssl_certificate_key ssl密钥路径;
access_log /var/log/nginx/static.tlanyan.access.log main buffer=64k flush=30s;
error_log /var/log/nginx/static.tlanyan.error.log;

root /var/www/tlanyan; # 请修改成网站实际目录

# 非静态资源转发到主站。此配置涉及到安全问题,非常重要,请务必配置!!
location / {
if ( $request_uri !~* .*\.(js|css|png|jpeg|jpg|gif|bmp|ico|ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|rss|atom|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf))
{
return 301 https://tlanyan.me$request_uri; #tlanyan.me请改成自己的域名
}
}

# 静态资源配置
location ~* .*\.(js|css|png|jpeg|jpg|bmp|ico|ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|rss|atom|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
expires max;
add_header Access-Control-Allow-Origin *; # 解决字体跨站问题
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,OPTIONS;
}
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn)
{
return 404;
}
}
2. 在网页内容输出前,修改静态资源域名为静态域名。具体操作是:编辑主题的functions.php文件,加入如下内容:

function replace_domain($content) {
# tlanyan.me请改成自己的域名
$pattern = '/https:\/\/tlanyan\.me\/wp-([^"\']*?)\.(js|css|png|jpeg|jpg|bmp|ico|ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|rss|atom|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)/i';
$replace = 'https://static.tlanyan.me/wp-$1.$2';
return preg_replace($pattern, $replace, $content);
}

add_action('init', 'replace_domain');
接下来重启Nginx,刷新网站文章,看看图片、js等文件路径的域名有没有换成静态域名吧。

修改WordPress上传域名
对于WordPress,除了主题所用的css、字体等静态资源,主要静态资源是用户上传的图片和文件。好消息便是,用户可以自定义上传目录和上传的域名,从而轻松做到静态分离。

操作方法为:

1. 登录网页后台,打开 https://你的域名/wp-admin/options.php(只能手动在浏览器打开),找到 upload_path 和 upload_url_path 两个选项,第一选项用来设置上传图片存放的文件夹(默认是 wordpress安装目录/wp-content/uploads),第二个是设置文件的域名:

WordPress自定义上传文件域名
WordPress自定义上传文件域名
2. 我们修改 upload_url_path 为静态域名,然后页面拖到下面点击“保存修改”;

3. 新建静态域名的Nginx配置文件,输入如下内容:

server {
listen 80;
server_name static.tlanyan.me; # 请替换成自己的域名

return 301 https://static.tlanyan.me$request_uri; # 请替换成自己的域名
}

server {
listen 443 ssl http2;
ssl_certificate ssl证书路径;
ssl_certificate_key ssl密钥路径;
access_log /var/log/nginx/static.tlanyan.access.log main buffer=64k flush=30s;
error_log /var/log/nginx/static.tlanyan.error.log;

root /var/www/tlanyan/wp-content/uploads; # 请修改成网站实际目录,注意根目录为 wp-content/uploads
}
由于 wp-content/uploads 目录只有上传的文件,不存在敏感信息,因此无需做额外安全设置。

4. 经过上述配置,新文章中的图片会使用静态域名,但旧文章还是原来的链接。我们可以通过数据库批量更新链接,操作为:登录数据库,执行这个SQL语句:update wp_posts set post_content=replace(post_content, 'tlanyan.me/wp-content/uploads', 'static.tlanyan.me');。注意语句中的tlanyan.me域名请换成你自己的域名。

这样,文章中的图片和文件链接便与文章做到动静分离了。

Nginx重定向
如果我们使用Nginx作为前端服务器,可以通过Nginx重定向功能将所有的静态资源请求转到静态域名。

操作如下:

1. 按照 WordPress域名替换 的方法新建静态域名的Nginx配置文件;

2. 在主域名的Nginx配置文件对静态资源做如下转发处理:

server {
# 其他配置
# 静态资源文件重定向
location ~* .*\.(js|css|png|jpeg|jpg|bmp|ico|ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|rss|atom|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
return 301 https://static.tlanyan.me$request_uri; # static.tlanyan.me请改成你的静态域名
}
# 其他配置
}
配置好后记得重启Nginx。

Nginx内容替换
WordPress可以做内容替换,Nginx有sub模块同样能替换网页内容,这样无需改动WordPress便能做到静态资源使用静态域名。

操作如下:

1. Nginx的PHP处理中增加如下替换命令:

location ~ \.php$ {
# 一些fastcgi 配置

# 替换配置
sub_filter_once off;
# 请修改成自己的域名
sub_filter 'https://tlanyan.me/wp-content/uploads' 'https://static.tlanyan.me';
}
2. 按照 修改WordPress上传域名 中的方法新建静态域名Nginx配置文件,然后重启Nginx。

总结
上文介绍了WordPress动静分离的四种办法,这里简单总结一下四种方法的优缺点:

方法 优点 缺点
WordPress域名替换 所有的静态资源都能走静态域名 静态网站需谨慎配置,否则有安全危险
修改WordPress上传域名 官方正统办法,无需对WordPress做修改 只能让上传的文件和图片走静态域名
Nginx重定向 只修改Nginx配置,比较简单 静态资源请求多了一次重定向
Nginx内容替换 只修改Nginx配置,操作简单 不支持正则匹配,只能让上传文件走静态域名

 

做一个永不暴露真实IP的网站

防范DDoS攻击最主要的手段是加钱上高防,同时隐藏网站真实IP。前文 隐藏网站的真实ip 简要介绍了网站隐藏真实ip的基本操作,但不够详细和深入。本文详细介绍几种网站隐藏真实ip的方法和优缺点,让你能真正做一个永不暴露真实IP的网站。

做一个永不暴露真实IP的网站
既然不想暴露网站的真实IP,那么真实服务器前面至少套一层代理。一般来说,位于最前线的反向代理主要有如下几种:

CDN:内容分发网络,就近为用户提供服务,加速访问;
高防IP:高防IP一般位于大带宽的骨干网节点上,用于清洗DDoS流量;
SLB:负载均衡器,用在大流量、繁忙的网站上,常见的SLB有LVS、F5等。
这三种反向代理主要作用不一样,配置好的情况下都能隐藏服务器真实IP。对于普通的网站,使用CDN或者高防就足够,业务量大的情况下才会用到SLB。

下面介绍使用了反向代理的情况下,隐藏网站真实IP的操作。

防火墙
使用防火墙是最简单的做法,即:将反向代理的回源IP加入白名单,屏蔽其他IP的任何请求。

例如使用CloudFlare的免费CDN服务,其回源IP可从 https://www.cloudflare.com/zh-cn/ips/ 获取,然后将其加入白名单,同时屏蔽其他IP:

# 将cf ip地址放在 cf_ips.txt
# 首先将cf的ip加入白名单
while read -r line
do
firewall-cmd --zone=trusted --add-source=$line
done < cf_ips.txt
# 然后移除其他ip对http和https服务的访问
firewall-cmd --remove-service=http
firewall-cmd --remove-service=https
经过上述设置,Cloudflare 的IP能正常访问,其他IP完全无法访问真实ip的网站服务器,很好的隐藏了真实IP。

该方法设置简单,适用于服务器托管单站点的情形。当服务器上托管多个网站,并且某些站点需要直接暴露外网时,这种做法缺乏灵活性,无法实现。

也可以通过Nginx的allow/deny指令达到相同效果

IPv6
对于防火墙和网络不熟悉的网友,可以考虑使用IPv6来隐藏网站的真实IP。具体操作为:

1.找一台有IPv6地址的服务器,只有IPv6的NAT VPS更好。目前IPv6地址正在普及中,许多商家都免费提供IPv6地址,例如 一些VPS商家整理 中的 阿里云、Vultr、Linode、CloudCone,有的还提供不止一个IPv6地址;

2. 设置网站只监听IPv6端口。以Nginx为例,网站配置文件形如:

server {
listen [::]:80;
server_name 主机名; # 请改成自己的主机名

return 301 https://主机名$request_uri;
}
server {
listen [::]:443 ssl http2;
server_name 主机名;
ssl_certificate 证书路径;
ssl_certificate_key ssl密钥路径;
# 其他设置
}
3. 找一家支持只有IPv6的CDN,例如 Cloudflare,设置IPv6解析:

CloudFlare设置ipv6解析
CloudFlare设置ipv6解析
经过上面三步设置,基本上可确保不会泄漏真实IP,原因如下:

1. 绝大多数情况下,人们都会理所当然的找IPv4,不会想到你的网站根本不存在IPv4网络上;

2. 相对于IPv4,IPv6的地址段实在太庞大。即使有zmap这种几小时扫描完全球ipv4段的神器,或者Shodan搜索引擎,也很难从海量地址中寻找单个地址。

如果不放心,可以同样加上防火墙,就万无一失了:

# 首先将cf的ip加入白名单
while read -r line
do
firewall-cmd --zone=trusted --add-source=$line
done < cf_ips.txt
# 然后屏蔽其他地址对ipv6的访问权限
firewall-cmd --add-rich-rule="rule family='ipv6' source address='::0/0' drop"
该方法同样设置简单,以奇招胜出,单台服务器能托管多个网站,并且其他网站可直接暴露不受影响。

CNAME
另一种常见隐藏真实IP方式是使用CNAME,同样无需设置防火墙。其操作如下:

1. CDN回源时使用CNAME方式回源到另一个主机名上。例如www.tlanyan.me回源的www.abcdexfd.com。需要注意的是,前端域名和源站域名最好不是同一个,防止通过爆破二级域名泄漏真实IP;

2. 在源站服务器上设置默认站点,防止通过host方式爆破。由于默认站点只是为了防止SNI方式泄漏真实IP,因此使用自签证书即可:

# 生成密钥
openssl genrsa -out example.key 2048
# 生成证书,期间需要填一些信息
openssl req -new -x509 -days 3650 -key example.key -out example.pem
接着以Nginx为例,设置默认站点:

server {
listen 80 default_server;
server_name example.com;
return 301 https://example.com$request_uri;
}

server {
listen 443 ssl http2;
server_name example.com default_server;
ssl_certificate example.pem;
ssl_certificate_key example.key;
}
然后重启Nginx即可。

该方法无需设置防火墙,设置较为简单,但是需要额外一个域名。

注意事项
以上操作只能让他人在明面上无法直接访问真实服务器,但请仔细阅读 隐藏网站的真实ip 中的建议,防止有发送邮件、WordPress pingback等隐式暴露IP的行为。

遇到DDoS怎么办?
如果域名之前从未用过,一出道就用上面提到的方法,基本上可以保证不会泄漏网站的真实IP。

但是不泄漏真实IP不代表不会被DDoS或者CC攻击,遇到DDoS怎么办?解决办法主要有:

1. 加钱上高防保平安;

2. DNS解析域名到127.0.0.1保平安;

3. 关机保平安。

请根据实际情况和业务需求采取相应措施。