How to invoke a command using specific proxy server?

Some applications support proxy (http proxy or socks proxy), and some are not.

For browsers, I can specify proxy server in the preferences/options dialog, and other applications may be able to configure proxy servers in config files.

For general purpose, can I invoke a command using a specific proxy? Like following:

$ proxy-exec --type sock5 --server 1.2.3.4:8000 -- wget/ftp ...

I'm using Ubuntu Maverick.

P.S.

In win32, it can be implemented by hijacking the socket dlls, maybe, I'm not familiar with Linux programming, but I guess it's possible in Linux. though.


Solution 1:

Most Linux commands that access the Internet look in the HTTP_PROXY, FTP_PROXY, and SOCKS_SERVER environment variables for proxy information. So, to do something like your example, just run:

export SOCKS_SERVER=1.2.3.4:8000
wget http://superuser.com/q/262956/66003

The syntax for HTTP_PROXY and FTP_PROXY is slightly different:

export HTTP_PROXY=http://1.2.3.4:3128/
export FTP_PROXY=ftp://1.2.3.4:25/

The default GNOME desktop environment included with Ubuntu's proxy settings has an Apply System-Wide button, which will automatically set those environment variables for you. Otherwise, you can add the export lines to your ~/.bashrc file to make them take effect at every login.

Unfortunately, wget doesn't support SOCKS at all. You can use curl, which is included with Ubuntu, to achieve many things that wget does. Unfortunately, it doesn't check SOCKS_SERVER, while it does check HTTP_PROXY (as does wget). To use curl to download this page with a SOCKS5 server (performing DNS resolution with that server) and save it as superuser.html, run this:

curl --socks5-hostname 1.2.3.4:8000 http://superuser.com/q/262956/66003 > superuser.html

If you want to make curl always use that SOCKS proxy, you could create a shell alias. Just add the following line to your ~/.bashrc:

alias curl='curl --socks5-hostname 1.2.3.4:8000'

You will need to restart your terminal or run that line as if it were a command for the changes to take effect.

Solution 2:

Try proxychains.

It can be installed with apt-get. Then you'll need to create a config file in either of

1) ./proxychains.conf
2) $(HOME)/.proxychains/proxychains.conf
3) /etc/proxychains.conf **

and you'll be able to invoke another commands like proxychains wget google.com - the connections will go through proxy. You can specify multiple proxies used at once or in random order.

For example:

➜  ssh -ND 4000 sockshost &
[1] 3446
➜  wget whoer.net -q -O- | grep remote_addr
89.71.*.*
➜  cat proxychains.conf 
[ProxyList]
socks5 127.0.0.1 4000
➜  proxychains wget whoer.net -q -O- | grep remote_addr
|D-chain|-<>-127.0.0.1:4000-<><>-95.211.121.18:80-<><>-OK
78.98.*.*

I stripped some HTML tags and IPs, but as you can see the proxy was used and the IP address did change.