Proxing and tunneling in *nix

You will be able in 10 minutes:
  1. Setup tunnel (VPN-like default gateway for all network connection) with SSH only.
  2. Setup HTTP, HTTPS, SOCKS5 proxy with SSH.
  3. Setup HTTP, HTTPS, SOCKS5 proxy with SQUID.
  4. How to connect SSH via / over SOCKS5 proxy.
  5. How to setup proxy variables in *nix (environment).
  6. Tips how to setup proxy for various software.
Fully explained commands following. You can copy-paste it to terminal to get the goals.
Should be compatible with all Linux and BSD distributions.

VPN-like tunnel to route all traffic to default GW created by SSH utility

The best way if you have no VPN connection but ssh only.
Also can be used over existing VPN connection to spread this only VPN connection
to the several client machines (out of the scope this article).
On the remote sshd server:
vi /etc/ssh/sshd_config
add or enable or uncomment following line:
PermitTunnel yes
and restart sshd.
iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE
iptables -A FORWARD -s -j ACCEPT
iptables -I FORWARD -p tcp -s   '!' '-d' -o eth0 --tcp-flags ALL RST -j DROP
Note, change eth0 to actual outgoing interface here.
On the local client machine:
Add precise route to the ssh server IP address:
route add -host gw
Make tun tunnels on both ends and all the magic:
ssh -o PermitLocalCommand=yes \
-o LocalCommand="ifconfig tun33 ; route add default gw" \
-o ServerAliveInterval=60 \
-o Tunnel=yes \
-w 33:33 \
root@ 'ifconfig tun33 ; echo tun33 ready'

Now all routing (default route was added) goes to our tunnel.
Please note, we have to use root user when connect to the remote ssh server machine.
You can substitute 33 and and
to multiply client connections to the same sshd server.

Make HTTP, HTTPS, SOCKS5 proxy with SSH

We use so-called dynamic forward here.
So DynamicForward is equal to the -D argument of the ssh command.
On the remote sshd server:
vi /etc/ssh/sshd_config
add or enable or uncomment following lines:
AllowTcpForwarding yes
PermitOpen any
and restart sshd.
On the local client machine:
vi ~/.ssh/config
add following lines:
Host target-host
        Protocol 2
        #User non-root-user
        Port 22
        Compression no
        CompressionLevel 9
        ForwardX11 no
        ForwardAgent no
                TCPKeepAlive yes
                ServerAliveInterval 60
                ServerAliveCountMax 9999
        DynamicForward *:31289

And invoke:
ssh remote-non-root-user@target-host

Now you have socks5 proxy on port 31289 of all local network interfaces.

Also you have port forwarding:
31290 - forward to squid instance on port 3128 at (setup explained below).
31291 - forward to squid instance on port 3128 somewhere at the remote network.
*squid supports HTTP, HTTPS and SOCKS5.
5900 - forward to VNC server on port 5900 at

Make HTTP, HTTPS, SOCKS5 proxy with SQUID

Just install SQUID on and set the following minimum SQUID configuration.
Minimal SQUID config is:
acl localnet src

acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210         # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all

http_port 3128

coredump_dir /var/spool/squid
#check dir permissions:
#drwxr-x--- 2 squid squid 4.0K /var/spool/squid

refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern -i (/cgi-bin/|\?) 0     0%      0
refresh_pattern .               0       20%     4320
Now you have HTTP, HTTPS and SOCKS5 proxy on port 3128 of loopback network interface.

Connecting SSH via / over SOCKS5 proxy

We already have ssh-based SOCKS5 proxy configured / connected (see above).
Apart of ssh tunnel (see above), we can use this SOCKS5 to proxing all our ssh connections.
We will use ProxyCommand and nc (netcat) or connect (connect-proxy) utilities.
Install utilities on the local client machine:
#RHEL CentOS Fedora based:
yum install nmap-ncat #for /usr/bin/nc

#Debian / Ubuntu based:
apt-get install connect-proxy #for /usr/bin/connect /usr/bin/connect-proxy
Where nmap-ncat is:
Nmap's Netcat replacement.

