DEV Community

Cover image for Setting network proxy on linux desktop
Navdeep Singh Rathore
Navdeep Singh Rathore

Posted on

Setting network proxy on linux desktop

I was trying to write a script to setup system wide proxy on my Ubuntu desktop. Turns out, Linux makes it way too difficult to configure a proxy across all apps.

Table of Contents

0. Setting app specific proxies

Most web browsers (Firefox in particular) have their own internal proxy settings. There is abundant documentation for all of these on their respective websites.

1. Gnome network settings

If you are using Gnome, you can go to Settings > Network > Network Proxy. Select Manual and enter the proxy details.

This the most obvious method and it covers most general use cases like using a proxy for WiFi inside a corporate or university network.

Gnome Network settings

Under the hood, this sets attributes in gconf(maybe dconf in modern distros). This can be done from the terminal as:

gsettings set org.gnome.system.proxy mode 'manual'
gsettings set org.gnome.system.proxy.http enabled true
gsettings set org.gnome.system.proxy.http host 'proxy.server.addr'
gsettings set org.gnome.system.proxy.http port proxy_port
Enter fullscreen mode Exit fullscreen mode

2. Setting environment variables

The previous method does not always work for shell instances. A proven way for using a proxy while working on the terminal (either while doing a simple curl, or while launching an app) is by setting environment variables like http_proxy or HTTP_PROXY to set a proxy for all http request.

Note: you might want to set both the uppercase and the lowercase version. This is necessary because, without a proper standard, over the years apps and languages either support both (with a set of priorities) or any one of the two. This leads to some long, head scratching debugging sessions, like this one

You can either do this for each shell instance like:

http_proxy="username:password@proxy_address:port" 
curl http://www.example.com

# you can skip the authentication part for an open proxy
Enter fullscreen mode Exit fullscreen mode

or be smart guy, and export this and other relevant variables inside .bashrc (or maybe .zshrc) as

export http_proxy="http://$username:$password@$proxy_address:$port"
export HTTP_PROXY="http://$username:$password@$proxy_address:$port"
Enter fullscreen mode Exit fullscreen mode

By other relavant variables, I mean

  1. https_proxy / HTTPS_PROXY
  2. ftp_proxy / FTP_PROXY
  3. no_proxy / NO_PROXY
  4. rsync_proxy / RSYNC_PROXY

To check if these variables have been set properly, you can run the following:
set | grep -i proxy
Similarly, these can be unset individually when required with unset http_proxy

Bonus
If you feel like all this is too much, you can use a tool like (ProxyMan)[https://github.com/himanshub16/ProxyMan/] that is a lightweight shell script with a simple interface to both set and unset these variables.

This also does advanced steps like setting a proxy for commands like apt update, if you require.
This is done by adding the following to /etc/apt/apt.conf

Acquire::http::Proxy "http://username:password@proxy_address:port";
Enter fullscreen mode Exit fullscreen mode

You can go even further with tools like proxychains that let you chain multiple proxies. This is used while setting up tor and comes pre-installed with pentesting distros like Kali and ParrotOS.

3. Using iptables

Most general use cases will be satisfied by the above 2 steps.
Even if you need to setup something like your own man-in-the-middle proxy like mitm or a transparent proxy like squid for simple logging, you could still use the previous step and launch apps from the terminal while setting the required variables to point to the proxy server
That does, mostly, work.

But what if you want to send all of your system's traffic through your proxy?
To setup a system wide proxy, most google searches will lead you to answers on stack-exchange that recommend some form of method #2. \
But, as stated in the Gitlab blog it does not always work, and is also a source of unwanted bugs.

Full disclaimer: I haven't tried this properly myself and am also fairly new to using iptables. But, it seems like the only valid approach out there that tries to solve this specific problem
I have kept my explanation; based on my rudimentary understanding; as short as possible
Please reference the post mentioned below for a better explanation

iptables is a tool provided by netfilter that is used to configure custom firewalls on your system.

For our use case, we can mark all our out going network packets from a certain user and forward it to the process running our proxy.

Make sure that the proxy is running under a separate user, so as to prevent the proxy from intercepting its own output.

Step-by-step instructions - https://serverfault.com/a/674389/946308

Some references online that helped me

  1. https://unix.stackexchange.com/a/213740/428441
  2. https://wiki.archlinux.org/title/Proxy_server
  3. https://discourse.mitmproxy.org/t/transparent-proxying-on-a-single-machine-iptables/97
  4. https://about.gitlab.com/blog/2021/01/27/we-need-to-talk-no-proxy/

Discussion (0)