Python Requests,如何指定出站流量的端口?

7
我正在从事一个项目,在这个项目中,我们想要为防火墙上的入站流量分配白名单数据包过滤器。我们使用带有requests库的Python脚本对该网络之外的一些服务器进行一些https请求。目前,脚本正在使用临时端口连接到服务器,但是我们希望通过指定端口进行这些https请求。这将允许我们为这些端口创建严格的白名单。
如何指定端口给请求库以便发送请求?目前,该脚本使用以下类型的代码来发送必要的请求。
response = requests.post(data[0], data=query, headers=headers, timeout=10)

这个方法可行,但是我现在需要指定发送http post请求的端口,以允许在网络上进行更严格的数据包过滤。该如何实现端口声明?我已经从多个来源搜索了解决方案,但是没有找到任何有用的信息。


你不能在标准套接字上这样做。端口是由你的操作系统选择的。 - Klaus D.
3
可以在标准插座上这样做。默认是将此任务留给操作系统。 - Martijn Pieters
@KlausD:诀窍在于如何告诉请求使用特定端口而不是默认端口。 - Martijn Pieters
虽然这可能是正确的,但它不会在防火墙上增加任何安全性。 - Klaus D.
2
@KlausD.:当然可以。然后,您可以将出站连接限制为非常特定的本地端口和目标IP地址。 - Martijn Pieters
1个回答

16

requests基于urllib3构建,它提供了设置连接源地址的功能;当你将源地址设置为('', port_number)时,你告诉它使用默认主机名但选择特定的端口。

你可以在连接池管理器上设置这些选项,并通过创建新的传输适配器告诉requests使用不同的连接池管理器:

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager


class SourcePortAdapter(HTTPAdapter):
    """"Transport adapter" that allows us to set the source port."""
    def __init__(self, port, *args, **kwargs):
        self._source_port = port
        super(SourcePortAdapter, self).__init__(*args, **kwargs)

    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(
            num_pools=connections, maxsize=maxsize,
            block=block, source_address=('', self._source_port))

将此适配器用于会话对象中,以下代码将适配器安装到所有的HTTP和HTTPS连接中,使用54321作为源端口:

适配器应用于会话对象,下面的代码将适配器安装到所有的HTTP和HTTPS连接中,使用54321作为源端口:
s = requests.Session()
s.mount('http://', SourcePortAdapter(54321))
s.mount('https://', SourcePortAdapter(54321))

您只能设置一个源端口,这将限制您一次只能有一个活动连接。如果您需要在不同的端口之间轮换,请注册多个适配器(每个 URL 一个)或每次重新注册全局挂载点。

有关 source_address 选项的详细信息,请参见create_connection() 实用程序函数文档

如果设置了 source_address,则必须将其设置为要在建立连接之前将套接字绑定为源地址的 (host, port) 元组。主机为 '' 或端口为 0,则表示使用默认值。


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