Lishengxie
  • Posts
  • About
  • Contact
  1. Home
  2. Posts
  3. Nginx禁止使用IP直接访问服务器上相应端口

Nginx禁止使用IP直接访问服务器上相应端口

May 11, 2024 linux Lishengxie

起因

我的服务器中部署了一个typecho博客和两个使用docker容器的服务,其中docker容器使用端口映射,将容器中的端口映射到宿主机上的端口实现访问。

一次偶然机会发现服务器上的服务可以通过IP+端口的方式直接访问,如果有未备案的域名解析到我们服务器的IP,可能会导致云服务器厂商关停我们的服务造成一些问题。因此,我们需要禁止通过IP+端口直接访问服务。

Nginx 配置

这里的三个服务通过nginx进行转发,对不同server_name的请求会直接转发到对应的服务进程。因此,这里有限考虑使用nginx配置来禁止IP+端口的访问。服务器上主要开放了两个端口,80和443,分别用于HTTP和HTTPS请求,在实际进行相应配置时二者也有所不同。

80 端口

对于80端口,我们在nginx.conf中添加如下配置。具体原理在于,当根据listen无法得到最佳匹配时,nginx会使用请求中的Host值匹配server_name,匹配顺序可以参考这篇博客。IP+端口进行请求时匹配到下面的server配置,直接返回403错误信息。

server {
    listen 80 default_server;
    server_name  _;    
    return 403;
}

443端口

由于使用了HTTPS协议,因此还需要禁止通过IP+443端口的访问方式。具体参考了下面的博客:

  • https://www.huixiangdou.cn/archives/nginx-jin-zhi-80-443-duan-kou

具体来说,Nginx 上对于 SSL 服务器在不配置证书的时候会出现协议错误,哪怕端口上配置了其他网站也会报错。因此,我们需要随便生成一个证书进行配置,生成 SSL 证书可以使用这个网站https://myssl.com/create_test_cert.html。在nginx.conf中添加如下配置:

server {
    listen 80 default;
    listen 443 default_server;
    #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
    #error_page 404/404.html;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/private.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    error_page 497  https://$host$request_uri;
    #SSL-END
    server_name _;
    return 403;
}

配置完成后重载 Nginx 配置。

$ nginx -t
$ nginx -s reload

Docker容器问题

Docker容器通过端口映射实现服务的对外可用性,这里是通过-p host_port:container_port实现容器上的端口到宿主机上端口的映射。具体来说,以容器的80端口映射到宿主机的8080端口为例,docker容器运行时使用了-p 8080:80,Nginx中监听了80端口,并在对应域名访问时将请求转发到服务器的8080端口。

location / {
    proxy_pass http://host_ip:8080;
}

但是,在根据上面的配置禁止了直接使用IP+80/443端口访问的方式后,发现host_ip:8080仍然能够访问到docker容器中的服务。查询相关资料修改了iptables路由表和sfw防火墙规则后,仍然无法解决问题。防火墙上没有打开端口,但仍然可以访问。最后通过查找资料发现是docker自身的原因,下面是docker官方的介绍:

If you don’t specify an IP address (i.e., -p 80:80 instead of -p 127.0.0.1:80:80) when publishing a container’s ports, Docker publishes the port on all interfaces (address 0.0.0.0) by default. These ports are externally accessible. This also applies if you configured UFW to block this specific port, as Docker manages its own iptables rules. Read more

大致意思是说docker容器中设置端口映射时如果没有指定宿主机IP,那么默认映射到0.0.0.0,即所有IP都可以访问。并且由于Docker镜像自行管理其路由表规则,设置宿主机防火墙也不起作用。知道原因后,我们只需要修稿docker容器的端口映射即可,对于正在运行的docker容器,修改方式参考如下博客,修改对应容器的/var/lib/docker/containers/{container_id}/hostconfig.json中的PostBindings->HostIp,HostIp设置为127.0.0.1即可。

  • https://blog.csdn.net/km_bandits/article/details/135724252

参考资料

  • Nginx配置禁止IP访问80和443端口
  • Nginx禁止未绑定域名或IP访问80和443端口实践小结
  • docker端口映射后,外部可以直接通过宿主机未开启的端口访问到服务的问题?
  • docker修改已运行容器的映射端口

Table of Contents

  • 起因
  • Nginx 配置
    • 80 端口
    • 443端口
  • Docker容器问题
  • 参考资料

Recent Posts

  • 分布式ID生成方案全解析:从数据库到雪花算法 Jun 25, 2026
  • Let's Encrypt 免费申请 SSL 证书,并实现自动续期 Sep 14, 2025
  • Redis ziplist、quicklist 和 listpack Mar 3, 2025
  • Nginx禁止使用IP直接访问服务器上相应端口 May 11, 2024
  • LeetCode刷题 - KMP算法 Feb 4, 2024

Categories

  • Linux7
  • 算法学习7
  • 论文笔记6
  • C++4
  • 未分类3
  • Go学习2
  • Redis1
  • SystemC1
  • Verilog1

Tags

← LeetCode刷题 - KMP算法 Redis ziplist、quicklist 和 listpack →

Related Posts

  • Let's Encrypt 免费申请 SSL 证书,并实现自动续期 Sep 14, 2025
  • 云服务器软件安装 Apr 30, 2023
  • 常用资源汇总 Apr 30, 2023
  • Linux常用命令记录 Apr 30, 2023
皖ICP备2023003716号-1 | 公安备案皖公网安备34012202341113 | 违法和不良信息举报邮箱:1141751053@qq.com
Powered by Hugo & Explore Theme.