DaemonForums  

Go Back   DaemonForums > OpenBSD > OpenBSD Packages and Ports

OpenBSD Packages and Ports Installation and upgrading of packages and ports on OpenBSD.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 9th February 2011
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 4,125
Default OpenBSD port of OpenVPN revisited

In Does pf conflict with OpenVPN? Emile posted a problem with OpenVPN on 4.7 stable

With a newly installed OBSD snapshot and a newer version of the OpenVPN package I had the same problem. A tcpdump on tun0 showed arp requests, which were never answered.
After a having a hard time installing FreeBSD (Xorg on FreeBSD is no fun) I could use FreeBSD to connect to a demo VPN account of 'swissvpn.net'.

I noticed that on FreeBSD no arp requests were being done.

It turned out that the OpenBSD port use a 'link0' flag to the configuration of the 'tun0' device, actually turning it into a level 2 device, hence the arp requests. And there is no way to coach OpenVPN to leave out that 'link0' flag.

In the OpenVPN man page I found some clues about running scripts, but that was sparsely documented and deeply buried inside the long, long man page.
The post of Tasmanian Devil on the OpenBSD misc list made me try harder and after some hacking on a script I could create a layer 3 tun0 device and connect to that SwissVPN demo account.

The startup script (to be run with root privileges):
Code:
#!/bin/sh

CONFIG=swissvpn.ovpn

cat <<END
Script to start up OpenVPN with custom 'ifconfig' script.

For some unknown reason the OpenBSD port configures a 'tun' device
as a layer 2 by using the 'link0' flag, making the 'tun' device to
the equivalent of a Linux 'tap' device (bridge mode).

# /sbin/ifconfig tun0 93.94.245.45 netmask 255.255.255.128 \
      mtu 1500 broadcast 93.94.245.127 link0
                                       ^^^^^
# ifconfig tun0
tun0: flags=9843<UP,BROADCAST,RUNNING,SIMPLEX,LINK0,MULTICAST> mtu 1500
        lladdr fe:e1:ba:d5:a6:69
        priority: 0
        groups: tun
        status: active
        inet 80.254.76.186 netmask 0xffffff80 broadcast 80.254.76.255
        inet6 fe80::fce1:baff:fed5:a669%tun0 prefixlen 64 scopeid 0x6

Notice the Link Level Address or MAC : fe:e1:ba:d5:a6:69

Because many VPN service providers, use layer 3, we circumvent this
by running a custom 'ifconfig' without the 'link0' flag.

# /sbin/ifconfig \${dev} \${ifconfig_local} netmask \${ifconfig_netmask} mtu \${tun_mtu}

# ifconfig tun0
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
        priority: 0
        groups: tun
        status: active
        inet 80.254.76.252 --> 0.0.0.0 netmask 0xffffff80
        inet6 fe80::210:4bff:fe65:6b4%tun0 ->  prefixlen 64 scopeid 0x
END

/usr/local/sbin/openvpn \
        --config ${CONFIG} \
        --verb 4 \
        --script-security 2 execve \
        --ifconfig-noexec \
        --up /etc/openvpn/up

# EXPLANTION OF OPTIONS (see 'man openvpn' for the details)
# -----------------------------------------------------------------------------------------------
# --config                      : specifies the configuration file supplied by the VPN service
# --verb                        : the verbosity level
# --script-security 2 execve    : allow scripts to be executed
# --ifconfig-noexec             : do not execute/run/do an 'ifconfig' on the device we are using
# --up                          : specify the name of the script where we do our own 'ifconfig'
The 'up' script where we do the custon ifconfig without the 'link0' flag.

Code:
#!/bin/sh

LOG="/var/log/OpenVPN-up-$(date '+%m%d_%H%M').log"

cat <<END >> ${LOG}
DATE: $(date '+%Y%m%d_%H%M')
-------- Available environment variables -------- 
$(env | sort)
----------------------------------------
END

if [ ${script_context} = "init" ] ; then
    /sbin/ifconfig ${dev} ${ifconfig_local} netmask ${ifconfig_netmask} mtu ${tun_mtu}
fi

cat <<END 
Configuration of ${dev} :
# ifconfig ${dev} 
$(ifconfig $dev)
---------------------------------------------
END
Attached Files
File Type: txt startup.txt (1.9 KB, 132 views)
File Type: txt up.txt (480 Bytes, 113 views)
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump

Last edited by J65nko; 9th February 2011 at 04:03 AM. Reason: Download
Reply With Quote
  #2   (View Single Post)  
Old 9th February 2011
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 4,125
Default

What is missing is patching the "/etc/resolv.conf" file so that nameserver queries also go through the VPN tunnel. But that is for another day
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump
Reply With Quote
  #3   (View Single Post)  
Old 9th February 2011
Emile Emile is offline
Port Guard
 
Join Date: Feb 2011
Posts: 25
Default

Reply With Quote
  #4   (View Single Post)  
Old 11th February 2011
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 4,125
Default

In the following scripts the original "/etc/resolv.conf' is saved, and a new one is generated, using the nameservers passed by the VPN server.
After the VPN connection has been terminated, the original resolv.conf is restored.

The relevant code of the new startup script
Code:
# ============== active code 

/usr/local/sbin/openvpn \
        --config ${CONFIG} \
        --verb 4 \
        --script-security 2 execve \
        --ifconfig-noexec \
        --up /etc/openvpn/up \
        --down /etc/openvpn/up          # yes, 'up', we handle everything in one script

# EXPLANTION OF OPTIONS (see 'man openvpn' for the details)
# -----------------------------------------------------------------------------------------------
# --config                      : specifies the configuration file supplied by the VPN service
# --verb                        : the verbosity level
# --script-security 2 execve    : allow scripts to be executed
# --ifconfig-noexec             : do not execute/run/do an 'ifconfig' on the device we are using
# --up                          : specify the name of the script where we do our own 'ifconfig'
# --down                        : script after tun0 has been torn down
# -----------------------------------------------------------------------------------------------
The new 'up' script :
Code:
#!/bin/sh
# $Id: up,v 1.5 2011/02/11 04:00:21 root Exp $

_log_environment() {
    LOG="/var/log/OpenVPN-up-$(date '+%m%d_%H%M').log"
    cat <<-END >> ${LOG}
        DATE: $(date '+%Y%m%d_%H%M')
        -------- Available environment variables -------- 
        $(env | sort)
        ----------------------------------------
END
}


_do_ifconfig() {
    /sbin/ifconfig ${dev} ${ifconfig_local} netmask ${ifconfig_netmask} mtu ${tun_mtu}
   cat <<-END 
        Configuration of ${dev} :
        # ifconfig ${dev} 
        $(ifconfig $dev)
        ---------------------------------------------
END
}


_show_resolv.conf() {
    cat <<-END
        Contents of /etc/resolv.conf
        -------------------------------------------
        $(cat /etc/resolv.conf)
        -------------------------------------------
        $(ls -l /etc/resolv.conf*)
        -------------------------------------------
END
}


_create_new_resolv.conf() {
    TEMP=resolv.conf.TEMP
    install -o root -g wheel -m u=rw,g=r,o=r /dev/null ${TEMP} 

    cat <<-END >>${TEMP}
        # $(date) : resolv.conf generated for OpenVPN connection 
        lookup file bind
END

    # --- environment variables wich hold nameserver addresses
    #foreign_option_1='dhcp-option DNS 80.254.79.157'
    #foreign_option_2='dhcp-option DNS 80.254.77.39'

    if [ ! X"${foreign_option_1}" = X ] ; then
        if (echo ${foreign_option_1} | grep 'dhcp-option DNS' >/dev/null ) ; then
            echo ${foreign_option_1} | sed -e 's/^..*DNS/nameserver/' >> ${TEMP}
        fi
    fi

    if [ ! X"${foreign_option_2}" = X ] ; then
        if (echo ${foreign_option_2} | grep 'dhcp-option DNS' >/dev/null ) ; then
            echo ${foreign_option_2} | sed -e 's/^..*DNS/nameserver/' >> ${TEMP}
        fi
    fi

    # get nr of 'nameserver ww.xx.yy.zz' lines
    count=$(egrep -c '^nameserver +[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' ${TEMP})

    if [ ${count} -gt 0 ] ; then 
        if [ -f /etc/resolv.conf ]; then
           cat /etc/resolv.conf > /etc/resolv.conf.beforeVPN
        fi
        install -S -m u=rw,g=r,o=r ${TEMP} /etc/resolv.conf && echo 'resolv.conf for VPN installed'
    fi
}


