跳转到主要内容

一个自动通过NTLM代理进行认证的HTTP代理服务器

项目描述

Chat on Gitter Chat on Matrix

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.dlllibcurl-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_PASSWORDPX_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 访问上游代理之前应进行登录。支持 BASICDIGEST 身份验证,以及 NTLMNEGOTIATE

客户端凭据可以与上游代理凭据不同,也可以相同(如果需要)。Windows 上还支持 SSPI,可以用于客户端、上游或两者。

默认情况下关闭客户端身份验证,可以使用 --client-authPX_CLIENT_AUTHpx.ini 启用。建议将值设置为 ANYSAFE

类似于上游代理,客户端用户名可以使用 --client-usernamePX_CLIENT_USERNAMEpx.ini 进行配置。密码可以使用 PxClient 作为网络地址名在密钥环中进行设置。PX_CLIENT_PASSWORD 可用于密钥环不可用的情况。

Windows 上默认启用 SSPI,可以通过 --client-nosspiPX_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:3128http://<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都备受赞赏。请加入我们的讨论板GitterMatrix,一起讨论Px。

致谢

感谢所有贡献者提交的PR和所有问题提交者。

Px基于来自互联网各处的代码,并承认无数来源。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源代码分发

此版本没有提供源代码分发文件。请参阅生成分发存档的教程

构建分发

px_proxy-0.9.2-py3-none-win_amd64.whl (1.6 MB 查看哈希)

上传时间 Python 3 Windows x86-64

px_proxy-0.9.2-py3-none-win32.whl (1.5 MB 查看哈希)

上传时间 Python 3 Windows x86

px_proxy-0.9.2-py3-none-any.whl (127.7 kB 查看哈希)

上传时间 Python 3

由以下组织支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面