This commit is contained in:
Héctor Molinero Fernández
2020-01-30 21:33:16 +01:00
parent 1abc1d8631
commit 26b9228cf7
21 changed files with 123 additions and 40 deletions

6
packer/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
packer_cache/
dist/
*.box
crash.log

81
packer/build.pkr.hcl Normal file
View File

@@ -0,0 +1,81 @@
build {
sources = [
"source.hcloud.main"
]
provisioner "file" {
direction = "upload"
source = "./rootfs/"
destination = "/"
}
provisioner "shell" {
inline = [
"chmod 644 /etc/apt/apt.conf.d/20auto-upgrades",
"chmod 644 /etc/apt/apt.conf.d/50unattended-upgrades",
"chmod 644 /etc/fail2ban/jail.d/sshd.conf",
"chmod 644 /etc/ssh/sshd_config",
"chmod 644 /etc/unbound/unbound.conf",
"chmod 644 /etc/wireguard/client-sample.conf",
"chmod 644 /etc/wireguard/wg0-peers.conf",
"chmod 600 /etc/wireguard/wg0.conf"
]
}
provisioner "shell" {
environment_vars = [
"DEBIAN_FRONTEND=noninteractive"
]
inline = [
"printf 'deb http://ppa.launchpad.net/wireguard/wireguard/ubuntu/ bionic main\n' > /etc/apt/sources.list.d/wireguard.list",
"apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E1B39B6EF6DDB96564797591AE33835F504A1A25",
"apt-get update",
"apt-get upgrade -yo DPkg::options::=--force-confold",
"apt-get install -yo DPkg::options::=--force-confold dns-root-data fail2ban ufw unattended-upgrades unbound",
"apt-get install -yo DPkg::options::=--force-confold linux-headers-$(uname -r) openresolv wireguard",
"apt-get install -yo DPkg::options::=--force-confold htop iperf3 qrencode nano ssh-import-id",
"apt-get autoremove -y"
]
}
provisioner "shell" {
inline = [
"systemctl disable --now systemd-resolved.service",
"unlink /etc/resolv.conf && printf 'nameserver 127.0.0.1\n' > /etc/resolv.conf",
"systemctl enable --now unbound.service unbound-resolvconf.service",
]
}
provisioner "shell" {
inline = [
"systemctl enable --now fail2ban.service ufw.service unattended-upgrades.service",
"systemctl enable --now wg-quick@wg0.service"
]
}
provisioner "shell" {
inline = [
"ufw --force enable",
"ufw default deny incoming",
"ufw default allow outgoing",
"ufw allow from any to any port 22 proto tcp"
]
}
provisioner "shell" {
inline = [
"groupadd -r ssh-user",
"usermod -aG ssh-user root",
"passwd -d root"
]
}
provisioner "shell" {
inline = [
"rm -f /etc/ssh/ssh_host_*key*",
"rm -f /etc/wireguard/*-*key",
"rm -f /etc/wireguard/*-iface",
"rm -rf /var/lib/apt/lists/*"
]
}
}

View File

@@ -0,0 +1,2 @@
instance-id: "instance0"
local-hostname: "localhost"

View File

@@ -0,0 +1,9 @@
#cloud-config
ssh_pwauth: true
disable_root: false
chpasswd: { list: ["root:toor"], expire: false }
runcmd:
- printf '%s\n' 'PermitRootLogin yes' >> /etc/ssh/sshd_config
- systemctl restart ssh.service

34
packer/qemu/start-vm.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/sh
set -eu
export LC_ALL=C
SRC_DIR=$(dirname "$(readlink -f "$0")")
TMP_DIR=$(mktemp -d)
trap 'rm -rf "${TMP_DIR:?}"' EXIT
CLOUDIMG_DISK=${SRC_DIR:?}/packer_output/wireguard.qcow2
SNAPSHOT_DISK=${TMP_DIR:?}/cloudinit-snapshot.qcow2
USERDATA_DISK=${TMP_DIR:?}/cloudinit-seed.img
USERDATA_YAML=${TMP_DIR:?}/user-data
# Create a snapshot image to preserve the original cloud-image
qemu-img create -b "${CLOUDIMG_DISK:?}" -f qcow2 "${SNAPSHOT_DISK:?}"
qemu-img resize "${SNAPSHOT_DISK:?}" +2G
# Create a seed image with metadata using cloud-localds
printf '%s\n' '#cloud-config' 'runcmd: ["ssh-import-id gh:hectorm"]' > "${USERDATA_YAML:?}"
cloud-localds "${USERDATA_DISK:?}" "${USERDATA_YAML:?}"
# Remove keys from the known_hosts file
ssh-keygen -R '[127.0.0.1]:2222'
ssh-keygen -R '[localhost]:2222'
# Launch VM
kvm \
-smp 1 -m 512 \
-nographic -serial mon:stdio \
-device e1000,netdev=n0 \
-netdev user,id=n0,hostfwd=tcp::2222-:22,hostfwd=udp::51820-:51820 \
-drive file="${SNAPSHOT_DISK:?}",if=virtio,format=qcow2 \
-drive file="${USERDATA_DISK:?}",if=virtio,format=raw

View File

@@ -0,0 +1,4 @@
APT::Periodic::Enable "1";
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";

View File

@@ -0,0 +1,9 @@
Unattended-Upgrade::Origins-Pattern { "origin=*"; };
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::InstallOnShutdown "false";
Unattended-Upgrade::Mail "root";
Unattended-Upgrade::MailOnlyOnError "false";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "05:30";

View File

@@ -0,0 +1,9 @@
[sshd]
enabled = true
filter = sshd
banaction = ufw
backend = systemd
maxretry = 5
findtime = 10m
bantime = 10m
ignoreip = 127.0.0.1/8 ::1

View File

@@ -0,0 +1,26 @@
Protocol 2
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
ListenAddress 0.0.0.0
Port 22
UseDNS no
UsePAM yes
X11Forwarding no
AllowTcpForwarding yes
AllowGroups ssh-user
PermitRootLogin without-password
PermitEmptyPasswords no
PermitUserEnvironment no
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
GSSAPIAuthentication no
Subsystem sftp internal-sftp
LoginGraceTime 30
TCPKeepAlive yes
ClientAliveInterval 60
ClientAliveCountMax 5
PrintMotd yes
PrintLastLog yes
SyslogFacility AUTH
LogLevel INFO

View File

@@ -0,0 +1,43 @@
server:
interface: 0.0.0.0
interface: ::0
port: 53
root-hints: "/usr/share/dns/root.hints"
auto-trust-anchor-file: "/var/lib/unbound/root.key"
access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.0/8 allow
access-control: 10.10.10.0/24 allow
access-control: ::0/0 refuse
access-control: ::1 allow
access-control: ::ffff:127.0.0.0/104 allow
access-control: fd10:10:10::1/64 allow
private-address: 0.0.0.0/8
private-address: ::ffff:0.0.0.0/104
private-address: 10.0.0.0/8
private-address: ::ffff:10.0.0.0/104
private-address: 100.64.0.0/10
private-address: ::ffff:100.64.0.0/106
private-address: 127.0.0.0/8
private-address: ::ffff:127.0.0.0/104
private-address: 169.254.0.0/16
private-address: ::ffff:169.254.0.0/112
private-address: 172.16.0.0/12
private-address: ::ffff:172.16.0.0/108
private-address: 192.168.0.0/16
private-address: ::ffff:192.168.0.0/112
private-address: ::/128
private-address: ::1/128
private-address: fc00::/7
private-address: fd00::/8
private-address: fe80::/10
hide-identity: yes
hide-version: yes
qname-minimisation: yes
cache-min-ttl: 300
cache-max-ttl: 14400
prefetch: yes
prefetch-key: yes
verbosity: 1
val-log-level: 1
#include: "/etc/unbound/unbound.conf.d/*.conf"

View File

@@ -0,0 +1,9 @@
[Interface]
PrivateKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Address = 10.10.10.2/32, fd10:10:10::2/128
DNS = 10.10.10.1, fd10:10:10::1
[Peer]
PublicKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
AllowedIPs = 0.0.0.0/0, ::0/0
Endpoint = XXX.XXX.XXX.XXX:51820

View File

@@ -0,0 +1,11 @@
#[Peer]
#PublicKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#AllowedIPs = 10.10.10.2/32, fd10:10:10::2/128
#[Peer]
#PublicKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#AllowedIPs = 10.10.10.3/32, fd10:10:10::3/128
#[Peer]
#PublicKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#AllowedIPs = 10.10.10.4/32, fd10:10:10::4/128

View File