_restore_resolv.conf() {

    if [ -f /etc/resolv.conf -a -f /etc/resolv.conf.beforeVPN ] ; then
        printf "\nSaving 'resolv.conf used during VPN ... "
        install -S -m u=rw,g=r,o=r /etc/resolv.conf /etc/resolv.conf.duringVPN  && echo OK 
        printf "\nRestoring original pre-VPN 'resolv.conf' ... "
        install -S -m u=rw,g=r,o=r  /etc/resolv.conf.beforeVPN /etc/resolv.conf && echo OK
    else
        echo Sorry: Cannot restore original resolv.conf
        echo ------------------------------------------
        ls -l /etc/resolv.conf*
        echo -----------------------
    fi
}


# ==================== active code 

_log_environment

if [ ${script_context} = "init" -a ${script_type} = 'up' ] ; then
    _do_ifconfig 
    echo 'Setting up resolv.conf ....'
    _show_resolv.conf
    _create_new_resolv.conf
    _show_resolv.conf
fi

if [ ${script_context} = "init" -a ${script_type} = 'down' ] ; then
    echo 'Restoring previous resolv.conf ....'
    _show_resolv.conf
    _restore_resolv.conf
    _show_resolv.conf
fi


# --- EOF --
EDIT: specified the exact file permissions for 'install(1)' so we don't get the default 'x' (eXecute) permissions.

Code:
RCS file: RCS/up,v
retrieving revision 1.4
diff -u -r1.4 up
--- up  2011/02/11 02:19:03     1.4
+++ up  2011/02/11 03:46:44
@@ -67,7 +67,7 @@
        if [ -f /etc/resolv.conf ]; then
           cat /etc/resolv.conf > /etc/resolv.conf.beforeVPN
        fi
-       install -S ${TEMP} /etc/resolv.conf && echo 'resolv.conf for VPN installed'
+       install -S -m u=rw,g=r,o=r ${TEMP} /etc/resolv.conf && echo 'resolv.conf for VPN installed'
     fi
 
 }
@@ -77,9 +77,9 @@
 
     if [ -f /etc/resolv.conf -a -f /etc/resolv.conf.beforeVPN ] ; then
        printf "\nSaving 'resolv.conf used during VPN ... "
-       install -S /etc/resolv.conf /etc/resolv.conf.duringVPN  && echo OK 
+       install -S -m u=rw,g=r,o=r /etc/resolv.conf /etc/resolv.conf.duringVPN  && echo OK 
        printf "\nRestoring original pre-VPN 'resolv.conf' ... "
-       install -S /etc/resolv.conf.beforeVPN /etc/resolv.conf && echo OK
+       install -S -m u=rw,g=r,o=r  /etc/resolv.conf.beforeVPN /etc/resolv.conf && echo OK
     else
        echo Sorry: Cannot restore original resolv.conf
        echo ------------------------------------------
Another reason for not pasting the files but to download the now corrected versions.
Attached Files
File Type: sh up.sh (2.9 KB, 130 views)
File Type: sh startup.sh (2.2 KB, 124 views)
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump

Last edited by J65nko; 11th February 2011 at 04:34 AM. Reason: Replaced the 'up' script with a correct one, which does not set the eXecute bit on /etc/resolv.conf
Reply With Quote
  #5   (View Single Post)  
Old 11th February 2011
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 4,125
Default

A snippet from a connection to the test account of http://swissvpn.net
Code:
Fri Feb 11 04:19:40 2011 us=266591 /etc/openvpn/up tun0 1500 1543 80.254.76.249 255.255.255.128 init
Configuration of tun0 :
# ifconfig tun0 
tun0: flags=8151<UP,POINTOPOINT,RUNNING,PROMISC,MULTICAST> mtu 1500
        priority: 0
        groups: tun
        status: active
        inet 80.254.76.249 --> 0.0.0.0 netmask 0xffffff80
