一个自动通过NTLM代理进行认证的HTTP代理服务器
项目描述
Px
什么是Px?
Px是一个HTTP(s)代理服务器,允许应用程序通过NTLM或Kerberos代理服务器进行认证,通常用于企业部署,无需处理实际的握手。Px利用Windows SSPI或单点登录,并自动使用当前登录的Windows用户账户进行认证。也可以在不使用单点登录的情况下,通过配置域名、用户名和密码来在Windows、Linux和MacOS上运行Px。
Px使用libcurl,因此支持libcurl支持的所有认证机制。
安装
Px的整个目的是帮助工具通过典型的企业代理。这意味着使用包管理器安装Px可能并不总是可行,这就是为什么Px提供了两种二进制选项
-
如果Python已经可用,可以通过从发布页面下载目标操作系统的
wheels
软件包来轻松安装Px及其所有依赖项。解压缩后,可以使用pip
安装Px及其所有依赖项python -m pip install px-proxy --no-index -f /path/to/wheels
-
如果Python不可用,可以从发布页面获取最新编译的二进制文件。Windows的二进制文件使用Python嵌入式构建,而Linux和OSX的二进制文件使用Nuitka编译,并包含运行独立程序所需的一切。
如果可以访问互联网且已安装Python,可以使用Python包管理器pip
轻松安装Px。这将下载并安装Px作为Python模块及其所有依赖项
python -m pip install px-proxy
在Windows上,也可以使用scoop
安装Px
scoop install px
安装完成后,可以按以下方式运行Px
- 直接运行
px
- 后台运行:
pythonw -m px
- 在控制台窗口中前台运行:
python -m px
Px需要libcurl库,Windows构建版本附带库副本。在Linux上,需要使用包管理器安装libcurl
- RHEL:
yum install libcurl
- Ubuntu:
apt install libcurl4
- Alpine:
apk add libcurl
源安装
可以通过pip从源代码下载和安装最新版本的Px
python -m pip install https://github.com/genotrance/px/archive/master.zip
源代码也可以下载并安装
-
通过git
git clone https://github.com/genotrance/px
-
下载ZIP
https://github.com/genotrance/px/archive/master.zip
下载后,可以像安装标准Python模块一样安装Px及其所有依赖项
python -m pip install .
注意:源安装方法将需要互联网访问,因为Python将尝试从互联网上安装Px依赖项。上一节中提到的二进制文件可以用于启动源安装。
注意:如前所述,在Linux上需要使用包管理器安装libcurl。对于Windows,请下载并解压缩libcurl.dll
和libcurl-x64.dll
到$PATH
。
不安装
Px可以作为本地Python脚本运行而无需安装。按照上述说明下载源代码,安装所有依赖项,然后运行Px
pip install keyring netaddr psutil python-dotenv pyspnego quickjs
# Download/install libcurl
pythonw px.py # run in the background
python px.py # run in a console window
卸载
如果Px已安装到Windows注册表以在启动时运行,则在删除之前应先卸载
python -m px --uninstall
然后可以使用以下命令使用pip
卸载Px
python -m pip uninstall px-proxy
Docker
Px可以作为预构建的Docker 镜像使用。
有两个镜像可供选择 - 默认版本包括keyring及其相关依赖项,而精简版更小,但需要依赖于PX_PASSWORD
和PX_CLIENT_PASSWORD
来提供凭证。
以下Docker标志将有助于配置和运行Px
--name px name container so it is easy to stop it
-d run in the background
--rm remove container on exit
网络
--network host make Px directly accessible from host network
OR
-p 3128:3128 publish the port - Px needs to run in --gateway mode
配置
-e PX_LOG=4 set environment variables to configure Px
-v /dir:/px mount a host directory with a px.ini or .env file to configure Px
OR
--mount source=/dir,target=/px
mount a volume if preferred
docker run ... genotrance/px --gateway --verbose
configure directly from the command line
凭证
可以将凭证存储在主机文件夹中,并按如下方式挂载到容器中
-v /keyrings:/root/.local/share/keyrings
mount a local dir to store keyring info
OR
--mount source=/keyrings,target=/root/.local/share/keyrings
mount a volume if preferred
可以使用命令行保存凭证
docker run ... genotrance/px --username=... --password
configure keyring directly from the command line
精简版没有keyring,因此需要使用环境变量设置凭证
-e PX_PASSWORD=... -e PX_CLIENT_PASSWORD=...
set environment variables to configure credentials
配置
Px只需要一条信息才能运行 - 代理服务器的服务器名和端口号。如果未指定,Px将检查“Internet选项”或环境变量以查找任何代理定义。如果没有这些,Px将尝试直接连接到网站。
noproxy
功能允许 Px 直接连接到配置的主机,完全绕过代理。这允许客户端连接到内网中的主机,无需为每个客户端或代理进行额外配置。
配置可以通过多种方式指定,按优先级排序如下:
- 命令行标志
- 环境变量
- dotenv 文件(.env)中的变量
- 工作目录
- Px 目录
- 配置文件
px.ini
- 工作目录
- Px 目录
有许多配置选项可以进行微调 - 请参阅用法部分或使用 --help
查看详细信息。
凭证
如果 SSPI 不可用或不受欢迎,可以使用 domain\username
格式提供 --username
,允许 Px 以该用户身份进行身份验证。相应的密码将通过 Python keyring 获取,并需要在适当的操作系统特定后端中进行设置。
凭据可以通过命令行设置
px --username=domain\username --password
如果用户名已使用 PX_USERNAME
或在 px.ini
中定义
px --password
有关密钥环后端的信息可以在这里找到。
作为替代,Px 还可以从环境变量 PX_PASSWORD
或 dotenv 文件中加载凭据。这仅在密钥环不可用时推荐。
Windows
凭据管理器是 Windows 推荐的后端,密码以 'Generic Credential' 类型存储,网络地址名为 'Px'。凭据管理器可以通过以下方式访问:
Control Panel > User Accounts > Credential Manager > Windows Credentials
Or on the command line: `rundll32.exe keymgr.dll, KRShowKeyMgr`
Linux
Linux 上使用 Gnome Keyring 或 KWallet 存储密码。
对于没有 GUI(无头、docker)的系统,可以交互式地启动 D-Bus
dbus-run-session -- sh
如果需要在脚本中执行此操作
export DBUS_SESSION_BUS_ADDRESS=`dbus-daemon --fork --config-file=/usr/share/dbus-1/session.conf --print-address`
Gnome Keyring 可以按照以下方式解锁
echo 'somecredstorepass' | gnome-keyring-daemon --unlock
如果默认的 SecretService 密钥环后端不起作用,可能需要第三方 后端。只需安装和配置一个,然后 keyring
将使用它。请记住,在启动 Px 之前指定它们所需的任何环境变量。
这对于 Nuitka 二进制文件不起作用,因此作为后备,可以使用 PX_PASSWORD
来设置凭据。
客户端身份验证
Px 对于代表客户端与上游代理服务器进行身份验证非常有用,但它也可以在需要时对连接到它的客户端进行身份验证。这在 gateway
模式下非常有用,其中远程客户端在通过 Px 访问上游代理之前应进行登录。支持 BASIC
和 DIGEST
身份验证,以及 NTLM
和 NEGOTIATE
。
客户端凭据可以与上游代理凭据不同,也可以相同(如果需要)。Windows 上还支持 SSPI,可以用于客户端、上游或两者。
默认情况下关闭客户端身份验证,可以使用 --client-auth
、PX_CLIENT_AUTH
或 px.ini
启用。建议将值设置为 ANYSAFE
。
类似于上游代理,客户端用户名可以使用 --client-username
、PX_CLIENT_USERNAME
或 px.ini
进行配置。密码可以使用 PxClient
作为网络地址名在密钥环中进行设置。PX_CLIENT_PASSWORD
可用于密钥环不可用的情况。
Windows 上默认启用 SSPI,可以通过 --client-nosspi
、PX_CLIENT_NOSSPI
或在 px.ini
中禁用它。
可以使用命令行在密钥环中设置客户端凭据
px --client-username=domain\username --client-password
Px 只支持一个上游代理凭据,但可以使用密钥环配置以支持多个客户端用户。每个用户应使用 PxClient
网络地址添加到密钥环。
使用上游代理不是必需的,因此 Px 也可以用作小型设置的简单身份验证代理。
其他
配置文件px.ini
可以使用--save
命令行参数创建或更新。
Px的二进制版本启动后将在后台运行,可以通过运行px --quit
来退出。在前台运行时,请使用CTRL-C
。
Px也可以使用--install
标志在Windows启动时自动运行。这是通过在Windows注册表中添加条目来完成的,可以使用--uninstall
来删除。
注意:使用--install
传递的命令行参数不会保存以供启动时使用。需要使用--save
标志或手动编辑px.ini
来在启动时提供配置给Px。
注意:在Windows上使用Px的二进制版本时,请使用.\pythonw -m px --install
而不是使用px.exe
。这将避免启动时弹出控制台窗口。
用法
px [FLAGS]
python px.py [FLAGS]
python -m px [FLAGS]
Actions:
--save
Save configuration to file specified with --config or px.ini in working directory
Allows setting up Px config directly from command line
Values specified on CLI override any values in existing config file
Values not specified on CLI or config file are set to defaults
--install
Add Px to the Windows registry to run on startup
--uninstall
Remove Px from the Windows registry
--quit
Quit a running instance of Px
--restart
Quit a running instance of Px and start a new instance
--password | PX_PASSWORD
Collect and save password to default keyring. Username needs to be provided
via --username, PX_USERNAME or in the config file.
As an alternative, Px can also load credentials from the environment variable
`PX_PASSWORD` or a dotenv file.
--client-password | PX_CLIENT_PASSWORD
Collect and save password to default keyring. Username needs to be provided
via --client-username, PX_CLIENT_USERNAME or in the config file.
As an alternative, Px can also load credentials from the environment variable
`PX_CLIENT_PASSWORD` or a dotenv file.
--test=URL | --test
Test Px as configured with the URL specified. This can be used to confirm that
Px is configured correctly and is able to connect and authenticate with the
upstream proxy. If URL is skipped, Px runs multiple tests against httpbin.org.
Configuration:
--config= | PX_CONFIG=
Specify config file. Valid file path, default: px.ini in working directory
or script directory
--proxy= --server= | PX_SERVER= | proxy:server=
NTLM server(s) to connect through. IP:port, hostname:port
Multiple proxies can be specified comma separated. Px will iterate through
and use the one that works
--pac= | PX_PAC= | proxy:pac=
PAC file to use to connect
Use in place of --server if PAC file should be loaded from a URL or local
file. Relative paths will be relative to the Px script or binary
--pac_encoding= | PX_PAC_ENCODING= | proxy:pac_encoding=
PAC file encoding
Specify in case default 'utf-8' encoding does not work
--listen= | PX_LISTEN= | proxy:listen=
Network interface(s) to listen on. Comma separated, default: 127.0.0.1
--gateway and --hostonly override this to bind to all interfaces
--port= | PX_PORT= | proxy:port=
Port to run this proxy on - default: 3128
--gateway | PX_GATEWAY= | proxy:gateway=
Allow remote machines to use proxy. 0 or 1, default: 0
Overrides --listen and binds to all interfaces
--hostonly | PX_HOSTONLY= | proxy:hostonly=
Allow only local interfaces to use proxy. 0 or 1, default: 0
Px allows all IP addresses assigned to local interfaces to use the service.
This allows local apps as well as VM or container apps to use Px when in a
NAT config. Overrides --listen and binds to all interfaces, overrides the
default --allow rules
--allow= | PX_ALLOW= | proxy:allow=
Allow connection from specific subnets. Comma separated, default: *.*.*.*
Whitelist which IPs can use the proxy. --hostonly overrides any definitions
unless --gateway mode is also specified
127.0.0.1 - specific ip
192.168.0.* - wildcards
192.168.0.1-192.168.0.255 - ranges
192.168.0.1/24 - CIDR
--noproxy= | PX_NOPROXY= | proxy:noproxy=
Direct connect to specific subnets or domains like a regular proxy. Comma separated
Skip the NTLM proxy for connections to these hosts
127.0.0.1 - specific ip
192.168.0.* - wildcards
192.168.0.1-192.168.0.255 - ranges
192.168.0.1/24 - CIDR
example.com - domains
--useragent= | PX_USERAGENT= | proxy:useragent=
Override or send User-Agent header on client's behalf
--username= | PX_USERNAME= | proxy:username=
Authentication to use when SSPI is unavailable. Format is domain\username
Service name "Px" and this username are used to retrieve the password using
Python keyring if available.
--auth= | PX_AUTH= | proxy:auth=
Force instead of discovering upstream proxy type
By default, Px will attempt to discover the upstream proxy type. This
option can be used to force either NEGOTIATE, NTLM, DIGEST, BASIC or the
other libcurl supported upstream proxy types. See:
https://curl.se/libcurl/c/CURLOPT_HTTPAUTH.html
To control which methods are available during proxy detection:
Prefix NO to avoid method - e.g. NONTLM => ANY - NTLM
Prefix SAFENO to avoid method - e.g. SAFENONTLM => ANYSAFE - NTLM
Prefix ONLY to support only that method - e.g ONLYNTLM => ONLY + NTLM
Set to NONE to defer all authentication to the client. This allows multiple
instances of Px to be chained together to access an upstream proxy that is not
directly connected:
Client -> Auth Px -> no-Auth Px -> Upstream proxy
'Auth Px' cannot directly access upstream proxy but 'no-Auth Px' can
--client-username= | PX_CLIENT_USERNAME= | client:client_username=
Client authentication to use when SSPI is unavailable. Format is domain\username
Service name "PxClient" and this username are used to retrieve the password using
Python keyring if available.
--client-auth= | PX_CLIENT_AUTH= | client:client_auth=
Enable authentication for client connections. Comma separated, default: NONE
Mechanisms supported: NEGOTIATE, NTLM, DIGEST, BASIC
ANY = enable all supported mechanisms
ANYSAFE = enable all supported mechanisms except BASIC
NTLM = enable only NTLM, etc.
NONE = disable client authentication altogether (default)
--client-nosspi= | PX_CLIENT_NOSSPI= | client:client_nosspi=
Disable SSPI for client authentication on Windows. default: 0
Set to 1 to disable SSPI and use the configured username and password
--workers= | PX_WORKERS= | settings:workers=
Number of parallel workers (processes). Valid integer, default: 2
--threads= | PX_THREADS= | settings:threads=
Number of parallel threads per worker (process). Valid integer, default: 32
--idle= | PX_IDLE= | settings:idle=
Idle timeout in seconds for HTTP connect sessions. Valid integer, default: 30
--socktimeout= | PX_SOCKTIMEOUT= | settings:socktimeout=
Timeout in seconds for connections before giving up. Valid float, default: 20
--proxyreload= | PX_PROXYRELOAD= | settings:proxyreload=
Time interval in seconds before refreshing proxy info. Valid int, default: 60
Proxy info reloaded from manual proxy info defined in Internet Options
--foreground | PX_FOREGROUND= | settings:foreground=
Run in foreground when compiled or run with pythonw.exe. 0 or 1, default: 0
Px will attach to the console and write to it even though the prompt is
available for further commands. CTRL-C in the console will exit Px
--log= | PX_LOG= | settings:log=
Enable debug logging. default: 0
1 = Log to script dir [--debug]
2 = Log to working dir
3 = Log to working dir with unique filename [--uniqlog]
4 = Log to stdout [--verbose]. Implies --foreground
If Px crashes without logging, traceback is written to the working dir
示例
使用proxyserver.com:80
,仅允许从本地主机请求
px --proxy=proxyserver.com:80
完全不使用任何代理,仅记录发生的情况
px --noproxy=0.0.0.0/0 --debug
允许从localhost
和所有本地分配的IP地址请求。这对于Windows上的Docker和NAT配置中的虚拟机非常有用,因为所有请求都来自主机的IP
px --proxy=proxyserver.com:80 --hostonly
允许从localhost
、本地分配的IP地址以及主机外指定在允许列表中的IP请求
px --proxy=proxyserver:80 --hostonly --gateway --allow=172.*.*.*
允许从任何地方请求。请小心,每个客户端都会使用您的登录信息
px --proxy=proxyserver.com:80 --gateway
注意:在Docker for Windows中,您需要在容器中将代理设置为http://host.docker.internal:3128
或http://<your_ip>:3128
(或Px实际监听的端口),并注意https://github.com/docker/for-win/issues/1380。
解决方案
docker build --build-arg http_proxy=http://<your ip>:3128 --build-arg https_proxy=http://<your ip>:3128 -t containername ../dir/with/Dockerfile
注意:在WSL2中,您可以按以下方式在/etc/profile
中设置代理
export http_proxy="http://$(tail -1 /etc/resolv.conf | cut -d' ' -f2):3128"
export https_proxy="http://$(tail -1 /etc/resolv.conf | cut -d' ' -f2):3128"
注意:当在WebSockets上运行MQTT时,将空闲超时增加到120秒将有所帮助:--idle=120
。默认值为30,这会导致WebSocket连接断开,因为默认的MQTT保活周期为60秒。
依赖关系
Px没有GUI,完全在后台运行。它依赖于以下Python包
Px还依赖于libcurl来处理所有出站HTTP连接和代理认证。
限制
Windows的进程间多处理仅在Python 3.3+上工作,因为那时才添加了对进程间共享套接字的支持。在Python的较旧版本中,Px将运行多线程但仅在一个进程中。
目前未实现MacOSX的套接字共享,并且限制在单个进程中运行。
尽管它应该大多数情况下都能正常工作,但由于目前没有测试环境来验证功能,Px尚未在MacOSX上测试。欢迎提交PR以帮助修复任何问题。
构建
为了构建一个自给自足的可执行文件,该文件不依赖于Python和依赖模块的存在,提供了Nuitka和PyInstaller脚本。还有Windows上更受欢迎的Python嵌入式构建。有关详细信息,请查看python tools.py
。
反馈
Px肯定是一个正在进行中的项目,欢迎任何反馈或建议。它托管在GitHub上,采用MIT许可,因此问题和PR都备受赞赏。请加入我们的讨论板、Gitter或Matrix,一起讨论Px。
致谢
感谢所有贡献者提交的PR和所有问题提交者。
Px基于来自互联网各处的代码,并承认无数来源。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。