NOTE: Update 23 October 2014: This is broken on Yosemite because of tighter controls on unsigned kernel extensions. These are NO LONGER allowed to either load or run as unsigned extensions. This prevents the /dev/tun* or /dev/tap* devices from being created. More to follow …
Michael
===
How I got VPNC working in Mac OS X Lion (works in Mavericks too), without clobbering my /etc/resolv.conf file, while preserving my local, default gateway setting!
NOTE: These steps are best used to access your work laptop securely from Home, rather than your entire Office network. Best to use the standard OS X VPN setup for that
Mac OS X Lion’s inbuilt Cisco IPSEC VPN client works a treat, except when you want to do two crucial things:
1. Not forward all traffic through the Tunnel, and
2. Preserve your DNS settings so that you can continue to roam freely outside the Tunnel
The canned options available to you in the Apple client do not let you configure it to this degree.
This is where VPNC comes in – I use it on my Ubuntu workstation in this exact way, so that I can access my Laptop within my Office Microsoft domain, while continuing to work as normal from Home.
Ubuntu’s VPNC package allows me to accomplish the two requirements mentioned earlier using the following two parameters in the .conf file:
Target networks 10.x.x.0/24
DNSUpdate no
The Target networks parameter basically tells VPNC I only want to access this particular private network – it effectively prevents all traffic from flowing through the tunnel interface, except for the given network address
And the DNSUpdate parameter, which is deprecated, preserves your local DNS settings by not allowing VPNC to clobber /etc/resolv.conf with the Tunnel’s server-side DNS settings
So much for the Ubuntu setup. Now, on to OS X Lion!
In a nutshell, here are the steps needed to make this work in OS X:
1. Install the Apple Xcode development system
2. Install the Command Line Tools component in Xcode (just in case!)
3. Install the MacPorts ecosystem from the wonderful people at www.macports.org
4. Using the MacPorts ecosystem, install the VPNC port for OS X Lion
5. Configure VPNC correctly
****
1. The Xcode development system is available from the Mac OS X App Store
2. Once installed, goto Applications in the Finder window, and double-click on Xcode – once open, goto Xcode Preferences -> Downloads -> Components
Select Command Line Tools and Install the component
3. Goto www.macports.org and download and install their system
4. Once MacPorts is installed, at a Terminal shell do:
sudo update selfupdate <— This ensures you have the latest version of the MacPorts system
sudo port install vpnc
…this will automatically determine which dependencies are needed by VPNC, download and install them, and then download and install VPNC itself.
Among the VPNC dependencies is the tuntaposx Tunnel interface package – a crucial bit right here!
5. The MacPorts system installs in /opt/local – very neat and tidy. It will also auto-configure your PATH variable the next time you open a Terminal window to include the path to its own executables. So for example to run vpnc, you only need to type ‘vpnc’ at the root command line.
You will find the VPNC conf files in the /opt/local/etc/vpnc directory. For our purposes, here is a typical VPN conf file – taken from my Ubuntu system:
[michael@asus ~]$ sudo cat /etc/vpnc/EMC.conf
## generated by pcf2vpnc
IPSec ID <your group id>
IPSec gateway <your vpn gateway IP>
IPSec secret <yoursecret>
Xauth username DOMAIN\<username>
Xauth password <password>
IKE Authmode psk
Target networks 10.x.x.0/24
#
DNSUpdate no
…we simply should copy the conf file into the /opt/local/etc/vpnc directory, and run:
sudo vpnc EMC
…to get things going in Mac OS X – but there are some very crucial bits to do before this:
A) The tuntaposx tunnel interfaces do not get automatically created, nor do the Kernel extensions get loaded, even though the tuntaposx package is properly installed.
I don’t know why this is – so here’s what we do:
sudo rsync -av /opt/local/Library/Extensions/* /Library/Extensions/ <— This copies the tap.kext and tun.kext Kernel extension bundles into the System Extensions directory
sudo rsync -av /opt/local/Library/StartupItems/* /Library/StartupItems/ <— This copies the tun and tap initialisation services into the System StartupItems directory
Reboot once this is done, and confirm you can see the following:
bash-3.2# ls /dev/tun*
/dev/tun0 /dev/tun10 /dev/tun12 /dev/tun14 /dev/tun2 /dev/tun4 /dev/tun6 /dev/tun8
/dev/tun1 /dev/tun11 /dev/tun13 /dev/tun15 /dev/tun3 /dev/tun5 /dev/tun7 /dev/tun9
(…we are only interested in tun devices, not tap devices)
…and also check that the Kernel extensions have been loaded too:
bash-3.2# kextstat |grep foo
109 0 0xffffff7f81afd000 0x8000 0x8000 foo.tun (1.0) <7 5 4 1>
110 0 0xffffff7f81b07000 0x7000 0x7000 foo.tap (1.0) <7 5 4 1>
B) Comment out the two superfluous parameters from the conf file:
# Target networks 10.x.x.0/24
# DNSUpdate no
…these two parameters are not needed anymore
C) Use the VPNC vpnc-script to emulate what the two parameters effectively did:
cd /opt/local/etc/vpnc
cp vpnc-script vpnc-script_ORIG
…and make the following changes using vi to vpnc-script:
#* INTERNAL_IP4_DNS — list of dns serverss
INTERNAL_IP4_DNS=
#* CISCO_SPLIT_INC — number of networks in split-network-list
#* CISCO_SPLIT_INC_%d_ADDR — network address
#* CISCO_SPLIT_INC_%d_MASK — subnet mask (for example: 255.255.255.0)
#* CISCO_SPLIT_INC_%d_MASKLEN — subnet masklen (for example: 24)
CISCO_SPLIT_INC=1
CISCO_SPLIT_INC_0_ADDR=10.x.x.0
CISCO_SPLIT_INC_0_MASK=255.255.255.0
CISCO_SPLIT_INC_0_MASKLEN=24
The INTERNAL_IP4_DNS=
…parameter effectively says do not clobber /etc/resolv.conf, and the
CISCO_SPLIT*
…parameters effectively setup a private connection through the tunnel to the 10.x.x.0 network
The default vpnc-script above is always called when vpnc is run, and with the above changes made, we can now make a connection:
[michael@air ~]$ sudo vpnc EMC
add net 10.x.x.0: gateway 10.x.x.8
add host x.x.x.x : gateway 192.x.x.1
add net 10.x.x.0: gateway 10.x.x.8
VPNC started in background (pid: 800)…
[michael@air ~]$ netstat -rn
Routing tables
Internet:
Destination Gateway Flags Refs Use Netif Expire
default 192.x.x.1 UGSc 45 0 en0
10.x.x/26 10.x.x.8 UGSc 0 0 tun0
10.x.x.8 10.x.x.8 UH 2 0 tun0
10.x.x/24 10.x.x.8 UGSc 0 0 tun0
.
.
.
…I can still resolve external hostnames, using my local DNS settings:
[michael@air ~]$ cat /etc/resolv.conf
#
# Mac OS X Notice
#
# This file is not used by the host name and address resolution
# or the DNS query routing mechanisms used by most processes on
# this Mac OS X system.
#
# This file is automatically generated.
#
domain theabbouds.lan
nameserver 192.x.x.1
[michael@air ~]$ ping http://www.google.com
PING http://www.l.google.com (74.125.237.112): 56 data bytes
64 bytes from 74.125.237.112: icmp_seq=0 ttl=56 time=10.193 ms
64 bytes from 74.125.237.112: icmp_seq=1 ttl=56 time=13.795 ms
64 bytes from 74.125.237.112: icmp_seq=2 ttl=56 time=13.579 ms
I can now ping the IP of my Office Laptop:
[michael@air ~]$ ping 10.x.x.33
PING 10.x.x.33 (10.x.x.33): 56 data bytes
64 bytes from 10.x.x.33: icmp_seq=0 ttl=122 time=18.259 ms
64 bytes from 10.x.x.33: icmp_seq=1 ttl=122 time=30.517 ms
64 bytes from 10.x.x.33: icmp_seq=2 ttl=122 time=23.366 ms
64 bytes from 10.x.x.33: icmp_seq=3 ttl=122 time=22.495 ms
64 bytes from 10.x.x.33: icmp_seq=4 ttl=122 time=20.989 ms
…and run an RDP session to it – at the same time
I just completed the installation of vpnc using the steps above. I couldn’t have found a clearer or more accurate site documenting this task. Thank you.
…thanks Ben – I appreciate your feedback!
Kudos .. worked like a charm
Thanks Amlan
Thank you this helped immensly
…pleasure – good to know!
VPNC up and running. This couldn’t be any clearer. So helpful. Thanks for the post.
…thanks for the feedback Joe – appreciate it!
Finally a solution that works exactly how i need it! Thanks!
…you’re welcome alexR! Thanks for the kudos.
Thanx man, pretty straight forward.
…you’re very welcome f4cl3y – good to see this tip is still a help!
Excellent guide – works right out of the box, on Mavericks too. Thanks a million – now I can ditch the Ubuntu VM that takes too long to boot up each time I need fast access
Thanks mcgreal, appreciate you feedback! I’ll update the article heading I think, to include Mavericks
Pingback: vpnc | gegorguly's
Hello, your article is awesome, but my needs are a bit more complex…
I regularly need to connect to 3 VPNs at the same time. AND I need to forward DNS requests to DNS servers on each of these VPNs. In Linux, team mates have solved this problem by installing bind9, custom configuring it to forward DNS requests and making resolv.conf immutable. Is there a better way?
Hoping for an answer…
RE: Part 5A
You can use launchd to manage the tun/tap services:
% sudo launchctl load -w /Library/LaunchDaemons/org.macports.tuntaposx.plist
This command is needed because all ports have their startup items disabled by default. You only have to run it once to enable tuntaposx’s plist, and then launchd will start managing it transparently.
On Mavericks works fine, bu not work on OS X 10.10 (Yosemite).
ls /dev/tun* return no rows,
kextstat |grep foo
extensions have not been loaded 😦
I try clean macports installation and install vpnc again, but not helped…
Thanks Emil,
I’ve only just upgraded to Yosemite, and am working on upgrading Macports as well – I’ll report back my findings once I know for myself … stay tuned!
Michael
thanks Michael 🙂
Thanks from the Netherlands for your efforts! Me and a bunch of friends/colleagues really appreciate your work.
Thanks you guys! Appreciate the feedback, as always 🙂
Just checking on this issue now, and can confirm Emil’s findings – the people at Homebrew have flagged this is as a known bug:
https://github.com/Homebrew/homebrew/issues/31153
Basically, Yosemite no longer allows unsigned kernel extensions to either load or run (see DomT4’s comment from July 28 in the above thread)
The workaround at the moment seems to disable all kext checking, which is unacceptable
Let’s see what we can find by looking al little deeper …
can’t be used this homebrew solution ?
”
sormy commented 3 days ago
Also, autoloading for kexts via StartupItems didn’t work anymore. Need to rework to use LaunchDaemons.
I think formula can be fixed to show solution for kext-dev-mode and also need to remove StratupItems and replace with LaunchDaemons solution.”
…I think you’ll find that kext-dev-mode=1 means to completely disable kext sign checking for ALL kexts. That is a bad workaround. There is another workaround I have seen, where the Google signed Tunnelblick *.kext extensions are used, instead of the ones supplied by Macports. That is worth investigating, but you’ll need to make sure that the Tunnelblick licence permits this …
you’re right, TUN/TAP driver from Tunnelblick is better solution. 🙂
thanks for this post…. you’re god!!!!
@mabboud123 you know if this could be applied to IOS devices ( ipads or iphones ) ?
hmmm… I reckon Cisco AnyConnect app might be the way to go, from the App Store – let me know how you go with that. Thanks @routerdark …
very nice