Wednesday, 23 September 2015

Generic UDP proxy for NodeMCU / ESP8266 - Simple LUA DNS proxy

For a project that has been in the works for quite some time, I need a ESP8266 module to act as a DNS proxy. Other than on my very popular CaptiveIntraweb project, that simply lies to all DNS requests, I need real DNS lookups this time.

Getting my head slowly around the event driven nature of NodeMCU, the code turned into a very compact, generic UDP proxy or forwarder.
The script is completely unaware of the structure of the data and could be used to proxy all sorts of UDP data.

Here is my code:

 -- Simple DNS Proxy  
 -- 20150923 by Andy Reischle  
 -- Blog: www.AReResearch.net  
 -- Vids: www.youtube.com/AReResearch  
 --  
 -- Uses googles dns server 8.8.8.8  
 -- change to whatever suits you  
 cu=net.createConnection(net.UDP,0)  
 cu:on("receive",function(cu,c)   
   -- print("Got a reply")  
   s:send(c)  
   end)  
 s=net.createServer(net.UDP)  
 s:on("receive",function(s,d)  
   -- print ("Got a request!")  
   cu:connect(53,"8.8.8.8")  
   cu:send(d)   
   end)  
 s:listen(53)  

The ESP-module is connected to a WiFi AP, of course. The IP address of the ESP module is 192.168.1.74 and will be different, depending on your home DHCP server.

I can query DNS information through the module now:
me@raspberrypi:~$ nslookup
> server 192.168.1.74
Default server: 192.168.1.74
Address: 192.168.1.74#53
> www.areresearch.net
Server:         192.168.1.74
Address:        192.168.1.74#53

Non-authoritative answer:
www.areresearch.net     canonical name = ghs.google.com.
ghs.google.com  canonical name = ghs.l.google.com.
Name:   ghs.l.google.com
Address: 173.194.65.121
>
The corresponding tcpdump also looks very clean:

me@raspberrypi:~$ sudo tcpdump -i eth0 port 53
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
23:39:08.416736 IP noname.43027 > noname.domain: 56537+ A? www.areresearch.net. (37)
23:39:08.422009 IP noname.46122 > fritz.box.domain: 4560+ PTR? 58.1.168.192.in-addr.arpa. (43)
23:39:08.426857 IP fritz.box.domain > noname.46122: 4560* 1/0/0 PTR noname. (88)
23:39:08.428198 IP noname.45680 > fritz.box.domain: 56651+ PTR? 74.1.168.192.in-addr.arpa. (43)
23:39:08.430620 IP fritz.box.domain > noname.45680: 56651* 1/0/0 PTR noname. (88)
23:39:08.432969 IP noname.38314 > fritz.box.domain: 15794+ PTR? 1.1.168.192.in-addr.arpa. (42)
23:39:08.435987 IP fritz.box.domain > noname.38314: 15794* 1/0/0 PTR fritz.box. (89)
23:39:08.480105 IP noname.domain > noname.43027: 56537 3/0/0 CNAME ghs.google.com., CNAME ghs.l.google.com., A 173.194.65.121 (101)

While the rest of the project still requires a lot of tinkering, this little piece of the puzzle works nicely.


11 comments:

  1. look likes very good. did you tried basic http request on client side? is esp8266 forwarding and answering packets?

    ReplyDelete
    Replies
    1. No luck yet. I ruled out power problems, but the disconnects still persist.

      Delete
  2. Yes I did try that but the module always disconnected from the downstream WiFi router. I had a ticket open with the NodeMCU develpers. They think it might be a power issue. This is possible, but I haven't had the time to fully verify yet.
    I'll keep inventigating the problem.

    ReplyDelete
    Replies
    1. This could caused by big packet since NodeMCU easily panic on such event

      Delete
    2. Yes, this matches what I've seen happening when using NodeMCU as a router/range-extender.
      If I find the time, I'll build it from newer source/sdk. Last time I tried, I ran into an SPIFFS bug, which is very annoying when storing large files. But that should be resolved by now.

      Delete
  3. Hi Andreas, I just got this to work, and I was even able to stream netflix through the ESP. I didn't notice any disconnection issues, not at wifi level and not on socket level.

    ReplyDelete
    Replies
    1. hello daniel salazar, please can you share how you can do it?
      i have a project but honestly it is confuse me because i am a newbie, please reply. thanks you.

      i am using wemos d1 r2 in windows by the way, hope you care to help me, please.

      Delete
  4. Hi just of curiosity is it possible to use nodemcu as wifi adapter for pc/mac.

    ReplyDelete
    Replies
    1. To my knowledge no-one has been crazy enough to write a driver. If I had to connect a PC to the Internet through a, ESP8266, I'd probably try an implementation of SLIP (Serial Line Internet Protocol) on the ESP.

      Delete
    2. There is now a SLIP implementation for the ESP available here:
      https://github.com/jeelabs/esp-link

      Delete
  5. Thank you for sharing such a concise and clear concept of the example code.
    Richard Brown idealsvdr

    ReplyDelete