LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Server (http://www.linuxquestions.org/questions/linux-server-73/)
-   -   OpenVPN+dhcpd+ldap (http://www.linuxquestions.org/questions/linux-server-73/openvpn-dhcpd-ldap-791287/)

Blue_Ice 02-24-2010 12:19 PM

OpenVPN+dhcpd+ldap
 
Hi all,

Does anyone have experience with integrating dhcpd and ldap with openvpn?

What I want to do is use the dhcp server of my internal network to assign ip addresses to my vpn clients. Besides that I also want to be able to use ldap to check if users are authorized to login via vpn.

I have included my openvpn.conf and the ldap.conf referred to in the configuration file:
Code:

# openvpn.conf

port 1194
proto udp
mode server
dev tap0
push "redirect-gateway 10.200.55.1"
client-to-client
duplicate-cn
keepalive 10 120
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
tls-server
tls-auth ta.key 0
cipher AES-128-CBC
comp-lzo
max-clients 200
persist-key
persist-tun
status openvpn-status.log
log-append /var/log/openvpn.log
verb 3
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so /etc/openvpn/auth/ldap.conf

Code:

<LDAP>
        URL                ldap://domain.example.com
        BindDN                uid=Manager,dc=example,dc=com
        Password        SecretPassword
        Timeout                15
        TLSEnable        yes
        FollowReferrals yes
        TLSCACertFile        /etc/openldap/cacerts/ca.pem
        TLSCACertDir        /etc/openldap/cacerts
        TLSCertFile        /etc/openldap/ssl/ldap.crt
        TLSKeyFile        /etc/openldap/ssl/ldap.key
        TLSCipherSuite        TLSv1+RSA:!NULL
</LDAP>

<Authorization>
        BaseDN                "ou=users,dc=example,dc=com"
        SearchFilter        "(uid=%u)"
        RequireGroup        false
        <Group>
                BaseDN                "ou=groups,dc=example,dc=com"
                SearchFilter        "(|(cn=domusers)(cn=domadmins))"
                MemberAttribute        uniqueMember
        </Group>
</Authorization>

I also adjusted my dhcpd.conf, according to something I found on google, to specify the range for the vpn clients:
Code:

...

class "openvpn" {
        match if substring(hardware, 1, 2)= 00:FF;
}

...

subnet 10.0.0.0 netmask 255.0.0.0 {
        pool {
                deny members of "openvpn";
                range 10.200.56.50 10.200.56.250;
                option routers 10.200.55.1;
        }

        pool {
                allow members of "openvpn";
                range 10.200.57.50 10.200.57.250;
        }
}

Can someone tell me if I am on the right way? And if not, what do have to do to make it work?

Arjan

nowonmai 02-24-2010 05:46 PM

It looks like you are going for a bridged setup.
DHCPD doesn't do the address allocation in this setup, OpenVPN does.
You need to add a line, server-bridge, containing the server bridge IP, the netmask and the client address pool, then exclude this pool from the DHCP pool.

Blue_Ice 02-24-2010 06:01 PM

Actually, I want to do it the other way around. It should be possible. I don't want OpenVPN to do this. The reason is that I want to centralized tasks as much as possible. By letting OpenVPN control this, I would introduce a second system that assigns IP addresses. So I need to setup openvpn to get its ip addresses from dhcpd.

nowonmai 02-25-2010 03:04 AM

It would be the clients that get the addresses from dhcpd, rather than openvpn, which just provides the infrastructure.
It seems that in order to do this, dhcps must be started AFTER the tap interface has been brought up... in other words, after the openvpn service, so that it is listening there for client requests. Not something I have done, tbh, the other way has always seemed satisfactory to me.

Blue_Ice 03-02-2010 04:01 PM

This seems to work. Of course in combination with the definition in dhcpd.conf and bridging eth0 and tap0.

Code:

mode server
tls-server
route-gateway dhcp
local 10.200.55.22
port 1194
proto tcp
dev tap0
ca ca.crt
cert server.crt
key server.key  # This file should be kept secret
dh dh1024.pem
server-bridge
client-to-client
keepalive 10 120
tls-auth ta.key 0 # This file is secret
cipher AES-128-CBC  # AES
comp-lzo
max-clients 200
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log-append  openvpn.log
verb 3

Next is trying to setup the ldap part and see if the gateway can be changed so all traffic is going through the tunnel.

Blue_Ice 04-25-2010 02:55 PM

Finally figured it all out..
My config looks like this now:
Code:

mode server
tls-server
route-gateway dhcp
local vpn.domain.home
port 1194
proto tcp
dev tap0
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server-bridge
client-to-client
keepalive 10 120
tls-auth ta.key 0
cipher AES-128-CBC
comp-lzo
max-clients 200
;user nobody
;group nobody
persist-key
persist-tun
status openvpn-status.log
log-append  openvpn.log
verb 3
duplicate-cn
push "redirect-gateway def1"
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-pam.so /etc/pam.d/system-auth

The pluging openvpn-auth-ldap contains a bug that causes TLS to be started after binding to ldap. Which, of course, is not possible. By adjusting the code a little bit you should be able to get it working. Unfortunately I didn't manage to get that working either. So I use openvpn-auth-pam now and that seems to work fine.

evilangel81 05-13-2010 06:07 PM

Quote:

Originally Posted by Blue_Ice (Post 3947310)
Finally figured it all out..
My config looks like this now:
Code:

mode server
tls-server
route-gateway dhcp
local vpn.domain.home
port 1194
proto tcp
dev tap0
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server-bridge
client-to-client
keepalive 10 120
tls-auth ta.key 0
cipher AES-128-CBC
comp-lzo
max-clients 200
;user nobody
;group nobody
persist-key
persist-tun
status openvpn-status.log
log-append  openvpn.log
verb 3
duplicate-cn
push "redirect-gateway def1"
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-pam.so /etc/pam.d/system-auth

The pluging openvpn-auth-ldap contains a bug that causes TLS to be started after binding to ldap. Which, of course, is not possible. By adjusting the code a little bit you should be able to get it working. Unfortunately I didn't manage to get that working either. So I use openvpn-auth-pam now and that seems to work fine.


Could you provide the full dhcpd.conf and openvpn settings you are using? :) I am looking to do exactly this and If you could redact your ip space/passwords, this would be a giant step forward for me.

Blue_Ice 05-13-2010 06:45 PM

For starters, in my previous post I already posted the complete OpenVPN config. However to be complete, here it is again:
Code:

mode server
tls-server
route-gateway dhcp
local vpn.mydomain.external
port 1194
proto tcp
dev tap0
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server-bridge
client-to-client
keepalive 10 120
tls-auth ta.key 0
cipher AES-128-CBC
comp-lzo
max-clients 200
;user nobody
;group nobody
persist-key
persist-tun
status openvpn-status.log
log-append  openvpn.log
verb 3
duplicate-cn
push "redirect-gateway def1"
management localhost 7505
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-pam.so /etc/pam.d/system-auth

My dhcpd config looks like this:
Code:

# Key to update DNS records
key dhcpupdate {
    algorithm hmac-md5;
    secret <secret>;
}

class "openvpn" {
    match if substring(hardware, 1, 2)= 00:FF;
}

allow booting;
allow bootp;

option domain-name "mydomain.local";
option domain-name-servers 10.200.55.10,xxx.xxx.xxx.xxx;
option subnet-mask 255.0.0.0;
option broadcast-address 10.255.255.255;
option netbios-name-servers 10.200.55.20;
option netbios-node-type 8;
option ntp-servers 10.200.55.10;

default-lease-time 86400;
max-lease-time 86400;

authoritative;

ddns-updates on;
ddns-update-style interim;
ddns-domainname "mydomain.local";
ddns-rev-domainname "in-addr.arpa";

ignore client-updates;

update-static-leases on;

log-facility local7;

zone mydomain.local. {
    primary 10.200.55.10;
    key dhcpupdate;
}

zone 10.in-addr.arpa. {
    primary 10.200.55.10;
    key dhcpupdate;
}

subnet 10.0.0.0 netmask 255.0.0.0 {
    pool {
        deny members of "openvpn";
        range 10.200.56.50 10.200.56.250;
        option routers 10.200.55.1;
        filename "pxelinux.0";
        next-server install.mydomain.local;
    }

    pool {
        allow members of "openvpn";
        range 10.200.57.50 10.200.57.250;
    }
}

Something that is very important as well, is the following script that is started during boot up:
Code:

#!/bin/sh
#
# bridgevpn      This shell script starts the bridge needed by openvpn
#
# chkconfig: - 24 76
#
# processname: bridgevpn
# description: bridgevpn
#

### BEGIN INIT INFO
# Provides: bridgevpn
# Required-Start: $network
# Required-Stop: $network
# Short-Description: start and stop bridgevpn
# Description: bridgevpn
### END INIT INFO



# Create global variables 
# Define Bridge Interface
br="br0"
# Define list of TAP interfaces to be bridged,
# for example tap="tap0 tap1 tap2".
tap="tap0"
# Define physical ethernet interface to be bridged
# with TAP interface(s) above.
eth="eth0"
eth_ip="10.200.55.22"  # The ipaddress of my vpn server.
eth_netmask="255.0.0.0"
eth_broadcast="10.255.255.255"
gw="10.200.55.1" 

start_bridge () { 
    ################################# 
    # Set up Ethernet bridge on Linux 
    # Requires: bridge-utils 
    #################################   
    for t in $tap; do
        openvpn --mktun --dev $t 
    done   
    for t in $tap; do
        ifconfig $t 0.0.0.0 promisc up 
    done
    ifconfig $eth 0.0.0.0 promisc up
    brctl addbr $br
    brctl addif $br $eth
    for t in $tap; do
        brctl addif $br $t 
    done   
    ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast up 
    route add default gw $gw $br
}

stop_bridge () { 
    #################################### 
    # Tear Down Ethernet bridge on Linux 
    ####################################   
    ifconfig $br down
    brctl delbr $br   
    for t in $tap; do
        openvpn --rmtun --dev $t 
    done 
    ifconfig $eth $eth_ip netmask $eth_netmask broadcast $eth_broadcast up 
    route add default gw $gw $eth


case "$1" in
    start) 
        echo -n "Starting Bridge" 
        start_bridge 
        ;;
    stop) 
        echo -n "Stopping Bridge" 
        stop_bridge 
        ;;
    restart) 
        stop_bridge 
        sleep 2 
        start_bridge 
        ;;
    *) 
        echo "Usage: $0 {start|stop|restart}" >&2 
        exit 1 
    ;;
