CNTLM(1)
๐ธ CNTLM ๐ธ
ok so this is the manual for cntlm โ an authenticating HTTP(S) proxy with TCP/IP tunneling and acceleration. yes she does all that. sit down, bestie, we're doing a deep dive ๐
โจ NAME โจ
cntlm โ authenticating HTTP(S) proxy with TCP/IP tunneling and acceleration ๐ฆ
๐ SYNOPSIS ๐
cntlm [ -AaBcDdFfGgHhILlMNOPpqRrSsTUuvwXx ] [ host1 port1 | host1:port1
] ... hostN portN
๐ DESCRIPTION ๐
Cntlm is an NTLM / NTLM SR / NTLMv2 authenticating HTTP proxy. She parks herself right between your apps and the corporate proxy and adds NTLM authentication on-the-fly, like a lil translator but make it network security. You can list several "parent" proxies and Cntlm will just work her way down the list one after another until one of them actually works. Every authenticated connection gets cached and reused so she stays fast fast. All you do is point your apps' proxy settings at Cntlm, fill in cntlm.conf (cntlm.ini), and boom โ you're ready to go. On Windows this is nice-to-have, but on non-Microsoft OS's it is essential, no cap.
Proxy IP addresses can come from the CLI (host1:port1 through hostN:portN) or from the configuration file. Either one, your call.
Another whole vibe: Cntlm can authenticate your local web connections with zero parent proxies. She works stand-alone, just like Squid or ISA. By default all requests get forwarded to the parent proxies, but you can set a "NoProxy" list โ a list of URL-matching wild-card patterns โ that routes things between direct mode and forward mode. Cntlm can also clock when all your corporate proxies are down and flip to stand-alone mode automatically (and then flip back). Iconic behavior honestly. ๐
On top of WWW and PROXY authentication, Cntlm has a feature that lets you migrate your laptop between work and home without ever touching the proxy settings in your apps (you just use cntlm the whole time, periodt). She also integrates transparent TCP/IP port forwarding (tunneling). Each tunnel opens a new listening socket on the local machine and forwards all connections to the target host behind the parent proxy. And if SSH-like tunnels aren't your thing, you can pick a limited SOCKS5 interface instead. Options on options. ๐
Core cntlm function used to be similar to the late NTLMAPS, but bestie, today she's evolved way beyond anything else of this type can offer. The feature list below speaks for itself, fr fr. Cntlm has a whole pile of security/privacy features โ NTLMv2 support, password protection โ and yes you can swap in password hashes (grab them with -H) instead of the actual password, or enter the password interactively (on start-up or via "basic" HTTP auth translation). And if you do use a plaintext password? It gets automatically hashed during startup and every trace of it is wiped from process memory. clean. ๐ง
Besides using barely any system resources, cntlm gets higher throughput on a given link. By caching authenticated connections she acts as an HTTP accelerator โ the 5-way auth handshake for each connection is transparently eliminated, so most of the time you get immediate access. Cntlm never caches a request/reply body in memory; in fact no traffic is generated except the exchange of auth headers until the client <-> server connection is fully negotiated. Only then does the real data transfer happen. She's written in optimized C and easily hits fifteen times faster responses than the others. ate. ๐ฅ
An example of cntlm vs NTLMAPS: cntlm gave avg 76 kB/s with peak CPU usage of 0.3%, whereas with NTLMAPS it was avg 48 kB/s with peak CPU at 98% (Pentium M 1.8 GHz). That extreme difference in resource usage is one of many important benefits for laptop use. Peak memory consumption (several complex sites, 50 parallel connections/threads; values are in KiB):
VSZ RSS CMD
3204 1436 ./cntlm -f -c ./cntlm.conf -P pid
411604 6264 /usr/share/ntlmaps/main.py -c /etc/ntlmaps/server.cfg
An inherent part of the development is profiling and memory management screening using Valgrind. The source distribution contains a file called valgrind.txt, where you can see the report confirming zero leaks, no access to unallocated memory, no usage of uninitialized data โ all traced down to each instruction emulated in Valgrind's virtual CPU during a typical production lifetime of the proxy. she is thorough. ๐
๐ OPTIONS ๐
Most options can be pre-set in a configuration file. Specifying an option more than once is not an error, but cntlm ignores all occurrences except the last one. (This does not apply to options like -L, where each one creates a new instance of some feature โ those stack, bestie.) Cntlm can be built with a hardcoded configuration file (e.g. /etc/cntlm.conf), which is always loaded, if possible. See the -c option for how to override some or all of its settings.
Use -h to see the available options with a short description. ๐ซถ
-A IP/mask(Allow) โ Allow ACL rule. Together with-D(Deny), these are the two rules allowed in ACL policy. It's more usual to have this in a configuration file, but Cntlm follows the premise that you can do the same on the command-line as you can using the config file. When Cntlm receives a connection request, she decides whether to allow or deny it. All ACL rules are stored in a list in the same order as specified. Cntlm then walks the list and the first IP/mask rule that matches the request source address is applied. The mask can be any number from0to32, where32is the default (that's an exact IP match). This notation is also known as CIDR. If you want to match everything, use0/0or an asterix. ACLs on the command-line take precedence over those in the config file. In such a case you'll see info about that in the log (among the list of unused options). There you can also see warnings about a possibly incorrect subnet spec โ that's when the IP part has more bits than you declare by mask (e.g.10.20.30.40/24should be10.20.30.0/24).-a NTLMv2 | NTLM2SR | NT | NTLM | LM | GSS(Auth) โ Authentication type. NTLM(v2) is made up of one or two hashed responses,NTandLMorNTLM2SRorNTv2andLMv2, which are computed from the password hash. Each response uses a different hashing algorithm; as new response types got invented, stronger algorithms came with them. When you first install cntlm, find the strongest one that works for you (preferably using-M). Above they're listed from strongest to weakest. Very old servers or dedicated HW proxies might not be able to process anything butLM. If none of those work, see the compatibility flags option-For submit a Support Request.
IMPORTANT: Although NTLMv2 is not widely adopted (i.e. enforced), it is supported on all Windows since NT 4.0 SP4. That's a very long time! I strongly suggest you use it to protect your credentials on-line. You should also replace plaintextPasswordoptions with hashedPass[NTLMv2|NT|LM]equivalents. NTLMv2 is the most and possibly the only secure authentication of the NTLM family.
GSS: the GSS option activates the kerberos authentication. You need a cached credential (see kinit doc): per default the cache file is in /tmp/krb5cc_<uid>, and you can override this using the environment variable KRB5CCNAME. In example KRB5CCNAME=FILE:/tmp/my_krb5cc_for_LDS.IT. If GSS is specified, at each connection it sends the auth token without asking the proxy if auth is needed. If GSS credentials are not available it will fallback to the NTLM discovery procedure. If no Auth type is specified and there is a GSS cached credential available and the server asks for a
-B(NTLMToBasic) โ This option enables "NTLM-to-basic", which allows you to use one cntlm for multiple users. Please note that all security of NTLM is lost this way. Basic auth uses just a simple encoding algorithm to "hide" your credentials, and it's moderately easy to sniff them. ๐
IMPORTANT: HTTP protocol obviously has means to negotiate authorization before letting you through, but TCP/IP doesn't (i.e. open port is open port). If you use NTLM-to-basic and DON'T specify some username/password in the configuration file, you are bound to lose tunneling features, because cntlm alone won't know your credentials.
Because NTLM identification has at least three parts (username, password, domain) and basic authentication provides fields for only two (username, password), you have to smuggle the domain part somewhere. You can set the Domain config/cmd-line parameter, which will then be used for all users who don't specify their domain as a part of the username. To do that and override the global domain setting, use this instead of a plain username in the password dialog: "domain\username".
-c <filename>โ Configuration file. Command-line options, if used, override its single options, or are added at the top of the list for multi options (tunnels, parent proxies, etc) โ with the exception of ACLs, which are completely overridden. Use/dev/nullto disable any config file.-D IP/mask(Deny) โ Deny ACL rule. See option-Aabove.-d <domain>(Domain) โ The domain or workgroup of the proxy account. This value can also be specified as a part of the username with-u.-F <flags>(Flags) โ NTLM authentication flags. This option is rather delicate and I do not recommend changing the default built-in values unless you had no success with parent proxy auth and tried magic autodetection (-M) and all possible values for the Auth option (-a). Remember that each NT/LM hash combination requires different flags. This option is sort of a complete "manual override" and you'll have to deal with it yourself. ๐ญ-fโ Run in console as a foreground job, do not fork into background. In this mode, all syslog messages will be echoed to the console (on platforms which support the syslogLOG_PERRORoption). Though cntlm is primarily designed as a classic UNIX daemon with syslogd logging, it provides a detailed verbose mode without detaching from the controlling terminal; see-v. In any case, all error and diagnostic messages are always sent to the system logger.-G <pattern>(ISAScannerAgent) โ User-Agent matching (case insensitive) for the trans-isa-scan plugin (see-Sfor explanation). A positive match identifies requests (applications) for which the plugin should be enabled without considering the size of the download (see-S). You can use shell wildcard characters, namely"*","?"and"[]". If used without-SorISAScannerSize, themax_size_in_kbis internally set to infinity, so the plugin will be active ONLY for selected User-Agents, regardless of download size.-gโ Gateway mode ๐ so in this mode cntlm listens on all network interfaces. Default vibe is to bind just loopback, which means only local processes can connect to cntlm. But in gateway mode? cntlm listens on all the interfaces and is accessible to other machines on the network. Heads up tho: with this option the command-line order matters when specifying proxy or tunnel local (listening) ports. Those positioned before it will bind only loopback; those after will be public.
IMPORTANT: all of the above applies only to local ports for which you didn't specify any source address. If you did, cntlm tries to bind the given port only on the specified interface (or rather IP address). ๐ซถ
-Hโ use this one to get hashes for password-less configuration. In this mode, cntlm prints the results and exits, so you can just copy & paste right into the config file. You ought to use this option with explicit-uand-d, because some hashes include the username and domain name in the calculation. And do see-afor security recommendations, bestie. ๐-hโ display help (available options with a short description) and exit. The classic "what do I even do here" button. โจ-Iโ Interactive password prompt. Any password settings from the command line or config file is ignored and a password prompt is issued instead. Use this option only from shell, ok? ๐-L [<saddr>:]<lport>:<rhost>:<rport>โ (Tunnel) ๐ tunnel definition. The syntax is the same as in OpenSSH's local forwarding (-L), with a new optional prefix,saddrโ the source IP address to bind thelportto. Cntlm will listen for incoming connections on the local portlport, forwarding every new connection through the parent proxy to therhost:rport(authenticating on the go โจ). This option can be used multiple times for unlimited number of tunnels, with or without thesaddroption. See-gfor the details concerning local port binding whensaddris not used.
Please note that many corporate proxies do not allow connections to ports other than 443 (https), but if you run your target service on this port, you should be safe. Connect to HTTPS is "always" allowed, otherwise nobody would be able to browse https:// sites. In any case, first try if you can establish a connection through the tunnel, before you rely on it. This feature does the same job as tools like corkscrew(1), but instead of communicating over a terminal, cntlm keeps it TCP/IP. no cap ๐ง
-l [<saddr>:]<lport>โ (Listen) ๐ง local port for the cntlm proxy service. Use the number you have chosen here and the hostname of the machine running cntlm (possiblylocalhost) as proxy settings in your browser and/or the environment. Most applications (including console) support the notion of proxy to connect to other hosts. On POSIX, set the following variables to use e.g.wget(1)without any trouble (fill in the actual address of cntlm):
$ export ftp_proxy=http://localhost:3128
$ export http_proxy=$ftp_proxy
$ export https_proxy=$ftp_proxy
You can choose to run the proxy service on more than one port, in such case just use this option as many times as necessary. But unlike tunnel definition, cntlm fails to start if it cannot bind all of the proxy service ports. ๐ซ Proxy service port can also be bound selectively. Use saddr to pick source IP address to bind the lport to. This allows you, for example, to run the service on different ports for subnet A and B and make it invisible for subnet C. See -g for the details concerning local port binding when saddr is not used.
-M <testurl>โ run magic NTLM dialect detection. ๐ฎ In this mode, cntlm tries some known working presets against your proxy. Probe requests are made for the specifiedtesturl, with the strongest hashes going first. When finished, settings for the most secure setup are printed. Although the detection will tell you which and how to useAuth,Flagsand password-hash options, you have to configure at least your credentials and proxy address first. You can use-Ito enter your password interactively. it's giving wizardry fr fr โจ-N <pattern1>[,<patternN]โ (NoProxy) avoid parent proxy for these host names. All matching URL's will be proxied directly by cntlm as a stand-alone proxy. Cntlm supports WWW authentication in this mode, thus allowing you to access local intranet sites with corporate NTLM authentication. Hopefully, you won't need that virtualized MSIE any more. :) ๐ฆ-O [<saddr>:]<port_number>โ (SOCKS5Proxy) enable SOCKS5 proxy and make it listen on local portport_number(source IP spec is also possible, as with all options). By default, there will be no restrictions as to who can use this service. Some clients don't even support SOCKS5 authentication (e.g. almost all browsers). If you wish to enforce authentication, use-Ror its equivalent option,SOCKS5User. As with port tunneling, it is up to the parent proxy whether it will allow connection to any requestedhost:port. This feature can be used withtsocks(1)to make most TCP/IP applications go thru the proxy rather than directly (only outgoing connections will work, obviously). To make apps work without DNS server, it is important that they don't resolve themselves, but using SOCKS. E.g. Firefox has this option available through URI "about:config", key namenetwork.proxy.socks_remote_dns, which must be set totrue. Proxy-unaware tsocksified apps, will have to be configured using IP addresses to prevent them from DNS resolving. ๐ง โจ-P <pidfile>โ create a PID filepidfileupon startup. If the specified file exists, it is truncated and overwritten. This option is intended for use withstart-stop-daemon(8)and other servicing mechanisms. Please note that the PID file is created AFTER the process drops its privileges and forks. When the daemon finishes cleanly, the file is removed. ๐งน-p <password>โ (Password, PassNT, ...) proxy account password. Cntlm deletes the password from the memory, to make it invisible in/procor with inspection tools likeps(1), but the preferable way of setting password is the configuration file. To that end, you can usePasswordoption (for plaintext, human readable format), or "encrypt" your password via-Hand then usePassNTLMv2,PassNTand/orPassLM. ๐-qโ sets the Syslog logging level toDEBUG(default level isINFO). more yapping in the logs, slay ๐ฃ๏ธ-R <username>:<password>โ (SOCKS5User) if SOCKS5 proxy is enabled, this option can make it accessible only to those who have been authorized. It can be used several times, to create a whole list of accounts (alloweduser:passcombinations). ๐-r "<name>: <value>"โ (Header) header substitution. Every client's request will be processed and any headers defined using-ror in the configuration file will be added to it. In case the header is already present, its value will be replaced. ๐-S <max_size_in_kb>โ (ISAScannerSize) enables the plugin for transparent handling of the dreaded ISA AV scanner, which returns an interactive HTTP page (displaying the scanning progress) instead of the file/data you've requested, every time it feels like scanning the contents. This presumptuous behavior breaks every automated downloader, updater and basically EVERY application relying on downloads (e.g.wget,apt-get). ๐
The parameter max_size_in_kb allows you to choose maximum download size you wish to handle by the plugin (see below why you might want that). If the file size is bigger than this, cntlm forwards you the interactive page, effectively disabling the plugin for that download. Zero means no limit. Use -G/ISAScannerAgent to identify applications for which max_size_in_kb should be ignored (forcing the plugin). It works by matching User-Agent header and is necessary for e.g. wget, apt-get and yum, which would fail if the response is some HTTP page instead of requested data. ๐ญ
How it works: the client asks for a file, cntlm detects ISA's bullshit response and waits for the secret link to ISA's cache, which comes no sooner than the file is downloaded and scanned by ISA. Only then can cntlm make the second request for the real file and forward it along with correct headers to the client. The client doesn't timeout while waiting for it, b/c cntlm is periodically sending an extra "keepalive" header, but the user might get nervous not seeing the progress bar move. It's of course purely psychological matter, there's no difference if cntlm or your browser requests the scanned file โ you must wait for ISA to do it's job and download then. You just expect to see some progress indicator move, which is all what the ISA's page does: it shows HTML countdown. โณ
If the plugin cannot parse the interactive page for some reason (unknown formatting, etc.), it quits and the page is forwarded to you โ it's never "lost". ๐ซถ
The keepalive header is called ISA-Scanner and shows ISA's progress, e.g.:
HTTP/1.1 200 OK
ISA-Scanner: 1000 of 10000
ISA-Scanner: 2000 of 10000
...
-sโ serializes all requests by not using concurrent threads for proxy (tunneling still works in parallel). This has a horrible impact on performance and is available only for debugging purposes. When used with-v, it yields nice sequential debug log, where requests take turns. ๐ not the moment for main character energy-T <filename>โ used in combination with-vto save the debug output into a trace file. It should be placed as the first parameter on the command line. To prevent data loss, it never overwrites an existing file. You have to pick a unique name or manually delete the old file. ๐-U <uid>โ the root-then-drop-it move ๐ when you run as root, cntlm does all the stuff that actually needs those permissions first (reading config, binding ports, etc.) and then immediately drops privileges and switches touid. This param can be either a number or a system username. Give it a number and both the uid and gid of the process get set to that value; give it a username and uid + gid get set from that user's uid and primary gid as defined in/etc/passwd. Bestie, use the username form โ ideally a dedicatedcntlmaccount. And like with literally any daemon, you are strongly advised to run cntlm under a non-privileged account. No cap.-u <user>[@<domain>]โ (Username) who even are you, auth-wise proxy account/user name. Domain can be entered here too, if you want.-vโ print debugging information. Automatically enables (-f), so heads up, it's a package deal.-w <workstation>โ (Workstation) NetBIOS name of your workstation. Do NOT use a fully qualified domain name (FQDN) here โ just the first part, okay? If you don't specify it, cntlm tries to grab the system hostname and if that fails, it uses"cntlm"โ this whole thing exists because some proxies are dramatic and require the field to be non-empty. ๐-x <PAC_file>โ (Pac) specify a PAC file to load. load it up โจ-X <sspi_handle_type>โ (SSPI) use SSPI with the specified handle type. Works only under Windows. Default isnegotiate(NTLM).
๐ CONFIGURATION ๐
Okay so the config file is basically an INI file, except there's no = between keys and values. It's just whitespace-delimited keyword + value pairs. That's the vibe. Apart from that there are sections too, and those use the usual [section_name] syntax.
A comment begins with a hash # or a semicolon ; and can be anywhere in the file โ everything after that mark up until EOL is a comment. Values can contain any characters, including whitespace. You can wrap the value in double quotes to set a string containing special characters like spaces, pound signs, etc. No escape sequences are allowed in quoted strings โ so don't try it, it's not that girl.
There are two types of keywords: local and global. Local options specify authentication details per domain (or location). Global keywords apply to all sections and proxies. They should be placed before all sections, but it's not necessary. They are: Allow, Deny, Gateway, Listen, SOCKS5Proxy, SOCKS5User, NTLMToBasic, Tunnel.
All available keywords are listed here, full descriptions are in the OPTIONS section:
Allow <IP>[/<mask>]โ ACL allow rule, see-A. let them in ๐Auth NTLMv2 | NTLM2SR | NT | NTLM | LM | GSSโ select any possible combination of NTLM hashes using a single parameter. TheGSSoption activates the kerberos authentication, see-a. โจ pick your fighter โจDeny <IP>[/<mask>]โ ACL deny rule, see-A. not today ๐ซDomain <domain_name>โ proxy account domain/workgroup name.Flags <flags>โ NTLM authentication flags. See-Ffor details.Gateway yes|noโ gateway mode. In the configuration file, order doesn't matter. Gateway mode applies the same to all tunnels.Header <headername: value>โ header substitution. See-rfor details and remember, no quoting.ISAScannerAgent <pattern>โ wildcard-enabled (*,?,[]) case insensitive User-Agent string matching for the trans-isa-plugin. If you don't defineISAScannerSize, it is internally set to infinity, i.e. disabling the plugin for all downloads except those agent-matched ones. See-G.ISAScannerSize <max_size_in_kb>โ enable trans-isa-scan plugin. See-Sfor more.Listen [<saddr>:]<port_number>โ local port number for the cntlm's proxy service. See-lfor more. it's giving listening ๐Password <password>โ proxy account password. As with any other option, the value (password) can be enclosed in double quotes (") in case it contains special characters like spaces, pound signs, etc.PassNTLMv2,PassNT,PassLM<password>โ hashes of the proxy account password (see-Hand-a). When you want to use hashes in the config (instead of plaintext password), eachAuthsetting requires different options:Auth NTLMv2โ requiresPassNTLMv2Auth NTLM2SRโ requiresPassNTAuth NTโ requiresPassNTAuth NTLMโ requiresPassNT+PassLMAuth LMโ requiresPassLM
Proxy <host:port>โ parent proxy, which requires authentication. The same as proxy on the command-line, can be used more than once to specify an arbitrary number of proxies. Should one proxy fail, cntlm automatically moves on to the next one. resilient queen ๐ The connect request fails only if the whole list of proxies is scanned and (for each request) and found to be invalid. Command-line takes precedence over the configuration file.NoProxy <pattern1>, <pattern2>, ...โ avoid parent proxy for these host names. All matching URL's will be proxied directly by cntlm as a stand-alone proxy. Cntlm supports WWW authentication in this mode, thus allowing you to access local intranet sites with corporate NTLM authentication. Hopefully, you won't need that virtualized MSIE any more. :) See-Nfor more.Pac </path/to/proxy.pac>โ specify a PAC file to load.SOCKS5Proxy [<saddr>:]<lport>โ enable SOCKS5 proxy. See-Ofor more.SOCKS5User <username>:<password>โ create a new SOCKS5 proxy account. See-Rfor more.NTLMToBasic yes|noโ enable/disable NTLM-to-basic authentication. See-Bfor more.Tunnel [<saddr>:]<lport>:<rhost>:<rport>โ tunnel definition. See-Lfor more.Usernameโ proxy account name, without the possibility to include domain name ('at' sign is interpreted literally). not me forgetting the domain ๐Workstation <hostname>โ the hostname of your workstation.SSPI NTLMโ enable SSPI for Windows clients. Only NTLM is supported for now.
๐ FILES ๐
The optional location of the configuration file is defined in the Makefile, with the default for 1) deb/rpm package, 2) traditional make; make install and 3) Windows installer, respectively, being:
/etc/cntlm.conf/usr/local/etc/cntlm.conf%PROGRAMFILES%\Cntlm\cntlm.ini
๐ PORTING ๐
Cntlm is being used on many platforms, little and big endian machines, so users should not have any problems with compilation. it's versatile, she contains multitudes ๐ Nowadays, cntlm is a standard tool in most Linux distributions and there are various repositories for other UNIX-like systems. Personally, I release Debian Linux (deb), RedHat Linux (rpm) and Windows (exe) binaries, but most people get cntlm from their OS distributor.
For compilation details, see README in the source distribution. Porting to any POSIX conforming OS shouldn't be more than a matter of a Makefile rearrangement. Cntlm uses strictly POSIX.1-2001 interfaces with ISO C99 libc and is also compliant with SUSv3. Since version 0.33, cntlm supports Windows using a POSIX emulation layer called Cygwin.
๐ BUGS ๐
To report a bug, enable the debug output, save it to a file and submit on-line along with a detailed description of the problem and how to reproduce it. Visit the home page for more.
cntlm -T cntlmtrace.log -v -s ... the rest ...
bestie if it's broken, log it and tell us everything ๐
๐ AUTHOR ๐
Written by David Kubicek <dave (o) awk.cz> Homepage: http://cntlm.sourceforge.net/
ยฉ๏ธ COPYRIGHT ยฉ๏ธ
Copyright ยฉ 2007-2010 David Kubicek Cntlm uses DES, MD4, MD5 and HMAC-MD5 routines from gnulib and Base64 routines from mutt(1).
okay that's the whole page, you made it to the end!! ๐ this was cntlm 0.93, dated Apr 2012, and it lives in the CNTLM(1) section of your man pages. go forth and proxy, bestie ๐โจ๐ฆ
๐ฆ where this page comes from
- ubuntu resolute: cntlm 0.94.0+dfsg-1 ยท GPL-2.0-or-later
- ubuntu stonking: cntlm 0.94.0+dfsg-2 ยท GPL-2.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms