在服务器管理和网络架构中,将域名与端口转发策略相结合是一项核心技能,尤其是在资源有限(如单个公网 IP 地址)但需要托管多个服务的场景下,本文将深入探讨在 CentOS 系统上如何实现这一目标,从基础概念到具体实践,旨在为您提供一个清晰、可操作的指南。

理解核心概念
在开始配置之前,我们必须首先理解两个基本概念:端口转发和域名解析。
端口转发,在网络术语中通常指网络地址转换(NAT)的一种形式,其核心作用是将从一个端口(通常是公网 IP 的某个端口)收到的网络流量,重新导向到同一网络内另一台设备的特定端口上,在 CentOS 单服务器场景下,这通常意味着将外部流量从服务器的某个端口(如 8080)导向到内部另一个服务正在监听的端口(如一个运行在 3000 端口的 Node.js 应用),这种机制允许单个 IP 地址为多个内部服务提供入口。
域名,则是为了解决 IP 地址难以记忆的问题而生的,当用户在浏览器中输入一个域名(如 service.yourdomain.com)时,DNS(域名系统)会将其解析为对应的服务器 IP 地址,DNS 本身并不处理端口,它只会将流量引导至 IP 地址的默认端口(如 HTTP 的 80 端口或 HTTPS 的 443 端口),要实现通过不同域名访问同一服务器上不同端口的服务,我们需要一个能够识别域名并进行智能转发的“中间人”,这个角色通常由反向代理服务器扮演。
使用 firewalld 进行基础端口转发
CentOS 7 及以上版本默认使用 firewalld 作为防火墙管理工具,它提供了一种相对简单的方式来设置端口转发规则,这种方法适用于直接通过 IP:Port 访问的场景,或者作为反向代理的底层支撑。
配置 firewalld 端口转发需要两个步骤:首先开启内核的 IP 转发功能,然后添加具体的转发规则。
开启 IP 转发:
临时开启:sudo sysctl -w net.ipv4.ip_forward=1
永久开启,编辑
/etc/sysctl.conf文件,添加或修改以下行:net.ipv4.ip_forward = 1保存后,执行
sudo sysctl -p使配置生效。配置 firewalld 规则:
假设我们希望将访问服务器公网 IP 的 8080 端口的流量,转发到本地的 3000 端口。# 添加转发规则(--add-forward-port) sudo firewall-cmd --zone=public --add-forward-port=port=8080:proto=tcp:toport=3000 --permanent # 如果目标是另一台内网服务器(如 192.168.1.100),则使用 toaddr # sudo firewall-cmd --zone=public --add-forward-port=port=8080:proto=tcp:toaddr=192.168.1.100:toport=3000 --permanent # 重新加载防火墙配置使规则生效 sudo firewall-cmd --reload
常用
firewalld端口转发命令如下表所示:
| 功能 | 命令示例 | 说明 |
|---|---|---|
| 添加转发规则(本地) | firewall-cmd --zone=public --add-forward-port=port=8080:proto=tcp:toport=3000 --permanent | 将 8080 端口流量转发到本机 3000 端口 |
| 添加转发规则(远程) | firewall-cmd --zone=public --add-forward-port=port=8080:proto=tcp:toaddr=192.168.1.100:toport=3000 --permanent | 将 8080 端口流量转发到内网另一台主机 |
| 移除转发规则 | firewall-cmd --zone=public --remove-forward-port=port=8080:proto=tcp:toport=3000 --permanent | 移除已添加的转发规则 |
| 查看当前转发规则 | firewall-cmd --zone=public --list-forward-ports | 列出当前区域的所有转发规则 |
firewalld 的缺点在于它工作在网络层和传输层,无法识别 HTTP 请求中的 Host 头部信息,因此无法根据域名进行区分,这正是反向代理的价值所在。
使用 Nginx 实现基于域名的反向代理
反向代理是解决“单 IP 多域名多服务”问题的最佳方案,Nginx 作为一款高性能的 Web 和反向代理服务器,是此场景下的理想选择,它接收来自客户端的请求,根据请求的域名或其他信息,将其转发到后端相应的服务器。
安装 Nginx:
sudo yum install epel-release -y sudo yum install nginx -y
配置 Nginx:
Nginx 的配置文件通常位于/etc/nginx/nginx.conf,而站点特定的配置文件建议放在/etc/nginx/conf.d/目录下,我们为每个服务创建一个独立的.conf文件。场景示例:
- 域名
blog.yourdomain.com指向一个运行在localhost:8080的博客服务。 - 域名
git.yourdomain.com指向一个运行在localhost:3000的 Git 仓库服务。
创建博客服务配置文件
/etc/nginx/conf.d/blog.conf:server { listen 80; server_name blog.yourdomain.com; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }创建 Git 服务配置文件
/etc/nginx/conf.d/git.conf:server { listen 80; server_name git.yourdomain.com; location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }在这些配置中,
server_name指令是关键,Nginx 会检查传入请求的Host头部,并与server_name进行匹配,一旦匹配成功,请求就会被proxy_pass指令转发到指定的后端地址。proxy_set_header部分用于传递客户端的真实信息给后端服务,这对于日志记录和应用逻辑非常重要。- 域名
启动并设置 Nginx 开机自启:
sudo systemctl start nginx sudo systemctl enable nginx
确保防火墙允许 HTTP(80 端口)和 HTTPS(443 端口)流量:

