Exec scripts at sigusr1 and established tunnel
PATCH 1/1 Exec scripts at sigusr1 and established tunnel
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]
openvpn.c Wed Dec 18 19:18:12 2002 renamed from openvpn.c Mon Oct 21 03:46:52 2002 +10 -1
@@ -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);
options.c Wed Dec 18 18:52:24 2002 renamed from options.c Sat Oct 19 23:26:11 2002 +13 -0
@@ -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")) {
options.h Wed Dec 18 18:25:46 2002 renamed from options.h Sat Oct 19 22:25:46 2002 +2 -0
@@ -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;
socket.c Wed Dec 18 18:56:18 2002 renamed from socket.c Sat Oct 19 23:23:19 2002 +18 -0
@@ -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];
socket.h Wed Dec 18 18:49:01 2002 renamed from socket.h Sat Oct 19 23:26:10 2002 +2 -0
@@ -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
Signature · 7 lines
Richard Mueller mailto:[email protected]... 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
Hi Richard,
The failover idea is interesting. I have a couple comments on the patch:
* How is --peerinit different from --ipchange?
* Shouldn't
if ( !(signal_received == SIGUSR1 && !options->sigusr1_script ) )
...
be
if (signal_received == SIGUSR1 && options->sigusr1_script)
...
?
James
Quoted 186 lines · Richard Mueller
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# floatpersist-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-cnbox2"# Routen setzen
peerinit/etc/openvpn/scripts/tun0.up
sigusr1/etc/openvpn/scripts/tun0.downlport 5006
rport 5007comp-lzo
#daemonreneg-sec 600
verb 5
[BOX1: tun1]
# interface configuration dev tun1# Peer connect configuartion
remote 172.16.90.4# floatpersist-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-cnbox2"# Routen setzen
peerinit/etc/openvpn/scripts/tun1.up
sigusr1/etc/openvpn/scripts/tun1.downlport 5506
rport 5507comp-lzo
#daemonreneg-sec 600
verb 5
[BOX2: tun0]
# interface configuration dev tun0# Peer connect configuartion
remote 172.16.90.1# floatpersist-tun
persist-key
ping 7
ping-restart 21ifconfig 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-cnbox1"# Routen setzen
peerinit/etc/openvpn/scripts/tun0.up
sigusr1/etc/openvpn/scripts/tun0.downlport 5007
rport 5006comp-lzo
#daemonreneg-sec 600
verb 5
[BOX1: tun1]
# interface configuration dev tun1# Peer connect configuartion
remote 172.16.90.1# floatpersist-tun
persist-key
ping 7
ping-restart 21ifconfig 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-cnbox1"peerinit
/etc/openvpn/scripts/tun1.up
sigusr1/etc/openvpn/scripts/tun1.downlport 5507
rport 5506comp-lzo
#daemonreneg-sec 600
verb 5
4.) Here is the patch:
[PATCH START]
diff -uopenvpn-1.3.2/openvpn.copenvpn-1.3.2-droute/openvpn.c
openvpn.c Wed Dec 18 19:18:12 2002 line 344
Quoted 5 lines
openvpn.c Wed Dec 18 19:18:12 2002 renamed from openvpn.c Mon Oct 21 03:46:52 2002 +1
-1@@ -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,
openvpn.c Wed Dec 18 19:18:12 2002 line 1406
Quoted 5 lines
openvpn.c Wed Dec 18 19:18:12 2002 renamed from openvpn.c Mon Oct 21 03:46:52 2002 +0
-0options->resolve_retry_seconds); #ifdef USE_CRYPTO@@ -1406,6 +1406,15 @@ run_script (options->down_script, tuntap_actual, MAX_RW_SIZE_TUN
(&frame),
openvpn.c Wed Dec 18 19:18:12 2002 line 1407
Quoted 1 line
openvpn.c Wed Dec 18 19:18:12 2002 renamed from openvpn.c Mon Oct 21 03:46:52 2002 +0
-0max_rw_size_udp, options->ifconfig_local,
options->ifconfig_remote);
Quoted 75 lines
openvpn.c Wed Dec 18 19:18:12 2002 renamed from openvpn.c Mon Oct 21 03:46:52 2002 +9
-0} + /* + * 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.copenvpn-1.3.2-droute/options.coptions.c Wed Dec 18 18:52:24 2002 renamed from options.c Sat Oct 19 23:26:11 2002 +13
-0@@ -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.hopenvpn-1.3.2-droute/options.hoptions.h Wed Dec 18 18:25:46 2002 renamed from options.h Sat Oct 19 22:25:46 2002 +2
-0@@ -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.copenvpn-1.3.2-droute/socket.csocket.c Wed Dec 18 18:56:18 2002 renamed from socket.c Sat Oct 19 23:23:19 2002 +2
-0@@ -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)
socket.c Wed Dec 18 18:56:18 2002 line 194
Quoted 3 lines
socket.c Wed Dec 18 18:56:18 2002 renamed from socket.c Sat Oct 19 23:23:19 2002 +0
-0@@ -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));
socket.c Wed Dec 18 18:56:18 2002
Quoted 7 lines
socket.c Wed Dec 18 18:56:18 2002 renamed from socket.c Sat Oct 19 23:23:19 2002 +7
-0+ + if (sock->peerinit_command) + { + char command[256]; + struct buffer out; + + msg (M_INFO, "Executing peerinit_script
%s",sock->peerinit_command);
Quoted 63 lines
socket.c Wed Dec 18 18:56:18 2002 renamed from socket.c Sat Oct 19 23:23:19 2002 +9
-0+ + 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.hopenvpn-1.3.2-droute/socket.hsocket.h Wed Dec 18 18:49:01 2002 renamed from socket.h Sat Oct 19 23:26:10 2002 +2
-0@@ -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
richardSignature · 19 lines
Richard Mueller mailto:[email protected]... 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 ------------------------------------------------------- This SF.NET email is sponsored by: Order your Holiday Geek Presents Now! Green Lasers, Hip Geek T-Shirts, Remote Control Tanks, Caffeinated Soap, MP3 Players, XBox Games, Flying Saucers, WebCams, Smart Putty. T H I N K G E E K . C O M http://www.thinkgeek.com/sf/ _______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
Hello James,
Thursday, December 19, 2002, 3:59:16 PM, you wrote:
JY> * How is --peerinit different from --ipchange? Good question. None. sh*t Please see below. :)
JY> * Shouldn't
JY> if ( !(signal_received == SIGUSR1 && !options->sigusr1_script ) )
JY> ...
JY> be
JY> if (signal_received == SIGUSR1 && options->sigusr1_script)
JY> ...
JY> ?
d*mn. yes. this is the sprit of "cut'n'paste" coding. Think I pasted the condition some lines above.
I wrote it short afer visiting "Lord of the Rings II" and a 18h workday without any coffee (I am allergic).
So sorry for the bad code, I won't do it again. ;-(
I took the conclusion for me:
$ patch && test && sleep && test && submit
JY> The failover idea is interesting.
It works quite good in my enviroment here (even better after fixing the patch ;) ).
- If openvpn is stopped on both sides, the alternative route is taken immediateley.
- If the link between the two tun-endpoints breaks it takes as long --ping-restart. The prefered route is taken immediateley when the tunnel returns.
Best regards and sorry again for the bad code,
Richard Mueller
Quoted 17 lines · Richard Mueller
Hello James,
Thursday, December 19, 2002, 3:59:16 PM, you wrote:
JY> * How is --peerinit different from --ipchange? Good question. None. sh*t Please see below. :)
JY> * Shouldn't
JY> if ( !(signal_received == SIGUSR1 && !options->sigusr1_script ) )
JY> ...
JY> be
JY> if (signal_received== SIGUSR1 &&options->sigusr1_script)
JY> ...
JY> ?
d*mn. yes. this is the sprit of "cut'n'paste" coding. Think I pasted the condition some lines above.
Quoted 2 lines
I wrote it short afer visiting "Lord of the Rings II" and a 18h workday without any coffee (I am allergic).
Hey, that's an interesting excuse... Tolkien had a great sense of foreboding about the advancing march of technology and industrialization and he would probably have taken some pleasure in knowing that his storyweaving would throw a wrench into the workings of someone's machinery... not to mention being under the influence of a lack of caffeine :)
Quoted 5 lines
So sorry for the bad code, I won't do it again. ;-( I took the conclusion for me:
$ patch && test && sleep && test && submit
Quoted 8 lines
JY> The failover idea is interesting.
It works quite good in my enviroment here (even better after fixing the patch ;) ).- If openvpn is stopped on both sides, the alternative route is taken immediateley.
- If the link between the two tun-endpoints breaks it takes as long
--ping-restart.
Quoted 1 line
The prefered route is taken immediateley when the tunnel returns.
So it looks like all we need is a --sigusr1-script option. That seems pretty reasonable. After you've tested it somewhat, would you mind writing an entry for the HOWTO that explains how to use the ipchange and sigusr1 scripts to set up a failover configuration? Probably just a restatement of what you've described in your emails, but maybe with a bit more detail such as how to set up the Linux Advanced Routing component of the setup. I think people would find it very useful, and this is certainly a case where the code itself (i.e. the script patch) is fairly trivial but the documentation on how to do it is the far more essential component.
Thanks,
James
Quoted 6 lines
Best regards and sorry again for the bad code,
Richard Mueller