diff --git a/utils/he_ipv6/config.py b/utils/he_ipv6/config.py index 185d99f..b44f165 100644 --- a/utils/he_ipv6/config.py +++ b/utils/he_ipv6/config.py @@ -1,53 +1,71 @@ import collections import copy -import ipaddress import os import re ## -import netaddr import requests import requests.auth from lxml import etree -from pyroute2 import IPRoute ## from . import tunnel def create_default_cfg(): # Create a stripped sample config. - nsmap = {None: 'https://tunnelbroker.net/', - 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'} - attr_qname = etree.QName('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation') - schema_url = 'http://schema.xml.r00t2.io/projects/he_ipv6.xsd' - schema_loc = '{0} {1}'.format(nsmap[None], schema_url) - xml = etree.Element('heIPv6', - {attr_qname: schema_loc}, - nsmap = nsmap) - xml.append(etree.Comment(('See example.tunnelbroker.xml for an extensively commented sample config.'))) - creds = etree.SubElement(xml, 'creds') - creds.append(etree.Comment(('Your tunnelbroker.net *login*. You can specify multiple credentials via multiple ' - '"cred" items. The "id" attribute is up to you but it must be unique.'))) - cred = etree.SubElement(creds, 'cred') - cred.attrib['id'] = '' - user = etree.SubElement(cred, 'user') - user.text = '' - password = etree.SubElement(cred, 'password') - password.text = '' - tunnels = etree.SubElement(xml, 'tunnels') - tunnels.append(etree.Comment(('You can have define multiple tunnels via multiple "tunnel" items. You should most ' - 'likely only run one at a time.'))) - tunnel = etree.SubElement(tunnels, 'tunnel') - tunnel.append(etree.Comment(('The "id" attribute should match the id number of a tunnel on your tunnelbroker.net ' - 'account. The "creds" attribute references a cred item id attribute.'))) - tunnel.attrib['id'] = '' - tunnel.attrib['creds'] = '' - ukey = etree.SubElement(tunnel, '') - return (etree.tostring(xml, - encoding = 'UTF-8', - xml_declaration = True, - pretty_print = True, - with_tail = True, - with_comments = True)) + ws_re = re.compile(r'^\s*$') + cur_dir = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) + xtbxml = os.path.join(cur_dir, 'example.tunnelbroker.xml') + with open(xtbxml, 'rb') as fh: + xml = etree.fromstring(fh.read()) + # Create a stripped sample config. + # First we strip comments (and fix the ensuing whitespace). + # etree has a .canonicalize(), but it chokes on a default namespace. + # https://bugs.launchpad.net/lxml/+bug/1869455 + # So everything we do is kind of a hack. + # for c in xml.xpath("//comment()"): + # parent = c.getparent() + # parent.remove(c) + xmlstr = etree.tostring(xml, with_comments = False, method = 'c14n', pretty_print = True).decode('utf-8') + newstr = [] + for line in xmlstr.splitlines(): + r = ws_re.search(line) + if not r: + newstr.append(line.strip()) + xml = etree.fromstring(''.join(newstr).encode('utf-8')) + # Remove text and attr text. + xpathq = "descendant-or-self::*[namespace-uri()!='']" + for e in xml.xpath(xpathq): + if e.tag == '{{{0}}}heIPv6'.format(xml.nsmap[None]): + continue + if e.text is not None and e.text.strip() != '': + e.text = '' + for k, v in e.attrib.items(): + if v is not None: + e.attrib[k] = '' + # Remove multiple children of same type to simplify. + for e in xml.xpath(xpathq): + if e.tag == '{{{0}}}heIPv6'.format(xml.nsmap[None]): + continue + parent = e.getparent() + try: + for idx, child in enumerate(parent.findall(e.tag)): + if idx == 0: + continue + parent.remove(child) + except AttributeError: + pass + # And add a comment pointing them to the fully commented config. + xml.insert(0, etree.Comment(('\n Please reference the fully commented example.tunnelbroker.xml found either ' + 'at:\n ' + ' * {0}\n * https://git.square-r00t.net/RouterBox/tree/utils/he_ipv6/' + 'example.tunnelbroker.xml\n and then configure this according to those ' + 'instructions.\n ').format(xtbxml))) + return(etree.tostring(xml, + pretty_print = True, + with_comments = True, + with_tail = True, + encoding = 'UTF-8', + xml_declaration = True)) class Credential(object): @@ -189,7 +207,10 @@ class Config(BaseConfig): def __init__(self, xml_path, *args, **kwargs): self.xml_path = os.path.abspath(os.path.expanduser(xml_path)) if not os.path.isfile(self.xml_path): - raise ValueError('xml_path does not exist') + with open(self.xml_path, 'wb') as fh: + fh.write(create_default_cfg()) + raise ValueError('xml_path does not exist; ' + 'a sample configuration has been generated (be sure to configure it)') else: with open(xml_path, 'rb') as fh: raw_xml = fh.read() diff --git a/utils/he_ipv6/example.tunnelbroker.xml b/utils/he_ipv6/example.tunnelbroker.xml index 4264e1d..94667c3 100644 --- a/utils/he_ipv6/example.tunnelbroker.xml +++ b/utils/he_ipv6/example.tunnelbroker.xml @@ -8,7 +8,8 @@ https://www.tunnelbroker.net/tunnel_detail.php?tid=584532 I highly recommend their (free) certification as well if you're brand-new to IPv6: https://ipv6.he.net/certification/ - **It is VERY highly encouraged to only use one tunnel at a time on a machine.** + **It is VERY highly encouraged to only use one tunnel at a time on a machine. Completely unpredictable results will + incur if this is not heeded.** --> xXxXxXxXxXxXxXXX - - true - true + + + true + + true + - + + + false + + false + + + + + + true + false + - - + 0000000000000000 diff --git a/utils/he_ipv6/ref b/utils/he_ipv6/ref index 236416a..f190ea3 100644 --- a/utils/he_ipv6/ref +++ b/utils/he_ipv6/ref @@ -1,4 +1,4 @@ -## General Info/Networking Configuration +## General Info/Networking Configuration ## # https://wiki.archlinux.org/index.php/IPv6_tunnel_broker_setup # https://gist.github.com/pklaus/960672 # https://genneko.github.io/playing-with-bsd/networking/freebsd-tunnelv6-he @@ -8,8 +8,27 @@ # https://shorewall.org/6to4.htm#idm143 # https://shorewall.org/6to4.htm#SixInFour # https://wiki.ubuntu.com/IPv6#Configure_your_Ubuntu_box_as_a_IPv6_router +# http://koo.fi/blog/2013/03/20/linux-ipv6-router-radvd-dhcpv6/ -## Tunnelbroker API +## Tunnelbroker API ## # https://forums.he.net/index.php?topic=3153.0 ("The following scripts conform to the Dyn DNS Update API (as documented at http://dyn.com/support/developers/api/).") # https://help.dyn.com/remote-access-api/return-codes/ -# + +## DNSMASQ ## +# https://hveem.no/using-dnsmasq-for-dhcpv6 + +## RFCs ## +# DNSSL # +# https://tools.ietf.org/html/rfc6106 +# https://tools.ietf.org/html/rfc8106 +# RDNSS # +# https://tools.ietf.org/html/rfc5006 (see also 6106, 8106) +# SLAAC +# https://tools.ietf.org/html/rfc2462 +# https://tools.ietf.org/html/rfc4862 +# https://tools.ietf.org/html/rfc8064 +# Router Advertisements +# https://tools.ietf.org/html/rfc4861 +# https://tools.ietf.org/html/rfc5175 +# https://tools.ietf.org/html/rfc6104 +# https://tools.ietf.org/html/rfc7772