Python请求,如何为传出流量指定端口?

时间:2017-11-09 13:14:13

标签: python linux python-requests port firewall

我正在开发一个项目,我们希望为防火墙上的传入流量分配白名单数据包过滤器,我们正在使用带有请求库的python脚本向该网络之外的某些服务器发出一些https请求。目前,脚本使用临时端口连接到服务器,但我们希望通过特定端口发出这些https请求。这将允许我们为这些端口创建严格的白名单。

如何指定请求应通过其发送请求的端口?脚本当前正在使用以下类型的代码来发送必要的请求。

response = requests.post(data[0], data=query, headers=headers, timeout=10)

这有效,但我现在需要指定应该发送http post请求的端口,以允许在网络上进行更严格的数据包过滤。如何实现这个港口宣言?我已经从几个来源搜索过这个问题的解决方案,并且完全没有提出任何问题。

1 个答案:

答案 0 :(得分:4)

requests建立在urllib3之上,可以为连接设置源地址;当您将源地址设置为('', port_number)时,您告诉它使用默认主机名,但选择一个特定端口。

您可以在pool manager上设置这些选项,并通过创建新的transport adapter告诉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))

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

s = requests.Session()
s.mount('http://', SourcePortAdapter(54321))
s.mount('https://', SourcePortAdapter(54321))

您只能设置一个源端口,一次限制为一个活动连接。如果需要在端口之间轮换,请注册多个适配器(每个URL一个)或每次重新注册catch-all安装。

有关source_address选项的详细信息,请参阅create_connection() utility function documentation

  

如果设置了source_address,则它必须是(host, port)的元组,以便在建立连接之前将套接字绑定为源地址。主持人''或端口0告诉操作系统使用默认值。