【问题标题】:Can't estabilish connection in TCP port from external host无法从外部主机建立 TCP 端口连接
【发布时间】:2018-08-14 19:21:31
【问题描述】:

请有人帮我解决这个问题!我现在真的挣扎了好几个小时。不知道怎么办了,到处找每一页,还是没有解决办法。

我有一个侦听端口 443 (https - TCP) 的 Python 脚本。它通过此端口接收 JSON POST 消息。问题是它没有从外部主机接收任何东西,只从它自己接收。我的意思是,当我使用来自外部主机的 POSTMAN 模拟 POST 时,它永远不会回答:

(我用“y.y.y.y”屏蔽了我的服务器 IP,用“xxxx”屏蔽了我的脚本中的令牌)

但是当我从自己的服务器内部发送完全相同的内容时,它可以完美运行。从我自己的服务器内部发送的代码:

[root@rrpump bot]# curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache"  -d '{
> "update_id":10000,
> "message":{
>   "date":1441645532,
>   "chat":{
>      "last_name":"Test Lastname",
>      "id":1111111,
>      "type": "private",
>      "first_name":"Test Firstname",
>      "username":"Testusername"
>   },
>   "message_id":1365,
>   "from":{
>      "last_name":"Test Lastname",
>      "id":1111111,
>      "first_name":"Test Firstname",
>      "username":"Testusername"
>   },
>   "text":"/start"
> }
> }' "https://y.y.y.y/xxxx"

成功响应:

* About to connect() to y.y.y.y port 443 (#0)
*   Trying y.y.y.y...
* Connected to y.y.y.y (y.y.y.y) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
*       subject: CN=y.y.y.y 1,O=Example Brooklyn Company,L=Brooklyn,ST=New York,C=US
*       start date: Mar 06 13:54:03 2018 GMT
*       expire date: Mar 06 13:54:03 2019 GMT
*       common name: y.y.y.y
*       issuer: CN=y.y.y.y,O=Example Brooklyn Company,L=Brooklyn,ST=New York,C=US
> POST /xxxx HTTP/1.1
> User-Agent: curl/7.29.0
> Host: y.y.y.y
> Accept: */*
> Content-Type: application/json
> Cache-Control: no-cache
> Content-Length: 392
>
* upload completely sent off: 392 out of 392 bytes
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: WebhookHandler/1.0 Python/3.6.4
< Date: Tue, 06 Mar 2018 16:52:55 GMT
<
* Closing connection 0

已经检查过它是否真的在那个端口监听:

[root@rrpump bot]# lsof -i:443
COMMAND     PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME
python3.6 30644 root    8u  IPv4 2785755157      0t0  TCP *:https (LISTEN)

也已经检查了 iptables(最后的“接受”行):

[root@rrpump bot]# iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited
           all  --  anywhere             anywhere
           tcp  --  anywhere             anywhere
           tcp  --  anywhere             anywhere             tcp dpt:pcsync-https
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:pcsync-https
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

防火墙也被禁用:

[root@rrpump bot]# firewall-cmd --permanent --add-port=443/tcp
FirewallD is not running

我在 CENTOS 7 64bits,美国托管 VPS 服务器上运行它。我忘了在这里检查什么??!

【问题讨论】:

  • 防火墙。您正在考虑在防火墙中打开 443。或者,因为您只有一个自签名的 ssl 证书,所以客户端无法建立连接。但请先尝试防火墙。
  • 在 iptables 规则中,您的脚本在 accept 规则之前有 reject 规则。它们从未被使用过。您必须将reject 规则移动到表的末尾(或删除它们,并将输入链的默认策略设置为rejectdrop
  • 我做了一个编辑:防火墙被禁用@barny
  • @RodrigoFormighieri 防火墙规则用于内核级别。因此禁用某些系统守护程序并不意味着您的主机是敞开的。总是有一些规则。您可以检查它 - 禁用防火墙守护程序,然后使用 iptable 列出规则。
  • @rsm,我正在尝试按照您对 iptables 所说的去做。关于防火墙,当我配置 VPS 时,它已在系统中禁用。你的意思是防火墙配置仍然是问题之一?

标签: python ssl tcp centos iptables


【解决方案1】:

在 iptables 规则中,您的脚本有 reject 规则和 accept 规则。它们从不使用,因为它们按照 iptables 列出它们的顺序进行检查。所以内核首先找到匹配的reject 规则。您必须将 reject 规则移动到表格的末尾,或者将您的规则移动到顶部(使用 iptables -I 插入它们,而不是通过 iptables -A 附加)。 或者删除reject规则,并将输入链的默认策略设置为rejectdrop)。

另外请记住,内核级别的所有表总是有一些规则(至少是默认策略)。因此,通过禁用某些系统守护程序,您不一定会让您的主机对所有连接开放。如果不确定,请始终参考iptables --list

哦,还有一个旧的解决方案,用于根据文件 /etc/hosts.allow/etc/hosts.deny 的内容接受/拒绝 TCP 连接。请检查一个是否允许连接到 443,而另一个是否拒绝。

【讨论】:

  • 哇!有效!问题是 REJECT ALL 规则高于我在 iptables 中的 ACCEPT (https-TCP) 规则!非常感谢@rsm
  • 很高兴能帮上忙 :) 感谢您接受回答,人们往往会忘记它。
  • 你完全值得我的朋友
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
  • 2018-09-03
  • 2019-03-11
相关资源
最近更新 更多