Updated for 2026: originally published in November 2017. Rewritten for RHEL 9 and 10 (RHEL 7 reached end of life in June 2024). The retired RHN section is gone, yum is replaced by dnf, and the structure below reflects how proxy settings actually work now: there is no single global switch.
The first thing to understand about proxies on RHEL is that there is no one setting that covers the whole system. Each layer reads its own configuration, and a setting in one place does nothing for the others. The shell, dnf, sudo, subscription-manager, the desktop, and systemd services each need their own entry. If you set only the environment variables and then wonder why dnf or registration still fails, this is why.
Checking what is already set
env | grep -i proxy
This shows every proxy variable in your current shell. An empty result does not mean nothing is proxied: dnf, subscription-manager, and GNOME each keep their own settings outside the environment. To see whether traffic actually goes through a proxy, watch curl negotiate it:
curl -v https://example.com 2>&1 | grep -i proxy
Shell and command-line tools
curl, wget, git, and most CLI tools read the environment variables. Set all three, in both cases, because different tools look at different casings:
export http_proxy=http://proxy.example.com:3128/
export https_proxy=http://proxy.example.com:3128/
export no_proxy=localhost,127.0.0.1
export HTTP_PROXY=http://proxy.example.com:3128/
export HTTPS_PROXY=http://proxy.example.com:3128/
export NO_PROXY=localhost,127.0.0.1
Note that the proxy URL itself uses http:// even for HTTPS destinations: the client connects to the proxy over plain HTTP and tunnels the encrypted traffic with CONNECT. With authentication, put the credentials in the URL:
export http_proxy=http://username:password@proxy.example.com:3128/
If the username or password contains reserved characters such as @, #, or :, URL-encode them (%40 for @) instead of backslash-escaping — backslashes do not work in proxy URLs.
Add internal hosts and your cloud metadata endpoint to no_proxy so local traffic never takes the proxy detour:
export no_proxy=localhost,127.0.0.1,.example.com,169.254.169.254
Making it permanent
For all users, put the exports in a login-shell snippet at /etc/profile.d/proxy.sh. New logins pick it up; existing sessions need a re-login (or source the file). Two gotchas: sudo strips environment variables by default, so commands run under sudo will not see your proxy. Keep the variables across sudo with a drop-in at /etc/sudoers.d/proxy (edit with visudo):
Defaults env_keep += "http_proxy https_proxy ftp_proxy no_proxy HTTP_PROXY HTTPS_PROXY FTP_PROXY NO_PROXY"
And remember that anything in /etc/profile.d is readable by every user on the box — avoid putting proxy passwords there. If only dnf needs authentication, keep the credentials in dnf’s own config instead.
dnf (replaces yum)
On RHEL 7 this lived in /etc/yum.conf. On RHEL 8 and later, dnf reads /etc/dnf/dnf.conf. Under [main]:
proxy=http://proxy.example.com:3128
proxy_username=proxyuser
proxy_password=secret
proxy_auth_method=any
Separate username/password keys beat embedding credentials in the URL, especially when the password contains reserved characters. When proxy= is unset, dnf falls back to the environment variables. Test it with:
dnf clean all && dnf makecache
A 407 Proxy Authentication Required here means the proxy itself rejected the credentials — check proxy_username and proxy_password before anything else.
subscription-manager
Registration is usually the first thing to break behind a proxy, because subscription-manager reads its own config in /etc/rhsm/rhsm.conf and those settings override the environment variables. Set them before you register, either in the file ([server] section: proxy_hostname, proxy_port, proxy_user, proxy_password) or with:
subscription-manager config --server.proxy_hostname=proxy.example.com --server.proxy_port=3128
Desktop (GNOME)
On a workstation, browsers and desktop apps use GNOME’s own proxy: Settings → Network → Network Proxy, set to Manual (host and port per protocol) or Automatic with a PAC URL. That covers the desktop only — it does not set the shell variables or dnf, so a workstation still needs the sections above for the command line.
systemd services
Services do not inherit your shell. Give a service its proxy with a drop-in:
systemctl edit myservice
[Service]
Environment="http_proxy=http://proxy.example.com:3128/"
Environment="https_proxy=http://proxy.example.com:3128/"
Environment="no_proxy=localhost,127.0.0.1"
Verification checklist
env | grep -i proxy— shell variables present.curl -I https://example.com— reaches the outside world through the proxy.dnf makecache— repositories reachable; 407 means bad proxy credentials.subscription-manager status— registration works through the proxy.
Set each layer once, verify each layer separately, and a proxy change becomes a five-minute job instead of a round of “works in curl, fails in dnf.”