esac

Hope this will help you out...

Noway2 05-14-2010 06:21 AM

I too wanted to have my DHCP assign addresses to remote clients as opposed to having OpenVPN assign the addresses via its pseudo DHCP. I really struggled with this for weeks. My efforts resulted in a slightly different solution to this issue. The blog by Hans Fugal "putting OpenVPN" (http://hans.fugal.net/blog/2009/01/0...-in-its-place/) was VERY helpful in figuring this out.

I finally got it to work by letting Linux create the TAP device upon startup rather than letting OpenVPN create it. This way, the TAP device is present BEFORE the DHCP server starts, which was mentioned in this thread. By creating the TAP device first, the DHCP server will bind to it and will assign addresses to devices on it. I then added the TAP device to the eth0 bridge and traffic automatically routes between the two lan segments. The other option would have been to use IPTABLES to do IP masquerading to route the traffic. I figured the bridge was easier.

I then created a zone for the VPN in my DHCP configuration and a forward and reverse zone for the DNS and allowed dynamic updates. Once this was working, I noticed a slight problem. When the TAP device is created on the client end, it gets a random MAC address. I used the lladdr declaration in the client.conf to assign it a fixed MAC address. The DHCP then looks for the first bytes which are 00:ff and identifies this as being a VPN device and assigns it an address from the VPN pool. Since the MAC address remains the same for the client, it will re-assign leases upon re-connection.

In order to get this to work, I had to dramatically simplify my server.conf and clinet.conf files compared to the ones in this thread. I have posted them below. You will notice that there are no server bridging and pushing declarations for OpenVPN as it is all handled by the DHCP and DNS.

server.conf
Code:

dev tap0
mode server
tls-server
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
tls-auth ta.key 0
cipher BF-CBC        # Blowfish (default)
comp-lzo
client-to-client
keepalive 10 120
passtos
client-config-dir ccd

Code:

### Client configuration file for OpenVPN
dev tap0
lladdr 00:ff:01:23:45:6f
client
remote example.com 1194
nobind
resolv-retry infinite
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
tls-auth ta.key 1
cipher BF-CBC
comp-lzo
passtos
verb 3
route-delay 10
up "up.sh"
down "down.sh"

On the client, the up.sh and down.sh simply create a tap0 device by calling ifup and ifdown.

Blue_Ice 05-14-2010 06:40 AM

Quote:

Originally Posted by Noway2 (Post 3968150)
I too wanted to have my DHCP assign addresses to remote clients as opposed to having OpenVPN assign the addresses via its pseudo DHCP. I really struggled with this for weeks. My efforts resulted in a slightly different solution to this issue. The blog by Hans Fugal "putting OpenVPN" (http://hans.fugal.net/blog/2009/01/0...-in-its-place/) was VERY helpful in figuring this out.

Hmm, your approach isn't different from mine, actually... It is all based on the same thing. The main differences are in the DHCP config, as I wanted my leases within the same subnet, and my clients have to authenticate using their user account and certificate. The script to create the bridge comes from OpenVPN itself. Actually all the information I used comes from the OpenVPN site. If you are searching long enough, you can find it all back... Unfortunately, it is sometimes hard to find the right clues. OpenVPN is not very clear on how to set up something like this, even though they say it is possible.
Once I figured out that there was a bug in the plugin openvpn-auth-ldap, my issues were solved in a couple of minutes. And that all due to the use of TLS in my OpenLDAP config.

PS: Be aware my servers are running CentOS, not Ubuntu. I don't know if that makes a difference, just to be sure.


All times are GMT -5. The time now is 03:17 PM.