对服务器安全的个人见解 👻

服务器安全一直是一个非常重要的课题,但对于我们这些小站长来说,专业能力相较于运维人员还有所欠缺,对 Linux 操作系统的熟悉程度也不够,更别提分析日志并提前发现和解决问题了。在个人精力和专业能力之间不可避免地要做出一些选择。

我总结了目前在服务器安全方面所做的努力,尽可能减少因个人原因导致的漏洞问题。当然,我毕竟不是专业人员,所提出的观点仅代表个人看法。本篇文章归类于 杂谈

一、云服务商

1.1 登录凭证

选择 SSH 密钥作为登录凭证,而非自定义密码。

1.2 密钥的绑定

SSH 密钥使用 ed25519 加密算法,并可选择设置"密钥短语"(passphrase)以增加安全性。

1.3 防火墙控制

尽量减少开放的端口,并对常见的通用扫描器 IP 段设置黑名单[1]

1.3.1 激进策略

  • 放弃 IPV4 访问,禁用整个 IPV4 段网络;放弃境外流量,对于 IPV6 仅允许中国境内的访问。

  • 更换常用服务的默认端口,例如将 Nginx 的端口从 80 和 443 改为 8880 和 44333,并使用 CDN 进行访问。

防火墙

1.3.2 国内常见 IPV6 段

  • 240e::/16: 中国电信
  • 2408::/15: 中国联通、移动

实际上,中国广电、科技网及国内的云服务商等在使用其他 IP 段。如果你对此有担忧,可以将 IP 段范围扩大到2400::/12,以确保亚太地区[2]的正常访问。

二、应用控制

2.1 SSH 应用

禁止密码登录、只允许密钥登录、更换默认端口
vim /etc/ssh/sshd_config
# 禁止密码登录
PasswordAuthentication no

# 允许密钥登录
PubkeyAuthentication yes

# 修改端口
Port 23322

2.2 Web 应用

2.2.1 DNS 阶段

首先,我们的理想状态是通过域名找不到服务器的真实 IP。备案的话,可以使用国内的 CDN 服务;没有备案时,可以使用 Cloudflare 的代理服务。这两种方法都能有效隐藏真实的服务器地址。

如果你依旧像我一样没心没肺毫不在乎访问体验,那么在 DNS 阶段可以设置成仅解析境内服务。以 DNSPod 为例,如果你购买了专业版,可以新增一条解析线路为云厂商(如阿里云、华为云、京东云、青云、亚马逊云等),解析地址为 127.0.0.1,让那些请求自个儿玩去吧。

:域名 DNS 默认解析在 CDN 设置为境内分发时,会导致境外 IP 访问时直接回源。

2.2.2 访问阶段

拒绝默认域名访问
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 default_server;
listen [::]:443 default_server;
ssl_reject_handshake on;

access_log /www/sites/default.website/log/access.log main;
error_log /www/sites/default.website/log/error.log;

location / {
return 444;
}
}
拒绝非 CDN 请求访问

在 CDN 面板中的回源设置里添加一个只有你知道的请求头和值,然后在对其判断,不符合就返回 444。

只有携带这个请求头才放行
# 私有请求头校验 X-Check
if ($http_x-check != 'helloworld') {
return 444;
}
搭配 Fail2Ban 进行屏蔽

创建 Nginx 过滤器,创建文件 /etc/fail2ban/filter.d/nginx-4xx.conf 并添加以下内容:

[Definition]
failregex = ^<HOST> - .* ".*" 4\d{2} .*
ignoreregex =

创建 Nginx 过滤器,创建文件 /etc/fail2ban/filter.d/nginx-4xx-5xx.conf 并添加以下内容:

[Definition]
failregex = ^<HOST> - .* \[[^\]]*\] ".*" (4\d{2}|5\d{2}) .*
ignoreregex =

创建 Nginx 过滤器,创建文件 /etc/fail2ban/filter.d/fail2ban-recidive.conf 并添加以下内容:

[Definition]
failregex = Ban <HOST>$
ignoreregex = \[fail2ban-recidive\] Ban <HOST>$

配置 Fail2Ban 监狱(Jail),编辑 Fail2Ban 的配置文件 /etc/fail2ban/jail.local,添加以下内容:

[nginx-all-default]
enabled = true
filter = nginx-4xx-5xx
logpath = /www/sites/default.website/log/access.log
maxretry = 1
findtime = 60
bantime = 3600

[nginx]
enabled = true
filter = nginx-4xx
logpath = /www/nginx/log/access.log
maxretry = 20
findtime = 60
bantime = 3600

[fail2ban-recidive]
enabled = true
filter = fail2ban-recidive
logpath = /var/log/fail2ban.log
bantime = -1
findtime = 604800
maxretry = 3

1Panel 的默认站点日志文件的实际位置是:

/opt/1panel/apps/openresty/openresty/www/sites/default.website/log/access.log

创建日志:

sudo touch /var/log/nginx-4xx.log
sudo chmod 640 /var/log/nginx-4xx.log
sudo chown root:adm /var/log/nginx-4xx.log

2.2.3 避免抛出错误信息

避免直接把错误信息展现给用户,不知道的永远是最好的,可以在网站的配置中重定向 5XX 错误。

重定向 4/5xx 请求
# 捕获所有4XX和5XX错误并重定向到返回444的位置
error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 426 428 429 431 451 500 501 502 503 504 505 506 507 508 510 511 = @return_444;

location @return_444 {
return 444;
}

2.2.4 对关键地址进行加密

比如在 Typecho 博客的后台登录页,可以直接利用面板的访问限制功能,对 /admin/ 路径进行简单加密。只有经过授权的用户才能访问该页面,否则会返回 401 Unauthorized 错误。

2.2.5 部署 Web 防火墙

无论你是使用面板的防火墙还是 ModSecurity 防火墙,请务必开启一个。

2.2.6 拉黑无意义的 UA

具体情况具体分析,我的拉黑策略相对激进,以下列内容的 User-Agent 均被我拉黑:

User-Agent 黑名单
一概拉黑
*nmap*|*NMAP*|*HTTrack*|*sqlmap*|*Java*|*zgrab*
*Python*|*python*|*curl*l*Curl*|*wget|*Wget*
*MJ12bot*|*a Palo Alto*|*ltx71*|*censys*|*AhrefsBot*
*Go-http-client*|*CensysInspect*|*toutiao*|*Barkrowler*

三、其他

面板

为面板设置证书,并配置 Nginx 反向代理访问(回源地址:https://127.0.0.1:port)。

数据库

没有必要开放数据库端口,通过 SSH 隧道进行访问,保持数据库的本地连接即可。


  1. Censys IP 段:Can I opt out of Censys scans↩︎

  2. 亚太地区包括:中国、日本、韩国、澳大利亚、新西兰、印度、新加坡、马来西亚、泰国、越南。 ↩︎

评论