Introduction

In order to understand the problem that the solution documented below seeks to solve, some background about my setup will help.

Here is a simplified diagram of my home LAN:

("ext. client" and "int. client" represent web clients or SSH clients or mail clients on the external internet and on the internal home LAN respectively.)

I use the BIND DNS server to avoid having to manage /etc/hosts on several (virtual) servers.

I have a Netgear DG834GTB integrated DSL modem, router and WLAN access point. This device can perform network address translation (NAT). This means that connections coming from the internet to the device on port 80 can be redirected to my webserver, connections coming from the internet to the device on port 22 can be redirected to my SSH server, etc. And here is a screenshot of the router's firewall configuration page:

I use the "No-IP Free" service provided by No-IP to cope with the regularly changing IP address allocated to my router by my ISP Alice.

All of this means that external clients can use the externally usable name (dione.no-ip.org) to connect to internal servers (e.g. they can use http://dione.no-ip.org to access the internal webserver).

More specifically, it means that external users can use the externally usable name (dione.no-ip.org) to connect to different internal servers depending on which port they connect to (e.g. they can use http://dione.no-ip.org to access the internal webserver and use imap://dione.no-ip.org/INBOX to access the internal mailserver).

Unfortunately, the router applies NAT only to connections coming from the internet; it does not apply it to connections coming from the home network, regardless of to which of the router's two NICs the connections go! Situations in which this might be a problem include:

  1. having browsed your way to one of your webserver's pages, you wish to include the URL in an email to an external user (but URL you accessed will not be valid for the external user).
  2. you have a laptop which stores configuration information relating to services provided by your servers (e.g. IMAP, SMTP, SVN) but the laptop frequently moves from the internal to the external network.

I could not find a satisfactory solution to this problem for a long time. I investigated:

  1. adding an entry to all internal client systems' /etc/hosts file, mapping the externally usable name to an internal IP address (not satisfactory because not appropriate for visitors and because not centralised)
  2. faking authority over the externally usable name's domain (no-ip.org) (not satisfactory because it becomes impossible to access other hosts in that domain (e.g. www.no-ip.org).

  3. getting BIND itself to resolve lookups of the dione.no-ip.org, but getting it to delegate, as per usual, for all other hosts in the same domain (I think it is not possible).

The procedure below, which has been tested, documents a partial workaround for this problem. It relies on forcing BIND to delegate to dnsmasq when resolving any host in the domain of the externally usable name (no-ip.org) and making dnsmasq provide the IP address for the externally usage name (dione.no-ip.org) itself, but delegate other requests to one of the official name servers for the domain. But note that dnsmasq is not aware of which port will be accessed and so can serve only one IP address for all requests. For my own setup, it makes most sense that this IP address is the IP address of the webserver.

An enhancement, which has not been tested yet, would be for dnsmasq to serve the IP address of a virtual interface (vNIC) somewhere, on which iptables rules ensure that connections coming to that vNIC on port 80 can be redirected to the webserver, connections coming to that vNIC on port 22 can be redirected to the SSH server, etc.

Finally, before explaining the procedure, here are a few keywords for google to latch on to:

accessing the outside from the inside, router, external interface, internal interface, NAT, redirect,
netgear DSL router, home LAN, internet, DNS bind dnsmasq, /etc/hosts, zone 

Procedure

This procedure assumes you already have an externally usable hostname (possible from a dynamic DNS service) and that you have configured BIND with zone authority for your home LAN. The commands below show hostnames and IP addresses specific to my own setup; you'll have to adjust them accordingly; read the introduction before doing this! All commands are to be run on your nameserver.

  1. Before starting, test that attempts to resolve the externally usable name give the externally usable IP address, by running something like:

    host dione.no-ip.org localhost
    dione.no-ip.org         A       85.181.88.83 
  2. Install the following packages and their prerequisites:
    • dnsmasq
    • host
  3. Determine the official nameservers for the domain by running something like:

    # host -t ns no-ip.org 
    no-ip.org               NS      nf1.no-ip.com 
    no-ip.org               NS      nf2.no-ip.com
    no-ip.org               NS      nf4.no-ip.com
    no-ip.org               NS      nf3.no-ip.com 
  4. Lookup the IP address of one of those nameserver by running something like:

    # host nf1.no-ip.com
    nf1.no-ip.com           A       204.16.252.8 
  5. Edit /etc/dnsmasq to contain only something like:

    no-resolv
    address=/dione.no-ip.org/192.168.1.5              #  this is the fake entry
    server=/no-ip.org/204.16.252.8                    #  other names in the same domain should use one of the official nameservers
    no-hosts                                          #  don't look up anything in /etc/hosts
    local-ttl=3600                                    #  assume faked entries valid for 1 hour
    port=55                                           #  listen on a non-standard port 
  6. Run:

    /etc/init.d/dnsmasq restart 
  7. Make BIND redirect all requests for lookups in the domain to dnsmasq by editing /etc/bind/named.conf.local and adding something like:

    zone "no-ip.org" {
        type forward;                                 
        forward only;
        forwarders { 127.0.0.1 port 55; };
    }; 
  8. Run:

    /etc/init.d/bind restart 
  9. Now you've finished, test that attempts to resolve the externally usable name give the internal IP address, by running something like:

    host dione.no-ip.org localhost
    dione.no-ip.org         A       192.168.1.5 
  10. Note that the same trick can be used for multiple services; while the DSL router can direct connections to different internal hosts based on the port number, this is not the case for lookups done on internal hosts. But by using different hostnames it can be done. So I have dione.no-ip.org and dione-mail.no-ip.org both having the same IP address and the router redirects externally initiated connections to port 80 to the webserver on my internal network and the router redirects externally initiated connections to port 25 to the mailserver on my internal network. But on the internal network these two hostnames resolve to different internal hosts - i.e. the webserver and mailserver respectively.

See also


CategoryProcedure

AccessingTheOutsideFromTheInside (last edited 2012-05-08 07:15:21 by AlexisHuxley)