Skip to content

Instantly share code, notes, and snippets.

@janl
Last active November 3, 2015 15:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janl/fa8379fbd890282205e7 to your computer and use it in GitHub Desktop.
Save janl/fa8379fbd890282205e7 to your computer and use it in GitHub Desktop.

I have a service running on a LAN that are also exposed over the WAN, say Service A is reachable under example.com and it’s running on Host A in the LAN. The way this is implemented is port forwarding in the WAN gateway in the LAN:

public_ip:80 -> host_a_ip:80

Now I have a laptop that is often in the LAN, but not always. When that laptop is in the LAN, it can’t reach example.com, because the gateway port forwarding doesn’t work for internal requests (and their is no option to add/enable this). I also can’t replace the gateway router. So when that laptop wants to access example.com while in the LAN, it has to use the internal LAN ip of Host A.

Rest assured this is annoying. How can I make it, so the laptop can reach example.com regardless of whether it is in the LAN or not?

Options:

  1. DNS trickery: Make example.com resolve to the local ip instead of the remote one. How do I set that up for Mac OS X? Would prefer not to have to set up my own DNS server, but would if it helped.

  2. IP routing trickery on the laptop. No idea how to do this, and how to make it transparently on/off depending on the wifi.

  3. While writing this, I could make another box on the LAN the gateway for everything in the LAN which in turn then only uses the WAN router. Then I’d have more control over ip forwarding shenanigans. Then I just need to figure out how to make the gateway configuration depending on whether the client is on the LAN.

But I’d still like to know if there is a simpler option.

@JakubOboza
Copy link

this might not be smart but you could enter example.com into /etc/hosts to point to your own box and add a sinatra/nginx proxy on some port on your box like eg. 6789 that will handle passing the request in right way to ip or host depending on what is reachable. Pretty bruteforce but might be solution.

You would need: (/etc/hosts)
127.0.0.1 example.com
Nginx locally to grab the request and proxy to handle the requests. Probably you can't sort this out on solo nignx.

@janl
Copy link
Author

janl commented Nov 2, 2015

@JakubOboza: how do I dynamically update /etc/hosts based on when I’m in the LAN or not?

@janl
Copy link
Author

janl commented Nov 2, 2015

One more complication: the laptop is in the LAN sometimes wired and sometimes wired, and moving back and forth.

@lsferreira42
Copy link

I think ngrok secure tunnels can help you with that!
https://ngrok.com/

@maxheadroom
Copy link

I assume that splitting the view of the DNS zone into internal and external is not an option? In theory the authoritative DNS server for example.com could be configured for different answers depending on the source IP of the requesting client.
This would even work if you don't really own the resolving DNS server. But you'd have to setup a DNS server inside your LAN and make this your default DNS resolver for the LAN (does not need to be on your Laptop). You would then override the example.com zone with your local LAN settings. All other requests would be just forwarded to the normal DNS resolvers. This could be for instance a RaspberryPI running a BIND. This solution would work for all your LAN members.

@klaemo
Copy link

klaemo commented Nov 2, 2015

You could install dnsmasq on the service host (or any other server on the LAN), configure it to respond to DNS queries for example.com and forward all other DNS queries to the WAN router.
Then point the laptop's DNS to the service host IP.
dnsmasq is easy to configure. Also, you get local DNS caching for free, if you want :)

@nemzes
Copy link

nemzes commented Nov 2, 2015

You can use ControlPlane to detect the on/off LAN changes. It's a little tedious to set up, but once you have it working you can run scripts when you enter/leave a certain context. With that, I'd have two simple scripts:

enter_lan.sh:

#!/bin/bash
sed -i -e 's/^# (.*)( # LAN)$/\\1\\2/g' /etc/hosts

leave_lan.sh:

#!/bin/bash
sed -i -e 's/^([^#].*)( # LAN)$/# \\1\\2/g' /etc/hosts

Then you can just put entries like these in your hosts file:

#127.0.0.1 example.com # LAN

Adjust regexes as needed. I haven't tested it fully. You probably need to make /etc/hosts R/W for all.

@janl
Copy link
Author

janl commented Nov 2, 2015

@maxheadroom yeah, custom DNS is likely an option, would try to avoid tho.

@leandrosferreira Ah nice, using an external bounce host could totally do the trick, I’ll look into that :)

@klaemo that sounds simple, just gotta check if I can make the DNS config dependent on the LAN I’m in.

@janl
Copy link
Author

janl commented Nov 2, 2015

@nelsonmenezes thanks, I’ll check that out! :)

@deveth0
Copy link

deveth0 commented Nov 2, 2015

Probably you can simply use the dns server on your router for this? Best and cleanest solution. Also most likely the one which will result in least errors.

@djc
Copy link

djc commented Nov 2, 2015

We used dnsmasq in a similar situation.

@janl
Copy link
Author

janl commented Nov 2, 2015

@deveth0 — router has no dns, can’t get a new router

@janl
Copy link
Author

janl commented Nov 2, 2015

@djc thanks!

@andrenarchy
Copy link

@janl I'd go with the dnsmasq-based solution proposed by @klaemo. Seems like you can specify DNS servers for locations in OSX; see here.

@maxheadroom
Copy link

@janl the solution with dnsmasq which @klaemo described is pretty much the same that I proposed with the custom DNS setup. The MacOS supports these settings with the different "Location" under network settings. There you could define a profile with DHCP but fixed DNS Server for your LAN. Then the only thing you'd need to do is switch to that network location profile whenever you're in the LAN. The Software "Control Plane" can help automagically detecting the network location and switch to it.

@janl
Copy link
Author

janl commented Nov 3, 2015

Thanks all, I’ve got dnsmasq running like a charm, this is awesome :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment