环境交代
Nginx配置IP白名单是非常基础的工作,这次试验就是配置某网页可以正常被部分IP访问,而其他网页访问将是403。目标网页地址是http://xxdtq.lechange.com/test/test.html
,内容如下:
本机的外网IP地址是115.205.2.28
,如图:
首先先nginx.conf
里的日志配置格式如下:
1
2
3log_format access '$http_x_forwarded_for - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $remote_addr $request_time $upstream_response_time $http_host';
Nginx的转发文件default.conf
如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15server {
listen 80;
server_name xxdtq.lechange.com; #如果浏览器输入的是xxdtq.lechange.com,那么就跳转到82端口
location / {
proxy_pass http://localhost:82;
}
}
server {
listen 80;
server_name xhssf.lechange.com; #如果浏览器输入的是xhssf.lechange.com,那么就跳转到82端口
location / {
proxy_pass http://localhost:83;
}
}
配置步骤
现在配置xxdtq.conf
文件内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 server
{
listen 82 default; #82端口
server_name xxdtq.lechange.com;
root /mnt/xiuxiudetiequan/; #根目录是/mnet/xiuxiudetiequan/
index index.html index.htm index.php;
add_header Set-Cookie "HttpOnly";
add_header Set-Cookie "Secure";
add_header X-Frame-Options "SAMEORIGIN";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location = /test/test.html { #如果remote_addr是125.205.2.28来访问/test/test.html,那么就返回403
if ($remote_addr = 115.205.2.28) {
return 403;
}
}
access_log /var/log/nginx/xxdtq/access.log access;
error_log /var/log/nginx/xxdtq/error.log error;
}
执行了nginx -s reload
后,刷新一下界面,却发现页面没变,并不是预期中的403,打开nginx的日志一看,发现获取到的$remote_addr
是127.0.0.1
!如下:
为什么是127.0.0.1?因为我们这个nginx做了一个80到82端口的转发呀,所以到80的地址是真实的外界IP,而80转发到82就是本机IP了。那这样的情况怎么办?就需要在default.conf
里添加一句proxy_set_header x-forwarded-for $remote_addr;
,如下:
1
2
3
4
5
6
7
8server {
listen 80;
server_name xxdtq.lechange.com;
location / {
proxy_pass http://localhost:82;
proxy_set_header x-forwarded-for $remote_addr;
}
}
重启一波nginx,发现http_x_forwarded_for
正是远程访问的IP地址115.205.2.28
,于是将xxdtq.conf判断IP改成如下内容:
1
2
3
4
5location = /test/test.html {
if ($http_x_forwarded_for = 115.205.2.28) { #改用http_x_forwarded_for
return 403;
}
}
重启nginx之后,果然页面是403,如图:
然后用其他的IP地址,比如用手机连接4G去打开http://xxdtq.lechange.com/test/test.html ,发现是正常读取的,试验成功!
如果是要整个/test/目录都不让访问的话,就要改成如下内容:
1
2
3
4
5location ^~ /test/ {
if ($http_x_forwarded_for = 115.205.2.28) { # =是精确匹配
return 403;
}
}
如果要配置多个IP地址,就要改成如下内容:
1
2
3
4
5location ~ ^/shopadmin {
if ($remote_addr ~* "第一个IP|第二个IP|第三个IP") { #这里改成~*
return 403;
}
}
elk里提取http_x_forwarded_for
nginx日志中的http_x_forwarded_for
字段会有多个IP。使用自定义的模板,grok
常用表达式的IPORHOST匹配http_x_forwarded_for
该字段,获取的IP值是最后一个,如何取第一个IP值?
答案是:
1
2
3
4mutate {
split => ["http_x_forwarded_for",","]
add_field => ["real_remote_addr","%{http_x_forwarded_for[0]}"]
}
IPORHOST这些变量匹配不到所有IP,只能通过自定义正则来匹配到所有IP;再通过以上方法截取第一个IP值。正则表达式写法是:[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\,\s]*
参考资料
http://seanlook.com/2015/05/17/nginx-location-rewrite/
https://zhuanlan.zhihu.com/p/21354318
http://blog.pengqi.me/2013/04/20/remote-addr-and-x-forwarded-for/
http://gong1208.iteye.com/blog/1559835
https://my.oschina.net/moooofly/blog/295853