Joe's Linux Blog Linux Admin tips and tricks

March 5, 2014

OpenVPN Linux clients with VPN-based DNS services

Filed under: Centos,Configuration,Installation — jfreivald @ 6:45 am

Openvpn is a really nice, relatively simple VPN service.

There are lots of tutorials on how to get things rolling. This post deals with the specific issue of DNS services made available through the VPN.

Most of my users connect to our VPN using Windows clients, which is great because OpenVPN’s Windows client has the ability to override the existing DNS services that the client is using and replace them with DNS services pushed by the VPN server.  This means that the users have access to all of our internal network using the same names as if they were connected locally.  Just what you would expect.

Under Linux this is a bit more complicated because Linux (and most of the *nix world) uses the /etc/resolv.conf file to resolve name information and the Linux Openvpn client doesn’t change the information stored thereon it’s own. This makes things painful if Linux users don’t have access to the internal DNS.

The Openvpn solution is to use the openvpn scripting feature to pass the information to a script which will process it. After a few false starts with other people’s scripts I came up with the following configuration. OpenVPN will provide warnings in syslog that scripting is enabled because almost anything can be done with scripts, even very bad things.

I hope that you find these scripts helpful.

 

Linux Client Configuration: /etc/openvpn/client.conf

client
dev tun
proto udp
script-security 2
up ./up.sh
down ./down.sh
remote <remote_server_ip_address> 1194
remote <remote_server_ip_address #2> 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca /etc/pki/tls/certs/my_cert_authority.pem
cert /etc/pki/tls/certs/my_client_certificate.pem
key /etc/pki/tls/private/my_client_key.key
ns-cert-type server
verb 1
mute 5

The up script: /etc/openvpn/up.sh:

#!/bin/bash
log="openvpn.log"
modified="0"
echo "Initialization: $0 $1 $2 $3 $4 $5 $6" >> $log
echo ";; created by openvpn" > ./resolv.conf.new 
echo ";; Initialization: $0 $1 $2 $3 $4 $5 $6" > ./resolv.conf.new
for opt in ${!foreign_option_*}; do
    optval=${!opt} 
    optiontype="`echo $optval | awk -F ' ' '{ print $1; }';`"
    if [ "$optiontype" == "dhcp-option" ]; then 
        dhcptype=`echo $optval | awk -F ' ' '{ print $2;}';` 
        dhcpval=`echo $optval | awk -F ' ' '{ print $3;}';` 
        if [ "$dhcptype" == "DNS" ]; then 
            modified="1" 
            echo "Adding DNS Server $dhcpval" >> $log 
            echo "nameserver $dhcpval" >>./resolv.conf.new 
        fi 
        if [ "$dhcptype" == "DOMAIN" ]; then 
            modified="1" 
            echo "Adding domain $dhcpval" >> $log 
            echo "domain $dhcpval" >> ./resolv.conf.new 
            echo "search $dhcpval" >> ./resolv.conf.new 
        fi 
        #Note that the DOMAIN must come first for the sed command do match properly.
        if [ "$dhcptype" == "DOMAIN-SEARCH" ]; then 
            modified="1"
            echo "Adding domain search $dhcpval" >> $log
            sed -i "s/^search \(.*\)/search \\1 $dhcpval/" ./resolv.conf.new
        fi
        dhcptype=
        dhcpval=
    else
        echo "Ignore non-dhcp option: $optval" >> $log
    fi
done
if [ "$modified" != "0" ]; then
    if [ -f /etc/resolv.conf ] && [ -f ./resolv.conf.new ]; then
        cp -f /etc/resolv.conf ./resolv.conf.saved
        if [ $? != 0 ]; then
            echo "Failed to copy existing /etc/resolv.conf." >> $log
        fi
    fi
 if [ -f ./resolv.conf.new ]; then
    echo "Replacing existing name services with VPN settings" >> $log
    cp -f ./resolv.conf.new /etc/resolv.conf
        if [ $? != 0 ]; then
            echo "Replacement resolv.conf failed." >> $log
            exit 1;
        else
            rm ./resolv.conf.new
        fi
    fi
else
    echo "/etc/resolv.conf not replaced" >> $log
fi

VPN Down script: /etc/openvpn/down.sh

