Running DNS Server to circumvent NAT-Loopback issue

First I want to say that I probably read everything that there is on the internet regarding the problem.

And the problem is that I can not access my owncloud over doc.selfhost.eu if I am in the same network. But I can access it from inside the network over its internal IP (192.168.2.200) and from outside the network over doc.selfhost.eu.

My setup: A home server running Linux Mint 17.2 Cinnamon which is supposed to be for media and to run owncloud.

The server is connected to a Speedport 723v which doesn't support NAT Loopback. Ports 80 and 443 are forwarded and for dynamic DNS I have an account on selfhost.de which I entered in the router settings.

On my Windows 7 machine (which I'm trying to access the server from) I entered 192.168.2.200 (the servers internal IP) as DNS.

In Mint I disabled network manager (in fact I removed it) and I am now using interfaces.

Not a solution would be to change the hosts files of all the clients (on unrooted androids this isn't even possible).

Question:

  1. What would I have to change to access my owncloud from the internal network over the external IP?

/etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.2.200
netmask 255.255.255.0
gateway 192.168.2.1
dns-nameservers doc.selfhost.eu 8.8.8.8

/etc/resolv.conf

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.0.1

In /etc/dnsmasq.conf this is the only thing I added:

listen-address=127.0.0.1
listen-address=192.168.2.200
address=/doc.selfhost.eu/192.168.2.200

/etc/dnsmasq.d/doc.selfhost.eu (read somewhere to create this)

address=/doc.selfhost.eu/192.168.2.200

/etc/hosts

127.0.0.1       localhost
127.0.1.1       doc-desktop
192.168.2.200   doc.selfhost.eu

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Owncloud settings in /var/www/owncloud/config/config.php

'trusted_domains' =>
  array (
0 => '192.168.2.200',
1 => 'doc.selfhost.eu',
  );

Apache configuration In /etc/apache2/apache2.conf everything is pretty standard. I only added:

ServerName doc-desktop

/etc/apache2/sites-enabled/owncloud.conf. No changes in sites-available, no linking.

<VirtualHost 192.168.2.200:80>

#### Redirect to port 443 ###
RewriteEngine on
ReWriteCond %{SERVER_PORT} !^443$
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
#### End of Redirection configuration ###

DocumentRoot /var/www/owncloud/
<Directory /var/www/owncloud>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
</Directory>

</VirtualHost>

<VirtualHost 192.168.2.200:443>
####Configuration for SSL #####
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.crt
SSLCertificateKeyFile /etc/apache2/ssl/apache.key
#### End of SSL Configuration ####
Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
DocumentRoot /var/www/owncloud/
<Directory /var/www/owncloud>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
</Directory>
</VirtualHost>

In case it comes up. from server:

dig doc.selfhost.eu

; <<>> DiG 9.9.5-3ubuntu0.5-Ubuntu <<>> doc.selfhost.eu
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49046
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;doc.selfhost.eu.          IN      A

;; ANSWER SECTION:
doc.selfhost.eu.   0       IN      A       192.168.2.200

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Oct 26 02:35:15 CET 2015
;; MSG SIZE  rcvd: 54

From client inside network (with cygwin):

dig doc.selfhost.eu

; <<>> DiG 9.10.3 <<>> doc.selfhost.eu
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29482
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;doc.selfhost.eu.          IN      A

;; ANSWER SECTION:
doc.selfhost.eu.   0       IN      A       192.168.2.200

;; Query time: 31 msec
;; SERVER: 192.168.2.200#53(192.168.2.200)
;; WHEN: Mon Oct 26 02:37:32     2015
;; MSG SIZE  rcvd: 54

I hope this is everything. Thanks.

This question comes from here since it was off-topic:

https://stackoverflow.com/questions/33337258/running-dns-server-to-circumvent-nat-loopback-issue


External Solutions

What would I have to change to access my owncloud from the internal network over the external IP?

Unfortunately, having never personally encountered a home router that didn't support NAT Loopback (also known as hairpinning), I can't provide a concrete answer on how to access it with anything external.

Other Solutions

  • You may want to look further into Split-horizon DNS or using PFSense NAT Reflection as suggested in this Super User question.

  • You may also want to look at this supported list of NAT Loopback supported routers from OpenSimulator.org if you decide to buy a new one.

  • It may also be possible to upgrade to custom firmware e.g. Tomato or DD-WRT, but I would investigate this process thoroughly before attempting anything.


A DNS-based Solution

Assuming your goal isn't more complicated than accessing your media server from the internal network with a human-readable domain and you are willing to configure BIND DNS, you can try to make a pseudo-domain available to your network as well.

This pseudo-domain would potentially allow you to access your local server at something like server.own on the internal network. This fake Top Level Domain (TLD) ex. .own can essentially be anything you want.

I would suspect this should work even with the NAT Loopback issue.

Using a Pseudo-domain

The simplest arrangement is to have one computer on the network provide DNS. The biggest potential drawbacks to this arrangement are:

  • You will likely need to make sure that your router is pointing to the server running BIND.

  • The computer serving as your DNS server will need to be on for this (and your net connection) to work.

Router DNS Entries Pointing To Local DNS Server

Also, while likely less important in this case, running a BIND service that provides access to both internal and external networks can be somewhat risky. Generally, you should not mimic a public TLD like .eu unless you know what you are doing. If you want to keep the doc.selfhost prefix rather than something else, that's fine, but you should pick a different unused extension (e.g. doc.selfhost.own).

Apache and Owncloud

Once enabled, you will need to set up Apache (your pseudo-domain will likely be a VirtualHost) and Owncloud to properly respond to queries and serve the appropriate content (e.g. Owncloud).

Working Examples

Below are some working examples of how to configure the main files in BIND to provide pseudo-domain services.

Note that I am not covering all of what you might need to do to get BIND itself working, so there may be some extra steps not explicitly mentioned here. Also note, these examples are technically for recent versions of BIND 9 on Windows (BIND 9.10+).

The actual contents of db.rev.10.txt and db.example.own.txt shouldn't need modification between Windows and *nix. The bigger obstacle is making sure the named.conf entries appear in the right files on non-Windows platforms and that db.rev.10.txt and db.example.own.txt appear in the correct *nix directories.


Note that when using Redhat-based distros, there are subtle differences between them and Debian/Ubuntu/Mint.


Assuming you are okay with all of this, here are the basic working examples. This is essentially a caching DNS configuration, if it matters.

  1. Get BIND set up and working. I'll wait. =)

  2. named.conf — Edit named.conf. (roughly) as given below. On Windows, all entries are in "named.conf" (located in the BIND "etc" directory). On modern *nix, these entries are often split over several files. Also make sure to include any proper "rndc-key" and "control" entries as needed.

    ex. named.conf

     # Our basic options -- where do we find our zone files, etc.?
     # On *nix, options likely need to go in "named.conf.options"
    
     options {
         directory "Path\to\zones";      # On *nix it's / not \ of course
         allow-transfer { none; };       # disable zone transfers by default
    
         # We restrict access to recursion to avoid security issues, etc.
         # You can change IPs as required.
         #allow-recursion {192.168.1.0/24;}; 
    
         # "localnets" is a special ACL in BIND
         allow-recursion {"localnets";};
    
         # We are using named.root, so forwarders are disabled.
         # forwarders { 8.8.8.8; 8.8.4.4; };
     };
    
     # Current versions of named.root/db.cache -- ftp://ftp.internic.net/domain/
     # *nix likely uses named.root (Redhat/Fedora) or db.cache (Deb/Ubu/Mint) 
     # This file does need periodic updating (perhaps twice a year)
    
     zone "." {
         type hint;
         file "named.root";      # On Windows, place in your BIND "zone" directory
     };
    
     # Local domain where "example.own" is whatever domain you want
     # On *nix, these zone definitions likely need to go in "named.conf.local"
    
     zone "example.own" IN {
         type master;
         file "db.example.own.txt";   # On Windows, place in your BIND "zone" directory
         allow-transfer { none; };
     }; 
    
     # Local loopback interface so our local domains work
     # The digits are the local lan prefix in reverse
     # Note that /16 subnets use only two digits e.g. 128.10 for 10.128.xxx.xxx
    
     zone "0.0.10.in-addr.arpa" IN {
           type master;
           file "db.rev.10.txt";     # On Windows, place in your BIND "zone" directory
           allow-transfer { none; };
     };
    
     # ### Any "rndc-key" and "control" statements go here ### 
    
     # End of named.conf
    
  3. db.rev.10.txt — Our Reverse zone file. Add PTR records for each physical server referenced in your Forward zone file (e.g. db.example.own.txt). In this example, we are assuming as single media server at 10.0.0.3 we wish to call example.own.

    ex. db.rev.10.txt

     ; BIND reverse data file for a local loopback interface
     ; The domain used should be a listed 'zone' in named.conf 
    
     $TTL 86400                ; Default TTL
     @   IN SOA  example.own.    admin.example.own. (
                  2015071301      ; serial
                  10800           ; Refresh period
                  3600            ; Retry interval
                  604800          ; Expire time
                  86400 )         ; Negative caching TTL
    
     ; The number before PTR is the last octet of the IP address
     ; for the device to map (e.g. 10.0.0.3). For /16 subnets,
     ; this is the last two digits e.g. "8.9" for "128.10.in-addr.arpa" (10.128.9.8)
    
         IN  NS  ns1.example.own.
         IN  NS  ns2.example.own.
     3   IN  PTR example.own.
    
  4. db.example.own.txt -- Our Forward zone file. In this example, we are assuming as single media server at 10.0.0.3 we wish to call example.own. You can add MX and CNAMEs as well, of course. If you add additional servers (e.g. media IN A 10.0.0.4), add the appropriate PTR record to your Reverse zone as well (e.g. db.rev.10.txt4 IN PTR media.example.own)

    ex. db.example.own.txt

     ; We are using our reverse DNS to provide name server services
     ; Enables use of http://(www).example.own on our local network
    
     $TTL 86400              ; Default TTL
     @   IN SOA  ns1.example.own.    admin.example.own. (
                 2015071322  ; serial
                 10800       ; Refresh period
                 3600        ; Retry interval
                 604800      ; Expire time
                 86400 )     ; Negative caching TTL
    
     @       NS  ns1.example.own.
    
     ns1             IN A        10.0.0.3        ; This entry is ABSOLUTELY NECESSARY - Use an IP
     ns2             IN A        10.0.0.3        ; Secondary Name Server Prefix/IP (Required 2nd Name Server - backup - IP or domain)
    
     example.own.    IN A        10.0.0.3        ; A Record for the basic domain name
     www             IN A        10.0.0.3        ; A Record for the www prefix
    

Odds and Ends

  • Make sure to update the Serial on both your Forward and Reverse zones each time you make changes to them.

  • Likewise, make sure to "reload" bind after making ANY changes to you BIND config files. As a general thought, you probably want to back any originals up as well before tinkering.

  • Assuming everything is set up correctly, every capable device (including Android) on the network should be able to access example.own without further configuration (i.e. like the regular net).

  • Note that that if you are using Chrome, you need to append a trailing slash in the address bar (e.g. example.own/), otherwise you may be redirected to Google search. This requirement will likely not be changed in any future versions.

  • While for more traditional setups, these two articles for Ubuntu and Centos 7 (Redhat) illustrate some of the differences in configuring BIND between the two.