When setting up an internal Debian/Ubuntu repository with HTTPS, self-signed certificates create verification hurdles. Unlike browsers or curl which offer temporary bypass options, APT requires explicit configuration to establish trust.
The key configuration elements in /etc/apt/apt.conf.d/99selfsigned
should be:
// Trust the CA chain
Acquire::https::repo.example.com::CaInfo "/etc/ssl/certs/ca-certificates.crt";
// When using client certificates:
Acquire::https::repo.example.com::SslCert "/etc/apt/client.pem";
Acquire::https::repo.example.com::SslKey "/etc/apt/client.key";
// Debugging (remove in production)
Debug::Acquire::https "true";
For system-wide trust of your CA:
# Debian/Ubuntu
sudo cp my-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
# RHEL/CentOS
sudo cp my-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
Before APT testing, validate with openssl:
openssl s_client -connect repo.example.com:443 \
-CAfile /etc/ssl/certs/ca-certificates.crt \
-cert /etc/apt/client.pem \
-key /etc/apt/client.key
Common failure patterns and solutions:
1. "Certificate verification failed"
→ Ensure your CA cert is in /etc/ssl/certs
→ Verify update-ca-certificates ran successfully
2. "SSL handshake failed"
→ Check TLS version compatibility
→ Verify private key permissions (600)
→ Test with curl --cacert for comparison
For environments where modifying system certificates isn't feasible:
# Per-repository override
echo "deb [trusted=yes] https://repo.example.com/ubuntu focal main" \
> /etc/apt/sources.list.d/internal.list
Note: This completely disables verification - use only in trusted networks.
When using self-signed certs:
- Implement certificate pinning
- Monitor for unexpected certificate changes
- Consider short-lived certificates with automation
When setting up an internal APT repository with HTTPS using self-signed certificates, you'll encounter certificate validation issues. While disabling verification (Verify-Peer "false") works, it defeats the purpose of HTTPS. Here's the proper way to configure APT to trust your self-signed certificate.
First, ensure your certificate chain is properly set up. Your CA certificate file should contain both the root CA and any intermediate certificates:
-----BEGIN CERTIFICATE----- (Your root CA certificate) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (Any intermediate certificates) -----END CERTIFICATE-----
The correct approach involves these steps:
- Place your CA certificate in
/usr/local/share/ca-certificates/
- Run
update-ca-certificates
- Configure your
sources.list
with the HTTPS repository
Sample /etc/apt/sources.list.d/internal-repo.list
:
deb https://repo.mydomain.com/ubuntu focal main
For better debugging, use this configuration in /etc/apt/apt.conf.d/99debug
:
Debug::Acquire::https "true"; Debug::pkgAcquire "true";
Then check logs with:
sudo apt-get update -o Debug::Acquire::https=true 2>&1 | grep https
If you can't modify system certificates, pin the specific certificate:
Acquire::https::repo.mydomain.com::CaInfo "/etc/apt/certs/my-cacert.pem"; Acquire::https::repo.mydomain.com::SslCert "/etc/apt/certs/client-cert.pem"; Acquire::https::repo.mydomain.com::SslKey "/etc/apt/certs/client-key.pem";
Test your configuration with:
sudo apt-get update curl --cacert /etc/apt/certs/my-cacert.pem \ --cert /etc/apt/certs/client-cert.pem \ --key /etc/apt/certs/client-key.pem \ https://repo.mydomain.com/ubuntu/dists/focal/InRelease
Remember to restart any services that might cache certificates, and ensure file permissions are correct (certificates should be readable by root only).