How do I configure DNS when sharing a VPN connection in linux?

2

I'm using a Linux computer (raspberry pi) to share a VPN connection over ethernet. I want the raspberry pi to connect to the internet normally (not over the VPN). I'm very close to getting it working, but I don't know how to configure the DNS for the eth1 network.

Connection to the internet: eth0 192.168.11.21/24, gateway 192.168.11.1
vpn connection: tun0 <- openvpn connection
vpn sharing network: eth1 192.168.5.1/24 <- this maching is the gatway for the vpn sharing network

eth1 config:

eth1: /etc/network/interface
auto eth1
iface eth1 inet static
address 192.168.5.1
netmask 255.255.255.0

I have dnsmasq running as a dhcp server for eth1 (vpn sharing network)

# Configuration file for dnsmasq.
#
interface=eth1
dhcp-range=192.168.5.50,192.168.5.150,12h

vpn config

I only want traffic coming from eth1 to use the vpn. I setup the routes myself using a separate routing table.

# extract from openvpn config
route-noexec
route-up "/etc/openvpn/route-up.sh"
down "/etc/openvpn/down.sh"

# route-up.sh
/sbin/ip route add $trusted_ip/32 via $route_net_gateway table vpn
/sbin/ip route add 0.0.0.0/1 via $route_vpn_gateway table vpn
/sbin/ip route add 128.0.0.0/1 via $route_vpn_gateway table vpn

I also needed to run some commands to setup the separate routing table:

# make a new routing table called vpn
echo 200 vpn >> /etc/iproute2/rt_tables 

# add a rule to use the routing table for the addresses on eth1
ip rule add from 192.168.5.0/24 table vpn

Tying together the interfaces:

sysctl net.ipv4.ip_forward=1      
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

Testing:

I put a windows laptop on the vpn sharing network. It is able to communicate to internet addresses directly. But using domain names DNS lookup fails. I haven't found a working way to configure the DNS.

I have tried adding this to dnsmasq

server=<dns-server-address> 

I also tried adding this line under eth1 in /etc/network/interfaces

dns-nameservers <dns-server-address> 

This caused resolvconf -l to return this:

# resolv.conf from eth1.inet
# Generated by ifup for eth1.inet
nameserver <dns-server-address1>
nameserver <dns-server-address2>

but /etc/resolv.conf reimains the same:

# Generated by resolvconf
nameserver 127.0.0.1

I even tried editing /etc/resolv.conf directly. - But it's auto-updated and gets written over again almost immediately.

--edit --

My goal is to have a setup which doesn't require any specific configuration on a client on the vpn-sharing network. (I'll be attaching devices which can't be configured)

I'd also like to send DNS requests through the VPN if possible.

--edit 2--

First. I switched to testing with a linux client. Modifying resolv.conf to add my dns server gets the vpn'd internet connection working.

However - It looks like solution 5 is the one for me. Is this intercepting DNS packets and altering them to direct them to a new DNS server?

I couldn't get it working for me. I'll post my configuration here. Am I missing something?

# iptables-save
# Generated by iptables-save v1.4.21 on Fri Sep 23 16:57:46 2016
*mangle
:PREROUTING ACCEPT [51:3878]
:INPUT ACCEPT [49:3758]
:FORWARD ACCEPT [2:120]
:OUTPUT ACCEPT [30:3438]
:POSTROUTING ACCEPT [32:3558]
-A PREROUTING -p tcp -m tcp --dport 53 -j MARK --set-xmark 0x1/0xffffffff
-A PREROUTING -p udp -m udp --dport 53 -j MARK --set-xmark 0x1/0xffffffff
COMMIT
# Completed on Fri Sep 23 16:57:46 2016
# Generated by iptables-save v1.4.21 on Fri Sep 23 16:57:46 2016
*nat
:PREROUTING ACCEPT [4:337]
:INPUT ACCEPT [3:277]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i tun0 -p tcp -m tcp --dport 53 -j DNAT --to-destination 198.18.0.1
-A PREROUTING -i tun0 -p tcp -m tcp --dport 53 -j DNAT --to-destination 198.18.0.2
-A POSTROUTING -o tun0 -j MASQUERADE
COMMIT
# Completed on Fri Sep 23 16:57:46 2016
# Generated by iptables-save v1.4.21 on Fri Sep 23 16:57:46 2016
*filter
:INPUT ACCEPT [41189:45918808]
:FORWARD ACCEPT [63803:44422296]
:OUTPUT ACCEPT [33919:5341216]
COMMIT
# Completed on Fri Sep 23 16:57:46 2016

# ip route list table vpn
0.0.0.0/1 via 172.21.24.1 dev tun0 
81.171.74.16 via 192.168.11.1 dev eth0 
128.0.0.0/1 via 172.21.24.1 dev tun0 


