Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement wireguard tunnel #17

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/cache
/workdir
/aes-key
/wireguardkeys.json
/config.yaml
__pycache__
.*.swp
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ v | discovery message |
| kexec to received kernel
| and network-root compatible initramfs
serve root block device |
| connect wireguard |
|<---------------------<---------------------+
| map/mount root fs |
|<---------------------<---------------------+
| |
Expand Down
2 changes: 2 additions & 0 deletions config-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ modules:
# never disable those core components:
- base
- nbd
# disabling this forces force plain text communication (DON'T DO IT)
- wireguard
###########################################################################
# select one of the following systems:
# support for arch linux payload systems (mkinitcpio)
Expand Down
3 changes: 2 additions & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ def __init__(self, raw):
self.macs = []



class ServerSetupConfig:
"""
server system setup information
Expand Down Expand Up @@ -171,6 +170,7 @@ def register_module(module_class):
return module_class
return register_module


# see module_config().
MODULE_CONFIG_CLASSES = {}

Expand Down Expand Up @@ -205,5 +205,6 @@ def __init__(self, raw):
def apply(self, cfg):
pass


# load the config on module initialization
CONFIG = Config('config.yaml')
25 changes: 24 additions & 1 deletion create-initrd
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
import argparse
import json
import os

from config import CONFIG as cfg
Expand Down Expand Up @@ -65,6 +66,7 @@ if not args.skip_setup:
'python3-aiohttp',
'systemd-container', # to allow launching inside nspawn during this script
'systemd-sysv', # to provide symlinks in /sbin: init, poweroff, ...
'wireguard-tools',
]

if 'nbd' in cfg.modules:
Expand Down Expand Up @@ -93,7 +95,6 @@ if not args.skip_setup:
'--components=main,contrib,non-free',
'--merged-usr',
'--verbose',
'--merged-usr',
'stable',
cfg.path.initrd,
args.debian_mirror
Expand All @@ -109,6 +110,25 @@ if not os.path.exists('aes-key'):
fileobj.write(os.urandom(16))
command('cp', 'aes-key', cfg.path.initrd)

# generate the wireguard keys
if 'wireguard' in cfg.modules and not os.path.exists('wireguardkeys.json'):
print('generating wireguard keys')
server_privkey = command('wg', 'genkey', capture_stdout=True).decode('utf-8')[:-1]
server_pubkey = command('wg', 'pubkey', stdin=server_privkey, capture_stdout=True).decode('utf-8')[:-1]
client_privkey = command('wg', 'genkey', capture_stdout=True).decode('utf-8')[:-1]
client_pubkey = command('wg', 'pubkey', stdin=client_privkey, capture_stdout=True).decode('utf-8')[:-1]

with open("wireguardkeys.json", "w") as f:
f.write(json.dumps(
{
"wg_client": client_pubkey,
"wg_clientkey": client_privkey,
"wg_server": server_pubkey,
"wg_serverkey": server_privkey,
}
))


if not args.skip_setup:
# set root password
command(
Expand Down Expand Up @@ -206,6 +226,7 @@ if not args.skip_setup:
'git',
'linux-headers-amd64',
'kmod',
'wireguard-tools',
nspawn=cfg.path.initrd_devel
)

Expand Down Expand Up @@ -296,6 +317,7 @@ os.chdir(cfg.path.initrd)

target_files = []


def scan_path(path):
for name in os.listdir(path):
full = os.path.normpath(os.path.join(path, name))
Expand All @@ -310,6 +332,7 @@ def scan_path(path):
if os.path.isdir(full) and not os.path.islink(full):
yield from scan_path(full)


print(f'packing {cfg.path.initrd}')

archive = command(
Expand Down
2 changes: 1 addition & 1 deletion doc/arch.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Dependencies

```
pacman -S debootstrap kexec-tools dosfstools nbd pigz pv python-pyudev python-yaml syslinux wireless_tools mtools gdisk
pacman -S debootstrap kexec-tools dosfstools nbd pigz pv python-pyudev python-yaml syslinux wireless_tools mtools gdisk wireguard-tools
```

Only required for debugging with `test-qemu`:
Expand Down
33 changes: 20 additions & 13 deletions overlays/initrd/usr/local/bin/stiefel-client
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import io
import json
import os
import socket
import struct
import subprocess
import sys
import tarfile
import time
import urllib.request
Expand Down Expand Up @@ -180,6 +178,7 @@ stiefelmodules = []
# these are supplied by stiefel-server.
inner_cmdline = ''

serverkey = clientprivkey = None
with io.BytesIO(tar_blob) as tarfileobj:
with tarfile.open(fileobj=tarfileobj, mode='r') as tar:
# validate challenge response
Expand All @@ -203,6 +202,10 @@ with io.BytesIO(tar_blob) as tarfileobj:
elif member.name == 'stiefelmodules':
# cmdline for the kexec'd real kernel
stiefelmodules = data.decode().split(" ")
elif member.name == 'wg_server':
serverkey = data.decode('utf-8')
elif member.name == 'wg_clientkey':
clientprivkey = data.decode('utf-8')
else:
with open(f'/{member.name}', 'wb') as fileobj:
fileobj.write(data)
Expand All @@ -213,25 +216,29 @@ print('server cmdline: %s' % "\n".join(inner_cmdline.split()))
# additional inner cmdline arguments given to the stiefel-client-kernel-cmdline
inner_cmdline += ' ' + base64.b64decode(cmdlineargs.get("stiefel_innercmdline", "")).decode()

if serverkey:
inner_cmdline += f' wg.privkey={clientprivkey} wg.pubkey={serverkey} wg.endpoint=[{SERVER.replace(SERVER_INTERFACE, "stiefellink")}]:51820 '

if any(mod in stiefelmodules for mod in ('system-debian', 'system-arch')):
CMDLINE = (
inner_cmdline +
" stiefel_nbdhost=" + SERVER.replace(SERVER_INTERFACE, "stiefellink") +
" stiefel_nbdname=stiefelblock" + # name is hardcoded in stiefel-server
" stiefel_link=" + CLIENT_INTERFACE_MAC
)

elif any(mod in stiefelmodules for mod in ('system-gentoo', 'system-arch-dracut')):
if any(mod in stiefelmodules for mod in (
'system-gentoo',
'system-arch-dracut',
'system-arch',
'system-debian',
)):
# dracut nbd & network invocation from man dracut.cmdline:
# netroot=nbd:srv:export[:fstype[:rootflags(fsflags)[:nbdopts]]]
# pls sync with test-qemu
CMDLINE = (
inner_cmdline +
" stiefel" +
" ifname=stiefellink:" + CLIENT_INTERFACE_MAC +
" ip=stiefellink:link6" +
" netroot=nbd:[" + SERVER.replace(SERVER_INTERFACE, "stiefellink") + "]:stiefelblock:::-persist"
" ip=stiefellink:link6"
)
if serverkey:
CMDLINE += " netroot=nbd:[fe80::1%wgstiefel]:stiefelblock:::-persist"
else:
CMDLINE += f" netroot=nbd:[{SERVER.replace(SERVER_INTERFACE, 'stiefellink')}]:stiefelblock:::-persist"

else:
raise Exception("with the given stiefelsystem modules, "
"couldn't construct kexec cmdline")
Expand Down
Loading