様々なプログラミングツールでNTLM認証のかかったProxyサーバーを突破してインターネットに接続するためのソフトウェアとして、Cntlm Authentication Proxyが有名です。
Cntlmはとても便利なのですが、WindowsのノートPCで使う上でいくつか不満もありました。
- Proxy環境外で動作しない(参考→Working with a sometimes proxy )。
- Proxy構成スクリプト(pac)を設定できない。
- 認証情報を設定ファイルに書かなければならない。
そこでPxという別のProxy Serverを試したところ上記の不満が解消されました。
日本語の記事が見つからなかったので紹介します。
とは言っても導入・設定はCntlmと比較しても簡単で、Cntlmを使っている方ならば簡潔にまとまったREADME.mdを読めば事足りてしまうと思います。
また欠点を先に書いておくと、Px経由でapt upgrade
等を実行した場合に失敗することがあり、Cntlmよりも動作が不安定なようです(issue)。
私も何度かapt update
を失敗したり、Dockerイメージのビルド中のファイルのダウンロードに失敗しビルド失敗になったりしました。
なので安定性を重視される方はCntlmを使い続けた方が良いと思うものの、両方インストールして起動する方を切り替えるのは簡単なので、一度試されてはいかがでしょうか。
なおLinuxやmacOSでも使えるCntlmとは異なり、PxはWindowsでしか動作しません(一から書き直されたPx2でマルチOS対応が進められているようです)。
他の選択肢として、LinuxとmacOSでもProxy環境外で動作しpacに対応したAlpacaというものも見つけました。macOSならHomebrewでインストールできるようです。こちらはCntlmとは違い、macOS以外では認証情報を保存する機能がなく、起動時にパスワードを入力しなければならない模様。
(2021/02/04追記)マルチOS対応かつWindowsではGUIでも設定できるというwinfoomも見つけました。Proxy環境外では動作しなくなってしまうようですが、その他の点はこちらでも満足できそうです。
(2022/05/22追記)pxの新バージョンはLinuxでも動作するようです(未確認)。
インストール方法
WindowsにPythonをインストールせずとも実行できる、バイナリファイルを使う方法は以下の通り。インストール自体の管理者権限は不要です。
ポートを空けるためのファイアウォールの設定が必要な場合は別途行ってください。
-
GitHubのReleaseページから最新の実行ファイルを含んだzip(
px-vX.X.X-windows.zip
)をダウンロード。 - 展開したディレクトリの名前を変更して
%USERPROFILE%/AppData/Local/Programs/px
などとして置く。 - PowerShellで上記ディレクトリを開き、
.\px.exe --install
を実行するとスタートアップにpx.exe
が登録される。
設定方法
pxの設定
- PowerShellで
px.exe
のあるディレクトリを開き、.\px.exe --save
を実行するとディレクトリ内に設定ファイルpx.ini
が生成される。 -
px.ini
を適宜編集する。 -
px.exe
をダブルクリックして起動(もしくはスタートアップで自動起動)。
例えばプロキシ設定にpacファイルを使っておりDocker Desktop含むWSL2等の仮想マシンを使いたい場合、以下のようにプロキシ構成スクリプトを指定するpac
と、ホスト上の仮想マシンからのアクセスを制御するhostonly
のみデフォルト値から変更してやれば大丈夫です。
このhostonly
の設定はとても便利で、Cntlmならばゲートウェイモードにして許可リストに仮想マシンのIPアドレスを入れ、禁止リストで仮想マシン以外を禁止リストに登録もしくはファイアウォールで仮想マシンからのアクセスのみ許可するということをしなければなりません。
Pxならhostonly = 1
にするだけで仮想マシンからのアクセスのみを許可してくれるので、IPアドレスを手動で入力する面倒な設定は不要です。
pac
にはWindowsのプロキシ設定に書かれている「スクリプトのアドレス」をそのまま入れると機能します。
[proxy]
server =
pac = http://proxy.pac
listen = 127.0.0.1
port = 3128
gateway = 0
hostonly = 1
allow = *.*.*.*
noproxy =
useragent =
username =
auth =
[settings]
workers = 2
threads = 5
idle = 30
socktimeout = 20.0
proxyreload = 60
foreground = 0
log = 0
Windowsの資格情報を使ってプロキシ認証を通ってくれるので、わざわざIDやパスワードを設定ファイルに書いておく必要はありません。
各所に行うプロキシ設定(おまけ)
以下の各所への設定はPx特有のものではなくCntlm等でも同じです。
Windows/WSL1
プロキシ設定をhttp://localhost:3128
にしてやればインターネットに接続できます。
$ curl -I https://curl.se -x http://localhost:3128
HTTP/1.1 200 Connection established
Server: SimpleHTTP/0.6 Python/3.7.3
Date: Wed, 03 Feb 2021 xx:xx:xx GMT
Proxy-Agent: SimpleHTTP/0.6 Python/3.7.3
以下略
Ubuntuの場合、~/.bashrc
とapt用の/etc/apt/apt.conf
にプロキシ設定を書いておけば大体事足りると思います。
Docker Desktop(WSL2バックエンドのLinuxコンテナ)
Docker Desktopのダッシュボードから設定(「Settings」→「Resources」→「PROXIES」)に入れる、docker pull
コマンド等で使われる設定(Dockerデーモンが使う設定)にはhttp://localhost:3128
を、
コンテナ内のプロキシ設定には、コンテナ内からホストのWindowsのポートを指定するためにhttp://host.docker.internal:3128
と書きます。1
後者の設定はホストの~/.docker/config.json
にだけ行っておけばコンテナ生成時に自動的にコンテナ内に大文字環境変数($HTTP_PROXY
など)と小文字環境変数($http_proxy
など)が同時に設定されるので、docker run
時にオプションで環境変数を設定する手間を省けます。
ダッシュボードと~/.docker/config.json
にプロキシ設定を行った状態で、DockerHubからイメージをpullできコンテナ内にプロキシ環境変数が設定されているかを下記のようにコンテナ内の環境変数を表示させ確認します。
> docker run --rm alpine env
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
4c0d98bf9879: Pull complete
Digest: sha256:08d6ca16c60fe7490c03d10dc339d9fd8ea67c6466dea8d558526b1330a85930
Status: Downloaded newer image for alpine:latest
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=xxxxxxxxxxxx
HTTP_PROXY=http://host.docker.internal:3128
http_proxy=http://host.docker.internal:3128
HTTPS_PROXY=http://host.docker.internal:3128
https_proxy=http://host.docker.internal:3128
HOME=/root
コンテナがインターネットに接続できることをcurl公式イメージで確認します。
> docker run --rm -it curlimages/curl curl -I https://curl.se
HTTP/1.1 200 Connection established
Server: SimpleHTTP/0.6 Python/3.7.3
Date: Wed, 03 Feb 2021 xx:xx:xx GMT
Proxy-Agent: SimpleHTTP/0.6 Python/3.7.3
以下略
WSL2
WSL2で動くLinux仮想マシンからWindows側のポートに接続するにはWindowsのIPアドレスを指定しなければならないのですが、デフォルトでは特別なホスト名が存在しないため名前解決できません(GitHubのissueには要望が沢山投稿されており、Microsoftでは解決に向けて動いているようです)。
ただしDocker Desktopをインストールした状態ならば、C:\Windows\System32\drivers\etc\hosts
にDocker Desktopがhost.docker.internal
のホスト名でWindowsの物理NICのIPアドレスを書き込み、これを元にWSL内で/etc/hosts
が自動生成されるため、WSL上からWindowsをhost.docker.internal
で名前解決できます。2
よってDockerコンテナ同様にhttp://host.docker.internal:3128
を指定してやります。
$ curl -I https://curl.se -x http://host.docker.internal:3128
HTTP/1.1 200 Connection established
Server: SimpleHTTP/0.6 Python/3.7.3
Date: Wed, 03 Feb 2021 xx:xx:xx GMT
Proxy-Agent: SimpleHTTP/0.6 Python/3.7.3
以下略
localhost
がhost.docker.internal
になった以外、WSL1の場合と同じです。
参考記事
- Cntlmを使ってNTLMv2認証Proxy環境をやっつける
- Docker Desktop for Windows の proxy 設定
- Configure Docker to use a corporate proxy
-
余談ですが
host.docker.internal
はDocker Desktopでしか機能しないため、LinuxでCntlmを使って同じようにDockerホストのポートにアクセスする設定をするにはホストの物理NICのIPを指定する(つまり固定IPにする必要がある)か、コンテナ作成時に--add-host=host.docker.internal:host-gateway
オプションを毎回付けてhost.docker.internal
をコンテナ内で名前解決できるようにしてやらなければなりません(GitHubのissue)。現状、OS混在環境でOS間の差異を吸収する必要があるならば、どのOSでも上記オプションを付けてコンテナ内のプロキシ設定は常にhttp://host.docker.internal:3128
にするのが一番良いと思われます。 ↩ -
WSL1/2上どころかWindows上からでも名前解決できるので
localhost
の代わりに使って全設定箇所host.docker.internal
にもできるのですが、IPアドレス不定なため信頼性はイマイチです。私の場合はVPN接続時にDocker Desktopを起動すると疎通不能な謎のIPが書き込まれたりしました。 ↩