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> 首先,用户查询是:“我想查找websocket外网无法访问Linux服务器的解决方案”,意思是“I want to find a solution for WebSocket not being accessible externally on a Linux server”。 我需要根据提供的系统级指令来回应。指令包括: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 用户的问题是关于WebSocket外网无法访问Linux服务器的解决方案。提供的引用有多个来源: - 引用[1]: 描述了一个问题,WebSocket连接失败,错误是Unexpected response code: 200。用的是.NET环境,但问题类似。 - 引用[2]: 给出了在Windows上启用WebSocket协议的方法,以及绑定IP的建议。 - 引用[3]: 提到了Linux系统上绑定IP的问题,错误是“unable to bind address”。 - 引用[4]: 讨论了使用Nginx反向代理来解决路由器不支持外网访问的问题。 用户说“上述引用仅供参考”,但我应该参考用户上一次的问题和我的回答。查看历史,用户上一个查询是关于同一个主题的,但在这个对话中,现在是首次响应。系统指令提到“参考用户上一次的问题和你的回答”,但在这个上下文中,这是初始查询。 在系统指令中,它说“请尽可能多的参考用户上一次的问题和你的回答”,但在这个消息中,用户没有指定上一个问题。所以,我应该基于当前查询和提供的引用。 我的回答结构需要清晰,帮助用户逐步解决问题。确保回答真实可靠。 关键点:用户正在使用Linux服务器。 从引用中提取相关解决方案: 1. 绑定正确的IP地址(引用[2]和[3]):确保WebSocket服务绑定到服务器的公共IP或0.0.0.0(所有接口),而不是127.0.0.1。 2. 防火墙设置(推断):Linux防火墙可能需要允许WebSocket端口(通常是80或443,或自定义端口)。 3. Nginx反向代理(引用[4]):设置Nginx作为反向代理来处理WebSocket连接。 4. 其他考虑:路由器端口转发、DNS设置等。 逐步解决方案: 1. **检查WebSocket服务绑定IP**:确认服务绑定到0.0.0.0或服务器的公网IP。 2. **配置防火墙**:打开WebSocket端口。 3. **使用Nginx反向代理**:设置Nginx代理WebSocket流量。 4. **路由器设置**:确保路由器端口转发到服务器。 5. **测试连接**:使用工具测试。 最后,生成相关问题。 回答用中文。 现在,关于数学表达式:用户的问题是关于WebSocket的,所以可能没有数学内容。但指令说“所有行内数学表达式必须使用$...$格式”。如果没有涉及数学,我应该避免强制添加。但在响应中,如果没有相关内容,就不用添加。 同样,对于独立公式:可能不需要。如果有任何计算或公式,我会使用$$...$$。 在WebSocket上下文中,不太可能有数学公式。所以,我应该专注于文本。 生成相关问题:在末尾添加相关问题。 引用标识:在回答中引用参考时,末尾添加如“[^1]”。 在响应中,我应该引用提供的文献。 结构化回答: - 引言:总结问题。 - 逐步解决方案。 - 结尾:确认或建议。 - 相关问题。 确保真实可靠:基于一般知识和引用。 最终响应: 1. 用中文。 2. 清晰步骤。 3. 引用参考。 4. 生成问题。 </think> ### WebSocket外网无法访问Linux服务器的解决方案 当WebSocket服务在Linux服务器上部署后,外网无法访问是一个常见问题,通常源于网络配置、服务绑定或代理设置不当。以下基于常见原因和最佳实践,提供一个逐步的解决方案流程。这些步骤融合了网络调试经验和相关引用建议,确保真实可靠。WebSocket协议通常使用端口80(HTTP)或443(HTTPS),也可能自定义端口如8080,因此在操作中需根据您的实际端口调整(例如,如果您使用自定义端口$port$,则替换相关命令)。 #### 步骤1: 检查WebSocket服务绑定IP WebSocket服务必须绑定到服务器的公网IP或所有接口(0.0.0.0),而不是仅绑定到本地环回地址(127.0.0.1)。否则,外网请求无法到达服务。 - **操作指南**: - 检查您的WebSocket代码(如Node.js、Python或PHP),确保绑定地址设置为0.0.0.0。例如,在PHP中使用`socket_bind()`时,IP应设为0.0.0.0: ```bash # 示例代码修改(参考引用[3]) $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_bind($socket, '0.0.0.0', 端口号); # 替换为您的实际端口 ``` 如果绑定错误如“unable to bind address”,表示IP配置无效,需更正为公网对应的内网IP或0.0.0.0[^3]。 - 使用命令行验证绑定状态: ```bash netstat -tuln | grep '端口号' # 检查服务是否在0.0.0.0上监听 ``` 输出应显示类似`0.0.0.0:端口号`的条目。如果不是,修改服务配置后重启服务。 #### 步骤2: 配置Linux防火墙 Linux防火墙(如iptables或firewalld)可能阻止外网流量。需开放WebSocket端口以保证通信。 - **操作指南**: - 使用firewalld(推荐在CentOS/Ubuntu): ```bash sudo firewall-cmd --zone=public --add-port=端口号/tcp --permanent # 添加端口规则 sudo firewall-cmd --reload # 重载配置 ``` - 使用iptables(如果未安装firewalld): ```bash sudo iptables -A INPUT -p tcp --dport 端口号 -j ACCEPT sudo service iptables save # 保存规则 ``` - 测试端口开放性: ```bash telnet 服务器公网IP 端口号 # 从外网设备测试连接 ``` 如果连接失败,检查防火墙规则是否生效或路由器是否转发流量(参考步骤4)。 #### 步骤3: 设置Nginx反向代理 Nginx可作为反向代理转发WebSocket流量,解决直接暴露服务的安全问题或路由器限制(如引用[4]所述)。这尤其适用于外网访问时出现HTTP 200错误(非WebSocket响应),表明客户端收到普通HTTP响应而非WebSocket握手。 - **操作指南**: - 安装并配置Nginx: ```bash sudo yum install nginx # CentOS sudo apt-get install nginx # Ubuntu ``` - 编辑Nginx站点配置文件(如`/etc/nginx/conf.d/websocket.conf`),添加代理设置: ```nginx server { listen 80; # 或443 for HTTPS server_name 您的域名或公网IP; location /websocket-path { # 替换为您的WebSocket路径 proxy_pass http://localhost:内部端口; # WebSocket服务的内网地址 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400s; # 保持长连接 } } ``` 此配置确保WebSocket握手正确传输(避免Unexpected response code: 200错误[^1])。 - 重启Nginx并测试: ```bash sudo nginx -t # 检查配置正确性 sudo systemctl restart nginx ``` 外网访问时使用`ws://域名或IP/websocket-path`。 #### 步骤4: 路由器端口转发和DNS设置 如果服务器位于内网,路由器需将外网端口转发到服务器内网IP,否则流量无法穿透。 - **操作指南**: - 登录路由器管理界面(如192.168.1.1),设置端口转发: - 外部端口(如8080)转发到服务器内网IP和WebSocket端口。 - 确保转发协议为TCP(WebSocket基于TCP)。 - 检查服务器公网IP是否固定;如果动态,使用DDNS服务绑定域名。 - 如果路由器不支持转发(如引用[4]场景),可结合步骤3的Nginx代理解决。 #### 步骤5: 测试和调试 完成配置后,全面测试连接性: - **本地测试**: - 从服务器内部使用`curl`或浏览器工具验证WebSocket服务可用: ```bash curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: localhost" http://localhost:端口号 ``` 应返回HTTP 101 Switching Protocols表示成功。 - **外网测试**: - 使用外网设备访问WebSocket地址(例如浏览器开发者工具或在线WebSocket测试工具)。 - 常见错误排查: - 如果出现HTTP 200错误,检查Nginx代理配置或服务绑定[^1]。 - 如果连接超时,确认防火墙和路由器转发生效。 - 使用工具如`tcpdump`抓包分析: ```bash sudo tcpdump -i eth0 port 端口号 # 监控流量 ``` #### 总结 以上步骤覆盖了WebSocket外网访问失败的主要成因:绑定IP错误、防火墙封锁、缺乏代理或路由器配置。解决方案成功率较高,但需根据您的具体环境调整(如WebSocket端口和服务器OS)。如果问题持续,提供更多细节(如错误日志)便于进一步诊断[^1][^3][^4]。一般在Linux服务器上实施后,外网可正常连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值