简短版本:如何允许 Linux 服务器上的 Yast 防火墙允许套接字连接到随机(由操作系统)选择的端口?
更长的版本:我的大型 Java 程序的一部分有一个客户端使用套接字连接到服务器。初始连接是在特定端口上使用 ConnectionManager 完成的,它为客户端提供要连接的端口和密码。我最初选择端口的方式是通过防火墙允许的端口列表(所有端口均高于 49152)。我注意到这个新连接会随机工作,或者拒绝连接。我得出的结论是端口被关闭或被其他东西使用(尝试关闭防火墙,但没有帮助)。
然后有人建议我让操作系统通过不指定端口号来选择端口(根据此构造函数使用 0:Java文档)。这选择了一个空闲端口,当防火墙关闭时,它可以正常工作。但是,防火墙会阻止连接,并且客户端会超时。
有没有办法设置 Yast 防火墙以允许套接字,而不会过度暴露服务器?或者我可以/应该为 Java 指定一个端口号范围以选择一个开放的端口,并允许这些端口?
注意:我最初在 stackoverflow 上提问,有人建议我在这里发帖。那里的情况完全一样:堆栈问题。
答案1
TCP 连接能够通过源 IP、源端口、目标 IP 和目标端口的组合进行唯一标识。一个很好的例子是 Web 服务器 - 每个人都在端口 80 上连接到它,但它能够同时维护与同一端口的所有这些连接,因为每个连接的源 IP 和端口都不同。
我在这里要说的是,为每个连接客户端打开一个不同的监听端口,这有点像在重新发明轮子。以同样方式运行的协议的最佳示例是被动模式 FTP。一些防火墙之所以能很好地处理它,只是因为深度数据包检查 - 由于需要打开高端口,所以在协议检查中存在代码,但这是针对被视为“传统”做事方式的特定一次性解决方法。
我建议对所有传入的客户端流量使用单个端口,这是一种更符合防火墙要求的允许客户端连接的方式 - 无论是在您这边还是在客户端,而客户端这边的防火墙策略可能经常会阻止高目标端口。如果您不担心这一点,并且确实指定了一系列端口并让所有端口通过防火墙,请确保没有其他任何端口正在监听这些端口。
答案2
在 YaST 方面 - 您不需要这样做,您可以直接使用 iptables 来允许/拒绝端口。更好的方法是在 Java 中打开正确的端口 - 通过迭代范围并尝试每个端口直到成功(如果其他人正在使用该端口,绑定将抛出异常),然后在防火墙中打开该范围。
另一种方法是(这是程序员的问题,但更适合 SO :))使用套接字池,您的应用程序将使用它。有一个好例子在 Koders。