be sure to not restart openvpn indefinetly if it can not use master provider

This commit is contained in:
htouvet
2018-06-29 19:40:40 +02:00
parent d25397d810
commit cb8bac56ea
+39 -32
View File
@@ -134,6 +134,40 @@ Sent 2 probes (1 broadcast(s))
result['alive'] = False result['alive'] = False
return result return result
def openvpn_local_sockets():
"""
Returns:
list of str of IP where openvpn is bound.
"""
(retcode,output) = run("/bin/netstat -lupnw | grep -E '(udp|tcp) .*/openvpn'")
"""
udp 0 0 192.168.1.254:1194 0.0.0.0:* 16919/openvpn
"""
result = []
listening = output.splitlines()
for conn in listening:
args = conn.split()
proto = args[0]
(local_ip,local_port) = args[3].rsplit(':',1)
result.append((proto,local_ip,local_port))
return result
def delete_conntrack(conn):
"""Remove conntrack entries matching the OpenVPN listening processes"""
for (proto,ip,port) in conn:
if ip != '0.0.0.0':
run('/usr/sbin/conntrack -D -p {proto} -s {src} --sport={port}'.format(src=ip,proto=proto,port=port))
else:
run('/usr/sbin/conntrack -D -p {proto} --sport={port}'.format(src=ip,proto=proto,port=port))
def restart_openvpn():
conn = openvpn_local_sockets()
print(run('/etc/init.d/openvpn stop'))
print(run('ip route flush cache'))
delete_conntrack(conn)
print(run('/etc/init.d/openvpn start'))
class Provider(object): class Provider(object):
def __init__(self,provider_name,device=None,gateway=None,target_ip=None,max_rtt=2000.0,max_loss=30,ping_count=10,ping_interval=0.5,timeout=1.5,led=None): def __init__(self,provider_name,device=None,gateway=None,target_ip=None,max_rtt=2000.0,max_loss=30,ping_count=10,ping_interval=0.5,timeout=1.5,led=None):
"""Parameters of an Internet provider as defined in Shorewall and availability limits """Parameters of an Internet provider as defined in Shorewall and availability limits
@@ -186,30 +220,6 @@ ipv4 2 udp 17 178 src=192.168.149.184 dst=80.13.55.10 sport=1194 dport=1194 src=
return True return True
return False return False
def openvpn_local_sockets(self):
"""
Returns:
list of str of IP where openvpn is bound.
"""
(retcode,output) = run("/bin/netstat -lupnw | grep -E '(udp|tcp) .*/openvpn'")
"""
udp 0 0 192.168.1.254:1194 0.0.0.0:* 16919/openvpn
"""
result = []
listening = output.splitlines()
for conn in listening:
args = conn.split()
proto = args[0]
(local_ip,local_port) = args[3].rsplit(':',1)
result.append((proto,local_ip,local_port))
return result
def delete_openvpn_conntrack(self,conn):
"""Remove conntrack entries matching the OpenVPN listening processes"""
for (proto,ip,port) in conn:
if ip != '0.0.0.0':
run('/usr/sbin/conntrack -D -p {proto} -s {src} --sport={port}'.format(src=ip,proto=proto,port=port),dry_run=self.dry_run)
def read_config(self,config_file): def read_config(self,config_file):
for attrib in ['target_ip','device','gateway']: for attrib in ['target_ip','device','gateway']:
if config_file.has_option(self.provider_name,attrib): if config_file.has_option(self.provider_name,attrib):
@@ -433,14 +443,6 @@ available == True if actual rtt and loss are below the max_rtt and max_loss
except Exception as e: except Exception as e:
logger.info('Retrying to disable/enable provider because %s'% e) logger.info('Retrying to disable/enable provider because %s'% e)
print(run('/var/lib/shorewall/firewall restart',dry_run=self.dry_run)) print(run('/var/lib/shorewall/firewall restart',dry_run=self.dry_run))
if self.openvpn_master:
logger.info('Restarting openvpn')
conn = self.openvpn_local_sockets()
print(run('/etc/init.d/openvpn stop',dry_run=self.dry_run))
print(run('ip route flush cache',dry_run=self.dry_run))
print(conn)
self.delete_openvpn_conntrack(conn)
print(run('/etc/init.d/openvpn start',dry_run=self.dry_run))
# here check the connectivity.... else rollback # here check the connectivity.... else rollback
self.update_leds() self.update_leds()
print('Routes after enabling provider %s\n%s'%(self.provider_name,run('/sbin/shorewall show routing'))) print('Routes after enabling provider %s\n%s'%(self.provider_name,run('/sbin/shorewall show routing')))
@@ -682,6 +684,10 @@ if __name__ == '__main__':
if not provider.enabled: if not provider.enabled:
logger.warning("Enabling the available provider {}".format(provider.provider_name)) logger.warning("Enabling the available provider {}".format(provider.provider_name))
provider.enable() provider.enable()
if provider.openvpn_master:
restart_openvpn()
# todo : check balance routing table. If an interface involved in default route is removed (ppp or tun) # todo : check balance routing table. If an interface involved in default route is removed (ppp or tun)
# the entire default route entry is removed by the kernel. # the entire default route entry is removed by the kernel.
# so if we can't find a route which refer to it in balance table, trigger a restart of shorewall to cleanup the situation... # so if we can't find a route which refer to it in balance table, trigger a restart of shorewall to cleanup the situation...
@@ -702,6 +708,7 @@ if __name__ == '__main__':
shorewall_restart_needed = True shorewall_restart_needed = True
logger.critical("Shorewall restart needed because provider {} is not in default balance route ".format(provider.provider_name)) logger.critical("Shorewall restart needed because provider {} is not in default balance route ".format(provider.provider_name))
else: else:
if provider.enabled: if provider.enabled:
if current_ok and not provider.fallback: if current_ok and not provider.fallback: