From bd217f066655aca116f99f7c1fa949bf3293494b Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Thu, 10 Dec 2020 16:14:17 +0100 Subject: [PATCH] bundles/pppd: automatically restart pppoe (once per hour) if no public ip address can be found --- .../pppd/files/restart-pppoe-if-no-public-ip | 46 +++++++++++++++++++ bundles/pppd/items.py | 3 ++ bundles/pppd/metadata.py | 4 ++ nodes/home/router.py | 2 +- 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 bundles/pppd/files/restart-pppoe-if-no-public-ip diff --git a/bundles/pppd/files/restart-pppoe-if-no-public-ip b/bundles/pppd/files/restart-pppoe-if-no-public-ip new file mode 100644 index 0000000..04e1fcd --- /dev/null +++ b/bundles/pppd/files/restart-pppoe-if-no-public-ip @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 + +from datetime import datetime +from ipaddress import ip_address +from subprocess import run +from sys import exit + +import netifaces + +now = int(datetime.timestamp(datetime.utcnow())) + +try: + with open('/var/tmp/pppd-last-restart.status', 'r') as f: + last_restart = int(f.read().strip()) +except: + last_restart = 0 + +if now-3600 < last_restart: + print('Last restart is less than an hour ago, exiting ...') + exit(0) + +ifaces = set() +for i in netifaces.interfaces(): + if i.startswith('ppp'): + ifaces.add(i) + +system_has_public_ip = False +for iface in ifaces: + for type in [netifaces.AF_INET, netifaces.AF_INET6]: + for ip in netifaces.ifaddresses(iface)[type]: + try: + addr = ip_address(ip['addr']) + + if not addr.is_private and not addr.is_loopback: + system_has_public_ip = True + except: + # Apparently not an ip + pass + +if not system_has_public_ip: + run(['systemctl', 'restart', 'pppoe']) + + with open('/var/tmp/pppd-last-restart.status', 'w') as f: + f.write(now) + + print('pppoe.service has been restarted') diff --git a/bundles/pppd/items.py b/bundles/pppd/items.py index c281c74..3f4395a 100644 --- a/bundles/pppd/items.py +++ b/bundles/pppd/items.py @@ -81,6 +81,9 @@ files = { 'svc_systemd:pppoe:restart', }, }, + '/usr/local/bin/restart-pppoe-if-no-public-ip': { + 'mode': '0755', + }, } if 'dyndns' in node.metadata['pppd']: diff --git a/bundles/pppd/metadata.py b/bundles/pppd/metadata.py index 909dfe3..ca29ca4 100644 --- a/bundles/pppd/metadata.py +++ b/bundles/pppd/metadata.py @@ -4,7 +4,11 @@ defaults = { 'ppp': {}, 'pppoe': {}, 'python3-requests': {}, + 'python3-netifaces': {}, 'ndisc6': {}, }, }, + 'cron': { + 'restart-pppoe-if-no-public-ip': '*/5 * * * * root /usr/local/bin/restart-pppoe-if-no-public-ip', + }, } diff --git a/nodes/home/router.py b/nodes/home/router.py index e2706f1..997d42d 100644 --- a/nodes/home/router.py +++ b/nodes/home/router.py @@ -41,7 +41,7 @@ nodes['home.router'] = { # connected longer than 24 hours. We install this cronjob # to make sure we don't get disconnected randomly during the # day. - 'restart_pppd': '23 2 * * * root systemctl restart pppoe', + 'restart_pppd': '23 2 * * * root systemctl restart pppoe && date -u +%s > /var/tmp/pppd-last-restart.status', }, 'dhcpd': { 'subnets': {