pip
proxy
CNTLM
Python
networking

Using pip behind a proxy with CNTLM

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In corporate networks, pip often cannot reach package indexes directly because outbound traffic must pass through an authenticated proxy. CNTLM solves that by running a small local proxy that speaks NTLM to the corporate proxy, letting tools like pip talk to localhost instead of handling enterprise authentication themselves.

How the Setup Works

The flow is usually:

text
pip -> CNTLM on localhost -> corporate NTLM proxy -> internet

pip only needs a normal HTTP or HTTPS proxy URL. CNTLM handles the hard part of authenticating with the upstream enterprise proxy.

Step 1: Configure CNTLM

A minimal cntlm.conf or cntlm.ini usually contains:

ini
1Username    your_user
2Domain      YOURDOMAIN
3Proxy       proxy.company.com:8080
4Listen      3128

Instead of storing a plain-text password, CNTLM can generate password hashes:

bash
cntlm -H -d YOURDOMAIN -u your_user

That command prompts for the password and prints hash values you can place in the config file.

After configuration, start CNTLM and make sure it listens on the chosen local port, often 3128.

Step 2: Point pip at CNTLM

The quickest test is to pass the proxy on the command line:

bash
pip install requests --proxy http://127.0.0.1:3128

If that works, the CNTLM side is healthy and the remaining job is making the proxy setting persistent.

Step 3: Persist the Proxy Setting

You can configure pip with environment variables:

bash
export HTTP_PROXY=http://127.0.0.1:3128
export HTTPS_PROXY=http://127.0.0.1:3128

Or put the setting in pip configuration:

ini
[global]
proxy = http://127.0.0.1:3128

You can inspect your current pip configuration with:

bash
pip config list

This is often cleaner than passing --proxy on every install command.

Example End-to-End Check

Once CNTLM is running, verify the connection in small steps.

First, check that CNTLM is reachable locally:

bash
curl -I -x http://127.0.0.1:3128 https://pypi.org/simple/

Then try pip:

bash
pip install --proxy http://127.0.0.1:3128 urllib3

If curl fails, the issue is probably CNTLM or the corporate proxy. If curl works but pip fails, inspect pip configuration, certificates, or Python environment differences.

HTTPS, Certificates, and Corporate Inspection

Some corporate proxies intercept TLS traffic and re-sign certificates. In those environments, pip may fail with certificate errors even after the proxy is correct.

Typical fixes include:

  • install the corporate root certificate into the system trust store
  • point pip to a certificate bundle with cert = /path/to/cert.pem
  • avoid using trusted-host as a casual shortcut unless policy and risk are understood

Proxy problems and certificate problems often appear together, but they are different layers.

A Useful pip Config Example

If your team uses an internal mirror plus CNTLM, a more complete config might look like:

ini
1[global]
2proxy = http://127.0.0.1:3128
3index-url = https://pypi.org/simple
4timeout = 60

You can set these values with commands as well:

bash
pip config set global.proxy http://127.0.0.1:3128
pip config set global.timeout 60

Troubleshooting Sequence

When the setup does not work, debug in this order:

  1. confirm CNTLM is running
  2. confirm CNTLM can authenticate to the upstream proxy
  3. test the local proxy with curl
  4. test pip --proxy ...
  5. inspect certificate and pip config issues

This order matters because many developers change pip settings repeatedly when the real problem is that CNTLM never connected upstream.

Common Pitfalls

  • Pointing pip directly at the corporate NTLM proxy instead of the local CNTLM listener.
  • Forgetting to start the CNTLM service before running installs.
  • Mixing shell environment variables with pip config and then not knowing which proxy is actually in effect.
  • Treating TLS certificate failures as proxy failures.
  • Leaving a stale proxy setting in pip config after moving to a different network.

Summary

  • CNTLM acts as a local NTLM-aware proxy that pip can use like a normal proxy.
  • Configure CNTLM first, then point pip at http://127.0.0.1:3128 or your chosen local port.
  • Use --proxy for quick testing and pip config or environment variables for persistent setup.
  • If installs still fail, separate proxy connectivity issues from certificate issues.
  • Debug from CNTLM outward rather than guessing inside pip.

Course illustration
Course illustration

All Rights Reserved.