[SOLVED] using TAP/DHCP - DNS not working

Got a problem with Viscosity or need help? Ask here!

MasterYous

Posts: 13
Joined: Wed Apr 14, 2010 9:41 am

Post by MasterYous » Wed Apr 14, 2010 10:00 am
Hey gurus - first post here - please don't shoot if this is answered elsewhere as I looked around A LOT before posting.

I am using the latest Viscosity (1.0.9) with a TAP configuration, setting everything from my remote DHCP server via bridging. This configuration works really well - I've used it with the Win32 OpenVPN client for years.

Installed Viscosity - very nice program. The link comes up, an IP address gets assigned from the DHCP pool, and I can ping machines behind the firewall via IP address - perfect.

So the problem is DNS does not work. scutil --dns does not show the DNS address and domain suffix pushed from DHCP... just the regular default Mac OS DNS before I connect. So DNS does not work. Here is what I have tried:

- turned on DHCP option in Viscosity
- turned on DNS option in Viscosity
- used BOTH the regular and "alternate" DNS option.

I suspected a DHCP problem pushing things over correctly, so I tried
> ipconfig getoption "tap0" domain_name
> ipconfig getoption "tap0" domain_name_server

Both return the CORRECT information so I am certain the DHCP server is pushing those options and the client is pulling them.