---------------------------------------------
Setting up resolv.conf ....
Contents of /etc/resolv.conf
-------------------------------------------
lookup file bind
nameserver 192.168.222.10
-------------------------------------------
-rw-r--r--  1 root  wheel  43 Nov 11 10:32 /etc/resolv.conf
-------------------------------------------
resolv.conf for VPN installed
Contents of /etc/resolv.conf
-------------------------------------------
# Fri Feb 11 04:19:40 CET 2011 : resolv.conf generated for OpenVPN connection 
lookup file bind
nameserver 80.254.79.157
nameserver 80.254.77.39
-------------------------------------------
-rwxr-xr-x  1 root  wheel  145 Feb 11 04:19 /etc/resolv.conf
-rw-r--r--  1 root  wheel   43 Feb 11 04:19 /etc/resolv.conf.beforeVPN
-------------------------------------------
Fri Feb 11 04:19:40 2011 us=521392 /sbin/route add -net 80.254.79.87 192.168.222.10 -netmask 255.255.255.255
add net 80.254.79.87: gateway 192.168.222.10
The one in blue is the new resolv.conf.

After stopping openvpn with cntrl-C:
Code:
Fri Feb 11 04:22:12 2011 us=883585 Closing TUN/TAP interface
Fri Feb 11 04:22:12 2011 us=884485 /etc/openvpn/up tun0 1500 1543 80.254.76.249 255.255.255.128 init
Restoring previous resolv.conf ....
Contents of /etc/resolv.conf
-------------------------------------------
# Fri Feb 11 04:19:40 CET 2011 : resolv.conf generated for OpenVPN connection 
lookup file bind
nameserver 80.254.79.157
nameserver 80.254.77.39
-------------------------------------------
-rwxr-xr-x  1 root  wheel  145 Feb 11 04:19 /etc/resolv.conf
-rw-r--r--  1 root  wheel   43 Feb 11 04:19 /etc/resolv.conf.beforeVPN
-------------------------------------------

Saving 'resolv.conf used during VPN ... OK

Restoring original pre-VPN 'resolv.conf' ... OK
Contents of /etc/resolv.conf
-------------------------------------------
lookup file bind
nameserver 192.168.222.10
-------------------------------------------
-rwxr-xr-x  1 root  wheel   43 Feb 11 04:22 /etc/resolv.conf
-rw-r--r--  1 root  wheel   43 Feb 11 04:19 /etc/resolv.conf.beforeVPN
-rwxr-xr-x  1 root  wheel  145 Feb 11 04:22 /etc/resolv.conf.duringVPN
-------------------------------------------
Fri Feb 11 04:22:13 2011 us=7752 SIGINT[hard,] received, process exiting
You can check the DNS queries with running tcpdump twice:
  1. A tcpdump on your network card e.g. xl0
    Code:
    sudo tcpdump -ni xl0 port 53
  2. tcpdump on the 'tun0' device
    Code:
    sudo tcpdump -ni tun0
After the VPN connection is made, the DNS queries on you network should stop, and appear in the tcpdump on 'tun0'.

Or do a nameserver query with dig and watch the SERVER line [code]
Code:
$ dig www.openbsd.org | grep SERVER
;; SERVER: 192.168.222.10#53(192.168.222.10)
After the VPN tunnel is up:
Code:
dig www.openbsd.org | grep SERVER
;; SERVER: 80.254.79.157#53(80.254.79.157)
BTW I now notice that I goofed up the permissions of the new resolv.conf.
Forgot that 'install(1)' sets the 'eXecute' bit by default
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump

Last edited by J65nko; 11th February 2011 at 04:35 AM.
Reply With Quote
Reply

Tags
openbsd, openvpn

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
openvpn on openbsd problem.... michaelk OpenBSD Security 8 9th February 2011 04:49 AM
openvpn-auth-ldap on openbsd 4.7 jespada OpenBSD General 2 26th August 2010 09:05 PM
install OpenBSD from serial port mfaridi OpenBSD Installation and Upgrading 2 17th April 2010 06:38 PM
OpenBSD Loongson port about to make OpenBSD 4.7 J65nko News 0 26th February 2010 12:47 AM
openVPN 2.1_rc7 (server) on openBSD 4.3 config examples s2scott Guides 2 23rd May 2008 06:16 PM


All times are GMT. The time now is 09:16 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick