Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Jan Just Keijser. OpenVPN 2 Cookbook (2011).pdf
Скачиваний:
193
Добавлен:
18.03.2016
Размер:
10.98 Mб
Скачать

Chapter 6

There's more...

When writing scripts, it is very important to keep the script execution time in mind. The design of OpenVPN 2 is very monolithic: everything (except plugins, which we will come to later in this chapter) is run under a single thread. This means that while a script is executing, the whole OpenVPN server is temporarily unavailable for all other clients: the routing of packets stop, other clients cannot connect or disconnect and even the management interface is not responding. So, it is very important to ensure that all the server-side scripts execute

very quickly.

This design flaw has been recognized, but it is not expected that there will be a major change until the arrival of OpenVPN 3.

Script security and logging

One of the major differences between OpenVPN 2.0 and 2.1 is related to the security when running scripts. With OpenVPN 2.0, all scripts were executed using a 'system' call and the entire set of server environment variables was passed to each script. With OpenVPN 2.1, the script-security configuration directive is introduced and the default for executing scripts is now the execv call, which is more secure. Also, it is wise to log output of your scripts for security reasons. With script logging output, including timestamps, it becomes much easier to track down problems and possible security incidents.

In this recipe, we will focus on the different options for the script-security configuration directive and on the methods to ease the logging of script output.

Getting ready

Install OpenVPN 2.1 or higher on two computers. Make sure the computers are connected over a network. Set up the client and server certificates using the first recipe from Chapter 2. For this recipe, the server computer was running CentOS 5 Linux and OpenVPN 2.1.1. The client was running Fedora 12 Linux and OpenVPN 2.1.1. Keep the server configuration file example6-1-server.conf from the first recipe at hand.

How to do it...

1.Start the OpenVPN server using the configuration file from the first recipe:

[root@server]# openvpn --config example6-1-server.conf

2.Create the client configuration file:

client proto udp

remote openvpnserver.example.com

177

Scripting and Plugins

port 1194

dev tun nobind

ca

/etc/openvpn/cookbook/ca.crt

cert

/etc/openvpn/cookbook/client1.crt

key

/etc/openvpn/cookbook/client1.key

tls-auth /etc/openvpn/cookbook/ta.key 1

ns-cert-type server

up "/etc/openvpn/cookbook/example6-8-up.sh arg1 arg2"

Save it as example6-8-client.conf. Notice the lack of the script-security directive.

3.Create the up script:

#!/bin/bash

exec >> /etc/openvpn/cookbook/example6-8.log 2>&1 date +"%H:%M:%S: START $script_type script ==="

echo "argv = [$0] [$1] [$2] [$3] [$4]" pstree $PPID

date +"%H:%M:%S: END $script_type script ==="

Save it as example6-8-up.sh and make sure it is executable.

4.Start the OpenVPN client:

[client]$ openvpn --config example6-8-client.conf

The client appears to connect successfully until the up script needs to be executed:

/etc/openvpn/cookbook/example6-8-up.sh [arguments]

openvpn_execve: external program may not be called unless '-- script-security 2' or higher is enabled. Use '--script-security 3 system' for backward compatibility with 2.1_rc8 and earlier. See --help text or man page for detailed info.

script failed: external program fork failed

Exiting

178

Chapter 6

5.When we repeat the above with an extra command-line parameter --script-security 2, the client can connect successfully:

[client]$ openvpn --config example6-8-client.conf \

--script-security 2

The log file /etc/openvpn/cookbook/example6-8.log now shows:

19:07:22: START up script ===

argv = [/etc/openvpn/cookbook/example6-8-up.sh] [arg1] [arg2] [tun0] [1500]

openvpn---example6-8-up.s---pstree 19:07:22: END up script ===

If we repeat the above exercise with --script-security 3 or --script-security 2 system directives, we would get a similar output.

How it works...

In order to execute the scripts on either the client or the server, the directive, script-security 2 (or 3) must be specified, otherwise, OpenVPN 2.1 or higher will refuse to start. The following parameters can be specified for the script-security directive:

0: No external programs can be called. This means that OpenVPN cannot successfully start up, except on Microsoft Windows under certain circumstances.

1: Only built-in external programs (such as /sbin/ifconfig, /sbin/ip on Linux, netsh.exe, and route.exe on Windows) can be called.

2: Built-ins and scripts can be called.

3: Same as 2, but now passwords can be passed to scripts via environment variables as well.

There is a second parameter for the script-security directive:

execve: Call external programs using the execve call. This is the default.

system: Call external programs using the system call.

The difference between the two is a minor one, yet there are subtle differences, especially, when spaces are used in pathor filenames.

179

Scripting and Plugins

There's more...

There are subtle differences between running scripts on Linux/NetBSD/Mac OS and on Windows. On Windows, the system call CreateProcess is used by default. If

script-security 2 system is used a system call is used. The biggest difference is seen when spaces are used in pathor filenames. OpenVPN often gets confused which part of a statement is the actual executable and which part are command-line parameters. The following script runs fine when using --script-security 2:

up "c:\\program\ files\\openvpn\\scripts\\example6-8-up.bat"

However, when --script-security 2 system is used, an error is reported:

c:\program' is not recognized as an internal or external command

Using the 'down-root' plugin

OpenVPN supports a plugin architecture, where external plugins can be used to extend the functionality of OpenVPN. Plugins are special modules or libraries that adhere to the OpenVPN Plugin API. One of these plugins is the down-root plugin, which is available only on Linux.

This allows the user to run specified commands as user root when OpenVPN shuts down. Normally, the OpenVPN process drops root privileges (if the --user directive is used) for security reasons. While this is a good security measure, it makes it hard to undo some of the actions that an up script can perform, which is run as user root. For this, the down-root plugin was developed. This recipe will demonstrate how the down-root plugin can be used to remove a file that was created by an up script.

Getting ready

Set up the server certificates using the first recipe from Chapter 2, Client-server IP-only. For this recipe, the server computer was running CentOS 5 Linux and OpenVPN 2.1.1. No client computer was required.

How to do it...

1.Create the server configuration file:

proto udp port 1194 dev tun

server 192.168.200.0 255.255.255.0

ca

/etc/openvpn/cookbook/ca.crt

cert

/etc/openvpn/cookbook/server.crt

180

Chapter 6

key

/etc/openvpn/cookbook/server.key

dh

/etc/openvpn/cookbook/dh1024.pem

tls-auth /etc/openvpn/cookbook/ta.key 0

persist-key persist-tun keepalive 10 60

topology subnet

user nobody

group nobody # nogroup on some distros

daemon

log-append /var/log/openvpn.log

script-security 2

cd /etc/openvpn/cookbook up "example6-9.sh"

plugin ./openvpn-down-root.so "./example6-9.sh --down"

suppress-timestamps verb 5

Save it as example6-9-server.conf.

2.Next, create the up script, which we will also use for the down-root plugin:

#!/bin/sh

if [ "$script_type" = "up" ] then

touch /tmp/example6-9.tempfile

fi

if [ "$1" = "--down" ] then

rm /tmp/example6-9.tempfile

fi

Save it as example6-9.sh and make sure it is executable.

3.Start the OpenVPN server:

[root@server]# openvpn --config example6-9-server.conf

181

Scripting and Plugins

The server log file will now show:

PLUGIN_CALL: POST ./openvpn-down-root.so/PLUGIN_UP status=0 example6-9.sh tun0 1500 1541 192.168.200.1 192.168.200.2 init

This indicates the plugin has started. The fact that there were no error codes right after the up script was executed indicates that it ran successfully.

4.Verify that the file /tmp/example6-9.tempfile was created on the server.

5.Next, stop the server. The server log will now show:

PLUGIN_CALL: POST ./openvpn-down-root.so/PLUGIN_DOWN status=0 PLUGIN_CLOSE: ./openvpn-down-root.so

6.Verify that the file /tmp/example6-9.tempfile has been removed.

How it works...

The down-root plugin is registered at system startup when the OpenVPN server process is still running with root privileges. Plugins are spawned off in a separate thread, meaning that when the main OpenVPN process drops its root privileges, the plugins will still have full root access. When OpenVPN shuts down, the plugin is called and it removes the file created by the user root when the server started.

An interesting part of the server log file is:

/sbin/ifconfig tun0 0.0.0.0 SIOCSIFADDR: Permission denied SIOCSIFFLAGS: Permission denied

Linux ip addr del failed: external program exited with error status: 255

PLUGIN_CALL: POST ./openvpn-down-root.so/PLUGIN_DOWN status=0 PLUGIN_CLOSE: ./openvpn-down-root.so

This indicates that the OpenVPN process was indeed not capable of running the command /sbin/ifconfig tun0 0.0.0.0, proving that root privileges had been successfully dropped. The plugin was then called, which did have root privileges, so that it could remove the root-owned file in /tmp.

Note that it is required to specify a path starting with './' for both the plugin itself and the script that the plugin runs. If the leading './' is not specified on Linux or Mac OS, then OpenVPN will not be able to find the plugin nor the script that the plugin needs to run, as the current directory ('.') normally is not part of the PATH environment variable.

Also note that the up script is called with an environment variable script_type set but that this is not true for plugins. To overcome this, an extra parameter was added so that the same script could be used as both the up and down-root scripts.

182