Could this be an issue with Viscosity itself given the tap configuration and DHCP pushing everything automatically? I am not using tun and I am not specifying push options on the OpenVPN server (I don't have to). I do not want to specify DHCP options in the Viscosity configuration file as I frequently change things via DHCP. I know that on the other O/S I have tried an openvpn client on (FreeBSD, Linux, Windows), I do not have to do this and options come across just fine. :D Sorry to be so picky with the config... I just want it to work the "default" easy way, as I use one server across all my clients and I pull everything across with DHCP. Low-maintenance.

Thanks for any help - I can send across any log files that may help, tho I didn't see anything useful in the details window:
Code: Select all
Tue Apr 13 19:34:38 2010: IMPORTANT: OpenVPN's default port number is now 1194, based on an official port number assignment by IANA.  OpenVPN 2.0-beta16 and earlier used 5000 as the default port.
Tue Apr 13 19:34:38 2010: NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
Tue Apr 13 19:34:38 2010: LZO compression initialized
Tue Apr 13 19:34:38 2010: UDPv4 link local (bound): [undef]:1194
Tue Apr 13 19:34:38 2010: UDPv4 link remote: xx.xx.xx.xx:1194
Tue Apr 13 19:34:38 2010: WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Tue Apr 13 19:34:39 2010: [mydomain.com] Peer Connection Initiated with xx.xx.xx.xx:1194
Tue Apr 13 19:34:41 2010: TUN/TAP device /dev/tap0 opened
Tue Apr 13 19:34:41 2010: /sbin/ifconfig tap0 lladdr xx:xx:xx:xx:xx:xx
Tue Apr 13 19:34:41 2010: TUN/TAP link layer address set to xx:xx:xx:xx:xx:xx
Tue Apr 13 19:34:41 2010: /Applications/Viscosity.app/Contents/Resources/dnsupalt.py tap0 1500 1574   init
Tue Apr 13 19:34:41 2010: Initialization Sequence Completed
Last edited by MasterYous on Fri Apr 16, 2010 6:58 am, edited 2 times in total.

MasterYous

Posts: 13
Joined: Wed Apr 14, 2010 9:41 am

Post by MasterYous » Fri Apr 16, 2010 6:55 am
Ok, I'm going to reply to myself here. ;)

I spent the last two days figuring this out. DNS configuration is handled through python scripts called automatically by OpenVPN (Viscosity) when the connection comes up or down. The existing scripts, dnsup.py, dnsdown.py, etc. are located in /Applications/Viscosity.app/Contents/Resources and there are other scripts as well (the alternate DNS scripts too).

So the long and short of it is that the existing scripts rely on the server having pushed variables via the dhcp-option directive in the OpenVPN server config file. This in turn gets interpreted by the openVPN client (Viscosity, in this case), by setting these variables in the environment (as "foreign_option_xxxx", etc.). The scripts in Viscosity look for those to determine how to set DNS. This is intended for people who do not have a real DHCP server to send things across, or do not want to, or those using a tun device which does not support DHCP broadcasting. My configuration does not send DHCP options because I have a real DHCP server push everything via the tap bridge, so it's like a real DHCP server on the network assigning stuff (hence, I selected "Enable DHCP" in my Viscosity connection).

So the supplied scripts with Viscosity do not work for setting DNS in this case at all and that is why I was having problems. However, I was able to determine that the DHCP server *was* sending everything I needed; Mac OS was just capturing it somewhere else - in the configd key
Code: Select all
State:/Network/Service/DHCP-tap0/DNS.
So, I have modified the two basic Viscosity DNS scripts to look in that key, pull out the DNS settings for the tap0 device, and use them in place of the old DNS settings. The dnsup.py script has been modified to look in the new location, and the dnsdown.py script has been modified to handle restoring the old settings, too. I also made some other optimizations and logging additions to the scripts to aid debugging. They should run a wee bit faster now due to some more efficient Python code in there. With a few tweaks to the Viscosity connection configuration file, I got everything to work.

I've attached the scripts I modified here, just in case someone else can benefit from this. You MUST be using a tap device, you MUST be broadcasting everything via DHCP, you must select "Enable DHCP" for your connection, and you must also realize that this will only work for tap0 - the first tap device. The script could still be further modified to look for additional tap devices for additional VPN connections and add them all in as well, but I haven't done that. Feel free to modify them further.

One more thing you may have to do - the scutil/configd key I mentioned above (State:/Network/Service/DHCP-tap0/DNS) gets populated ONLY AFTER the DHCP server sends stuff over. This is a handshake, and sometimes this happens too late for the dnsup.py script to find them in time, since the script runs as soon as the tap device is opened. To remedy this problem, change the dnsup.py script to do nothing, and create a new script to do all the "real" work. Attach this script to the route script hook in OpenVPN, which can conveniently be delayed via the "route-delay" option in OpenVPN/Viscosity. That way you can set it to run several seconds after the DHCP handshake has had time to complete.
Code: Select all
route-delay 20
route-up "/Applications/Viscosity.app/Contents/Resources/dnsup-delayed.py tap0 1500 1574 init"
Enjoy ... and let me know if this helps you out or not.
Attachments
dns_python_scripts.zip
dnsup, dnsup-delayed, dnsdown
(3.02 KiB) Downloaded 686 times

James

User avatar
Posts: 2313
Joined: Thu Sep 04, 2008 9:27 pm

Post by James » Mon Apr 19, 2010 2:53 pm
Thanks for posting your detailed solution MasterYous, I'm sure others will find it useful!

Cheers,
James
Web: https://www.sparklabs.com
Support: https://www.sparklabs.com/support
Twitter: https://twitter.com/sparklabs

Pyrofallout

Posts: 2
Joined: Sun May 09, 2010 4:25 pm

Post by Pyrofallout » Tue May 11, 2010 9:38 am
This solved my problems! Thank you very much!

FWIW: I am running my OpenVPN server on a DDWRT box that is not my DHCP server or my primary router. It exists only for OpenVPN and WOL. I was able to get an IP address from the primary router, and communicate with all ips on the local network, but was unable to reach anything on the outside (internet) after I turned on "Send ALL Traffic over VPN".

Although I am not sure exactly how this fixed it, I think it was an issue with creating the routes. Because it would show both default routes in a netstat (home network and clients internet connection) but the internet connection's default route would always be above the vpn's default route in the routing table. I tried many different configurations and tweaks and none would seem to make it work after 2 days of messing with this. I installed your scripts and added the two lines to my advanced options and it worked first try. I also couldn't resolve any addresses other than the internal domain, so I don't know what exactly was going on, but this has it working, so I am happy. :D

MasterYous

Posts: 13
Joined: Wed Apr 14, 2010 9:41 am

Post by MasterYous » Thu May 27, 2010 8:35 am
I would guess your problem was a timing problem. Because my method installs a delay on the route via the route-delay and up-delay commands, your negotiation of IP address probably had more time to complete so the routes are getting inserted in the right order.

By the way, you can avoid the "two default routes" issue cleanly if you have control over the DHCP server (I use isc-dhcpd). You can write DHCP rules so that connections originating with a specific ethernet (mac) address do not get assigned a default route. This is needed for Windows openVPN clients, for example. You should really not need more than one default route in your routing tables regardless of the # of connections/network interfaces.

You can use the 'lladdr' command in the Advanced connection properties of Viscosity to set a mac address that will be used every time Viscosity starts. Write your DHCP rule in the DHCP server configuration file so that connections using that MAC address do not get assigned a default route. There is detailed information about how to do this on the net.

Pyrofallout

Posts: 2
Joined: Sun May 09, 2010 4:25 pm

Post by Pyrofallout » Thu May 27, 2010 10:01 am
My DHCP server is an Airport Extreme, I don't think that will work. :(
6 posts Page 1 of 1