修改centos7远程端口和nginx安全设置
公司给了个阿里云服务器,自己搭了测试环境。没过几天,发现被扫描了,内容大概这样
2019/10/29 20:53:59 [error] 1269#0: *5878 open() "xxxxx/whoami.php" failed (2: No such file or directory), client: 172.105.23.36, server: localhost, request: "GET /whoami.php HTTP/1.1", host: "xxx.xxx.xxx.xxx"
2019/10/29 20:57:39 [error] 1269#0: *5879 open() "xxxxx/cache/global/img/gs.gif" failed (2: No such file or directory), client: 80.82.70.187, server: localhost, request: "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1", host: "www.baidu.com"
2019/10/29 21:01:01 [error] 1269#0: *5882 open() "xxxxx/cache/global/img/gs.gif" failed (2: No such file or directory), client: 80.82.70.187, server: localhost, request: "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1", host: "www.baidu.com"
2019/10/29 22:45:18 [error] 1269#0: *5923 open() "xxxxx/editBlackAndWhiteList" failed (2: No such file or directory), client: 159.203.196.79, server: localhost, request: "GET /editBlackAndWhiteList HTTP/1.1", host: "xxx.xxx.xxx.xxx", referrer: "188.65.219.106"
2019/10/29 23:48:55 [error] 1269#0: *5936 open() "xxxxx/index.php" failed (2: No such file or directory), client: 45.67.14.148, server: localhost, request: "POST /index.php HTTP/1.1", host: "xxx.xxx.xxx.xxx"
2019/10/30 03:23:02 [error] 1269#0: *5963 open() "xxxxx/azenv.php" failed (2: No such file or directory), client: 95.213.177.124, server: localhost, request: "POST http://check.proxyradar.com/azenv.php?auth=157237698109&a=PSCN&i=2018398604&p=80 HTTP/1.1", host: "check.proxyradar.com", referrer: "http://best-proxies.r(这里博客园提示敏感词,汗。。)u/"
嗯。。我一个java后台你扫我php。。
还有为什么会有来自百度的请求,麻烦知道的大佬指教一二,先谢过了!
好可怕,吓得我赶紧改了远程端口,记录一下。
修改远程端口
1 先决定一个新的远程端口(这里用12345举例),去服务器的安全组开放此端口。
2 远程连接进服务器
vim /etc/ssh/sshd_config
先将Port 22前面的注释放开,然后再其下面再添加一条(这样22和12345都可远程连接。这么做是为了一会先试新端口,成功了再回来关闭22端口,不然直接改了回头发现新端口连不上就坑大了)
Port 22
Port 12345
3 重启sshd
service sshd restart
4 用新端口远程连接,成功后关闭安全组的22端口(到这里发现sshd_config的22端口开着好像也没事,因为最外面的安全组已经屏蔽了)。
关闭8080端口
改好远程端口后,突然又想到,项目是前后台分离,前端80,后端8080。但其实对外只用暴露80端口,8080不需要暴露,这不是又多了一个别人扫你api的风险么。
于是,利用nginx的转发功能实现之。
1 将后台的api访问url由xxx.xxx.xxx.xxx:8080改为xxx.xxx.xxx.xxx/api
2 nginx的配置添加
location /api/ {
proxy_pass http://localhost:8080/;
}
这里说下proxy_pass 后面的url带斜线(/)和不带的区别
假设后台访问路径为test.do
1) 加斜线就是直接将配置的路径转发到url下,例如
```
location /api/ {
proxy_pass http://localhost:8080/;
}
```
最后访问路径为 http://localhost:8080/test.do
2) 不加斜线是将配置的路径加入到url后面,例如
```
location /api/ {
proxy_pass http://localhost:8080;
}
```
最后访问路径为 http://localhost:8080/api/test.do
那么我这里当然是使用加斜线的配置
再顺带一提,如果后台做了负载均衡,只用把proxy_pass后面换成对应的upstream即可,如
location /api/ {
proxy_pass http://backend/;
}
upstream backend {
server localhost:8081 weight=1;
server localhost:8082 weight=1;
}
嗯,好像彻底没8080端口什么事了。
3 重启nginx
./nginx -s reload
Nginx反爬虫(禁止User Agent)
网络上不光有无聊(并不,是想抓肉鸡)的扫描,还有灰常多的爬虫,有的有益(如百度蜘蛛),有的是恶意访问,浪费流量,所以我们需要设置一下
1 进入nginx配置目录,创建一个新的配置文件agent_deny.conf
cd /usr/local/nginx/conf
vim agent_deny.conf
写入如下内容
#禁止Scrapy等工具的抓取
if ($http_user_agent ~* (Scrapy|Curl|bot|Python|sql|php|HttpClient)) {
return 403;
}
#禁止指定UA及UA为空的访问
if ($http_user_agent ~ "WinHttp|WebZIP|FetchURL|node-superagent|java/|FeedDemon|Jullo|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|Java|Feedly|Apache-HttpAsyncClient|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|HttpClient|MJ12bot|heritrix|EasouSpider|Ezooms|BOT/0.1|YandexBot|FlightDeckReports|Linguee Bot|^$" ) {
return 403;
}
#禁止非GET|HEAD|POST方式的抓取
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 403;
}
2 在网站配置中的server段引入上面的配置文件
server {
...
include agent_deny.conf;
...
}
3 重启nginx
./nginx -s reload
4 测试
curl -I -A "BaiduSpider" www.yourdomainname.com
结果正常
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Tue, 26 Nov 2019 09:33:50 GMT
Content-Type: text/html
Content-Length: 51
Last-Modified: Fri, 22 Nov 2019 08:52:51 GMT
Connection: keep-alive
ETag: "5dd7a1e3-33"
Accept-Ranges: bytes
curl -I -A "JikeSpider" www.yourdomainname.com
访问拒绝
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Tue, 26 Nov 2019 09:35:07 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
说明我们配置有效了。后续agent_deny.conf根据实际情况调整。
附:垃圾UA
FeedDemon 内容采集
BOT/0.1 (BOT for JCE) sql注入
CrawlDaddy sql注入
Java 内容采集
Jullo 内容采集
Feedly 内容采集
UniversalFeedParser 内容采集
ApacheBench cc攻击器
Swiftbot 无用爬虫
YandexBot 无用爬虫
AhrefsBot 无用爬虫
YisouSpider 无用爬虫(已被UC神马搜索收购,此蜘蛛可以放开!)
jikeSpider 无用爬虫
MJ12bot 无用爬虫
ZmEu phpmyadmin 漏洞扫描
WinHttp 采集cc攻击
EasouSpider 无用爬虫
HttpClient tcp攻击
Microsoft URL Control 扫描
YYSpider 无用爬虫
jaunty wordpress爆破扫描器
oBot 无用爬虫
Python-urllib 内容采集
Indy Library 扫描
FlightDeckReports Bot 无用爬虫
Linguee Bot 无用爬虫
Nginx防DDoS
分布式拒绝服务攻击(DDoS),是通过多台机器,向特定目标网站发送大量并发连接,从而使其瘫痪的攻击方式。
nginx在此方面也可进行一定防御配置。
1 限制请求率
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; // 所有访问ip,限制每秒10个请求
server {
# ...
location / {
limit_req zone=one burst=5 nodelay; //缓冲区大小为5,如果短期内超过10个请求,会由缓存区暂存。nodelay代表暂存区直接处理
# ...
}
}
参数说明
$binary_remote_addr 二进制远程地址
zone=one:10m 定义zone名字叫one,并为这个zone分配10M内存,用来存储会话(二进制远程地址),1m内存可以保存16000会话
rate=10r/s; 限制频率为每秒10个请求
burst=5 允许超过频率限制的请求数不多于5个,假设1、2、3、4秒请求为每秒9个,那么第5秒内请求15个是允许的,反之,如果第一秒内请求15个,会将5个请求放到第二秒,第二秒内超过10的请求直接503,类似多秒内平均速率限制。
nodelay 超过的请求不被延迟处理,设置后15个请求在1秒内处理。
2 限制连接数
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
# ...
location /download/ {
limit_conn addr 1; //限制同一个时间内1个连接,多余的直接返回503
# ...
}
}
3 关闭慢速连接
http {
client_body_timeout 5s;
client_header_timeout 5s;
# ...
}
关闭不太频繁写入数据的连接,它们仅仅是为了保持连接尽可能长的时间,以此降低服务器接收新连接的能力。Slowloris就是这种攻击的一个典型例子。
client_body_timeout
和client_header_timeout
定义读取客户端请求体和请求头的超时时间。这两个参数的默认值都是 60s,上面的例子将它们设为了5s。
友好提示
上面做了限流处理,那么不排除有些用户就是手快(贱),点着玩,那么我们如何给与友好提示呢。
我们可以自定义503错误返回信息
error_page 503 /503;
location = /503 {
default_type application/json;
add_header Content-Type 'text/html; charset=utf-8';
return 200 '{"code":"503","msg":"您的操作太频繁,请稍后再试..."}';
}
然后前端js处理一下,比如我是ajax,那么就在error回调方法里特殊处理一下
$.ajax({
type: "POST",
dataType: "json",
url: "xxx",
data: data,
success: function (result) {
// balabala..
},
error : function(result) {
if(result.responseJSON["code"] == 503){
alert(result.responseJSON["msg"]);
return;
}
alert('未知异常');
}
});
Nginx防盗链
假如我们的网站里有优质图片,可能会被别人直接拿去使用,这样白白就消耗了我们的服务器带宽或流量资源。
故我们对特定资源做以下设置
location ~* \.(gif|jpg|png|swf|flv)$ {
root /xxx/yyy
valid_referers none blocked server_names;
if ($invalid_referer) {
return 403;
# 也可返回一个图片,图片内容一般是三个字:防盗链
# rewirte ^/ http://xxx.com/yyy/zzz.png;
}
}
还可以对特定目录设置
location /img/ {
root /xxx/yyy/;
valid_referers none blocked server_names;
if ($invalid_referer) {
return 403;
}
}
如此一来,其他网站就不能引用我们图片了。
当然,对方依旧可以使用工具伪造referer,这种情况就只能动用其他防护措施了,但一般情况的话,上述配置足够了。
总结
这样服务器对外只暴露80端口(远程端口外界是未知的),屏蔽了一些恶意扫描或访问,终于感觉安全了一丢丢~
至于数据库,redis(记得设置密码)等远程端口,在测试阶段可以开放,最后生产环境还是关闭比较安全。