你的服务器够安全吗

一份不一定很全的服务器安全防范措施, 但值得看看. (╯-_-)╯~╩╩.

文章地址: https://blog.piaoruiqing.com/2019/11/24/is-your-server-safe-enough/

前言

近期服务器经常被暴力扫描、攻击, 故周末花时间打理下服务器, 将一些可能存在的风险处理掉. 笔者根据实践总结出一份简单的防范措施列表, 希望能对你有帮助.

阅读本文你能收获到:

  • 一些服务器安全防范措施.
  • 快乐 (如果学习能使你快乐的话 ( ̄. ̄) )

一. 防火墙

防火墙采用白名单策略, 只开放必要端口. 如: 80/443以及ssh登录端口.

而数据库、缓存等端口, 最好只允许本地访问, 若需要调试, 建议使用白名单IP、代理等方法进行连接.

80-443

二. 利用内网穿透工具

参考文档: https://github.com/fatedier/frp/

对于有调试需求的服务器而言, 数据库、缓存、消息队列等端口需要开放. 而直接开放端口会给服务器带来不必要的安全隐患. 此时我们必须对访问者进行限制, 如: IP白名单、VPN等. 除此之外, 笔者推荐一个内网穿透工具用来辅助建立调试环境 —— FRP

FRP是一个可用于内网穿透的高性能的反向代理应用, 有多种穿透方式, 可以指定端口进行代理. 我们可以在服务器启动服务端(frps)和客户端(frpc)两个服务, 本地客户端的frpc通过frps监听的唯一端口与服务端的frpc建立连接, 这样就能将服务器上只能内部访问的端口映射到开发者电脑本地端口.

使用FRP的优势: 指定端口、可压缩流量、可加密、服务端只需要暴露frps的端口.

frps-frpc

三. 隐藏无用信息

参考文档:

1). http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header

2). http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens

3. http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_hide_header

通过服务器返回的信息, 攻击者能从中发现一些漏洞, 比如nginx版本、所使用的web服务器等. 而这些信息对于用户来说都是非必要的. 笔者随便找了个网站查看, 如图:

这些细节都可能为攻击者提供途径. 所以有必要屏蔽掉这些信息.

  1. proxy_hide_header {Your-Header}: nginx中, 通过proxy_hide_header可以隐藏掉上游服务返回的某些header.
  2. server_tokens off: server_tokens是nginx版本信息开关, 可以开启或隐藏错误页或header的Server字段后面带的版本号.
  3. fastcgi_hide_header X-Powered-By: 如果您使用的是php-fpm, 这个配置可以隐藏掉header中php及版本信息.

配置完成后执行nginx -s reload后配置即生效.

四. 限流

参考文档: http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

用户正常的访问行为, 不会产生过于频繁的请求, 限流可以防止某些不安分的IP因某些目的而频繁访问服务器而导致资源耗尽, 影响正常用户的访问体验.

一般地, 我们可以通过nginx配置ngx_http_limit_req_module进行限流:

1
2
3
4
5
6
7
8
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
...
server {
...
location /search/ {
limit_req zone=one burst=5;
}
  • limit_req_zone…: 设置一个大小为10M的共享区域, 命名为one, 其KEY为$binary_remote_addr即IP, 访问速率限制为1次/秒.
  • limit_req…: 路径为search的location使用共享区域one进行限流, 突发请求限制为5. (如果只限制了1r/s, 将会严格按照每秒一次的请求进行限制, 但对于用户来说, 点开网页可能会并发请求数个资源, 如此死板的限制对于体验并不友好, 所以我们还需要设置突发的请求限制)

五. 祸水东引

总之一句话, 引流到扛得住高并发的静态页. 比如GitPage.

参考文章: 我是如何通过Nginx日志实时封禁风险IP的

相信不少站长都了解被cc或ddos攻击支配的恐惧.

尤其对于个人主页等小站来说, 购买高防服务器或购买各种防护服务可能性价比并不高. 但普通服务器遇到稍大规模的攻击(也许这规模并不是真的很大), 可能服务器直接就挂了, 就算配置了页面的静态缓存, 也不一定能扛得住多大规模的攻击, 况且流量挺贵的.

对此笔者的方案是:

  1. 实时分析访问日志, 对每个IP进行危险等级评分.
  2. 锁定异常IP, 将这些IP的全部请求通过302临时重定向到GitPage备份站.
  3. 对于危险等级更高的IP, 直接使用ipset+iptables封禁

之所以对于一般危险等级的IP进行重定向, 主要目的是:

  1. 节约流量, 节约服务器资源(这点对动态网站尤为重要)
  2. 劝退攻击者: 大家无冤无仇, 您去找更好搞的站点攻击, 请不要在这里耗费太多时间.
  3. 防止误杀, 异常IP评估可能存在误差, 直接封禁对于访问者而言极其不友好, 会白白损失用户. 服务降级总比不提供服务要好. 故选择先临时重定向, 若该IP行为仍旧不规范, 此时再封禁也不晚.

下图引自我的前一篇文章《我是如何通过Nginx日志实时封禁风险IP的》

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sequenceDiagram
participant Nginx
participant Filebeat
participant Redis
participant Monitor
participant Actuator
Nginx ->> Filebeat: accessLog(File)
Filebeat ->> Redis: accessLog(JSON)
loop Always
Redis ->> Monitor: accessLog(JSON)
activate Monitor
Monitor ->> Monitor: Analysis
Monitor ->> Monitor: Risk assessment
Monitor ->> Actuator: Banned
Monitor ->> Monitor: Storing
end
deactivate Monitor

六. 禁用root远程登录

禁止使用root用户远程登录, 仅允许某个权限少的普通用户远程登录, 登录后再执行su提权.

对于允许远程登录的账户, 建议不要使用密码登录, 更不能使用简单密码. 建议使用秘钥登录.

ssh-keygen生成秘钥对, 将公钥放入authorized_keys文件中即可.

七. 其他

  • 定期备份, 建议使用crontab配置备份定时任务. 并且定期将重要数据冷备份.
  • 及时更新系统, 修复安全漏洞.
  • 只安装需要的、用不着就关闭

结语

服务器安全事大, 对于开发、运维、测试等工作来说, 安全都是重点关注的问题, 养成良好的习惯, 防患于未然.

欢迎关注公众号(代码如诗)

代码如诗(poetic_code)

推荐阅读