@@ -0,0 +1,36 @@
[Interface]
Address = 10.10.10.1/24, fd10:10:10::1/64
ListenPort = 51820
# Load keys
PostUp = [ -e '/etc/wireguard/%i-privatekey' ] || (umask 077 && wg genkey > '/etc/wireguard/%i-privatekey')
PostUp = [ -e '/etc/wireguard/%i-publickey' ] || (umask 022 && wg pubkey < '/etc/wireguard/%i-privatekey' > '/etc/wireguard/%i-publickey')
PostUp = wg set '%i' private-key '/etc/wireguard/%i-privatekey'
# Load peers
PostUp = [ -e '/etc/wireguard/%i-peers.conf' ] || (umask 022 && touch '/etc/wireguard/%i-peers.conf')
PostUp = wg addconf '%i' '/etc/wireguard/%i-peers.conf'
# Enable IPv4/IPv6 forwarding
PostUp = grep -Fxq '1' /proc/sys/net/ipv4/ip_forward || printf 1 > /proc/sys/net/ipv4/ip_forward
PostUp = grep -Fxq '1' /proc/sys/net/ipv6/conf/all/forwarding || printf 1 > /proc/sys/net/ipv6/conf/all/forwarding
PostUp = grep -Fxq '1' /proc/sys/net/ipv6/conf/default/forwarding || printf 1 > /proc/sys/net/ipv6/conf/default/forwarding
# Store the internet-facing interface in a file for later use
PostUp = ip route show default | awk '/^default/{print $5}' > '/etc/wireguard/%i-iface'
# Allow access WireGuard via port 51820/UDP on the internet-facing interface
PostUp = iptables -A INPUT -i "$(cat '/etc/wireguard/%i-iface')" -p udp --dport 51820 -j ACCEPT
PostUp = ip6tables -A INPUT -i "$(cat '/etc/wireguard/%i-iface')" -p udp --dport 51820 -j ACCEPT
PostDown = iptables -D INPUT -i "$(cat '/etc/wireguard/%i-iface')" -p udp --dport 51820 -j ACCEPT
PostDown = ip6tables -D INPUT -i "$(cat '/etc/wireguard/%i-iface')" -p udp --dport 51820 -j ACCEPT
# Allow access WireGuard via port 53/UDP on the internet-facing interface (to circumvent some firewalls)
PostUp = iptables -t nat -A PREROUTING -i "$(cat '/etc/wireguard/%i-iface')" -p udp --dport 53 -j REDIRECT --to-port 51820
PostUp = ip6tables -t nat -A PREROUTING -i "$(cat '/etc/wireguard/%i-iface')" -p udp --dport 53 -j REDIRECT --to-port 51820
PostDown = iptables -t nat -D PREROUTING -i "$(cat '/etc/wireguard/%i-iface')" -p udp --dport 53 -j REDIRECT --to-port 51820
PostDown = ip6tables -t nat -D PREROUTING -i "$(cat '/etc/wireguard/%i-iface')" -p udp --dport 53 -j REDIRECT --to-port 51820
# Allow packet forwarding on the WireGuard interface
PostUp = iptables -A FORWARD -i '%i' -j ACCEPT && iptables -t nat -A POSTROUTING -o "$(cat '/etc/wireguard/%i-iface')" -j MASQUERADE
PostUp = ip6tables -A FORWARD -i '%i' -j ACCEPT && ip6tables -t nat -A POSTROUTING -o "$(cat '/etc/wireguard/%i-iface')" -j MASQUERADE
PostDown = iptables -D FORWARD -i '%i' -j ACCEPT && iptables -t nat -D POSTROUTING -o "$(cat '/etc/wireguard/%i-iface')" -j MASQUERADE
PostDown = ip6tables -D FORWARD -i '%i' -j ACCEPT && ip6tables -t nat -D POSTROUTING -o "$(cat '/etc/wireguard/%i-iface')" -j MASQUERADE
# Allow access to the local DNS server on the WireGuard interface
PostUp = iptables -A INPUT -i '%i' -p tcp --dport 53 -j ACCEPT && iptables -A INPUT -i '%i' -p udp --dport 53 -j ACCEPT
PostUp = ip6tables -A INPUT -i '%i' -p tcp --dport 53 -j ACCEPT && ip6tables -A INPUT -i '%i' -p udp --dport 53 -j ACCEPT
PostDown = iptables -D INPUT -i '%i' -p tcp --dport 53 -j ACCEPT && iptables -D INPUT -i '%i' -p udp --dport 53 -j ACCEPT
PostDown = ip6tables -D INPUT -i '%i' -p tcp --dport 53 -j ACCEPT && ip6tables -D INPUT -i '%i' -p udp --dport 53 -j ACCEPT

48
packer/sources.pkr.hcl Normal file
View File

@@ -0,0 +1,48 @@
source "hcloud" "main" {
image = "ubuntu-18.04"
server_type = "cx11"
location = "fsn1"
server_name = "wireguard-{{timestamp}}"
snapshot_name = "wireguard-{{timestamp}}"
snapshot_labels {
service = "wireguard"
}
ssh_port = "22"
ssh_username = "root"
ssh_timeout = "10m"
}
source "qemu" "main" {
iso_url = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img"
iso_checksum_url = "https://cloud-images.ubuntu.com/bionic/current/SHA256SUMS"
iso_checksum_type = "sha256"
disk_image = true
vm_name = "wireguard.qcow2"
http_directory = "{{template_dir}}/qemu/http/"
output_directory = "{{template_dir}}/qemu/dist/"
accelerator = "kvm"
cpus = 1
memory = 512
headless = true
qemuargs {
qemuargs = ["-smbios", "type=1,serial=ds=nocloud-net;s=http://{{.HTTPIP}}:{{.HTTPPort}}/seed/"]
}
net_device = "virtio-net"
format = "qcow2"
disk_size = "4G"
disk_interface = "virtio"
disk_compression = false
ssh_port = "22"
ssh_username = "root"
ssh_password = "toor"
ssh_timeout = "10m"
shutdown_command = "shutdown -P now"
}