Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why my script follows /etc/hosts but the browsers do not, when there is a SOCKS proxy?

My MacBook in office does not have internet access. So I set up an instant SOCKS Proxy over SSH to access stackoverflow. I mainly use my MacBook for development so I rely on /etc/hosts and virtual hosts to test some sites locally.

However, when I try to add an entry to /etc/hosts, the browser does not go to the site I expected ...

My MacBook's WIFI is off and is connected to the company LAN:

 IP address:  192.168.8.250
 Subnet mask: 255.255.255.0
 Router:      192.168.8.1
 DNS server:  8.8.8.8

Be default, there is not internet access.

There a Linux development box (192.168.12.128) which has access to the internet, so I set up an instant SOCKS proxy to gain internet access for my MacBook:

 ssh -fND localhost:30000 [email protected]

Then in my MacBook's System Preferences > Network > Proxies

 (Enable) SOCKS Proxy
 SOCKS Proxy sever: 127.0.0.1:30000
 Bypass proxy settings for these Hosts & Domains:
   *.local, 169.254/16, 127.0.0.1

Now I can surf the web, so far so good.

For development, I set up a few entries in /etc/hosts for virtual hosts purpose:

 127.0.0.1 air.company.com

In bash:

 $ ping air.company.com
 PING air.ohho.es (127.0.0.1): 56 data bytes
 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.046 ms

 $ curl air.company.com
 <html>OK</html>

It looks good and curl returns the content of the index.html nicely.

However, if I try to open the site:http://air.company.com in the browsers (Safari/Chrome/Firefox), none of them returns the result like curl did. Chrome give an error:

This webpage is not available The webpage at http://air.company.com/ might be temporarily down or it may have moved permanently to a new web address. Error 120 (net::ERR_SOCKS_CONNECTION_FAILED): Unknown error.

If I add another entry in /etc/hosts:

 127.0.0.1 www.microsoft.com

In bash, it looks OK:

 $ ping www.microsoft.com
 PING www.microsoft.com (127.0.0.1): 56 data bytes
 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.047 ms
 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.128 ms
 ^C
 --- www.microsoft.com ping statistics ---
 2 packets transmitted, 2 packets received, 0.0% packet loss
 round-trip min/avg/max/stddev = 0.047/0.087/0.128/0.041 ms

 $ curl www.microsoft.com
 <html>OK</html>

I also try using ruby script:

 require 'socket'
 require 'curl'

 ip = IPSocket.getaddress('www.microsoft.com')
 puts ip

 puts

 http = Curl.get("http://www.microsoft.com/")
 puts http.body_str

The output looks OK:

 $ bundle exec ruby openweb.rb 
 127.0.0.1

 <html>OK</html>

However, when I use the browsers, the browsers return the content from the web server of the real Microsoft site, instead of the content from my MacBook (127.0.01). Why?

p.s.:

If I disable the SOCKS proxy, the browser returns the content from 127.0.0.1 correctly.

If I disconnect the LAN cable, the browser returns the content from 127.0.0.1 correctly.

like image 297
ohho Avatar asked Jun 19 '13 07:06

ohho


3 Answers

SOCKS5 will do DNS look-ups remotely; this is a good thing for security.

I think what you want is to instruct your browser not to use the proxy for internal or your custom development addresses.

To do that, set your "Bypass proxy settings for these Hosts & Domains:" to include *.company.com. If you have particularly complex settings, you can set up a proxy access control (aka .pac) file that allows very granular control of what goes over the proxy and what is accessed directly.

like image 162
Emil Sit Avatar answered Nov 27 '22 19:11

Emil Sit


I will try to answer it at my best, as I already had this problem.

When you are using a Socks5 connection, your ip resolution is forwarded to the socks server.

At the version 5 the SOCKS implementation may receive full domain names as the destination and source addresses[1] (page 4).

On the Mac OS the default is SOCKS 5 as indicated in [2] at (NSStreamSOCKSProxyVersionKey).

So by default the mac client will use SOCKS5 and WILL forward the DNS requests.

I hope this answer your question: "Why my script follows /etc/hosts but the browsers do not, when there is a SOCKS proxy?" --> because the SOCKS5 implementation forward dns requests :)

With Regards

1 - http://www.ietf.org/rfc/rfc1928.txt

2 - https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSStream_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSStreamSOCKSProxyConfigurationKey

like image 38
Carlos Henrique Cano Avatar answered Nov 27 '22 18:11

Carlos Henrique Cano


With SOCKSv4a and SOCKSv5 clients are actually able to have the server connect to a domain name, not only to an address (http://en.wikipedia.org/wiki/SOCKS#SOCKS4a).

                                                      ----------
                                                      -   DNS  -
                                                      ┐---------
                                                     .
                                                    .
----------------                   ----------------.-
-              ====================-                -
- Browser      = CON microsoft.com - SOCKS Server   -
-              ====================-                -
----------------                   ------------------

And since the SOCKS server has internet access, you can see the site of Microsoft, and not your local version.


Ideas:

  • If you are able to change the version of the SOCKS protocol to version 4, it should work.
  • Probably better in the long run: Disable remote DNS in the browser, at least Firefox supports this setting: Network.proxy.socks.remote_dns.
like image 44
thriqon Avatar answered Nov 27 '22 19:11

thriqon