Where connect-proxy is:
Establish TCP connection using SOCKS4/5 or HTTP tunnel
connect-proxy is a simple relaying command to make tunnel TCP connection
via SOCKS or HTTPS proxies.
It is mainly intended to be used as proxy command of OpenSSH.

On the local client machine:
vi ~/.ssh/config
add following lines to the bottom of file:
#Will be applied for all hosts you connects to:
Host *
        Protocol 2,1
        TCPKeepAlive yes
        ServerAliveInterval 60
        ServerAliveCountMax 9999
        #User some-ssh-user
        Port 22
          CheckHostIP no
          #ProxyCommand=nc -X 5 -x %h %p
          ProxyCommand=connect -4 -S %h %p

And if you not yet done it already (as described above) invoke:
ssh -D *:31289 remote-non-root-user@target-host
to setup SOCKS5 proxy on port 31289.

Now invoke:
ssh remote-non-root-user@
this connection will be proxied via SOCK5 proxy.
I recommend to prefer connect over nc.
CheckHostIP no also required to make things work.

Excluding some hosts from being proxied

Also you can exclude some hosts from being proxied:
vi ~/.ssh/config

Host *
definition to:
Host ! *
to exclude IP address from being proxied.

Host ! *
definition to:
Host ! !10.22.*.* *
to exclude subnet from being proxied.

Also, please do not forget to
add following lines to the bottom of file:
        ProxyCommand none
Host 10.22.*.*
        ProxyCommand none

Tips how to setup proxy variables in *nix (environment)

Our main tip is related to *nix itself:
 export http_proxy=
 export https_proxy=$http_proxy
 export ftp_proxy=$http_proxy
 export rsync_proxy=$http_proxy
 export no_proxy="localhost,,localaddress,"
Or just use all_proxy environment variable.
Possible values illustrated here:
export all_proxy=socks5:// #1080 is the default port for SOCKS5
export all_proxy= #
export all_proxy=socks5:// #via local tor
You can put it to the following files:~/.bash_profile (per-user) or /etc/environment (system-wild),
or just copy-paste it in run-time to the terminal (per bash instance / per terminal tab) when need it.

To cancel it in run-time invoke (per bash instance / per terminal tab):
unset http_proxy https_proxy ftp_proxy rsync_proxy no_proxy  all_proxy
Note that not all apps support this environment variables.
Also note that some applications may not understand the all_proxy environment variable,
but will understand some of http_proxy, https_proxy, ftp_proxy or rsync_proxy environment variables instead.
Also note that some applications may not understand the socks5:// or https:// scheme / protocol,
in any of the http_proxy, https_proxy, ftp_proxy, rsync_proxy, no_proxy or all_proxy environment variables.
It is better to try all_proxy environment variable together with (not instead of) other environment variables with the same scheme / protocol.
If some of the environment variable and scheme / protocol combination don't work - use tunneling (see above).

Tips how to setup proxy for various software

Firefox You can set SOCKS5 or any other type of proxy here, apart of the system proxy settings.
openvpn Use socks-proxy 6876 to setup the use of the SOCKS5 proxy.
  1. You can use https_proxy= with chef_server_url starting with 'httpS://...'.
  2. 'knife' / 'berks' utility failed to use sock5:// proxy scheme / protocol.
  3. For 'knife' / 'berks' all_proxy= environment variable is more prior than http_proxy= and https_proxy= env. variables (this is poor app design),
  4. I suggest to put into ~/.bash_profile:
    export all_proxy=socks5://
    alias knife="https_proxy= knife"
    berks knife="https_proxy= berks"
knife bootstrap Use knife bootstrap --bootstrap-proxy= ....
Also you have to setup ProxyCommand= for ssh (see above).
git Use git config --global --set http.proxy http://my.corp.proxy:8080..
Also you may need (in case of use ssh to access git repos) to setup ProxyCommand= for ssh (see above).
Thunderbird e-mail program To set porxy go to: Edit -> Properties -> Advanced -> Network & Disk space -> Connection -> Settings.
curl curl --preproxy 'socks5://' ....
apt echo 'Acquire::http::Proxy "";' > /etc/apt/apt.conf.d/01proxy .
apt-key apt-key adv --recv .. --keyserver-options http-proxy=