• 2009-06-17

    Making SOCKS proxy transparent - [UNIX/LINUX]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://joshuafan.blogbus.com/logs/41143488.html

    If we have a limited connectivity to the world from current location, but still can connect to a shell account fully open to the world (or open to the other non-public network), than dynamic port forwarding available in ssh can save us. This feature (accessible by -D option) in fact makes ssh acting as SOCKS server. OK, but what can we do if our application doesn't support SOCKS proxy? It's important question, because vast majority of software is unaware of such protocol. In Linux we have a great tsocks (http://tsocks.sourceforge.net/), shell wrapper which transparently allow an application to use SOCKS proxy. In Windows there is FreeCap (http://www.freecap.ru/eng/), which does the same thing, but in a different way. Nice, but what if we have dozens of machines to set up. Teaching all users how to use any of mentioned application can be also really inconvenient. Making SOCKS proxy transparent will solve (almost?) all our problems. Is it feasible? YES, but you must have an access to superuser account on a gateway server (it can be also any other server, but gateway is used here for simplicity).

    I'm assuming that you already have SOCKS server bound to localhost on standard port 1080 (e.g. you started ssh with -D1080).

    1. Install libevent (http://www.monkey.org/~provos/libevent/). It can be already available in your distribution repository. This will be used for compiling in next step, so you must get development package (usually libevent-dev).
    2. Download transocks_ev (http://oss.tiggerswelt.net/transocks_ev/ - use svn or simply wget files) and build it using make.
    3. Run transocks_ev with following arguments: -p 12345 -H localhost -s 1080 -S localhost. -H tells where to bind transocks_ev, -p where to listen for incoming connections, -s and -S point SOCKS server.
    4. Change iptables configuration. This step requires superuser powers. Below you have example script (heavily based on tranSOCKS_ev's README) with some common alternatives:
      #!/bin/sh
       
      IPTABLES="/sbin/iptables"
       
      TRANSOCKS_PORT="12345"
      SOCKS_HOST="192.168.0.1"
      SOCKS_PORT="1080"

      # Create our own chain
      $IPTABLES -t nat -N TRANSOCKS 
      # Do not try to redirect local traffic
      $IPTABLES -t nat -I TRANSOCKS -o lo -j RETURN  
      # Do not redirect LAN traffic and some other reserved addresses.
      $IPTABLES -t nat -A TRANSOCKS -d 0.0.0.0/8 -j RETURN $IPTABLES -t nat -A TRANSOCKS -d 10.0.0.0/8 -j RETURN
      $IPTABLES -t nat -A TRANSOCKS -d 127.0.0.0/8 -j RETURN
      $IPTABLES -t nat -A TRANSOCKS -d 169.254.0.0/16 -j RETURN
      $IPTABLES -t nat -A TRANSOCKS -d 172.16.0.0/12 -j RETURN
      $IPTABLES -t nat -A TRANSOCKS -d 192.168.0.0/16 -j RETURN
      $IPTABLES -t nat -A TRANSOCKS -d 224.0.0.0/4 -j RETURN
      $IPTABLES -t nat -A TRANSOCKS -d 240.0.0.0/4 -j RETURN  
      # Do not redirect traffic for the SOCKS server (not needed if server is already excluded by above rules)
      $IPTABLES -t nat -I TRANSOCKS -p tcp -d $SOCKS_HOST --dport $SOCKS_PORT -j RETURN  
      ## Redirect only specified addresses.
      #$IPTABLES -t nat -A TRANSOCKS -m iprange ! --dst-range 123.45.6.78-123.45.6.90 -j RETURN 
      # Redirect all traffic that gets to the end of our chain
      $IPTABLES -t nat -A TRANSOCKS -p tcp -j REDIRECT --to-port $TRANSOCKS_PORT  
      # Filter (i.e. just branch into the TRANSOCKS-chain) all traffic that is routed over this host
      $IPTABLES -t nat -A PREROUTING -j TRANSOCKS  
      ## Filter all traffic from the own host (BE CAREFUL HERE IF THE SOCKS SERVER RUNS ON THIS MACHINE!)
      #$IPTABLES -t nat -A OUTPUT -j TRANSOCKS
    5. Now all hosts with your machine as a gateway use SOCKS proxy accordingly to iptables rules. Transparently!
    6. Open another beer bottle and enjoy. 8-)

    收藏到:Del.icio.us