# ip route list table main
default via 192.168.11.1 dev eth0 
default via 192.168.11.1 dev eth0  metric 202 
172.21.24.0/23 dev tun0  proto kernel  scope link  src 172.21.24.57 
192.168.5.0/24 dev eth1  proto kernel  scope link  src 192.168.5.1 
192.168.11.0/24 dev eth0  proto kernel  scope link  src 192.168.11.21 
192.168.11.0/24 dev eth0  proto kernel  scope link  src 192.168.11.21  metric 202 

# ip rule
0:  from all lookup local 
32764:  from all fwmark 0x1 lookup vpn 
32765:  from 192.168.5.0/24 lookup vpn 
32766:  from all lookup main 
32767:  from all lookup default 

# cat /etc/resolv.conf 
# Generated by resolvconf
nameserver 127.0.0.1

# On the client
# cat /etc/resolv.conf 
# Generated by resolvconf
nameserver 192.168.5.1

-- edit 3 --

# tcpdump -i tun0 -n port 53
23:44:29.787915 IP 192.168.5.1.53 > 192.168.5.128.38840: 36460 4/0/0 A 157.7.203.102, A 157.7.154.23, A 116.58.172.182, A 157.7.235.92 (101)
23:44:29.788071 IP 192.168.5.1.53 > 192.168.5.128.38840: 37999 0/0/0 (37)
23:44:30.619149 IP 192.168.5.1.53 > 192.168.5.128.58425: 3383 1/0/0 A 129.169.10.40 (47)
23:44:30.620635 IP 192.168.5.1.53 > 192.168.5.128.58425: 11649 0/1/0 (83)

Looking at this we are getting DNS responses coming back, but they are not making their way to the client (192.168.5.128). Right? Now I need to figure out how to fix that...

linux
networking
vpn
dns
dnsmasq
asked on Super User Sep 22, 2016 by pauld • edited Sep 23, 2016 by pauld

1 Answer

1

You have not clarified whether you wish the DNS servers to be specific to your Windows machine, to all of the OpenVPN clients, or perhaps even to you RPI, and whether you wish the DNS querying to go through the VPN or not.

1. Separate client (over OpenVPN) and RPI DNSes.

This is the easiest case: set the client DNSes in the client, and the RPI DNSes in /etc/resolv.conf.

2. Separate client (outside OpenVPN) and RPI DNSes.

Same as above except you will have to add the following routing rule to the RPI:

    ip route add 8.8.8.8/32 via Your.Router.IP.Address dev Your.Non.VPN.Interface table vpn

where I assumed your (Windows) client uses Google's DNS, 8.8.8.8.

3. Alternatively, you can mark DNS packets from clients, and route them thru the main routing table:

     iptables -A PREROUTING -t mangle -p tcp --dport 53 -j MARK --set-mark 1
     iptables -A PREROUTING -t mangle -p udp --dport 53 -j MARK --set-mark 1
     ip rule add from all fwmark 1 table main
     iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE

4. Same DNS servers for RPI and clients, whether over the OpenVPN or outside.

Same as bullet 1 or 2, just use the same set of DNSes.

5. Automatic setting for all OpenVPN clients, over OpenVPN obviously.

You may think that setting DNSes individually over each VPN client is tedious, especially if you need to set DNSes in the server's network, not something as easy as Google's. You will have first to push the DNS option from the server to the RPI client, by adding the follwoing stetment to the server's configuration file:

    push "dhcp-option DNS 10.66.0.4"

This option is written to a variable called foreign_option_{n}: the first option pushed this way will have n=1, and its value (in the case above) is:

    foreign_option_1="dhcp-options DNS 10.66.0.4"

This variable is automatically passed to the up script, where you will have to break it into three parts, extracting the IP address in, say $var3, and you can now add the following lines to your route-up script:

    iptables -t mangle -A PREROUTING -p tcp --dport 53 -j MARK --set-mark 1
    iptables -t mangle -A PREROUTING -p udp --dport 53 -j MARK --set-mark 1
    ip rule add  fwmark 1 table vpn
    iptables -t nat -A PREROUTING -p tcp --dport 53 -i tun0 -j DNAT --to-destination $var3
    iptables -t nat -A PREROUTING -p udp --dport 53 -i tun0 -j DNAT --to-destination $var3

To make this work, you may have to disable the reverse path filter: I am not sure because on my Arch Linux laptop I do not need to do that, while on my Debian workstation I do. So, I am a little befuddled, right now, sorry about this.

answered on Super User Sep 22, 2016 by MariusMatutiae • edited Sep 23, 2016 by MariusMatutiae

User contributions licensed under CC BY-SA 3.0