sudo firewall-cmd --zone=public --add-service=http --permanent sudo firewall-cmd --zone=public --add-service=https --permanent sudo firewall-cmd --reload
当用户访问 blog.yourdomain.com 时,流量会被 Nginx 接收并精准地转发到内部的 8080 端口服务;访问 git.yourdomain.com 则会被转发到 3000 端口,整个过程对用户是透明的,他们只需要记住简单的域名即可。
相关问答FAQs
firewalld 的端口转发和 Nginx 的反向代理有什么本质区别?我应该选择哪一个?
解答: 两者的本质区别在于它们工作的网络层次和功能的复杂度。
firewalld端口转发:工作在网络层(第三层)和传输层(第四层),它只关心 IP 地址和端口号,不关心传输的数据内容(如 HTTP 请求头),它像一个简单的交通调度员,只看目的地是哪个路口(端口),然后直接指路,它无法根据域名来做决策。- Nginx 反向代理:工作在应用层(第七层),它能理解并检查 HTTP/HTTPS 协议的内容,特别是
Host头部(即域名),它像一个智能前台,不仅看来访者的目的地,还看他们要找的具体是谁(域名),然后精确引导。
选择建议:
- 如果你的需求非常简单,只是想把一个外部端口映射到内部端口,且不涉及域名区分,使用
firewalld更轻量。 - 如果你需要通过不同的域名访问同一服务器上的多个 Web 服务,或者需要对后端服务进行负载均衡、缓存、SSL 卸载等高级操作,那么必须使用 Nginx 或类似的反向代理软件,在现代 Web 架构中,反向代理是标准实践。
我已经配置了 Nginx 反向代理,为什么还需要用 firewalld 开放端口?
解答: 这是一个非常好的问题,涉及到多层防御的理解,即使 Nginx 已经在处理请求,firewalld 仍然是服务器的第一道防线。
- 外部访问入口:Nginx 本身作为一个服务,也需要监听一个端口(通常是 80 和 443)来接收来自互联网的请求。
firewalld阻止了这些端口的访问,那么外部流量根本无法到达 Nginx,自然也就无法进行代理转发,你必须用firewalld开放 Nginx 监听的端口(sudo firewall-cmd --add-service=http)。 - 内部服务隔离:Nginx 转发到的后端服务(如运行在 3000 端口的应用)通常只需要在本地(
localhost或0.0.1)监听,不需要直接暴露给公网,在这种情况下,你不应该用firewalld开放这些内部端口(如 3000),这样,即使 Nginx 因为配置漏洞被绕过,攻击者也无法直接访问你的后端应用,增加了一层安全保障。
firewalld 负责控制谁能“敲门”(访问服务器的哪些端口),而 Nginx 负责在门打开后,根据访客的意图(域名)将其引导到正确的房间(内部服务),两者协同工作,构成了一个既灵活又安全的访问控制体系。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复