add livebox firewall support

This commit is contained in:
Gilles Grandou 2020-10-04 17:41:05 +02:00
parent 677db2e9a6
commit 2f970cd71c
1 changed files with 79 additions and 11 deletions

View File

@ -116,18 +116,18 @@ def full_name(host, domain):
return '.'.join([host, domain])
def zone_add_entry(zone, prot, name, addr, stamp):
#print('zone_add_entry: {} {} {} {}'.format(prot, name, addr, stamp))
def zone_add_entry(zone, prot, key, value, stamp):
#print('zone_add_entry: {} {} {} {}'.format(prot, key, value, stamp))
if not zone.get(prot):
zone[prot] = {}
if not zone[prot].get(name):
zone[prot][name] = {}
if not zone[prot][name].get(addr):
zone[prot][name][addr] = { 'first': stamp }
zone[prot][name][addr]['last'] = stamp
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, domain, 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)
if not zone.get('A'):
@ -140,12 +140,19 @@ def populate_zone(zone, wan_hostname, wan_addr, hosts, hosts_list, hosts_nat, do
for host in hosts_nat:
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'] != '':
zone_add_entry(zone, 'AAAA', wan_hostname, wan_addr['ipv6'], stamp)
for host in hosts_list:
for addr in hosts['AAAA'].get(host, []):
zone_add_entry(zone, 'AAAA', full_name(host, domain), addr, stamp)
for port in pinhole_list.get(host, []):
zone_add_entry(zone, 'pin', addr, port, stamp)
def process_zone(zone, stamp, grace_period, sync_zone):
@ -213,8 +220,8 @@ def ovh_update_zone(domain, zone, update, sync_zone):
client = ovh.Client()
if sync_zone:
for prot in zone:
for name in zone[prot]:
for prot in ['A', 'AAAA']:
for name in zone.get(prot, []):
result = client.get('/domain/zone/{}/record'.format(domain),
fieldType=prot, subDomain=name)
@ -223,6 +230,8 @@ def ovh_update_zone(domain, zone, update, sync_zone):
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)
@ -233,6 +242,8 @@ def ovh_update_zone(domain, zone, update, sync_zone):
client.delete('/domain/zone/%s/record/%d' % (domain, id))
for prot, name, addr in update['add']:
if not prot in ['A', 'AAAA']:
continue
print("OVH: create entry for %s %s %s" % (name, prot, addr))
client.post('/domain/zone/%s/record' % domain,
fieldType=prot,
@ -247,6 +258,62 @@ def ovh_update_zone(domain, zone, update, sync_zone):
print('OVH update error\n')
return False
def livebox_rule_id(words):
id='dyndomain_{}'.format('_'.join(words))
id = id.replace('.', '_')
return id
def livebox_delete_port_nat(port, addr):
print('livebox: delete PortNat {} to {}'.format(port, addr))
id = livebox_rule_id([port])
r = sysbus.requete('Firewall:deletePortForwarding', { 'id': id, 'origin': 'webui' })
def livebox_delete_pinhole(port, addr):
print('livebox: delete pinhole {} to {}'.format(port, addr))
id = livebox_rule_id([port, addr])
r = sysbus.requete('Firewall:deletePinhole', { 'id': id, 'origin': 'webui' })
def livebox_add_port_nat(port, addr):
print('livebox: add PortNat {} to {}'.format(port, addr))
id = livebox_rule_id([port])
a = {
'id': id,
'origin': 'webui',
'sourceInterface': 'data',
'destinationIPAddress': addr,
'protocol': '6',
'internalPort': port,
'enable': True,
}
r = sysbus.requete('Firewall:setPortForwarding', a)
def livebox_add_pinhole(port, addr):
print('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',
'enable': True,
}
r = sysbus.requete('Firewall:setPinhole', a)
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
@ -311,12 +378,13 @@ if not zone:
sync_zone = True
stamp = int(time.time())
populate_zone(zone, wan_hostname, wan, hosts, hosts_list, nat_list, zone_subdomain, stamp)
populate_zone(zone, wan_hostname, wan, hosts, hosts_list, nat_list, pinhole_list, zone_subdomain, stamp)
update = process_zone(zone, stamp, zone_timeout, sync_zone)
if update:
log_update_zone(update)
success = ovh_update_zone(zone_domain, zone, update, sync_zone)
livebox_update_fw(zone, update, sync_zone)
if success:
send_update_mail(mail_to, mail_from, zone_domain, update, mail_ignore_list, wan)