1

这个问题是我遇到过的最奇怪的 5 件事。所以请多多包涵。

我正在使用 ufw 防火墙运行 arch linux(截至 2017 年 3 月 9 日是最新的)。

启用防火墙后,我无法再连接到基于 websocketpp 的应用程序。不,我没有封锁有问题的端口。

事实上,如果我禁用防火墙,我仍然无法连接,直到我重新启动整个计算机(只是重新启动有问题的应用程序没有帮助)。

而且,UFW 也允许本地主机上的所有流量,但如果我在本地连接,它并没有什么不同。

我也用websocketpp 存储库中的示例回显服务器验证了这个问题。

检查我的应用程序是否在端口 9002 上侦听

sudo netstat -lnp | grep 900
tcp6       0      0 :::9002                 :::*                    LISTEN      12695/./bin/echo_se 

在这里我们可以看到 echo server 绑定到了 ipv6。但是仅更改为 ipv4 并没有帮助。已经试过了。

带有调试的回显服务器的输出

[2017-03-09 11:38:06] [devel] endpoint constructor
[2017-03-09 11:38:06] [devel] server constructor
[2017-03-09 11:38:06] [devel] asio::init_asio
[2017-03-09 11:38:06] [devel] set_message_handler
[2017-03-09 11:38:06] [devel] asio::listen
[2017-03-09 11:38:06] [devel] create_connection
[2017-03-09 11:38:06] [devel] asio con transport constructor
[2017-03-09 11:38:06] [devel] connection constructor
[2017-03-09 11:38:06] [devel] transport::asio::init
[2017-03-09 11:38:06] [devel] asio::async_accept

我正在使用 telnet 尝试连接(因为此时我只关心 tcp 握手

telnet localhost 9002
Trying ::1...
(eventually timeout)

如果我关闭回声服务器,那么就没有应用程序在监听了。然后我得到(如预期的那样)

telnet localhost 9002
Trying ::1...
Connection failed: Connection refused
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

所以,现在操作系统注意到没有人在监听并发送连接被拒绝。

和 UWF 规则:

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere                  
22                         ALLOW       Anywhere                          
7000:8000/udp              ALLOW       Anywhere                  
7000:8000/tcp              ALLOW       Anywhere                  
9000:9500/tcp              ALLOW       Anywhere                  
9002                       ALLOW       Anywhere                  
22/tcp (v6)                ALLOW       Anywhere (v6)             
22 (v6)                    ALLOW       Anywhere (v6)                    
7000:8000/tcp (v6)         ALLOW       Anywhere (v6)             
9000:9500/tcp (v6)         ALLOW       Anywhere (v6)             
9002 (v6)                  ALLOW       Anywhere (v6)             

我还应该提到其他服务器。例如我在同一个端口上尝试过的最小提升 asio telnet 服务器、基于 zmq 的服务器等工作得很好。

所以,我认为它一定是 websocketpp 的东西,但我不明白它可能是什么。感觉不可能,因为 tcp 握手是在应用程序级别以下执行的。

在这一点上,任何想法都会受到赞赏。

为了完整性。禁用 UFW 并重新启动后,我从 echo server 得到这个:

2017-03-09 11:49:17] [devel] endpoint constructor
[2017-03-09 11:49:17] [devel] server constructor
[2017-03-09 11:49:17] [devel] asio::init_asio
[2017-03-09 11:49:17] [devel] set_message_handler
[2017-03-09 11:49:17] [devel] asio::listen
[2017-03-09 11:49:17] [devel] create_connection
[2017-03-09 11:49:17] [devel] asio con transport constructor
[2017-03-09 11:49:17] [devel] connection constructor
[2017-03-09 11:49:17] [devel] transport::asio::init
[2017-03-09 11:49:17] [devel] asio::async_accept
[2017-03-09 11:49:23] [devel] asio::handle_accept
[2017-03-09 11:49:23] [devel] connection start
[2017-03-09 11:49:23] [devel] asio connection init
[2017-03-09 11:49:23] [devel] asio connection handle pre_init
[2017-03-09 11:49:23] [devel] asio connection post_init
[2017-03-09 11:49:23] [devel] asio connection handle_post_init
[2017-03-09 11:49:23] [devel] connection handle_transport_init
[2017-03-09 11:49:23] [devel] connection read_handshake
[2017-03-09 11:49:23] [devel] asio async_read_at_least: 1
[2017-03-09 11:49:23] [devel] create_connection
[2017-03-09 11:49:23] [devel] asio con transport constructor
[2017-03-09 11:49:23] [devel] connection constructor
[2017-03-09 11:49:23] [devel] transport::asio::init
[2017-03-09 11:49:23] [devel] asio::async_accept
[2017-03-09 11:49:23] [devel] asio post init timer cancelled

这在 telnet 中:

telnet localhost 9002
Trying ::1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

因此,一切正常。

并且“在 sudo ufw enable && sudo ufw disable 之后”它不再起作用......

4

1 回答 1

1

好的,经过两天的调试(在我写问题的前一天和今天)我找到了它。

操作系统的 listen() 调用中的 backlog 参数为 0。当加载 UFW/iptables 时,这会导致服务器无法正常运行,否则服务器会正​​常运行。

为什么加载或不加载 iptables 的行为会有所不同,这对我来说是个谜。

这篇文章建议即使设置为 0,积压工作至少应该是 16。也许(这是我猜的)加载了 iptables 的内核不再对积压参数进行四舍五入,而 0 会导致它“不起作用”。我可以理解,因为 0 的队列没有意义。

反正。将积压工作设置为 64 解决了我的问题。

websocketPpServerObject.set_listen_backlog(64);

如果您对更多细节感兴趣,也可以查看这个 github 线程。

于 2017-03-09T15:37:27.727 回答