Linux 中iptables转发外网成功转发本地失败的解决办法

1、Nginx端口转发

因为nginx账号不能直接启动80端口,所以利用iptables做了80到8081端口的转发,这样外部应用可以直接访问80端口,然后通过iptables转发到真正的nginx服务的8081端口。

 

Iptables转发命令:

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

 

 

2、外网能通,但是本地不通

外网的网页页面能打通,如下:

[tomcat@dev_121_21 ~]$ wget http://bright.test.com/PLATFORM_AUTH_Service/1.html

--2016-11-22 12:43:01--  http://bright.test.com/PLATFORM_AUTH_Service/1.html

正在解析主机 bright.test.com... 192.168.121.21

正在连接 bright.test.com|192.168.121.21|:80... 已连接。

已发出 HTTP 请求,正在等待回应... 200 OK

长度:39 [text/html]

正在保存至: “1.html”

 

100%[=====================================================================================================================================================>] 39          --.-K/s   in 0s     

 

2016-11-22 12:43:01 (4.13 MB/s) - 已保存 “1.html” [39/39])

 

[tomcat@dev_121_21 ~]$

 

 

 

本地的service服务器打不通:

[tomcat@dev_121_21 ~]$ wget http://bright.test.com/PLATFORM_AUTH_Service/remoting/AuthenticationService

--2016-11-22 12:29:17--  http://bright.test.com/PLATFORM_AUTH_Service/remoting/AuthenticationService

正在解析主机 bright.test.com... 192.168.121.21

正在连接 bright.test.com|192.168.121.21|:80... 失败:拒绝连接。

[tomcat@dev_121_21 ~]$

 

问题在哪里呢?直接telnet端口80试试

# telnet域名的80端口不通

[tomcat@dev_121_21 ~]$ telnet bright.test.com 80

Trying 192.168.121.21...

telnet: connect to address 192.168.121.21: Connection refused

[tomcat@dev_121_21 ~]$

# telnet 域名所在ip地址的80端口,也不通

[tomcat@dev_121_21 ~]$ telnet 192.168.121.21 80

Trying 192.168.121.21...

telnet: connect to address 192.168.121.21: Connection refused

[tomcat@dev_121_21 ~]$

 

# 因为80只是iptables转发的端口,不是真正nginx服务的端口,nginx服务的8081端口是有效的,

[tomcat@dev_121_21 ~]$ telnet bright.test.com 8081

Trying 192.168.121.21...

Connected to bright.test.com.

Escape character is '^]'.

Connection closed by foreign host.

[tomcat@dev_121_21 ~]$

 

问题场景很明显了,就是本地本机telnet不通80端口,其它的外部过来的访问80端口都ok。

 

问题分析:
外网访问需要经过PREROUTING链,但是localhost以及192.168.121.21本机ip地址不经过该链,因此需要用OUTPUT。

 

 

3、设置OUTPUT

设置output限制:

#在本机telnet也可以做转发到本机端口,不过限制了ip地址为localhost的域名访问

[root@dev_121_21 ~]#iptables -t nat -A OUTPUT -d 192.168.121.21 -p tcp --dport 80 -j REDIRECT --to-ports 8081        

 

#不限制ip地址的访问

[root@dev_121_21 ~]#iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 8081

 

PS:如果想外部内部都通过域名来走,而域名又绑定实际的ip地址的话,那么这里就需要采用第一种限制域名实际ip的方式来操作才能有效

 

# iptables永久生效,保存到系统配置中

[root@dev_121_21 ~]# service iptables save;

iptables:将防火墙规则保存到 /etc/sysconfig/iptables:     [确定]

[root@dev_121_21 ~]#      chkconfig --level 2345 iptables on;

[root@dev_121_21 ~]#      chkconfig --add iptables;

[root@dev_121_21 ~]# service iptables restart

iptables:清除防火墙规则:                                 [确定]

iptables:将链设置为政策 ACCEPT:nat                       [确定]

iptables:正在卸载模块:                                   [确定]

iptables:应用防火墙规则:                                 [确定]

[root@dev_121_21 ~]#

 

 

 

4、问题解决本地能通

 

再试下,本地就可以访问本地的service接口服务了:

[tomcat@dev_121_21 ~]$ wget http://bright.test.com/PLATFORM_AUTH_Service/remoting/AuthenticationService

--2016-11-22 12:51:14--  http://bright.test.com/PLATFORM_AUTH_Service/remoting/AuthenticationService

正在解析主机 bright.test.com... 192.168.121.21

正在连接 bright.test.com|192.168.121.21|:80... 已连接。

已发出 HTTP 请求,正在等待回应... 405 Method Not Allowed

2016-11-22 12:51:14 错误 405:Method Not Allowed。

 

[tomcat@dev_121_21 ~]$

 

 

参考文章:http://blog.youkuaiyun.com/zzhongcy/article/details/42738285

