防止绕过nginx直接访问tomcat
这周我在阿里云配置nginx的时候,发现居然可以绕过nginx直接访问tomcat,这样就会使nginx上面的一些配置失效,造成程序的bug,比如配置的负载均衡,如果一直通过ip+端口来访问就会使负载均衡失去意义。再比如在项目中使用的nginx配置好的静态资源路径会失去效果,造成排版混乱、无法加载等一些问题。
通过一定的研究终于找到了问题的所在。
接下来我们就通过nginx配置和防火墙设置,两方面来说明怎么解决这个问题。
nginx配置
首先我们看一段nginx的常用配置
user root;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#tcp_nopush on;
client_max_body_size 1000m;
client_body_temp_path /www/images/nginx_temp;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream xxxservice{
#server 192.168.1.110:8080 weight=10; //本机ip 但不可使用此种写法,使用下面127的写法
server 127.0.0.1:8080 weight=10;
server 192.168.1.111:8080 weight=10; //负载均衡的项目ip端口
}
upstream aaamanager{
#server 192.168.1.110:8081 //同上
server 127.0.0.1:8081;
}
upstream bbbmanager{
#server 192.168.1.110:8082 //同上
server 127.0.0.1:8082;
}
//拦截ip访问80端口,防止nginx暴露,引流到某一地址,可以转向自己的网站。
server{
listen 80 default_server;
server_name _;
return http://www.xxx.cn;
}
//负载均衡的项目地址
server{
listen 80;
server_name xxx.xxx.cn; //映射到域名
location /xxxservice {
proxy_pass http://xxxservice/xxxservice;
}
}
server{
listen 80;
server_name aaa.manager.xxx.cn; //映射到域名
location / {
proxy_pass http://aaamanager; //指向上面的反向代理地址
}
location ^~ /img/ {
alias /www/images/;
autoindex on;
expires 1h;
}
}
server{
listen 80;
server_name bbb.manager.xxx.cn;
location / {
proxy_pass http://bbbmanager;
}
location ^~ /img/ {
alias /www/images/;
autoindex on;
expires 1h;
}
}
}
从上面的这段配置中,我们可以看出,nginx配置的时候反向代理转发如果是本机的应用服务器,一定要写成127.0.0.1:port 原因我们后面再说,如果有做负载均衡的话,就指向到另外一物理服务器的具体地址,如192.168.1.0:8080这样。关于nginx的其它配置网上有很多,有不明白的可以自行查阅。
防火墙安全组
如果想让外部能访问到的你服务器就需要开放相对应的端口,就像刚刚我们nginx配置的那样,但是如果端口都开放了,一旦被人猜到了具体的端口号,就能轻易的绕过nginx来访问我们部署的项目,会使我们nginx配置失效,所以具体应用服务器端口号不应该对外开放,只开放一个nginx端口即80端口,使用反向代理来内部转到的不同的应用服务器上去,如下所示。
# /etc/init.d/iptables status
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:1186
2 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306
3 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
上面是centos系统里的防火墙设置,也可以通过阿里云的安全规则组来设置。
可能看到这里有的朋友会问,一会要开放才能访问、一会要限制直接访问,这不是互相矛盾吗?
这时候nginx配置就很重要了,因为我们此时转发到的是本机的某一端口,如果使用本机ip的话还需要进行tcp连接,这时候防火墙就会把这个端口的tcp连接给拦截掉,本机也无法访问这个ip的某一端口,使用127.0.0.1就可以完美的避开这个问题。
那我们如果代理服务器和应用服务器不是同一物理服务器该怎么设置呢?之前我们的nginx配置中有负载均衡的设置,转发到了另一物理服务器上的某一端口。
我们可以在阿里云的规则组上专门为某一ip开放端口号,就可以完美的解决这个问题,物理服务器之间才可以进行特定端口的tcp连接。如下设置:
端口开放范围就是我们说的端口号8080/8080的意思就是从某一端口开放到某一端口,两个一样的就是只开放单一端口,授权对象的意思就是给特定地址开放,0.0.0.0/0就是默认全部开放。这个32的意思是子网掩码,子网掩码可以通过ifconfig命令来查询,查询到的4个数字分别转化成二进制数1个的个数就可以了。如255.255.255.255对应的二进制就是11111111 11111111 11111111 11111111 即为32个1,所以这里就写32。
查询ip和子网掩码的时候要看清楚是哪个网卡的,因为一台机器上可能有多个网卡。加上eth+数字可以具体查询某一网卡。
这样子设置好规则之后,两台服务器之间就开放了这一端口可以访问了。