#!/bin/bash
log="openvpn.log"
if [ -f ./resolv.conf.saved ]; then
    echo "Reverting to original name services." >> $log
    cp -f ./resolv.conf.saved /etc/resolv.conf
    if [ $? == 0 ]; then
        rm -f resolv.conf.saved
    else
        echo "Failed to recover /etc/resolv.conf." >> $log
    fi
else
    echo "No stored name service information available." >> $log
fi

Server configuration file: /etc/openvpn/server.conf

port 1194
dev tun
# TLS parms
tls-server
#Notice that the server uses a Diffie-Hellman file. This is to make session key generation less resource intensive.
ca /etc/pki/tls/certs/<my_certificate_authority>.pem
cert /etc/pki/tls/certs/<my_server_certificate>.pem
key /etc/pki/tls/private/<my_server_key>.key
dh /etc/pki/tls/private/<my_server_diffe_hellman_file>.pem
# Tell OpenVPN to be a multi-client udp server
mode server
# The server's virtual endpoints
ifconfig 192.168.200.1 192.168.200.2
# Require all clients to have a ccd file. This provides clients with a static IP address, and no client that isn't assigned a static IP address will be permitted to join the network.
# It is a little more overhead to keep track of clients, and probably isn't necessary in most cases.
ccd-exclusive
# Use individual client configs based on SSL CN
client-config-dir /etc/openvpn/ccd
# Pool of /30 subnets to be allocated to clients.
# When a client connects, an --ifconfig command
# will be automatically generated and pushed back to
# the client.
# ifconfig-pool 10.2.0.4 10.2.0.255
# Push route to client to bind it to our local virtual endpoint.
# These are the only routes that will be delivered to the client over the VPN. All other internet traffic will route based on their current routing tables.
push "route 192.168.200.0 255.255.255.0"
push "route 10.1.0.0 255.255.0.0"
push "route 10.2.0.0 255.255.0.0"
push "route 10.128.0.0 255.255.0.0"
# Push DHCP options to clients. Windows clients use these automatically, Linux clients need our up/down scripts to help them.
push "dhcp-option DNS 192.168.200.12"
push "dhcp-option DOMAIN work"
push "dhcp-option DOMAIN-SEARCH intranet.work"
# Client should attempt reconnection on link
# failure.
keepalive 10 60
# Delete client instances after some period
# of inactivity.
inactive 600
# Route the --ifconfig pool range into the
# OpenVPN server.
route 192.168.201.0 255.255.255.0
# The server doesn't need privileges
user openvpn
group openvpn
# Keep TUN devices and keys open across restarts.
persist-tun
persist-key
verb 2

April 22, 2010

ALIX Centos Image

Filed under: ALIX,Centos,Installation — Tags: , , , , , — jfreivald @ 10:48 pm

UPDATE 12/31/2011: I have updated the Alix Centos 5 image to 5.7.  During the process, I removed the /etc/ssh/ssh_host* keys so that each host will generate its own keys on boot up.  Note that during the ‘yum upgrade’ process, I had boost the memory on the virtual image. Yum was unable to allocate enough ram with only 256 MB available. This means that it is unlikely that an update from 5.5 to 5.7 can be performed in a single step on a live board with only 256 MB of RAM.

As for the Centos 6 image, it is being troublesome because the up-line removed all of the non-pae kernel images for the 32-bit architecture.  I’ve attempted to custom package a few kernels to complete the image but none of the work to my satisfaction.

UPDATE 10/22/2010: Added a step in the ‘Using the Image’ section below. All active installations should ensure they replace their SSH System keys to prevent man-in-the-middle attacks. I will post an updated image that has the keys removed when I get around to it. Until then, just perform the commands in item 7 of the Using the Image section.

UPDATE: A new version of the image is available.  It had ‘yum upgrade’ executed on June 12th, 2010, which upgraded it to Centos Version 5.5.  The new image is located at http://software.freivald.com/centos/alix-centos-5.7-2gcf.gz.  There is also an MD5 sum file at http://software.freivald.com/centos/alix-centos-5.7-2gcf.md5.

I could not find my 2 GB card. I used the original image, copied it to a 4 GB card, performed the update, and then copied only the first 2 GB back into the new image. Please provide feedback if the image does not work on a 2GB card.

UPDATE: Hat-tip @Cris. In order to get the vga to work on the 3d3 board you must put the irqpoll as kernel boot parameter.  See his comment for more information.

INFO: For those who are unfamiliar with Centos, it is a distribution that is binary compatible with RedHat Enterprise Linux.

EDIT: We’ve been added to the ALIX web page. Thank you for the testing and support from the PC-Engines crew.

I’ve been working with one of PC Engine’s Alix 6e1 boards a bit lately.  It’s a 500 MHz i586 AMD Geode-based embedded board with 256 MB of RAM that sells for under $150. I was testing various distributions and found that Centos was pretty easy to adapt. It wasn’t listed as supported on the PC Engines Web Site, so I wanted to contribute an image back to the community.

The image I’ve created has the following changes from a base install:

1.  It has no swap.

2.  It has the noatime and nodiratime options for all mounted partitions, although it uses ext3 because of the wal-wart-no-backup-power-for-shutdown configuration.

3.  Grub is configured for a 2-second timeout, and uses the serial port as the console – both for grub and the kernel.  Hook up a terminal emulator set to 38000, 8N1 to view the boot sequence or access the console directly.

4.  /etc/inittab was modified to use the serial console.  xdm was also disabled.

5.  All console settings are set for 38400 because that is what the initial boot-up bios uses on the ALIX 6e1 that I have.

6.  /etc/securetty has been modified to allow login via /dev/ttyS0 (tty0 and vc/1 are also left open because I use VMWare to modify the image).

7.  Fortunately, due to the stock Centos LVM configuration, no changes were necessary to fstab or the initrd image.

8.  Only a base install was performed.  Several of the ‘default’ packages have been omitted (things like bluetooth, extra shells, smart card reader daemon, procmail, cups, NetworkManager, etc. )  Of course they are still available using YUM.

9.  Lots of the startup stuff is turned off (kudzu, gpm, netfs, iptables and others).  Use chkconfig to turn them back on if you want them.

10.  The root password is – yep, you guess it: password

11. The eth0 (next to the USB ports) is configured for DHCP. eth1 (next to the serial port) is configured for 192.168.1.50. The hardware MAC lines have been commented out so that it will work with any box, but there is a slight chance that the order of the ports will get reversed. This has never happened to me, but YMMV. You can use either port to get the box up and running with ssh or putty if you don’t want to use or don’t have a serial interface.

12.  The CF card I used was A 2GB SanDisk Ultra 15MB/s.  Because it’s LVM based, you can use the LVM tools to shrink or grow the volumes.  Check out the LVM Howto for all the recipies you need.

13. I updated the packages using ‘yum update’ on the day it was created, so hopefully you won’t have as much downloading to do. I did not enable centosplus, extras, or any other repositories, which makes the image binary compatible with RHEL 5.4.

Using the Image

1.  Download the latest image from http://software.freivald.com/centos/.

2.  Unzip the image with bunzip2.  Please verify the uncompressed image with md5sum. Several users who had issues simply had bad downloads or uncompressed the file improperly.  An md5sum will catch these types of issues.  The md5sum file is in the same directory as the image.

3.  Copy it to your Compact Flash drive using ‘dd if=<inputfile> of=<outputdevice> bs=4096’.  <inputfile> is the uncompressed image that you verified in step 2.  <outputdevice> is your compact flash card.  You can find the correct one for your system with ‘sudo parted -l’.  You must use the disk device, not a partition i.e: /dev/sdc as opposed to /dev/sdc1.  This will install the boot loader and all necessary partitions to have a running system.  If your compact flash is larger than 2GB, see the comments section of this post for ways in which you can use the rest of the space.

4.  Install the Compact Flash into the ALIX.

5.  Attach your favorite terminal program to the ALIX platform.  I use putty.exe under Windows or minicom under linux.

6.  Apply power to the unit.  It should boot without any fuss. If you don’t have a serial port, use eth0 (next to the USB) to have your DHCP router assign and address, or use eth1 (next to the serial port) for a static configuration. eth1 is configured for 192.168.1.50 and the connector auto-rolls the cable if it needs to, so configure your computer for something like 192.168.1.51 and ping until the system is online. Then use ssh, or putty.exe if you are using Windows, to access the unit.

7.  I recommend some changes: Obviously, the root password.  Also, add an MD5 password to the grub configuration, since without one anyone with a serial cable can pass parameters to the kernel. You will also probably want to add more software using yum. You might also want to create some scratch space under /tmp, or some of the /var/cache directories using tmpfs. I didn’t do any of the these because they are simple, and different users will have different requirements, especially with the advancement of CF cards (wear leveling, 1000000+writes/block, etc.). You will probably want to customize /etc/securetty for your installation.

8. On images earlier than 5.7, change the SSH server keys with:
$ sudo rm /etc/ssh/ssh_host_*
$ sudo /etc/init.d/sshd restart
(Hat tip to @pmoor for catching this one!)

With this setup, the initial boot up takes 1:32 and has 193MB of free memory. Enjoy.

–JATF

February 25, 2010

Qt 4.6.2 packages for Centos 5.4

Filed under: Centos,Configuration,Installation,qt,Tools — jfreivald @ 2:25 pm

UPDATE: New post for the new packages: http://joseph.freivald.com/linux/2010/06/09/qt-4-6-3-and-qt-creator-1-3-1-1-updates-for-centos-5-5/

The Qt4 packages for Centos are updated to 4.6.2 and Qt Creator is updated to 1.3.1.

To install:

rpm -ivh http://software.freivald.com/el/5/i386/os/software.freivald.com-2.0.0-0.el.noarch.rpm
yum update fontconfig fontconfig-devel qt4 qt4-devel qt4-doc qt4-postgresql qt4-odbc qt4-sqlite qt-creator

Verify that the versions are coming from software.freivald.com and enjoy. 🙂

May 24, 2009

Qt4 RPMs for Centos 5

Filed under: Centos,Installation,qt — Tags: , — jfreivald @ 11:03 am

UPDATE; New post for the new packages: http://joseph.freivald.com/linux/2010/06/09/qt-4-6-3-and-qt-creator-1-3-1-1-updates-for-centos-5-5/

UPDATE: Nokia released Qt 4.6.0 and qt-creator 1.3.0 today.  The new RPMs are compiled and stored in the repository.  ‘yum update’ should be sufficient to grab the new ones.  I also changed the directory to reflect Centos 5.4 instead of 5.3.  Let me know of any issues.

–JATF

Want to get the Qt SDK working on Centos 5.3?

Quick instructions:

rpm -ivh http://software.freivald.com/centos/software.freivald.com-1.0.0-1.noarch.rpm
yum update fontconfig fontconfig-devel qt4 qt4-devel qt4-doc qt4-postgresql qt4-odbc qt4-sqlite qt-creator

Verify that the versions are coming from software.freivald.com and install. 🙂

Longer story:

All of the RPM’s described in this post are in a yum repository that you can access by installing this RPM.  It includes both x86_64 and i386 repositories that are automatically selected based on your architecture.

The first problem: the FcFreeTypeQueryFace problem that is very well described here, with a manual compile and upgrade way around it.  I thought I would go one step further and create an RPM.  Here is what I did:

I started with this source file from fontconfig.org and this SRPM from redhat.com, modified the spec file from the SRPM because of a changed config file location, and created these RPM files for you to install.

The second problem:  the QtSDK is built against several other libraries that are newer than provided with CentOS 5.3.  Rather than update those libraries, I’ve opted to compile RPMs for qt4 and qt-creator for CentOS 5.3. There are all new packages for them in the repository. They upgrade the shipped version (4.2.1) to the new version. They should be binary compatible, since theoretically Qt only breaks binary backwards compatibility on a major revision number change, but I don’t have any real way to test this. Feel free to post any problems you encounter.

The third problem: qt-creator isn’t included with the qt4 source.  I created it as its own package.  ‘yum install qt-creator’ to install it by itself.

Hopefully after installing the repository package, a

yum update

and everything should ‘just work’.

Oh, and feel free to use the ‘joewidgets’ and ‘joewidgets-devel’ packages.  They include some widgets that I use for other projects, primarily a back-port of the KLed widget to QLed that removed KDE dependancies, and a multi-state button with configurable colors for each state.  The ‘devel’ package includes designer plugins that also work in qt-creator.  Source for those are published in the srpms directory.

–JATF

Powered by WordPress