diff options
Diffstat (limited to 'sample-scripts')
-rwxr-xr-x | sample-scripts/auth-pam.pl | 97 | ||||
-rwxr-xr-x | sample-scripts/bridge-start | 39 | ||||
-rwxr-xr-x | sample-scripts/bridge-stop | 18 | ||||
-rwxr-xr-x | sample-scripts/openvpn.init | 244 | ||||
-rwxr-xr-x | sample-scripts/ucn.pl | 11 | ||||
-rwxr-xr-x | sample-scripts/verify-cn | 52 |
6 files changed, 461 insertions, 0 deletions
diff --git a/sample-scripts/auth-pam.pl b/sample-scripts/auth-pam.pl new file mode 100755 index 0000000..5333bad --- /dev/null +++ b/sample-scripts/auth-pam.pl @@ -0,0 +1,97 @@ +#!/usr/bin/perl -t + +# OpenVPN PAM AUTHENTICATON +# This script can be used to add PAM-based authentication +# to OpenVPN 2.0. The OpenVPN client must provide +# a username/password, using the --auth-user-pass directive. +# The OpenVPN server should specify --auth-user-pass-verify +# with this script as the argument and the 'via-file' method +# specified. The server can also optionally specify +# --client-cert-not-required and/or --username-as-common-name. + +# SCRIPT OPERATION +# Return success or failure status based on whether or not a +# given username/password authenticates using PAM. +# Caller should write username/password as two lines in a file +# which is passed to this script as a command line argument. + +# CAVEATS +# * Requires Authen::PAM module, which may also +# require the pam-devel package. +# * May need to be run as root in order to +# access username/password file. + +# NOTES +# * This script is provided mostly as a demonstration of the +# --auth-user-pass-verify script capability in OpenVPN. +# For real world usage, see the auth-pam module in the plugin +# folder. + +use Authen::PAM; +use POSIX; + +# This "conversation function" will pass +# $password to PAM when it asks for it. + +sub my_conv_func { + my @res; + while ( @_ ) { + my $code = shift; + my $msg = shift; + my $ans = ""; + + $ans = $password if $msg =~ /[Pp]assword/; + + push @res, (PAM_SUCCESS(),$ans); + } + push @res, PAM_SUCCESS(); + return @res; +} + +# Identify service type to PAM +$service = "login"; + +# Get username/password from file + +if ($ARG = shift @ARGV) { + if (!open (UPFILE, "<$ARG")) { + print "Could not open username/password file: $ARG\n"; + exit 1; + } +} else { + print "No username/password file specified on command line\n"; + exit 1; +} + +$username = <UPFILE>; +$password = <UPFILE>; + +if (!$username || !$password) { + print "Username/password not found in file: $ARG\n"; + exit 1; +} + +chomp $username; +chomp $password; + +close (UPFILE); + +# Initialize PAM object + +if (!ref($pamh = new Authen::PAM($service, $username, \&my_conv_func))) { + print "Authen::PAM init failed\n"; + exit 1; +} + +# Authenticate with PAM + +$res = $pamh->pam_authenticate; + +# Return success or failure + +if ($res == PAM_SUCCESS()) { + exit 0; +} else { + print "Auth '$username' failed, PAM said: ", $pamh->pam_strerror($res), "\n"; + exit 1; +} diff --git a/sample-scripts/bridge-start b/sample-scripts/bridge-start new file mode 100755 index 0000000..bfbbdc5 --- /dev/null +++ b/sample-scripts/bridge-start @@ -0,0 +1,39 @@ +#!/bin/bash + +################################# +# Set up Ethernet bridge on Linux +# Requires: bridge-utils +################################# + +# 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="192.168.8.4" +eth_netmask="255.255.255.0" +eth_broadcast="192.168.8.255" + +for t in $tap; do + openvpn --mktun --dev $t +done + +brctl addbr $br +brctl addif $br $eth + +for t in $tap; do + brctl addif $br $t +done + +for t in $tap; do + ifconfig $t 0.0.0.0 promisc up +done + +ifconfig $eth 0.0.0.0 promisc up + +ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast diff --git a/sample-scripts/bridge-stop b/sample-scripts/bridge-stop new file mode 100755 index 0000000..d452893 --- /dev/null +++ b/sample-scripts/bridge-stop @@ -0,0 +1,18 @@ +#!/bin/bash + +#################################### +# Tear Down Ethernet bridge on Linux +#################################### + +# Define Bridge Interface +br="br0" + +# Define list of TAP interfaces to be bridged together +tap="tap0" + +ifconfig $br down +brctl delbr $br + +for t in $tap; do + openvpn --rmtun --dev $t +done diff --git a/sample-scripts/openvpn.init b/sample-scripts/openvpn.init new file mode 100755 index 0000000..6c699cc --- /dev/null +++ b/sample-scripts/openvpn.init @@ -0,0 +1,244 @@ +#!/bin/sh +# +# openvpn This shell script takes care of starting and stopping +# openvpn on RedHat or other chkconfig-based system. +# +# chkconfig: 345 24 76 +# +# description: OpenVPN is a robust and highly flexible tunneling application that +# uses all of the encryption, authentication, and certification features +# of the OpenSSL library to securely tunnel IP networks over a single +# UDP port. +# + +# Contributed to the OpenVPN project by +# Douglas Keller <doug@voidstar.dyndns.org> +# 2002.05.15 + +# To install: +# copy this file to /etc/rc.d/init.d/openvpn +# shell> chkconfig --add openvpn +# shell> mkdir /etc/openvpn +# make .conf or .sh files in /etc/openvpn (see below) + +# To uninstall: +# run: chkconfig --del openvpn + +# Author's Notes: +# +# I have created an /etc/init.d init script and enhanced openvpn.spec to +# automatically register the init script. Once the RPM is installed you +# can start and stop OpenVPN with "service openvpn start" and "service +# openvpn stop". +# +# The init script does the following: +# +# - Starts an openvpn process for each .conf file it finds in +# /etc/openvpn. +# +# - If /etc/openvpn/xxx.sh exists for a xxx.conf file then it executes +# it before starting openvpn (useful for doing openvpn --mktun...). +# +# - In addition to start/stop you can do: +# +# service openvpn reload - SIGHUP +# service openvpn reopen - SIGUSR1 +# service openvpn status - SIGUSR2 +# +# Modifications: +# +# 2003.05.02 +# * Changed == to = for sh compliance (Bishop Clark). +# * If condrestart|reload|reopen|status, check that we were +# actually started (James Yonan). +# * Added lock, piddir, and work variables (James Yonan). +# * If start is attempted twice, without an intervening stop, or +# if start is attempted when previous start was not properly +# shut down, then kill any previously started processes, before +# commencing new start operation (James Yonan). +# * Do a better job of flagging errors on start, and properly +# returning success or failure status to caller (James Yonan). +# +# 2005.04.04 +# * Added openvpn-startup and openvpn-shutdown script calls +# (James Yonan). +# + +# Location of openvpn binary +openvpn="" +openvpn_locations="/usr/sbin/openvpn /usr/local/sbin/openvpn" +for location in $openvpn_locations +do + if [ -f "$location" ] + then + openvpn=$location + fi +done + +# Lockfile +lock="/var/lock/subsys/openvpn" + +# PID directory +piddir="/var/run/openvpn" + +# Our working directory +work=/etc/openvpn + +# Source function library. +. /etc/rc.d/init.d/functions + +# Source networking configuration. +. /etc/sysconfig/network + +# Check that networking is up. +if [ ${NETWORKING} = "no" ] +then + echo "Networking is down" + exit 0 +fi + +# Check that binary exists +if ! [ -f $openvpn ] +then + echo "openvpn binary not found" + exit 0 +fi + +# See how we were called. +case "$1" in + start) + echo -n $"Starting openvpn: " + + /sbin/modprobe tun >/dev/null 2>&1 + + # From a security perspective, I think it makes + # sense to remove this, and have users who need + # it explictly enable in their --up scripts or + # firewall setups. + + #echo 1 > /proc/sys/net/ipv4/ip_forward + + # Run startup script, if defined + if [ -f $work/openvpn-startup ]; then + $work/openvpn-startup + fi + + if [ ! -d $piddir ]; then + mkdir $piddir + fi + + if [ -f $lock ]; then + # we were not shut down correctly + for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do + if [ -s $pidf ]; then + kill `cat $pidf` >/dev/null 2>&1 + fi + rm -f $pidf + done + rm -f $lock + sleep 2 + fi + + rm -f $piddir/*.pid + cd $work + + # Start every .conf in $work and run .sh if exists + errors=0 + successes=0 + for c in `/bin/ls *.conf 2>/dev/null`; do + bn=${c%%.conf} + if [ -f "$bn.sh" ]; then + . $bn.sh + fi + rm -f $piddir/$bn.pid + $openvpn --daemon --writepid $piddir/$bn.pid --config $c --cd $work + if [ $? = 0 ]; then + successes=1 + else + errors=1 + fi + done + + if [ $errors = 1 ]; then + failure; echo + else + success; echo + fi + + if [ $successes = 1 ]; then + touch $lock + fi + ;; + stop) + echo -n $"Shutting down openvpn: " + for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do + if [ -s $pidf ]; then + kill `cat $pidf` >/dev/null 2>&1 + fi + rm -f $pidf + done + + # Run shutdown script, if defined + if [ -f $work/openvpn-shutdown ]; then + $work/openvpn-shutdown + fi + + success; echo + rm -f $lock + ;; + restart) + $0 stop + sleep 2 + $0 start + ;; + reload) + if [ -f $lock ]; then + for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do + if [ -s $pidf ]; then + kill -HUP `cat $pidf` >/dev/null 2>&1 + fi + done + else + echo "openvpn: service not started" + exit 1 + fi + ;; + reopen) + if [ -f $lock ]; then + for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do + if [ -s $pidf ]; then + kill -USR1 `cat $pidf` >/dev/null 2>&1 + fi + done + else + echo "openvpn: service not started" + exit 1 + fi + ;; + condrestart) + if [ -f $lock ]; then + $0 stop + # avoid race + sleep 2 + $0 start + fi + ;; + status) + if [ -f $lock ]; then + for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do + if [ -s $pidf ]; then + kill -USR2 `cat $pidf` >/dev/null 2>&1 + fi + done + echo "Status written to /var/log/messages" + else + echo "openvpn: service not started" + exit 1 + fi + ;; + *) + echo "Usage: openvpn {start|stop|restart|condrestart|reload|reopen|status}" + exit 1 + ;; +esac +exit 0 diff --git a/sample-scripts/ucn.pl b/sample-scripts/ucn.pl new file mode 100755 index 0000000..6d708f8 --- /dev/null +++ b/sample-scripts/ucn.pl @@ -0,0 +1,11 @@ +#!/usr/bin/perl -t + +# OpenVPN --auth-user-pass-verify script. +# Only authenticate if username equals common_name. +# In OpenVPN config file: +# auth-user-pass-verify ./ucn.pl via-env + +$username = $ENV{'username'}; +$common_name = $ENV{'common_name'}; + +exit !(length($username) > 0 && length($common_name) > 0 && $username eq $common_name); diff --git a/sample-scripts/verify-cn b/sample-scripts/verify-cn new file mode 100755 index 0000000..5d56d95 --- /dev/null +++ b/sample-scripts/verify-cn @@ -0,0 +1,52 @@ +#!/usr/bin/perl + +# verify-cn -- a sample OpenVPN tls-verify script +# +# Return 0 if cn matches the common name component of +# X509_NAME_oneline, 1 otherwise. +# +# For example in OpenVPN, you could use the directive: +# +# tls-verify "./verify-cn Test-Client" +# +# This would cause the connection to be dropped unless +# the client common name is "Test-Client" + +die "usage: verify-cn cn certificate_depth X509_NAME_oneline" if (@ARGV != 3); + +# Parse out arguments: +# cn -- The common name which the client is required to have, +# taken from the argument to the tls-verify directive +# in the OpenVPN config file. +# depth -- The current certificate chain depth. In a typical +# bi-level chain, the root certificate will be at level +# 1 and the client certificate will be at level 0. +# This script will be called separately for each level. +# x509 -- the X509 subject string as extracted by OpenVPN from +# the client's provided certificate. +($cn, $depth, $x509) = @ARGV; + +if ($depth == 0) { + # If depth is zero, we know that this is the final + # certificate in the chain (i.e. the client certificate), + # and the one we are interested in examining. + # If so, parse out the common name substring in + # the X509 subject string. + + if ($x509 =~ /\/CN=([^\/]+)/) { + # Accept the connection if the X509 common name + # string matches the passed cn argument. + if ($cn eq $1) { + exit 0; + } + } + + # Authentication failed -- Either we could not parse + # the X509 subject string, or the common name in the + # subject string didn't match the passed cn argument. + exit 1; +} + +# If depth is nonzero, tell OpenVPN to continue processing +# the certificate chain. +exit 0; |