aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2013-06-16 17:07:00 +0200
committerLaurent Ghigonis <laurent@p1sec.com>2013-06-16 17:07:00 +0200
commita5bf74a6df654c5b9a0d419278c0c4a57f460c92 (patch)
tree12c6716a4d798dfb15e62f467af86597a4c678a8
parentadd READMEs around (diff)
downloadlaurent-tools-a5bf74a6df654c5b9a0d419278c0c4a57f460c92.tar.xz
laurent-tools-a5bf74a6df654c5b9a0d419278c0c4a57f460c92.zip
add covpn - Wrapper to run OpenVPN with server push filtering, tcp/udp/defgw modes
Diffstat (limited to '')
-rw-r--r--covpn/README.txt25
-rw-r--r--covpn/conf/covpn.conf21
-rwxr-xr-xcovpn/conf/openvpn-up.sh47
-rw-r--r--covpn/conf/openvpn.conf30
-rwxr-xr-xcovpn/covpn.sh85
5 files changed, 208 insertions, 0 deletions
diff --git a/covpn/README.txt b/covpn/README.txt
new file mode 100644
index 0000000..c6893bb
--- /dev/null
+++ b/covpn/README.txt
@@ -0,0 +1,25 @@
+covpn - Wrapper to run OpenVPN with server push filtering, tcp/udp/defgw modes
+2013, Laurent Ghigonis <laurent@gouloum.fr>
+
+
+sudo covpn.sh [-g] [-t] <conf_path>
+
+Examples
+========
+
+# Run in UDP mode and not modifying default gateway (default)
+./covpn.sh conf/
+
+# Run in UDP mode, overriding the default gateway
+# (restores it on exit)
+./covpn.sh -g conf/
+
+# Run in TCP mode
+./covpn.sh -t conf/
+
+
+Configuration
+=============
+
+Configuration is in conf/ by default
+You should edit covpn.conf and openvpn.conf, and add your OpenVPN keys there
diff --git a/covpn/conf/covpn.conf b/covpn/conf/covpn.conf
new file mode 100644
index 0000000..06e1f6c
--- /dev/null
+++ b/covpn/conf/covpn.conf
@@ -0,0 +1,21 @@
+# Configuration file for copvn
+
+# OpenVPN configuration options, for covpn.sh
+
+CONF_UDP_REMOTE="X.X.X.X 1194" # IP of the VPN concentrator + UDP port
+CONF_TCP_REMOTE="X.X.X.X 443" # IP of the VPN concentrator + TCP port
+
+# Filtering pushed options from server, for openvpn-up.sh
+
+# Your DNS IP (regex), via dhcp-option DNS <ip>
+# Set to "disable" to forbid any DNS changes
+EXPECTED_DNS="192.168.99.254"
+# Attributed IP range (regex)
+EXPECTED_IP_RANGE="192.168.99.[0-9]+"
+# VPN subnet IP range (regex)
+EXPECTED_ROUTE_RANGE="192.168.99.[0-9]+"
+# VPN subnet netmask (regex)
+EXPECTED_ROUTE_MASK="255.255.255.0"
+# VPN default gateway (regex)
+EXPECTED_GATEWAY="192.168.99.254"
+
diff --git a/covpn/conf/openvpn-up.sh b/covpn/conf/openvpn-up.sh
new file mode 100755
index 0000000..0f017a1
--- /dev/null
+++ b/covpn/conf/openvpn-up.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# OpenVPN up.sh script, part of covpn
+# Filters input from OpenVPN, usefull for checking IPs/ranges/DNS pushed by an
+# OpenVPN server
+# 2013 Laurent Ghigonis <laurent@gouloum.fr>
+
+# Reads its configuration (EXPECTED_* vars) from $covpn_conf
+
+# Some env vars also available:
+# script_context=init
+# script_type=up
+
+if [ ! -f $covpn_conf ]; then
+ echo "covpn openvpn-up.sh: ERROR: $covpn_conf not found !"
+ exit 99
+fi
+. $covpn_conf
+
+dns=`echo $foreign_option_1 |cut -d' ' -f3`
+if [ X"$dns" != X"" -a X"$EXPECTED_DNS" != X"disable" ]; then
+ echo $dns |egrep -q "^$EXPECTED_DNS$" ||exit 10
+else
+ dns="none"
+fi
+echo $dev |egrep -q "^tun[0-9]$" ||exit 11
+test $tun_mtu -gt 200 -a $tun_mtu -lt 2000 ||exit 12
+echo $ifconfig_local |egrep -q "^$EXPECTED_IP_RANGE$" ||exit 13
+echo $ifconfig_remote |egrep -q "^$EXPECTED_IP_RANGE$" ||exit 14
+echo $route_network_1 |egrep -q "^$EXPECTED_ROUTE_RANGE$" ||exit 15
+echo $route_netmask_1 |egrep -q "^$EXPECTED_ROUTE_MASK$" ||exit 16
+echo $route_network_2 |egrep -q "^$EXPECTED_GATEWAY$" ||exit 17
+
+/usr/sbin/ip addr add $ifconfig_local peer $ifconfig_remote dev $dev ||exit 20
+/usr/sbin/ip link set $dev mtu $tun_mtu ||exit 21
+/usr/sbin/ip link set $dev up ||exit 22
+/usr/sbin/ip route add ${route_network_1}/${route_netmask_1} dev $dev ||exit 23
+if [ X"$openvpn_gateway" = X"1" ]; then
+ /usr/sbin/ip route add $remote_1 via $route_net_gateway
+ /usr/sbin/ip route delete default
+ /usr/sbin/ip route add 0/1 via $route_network_2
+ /usr/sbin/ip route add 128/1 via $route_network_2
+fi
+if [ $dns != "none" ]; then
+ cp /etc/resolv.conf /etc/resolv.conf.bak-covpn
+ echo "nameserver $dns" > /etc/resolv.conf ||exit 24
+fi
diff --git a/covpn/conf/openvpn.conf b/covpn/conf/openvpn.conf
new file mode 100644
index 0000000..494f812
--- /dev/null
+++ b/covpn/conf/openvpn.conf
@@ -0,0 +1,30 @@
+# OpenVPN client configuration file
+# Part of covpn
+
+client
+dev tun
+# proto: given by covpn command line, see covpn.conf
+# remote: given by covpn command line, see covpn.conf
+
+resolv-retry infinite
+nobind
+
+persist-key
+persist-tun
+
+ca ca.crt
+cert client.crt
+key client.key
+
+ns-cert-type server
+tls-auth ta.key 1
+
+comp-lzo
+
+ifconfig-noexec
+route-noexec
+script-security 2
+up openvpn-up.sh
+user openvpn
+group openvpn
+
diff --git a/covpn/covpn.sh b/covpn/covpn.sh
new file mode 100755
index 0000000..6139909
--- /dev/null
+++ b/covpn/covpn.sh
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+# covpn - Wrapper to run OpenVPN with server push filtering, tcp/udp/defgw modes
+# 2013 Laurent Ghigonis <laurent@gouloum.fr>
+
+# Works together with correct openvpn-up.sh
+# Uses same config file for UDP and TCP, passing --proto and --remote in command line
+# Change of default gateway and DNS is done in openvpn-up.sh
+# Passes env var 'openvpn_gateway' to openvpn-up.sh in case default gw is set to VPN
+# Passes env var 'covpn_conf' to openvpn-up.sh to load it's configuration
+
+usage_exit() {
+ echo "`basename $0` [-g] [-t] <conf_path>"
+ exit 1
+}
+
+restore() {
+ restore_gateway
+ restore_dns
+}
+
+restore_gateway() {
+ echo "INFO: check_gateway"
+ gw_cur=`ip route show 0/0 |cut -d' ' -f3`
+ echo "INFO: gw_cur=$gw_cur"
+ if [ "$gw_before" != "$gw_cur" ]; then
+ echo "INFO: Gateway changed (before=$gw_before, cur=$gw_cur)"
+ echo "INFO: Restoring previous default gw"
+ /usr/sbin/ip route delete default
+ /usr/sbin/ip route add default via $gw_before
+ fi
+}
+
+restore_dns() {
+ echo "INFO: check_dns"
+ if [ -f /etc/resolv.conf.bak-covpn ]; then
+ echo "INFO: restoring previous DNS"
+ mv /etc/resolv.conf.bak-covpn /etc/resolv.conf
+ fi
+}
+
+if [ `id -u` -ne 0 ]; then
+ echo "must be root"
+ exit 1
+fi
+
+gw_before=`ip route show 0/0 |cut -d' ' -f3`
+
+opts="$(getopt -o gth -l gateway,tcp,help -n "$program" -- "$@")"
+openvpn_proto="udp"
+gateway=0
+err=$?
+echo "INFO: gw_before=$gw_before"
+eval set -- "$opts"
+while true; do case $1 in
+ -g|--gateway) gateway=1; shift;;
+ -t|--tcp) openvpn_proto="tcp"; shift ;;
+ -h|--help) usage_exit ;;
+ --) shift; break ;;
+esac done
+test $err -ne 0 && usage_exit
+test $# -lt 1 && usage_exit
+conf_path=`readlink -f $1`
+shift
+
+covpn_conf="$conf_path/covpn.conf"
+if [ ! -f $covpn_conf ]; then
+ echo "ERROR: missing covpn.conf in $conf_path !"
+ exit 1
+fi
+. $covpn_conf
+
+if [ $openvpn_proto = "udp" ]; then
+ openvpn_remote="$CONF_UDP_REMOTE"
+else
+ openvpn_remote="$CONF_TCP_REMOTE"
+fi
+
+trap restore INT TERM EXIT
+
+/usr/sbin/openvpn --setenv openvpn_gateway $gateway \
+ --setenv covpn_conf $covpn_conf \
+ --cd $conf_path --config openvpn.conf --chroot $conf_path \
+ --proto $openvpn_proto --remote $openvpn_remote $@
+