Many developers working behind corporate firewalls face the challenge of accessing both internal and external APT repositories. While companies often mirror main Debian/Ubuntu repositories internally, there are legitimate cases where we need to access external repos (like PPAs or third-party sources) through proxy servers.
The standard approach of setting a global proxy in /etc/apt/apt.conf.d/
files causes issues because:
# Problematic when some repos are internal
Acquire::http::Proxy "http://proxy.example.com:3128";
This configuration fails when trying to access internal repositories that don't require proxy authentication.
Debian's APT system actually supports per-repository proxy settings through the apt.conf.d
mechanism. Here's how to implement it:
# /etc/apt/apt.conf.d/99proxy
Acquire::http::Proxy::archive.ubuntu.com "http://proxy.example.com:3128";
Acquire::https::Proxy::security.ubuntu.com "http://proxy.example.com:3128";
Acquire::http::Proxy::ppa.launchpad.net "http://proxy.example.com:3128";
# No proxy for internal repos
Acquire::http::Proxy::internal.repo.example.com "DIRECT";
For Debian systems (version 1.1+), you can specify proxy settings directly in your sources.list
:
# Internal repo - direct access
deb http://internal.repo.example.com/debian bullseye main
# External repo - via proxy
deb [proxy=http://proxy.example.com:3128] http://archive.ubuntu.com/ubuntu focal main
When troubleshooting, these commands are invaluable:
# Check which repositories are being accessed
sudo apt-get update -o Debug::Acquire::http=yes
# Verify proxy settings
sudo apt-config dump | grep -i proxy
For authenticated proxies, use this syntax:
Acquire::http::Proxy::external.repo.example.com "http://username:password@proxy.example.com:3128";
- Place proxy configurations in
/etc/apt/apt.conf.d/99proxy
rather than main apt.conf - Use hostnames rather than IP addresses for better maintainability
- Test configurations with
apt-get update
before full package operations
Working behind corporate firewalls often presents unique challenges for package management. Many organizations mirror Debian/Ubuntu repositories internally while restricting direct internet access through proxy servers. This creates a situation where:
- Internal repositories should be accessed directly
- External repositories require proxy configuration
- Global proxy settings break internal access
APT reads configurations from multiple locations with this precedence order:
1. Command line options
2. /etc/apt/apt.conf.d/* (alphabetical order)
3. /etc/apt/apt.conf
4. /etc/apt/preferences.d/*
5. Environment variables
The solution lies in APT's Acquire::http::Proxy::
directive. Here's how to implement it:
// Create or modify /etc/apt/apt.conf.d/99proxy
Acquire {
http {
Proxy "http://internal-proxy.example.com:3128";
Proxy::deb.debian.org "DIRECT";
Proxy::security.debian.org "DIRECT";
};
https {
Proxy "http://internal-proxy.example.com:3128";
Proxy::deb.debian.org "DIRECT";
Proxy::security.debian.org "DIRECT";
};
}
Consider this scenario with mixed internal/external sources.list:
# /etc/apt/sources.list
deb http://internal-mirror.example.com/debian bullseye main
deb http://deb.debian.org/debian bullseye-updates main
deb http://security.debian.org bullseye-security main
The corresponding proxy configuration would be:
// /etc/apt/apt.conf.d/10proxy
Acquire {
http {
Proxy "http://corp-proxy:8080";
Proxy::internal-mirror.example.com "DIRECT";
};
https {
Proxy "http://corp-proxy:8080";
};
}
For more complex setups, you can use:
// Multiple proxy support with failover
Acquire::http::Proxy {
"deb.debian.org" "http://proxy1:3128";
"security.debian.org" "http://proxy2:3128";
default "DIRECT";
};
// Authentication requirements
Acquire::http::Proxy-Auto-Detect "/usr/local/bin/apt-proxy-detect";
Acquire::http::Proxy::external.repo.example.com "http://user:pass@proxy:port";
Test your configuration with:
apt-get update -o Debug::Acquire::http=1
# Check which proxy is being used for each repository
apt-config dump Acquire::http::Proxy
Common issues to watch for:
- Proxy directives are case-sensitive
- Hostnames must match exactly what's in sources.list
- HTTP and HTTPS proxies need separate configurations