`
498320858
  • 浏览: 386823 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

nginx限制域名访问

 
阅读更多

背景:一个未备案的域名恶意解析到我司的服务器,导致服务器托管服务商认为我司故意不备案域名,服务商准备停掉我们的服务器的接入

 

解决思路:

1.通过防火墙限制域名访问

2.设置代理服务器,对于域名不是我司注册的一律限制访问

 

       开始是希望通过防火墙去限制域名的访问,这样开销应该是最小的,但仔细想发现防火墙应该是解决不了这个需求,因为域名解析是在域名服务商那做的,在通过防火墙的时候,域名已经转换成ip地址了。

以下是摘自论坛的说法“

写道
目前的 iptables 是无法实现的
因为 iptables 工作在网络层,他看到的仅仅是数据包
domain 存放在两种数据包中
1、DNS 请求的 udp 包
2、HTTP 请求头部的 host 字段

对于 1 来说,我们得不到它,因为 DNS 请求是去放用户设置的 DNS 地址的,而且即便获得到了也做不了什么
对于 2 来说,我们虽然可以获得 host 字段具体域名,但如果在获得后再转向的话,前面的 connection 已经建立了,后面突然转向就未被了 TCP 工作原理,理论上是无法实现的

但是,利用 squid 或者 nginx 却是可以实现的,他们相当于七层代理,完全把 HTTP 请求截获,换成新的请求发向内网,得到信息再回传给客户,这样可行

至于前面有人说的 mark、tc 等,都是理论上行不通的,违反了 OSI 七层模型中 TCP 传输原理

 ”

      尝试了一段时间后,发现无法通过防火墙来解决这个问题,那就只能切换到nginx前端代理去禁止恶意域名访问了,其实是利用了nginx对不同来路的域名解析到不同服务器的规则实现的,以下为nginx的配置

user  nginx;
worker_processes  3;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/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  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

     keepalive_timeout  65;

    #gzip  on;

    #include /etc/nginx/conf.d/*.conf;

    upstream cncamm{
        server 127.0.0.1:8080;
    }

    server {
        listen       80;
        server_name  www.cn-camm.com;
        access_log      /var/log/nginx/cn-camm.server.access.log main;
        if ( $host != 'www.cn-camm.com' ){
             rewrite ^/(.*)$ http://www.emapp.cn/$1 permanent;
        }
        
        location / {
                proxy_pass      http://cncamm;
                proxy_set_header Host $host;
        }

   }

}

 

 

 

 电信人员人工检查域名后发现了我们对恶意域名采用的是转发机制,他们认为还是不行,必须要限制恶意域名的访问,于是只能对恶意域名配置403了,新的配置文件贴出来

user  nginx;
worker_processes  3;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/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  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

     keepalive_timeout  65;

    #gzip  on;

    #include /etc/nginx/conf.d/*.conf;
	
    upstream cncamm{
        server 127.0.0.1:8080;
    }	
     
    server {
        listen       80;
        server_name  www.cn-camm.com;
        access_log      /var/log/nginx/cn-camm.server.access.log main;
	if ( $host != 'www.cn-camm.com' ){
#	     rewrite ^/(.*)$ http://www.emapp.cn/$1 permanent;
		return 403;
	}

        location / {
                proxy_pass      http://cncamm;
                proxy_set_header Host $host;
        }
	

   }

 

 以上配置在短时间内确实生效了,可以成功拦截到恶意域名,但是接着问题又来了,现在服务器上有两个应用,并且都同时运行,其中一个应用需要通过localhost

来访问另外一个应用,因为不希望直接通过代理后的ip预计端口访问,希望保持tomcat做前端服务器时的代码,所以localhost依然要通过nginx转发,此时发现以上配置对localhost
也进行了拦截,所以以上配置还需要修改,正常思路是在if判断中再加一层逻辑与 ,但是nginx不支持多重逻辑,此时只能使用nginx的变量了

新版配置如下:
      
user  nginx;
worker_processes  3;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/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  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

     keepalive_timeout  65;

    #gzip  on;

    #include /etc/nginx/conf.d/*.conf;

    upstream cncamm{
        server 127.0.0.1:8080;
    }

    server {
        listen       80;
        server_name  www.cn-camm.com;
        access_log      /var/log/nginx/cn-camm.server.access.log main;
set $tag "0";

 if ( $host !~ ^www.cn-camm.com$ ){
                set $tag "$tag,1";
  }

  if ( $host !~ ^localhost$ ){
                set $tag "$tag,2";
   }
 
  if ( $tag ~ ^0,1,2$ ){
                return 403;
    }

location / {
                proxy_pass      http://cncamm;
                proxy_set_header Host $host;
        }

   }

}


以上配置对比之前只允许一个域名可以访问的配置要灵活很多,这里我们可以加入更多允许通过的域名

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics