Tuesday, July 5, 2016

Ubuntu - Create a wifi hotspot (access point accessible by Android devices) whose traffic is forwarded through a SOCKS proxy

The objective is to take my ubuntu laptop connected to the internet via ethernet and create a wifi hotspot (access point) that will allow an android device to connect. The hotspot will provide internet access to all connected devices.

The crucial feature is that all traffic from devices connected to the hotspot must pass through a SOCKS proxy. This means that all requests and connections from these devices seem to come from the external end of the SOCKS connection.

Although the internet is full of advice on this there is very little that works. Surprisingly the solution is actually quite simple.

The first step is to create the hotspot. On ubuntu the network-manager takes care of this with a simple modification. The steps are detailed in http://ubuntuhandbook.org/index.php/2014/09/3-ways-create-wifi-hotspot-ubuntu/. Basically create a new infrastructure mode wifi network using the network-manager and then edit a single configuration file (in /etc/NetworkManager/system-connections/) to change the mode to ap.

Once this network is enabled using the network-manager, your devices (including those running Android) will be able to connect the network and receive internet through the ethernet connection on your computer.

Step two is to create a SOCKS tunnel using ssh -D. This can be achieved using a single command on the terminal or by adding an entry in ~/.ssh/config for example:
Host <name>

    User <user>
    Hostname <host address>
    IdentityFile <full path to ssh key file>
    DynamicForward <port>
    ServerAliveInterval 60

With this configuration issuing the command ssh <name> will establish a connection the remote machine while the DynamicForward instruction will create a SOCKS5 tunnel such that any packets sent to port number <port> will be sent through the ssh tunnel. The packets will appear to come from the remote machine itself.

The SOCKS tunnel can be tested using a browser on the computer (not the hotspot yet) by setting it to use a SOCKS proxy. Point the browser at www.icanhazip.com and/or www.whoismyisp.org to check that packets are being sent over the tunnel.

The ssh socks port can interface with a browser (the latter being intelligent about it) but it won't handle raw ip traffic from the hotspot. We need a proxy that can take the traffic and send it via the ssh socks port. Enter redsocks a lightweight socks proxy. Unlike squid or polipo it is NOT a proxy server, that is, it cannot be used directly by a browser. redsocks connects to the socks port upstream and provides an incoming port where all incident traffic is sent out via the socks tunnel. Traffic is redirected to the redsocks incoming port using iptables.

Once redsocks is installed (sudo apt-get install redsocks) modify /etc/redsocks.conf. Focus on the redsocks {} section. Change local_ip to 0.0.0.0 (don't know if this is strictly necessary). local_port specifies the incoming port. I chose 12345.

Set port to the socks port set in the ssh config file and set type to socks5. Then restart redsocks (sudo service redsocks restart).

With redsocks set up we are now at the final stage and ready to redirect traffic from the wifi hotspot to through the socks tunnel. To that end we need the ip address block assigned to the hotspot. Since my hotspot works on the wlan0 interface I simply ran ifconfig wlan0 (or ip addr) to discover the address block which turned out to be 10.42.0.1/24, that is, address 10.42.0.1 and netmask 255.255.255.0.

When the network-manager creates the wifi hotspot (using the technique defined above) it creates a number of iptables rules to take care of the traffic forwarding. Since we need all traffic forwarded to the redsocks incoming port (12345) we simply delete all these rules and provided just one of our own.

    sudo iptables -F
    sudo iptables -t nat -F
    sudo iptables -t nat -A PREROUTING -s 10.42.0.0/24 -p tcp -j REDIRECT --to-ports 12345

Basically we are instructing iptables to take all packets that come from the 10.42.0.0/24 subnet and redirect it to the incoming port of redsocks which sends it over the socks ssh tunnel.

The final step is to enable ip packet forwarding in the kernel using

sudo sysctl -w net.ipv4.ip_forward=1

And we are set. On your hotspot connected device (Android phone for example) navigate to www.icanhazip.com and www.whoismyisp.org to confirm.

21 comments:

  1. Thanks! I had a setup with multiple chains and could not get it to work. I didn't know that redsocks allready does masquerading itself. I tried to masquerade the network of the hotspot with iptables and then tried to grab the packages after the masquerading to redirect them to redsocks. But this setup is so much simpler + it actually works ;)

    ReplyDelete
  2. Any thoughts on how to so similar stuff on OSX. What would be the equivlant for iptables?

    ReplyDelete
  3. I'm sorry, unfortunately I have zero experience with OSX. Stackoverflow has a few questions that seem to address this.

    ReplyDelete
    Replies
    1. Hi abid, thanks for sharing such a great tutorial.
      I have a question. Do u know how do it in windows? I need to know how can we share a socks5 proxy through a wifi hotspot in windows. There are lots of wifi hotspots like connectify available for windows but they dont share a proxy connection.
      Please help me out. I am willing to pay
      Thanks in advance
      MaE21197@gmail.com

      Delete
    2. I'm sorry, I have no experience of this (or most things) in Windows. If your need is dire enough I would recommend buying a cheap Raspberry Pi and following this tutorial on it. That is actually a more permanent solution if you need a socks5 proxy on a regular basis.

      Delete
  4. Sorry for the silly question but how do i find my ip address block?
    I tried ifconfig and found inet addr: 10.42.0.1 Bcast: 10.42.0.255 Mask: 255.255.255.0
    What is my address block?

    My 2nd: Can i use a socks5 proxy that are sold by different sites with just ip and port (for example 173.244.217.171:34507) in Step 2 Or Is ssh necessary?
    If yes then how?

    Please answer my questions in detail.
    Thanks in advance

    ReplyDelete
    Replies
    1. With the address and netmask you specified your ip address block would be 10.42.0.1/24. I have no experience with using a commercial socks5 proxy but I don't see any reason why it shouldn't work. Simply use the commercial server's ip address and port in the redsocks config.

      Delete
    2. Thanks, it worked :)

      I have one more question. How to resolve dns through proxy using redsocks? because when i go to ipleak.net or whoer.com it shows my isp dns. How can i resolve hostnames through proxy? (the proxy has dns with ability to resolve dns and i checked it with proxifier)

      Delete
    3. Are you navigating to "ipleak.net" from your PC (that is running redsocks) or your phone? Only devices on the 10.42.0.1/24 block (other than the PC) have traffic redirected over redsocks. For the PC itself the browser can easily be set to use the socks proxy directly.

      Delete
    4. I m navigating ipleak.net from my phone thats connected to hotspot. The ip shows up from the proxy but the dns is from my isp. Does redsocks have the ability to resolve dns through proxy? if yes then how can we do it?

      Thanks in advance

      Delete
    5. Redsocks can only forward TCP based dns requests over the socks5 tunnel. It implements a fake dns resolver to send truncated responses to UDP requests to force the client to switch to TCP. Not all dns clients support this.

      Take a look at http://darkk.net.ru/redsocks/ for details.

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Seems to work, have to test it out on monday... thank you for the instructions! Like you said, not much good info to find on this topic.

    ReplyDelete
  7. Hello,
    I use ethernet for internet on which I need to use proxy (provided by collage to access internet which is 172.30.0.13:3128). Now I created a hotspot . Now any device connected to hotspot also need to configure proxy setting. I want to eliminate that by redirecting all request from all client to that proxy server how to do that.
    I tried this which is not seems to be working.
    sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -i wlp2s0 -j DNAT --to 172.30.0.13:3128

    ReplyDelete
    Replies
    1. Unfortunately I am a novice when it comes to iptables so I can't be of much help. Apologies.

      Delete
  8. Good afternoon, can I use this tutorial on xubuntu 16.04?

    ReplyDelete
    Replies
    1. I am not entirely sure, but I don't see why not. Please leave a comment about your attempt. Thanks.

      Delete
  9. Why do you need to flush the iptable before adding the new rules? Wouldn't that remove other rules (besides the ones related to the hotspot)?

    ReplyDelete
  10. It does remove other rules but I found that both my laptop and the hotspot tunneled through the socks proxy kept working with the updated iptables. Feel free to list the rules and delete them one by one to see if you can find a maximal set that works.

    ReplyDelete
  11. it say connection refused on my phones every sites excepted google

    ReplyDelete
    Replies
    1. Which phone are you using, specifically which OS (and version) is it running?

      Delete