如何访问 Linux 上的开放和侦听端口?

如何访问 Linux 上的开放和侦听端口?

转发我希望打开的端口后,我似乎无法连接该端口或从该端口获取任何数据。我编写的 PHP CLI 软件正在主动监听端口乌班图14.04。部分代码如下所示。端口作为 AF_INET 打开,脚本每行都不会抛出错误,并且 /etc/protocols 将 tcp 定义为“tcp 6 TCP”。

// I have tried $host=gethostbyname(gethostname());$port=8399 (host is 127.0.1.1)
// as well as $host = '0.0.0.0'; $port = 8399; and other addresses

$this->wsRead[0] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)
socket_set_option($this->wsRead[0], SOL_SOCKET, SO_REUSEADDR, 1)
socket_bind($this->wsRead[0], $host, $port) 
socket_listen($this->wsRead[0], 10)
while (isset($this->wsRead[0])) { /* Handshake/Process data, etc. */ }

端口已转发,我的iptables 为空,尽管我已经尝试专门为该端口添加允许规则。我尝试以超级用户身份运行脚本。当服务器正在侦听时,netstat -tuln 列出了这一行(带有我的端口 8399),我注意到 apache 也列出了,它工作正常并显示为来自外部端口检查网站的开放端口(在端口 8301 上):

Proto Recv-Q Send-Q Local Address      Foreign Address    State
tcp        0      0 0.0.0.0:8399       0.0.0.0:*          LISTEN
tcp6       0      0 :::8301            :::*               LISTEN
tcp6       0      0 :::80              :::*               LISTEN

使用 nmap 端口也显示为打开。我也尝试过不同的端口。我的客户端连接脚本是一个 JavaScript websocket 脚本,可在 Windows 上运行 PHP CLI 时进行连接。该脚本太长,无法包含在此处,并且它不从外部网络连接。如果我将 JS 和 PHP 脚本设置为本地地址 127.0.0.1 或 192.168.0.###,那么它可以工作,但不能从我的 LAN 之外的设备上工作。

// The JS is basically this, plus some connection events to alert success/fail.
// This external connection request will always time out
Server = new WebSocket('ws://68.215.154.129:8399');

除了 iptables 之外,我是否在 Linux 中缺少一些我没有绕过的防火墙? Apache 正在正确打开端口以及 PC 上的其他软件,但我的脚本似乎缺少完全打开端口以供外部使用的必要步骤。

TL,博士;使用 JavaScript 客户端使用外部 IP 地址连接到在 Windows 上运行但在 Ubuntu 上运行的 PHP 服务器。端口转发、监听、不被 iptables 阻止, 还剩下什么?

答案1

您在概念上和代码中遗漏了一些东西。您有 PHP 代码侦听连接,但您必须在使用它之前接受连接。

$ns = socket_accept($this->wsRead[0]);
$some_string = socket_read($ns, 128);

对块的调用socket_accept()。直到某个客户端程序连接到正在等待连接的程序时,它才会返回。

调用socket_accept()返回您用于与远程程序通信的实际套接字。我不认为isset()这真的是你想要的,你应该调查一下socket_select()什么的。当您完成与远程的通信后,您可以调用socket_close($ns),然后循环返回以socket_accept($this->wsRead[0])等待另一个远程程序连接到您的程序。

当您的 PHP 程序完成处理连接时,它应该调用socket_close($this->wsRead[0])关闭套接字,这基本上告诉操作系统内核停止侦听您指定端口的传入 TCP SYN 数据包。

答案2

事实证明,问题出在多个方面,主要源于我的调制解调器/路由器。我用一个摩托罗拉SB6580,最近进行了固件更新,并且已经有10天没有重新启动了,导致它变得相当慢,阻止了我想要对其进行太多更改。

固件更新更改了端口转发页面包含外部远程主机地址部分(默认为 0.0.0.0)在这里没有问题,但他们确实打破了我设置的现有端口转发规则。

我使用了一系列无法​​转发的端口,通过将此范围更改为 8399 - 8399,它再次开始工作。除了提高调制解调器速度之外,重新启动并没有影响它,将协议从 Both 更改为 TCP 也没有影响。

IP Addr|Start Port|End Port|Remote Host Addr|Start Port|End Port|Protocol|Enabled
192.168.0.101|8340|    8399|         0.0.0.0|      8340|    8399|    Both|Checked
192.168.0.101|8399|    8399|         0.0.0.0|      8399|    8399|     TCP|Checked

另外,在 Linux 上使用 PHP 命令 gethostbyname(gethostname()) 时,返回的地址是本地地址 127.0.1.1,即 /etc/hosts 文件中的第二个条目,这不适用于绑定套接字。 $_SERVER['REMOTE_ADDR'] 还返回警告:无法查找主机。经过手动将其更改为家庭(子网?)地址(我的是 192.168.0.101)或 IPv4 通配符 0.0.0.0,套接字侦听器已正确绑定并接受外部连接。

我对路由器的使用经验和对 Linux 的缺乏经验使我倾向于在 Linux 故障排除方面走上错误的道路。在注意到 Windows 7 上的情况也无法正常工作后,我进行了上述 2 项更改,现在一切都可以正常工作。

相关内容