《域名访问完全指南》 – 更安全的容器化域名访问转发方案!

在购买并备案域名,在云服务器提供商处完成绑定后,虽然用 域名:port 的方式可以访问到云服务器的特定端口,但是在跳转到相应页面后,服务器的ip和端口号会直接暴露。如何配置实现域名直接访问某服务,且不将ip和端口号暴露给访问者呢?今天的文章就介绍一下博主采用的 docker容器化部署 + nginx反向代理 的方案,记录一下在配置过程中碰到的坑:

初次尝试 iptable流量转发 (不推荐)

通过域名访问时,默认会调用域名绑定服务器的 80 端口(HTTP)。为了让访问域名的流量转发到特定服务(例如 WordPress 博客,端口为 6666),可以使用 iptables 命令将 80 端口的流量重定向:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 6666

这种方法虽然可以通过域名直接访问服务,但问题在于:端口号仍然会暴露,并不是理想的解决方案。因此,不推荐这种方法。

nginx 反向代理

为了解决端口暴露的问题,我选择用 Docker 来搭建 Nginx,并通过反向代理来隐藏目标服务的实际端口。

首先,搭建 Nginx 的过程不再赘述。接下来是关键的 Nginx 配置(修改 nginx.conf 文件):

本人第一次的配置是这样的:

upstream blog_server{
    server 127.0.0.1:6666;
}

server {
    listen       80;
    server_name  superbloom.cn;

    location / {
        proxy_pass http://blog_server;
    }
}

也就是将来自域名 superbloom.cn 访问的 80 端口流量都代理转发到本机的6666端口,也就是docker容器对外的端口。

然而这样配置后转发并没有成功!!!

问题排查

在多次排查后,发现问题可能不出在对nginx的配置上,而是 Nginx容器 与 服务提供容器之间的通信问题,因为nginx搭载在docker容器中,所以nginx中配置的127.0.0.1实际上指向的是这个容器本身的虚拟机,而不是宿主机。这意味着,这里的127.0.0.1:6666访问的是本容器内部的6666端口,当然访问不到正确结果。

要解决问题,这里有两个解决方案:

1. 设置nginx的网络模式,使其可以与宿主机通信

在创建并启动容器时,将容器设置为host模式。

比如host模式下,容器和宿主机共享IP地址和端口空间,容器内的服务可以直接通过localhost访问宿主机的服务。我们可以将 nginx 设置为host模式,就可以直接通过localhost:6666 访问到目标服务了。

docker run --network host <image>

这种方案简单易行,但是每次代理都需要访问宿主机的端口,未充分利用 Docker 的隔离性。因此,尽管这种方法有效,但并不是最佳选择。

2. 将nginx和目标服务放在一个docker网络下,使其在网络内部通信

更优雅的解决方案是:将 Nginx 和目标服务容器置于同一个 Docker 网络中。这样,Nginx 就可以通过内部网络访问目标服务的内部端口,而不需要公开服务容器的对外端口。

因为目标服务容器的对外端口没有使用到,外界的访问都是通过nginx代理转发过来的,完全可以关闭该对外接口,让提供服务的容器只在docker内部网络提供服务,整个服务网络只对外开放nginx监听接口,完全实现服务的隔离,提高了整体服务的安全性!

具体步骤如下:

1 创建该服务的docker网络:

docker network create service_network

2 将 Nginx 容器和目标服务容器(或许还有服务数据库)都连接到这个网络:

docker run --network service_network --name service_nginx -d nginx
docker run --network service_network --name wordpress_blog -d my_blog_image

3 在 Nginx 的配置中,将 upstream 直接配置为目标服务容器的名称,而不是 127.0.0.1,端口也设置为容器网络内部接口:

upstream blog_server {
    server wordpress_blog:80;
}

server {
    listen       80;
    server_name  superbloom.cn;

    location / {
        proxy_pass http://blog_server;
    }
}

4 记得重启nginx!

这样,Nginx 通过 Docker 网络内部的名称 my_blog 访问服务容器,而服务容器的端口对外是不可见的。访问者只能通过 Nginx 的 80 端口访问服务,避免了端口泄露,并且确保了 Docker 的隔离性和安全性

评论

  1. 博主
    3 月前
    2024-10-14 21:35:34

    挖坑:需要更新支持HTTPS访问的日志(๑•̀ㅁ•́ฅ)

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