1. Introduction

Proxy servers provide a shield when establishing network connections. However, to use that shield, we might need a username and password combination, i.e., authentication. Failing to properly configure and register this pair with all proxy clients can result in connectivity issues and errors.

In this tutorial, we explore setting up an authenticated proxy connection for package updates via APT. First, we briefly refresh our knowledge about proxies. After that, we explain how and why a package manager communicates with the outside world. Next, we delve into the proxy setup of APT and potential issues in case of misconfiguration. Finally, we go over a specific proxy context and its settings.

We tested the code in this tutorial on Debian 12 (Bookworm) with GNU Bash 5.2.15. It should work in most POSIX-compliant environments unless otherwise specified.

2. Proxies

With the advancement of network security, there are many reasons to use a proxy server for access to the Internet or even a wide area network (WAN) and local area network (LAN). A proxy is a system that acts as an intermediary filter for communication to and from our machine.

Such a setup has multiple benefits:

  • avoid direct connection to insecure third-party servers
  • prevent inbound connections
  • enable obfuscation and complex traffic engineering

However, there are also downsides to using a proxy:

  • host and maintain or rent a proxy server
  • properly secure and protect any credentials and data
  • configure proxy server
  • configure the operating system (OS) or each network application

Because of these hurdles, some systems only use proxy servers for some connections.

One of the most critical activities that we need functional at all times, even behind a proxy, is package management.

3. Package Manager Communication

To install and update packages, a package manager requires repository sources. Although there are many types of repositories, the default sources for many Linux distributions use remote HTTP(S) servers. This is usually the best way to keep a system as up-to-date as possible.

For example, let’s see the default Debian repositories:

$ cat /etc/apt/sources.list
#deb cdrom:[Official Debian GNU/Linux Live 2023-06-26T06:56:00Z]/ bookworm main non-free-firmware

deb http://deb.debian.org/debian stable main
deb-src http://deb.debian.org/debian stable main

deb http://deb.debian.org/debian-security/ stable-security main
deb-src http://deb.debian.org/debian-security/ stable-security main

deb http://deb.debian.org/debian stable-updates main
deb-src http://deb.debian.org/debian stable-updates main

Although there can also be a CD-ROM repository as we see above, the main ones use the http://deb.debian.org official Debian URL with the respective suffix.

So, we expect a package manager like APT to contact the Internet during updates, upgrades, package downloads, and package installation procedures such as dependency resolution.

Because of this, proper proxy configuration becomes critical for apt when it’s necessary for Internet connectivity.

4. Package Manager Proxy

Let’s demonstrate the result of having a machine behind a proxy and not configuring APT to use that proxy:

$ apt-get update
Ign:1 http://deb.debian.org/debian stable InRelease
Ign:1 http://deb.debian.org/debian stable InRelease
Ign:1 http://deb.debian.org/debian stable InRelease
Err:1 http://deb.debian.org/debian stable InRelease
  Temporary failure resolving 'deb.debian.org'
Reading package lists... Done
W: Failed to fetch http://deb.debian.org/debian/dists/stable/InRelease  Temporary failure resolving 'deb.debian.org'
W: Some index files failed to download. They have been ignored, or old ones used instead.

Since there’s practically no Internet access without going through the proxy, we already fail at the name resolution step. Even if our repository URL included an IP address instead, we wouldn’t be able to connect to it.

To resolve this, we can configure a proxy server in a new file under the /etc/apt/apt.conf.d/ directory:

$ cat /etc/apt/apt.conf.d/88proxy
Acquire::http::Proxy "http://<USERNAME>:<PASSWORD>@<PROXY_HOSTNAME>:<PROXY_PORT>/";
Acquire::https::Proxy "https://<USERNAME>:<PASSWORD>@<PROXY_HOSTNAME>:<PROXY_PORT>/";
Acquire::ftp::Proxy "ftp://<USERNAME>:<PASSWORD>@<PROXY_HOSTNAME>:<PROXY_PORT>/";

After replacing the appropriate fields with the respective values, we should have a properly configured proxy server for our APT activities through each supported network protocol:

$ cat /etc/apt/apt.conf.d/88proxy
Acquire::http::Proxy "";
Acquire::https::Proxy "";
Acquire::ftp::Proxy "";

However, we might still encounter issues when running apt:

$ apt-get update
Err:1 http://deb.debian.org/debian stable InRelease
  407  Proxy Authentication Required [IP: 666]

In this case, the new problem comes down to the proxy server requiring authentication, which we haven’t provided.

Often, this can be resolved by configuring the correct username and password pair according to the syntax we saw earlier:

$ cat /etc/apt/apt.conf.d/88proxy
Acquire::http::Proxy "http://user:[email protected]:666/";
Acquire::https::Proxy "https://user:[email protected]:666/";
Acquire::ftp::Proxy "ftp://user:[email protected]:666/";

Notably, if our credentials contain special characters, we can use percent encoding to insert them without invalidating the syntax.

5. Enterprise NTLM Authentication

In some cases, basic proxy configuration might not be sufficient.

For example, NewTechnology LAN Manager (NTLM) authentication requires extra packages for support:

$ apt-get install cntlm

Paradoxically, we might need APT to work before configuring it with the cntlm package. So, we can install cntlm from source by cloning its Git repository:

$ git clone https://github.com/Evengard/cntlm.git
$ cd cntlm
$ ./configure && make && make install

In any case, we can then configure the respective settings in /etc/cntlm.conf:

$ cat /etc/cntlm.conf
# Cntlm Authentication Proxy Configuration
# NOTE: all values are parsed literally, do NOT escape spaces,
# do not quote. Use 0600 perms if you use plaintext password.

Username	x
Domain		baeldung.com


# Specify the netbios hostname cntlm will send to the parent
# proxies. Normally the value is auto-guessed.
Workstation	xost

# List of parent proxies to use. More proxies can be defined
# one per line in format <proxy_ip>:<proxy_port>

# List addresses you do not want to pass to parent proxies
# * and ? wildcards can be used
NoProxy		localhost, 127.0.0.*, 10.*, 192.168.*

# Specify the port cntlm will listen on
# You can bind cntlm to specific interface by specifying
# the appropriate IP address also in format <local_ip>:<local_port>
# Cntlm listens on by default
Listen		3128

Finally, we restart the cntlm service via systemctl or directly with /etc/init.d/cntlm restart:

$ systemctl restart cntlm # /etc/init.d/cntlm restart

At this point, we can employ localhost:3128 as our APT proxy. Notably, it’s not recommended to use clear-text passwords directly within the configuration file.

6. Summary

In this article, we talked about proxy authentication for APT, as well as a special case when connecting our package manager to the Internet.

In conclusion, although we might have to go through several extra steps, APT proxy configuration is a good way to keep a system up-to-date even when avoiding direct Internet access.