diff --git a/bundles/hetzner-dyndns/items.py b/bundles/hetzner-dyndns/items.py new file mode 100644 index 0000000..d278949 --- /dev/null +++ b/bundles/hetzner-dyndns/items.py @@ -0,0 +1,6 @@ +directories['/opt/hetzner-dyndns/src'] = {} + +git_deploy['/opt/hetzner-dyndns/src'] = { + 'repo': 'https://git.franzi.business/sophie/hetzner-dyndns.git', + 'rev': 'main', +} diff --git a/bundles/hetzner-dyndns/metadata.py b/bundles/hetzner-dyndns/metadata.py new file mode 100644 index 0000000..a5369f6 --- /dev/null +++ b/bundles/hetzner-dyndns/metadata.py @@ -0,0 +1,26 @@ +defaults = { + 'systemd-timers': { + 'timers': { + 'hetzner-dyndns-update': { + 'when': 'hourly', + }, + }, + }, +} + + +@metadata_reactor.provides( + 'systemd-timers/timers/hetzner-dyndns-update', +) +def command_template(metadata): + empty_command = f'/usr/bin/python3 /opt/hetzner-dyndns/src/hetzner-api-dyndns.py --api_key {{}} --zone {node.metadata.get('hetzner-dyndns/zone')} --record {node.metadata.get('hetzner-dyndns/record')}' + + return { + 'systemd-timers': { + 'timers': { + 'hetzner-dyndns-update': { + 'command': node.metadata.get('hetzner-dyndns/api_key').format_into(empty_command), + }, + }, + }, + } diff --git a/nodes/sophie/vmhost.py b/nodes/sophie/vmhost.py index aca520c..092e0b2 100644 --- a/nodes/sophie/vmhost.py +++ b/nodes/sophie/vmhost.py @@ -2,11 +2,13 @@ nodes['sophie.vmhost'] = { 'hostname': '172.19.164.2', 'bundles': { 'backup-client', + 'hetzner-dyndns', 'lm-sensors', - 'nfs-server', 'mosquitto', + 'nfs-server', 'smartd', 'vmhost', + 'wireguard', 'zfs', }, 'groups': { @@ -21,6 +23,11 @@ nodes['sophie.vmhost'] = { 'groups': { 'nas': {}, }, + 'hetzner-dyndns': { + 'zone': 'sophies-kitchen.eu', + 'record': 'router.home', + 'api_key': vault.decrypt('encrypt$gAAAAABoABHrRTTyOAAFIsHK_g-bubDoNJidbAQ6_0VXyqfal8-wpVMuPPlrw-OtbI1AjNU6Rd1_gKTvwYtNYO9X6RuvuW3TCCH_eitpsoylVEQ0X6SDFNQAFfjkRlOgEiFl85oyTazl'), + }, 'interfaces': { 'br1': { 'ips': { @@ -66,6 +73,21 @@ nodes['sophie.vmhost'] = { }, }, }, + 'nftables': { + 'forward': { + '50-router': [ + 'ct state { related, established } accept', + 'oifname br1 accept', + ], + }, + 'input': { + '50-wireguard': [ + 'udp dport 1194 accept', + 'udp dport 10348 accept', + 'udp dport 10349 accept', + ], + }, + }, 'smartd': { 'disks': { '/dev/nvme0', @@ -75,6 +97,12 @@ nodes['sophie.vmhost'] = { '/dev/disk/by-id/ata-ST20000NM007D-3DJ103_ZVT7D6JP', }, }, + 'sysctl': { + 'options': { + 'net.ipv4.conf.all.forwarding': '1', + 'net.ipv6.conf.all.forwarding': '1', + }, + }, 'systemd-networkd': { 'bridges': { 'br0': { @@ -109,6 +137,29 @@ nodes['sophie.vmhost'] = { }, }, }, + 'wireguard': { + 'snat_ip': '172.19.137.2', + 'peers': { + 'thinkpad': { + 'endpoint': None, + 'exclude_from_monitoring': True, + 'my_ip': '172.19.165.64', + 'my_port': 10348, + 'their_ip': '172.19.165.65', + 'psk': vault.decrypt('encrypt$gAAAAABoAUy3lAHfn7d9Jn4ppiPRr6LOReFGyGS4HzWC5ACHNipDFnGttnOHNji2DGIYVITzj3PosZs7PRn8BvXmwumEXNNP-G0nDucuiNNzUKuOCP4YWaF9-I1tnpmT_td3nqsCDajH'), + 'pubkey': vault.decrypt('encrypt$gAAAAABoAUxlf048ovJebqo0MlLiLHcuuTCSmnCzhxSZPrFMjRaFLW0CvC3GnVed_4n7CjjZ6ygrORSl8xyBM5hvbN0-JM_56ZZFpn1UVkizctjHjb1u2XtpGAe2nMAnq2Cdg5swgH9S'), + }, + 'smartphone': { + 'endpoint': None, + 'exclude_from_monitoring': True, + 'my_ip': '172.19.165.66', + 'my_port': 10349, + 'their_ip': '172.19.165.67', + 'psk': vault.decrypt('encrypt$gAAAAABoAUy3lAHfn7d9Jn4ppiPRr6LOReFGyGS4HzWC5ACHNipDFnGttnOHNji2DGIYVITzj3PosZs7PRn8BvXmwumEXNNP-G0nDucuiNNzUKuOCP4YWaF9-I1tnpmT_td3nqsCDajH'), + 'pubkey': vault.decrypt('encrypt$gAAAAABoAWD96YcEFsLzfOCzjS_4Hg7xX516OZ5RD_qFPSEZliaYSRMhY3uyNDtQ--e0dzEwdFHK_xGT3F7jQzYAvftH4iFtk9y3n3FNFVPxqsWckX4cJIX7ZZszbQCq8sfZZXGUR0C9'), + }, + }, + }, 'zfs': { 'pools': { 'storage': {