Thursday, June 17, 2010

the linux proxy problem

For those of you who use linux for anything more than web browsing (in university/office) must be aware of the problems a proxy can pose. In many places as in my institute, you need to necessarily use a specified proxy server to access outside world, needing authentication for your credentials.
In my college, a common login registered in a central ldap server provides for all authentication services (used for course registration/fees payments/emails/proxy/...). Hence it is very important to protect it. Here i will show one way to avoid anyone easily getting your password.


Network proxy loophole in GNOME:
If you are using GNOME (default Fedora/Ubuntu) and you set your proxy details in "system->preferences->network proxy" then you open a simple loophole in the settings.
After setting your username/password, open a new terminal and type
    echo $http_proxy
Now you can clearly see your password as
        http://<user>:<pass>@proxy.com:3128/
Now since many people come to your rooms in colleges you can see how simple it is to get your credentials.

Is there a way out:
There may be other ways, but here's the one which i follow. I create a local forwarding proxy server on my own computer and direct all applications to use that proxy. The settings for my proxy server are written in a file only readable by the root.
What follows is a step-by-step guide to set it up. Tested on Fedora

What do i use:
I use a small proxy server 3proxy, you could also use any other proxy server such as squid. In fact i used to use squid before i came to know of 3proxy (when it was packaged in fedora). Squid is a much more feature rich and heavy proxy. When i was using it had a bug whereby it would do at least 100 cpu wakeups per second, using precious power on my laptop. This may have been fixed by now.

Installation:
 On Fedora systems you can do
    yum install 3proxy
A similar command for apt-get may work on Ubuntu (i've never tried)

Configuration:
The configuration you need to do is

  1. Open the file /etc/3proxy.cfg in editor of your choice as root
  2. Locate the line containing 'proxy -n'
  3. Above this line, upto the line 'dnspr', comment out all uncommented lines and instead add the following lines:

    auth iponly

    allow * * 127.0.0.0/24,<local_IPs> * * * *
    allow * * * * * * *
    parent 1000 http <proxy.server.com> <port> <proxy_user> <proxy_pass>
    proxy -n

    The values in angle brackets need to be replaced by you configuration The values for my college are given in parenthesis
    <local IPs> = ips not connected through proxy [10.0.0.0/8]
    <proxy.server.name> = proxy server [netmon.iitb.ac.in]
    <port> = proxy port [80]
    <proxy_user> = proxy authentication username
    <proxy_pass> = proxy authentication password
  4. Comment out all lines with the content:

    socks
    pop3p
    ftppr
    admin
    dnspr
    tcppm
    udppm
  5. Save the file
  6. as root run (this will make the file only readable by root user)
        chmod o-rwx /etc/3proxy.cfg
        chkconfig 3proxy on
  7. ??
  8. profit
The details of the 3proxy.cfg file are documented at http://www.3proxy.ru/doc/html/man3/3proxy.cfg.3.html

Now in whichever application you need to set the proxy server, set it as

http://127.0.0.1:3128/

without any authentication.
Thats it, now only root knows your ldap password, and no one else can snoop

EDIT:
If you automatically want to set the proxy environment variable of the whole system, then you can create a file /etc/profile.d/proxy.sh with the following content

export http_proxy=http://127.0.0.1:3128/
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy

Many (not all) programs on linux use these environment variables to get proxy settings.

EDIT2 :
To set multiple proxies (different hosts go through different proxies) you can do something like below (see 3proxy.cfg manual for much more detail and many other options):
# direct connection allow * 127.0.0.1 127.0.0.0/24,<local_IPs> * * # through proxy1 allow * * <hosts_thru_proxy1> * * parent 1000 http <proxy1.server.com> <port> <proxy_user>  # through proxy2 allow * * <hosts_thru_proxy2> * * parent 1000 http <proxy2.server.com> <port> <proxy_user>  # through proxy3 allow * * <hosts_thru_proxy3> * * parent 1000 http <proxy3.server.com> <port> <proxy_user> allow * * * * * proxy -n