Home Linux AdministrationConfigure System-Wide Proxy Settings on Ubuntu 26.04 LTS [Complete Guide]

Configure System-Wide Proxy Settings on Ubuntu 26.04 LTS [Complete Guide]

By sk
13 views 30 mins read

You've just installed Ubuntu. You set http_proxy in your terminal, curl google.com works, but sudo apt update fails. Welcome to Linux proxy configuration.

Ubuntu (and Linux in general) does not have a single, system-wide proxy setting that all applications respect. Unlike Windows or macOS, where you can set a proxy in system preferences and most apps will use it, Ubuntu relies on a fragmented approach with no central proxy switch.

Each tool either:

  1. Ignores environment variables entirely, or
  2. Uses them only under specific conditions, or
  3. Requires its own separate configuration.

Setting up a proxy on Ubuntu genuinely means configuring multiple tools independently.

In this detailed guide, we'll cover apt, curl, wget, git, pip, npm, Docker, Snap, and systemd with working configuration examples.

You'll learn about different proxy types and exactly where to configure each tool, so you can finally set it once and have everything work.


Tested on: Ubuntu 26.04 LTS (Resolute Raccoon)
Level: Beginner to Advanced
Reading time: ~30 minutes


Table of Contents

Why Proxy Configuration on Ubuntu Linux Is Tricky

Here is something that surprises most new Ubuntu users: there is no single proxy setting that works everywhere.

Unlike Windows, Ubuntu does not have one central proxy switch. Instead, each tool, such as apt, curl, wget, git, pip, npm, Docker, Snap, your browser, and your terminal, manages its own proxy config independently. So when you set a proxy in GNOME Settings, your terminal ignores it completely. When you set an environment variable, APT ignores it entirely. On top of that, sudo strips your environment variables before running commands, and systemd services never see them at all.

This disconnect frustrates a lot of people because they set the proxy in one place and then wonder why it still does not work somewhere else.

In this comprehensive article, we will explain exactly where to set your proxy for every major tool on Ubuntu, and why each one behaves the way it does.

Let's start from the beginning.

Understanding Proxy Types

Before you configure anything, you need to know what kind of proxy you are working with. Different proxy types behave differently, and choosing the wrong type can cause connection failures.

Datacenter Proxies

Datacenter proxies come from servers hosted in data centers. They are fast and cheap, but websites can often detect and block them because their IP addresses do not look like real home internet connections.

Because of this, they work best for high-volume, low-risk tasks (like scraping public datasets, monitoring your own infrastructure, or load testing) where speed matters more than going undetected.

Residential Proxies

Residential proxies use IP addresses that real internet service providers (ISPs) assign to real home devices. Because of this, websites treat traffic from residential proxies like traffic from a regular user.

This makes them very useful for web scraping, geo-testing, and tasks where datacenter IPs get blocked.

HTTP vs HTTPS Proxies

An HTTP proxy handles standard web traffic. An HTTPS proxy adds encryption to the connection between your device and the proxy server, which means your credentials and request metadata stay protected from anyone watching your local network. Most modern proxy setups use HTTPS, so always check what protocol your provider supports.

For a deeper technical explanation of how HTTP and HTTPS proxies work at the protocol level, including how the CONNECT method creates tunnels and what PAC files do, MDN Web Docs covers it thoroughly.

SOCKS5 Proxies

SOCKS5 proxies work at a lower level than HTTP/HTTPS proxies. Unlike HTTP proxies that only handle web traffic, SOCKS5 routes all network traffic, including UDP, FTP, and non-HTTP protocols, which makes it the more flexible and privacy-friendly choice. Many tools on Ubuntu support SOCKS5 natively, including curl, ssh, and most torrent clients.

Now that you understand the types, let's get into the actual configuration.

Method 1: Environment Variables

Environment variables are the closest thing Ubuntu has to a universal proxy setting. Many command-line tools check these variables automatically, so setting them is always the best place to start.

The Key Variables

Ubuntu recognizes these standard proxy environment variables:

http_proxy      # Proxy for HTTP traffic
https_proxy # Proxy for HTTPS traffic
ftp_proxy # Proxy for FTP traffic
no_proxy # Comma-separated list of hosts to bypass
ALL_PROXY # Fallback proxy for tools that ignore the others

Always use lowercase variable names. The uppercase versions (HTTP_PROXY, HTTPS_PROXY) have a known security vulnerability in CGI environments called httpoxy (VU#797896).

An attacker can send a crafted HTTP Proxy: request header that a CGI web server promotes to the HTTP_PROXY environment variable, which then redirects your application's outbound traffic to the attacker's server.

Lowercase variables are not affected by this attack because the CGI specification (RFC 3875) only promotes HTTP request headers to uppercase environment variables. So while both cases work in most situations, lowercase is the safer standard and the one you should always use.

Also note the ALL_PROXY variable, many tools including curl, git, and various Python libraries fall back to ALL_PROXY when they cannot find a protocol-specific variable. Including it makes your configuration more robust with very little extra effort.

Set Variables for Your Current Session Only

If you want to test your proxy quickly without making permanent changes, run these commands in your terminal:

export http_proxy="http://proxyhost:port"
export https_proxy="http://proxyhost:port"
export ftp_proxy="http://proxyhost:port"
export ALL_PROXY="http://proxyhost:port"
export no_proxy="localhost,127.0.0.1,::1"

Replace proxyhost with your proxy server's actual IP address or hostname and port with the port number. These settings disappear as soon as you close the terminal window, so they are perfect for quick tests.

Make Variables Permanent for Your User Account

To keep the proxy settings every time you open a terminal, add the export lines to your ~/.bashrc file:

nano ~/.bashrc

Scroll to the bottom and add:

# Proxy settings
export http_proxy="http://proxyhost:port"
export https_proxy="http://proxyhost:port"
export ftp_proxy="http://proxyhost:port"
export ALL_PROXY="http://proxyhost:port"
export no_proxy="localhost,127.0.0.1,::1"

Save with Ctrl+O, press Enter, then exit with Ctrl+X. Reload immediately:

source ~/.bashrc

Make Variables System-Wide for All Users

If you need every user on the machine to use the same proxy, you have two good options.

Option 1: /etc/environment

This is the simplest approach. It is a static key-value file that PAM reads at login and applies to every user and every session:

sudo nano /etc/environment

Add these lines at the bottom. Note that /etc/environment does not use the export keyword, and it does not support variable expansion. You cannot reference $HOME or other variables inside it:

http_proxy="http://proxyhost:port"
https_proxy="http://proxyhost:port"
ftp_proxy="http://proxyhost:port"
ALL_PROXY="http://proxyhost:port"
no_proxy="localhost,127.0.0.1,::1"

Save and reboot for changes to apply to all users.

Option 2: /etc/profile.d/proxy.sh

This is the better choice when you need dynamic logic - for example, if your proxy address depends on an environment variable, a hostname lookup, or a condition. Unlike /etc/environment, shell scripts in /etc/profile.d/ support full bash syntax:

sudo nano /etc/profile.d/proxy.sh

Add:

#!/bin/bash
# System-wide proxy settings

PROXY_HOST="proxyhost"
PROXY_PORT="port"

export http_proxy="http://${PROXY_HOST}:${PROXY_PORT}"
export https_proxy="http://${PROXY_HOST}:${PROXY_PORT}"
export ftp_proxy="http://${PROXY_HOST}:${PROXY_PORT}"
export ALL_PROXY="http://${PROXY_HOST}:${PROXY_PORT}"
export no_proxy="localhost,127.0.0.1,::1"

Make it executable:

sudo chmod +x /etc/profile.d/proxy.sh

This script runs for every interactive login shell on the system. It is the preferred approach for admins managing multi-user servers.

Important note: Even though environment variables work for many CLI tools, apt, sudo, systemd services, and Snap packages all ignore them. Each of those needs its own dedicated config, which the sections below cover in detail.

Method 2: APT Proxy Configuration

APT has its own proxy system. It does not read your environment variables at all. Therefore, even if you set http_proxy correctly, APT will still bypass the proxy unless you configure it directly.

The Right Way to Configure APT Proxy

Create a dedicated proxy config file for APT:

sudo nano /etc/apt/apt.conf.d/proxy.conf

This file does not exist by default, so you are creating a new one. Add these lines:

Acquire::http::Proxy "http://proxyhost:port";
Acquire::https::Proxy "http://proxyhost:port";
Acquire::ftp::Proxy "ftp://proxyhost:port";

Save the file and exit. From this point forward, every apt command will automatically route through your proxy. You do not need to restart anything.

Test That APT Uses the Proxy

Run a simple update to confirm the proxy is working:

sudo apt update

If APT connects and downloads package lists without errors, your proxy configuration is correct.

Disable APT Proxy for Specific Hosts

Sometimes you want APT to bypass the proxy for certain internal servers:

Acquire::http::Proxy {
"internal.server.local" DIRECT;
};

This tells APT to connect directly to internal.server.local while still routing everything else through the proxy.

Remove the APT Proxy

To stop APT from using the proxy, delete the config file:

sudo rm /etc/apt/apt.conf.d/proxy.conf

Method 3: curl

curl is one of the most widely used command-line tools on Ubuntu. Configuring it to use a proxy is straightforward, but understanding how it finds config files saves a lot of debugging time.

Use a Proxy for a Single curl Command

Add the -x flag:

curl -x http://proxyhost:port https://example.com

Make the Proxy Permanent for Your User

Save your proxy settings in curl's user configuration file:

nano ~/.curlrc

Add:

proxy = http://proxyhost:port

From now on, every curl command you run will automatically use this proxy. curl looks for this file in $CURL_HOME/.curlrc, then $XDG_CONFIG_HOME/.curlrc, then ~/.curlrc.

Make curl Use the Proxy System-Wide

curl does not have a standard system-wide config file path on Linux. The most reliable way to make curl use a proxy for all users on the system is to set the environment variables in /etc/profile.d/proxy.sh (covered in Method 1). curl reads http_proxy and https_proxy automatically at the lowest precedence level, so system-wide environment variables are the correct approach here.

If you need to override the proxy for a specific user or script, you can point curl at any config file with the -K flag:

curl -K /path/to/curlconfig https://example.com

Override the Proxy for a Single Command

curl --noproxy "*" https://internal.server.local

SSL Certificate Considerations

If your organization uses an intercepting proxy that inspects HTTPS traffic, curl will throw SSL certificate errors. Never use -k (insecure mode) in production. It disables all certificate verification. Instead, install your organization's root CA certificate into Ubuntu's trust store. It will be covered in the Corporate CA Certificates section in detail.

Method 4: wget

wget has its own configuration file and does not inherit APT's proxy settings.

Use a Proxy for a Single wget Command

wget -e use_proxy=yes -e http_proxy=http://proxyhost:port https://example.com

Make the Proxy Permanent for Your User

nano ~/.wgetrc

Add:

http_proxy = http://proxyhost:port
https_proxy = http://proxyhost:port
ftp_proxy = ftp://proxyhost:port
use_proxy = on

Make the Proxy System-Wide for All Users

sudo nano /etc/wgetrc

Find the proxy-related lines (they are commented out by default). Remove the # from each and fill in your proxy details:

http_proxy = http://proxyhost:port
https_proxy = http://proxyhost:port
ftp_proxy = ftp://proxyhost:port
use_proxy = on

Bypass the Proxy for Specific Domains

Add a no_proxy line to ~/.wgetrc:

no_proxy = localhost,127.0.0.1,.internal.company.com

Method 5: GNOME Desktop Settings

Ubuntu 26.04 ships with GNOME 50 as its default desktop environment. GNOME includes a built-in proxy panel that is easy to use, but it comes with a critical limitation.

How to Access GNOME Proxy Settings

  1. Open Settings from the app menu or the top-right system tray
  2. Click Network in the left sidebar
  3. Scroll down to Proxy and click the gear icon
GNOME Proxy Settings in Ubuntu 26.04 LTS
GNOME Proxy Settings in Ubuntu 26.04 LTS

In the next window, toggle the switch "Network proxy" to ON position. And then, choose "Manual" from the Configuration section.

Set proxy addresses for HTTP, HTTPS, FTP, and SOCKS individually.

Configure Proxy Settings on Ubuntu 26.04 via GNOME Settings
Configure Proxy Settings on Ubuntu 26.04 via GNOME Settings

The Critical Limitation of GNOME Proxy Settings

GNOME proxy settings only apply to GNOME applications. Your browser, Files app, and other GUI apps will respect these settings. But your terminal, apt, curl, wget, git, and all other command-line tools completely ignore them.

This is a very common source of confusion. Many people set the proxy in GNOME Settings, open a terminal, and then find that curl still connects directly. The solution is to always combine GNOME Settings with environment variables for full coverage.

When GNOME Settings Are Enough

If you only need proxy support for your web browser and desktop apps, GNOME Settings alone is sufficient. Otherwise, use it alongside the methods in this guide.

Method 6: Git

Almost every developer and admin uses Git. Git uses libcurl internally to handle all network connections (both HTTP and HTTPS) which means it has its own proxy configuration separate from system environment variables.

Set a Global Git Proxy

Git's http.proxy configuration key covers both HTTP and HTTPS connections. You only need to set one key:

git config --global http.proxy http://proxyhost:port

Verify the setting was saved:

git config --global --list | grep proxy

Set a Proxy for a Single Repository

If you only need the proxy for one specific repo, run this inside that repository's directory:

git config http.proxy http://proxyhost:port

Bypass the Proxy for Internal Git Servers

If you have an internal GitLab or Gitea server that should connect directly, tell Git to skip the proxy for that specific URL:

git config --global http.https://gitlab.internal.company.com.proxy ""

Remove the Git Proxy

git config --global --unset http.proxy

Where Git Stores These Settings

Git writes proxy settings to ~/.gitconfig. You can also edit this file directly:

nano ~/.gitconfig

It will look like this:

[http]
proxy = http://proxyhost:port

Note: Git's http.proxy covers both HTTP and HTTPS repository URLs because Git uses libcurl internally for all transport. You do not need (and should not set) a separate https.proxy key, as it is not a documented git configuration option.

Method 7: pip (Python)

Python's package manager pip has its own proxy configuration. While pip does read http_proxy and https_proxy environment variables, a permanent pip.conf file is more reliable and works regardless of how the shell environment is set up.

Set a Proxy for a Single pip Command

pip install requests --proxy http://proxyhost:port

Make the Proxy Permanent for Your User

Create the pip config directory and file:

mkdir -p ~/.config/pip
nano ~/.config/pip/pip.conf

Add:

[global]
proxy = http://proxyhost:port

Make the Proxy System-Wide for All Users

pip checks /etc/pip.conf for global settings on Linux:

sudo nano /etc/pip.conf

Add the same content:

[global]
proxy = http://proxyhost:port

pip Inside a Virtual Environment

If you use Python virtual environments, the proxy from your global or user pip.conf still applies. However, if you need a different proxy per project, create a pip.conf inside the virtual environment:

nano /path/to/venv/pip.conf

Add the same [global] block with the project-specific proxy.

Method 8: npm (Node.js)

npm stores its proxy configuration separately from system environment variables. You set it with the npm config command, which writes to ~/.npmrc.

Set the npm Proxy

npm config set proxy http://proxyhost:port
npm config set https-proxy http://proxyhost:port

Verify the npm Proxy Settings

npm config get proxy
npm config get https-proxy

Remove the npm Proxy

npm config delete proxy
npm config delete https-proxy

System-Wide npm Proxy

To apply the proxy to all users on the machine, edit the global npmrc file:

sudo npm config set proxy http://proxyhost:port --global
sudo npm config set https-proxy http://proxyhost:port --global

SSL Certificate Issues with npm

If npm throws SSL errors behind an intercepting proxy, point npm to Ubuntu's system CA bundle after installing your corporate certificate (see the CA Certificates section for details):

npm config set cafile /etc/ssl/certs/ca-certificates.crt

Method 9: Docker

Docker needs proxy configuration in two separate places, and confusing them is one of the most common mistakes. One config controls the Docker daemon itself (for pulling images). The other controls Docker client operations including builds.

Part 1: Proxy for the Docker Daemon (Pulling Images)

The Docker daemon runs as a systemd service, so it needs a systemd drop-in file. The official Docker documentation recommends creating a specifically named file:

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

Add:

[Service]
Environment="HTTP_PROXY=http://proxyhost:port"
Environment="HTTPS_PROXY=http://proxyhost:port"
Environment="NO_PROXY=localhost,127.0.0.1,.internal.company.com"

Alternatively, sudo systemctl edit docker creates the same directory structure with a file named override.conf. Both approaches work identically because systemd reads all .conf files in the directory.

Save and exit, then reload and restart Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

Confirm the environment variables are live:

sudo systemctl show --property=Environment docker

Part 2: Proxy for the Docker Client (Builds, Pulls, and More)

The Docker client proxy configuration in ~/.docker/config.json controls how proxy settings are passed during Docker CLI operations — including docker build, docker pull, and containers that need proxy access at runtime. Configure it here:

nano ~/.docker/config.json

Add or merge this block:

{
"proxies": {
"default": {
"httpProxy": "http://proxyhost:port",
"httpsProxy": "http://proxyhost:port",
"noProxy": "localhost,127.0.0.1,.internal.company.com"
}
}
}

Docker automatically passes these values as build arguments to every docker build command. You do not need to add --build-arg manually.

Note: The proxy settings in ~/.docker/config.json apply to Docker CLI client operations. They are injected as build-time ARGs during docker build, and they set environment variables for operations that respect them. However, they do not automatically set environment variables inside long-running containers started with docker run. Those containers need their own explicit -e flags or their own application-level proxy configuration.

Method 10: Snap Packages

Ubuntu 26.04 ships many applications as Snap packages. Snap completely ignores system environment variables, /etc/environment, and everything else covered so far. It has its own proxy system managed through snapd.

Set the Snap Proxy

sudo snap set system proxy.http="http://proxyhost:port"
sudo snap set system proxy.https="http://proxyhost:port"

Verify the Snap Proxy

sudo snap get system proxy

You should see output like:

Key           Value
proxy.http http://proxyhost:port
proxy.https http://proxyhost:port

Remove the Snap Proxy

sudo snap unset system proxy.http
sudo snap unset system proxy.https

Restart snapd After Changes

After setting the proxy, restart the snapd service for the changes to take effect immediately:

sudo systemctl restart snapd

Method 11: Systemd Services

Any application running as a systemd service (a web server, a scraper daemon, a scheduled task) will not inherit proxy settings from /etc/environment, ~/.bashrc, or any user-level config.

Systemd services run in their own isolated environment. This surprises many admins the first time they encounter it.

The correct approach is a systemd drop-in override file, which keeps your changes separate from the original unit file so that package updates do not overwrite them.

Create a Drop-In Override for Any Service

Replace servicename with the actual name of the service (for example, nginx, myapp, or scraper):

sudo systemctl edit servicename

This creates an override file at /etc/systemd/system/servicename.service.d/override.conf. Add:

[Service]
Environment="http_proxy=http://proxyhost:port"
Environment="https_proxy=http://proxyhost:port"
Environment="no_proxy=localhost,127.0.0.1,.internal.company.com"

Save and exit, then reload systemd and restart the service:

sudo systemctl daemon-reload
sudo systemctl restart servicename

Verify the Service Has the Right Environment

sudo systemctl show servicename --property=Environment

Apply Proxy to All Services at Once

If you want every systemd service on the machine to use the same proxy, create a global environment file that systemd reads:

sudo nano /etc/systemd/system.conf

Find the [Manager] section and add or uncomment:

DefaultEnvironment="http_proxy=http://proxyhost:port" "https_proxy=http://proxyhost:port"

Then reload systemd:

sudo systemctl daemon-reload

Use this approach carefully. It applies the proxy to every single service on the machine, which is rarely what you want.

Handling Proxy Authentication

Many proxy servers, especially residential and corporate proxies, require a username and password. Adding credentials to your proxy URL is simple, but there are a few edge cases to handle carefully.

Basic Authentication Format

http://username:password@proxyhost:port

For example:

export http_proxy="http://john:mypassword@proxy.example.com:8080"

For temporary use in scripts without storing credentials permanently:

read -sp "Proxy password: " PROXY_PASS
export http_proxy="http://username:${PROXY_PASS}@proxyhost:port"
unset PROXY_PASS # Clear after use

Special Characters in Passwords

If your password contains special characters like @, :, /, or #, you must URL-encode them. Otherwise the proxy URL breaks because those characters have special meaning inside a URL.

CharacterURL-Encoded
@%40
:%3A
/%2F
#%23
!%21
$%24
(space)%20

For example, if your password is p@ss:word, write it as p%40ss%3Aword in the proxy URL.

Protect Your Credentials

Storing a password in plaintext inside .bashrc or /etc/environment is a security risk. Here are two better approaches:

Option 1: Restrict file permissions

Create a separate file that holds only your proxy credentials:

nano ~/.proxy_credentials

Add:

export http_proxy="http://username:password@proxyhost:port"
export https_proxy="http://username:password@proxyhost:port"
export ALL_PROXY="http://username:password@proxyhost:port"

Lock the file down so only your user can read it:

chmod 600 ~/.proxy_credentials

Then source it from your .bashrc:

source ~/.proxy_credentials

Option 2: Use a secrets manager

For production servers, consider tools like pass (the standard Unix password manager) or HashiCorp Vault to store and inject proxy credentials at runtime. This approach keeps credentials out of config files entirely and is the right choice for any server with multiple users or automated deployments.

Installing Corporate CA Certificates

In corporate and enterprise environments, proxy servers often use TLS inspection. They intercept your HTTPS connections and re-sign them with their own root certificate. Every CLI tool will throw SSL errors until you install that root certificate into Ubuntu's system trust store.

This is the proper, permanent fix. Never use -k in curl or --no-check-certificate in wget as a workaround. Those flags disable all certificate verification and expose you to man-in-the-middle attacks from any source, not just your proxy.

Step 1: Get the Corporate CA Certificate

Ask your IT or network team for the root CA certificate file. It will typically be in .crt or .pem format. If you cannot get the file directly, you can export it from a browser that already trusts the proxy.

Step 2: Copy the Certificate to the Right Location

sudo cp your-corporate-ca.crt /usr/local/share/ca-certificates/

The file must have a .crt extension. If your certificate is in .pem format, rename it first:

sudo cp your-corporate-ca.pem /usr/local/share/ca-certificates/your-corporate-ca.crt

Step 3: Rebuild the System CA Bundle

sudo update-ca-certificates

You should see output confirming the certificate was added:

Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.

After this, curl, wget, apt, git, pip, npm, and most other tools will automatically trust your corporate proxy's certificate. You do not need to configure each tool individually.

Step 4: Verify the Certificate Is Trusted

Test with a simple curl request through your proxy:

curl -x http://proxyhost:port https://example.com

If you no longer see SSL errors, the certificate installation worked correctly.

Java and Python SSL Stores

Note that Java and some Python libraries maintain their own separate certificate stores and do not read Ubuntu's system bundle automatically.

For Java, the cacerts file location depends on which JVM version you have installed. Find it first, then import:

# Step 1 — Find your Java cacerts file
find /usr/lib/jvm -name "cacerts" 2>/dev/null

# Step 2 — Import your corporate CA (replace the path with the one found above)
sudo keytool -import -alias corporate-ca \
-file /usr/local/share/ca-certificates/your-corporate-ca.crt \
-keystore /usr/lib/jvm/java-21-openjdk-amd64/lib/security/cacerts \
-storepass changeit -noprompt

The find command is essential because the path changes with every JVM version and installation method. Using a hardcoded path will fail silently if your JVM is installed differently.

The sudo Problem Every Admin Hits

This is the single most common proxy failure on Ubuntu, and it affects even experienced admins.

When you run any command with sudo, sudo strips your environment variables by default as a security measure. This means http_proxy, https_proxy, and every other proxy variable you set will simply disappear for that command, even if they are perfectly configured in your shell.

So when you set up environment variables and then run sudo apt update, APT is not ignoring your proxy because APT ignores environment variables (which it does). The deeper issue is that sudo already stripped them before APT even started.

Quick Fix: Use sudo -E for a Single Command

The -E flag tells sudo to preserve your environment variables:

sudo -E curl https://example.com
sudo -E pip install requests

However, this only works for that one command, and it does not fix apt since APT has its own proxy config anyway.

Permanent Fix: Configure sudoers to Keep Proxy Variables

The proper permanent solution is to tell sudo which variables to preserve for all commands. Edit the sudoers file safely using visudo:

sudo visudo

Find the Defaults section and add this line:

Defaults env_keep += "http_proxy https_proxy ftp_proxy no_proxy ALL_PROXY HTTP_PROXY HTTPS_PROXY NO_PROXY"

Save and exit. From this point forward, sudo will preserve your proxy environment variables for every command.

Verify sudo Preserves the Variables

Test that it works:

export http_proxy="http://proxyhost:port"
sudo printenv http_proxy

If you see the proxy address printed, sudo is now preserving the variable correctly.

Security note: Preserving proxy environment variables in sudoers is safe in most environments. However, be aware that on highly sensitive systems, proxy variables could theoretically be manipulated to redirect privileged traffic. In those cases, configure each privileged tool (APT, system-level pip, etc.) with its own dedicated config file instead of relying on inherited environment variables.

Verifying Your Proxy Actually Works

There is an important difference between checking that a variable is set and confirming that the proxy is actually routing your traffic.

Running echo $http_proxy only confirms the variable exists in your shell. It tells you nothing about whether the proxy is reachable or working.

Use these commands to confirm real proxy connectivity.

Check What IP the World Sees

This is the most reliable test. It sends a request through your proxy and returns the IP address the destination server sees:

curl -x http://proxyhost:port https://httpbin.org/ip

If the proxy is working, the IP address in the response should match your proxy server's IP, not your local machine's IP. If it shows your real IP, the proxy is being bypassed.

Watch the Proxy Handshake in Verbose Mode

The -v flag shows exactly what curl is doing step by step:

curl -v -x http://proxyhost:port https://example.com

Look for a line like Connected to proxyhost near the top. If you see Connected to example.com instead, curl is bypassing the proxy.

Test That sudo Preserves the Proxy

export http_proxy="http://proxyhost:port"
sudo -E curl -x $http_proxy https://httpbin.org/ip

Test APT Separately

APT does not use environment variables, so test it independently:

sudo apt update -o Acquire::http::proxy="http://proxyhost:port"

If this works but your normal sudo apt update does not, your APT config file has a problem.

Test a systemd Service's Network Path

To confirm a service is routing through the proxy, check what environment it actually sees:

sudo systemctl show myservice --property=Environment

For Docker daemon proxy verification

sudo systemctl show docker --property=Environment

Shell Compatibility: bash, zsh, and fish

This guide uses bash syntax throughout, because Ubuntu 26.04 defaults to bash. However, many developers use zsh or fish, and the syntax for setting environment variables differs between them.

bash

Add to ~/.bashrc (interactive shells) or ~/.bash_profile (login shells):

export http_proxy="http://proxyhost:port"
export https_proxy="http://proxyhost:port"
export no_proxy="localhost,127.0.0.1"

zsh

The syntax is identical to bash. Add to ~/.zshrc:

export http_proxy="http://proxyhost:port"
export https_proxy="http://proxyhost:port"
export no_proxy="localhost,127.0.0.1"

fish

Fish uses a completely different syntax. Add to ~/.config/fish/config.fish:

set -x http_proxy "http://proxyhost:port"
set -x https_proxy "http://proxyhost:port"
set -x no_proxy "localhost,127.0.0.1"

Fish does not use export. Instead, the -x flag on set marks a variable as exported to child processes — which is the fish equivalent of export.

Note: Regardless of which shell you use, system-level configs (/etc/environment, /etc/profile.d/proxy.sh, APT, curl, wget, Git, pip, npm, Docker, Snap, and systemd) remain the same. Shell syntax only affects the user-level ~/.*rc files.

Understanding Variable Precedence

When multiple proxy settings exist at the same time (an environment variable, a tool config file, and a command-line flag), which one wins? Understanding the order prevents hours of debugging when a setting does not seem to take effect.

curl Precedence (Highest to Lowest)

PrioritySource
1 (highest)-x / --proxy command-line flag
2~/.curlrc user config file
3 (lowest)http_proxy / https_proxy environment variables

A command-line flag always wins. If you set a proxy in ~/.curlrc but then run curl --noproxy "*", the flag overrides the config file completely. Note that curl has no system-wide config file on Linux — environment variables are the system-wide mechanism.

wget Precedence (Highest to Lowest)

PrioritySource
1 (highest)-e command-line option
2~/.wgetrc user config file
3/etc/wgetrc system config file
4 (lowest)http_proxy / https_proxy environment variables

git Precedence (Highest to Lowest)

PrioritySource
1 (highest)--config command-line flag
2.git/config repository-level config
3~/.gitconfig user-level config
4 (lowest)/etc/gitconfig system-level config

pip Precedence (Highest to Lowest)

PrioritySource
1 (highest)--proxy command-line flag
2pip.conf in the active virtual environment
3~/.config/pip/pip.conf user config
4/etc/pip.conf system config
5 (lowest)http_proxy / https_proxy environment variables

The practical takeaway is this: command-line flags always win, environment variables always lose. If a tool is not picking up your proxy, check whether a config file somewhere is overriding your environment variable with a different setting.

The no_proxy Format Guide

The no_proxy variable tells tools which hosts to reach directly, bypassing the proxy. However, different tools interpret it differently. And if you get the format wrong, you will either route internal traffic through the proxy or bypass the proxy for hosts that should use it.

The Most Compatible Format

This format works correctly across the widest range of tools:

export no_proxy="localhost,127.0.0.1,::1,.company.internal,10.0.0.0/8,192.168.0.0/16"

Key rules:

  • Use commas to separate entries - no spaces after commas in most tools
  • Use a leading dot (.company.internal) to match a domain and all its subdomains. Without the dot, most tools only match the exact hostname
  • You can include CIDR notation for IP ranges, but not all tools support it - curl and wget do; older tools may not
  • Always include localhost and 127.0.0.1 explicitly

Tool-Specific Differences

ToolSubdomain matchingCIDR supportWildcard support
curlLeading dot .example.comYes* for all
wgetLeading dot .example.comPartialNo
gitLeading dot .example.comNoNo
pipLeading dot .example.comNoNo
npmLeading dot .example.comNoNo
Docker daemonLeading dot .example.comYesNo

Common Mistake: Missing the Leading Dot

Without the leading dot, company.internal only bypasses the proxy for the exact hostname company.internal. Subdomains like gitlab.company.internal will still go through the proxy. Always use .company.internal to cover the domain and all its subdomains.

Troubleshooting Common Problems

Even after careful configuration, things sometimes go wrong. Here are the most common problems and their solutions.

1. My proxy works in the browser but not in the terminal.

GNOME proxy settings only apply to GUI apps. Open ~/.bashrc and add the proxy environment variables as shown in Method 1. Then run source ~/.bashrc.

2. I set the environment variables but APT still fails.

APT ignores environment variables by design. Create /etc/apt/apt.conf.d/proxy.conf as described in Method 2.

3. I set environment variables but sudo commands still bypass the proxy.

sudo strips environment variables by default. Either use sudo -E for individual commands, or add the proxy variables to the env_keep list in /etc/sudoers using sudo visudo. See the sudo Problem section above.

4. curl works but wget does not.

They use separate config files. Add your proxy to ~/.wgetrc as described in Method 4.

5. I set everything but HTTPS connections still fail with SSL errors.

You are behind an intercepting proxy that re-signs certificates. Install your organization's root CA certificate using the steps in the CA Certificates section. Never use -k or --no-check-certificate as a permanent fix.

6. My systemd service still bypasses the proxy.

Services do not inherit environment variables. Use sudo systemctl edit servicename to create a drop-in override with explicit Environment= lines. See Method 11.

7. Snap apps ignore my proxy settings.

Snap has its own proxy system. Run sudo snap set system proxy.http="http://proxyhost:port" and sudo snap set system proxy.https="...", then restart snapd. See Method 10.

8. Git clone fails even though curl works fine.

Git does not inherit system environment variables reliably for proxy use. Set the proxy explicitly with git config --global http.proxy http://proxyhost:port. Note that this single key covers both HTTP and HTTPS connections. See Method 6.

9. pip install fails behind the proxy.

Create ~/.config/pip/pip.conf and add a [global] proxy = ... line. See Method 7.

10. Docker cannot pull images.

The Docker daemon is a systemd service, so it needs its own drop-in file. See Method 9, Part 1. This is separate from the Docker client config in ~/.docker/config.json.

11. My environment variables disappear after I log out.

Variables set with export in the terminal only last for that session. Add them to ~/.bashrc for your user, or /etc/environment or /etc/profile.d/proxy.sh for all users.

12. My proxy settings work but some internal servers are unreachable.

Check your no_proxy variable. Make sure internal hostnames have a leading dot (.company.internal) and that you have included the relevant IP ranges. See the no_proxy Format Guide above.

13. I am getting authentication errors even though my credentials are correct.

Check for special characters in your password. URL-encode any @, :, /, or # characters. See the Authentication section above.

Quick Reference Table

Here is a complete summary of every tool covered in this guide.

ToolConfig File / MethodScopeReads Env Vars?
Most CLI tools~/.bashrc or /etc/environmentUser / System
APT/etc/apt/apt.conf.d/proxy.confSystem❌ No
curl~/.curlrc (user only; no system-wide file)User✅ Yes (lowest priority)
wget~/.wgetrc or /etc/wgetrcUser / System✅ Yes (lowest priority)
Git~/.gitconfig via http.proxyUser⚠️ Unreliable
pip~/.config/pip/pip.conf or /etc/pip.confUser / System✅ Yes (lowest priority)
npm~/.npmrc via npm config setUser⚠️ Partial
Docker daemon/etc/systemd/system/docker.service.d/http-proxy.confSystem❌ No (systemd service)
Docker client~/.docker/config.jsonUser❌ No
Snapsnap set system proxy.*System❌ No
systemd servicessystemctl edit servicenamePer service❌ No
GNOME appsSettings → Network → ProxyGUI only❌ No
sudo commandsvisudo env_keepPer command❌ Stripped by default

Final Summary

Configuring a proxy on Ubuntu 26.04 takes more work than most people expect, but the pattern is consistent once you understand it: each tool manages its own proxy, and environment variables are just a starting point, not a complete solution.

The most important things to take away from this guide are:

  • Start with environment variables in ~/.bashrc and /etc/environment. They cover the widest range of tools with the least effort.
  • Always configure APT separately. It never reads environment variables.
  • Remember that sudo strips your environment. Either use sudo -E or configure env_keep in sudoers.
  • Systemd services and Snap packages have completely separate proxy systems that ignore everything else.
  • Install your organization's CA certificate into Ubuntu's trust store once, and most HTTPS problems disappear across all tools at once.
  • Always use lowercase proxy variable names. They are widely supported and avoid the httpoxy security vulnerability.
  • Git's http.proxy covers both HTTP and HTTPS connections. You only need to set it once.
  • curl has no system-wide config file on Linux; use environment variables via /etc/profile.d/proxy.sh for system-wide curl proxy.

With the right configuration across every layer of the stack, your Ubuntu machine will route traffic exactly where you want it, every single time.

Did this guide help you? Share it with a fellow Linux admin who is dealing with the same proxy headaches.

You May Also Like

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies to improve your experience. By using this site, we will assume that you're OK with it. Accept Read More