Hello openvpn-developers, I needed two more places in openvpn where to exec some scripts because I wanted to build a "fail-over" solution between two tuns.
1.) Situation: +---------+ tun0 (ISP0) +---------+ | BOX 1 +----------------------+ BOX 2 | | | | | | +----------------------+ | +---------+ tun1 (ISP1) +---------+ tun0 is prefered but if tun0 fails tun1 should do the job. Linux advanced routing has a usable solution for this: Two routing tables with one prefered. Because of this I needed to add/delete routes at this points: - After the first "answer" from the peer (add route for tun?) - At a SIGUSR1 == "peer dead" (del route for tun?) 2.) I used following configs: [BOX1: tun0] # interface configuration dev tun0 # Peer connect configuartion remote 172.16.90.4 # float persist-tun persist-key ping 7 ping-restart 21 # 10.255.253.8 is our local VPN endpoint # 10.255.253.9 is our remote VPN endpoint ifconfig 10.255.254.122 10.255.254.121 # TSL-Client tls-client ca /etc/openvpn/certs/ca.crt cert /etc/openvpn/certs/box1.crt key /etc/openvpn/certs/box1.key tls-verify "/usr/local/sbin/verify-cn box2" # Routen setzen peerinit /etc/openvpn/scripts/tun0.up sigusr1 /etc/openvpn/scripts/tun0.down lport 5006 rport 5007 comp-lzo #daemon reneg-sec 600 verb 5 [BOX1: tun1] # interface configuration dev tun1 # Peer connect configuartion remote 172.16.90.4 # float persist-tun persist-key ping 7 ping-restart 21 # 10.255.253.8 is our local VPN endpoint # 10.255.253.9 is our remote VPN endpoint ifconfig 10.255.253.122 10.255.253.121 # TSL-Client tls-client ca /etc/openvpn/certs/ca.crt cert /etc/openvpn/certs/box1.crt key /etc/openvpn/certs/box1.key tls-verify "/usr/local/sbin/verify-cn box2" # Routen setzen peerinit /etc/openvpn/scripts/tun1.up sigusr1 /etc/openvpn/scripts/tun1.down lport 5506 rport 5507 comp-lzo #daemon reneg-sec 600 verb 5 [BOX2: tun0] # interface configuration dev tun0 # Peer connect configuartion remote 172.16.90.1 # float persist-tun persist-key ping 7 ping-restart 21 ifconfig 10.255.254.121 10.255.254.122 # TSL-Client tls-client ca /etc/openvpn/certs/ca.crt cert /etc/openvpn/certs/box2.crt key /etc/openvpn/certs/box2.key tls-verify "/usr/local/sbin/verify-cn box1" # Routen setzen peerinit /etc/openvpn/scripts/tun0.up sigusr1 /etc/openvpn/scripts/tun0.down lport 5007 rport 5006 comp-lzo #daemon reneg-sec 600 verb 5 [BOX1: tun1] # interface configuration dev tun1 # Peer connect configuartion remote 172.16.90.1 # float persist-tun persist-key ping 7 ping-restart 21 ifconfig 10.255.253.121 10.255.253.122 # TSL-Client tls-client ca /etc/openvpn/certs/ca.crt cert /etc/openvpn/certs/box2.crt key /etc/openvpn/certs/box2.key tls-verify "/usr/local/sbin/verify-cn box1" peerinit /etc/openvpn/scripts/tun1.up sigusr1 /etc/openvpn/scripts/tun1.down lport 5507 rport 5506 comp-lzo #daemon reneg-sec 600 verb 5 4.) Here is the patch: [PATCH START] diff -u openvpn-1.3.2/openvpn.c openvpn-1.3.2-droute/openvpn.c --- openvpn-1.3.2/openvpn.c Mon Oct 21 03:46:52 2002 +++ openvpn-1.3.2-droute/openvpn.c Wed Dec 18 19:18:12 2002 @@ -341,7 +341,7 @@ options->local_port, options->remote_port, options->bind_local, options->remote_float, options->inetd, - udp_socket_addr, options->ipchange, + udp_socket_addr, options->ipchange, options->peerinit_script, options->resolve_retry_seconds); #ifdef USE_CRYPTO @@ -1406,6 +1406,15 @@ run_script (options->down_script, tuntap_actual, MAX_RW_SIZE_TUN (&frame), max_rw_size_udp, options->ifconfig_local, options->ifconfig_remote); } + /* + * Execute sigusr1 script + */ + if ( !(signal_received == SIGUSR1 && !options->sigusr1_script ) ) + { + msg (M_INFO, "Executing sigusr1 script %s",options->sigusr1_script); + system_check (options->sigusr1_script, "sigusr1 command failed", false); + } + done: /* pop our garbage collection level */ gc_free_level (gc_level); diff -u openvpn-1.3.2/options.c openvpn-1.3.2-droute/options.c --- openvpn-1.3.2/options.c Sat Oct 19 23:26:11 2002 +++ openvpn-1.3.2-droute/options.c Wed Dec 18 18:52:24 2002 @@ -316,6 +316,9 @@ SHOW_STR (writepid); SHOW_STR (up_script); SHOW_STR (down_script); + SHOW_STR (peerinit_script); + SHOW_STR (sigusr1_script); + SHOW_STR (down_script); SHOW_BOOL (daemon); SHOW_BOOL (inetd); SHOW_INT (nice); @@ -726,6 +729,16 @@ { ++i; options->down_script = p2; + } + else if (streq(p1, "peerinit") && p2) + { + ++i; + options->peerinit_script = p2; + } + else if (streq(p1, "sigusr1") && p2) + { + ++i; + options->sigusr1_script = p2; } else if (streq (p1, "daemon")) { diff -u openvpn-1.3.2/options.h openvpn-1.3.2-droute/options.h --- openvpn-1.3.2/options.h Sat Oct 19 22:25:46 2002 +++ openvpn-1.3.2-droute/options.h Wed Dec 18 18:25:46 2002 @@ -87,6 +87,8 @@ const char *writepid; const char *up_script; const char *down_script; + const char *peerinit_script; + const char *sigusr1_script; bool daemon; bool inetd; int nice; diff -u openvpn-1.3.2/socket.c openvpn-1.3.2-droute/socket.c --- openvpn-1.3.2/socket.c Sat Oct 19 23:23:19 2002 +++ openvpn-1.3.2-droute/socket.c Wed Dec 18 18:56:18 2002 @@ -105,6 +105,7 @@ bool inetd, struct udp_socket_addr *usa, const char *ipchange_command, + const char *peerinit_command, int resolve_retry_seconds) { CLEAR (*sock); @@ -112,6 +113,7 @@ sock->remote_float = remote_float; sock->addr = usa; sock->ipchange_command = ipchange_command; + sock->peerinit_command = peerinit_command; /* were we started by inetd or xinetd? */ if (inetd) @@ -190,6 +192,22 @@ sock->set_outgoing_initial = true; mutex_unlock (L_SOCK); msg (M_INFO, "Peer Connection Initiated with %s", print_sockaddr (&usa->actual)); + + if (sock->peerinit_command) + { + char command[256]; + struct buffer out; + + msg (M_INFO, "Executing peerinit_script %s",sock->peerinit_command); + + buf_set_write (&out, command, sizeof (command)); + buf_printf (&out, "%s %s", + sock->peerinit_command, + print_sockaddr_ex (&usa->actual, true, " ")); + msg (D_TLS_DEBUG, "executing ip-change command: %s", command); + system_check (command, "peerinit command failed", false); + } + if (sock->ipchange_command) { char command[256]; diff -u openvpn-1.3.2/socket.h openvpn-1.3.2-droute/socket.h --- openvpn-1.3.2/socket.h Sat Oct 19 23:26:10 2002 +++ openvpn-1.3.2-droute/socket.h Wed Dec 18 18:49:01 2002 @@ -42,6 +42,7 @@ bool remote_float; struct udp_socket_addr *addr; const char *ipchange_command; + const char *peerinit_command; int sd; /* file descriptor for socket */ }; @@ -56,6 +57,7 @@ bool inetd, struct udp_socket_addr *addr, const char *ipchange_command, + const char *peerinit_command, int resolve_retry_seconds); void [PATCH START] 5.) If it is interesting for you, James, you are free to clean the code and fix the documentation and merge it in your branch. Just write a Creditline in the changelog. ;-) 6.) Feel free to ask, if you have some questions. bye richard -- Richard Mueller mailto:muel...@teamix.net Fon: +49 9171 896287 Teamix GmbH http://www.teamix.de Fax: +49 9171 896286 PGP Public Key http://www.teamix.net/pgp/rm_public_key_2048 Fingerprint: ea 50 21 6c a5 39 e9 03 a6 59 af e3 c5 1f 63 8e Networks - Consulting - Training - Software Development - eCommerce