My school us­es an NTLM-au­then­ti­cat­ing proxy server, and this caus­es prob­lems with lots of ap­pli­ca­tions which don’t sup­port proxy servers. Many, many so­lu­tions have been pro­posed to this prob­lem, but I’ll fo­cus on one that I find par­tic­u­lar­ly ap­peal­ing: set­ting up a non-au­then­ti­cat­ing per­son­al proxy server which for­wards re­quests to the main proxy server.

Up­date: use the new ver­sion of this con­fig file - it works bet­ter.

Here’s why this so­lu­tion is op­ti­mal, or at least bet­ter than other cur­rent­ly-avail­able so­lu­tions. Con­sid­er one method of forc­ing pro­grams to use the proxy (un­der Lin­ux), which is set­ting the http_proxy and ftp_proxy en­vi­ron­ment vari­ables. Pro­grams that sup­port proxy servers and that sup­port proxy au­then­ti­ca­tion (be­cause my school us­es an au­then­ti­cat­ing proxy), no­tably apt-get, wget, and lynx, will use those en­vi­ron­ment vari­ables to con­nect through the proxy server. Pro­grams that don’t, or those that don’t read the en­vi­ron­ment vari­ables (biggest of­fend­ers: most GNOME pro­grams), won’t.

The biggest prob­lem with this method is its in­con­sis­ten­cy - it’s im­pos­si­ble to know nec­es­sar­i­ly which pro­grams work, and which pro­grams sup­port proxy au­then­ti­ca­tion; and in ad­di­tion, one needs to re-en­ter one’s proxy set­tings in the en­vi­ron­ment vari­ables (bashrc, prob­a­bly), in the GNOME set­tings, and prob­a­bly in­di­vid­u­al­ly for some pro­grams too. On top of that, many GNOME pro­grams don’t (or didn’t) sup­port proxy au­then­ti­ca­tion… fi­nal­ly, it is im­pos­si­ble in the en­vi­ron­ment vari­able to spec­i­fy which con­nec­tions (like those to the lo­cal net­work) should be di­rect, and which should be through the proxy.

Con­sid­er a slight­ly bet­ter method, which is proxychains. In order to use prox­y­chains, one must type com­mands like so:

# In­stead of writ­ing
su­do apt-get in­stall ubun­tu-desk­top
# One must write
su­do prox­y­chains apt-get in­stall ubun­tu-desk­top

Okay, so that’s not too bad, if a lit­tle bit in­con­ve­nient. The good thing about this method is that prox­y­chains can “prox­i­fy” pro­grams that don’t sup­port proxy servers na­tive­ly. The proxy au­then­ti­ca­tion user­name and pass­word are al­so stored in one place on­ly: the prox­y­chains con­fig­u­ra­tion file. The on­ly two prob­lems with this method? 1. Typ­ing prox­y­chains be­fore ev­ery com­mand, and 2. The in­abil­i­ty of prox­y­chains (at least the most re­cent ver­sion) to make some con­nec­tions di­rect (i.e. those on the lo­cal net­work) and some to go through the proxy, just like the pre­vi­ous method.

Fine, so those meth­ods aren’t ide­al. What makes the Squid 3 method bet­ter? Well, on the sur­face it solves most, if not all, the prob­lems that the pre­vi­ous meth­ods had. It doesn’t re­quire au­then­ti­ca­tion (that is han­dled trans­par­ent­ly by the per­son­al proxy) and au­then­ti­ca­tion in­for­ma­tion is stored in one place on­ly (the squid.conf). This alone makes many pro­grams work much bet­ter. You can cache far more per­son­al­ized web data (the school’s proxy serv­ing hun­dreds of stu­dents prob­a­bly won’t cache data that you, per­son­al­ly fre­quent­ly use), and sav­ing proxy in­for­ma­tion in many dif­fer­ent places is okay, be­cause if your user­name and pass­word change, you don’t need to change it in all those dif­fer­ent places. Fi­nal­ly, one can still use prox­y­chains to prox­i­fy mis­be­hav­ing pro­grams, be­cause Squid can be con­fig­ured to con­nect to some ad­dress­es di­rect­ly in­stead of prox­y­ing through the par­ent proxy. Its biggest prob­lem is that run­ning Squid more or less re­quires Lin­ux.

Okay, enough ban­ter. Let’s learn how to do this thing. I’m us­ing Ubun­tu 8.04 server (on a vir­tu­al ma­chine), so the­se in­struc­tions may or may not be Ubun­tu-speci­fic. Here’s my con­fig file:

cache_ef­fec­tive_user proxy # Ubun­tu-speci­fic?
cache_ef­fec­tive_group proxy # Ubun­tu-speci­fic?

http_port 3128
http_ac­cess al­low all

cache_peer prx1 par­ent 3128 3190 no-query login=user­name:pass
cache_peer prx2 par­ent 3128 3190 no-query login=user­name:pass
cache_peer_ac­cess prx1 al­low all
cache_peer_ac­cess prx2 al­low all

hier­ar­chy_sto­plist cgi-bin ?

cache_mem 64 MB # How much mem­o­ry Squid us­es for cache.
                # Make low­er if you have less mem­o­ry
max­i­mum_ob­ject_size_in_mem­o­ry 64 KB # Make low­er if you have less mem­o­ry

cache_re­place­ment_pol­i­cy heap LFU­DA
cache_dir aufs /var/spool/squid3 6000 16 256
max­i­mum_ob­ject_size 16384 KB

ac­cess_log /var/log/squid3/ac­cess.log squid

shut­down_life­time 1 sec­ond

acl lo­cal-servers dst 127.0.0.1 192.168.1.0/24
nev­er_di­rect deny lo­cal-servers
nev­er_di­rect al­low all

There are two “par­ent” prox­ies in this file which this per­son­al proxy can ac­cess. Ob­vi­ous­ly, re­place user­name and pass­word with your own au­then­ti­ca­tion in­for­ma­tion. Al­so, don’t for­get to change cache_ef­fec­tive_user and cache_ef­fec­tive_group to your lik­ing or your dis­tro. Change the cache_re­place­ment_pol­i­cy to fit your caching needs, and fi­nal­ly, make sure to ed­it the acl lo­cal-servers to spec­i­fy which servers you do not want to proxy.

After do­ing this, you should be able to restart Squid and have ev­ery­thing work­ing! Next up: trans­par­ent prox­y­ing with ipt­a­bles.