隐藏

在Nginx中允许域名访问而禁止通过IP访问

发布:2022/12/12 14:00:00作者:管理员 来源:本站 浏览次数:438

1. 背景


近期因为信息安全方面的要求,安全部门提出我们的对公服务,要屏蔽来自 IP 地址的访问。我们接到这个需求,分析出要在反向代理服务器上设置禁止通过 IP 地址来访问服务,只允许通过域名的访问。

2. 现状


因为我们的对公服务域名有多个,而且域名,因为当初建设过程中,没考虑冗余,都配置成同城同机房一组外网服务器进行转发,所以这些域名都对应同一个公网 IP 。

3. 问题分析


提前补充一点网络的小知识,通过IP访问 与 通过 域名访问的区别就在于 HTTP 请求头信息中的 Host 值。我们在反向代理软件中,只要校验 Host 属性与我们自身域名不相同,则直接给我们的错误代码。


   域名访问


通过域名访问


   IP访问


通过IP访问

3.1. 多域名


我们域名比较多,但是 Nginx 的 Lua 语法不支持多重判断。所这里这里可以使用多个条件语句。

3.2. 多监听


此处没法绕过,只能挨个 server 配置,如果有更好的办法,欢迎请在留言处指明。

4. Nginx版本


此次演示是基于 1.21.6 的版本来操作。


nginx version: nginx/1.21.6


5. 实现方案


由于 Nginx 语法特殊性,写法也有不同,下来主要就两种方式来说明实现方案。

5.1. 传统方式


Nginx 通过 $host 来获取 HTTP 中的 Host 属性,对 $host 内容进行判定即可。



http {

   include mime.types;

   default_type application/octet-stream;

   sendfile on;

   keepalive_timeout 65;


   server {

       listen 80;

       server_name _;


       set $flag 0;

       if ($host ~* ^cia* ) {

            set $flag "1${flag}";

        }

        if ($host ~* ^mo* ) {

            set $flag "1${flag}";

        }

        if ($flag !~* ^1* ) {

            return 403;

        }

   }

}


这种方式,就是堆叠 if 语句,客观性和拓展性不够好。适用于临时应急方案。

5.2. 正则方式


既然传统方式不够友好,那需要考虑其他实现方案。通过观察,我们域名都有一定的特点,如后缀都是 ejk5.com 。所以这里考虑使用正则表达式。


只要是 server_name 中的域名都是以 ejk5.com 结尾的都是放行,最终配置如下:



http {

   include mime.types;

   default_type application/octet-stream;

   sendfile on;

   keepalive_timeout 65;


   server {

       listen 80;

       server_name ~^(.+).ejk5.com$;;

   }

}