<think>好的,我现在需要解决用户的问题:如何配置本地服务器端口,使得通过curl访问时不仅可以返回正确内容,还能让外部网络访问。根据用户提供的引用内容,我需要综合这些信息来给出解决方案。 首先,用户提到使用SSH隧道将外网服务器端口映射到本地,比如8080端口,这样在本地浏览器可以访问。但可能遇到的问题是,当使用curl访问本地端口时,只能返回HTML,或者外部无法访问。这可能涉及到几个方面:服务绑定地址、防火墙设置、端口转发或代理配置,以及可能的容器网络配置。 引用[1]中,用户通过SSH隧道将服务器的8080端口映射到本地的8080端口。这种情况下,本地服务实际上是通过SSH隧道连接到远程服务器的,因此需要确保服务器上的服务正在监听正确的接口。例如,如果服务器上的服务仅绑定到127.0.0.1,那么即使通过SSH隧道映射,可能也只能在本地访问,而外部无法直接访问。需要检查服务是否绑定到0.0.0.0,以允许外部连接。 引用[2]提到Ollama服务默认绑定到127.0.0.1的11434端口,导致外部无法访问。解决方法是通过设置环境变量OLLAMA_HOST来改变绑定的地址。这提示用户需要调整服务的绑定地址,确保服务监听0.0.0.0,而不仅仅是本地回环地址。 引用[3]指出在Linux容器中,即使暴露了端口,外部仍然无法访问,可能因为容器配置问题或防火墙限制。例如,Docker可能需要正确映射端口,并且防火墙需要允许该端口的流量。此外,容器网络模式也可能影响外部访问。 综合这些信息,我需要分步骤指导用户检查服务绑定地址、防火墙设置、SSH隧道配置,以及可能的容器网络配置。例如,首先确认服务是否监听0.0.0.0:端口,然后检查防火墙是否开放该端口,接着确保SSH隧道正确映射,最后如果是容器应用,检查端口映射和网络设置。 用户的问题还可能涉及到curl返回HTML的问题,这可能是因为服务返回的是HTML内容,而用户期望其他格式,比如JSON。或者,curl命令可能需要添加特定的头信息来正确获取响应。不过用户的主要诉求是外部访问,因此需要优先解决网络配置问题。 总结解决步骤: 1. 确保服务绑定到0.0.0.0而非127.0.0.1。 2. 检查服务器防火墙,开放对应端口。 3. 正确配置SSH隧道,确保端口映射正确。 4. 如果是容器应用,检查Docker端口映射和网络设置。 5. 测试外部访问,使用curl或浏览器验证。 同时,生成相关问题,帮助用户深入理解可能涉及的方面,比如服务绑定配置、防火墙管理、SSH隧道优化,以及容器网络配置等。</think>### 分步解决方案 #### **步骤1:确认服务绑定地址** 服务默认可能仅绑定在本地回环地址$127.0.0.1$,需修改为监听所有网络接口$0.0.0.0$: 1. 检查服务配置文件(如Nginx、Flask、FastAPI等),将`host`参数设为$0.0.0.0$ - 例如Flask启动命令:`flask run --host=0.0.0.0 --port=8080` 2. 若使用容器(如Docker),确保启动命令包含`-p 主机端口:容器端口`,例如:`docker run -p 8080:8080 ...`[^3] #### **步骤2:检查防火墙配置** 开放服务器对应端口: 1. Linux系统使用`ufw`或`iptables`放行端口: ```bash sudo ufw allow 8080/tcp sudo ufw reload ``` 2. Windows系统需在防火墙高级设置中添加入站规则 #### **步骤3:验证SSH隧道配置** 确保SSH隧道正确映射远程端口到本地: ```bash ssh -CNg -L 本地端口:远程服务器IP:远程服务端口 用户名@服务器域名 -p SSH端口 ``` - 示例:将远程8080映射到本地8080: `ssh -CNg -L 8080:0.0.0.0:8080 user@example.com -p 22`[^1] #### **步骤4:处理容器网络问题** 若服务运行在容器内: 1. 检查容器网络模式是否为`bridge`,并正确映射端口 ```bash docker run -d --name myapp -p 8080:8080 myimage ``` 2. 确保容器内部服务监听$0.0.0.0$,而非仅$127.0.0.1$[^3] #### **步骤5:测试外部访问** 1. 本地测试:`curl http://127.0.0.1:8080/api` - 若返回HTML,检查服务是否配置了API路由 2. 外部设备访问:通过另一台设备访问`服务器公网IP:8080` - 若失败,排查防火墙或云服务商安全组规则 --- ### 相关问题 1. 如何验证服务是否成功绑定到$0.0.0.0$? 2. SSH隧道端口映射失败的可能原因有哪些? 3. Docker容器端口映射无效时如何调试? 4. 如何通过Nginx反向代理实现外部访问? --- ### 引用说明 : SSH隧道通过将远程端口映射到本地实现服务访问,需确保命令格式正确且网络策略允许。 [^2]: 修改服务绑定地址(如设置$OLLAMA_HOST=0.0.0.0$)可解除仅本地访问限制。 : Docker需同时配置容器端口映射和宿主防火墙规则,避免出现“Connection refused”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值