Python套接字监听所有端口。

6

基本上,我想使用socket模块监听所有端口。如何使port等于服务器上所有开放的端口?非常感谢任何指南或资源。这是我的当前代码。

import socket

def Main():
    host = '127.0.0.1'
    port = 5000

    s = socket.socket()
    s.bind((host, port))

    s.listen(1)
    c, addr = s.accept()
    print('Connection from: ' + str(addr))
    while True:
        data = c.recv(1024)
        if not data:
            break
        print('from connected user: ' + str(data))
        data = str(data).upper()
        print('sending: ' + str(data))
        c.send(data)
    c.close()


if __name__ == '__main__':
    Main()

1
你真的是指“所有”端口吗?它们总共有65535个。 - Paul Cornelius
2
可能是如何使服务器侦听多个端口的重复问题。 - agtoever
1
@PaulCornelius 是的,所有65535个性感端口。 - a2mky
2个回答

8

您可以尝试所有可能的端口并将它们存储在一个列表中。请记住,1024以下的端口是保留端口,某些端口可能正在使用中。因此,如果无法绑定到该端口,则会出现一些错误,您需要处理这些错误。此外,由于套接字只能监听一个端口,因此每个端口都需要一个套接字。创建一个名为create_socket的函数来返回套接字,然后将它们存储在一个列表中。如果在尝试连接时出现错误,则只需跳过这些错误。这可能不是一个好的方法,但它可以为您工作。

def create_socket(port_number):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(('127.0.0.1', port_number))
    server_socket.listen(1)

    return server_socket

socket_list = []

for port_number in range(1025,65536):
    try:
        socket_list.append(create_socket(port_number))
    except Exception: 
        pass        

这个在某种程度上是有效的。Python(或者更确切地说是ulimit)一次只能打开有限数量的文件。在我的Mac上,这个限制似乎是10236,否则会出现错误<class 'OSError'> [Errno 24] Too many open files - JBirdVegas

1

进行数据包过滤和转换

另一种方法是在主机上设置数据包过滤和转换,将所有传入的TCP请求定向到您的进程,而不考虑目标端口。sshuttle 就是这样将所有请求隧道化到一个 ssh 服务器。这样,您的进程就不需要打开成千上万个文件。

在 freeBSD/macOS 中,可以通过以下方式进行配置。其他操作系统会有它们特定的做法(例如 Debian 中的 nftables 的 nft(8))。

配置文件

创建一个文件(此示例中命名为 rules.txt),其内容如下:

# Redirect incoming traffic on interface en0 to localhost:5000
rdr pass on en0 inet proto tcp all -> 127.0.0.1 port 5000

en0更改为您希望拦截传入连接的接口。删除inet或替换为inet6以分别接受IP和IPv6或仅接受IPv6。请查看pf.conf(5)以获取此文件的确切语义和语法。

启用规则

在具有管理访问权限的情况下运行以下命令,以加载先前创建文件中包含的规则。

启用数据包过滤和转换:

pfctl -e

清空所有内容(谨慎操作,因为这将删除已经设置的路由和翻译配置):

pfctl -F a

加载规则:

pfctl -f rules.txt

测试一下。

同时包括出站流量

如果您也想像sshuttle一样包括出站流量,则应将下一行附加到rules.txt

pass out route-to lo0 inet proto tcp all

您还可以调整此规则,使其更具选择性,并避免设置网络监狱(请参见下面的注释1)。

注释

  1. 如果包括出站流量,则除非您先接收连接或具有替代接口,否则将无法与外部世界通信。这是因为出站流量将被路由到您的catchall进程(由于route-to关键字)。
  2. 请注意,此方法允许绑定到本地主机的进程可从外部访问。在上面的设置中,任何连接到en0上的任何端口的人都将能够与绑定到127.0.0.1:5000的进程通信。
  3. 记得在更改rules.txt后重新加载规则以使其生效。
  4. 要禁用数据包过滤和转换,请运行pfctl -d。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接