Mercurial > code > home > repos > infra
changeset 5:7e8c7de5b490
port wireguard setup
author | drewp@bigasterisk.com |
---|---|
date | Wed, 10 Nov 2021 09:51:54 -0800 |
parents | 53ab69ba2d07 |
children | aa633eb49c63 |
files | inventory.py tasks.py templates/wireguard_bogasterisk.conf.j2 templates/wireguard_wg0.conf.j2 wireguard.py |
diffstat | 5 files changed, 135 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/inventory.py Wed Nov 10 09:50:31 2021 -0800 +++ b/inventory.py Wed Nov 10 09:51:54 2021 -0800 @@ -2,11 +2,37 @@ ssh_key = '/root/.ssh/id_ecdsa' big = [ - 'bang', - 'dash', - 'slash', + ('bang', { + 'wireguard_address': '10.5.0.1' + }), + ('dash', { + 'interface': 'enp2s0', + 'addr': '10.1.0.5', + 'wireguard_address': '10.5.0.5' + }), + ('slash', { + 'interface': 'enp3s0', + 'addr': '10.1.0.6', + 'wireguard_address': '10.5.0.6' + }), ] pi = [ - 'frontbed', - ('garage', {'ssh_hostname': '10.2.0.19'}), + ('frontbed', { + 'interface': 'eth0', + 'addr': '10.2.0.17', + 'wireguard_address': '10.5.0.17' + }), + ('garage', { + 'ssh_hostname': '10.2.0.19', + 'interface': 'eth0', + 'addr': '10.2.0.14', + 'wireguard_address': '10.5.0.14' + }), ] + +remote = [ + ('prime', { + 'ssh_hostname': 'public.bigasterisk.com', + 'wireguard_address': '10.5.0.2' + }), +]
--- a/tasks.py Wed Nov 10 09:50:31 2021 -0800 +++ b/tasks.py Wed Nov 10 09:51:54 2021 -0800 @@ -7,14 +7,22 @@ cd /my/proj/infra env/bin/pyinfra ''' + @task def users(ctx): ctx.run(cmd + 'inventory.py users.py', pty=True) + @task def system(ctx): ctx.run(cmd + 'inventory.py system.py', pty=True) + +@task +def wireguard(ctx): + ctx.run(cmd + 'inventory.py wireguard.py', pty=True) + + @task def get_fact(ctx, host='dash', fact='server.LinuxDistribution'): ctx.run(cmd + f'{host} fact {fact}', pty=True)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/wireguard_bogasterisk.conf.j2 Wed Nov 10 09:51:54 2021 -0800 @@ -0,0 +1,12 @@ +# written by pyinfra + +[Interface] +# {{ host.name }} +Address = 10.7.0.2/16 +PrivateKey = {{priv_key}} +ListenPort = 2113 + +{{ peer_block('monk', 'aroc8MNdTnKg175HYxri+Yr1afuaC0awyr6TfGMpvxI=', '10.7.0.42/32') }} +{{ peer_block('firebert (phone)', 'Rr9N6dGbMLzl6wuEJlaq67gNQ5QW2ZcwD4Brn/3XJyA=', '10.7.0.88/32') }} +{{ peer_block('bird', '9CkgqeAiX1GhNM+t9m2nJD5QJHx9iTCFRB5c1x7h704=', '10.7.0.46/32') }} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/wireguard_wg0.conf.j2 Wed Nov 10 09:51:54 2021 -0800 @@ -0,0 +1,25 @@ +# written by pyinfra + +[Interface] +# {{ host.name }} +Address = {{wireguard_ip}}/24 +PrivateKey = {{priv_key}} +ListenPort = 1195 + +{% if host.name == 'bang' %} + {{ peer_block('dash', 'X39ewB2uYLZTFaG+RFeLpyOrnCgjc4wRKrcV0Jz3sTM=', '10.5.0.5/32', 'dash:1195') }} + {{ peer_block('dot', 'sav1VQE1XzbOGfNjDRxcHAmEWtmVGYC1B7KXH+5IKxY=', '10.5.0.30/32', 'dot:1195') }} + {{ peer_block('frontbed', 'ENhRhEgGaFfwV74MqYBHJgkOFpNAF5kVHVK5/tRVTjU=', '10.5.0.17/32', 'frontbed:1195') }} + {{ peer_block('garage', 'x2i552K4ApoYYRUnx2HFgJRsdRWizcd4P5IqSZD5iwM=', '10.5.0.14/32', 'garage:1195') }} + {{ peer_block('prime', 'vR9lfsUSOIMxkY/k2gRJ6E8ZudccfPpVhrbE9zuxalU=', '10.5.0.0/24', 'public.bigasterisk.com:1195', 50) }} + {{ peer_block('slash', 'IRLLt2yFuXVJbpevAj9d84mGAvi6SbJr1AwLAK/pBTM=', '10.5.0.6/32', 'slash:1195') }} +{% elif host.name == 'prime' %} + {{ peer_block('bang', 'pAxirNVF08R6zYyudhTKjZ9fqC9UKMxknfLi5A39QVY=', '10.5.0.0/24') }} + {{ peer_block('plus', 'tH2og4BbXaH6BrHSBd73Fx1XT0DxR8vjQxjqHFa913A=', '10.5.0.110/32') }} + {{ peer_block('drew-note10', 'QMgx4cmuUTfJ7RH4Q46b54tSQl4eISOmdEney17fnE8=', '10.5.0.112/32') }} +{% elif host.name == 'plus' %} + {{ peer_block('bang', 'pAxirNVF08R6zYyudhTKjZ9fqC9UKMxknfLi5A39QVY=', '10.5.0.0/24', '10.1.0.1:1195', 50) }} +{% else %} + {{ peer_block('bang', 'pAxirNVF08R6zYyudhTKjZ9fqC9UKMxknfLi5A39QVY=', '10.5.0.0/24', '10.1.0.1:1195', 50) }} +{% endif %} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wireguard.py Wed Nov 10 09:51:54 2021 -0800 @@ -0,0 +1,59 @@ +import subprocess + +from pyinfra import host +from pyinfra.facts.files import FindInFile +from pyinfra.operations import apt, files, systemd + +# other options: +# https://www.reddit.com/r/WireGuard/comments/fkr240/shortest_path_between_peers/ +# https://github.com/k4yt3x/wireguard-mesh-configurator +# https://github.com/mawalu/wireguard-private-networking +# + + +def peer_block(hostname, public_key, allowed_ips, endpoint=None, keepalive=None): + out = f'''\ + +[Peer] +# {hostname} +PublicKey = {public_key} +AllowedIPs = {allowed_ips} +''' + if endpoint is not None: + out += f'Endpoint = {endpoint}\n' + if keepalive is not None: + out += f'PersistentKeepalive = {keepalive}\n' + return out + + +for wireguard_interface in ['wg0', 'bogasterisk']: + if wireguard_interface == 'bogasterisk' and host.name != 'prime': + continue + + # note- this is specific to the wg0 setup. Other conf files don't use it. + wireguard_ip = host.host_data['wireguard_address'] + + apt.packages(packages=['wireguard']) + # new pi may fail with 'Unable to access interface: Protocol not supported'. reboot fixes. + + priv_key_lines = host.get_fact(FindInFile, path=f'/etc/wireguard/{wireguard_interface}.conf', pattern=r'PrivateKey.*') + if not priv_key_lines: + priv_key = subprocess.check_output(['wg', 'genkey']).strip().decode('ascii') + else: + priv_key = priv_key_lines[0].split(' = ')[1] + + pub_key = subprocess.check_output(['wg', 'pubkey'], input=priv_key.encode('ascii')).strip().decode('ascii') + # todo: if this was new, it should be added to a file of pubkeys that peer_block can refer to + + files.template( + src=f'templates/wireguard_{wireguard_interface}.conf.j2', + dest=f'/etc/wireguard/{wireguard_interface}.conf', + mode='600', + wireguard_ip=wireguard_ip, + priv_key=priv_key, + peer_block=peer_block, + ) + svc = f'wg-quick@{wireguard_interface}.service' + files.link(path=f'/etc/systemd/system/multi-user.target.wants/{svc}', target='/lib/systemd/system/wg-quick@.service') + + systemd.service(service=svc, daemon_reload=True, running=True, enabled=True)