Compare commits
	
		
			33 Commits
		
	
	
		
			no_livebox
			...
			master
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 31f5e94ae1 | |||
| 60b13d46f7 | |||
| f0033fb61a | |||
| b1a296f05a | |||
| ff4302cf0a | |||
| a63bd3a5a5 | |||
| 2f970cd71c | |||
| 677db2e9a6 | |||
| 893327c31d | |||
| a30efabbda | |||
| 6cb57c6dbf | |||
| f4652bfc12 | |||
| 2534a41a27 | |||
| 819df7f6e1 | |||
| 8c4f998018 | |||
| 055f4949cd | |||
| 79337e8411 | |||
| 11c20250b9 | |||
| 0616e22e0c | |||
| 79eb79f46c | |||
| 5aa8575127 | |||
| 6894ee25d9 | |||
| 7fb17678b8 | |||
| 2609ce5f6d | |||
| 7599ec2684 | |||
| bdcf586a6c | |||
| 95a20f78e5 | |||
| 67335c198b | |||
| 306d4b536e | |||
| df66e50d47 | |||
| 841e6043c6 | |||
| 2cc7d966a0 | |||
| 6c4bc82319 | 
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
|  | *.log | ||||||
| home.conf | home.conf | ||||||
| ovh.conf | ovh.conf | ||||||
| zone.list | zone.json | ||||||
| zone.log |  | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								README
									
									
									
									
									
								
							| @@ -143,6 +143,10 @@ Setup - Réseau local | |||||||
|  |  | ||||||
|         Chaque mise à jour génerera un mail qui sera envoyé à cette adresse. |         Chaque mise à jour génerera un mail qui sera envoyé à cette adresse. | ||||||
|  |  | ||||||
|  | * configuration [MailIgnore]: | ||||||
|  |  | ||||||
|  | 	Si les mises à jour ne concernent que des entrées dans cette liste | ||||||
|  | 	le mail ne sera pas envoyé | ||||||
|  |  | ||||||
| Utilisation | Utilisation | ||||||
| ----------- | ----------- | ||||||
|   | |||||||
							
								
								
									
										419
									
								
								dyndomain
									
									
									
									
									
								
							
							
						
						
									
										419
									
								
								dyndomain
									
									
									
									
									
								
							| @@ -1,10 +1,12 @@ | |||||||
| #!/usr/bin/python3 | #!/usr/bin/python3 | ||||||
|  |  | ||||||
| import sys |  | ||||||
| import os |  | ||||||
| import configparser | import configparser | ||||||
| import subprocess | import copy | ||||||
|  | import json | ||||||
|  | import os | ||||||
| import smtplib | import smtplib | ||||||
|  | import subprocess | ||||||
|  | import sys | ||||||
| import time | import time | ||||||
| from email.message import EmailMessage | from email.message import EmailMessage | ||||||
| from pprint import pprint | from pprint import pprint | ||||||
| @@ -12,15 +14,16 @@ from pprint import pprint | |||||||
| rundir=os.path.realpath(os.path.dirname(sys.argv[0])) | rundir=os.path.realpath(os.path.dirname(sys.argv[0])) | ||||||
| os.chdir(rundir) | os.chdir(rundir) | ||||||
|  |  | ||||||
|  | sys.path.append(os.path.join(rundir,'sysbus/src')) | ||||||
| from sysbus import sysbus | from sysbus import sysbus | ||||||
| from ovh import ovh | from ovh import ovh | ||||||
|  |  | ||||||
|  |  | ||||||
| def load_conf(): | def load_conf(): | ||||||
|     global zone_filename, log_filename |     global zone_filename, log_filename | ||||||
|     global wan_hostname, zone_domain, zone_subdomain |     global wan_hostname, zone_domain, zone_subdomain, zone_timeout | ||||||
|     global hosts_list, hosts_ipv4_nat_list |     global hosts_list, nat_list, pinhole_list | ||||||
|     global mail_from, mail_to |     global mail_from, mail_to, mail_ignore_list | ||||||
|  |  | ||||||
|     conf = configparser.ConfigParser(allow_no_value=True) |     conf = configparser.ConfigParser(allow_no_value=True) | ||||||
|     conf.read('home.conf') |     conf.read('home.conf') | ||||||
| @@ -28,39 +31,88 @@ def load_conf(): | |||||||
|     zone_filename = conf['Files']['zonefile'] |     zone_filename = conf['Files']['zonefile'] | ||||||
|     log_filename = conf['Files']['logfile'] |     log_filename = conf['Files']['logfile'] | ||||||
|  |  | ||||||
|     wan_hostname = conf['Wan']['hostname'] |     wan_hostname = conf['Wan']['hostname'].lower() | ||||||
|     zone_domain = conf['Zone']['domain'] |     zone_domain = conf['Zone']['domain'].lower() | ||||||
|     zone_subdomain = conf['Zone']['subdomain'] |     zone_subdomain = conf['Zone']['subdomain'].lower() | ||||||
|     mail_from = conf['Mail']['from'] |     mail_from = conf['Mail']['from'] | ||||||
|     mail_to   = conf['Mail']['to'] |     mail_to   = conf['Mail']['to'] | ||||||
|  |     mail_ignore_list = [ host.lower() for host in conf['MailIgnore'] ] | ||||||
|  |     mail_ignore_list = [ '.'.join([h, zone_subdomain]) if not h.endswith('.'+zone_subdomain) else h for h in mail_ignore_list ] | ||||||
|  |  | ||||||
|     hosts_list = [ host for host in conf['Hosts'] ] |     hosts_list = [ host.lower() for host in conf['Hosts'] ] | ||||||
|     hosts_ipv4_nat_list = [ host for host in conf['NatHosts'] ] |  | ||||||
|  |     nat_list = {} | ||||||
|  |     for e in conf.items('PortsNat'): | ||||||
|  |         if e[1]: | ||||||
|  |             nat_list[e[0]] = e[1].split(',') | ||||||
|  |         else: | ||||||
|  |             nat_list[e[0]] = [] | ||||||
|  |  | ||||||
|  |     pinhole_list = {} | ||||||
|  |     for e in conf.items('Firewall'): | ||||||
|  |         if e[1]: | ||||||
|  |             pinhole_list[e[0]] = e[1].split(',') | ||||||
|  |         else: | ||||||
|  |             pinhole_list[e[0]] = [] | ||||||
|  |     zone_timeout = conf['Zone']['keep'] | ||||||
|  |     if zone_timeout[-1] == 's': | ||||||
|  |         zone_timeout = int(zone_timeout[:-1]) | ||||||
|  |     elif zone_timeout[-1] == 'm': | ||||||
|  |         zone_timeout = int(zone_timeout[:-1]) * 60 | ||||||
|  |     elif zone_timeout[-1] == 'h': | ||||||
|  |         zone_timeout = int(zone_timeout[:-1]) * 3600 | ||||||
|  |     elif zone_timeout[-1] == 'd': | ||||||
|  |         zone_timeout = int(zone_timeout[:-1]) * 86400 | ||||||
|  |     else: | ||||||
|  |         zone_timeout = int(zone_timeout) | ||||||
|  |  | ||||||
|  |  | ||||||
| def ping(hostname): | def ping(hostname): | ||||||
|     cmd = "ping -c1 -w3 %s" % hostname |     cmd = "ping -4 -c1 -w3 %s" % hostname | ||||||
|     ret = subprocess.run(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) |     ret = subprocess.run(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||||||
|     return 0 if ret.returncode else 1 |     return 0 if ret.returncode else 1 | ||||||
|  |  | ||||||
| def get_ipv6_hosts(): |  | ||||||
|     r = sysbus.requete('Hosts:getDevices') |  | ||||||
|  |  | ||||||
|     ipv6_hosts = dict() | def get_hosts(): | ||||||
|     for host in r['status']: |     r = sysbus.requete('Devices:get', silent=True) | ||||||
|         hostname=host['hostName'] |     hosts = { 'A': {}, 'AAAA': {} } | ||||||
|         for addr in host['addresses']: |     if not r: | ||||||
|             ipv6_hosts[hostname] = [] |         return hosts | ||||||
|             if addr['family'] == 'IPv6' and addr['scope'] == 'global': |  | ||||||
|                 ipv6_hosts[hostname].append(addr['ipAddress']) |     for h in r['status']: | ||||||
|     return ipv6_hosts |         ns = {} | ||||||
|  |         for n in h['Names']: | ||||||
|  |             ns[n['Source']] = n['Name'] | ||||||
|  |         hostname = h['Name'] | ||||||
|  |         hostname = ns.get('mdns', hostname) | ||||||
|  |         hostname = ns.get('dhcp', hostname) | ||||||
|  |         hostname = ns.get('webui', hostname) | ||||||
|  |         hostname = hostname.lower() | ||||||
|  |         for a in h.get('IPv6Address', []): | ||||||
|  |             if a['Scope'] != 'global' or a['Status'] != 'reachable': | ||||||
|  |                 continue | ||||||
|  |             if not hostname in hosts['AAAA']: | ||||||
|  |                 hosts['AAAA'][hostname] = [] | ||||||
|  |             hosts['AAAA'][hostname].append(a['Address']) | ||||||
|  |         for a in h.get('IPv4Address', []): | ||||||
|  |             if a['Scope'] != 'global' or a['Status'] != 'reachable': | ||||||
|  |                 continue | ||||||
|  |             if not hostname in hosts['A']: | ||||||
|  |                 hosts['A'][hostname] = [] | ||||||
|  |             hosts['A'][hostname].append(a['Address']) | ||||||
|  |     return hosts | ||||||
|  |  | ||||||
|  |  | ||||||
| def get_wan_addr(): | def get_wan_addr(): | ||||||
|     r = sysbus.requete('NMC:getWANStatus') |     r = sysbus.requete('NMC:getWANStatus', silent=True) | ||||||
|     wan = dict() |     wan = dict() | ||||||
|  |     if not r or not r.get('data') or not r['data'].get('IPAddress') or not r['data'].get('IPv6Address'): | ||||||
|  |         log('get_wan_addr: {}'.format(r)) | ||||||
|  |         return None | ||||||
|     wan['ipv4'] = r['data']['IPAddress'] |     wan['ipv4'] = r['data']['IPAddress'] | ||||||
|     wan['ipv6'] = r['data']['IPv6Address'] |     wan['ipv6'] = r['data']['IPv6Address'] | ||||||
|  |     if wan['ipv4'] == '0.0.0.0': | ||||||
|  |         wan['ipv4'] = '' | ||||||
|     return wan |     return wan | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -69,96 +121,225 @@ def full_name(host, domain): | |||||||
|     return '.'.join([host, domain]) |     return '.'.join([host, domain]) | ||||||
|  |  | ||||||
|  |  | ||||||
| def make_zone_list(wan_hostname, wan_addr, hosts, hosts_nat, domain): | def zone_add_entry(zone, prot, key, value, stamp): | ||||||
|     zone = [] |     #print('zone_add_entry: {} {} {} {}'.format(prot, key, value, stamp)) | ||||||
|  |     if not zone.get(prot): | ||||||
|  |         zone[prot] = {} | ||||||
|  |     if not zone[prot].get(key): | ||||||
|  |         zone[prot][key] = {} | ||||||
|  |     if not zone[prot][key].get(value): | ||||||
|  |         zone[prot][key][value] = { 'first': stamp } | ||||||
|  |     zone[prot][key][value]['last'] = stamp | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def populate_zone(zone, wan_hostname, wan_addr, hosts, hosts_list, hosts_nat, pinhole_list, domain, stamp): | ||||||
|     wan_hostname = full_name(wan_hostname, domain) |     wan_hostname = full_name(wan_hostname, domain) | ||||||
|  |  | ||||||
|  |     if not zone.get('A'): | ||||||
|  |         zone['A'] = {} | ||||||
|  |     if not zone.get('AAAA'): | ||||||
|  |         zone['AAAA'] = {} | ||||||
|  |  | ||||||
|     if wan_addr['ipv4'] != '': |     if wan_addr['ipv4'] != '': | ||||||
|         zone.append([wan_hostname, 'A', wan_addr['ipv4']]) |         zone_add_entry(zone, 'A', wan_hostname, wan_addr['ipv4'], stamp) | ||||||
|         for host in hosts_nat: |         for host in hosts_nat: | ||||||
|             zone.append([full_name(host, domain), 'A', wan_addr['ipv4']]) |             if hosts['A'].get(host): | ||||||
|  |                 zone_add_entry(zone, 'A', full_name(host, domain), wan_addr['ipv4'], stamp) | ||||||
|  |                 # we can only add PortNat entry for on Address, | ||||||
|  |                 # so let's arbitrarely take the 1st one | ||||||
|  |                 for port in hosts_nat[host]: | ||||||
|  |                     zone_add_entry(zone, 'nat', hosts['A'][host][0], port, stamp) | ||||||
|  |  | ||||||
|     if wan_addr['ipv6'] != '': |     if wan_addr['ipv6'] != '': | ||||||
|         zone.append([wan_hostname, 'AAAA', wan_addr['ipv6']]) |         zone_add_entry(zone, 'AAAA', wan_hostname, wan_addr['ipv6'], stamp) | ||||||
|         for host in hosts: |         for host in hosts_list: | ||||||
|             for addr in hosts[host]: |             for addr in hosts['AAAA'].get(host, []): | ||||||
|                 if host in hosts_list: |                 zone_add_entry(zone, 'AAAA', full_name(host, domain), addr, stamp) | ||||||
|                     zone.append([full_name(host, domain), 'AAAA', addr]) |                 for port in pinhole_list.get(host, []): | ||||||
|  |                     zone_add_entry(zone, 'pin', addr, port, stamp) | ||||||
|     return zone |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def read_zone_list_from_file(zone_filename): |  | ||||||
|     zone_list = [] | def process_zone(zone, stamp, grace_period, sync_zone): | ||||||
|     config = configparser.ConfigParser() |     update = { 'add': [], 'delete': [] } | ||||||
|     config.read(zone_filename) |     for prot in zone: | ||||||
|     for host in config: |         for name in zone[prot]: | ||||||
|         for p in config[host]: |             active = False | ||||||
|             zone_list.append([host, p.upper(), config[host][p]]) |             for addr in zone[prot][name]: | ||||||
|     return zone_list |                 e = zone[prot][name][addr] | ||||||
|  |                 if e['first'] == stamp: | ||||||
|  |                     update['add'].append([prot, name, addr]) | ||||||
|  |                 if e['last'] == stamp: | ||||||
|  |                     active = True | ||||||
|  |             for addr in zone[prot][name]: | ||||||
|  |                 e = zone[prot][name][addr] | ||||||
|  |                 if active and e['last'] < stamp: | ||||||
|  |                     update['delete'].append([prot, name, addr]) | ||||||
|  |                 elif not active and stamp - e['last'] > grace_period: | ||||||
|  |                     update['delete'].append([prot, name, addr]) | ||||||
|  |                 elif sync_zone: | ||||||
|  |                     update['add'].append([prot, name, addr]) | ||||||
|  |  | ||||||
|  |     if not update['add'] and not update['delete']: | ||||||
|  |         update = None | ||||||
|  |     return update | ||||||
|  |  | ||||||
|  |  | ||||||
| def make_update_zone_list(zone_list, prev_zone_list): | def read_zone_list(zone_filename): | ||||||
|     update_zone_list = [] |     try: | ||||||
|     for entry in zone_list: |         with open(zone_filename) as jsonfile: | ||||||
|         if not any(entry == x for x in prev_zone_list): |             zone = json.load(jsonfile) | ||||||
|             update_zone_list.append(entry) |         return zone | ||||||
|     return update_zone_list |     except FileNotFoundError: | ||||||
|  |         return {} | ||||||
|  |  | ||||||
|  |  | ||||||
| def write_zone_list_to_file(zone_filename, zone_list): | def write_zone_list(zone_filename, zone, update): | ||||||
|     config = configparser.ConfigParser() |     zone = copy.deepcopy(zone) | ||||||
|     for host,typefield,target in zone_list: |     if update: | ||||||
|         if not host in config: |         for prot, name, addr in update['delete']: | ||||||
|             config[host] = {} |             del zone[prot][name][addr] | ||||||
|         config[host][typefield] = target |             if not zone[prot][name]: | ||||||
|     with open(zone_filename, 'w') as configfile: |                 del zone[prot][name] | ||||||
|         config.write(configfile) |     with open(zone_filename, 'w') as jsonfile: | ||||||
|  |         json.dump(zone, jsonfile, indent=2, sort_keys=True) | ||||||
|  |  | ||||||
|  |  | ||||||
| def log(msg): | def log(msg): | ||||||
|     stamp = time.strftime("%Y-%m-%d %H:%M:%S") |     stamp = time.strftime("%Y-%m-%d %H:%M:%S") | ||||||
|     with open(log_filename, 'a') as logfile: |     if sys.stdout.isatty(): | ||||||
|         for line in msg.split('\n'): |         for line in msg.split('\n'): | ||||||
|             logfile.write("%s - %s\n" % (stamp, msg)) |             print("%s - %s" % (stamp, msg)) | ||||||
|  |     else: | ||||||
|  |         with open(log_filename, 'a') as logfile: | ||||||
|  |             for line in msg.split('\n'): | ||||||
|  |                 logfile.write("%s - %s\n" % (stamp, msg)) | ||||||
|  |  | ||||||
|  |  | ||||||
| def log_update_zone(zone_list): | def log_update_zone(update): | ||||||
|     for host,typea,addr in zone_list: |     op_str = { 'add': '', 'delete': '[DEL]' } | ||||||
|         log("%-20s %-6s %s" % (host, typea, addr)) |  | ||||||
|  |     for op in update: | ||||||
|  |         for prot, name, addr in update[op]: | ||||||
|  |             op = op_str.get(op, op) | ||||||
|  |             log('%5s %-20s %-6s %s' % (op, name, prot, addr)) | ||||||
|  |  | ||||||
|  |  | ||||||
| def ovh_update_zone(domain, zone_list): | def ovh_update_zone(domain, zone, update, sync_zone): | ||||||
|     if not len(zone_list): |     try: | ||||||
|  |         client = ovh.Client() | ||||||
|  |  | ||||||
|  |         if sync_zone: | ||||||
|  |             for prot in ['A', 'AAAA']: | ||||||
|  |                 for name in zone.get(prot, []): | ||||||
|  |  | ||||||
|  |                     result = client.get('/domain/zone/{}/record'.format(domain), | ||||||
|  |                                         fieldType=prot, subDomain=name) | ||||||
|  |                     for id in result: | ||||||
|  |                         log('OVH: delete entry #{} {} {}'.format(id, name, prot)) | ||||||
|  |                         client.delete('/domain/zone/{}/record/{}'.format(domain, id)) | ||||||
|  |  | ||||||
|  |         for prot, name, addr in update['delete']: | ||||||
|  |             if not prot in ['A', 'AAAA']: | ||||||
|  |                 continue | ||||||
|  |             result = client.get('/domain/zone/%s/record' % domain, | ||||||
|  |                                 fieldType=prot, | ||||||
|  |                                 subDomain=name) | ||||||
|  |             for id in result: | ||||||
|  |                 r = client.get('/domain/zone/%s/record/%d' % (domain, id)) | ||||||
|  |                 if r['fieldType'] == prot and r['target'] == addr: | ||||||
|  |                     log("OVH: delete entry for %s %s %s (#%s)" % (name, prot, addr, id)) | ||||||
|  |                     client.delete('/domain/zone/%s/record/%d' % (domain, id)) | ||||||
|  |  | ||||||
|  |         for prot, name, addr in update['add']: | ||||||
|  |             if not prot in ['A', 'AAAA']: | ||||||
|  |                 continue | ||||||
|  |             log("OVH: create entry for %s %s %s" % (name, prot, addr)) | ||||||
|  |             client.post('/domain/zone/%s/record' % domain, | ||||||
|  |                     fieldType=prot, | ||||||
|  |                     subDomain=name, | ||||||
|  |                     target=addr, | ||||||
|  |                     ttl=60) | ||||||
|  |  | ||||||
|  |         log("OVH: Refresh zone %s" % domain) | ||||||
|  |         client.post('/domain/zone/%s/refresh' % domain) | ||||||
|  |         return True | ||||||
|  |     except: | ||||||
|  |         log('OVH update error\n') | ||||||
|         return False |         return False | ||||||
|  |  | ||||||
|     client = ovh.Client() |  | ||||||
|  |  | ||||||
|     for host, fieldtype, target in zone_list: | def livebox_rule_id(words): | ||||||
|         result = client.get('/domain/zone/%s/record' % domain, |     id='dyndomain_{}'.format('_'.join(words)) | ||||||
|                             fieldType=fieldtype, |     id = id.replace('.', '_') | ||||||
|                             subDomain=host) |     return id | ||||||
|         if len(result) == 0: |  | ||||||
|             #print("Create new entry for %s %s %s" % (host, fieldtype, target)) |  | ||||||
|             client.post('/domain/zone/%s/record' % domain, |  | ||||||
|                         fieldType=fieldtype, |  | ||||||
|                         subDomain=host, |  | ||||||
|                         target=target, |  | ||||||
|                         ttl=60) |  | ||||||
|         else: |  | ||||||
|             id = result[0] |  | ||||||
|             #print("Update entry for %s %s %s" % (host, fieldtype, target)) |  | ||||||
|             client.put('/domain/zone/%s/record/%ld' % (domain, id), |  | ||||||
|                        target=target) |  | ||||||
|  |  | ||||||
|     #print("Refresh zone %s" % domain) |  | ||||||
|     client.post('/domain/zone/%s/refresh' % domain) |  | ||||||
|     return True |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def send_update_mail(mail_to, mail_from, zone_domain, update_zone_list, wan): | def livebox_delete_port_nat(port, addr): | ||||||
|     #print('Send email to %s' % mail_to) |     log('livebox: delete PortNat {} to {}'.format(port, addr)) | ||||||
|  |     id = livebox_rule_id([port]) | ||||||
|  |     r = sysbus.requete('Firewall:deletePortForwarding', { 'id': id, 'origin': 'webui' }, silent=True) | ||||||
|  |  | ||||||
|  | def livebox_delete_pinhole(port, addr): | ||||||
|  |     log('livebox: delete pinhole {} to {}'.format(port, addr)) | ||||||
|  |     id = livebox_rule_id([port, addr]) | ||||||
|  |     r = sysbus.requete('Firewall:deletePinhole', { 'id': id, 'origin': 'webui' }, silent=True) | ||||||
|  |  | ||||||
|  | def livebox_add_port_nat(port, addr): | ||||||
|  |     log('livebox: add PortNat {} to {}'.format(port, addr)) | ||||||
|  |     id = livebox_rule_id([port]) | ||||||
|  |     a = { | ||||||
|  |         'id': id, | ||||||
|  |         'origin': 'webui', | ||||||
|  |         'sourceInterface': 'data', | ||||||
|  |         'destinationIPAddress': addr, | ||||||
|  |         'protocol': '6,17', | ||||||
|  |         'internalPort': port, | ||||||
|  |         'enable': True, | ||||||
|  |     } | ||||||
|  |     r = sysbus.requete('Firewall:setPortForwarding', a, silent=True) | ||||||
|  |  | ||||||
|  | def livebox_add_pinhole(port, addr): | ||||||
|  |     log('livebox: add pinhole {} to {}'.format(port, addr)) | ||||||
|  |     id = livebox_rule_id([port, addr]) | ||||||
|  |     a = { | ||||||
|  |         'id': id, | ||||||
|  |         'origin': 'webui', | ||||||
|  |         'sourceInterface': 'data', | ||||||
|  |         'destinationPort': port, | ||||||
|  |         'destinationIPAddress': addr, | ||||||
|  |         'protocol': '6,17', | ||||||
|  |         'ipversion': '6', | ||||||
|  |         'enable': True, | ||||||
|  |     } | ||||||
|  |     r = sysbus.requete('Firewall:setPinhole', a, silent=True) | ||||||
|  |  | ||||||
|  | def livebox_update_fw(zone, update, sync_zone): | ||||||
|  |     for prot, addr, port in update['delete']: | ||||||
|  |         if prot == 'nat': | ||||||
|  |             livebox_delete_port_nat(port, addr) | ||||||
|  |         elif prot == 'pin': | ||||||
|  |             livebox_delete_pinhole(port, addr) | ||||||
|  |     for prot, addr, port in update['add']: | ||||||
|  |         if prot == 'nat': | ||||||
|  |             livebox_add_port_nat(port, addr) | ||||||
|  |         elif prot == 'pin': | ||||||
|  |             livebox_add_pinhole(port, addr) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def send_update_mail(mail_to, mail_from, zone_domain, update, mail_ignore_list, wan): | ||||||
|  |     okmail=False | ||||||
|  |     for op in update: | ||||||
|  |         for prot,name,addr in update[op]: | ||||||
|  |             if not name in mail_ignore_list: | ||||||
|  |                 okmail = True | ||||||
|  |                 break | ||||||
|  |  | ||||||
|  |     if not okmail: | ||||||
|  |         return | ||||||
|  |  | ||||||
|  |     log('Send email to %s' % mail_to) | ||||||
|     msg = EmailMessage() |     msg = EmailMessage() | ||||||
|  |  | ||||||
|     msg['Subject'] = "Livebox update in %s" % zone_domain |     msg['Subject'] = "Livebox update in %s" % zone_domain | ||||||
| @@ -166,15 +347,22 @@ def send_update_mail(mail_to, mail_from, zone_domain, update_zone_list, wan): | |||||||
|     msg['To' ] = mail_to |     msg['To' ] = mail_to | ||||||
|  |  | ||||||
|     txt = "Livebox update\n\n" |     txt = "Livebox update\n\n" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     if updated['add']: | ||||||
|  |         txt = txt + "\nUpdated entries:\n" | ||||||
|  |         for prot,name,addr in update['add']: | ||||||
|  |             txt = txt + "  %-20s %-4s %s\n" % (name,prot,addr) | ||||||
|  |  | ||||||
|  |     if update['delete']: | ||||||
|  |         txt = txt + "\nRemoved entries:\n" | ||||||
|  |         for prot,name,addr in update['delete']: | ||||||
|  |             txt = txt + "  %-20s %-4s %s\n" % (name,prot,addr) | ||||||
|  |  | ||||||
|  |     txt = txt + '\n' | ||||||
|     txt = txt + "WAN IPv4 : %s\n" % wan['ipv4'] |     txt = txt + "WAN IPv4 : %s\n" % wan['ipv4'] | ||||||
|     txt = txt + "WAN IPv6 : %s\n" % wan['ipv6'] |     txt = txt + "WAN IPv6 : %s\n" % wan['ipv6'] | ||||||
|  |  | ||||||
|     txt = txt + "\nZone %s has been updated:\n" % zone_domain |  | ||||||
|      |  | ||||||
|     for host,tp,addr in update_zone_list: |  | ||||||
|         txt = txt + "  %-20s %-4s %s\n" % (host,tp,addr) |  | ||||||
|     txt = txt + '\n' |  | ||||||
|  |  | ||||||
|     msg.set_content(txt) |     msg.set_content(txt) | ||||||
|  |  | ||||||
|     s = smtplib.SMTP('localhost') |     s = smtplib.SMTP('localhost') | ||||||
| @@ -189,28 +377,37 @@ if not ping(wan_hostname): | |||||||
|     sys.exit(0) |     sys.exit(0) | ||||||
|  |  | ||||||
| sysbus.load_conf() | sysbus.load_conf() | ||||||
| sysbus.auth() | try: | ||||||
|  |     r = sysbus.auth(False) | ||||||
|  |     if not r: | ||||||
|  |         log('Error: cannot authenticate on livebox') | ||||||
|  |         sys.exit(1) | ||||||
|  | except Exception as e: | ||||||
|  |     log('Error: %s'.format(e)) | ||||||
|  |     sys.exit(1) | ||||||
|  |  | ||||||
| hosts = get_ipv6_hosts() | hosts = get_hosts() | ||||||
| wan = get_wan_addr() | wan = get_wan_addr() | ||||||
|  | if not wan: | ||||||
|  |     sys.exit(0) | ||||||
|  |  | ||||||
| zone_list = make_zone_list(wan_hostname, wan, hosts, hosts_ipv4_nat_list, zone_subdomain) | zone = read_zone_list(zone_filename) | ||||||
| prev_zone_list = read_zone_list_from_file(zone_filename) | sync_zone = False | ||||||
| update_zone_list = make_update_zone_list(zone_list, prev_zone_list) | if not zone: | ||||||
|  |     sync_zone = True | ||||||
|  |  | ||||||
| #print('zone_list:') | stamp = int(time.time()) | ||||||
| #pprint(zone_list) | populate_zone(zone, wan_hostname, wan, hosts, hosts_list, nat_list, pinhole_list, zone_subdomain, stamp) | ||||||
| #print('prev_zone_list:') | update = process_zone(zone, stamp, zone_timeout, sync_zone) | ||||||
| #pprint(prev_zone_list) | if update: | ||||||
| #print('update_zone_list:') |     log_update_zone(update) | ||||||
| #pprint(update_zone_list) |  | ||||||
|  |  | ||||||
| log_update_zone(update_zone_list) |  | ||||||
|  |  | ||||||
| sucess = ovh_update_zone(zone_domain, update_zone_list) |  | ||||||
|  |  | ||||||
| if sucess: |  | ||||||
|     new_zone_list = write_zone_list_to_file(zone_filename, prev_zone_list+update_zone_list) |  | ||||||
|     send_update_mail(mail_to, mail_from, zone_domain, update_zone_list, wan) |  | ||||||
|  |  | ||||||
|  |     success = ovh_update_zone(zone_domain, zone, update, sync_zone) | ||||||
|  |     livebox_update_fw(zone, update, sync_zone) | ||||||
|  |     if success: | ||||||
|  |         try: | ||||||
|  |             send_update_mail(mail_to, mail_from, zone_domain, update, mail_ignore_list, wan) | ||||||
|  |         except: | ||||||
|  |             pass | ||||||
|  |  | ||||||
|  | write_zone_list(zone_filename, zone, update) | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| # edit it and save it as home.conf | # edit it and save it as home.conf | ||||||
|  |  | ||||||
| [Files] | [Files] | ||||||
| zonefile = zone.list | zonefile = zone.json | ||||||
| logfile = zone.log | logfile = zone.log | ||||||
|  |  | ||||||
| [Wan] | [Wan] | ||||||
| @@ -13,15 +13,22 @@ mypc1 | |||||||
| mypc2 | mypc2 | ||||||
| mypc3 | mypc3 | ||||||
|  |  | ||||||
| [NatHosts] | [PortsNat] | ||||||
| mypc2 | mypc2 = 22,443 | ||||||
| mypc4 | mypc3 = 10022 | ||||||
|  |  | ||||||
|  | [Firewall] | ||||||
|  | mypc2 = 22,443 | ||||||
|  | mypc3 = 10022 | ||||||
|  |  | ||||||
| [Zone] | [Zone] | ||||||
| domain = example.com | domain = example.com | ||||||
| subdomain = home | subdomain = home | ||||||
|  | keep = 3d | ||||||
|  |  | ||||||
| [Mail] | [Mail] | ||||||
| from = me@example.com | from = me@example.com | ||||||
| to = you@example.com | to = you@example.com | ||||||
|  |  | ||||||
|  | [MailIgnore] | ||||||
|  | mypc2 | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								ovh
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								ovh
									
									
									
									
									
								
							 Submodule ovh updated: 526c9e0fab...11d03357a5
									
								
							| @@ -1,8 +1,13 @@ | |||||||
| #!/usr/bin/python3 | #!/usr/bin/python3 | ||||||
|  |  | ||||||
|  | import sys | ||||||
| from ovh import ovh | from ovh import ovh | ||||||
|  |  | ||||||
| domain = 'example.com' | if len(sys.argv) != 2: | ||||||
|  |     print('usage: {} <domain>'.format(sys.argv[0])) | ||||||
|  |     sys.exit(1) | ||||||
|  |  | ||||||
|  | domain = sys.argv[1] | ||||||
|  |  | ||||||
| client = ovh.Client() | client = ovh.Client() | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								sysbus
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								sysbus
									
									
									
									
									
								
							 Submodule sysbus updated: bf7689ce0a...87040a0906
									
								
							
		Reference in New Issue
	
	Block a user