From 79e2dc6df9499ab49bb0d28bc44c359a23467359 Mon Sep 17 00:00:00 2001
From: Leonidas Spyropoulos <artafinde@archlinux.org>
Date: Sat, 15 Feb 2025 15:34:57 +0000
Subject: [PATCH] Add new sponsored reproducible worker (repro4)

The server only has a public IPv6 address and a DNATed (port forwarded)
SSH port for accessing the server over IPv4. So this commit contains
some changes for supporting that.

Co-authored-by: Kristian Klausen <kristian@klausen.dk>
---
 docs/servers.md                               |  8 ++++--
 host_vars/gitlab.archlinux.org/misc.yml       |  1 +
 host_vars/repro4.pkgbuild.com/misc.yml        | 28 +++++++++++++++++++
 hosts                                         |  1 +
 misc/vaults/vault_tux_si.yml                  | 11 ++++++++
 roles/networking/defaults/main.yml            |  1 +
 roles/networking/files/50-tcp_fastopen.conf   |  1 +
 roles/networking/handlers/main.yml            |  7 +++++
 roles/networking/tasks/main.yml               | 14 ++++++++++
 .../templates/10-static-ethernet.network.j2   |  6 ++--
 .../templates/10-static6-ethernet.network.j2  | 14 ++++++++++
 roles/sshd/tasks/main.yml                     |  2 +-
 roles/sshd/templates/sshd_config.j2           |  2 +-
 tf-stage1/archlinux.tf                        |  3 ++
 tf-stage1/templates.tf                        |  4 ++-
 15 files changed, 94 insertions(+), 9 deletions(-)
 create mode 100644 host_vars/repro4.pkgbuild.com/misc.yml
 create mode 100644 misc/vaults/vault_tux_si.yml
 create mode 100644 roles/networking/files/50-tcp_fastopen.conf
 create mode 100644 roles/networking/templates/10-static6-ethernet.network.j2

diff --git a/docs/servers.md b/docs/servers.md
index c2eed4785..83ffab6f3 100644
--- a/docs/servers.md
+++ b/docs/servers.md
@@ -85,9 +85,11 @@ So to set up this server from scratch, run:
 
 ### Services
   - Runs a master [rebuilderd](https://reproducible.archlinux.org) instance
-    with two workers:
-    - repro2.pkgbuild.com (Kape server with an EPYC 7702P and 256G RAM)
-    - repro3.pkgbuild.com (Equinix Metal box with a Xeon E-2278G and 64G RAM)
+    with these workers:
+    - repro2.pkgbuild.com (Kape server with an EPYC 7702P and 256G RAM - 4 workers)
+    - repro3.pkgbuild.com (Equinix Metal box with a Xeon E-2278G and 64G RAM - 2 workers)
+    - repro4.pkgbuild.com (Proxmox VM with 16vCores and 192G RAM - 2 workers)
+
 
 ## runner1.archlinux.org
 
diff --git a/host_vars/gitlab.archlinux.org/misc.yml b/host_vars/gitlab.archlinux.org/misc.yml
index 98378f1bd..6a794d5e2 100644
--- a/host_vars/gitlab.archlinux.org/misc.yml
+++ b/host_vars/gitlab.archlinux.org/misc.yml
@@ -1,4 +1,5 @@
 ansible_port: 2222
+sshd_port: 2222
 enable_zram_swap: true
 additional_addresses: ["213.133.111.6/32", "2a01:4f8:222:174c::2/64"]
 wireguard_address: 10.0.0.5
diff --git a/host_vars/repro4.pkgbuild.com/misc.yml b/host_vars/repro4.pkgbuild.com/misc.yml
new file mode 100644
index 000000000..844d00088
--- /dev/null
+++ b/host_vars/repro4.pkgbuild.com/misc.yml
@@ -0,0 +1,28 @@
+# This host does not have a public IPv4 address, but only a public IPv6
+# address. We have a DNATed (port forwarded) SSH port for accessing the
+# server over IPv4 though, which is defined below.
+ansible_host: 141.255.217.9
+ansible_port: 8189
+
+ipv4_address: 10.113.2.189
+ipv4_netmask: /24
+ipv6_address: 2001:1470:fffd:3050::189:1
+ipv4_gateway: 10.113.2.1
+ipv6_interface: ens19
+ipv6_netmask: /112
+ipv6_gateway: 2001:1470:fffd:3050::1
+ipv6_ignore_ra: true
+network_interface: ens18
+# TFO is broken on this network likely due to some middlebox.
+# systemd-resolved uses TFO if possible, so this must be disabled for
+# DNS to work reliably.
+network_disable_ipv4_tcp_fast_open: true
+system_disks:
+  - /dev/sda
+configure_network: true
+
+rebuilderd_workers:
+  - repro41
+  - repro42
+wireguard_address: 10.0.0.47
+wireguard_public_key: MJrXDwK61CF7nT5r1HRxxp44DocZyrQslK5plCJFexY=
diff --git a/hosts b/hosts
index cda592bfc..833d66a76 100644
--- a/hosts
+++ b/hosts
@@ -112,6 +112,7 @@ reproducible.archlinux.org
 [rebuilderd_workers]
 repro2.pkgbuild.com
 repro3.pkgbuild.com
+repro4.pkgbuild.com
 
 [memcached]
 wiki.archlinux.org
diff --git a/misc/vaults/vault_tux_si.yml b/misc/vaults/vault_tux_si.yml
new file mode 100644
index 000000000..b80f781bd
--- /dev/null
+++ b/misc/vaults/vault_tux_si.yml
@@ -0,0 +1,11 @@
+$ANSIBLE_VAULT;1.2;AES256;super
+33306163393032613465383739303962343335636564346265653964353062646266343638636435
+3964313736313037356532626634636465663732356333660a313038393762336536653564333663
+62353832346638333336306563353832326638656663386137353535383536643732616538663733
+6536663831333631640a656366653034353465303432313230323762333263393032316265316165
+65616261623131366531343832393034323662373639313066623761323134373164653461373431
+34623962643734326635643236353932636332656264393238343238643737626364636138653031
+39343466323833393436666539363034363835653663376332613263653861323363393934613061
+61663064386261633162376630663133666663306536346661393936623535303764313735346665
+33646532636338663134666237633566386634646534313464343139646330353837346164323932
+3438343466383532366335646437326332613935333563336634
diff --git a/roles/networking/defaults/main.yml b/roles/networking/defaults/main.yml
index 8ba213dd4..c4a4a3bef 100644
--- a/roles/networking/defaults/main.yml
+++ b/roles/networking/defaults/main.yml
@@ -1,2 +1,3 @@
 chroot_path: ""
 network_interface: "en*"
+network_disable_ipv4_tcp_fast_open: false
diff --git a/roles/networking/files/50-tcp_fastopen.conf b/roles/networking/files/50-tcp_fastopen.conf
new file mode 100644
index 000000000..f4ba9eec2
--- /dev/null
+++ b/roles/networking/files/50-tcp_fastopen.conf
@@ -0,0 +1 @@
+net.ipv4.tcp_fastopen=0
diff --git a/roles/networking/handlers/main.yml b/roles/networking/handlers/main.yml
index 147e784c3..e924ebd82 100644
--- a/roles/networking/handlers/main.yml
+++ b/roles/networking/handlers/main.yml
@@ -4,3 +4,10 @@
     state: restarted
     daemon_reload: true
   when: chroot_path | length == 0
+
+- name: Restart systemd-sysctl
+  systemd_service:
+    name: systemd-sysctl
+    state: restarted
+    daemon_reload: true
+  when: chroot_path | length == 0
diff --git a/roles/networking/tasks/main.yml b/roles/networking/tasks/main.yml
index 35633eab4..27760be75 100644
--- a/roles/networking/tasks/main.yml
+++ b/roles/networking/tasks/main.yml
@@ -6,6 +6,14 @@
       notify:
         - Restart networkd
 
+    - name: Install 10-static6-ethernet.network
+      template: src=10-static6-ethernet.network.j2 dest={{ chroot_path }}/etc/systemd/network/10-static6-ethernet.network owner=root group=root mode=0644
+      vars:
+        network_interface: "{{ ipv6_interface }}"
+      notify:
+        - Restart networkd
+      when: ipv6_interface is defined
+
     - name: Create drop-in directory for 10-static-ethernet.network
       file: path={{ chroot_path }}/etc/systemd/network/10-static-ethernet.network.d state=directory owner=root group=root mode=0755
 
@@ -38,6 +46,12 @@
     - Restart networkd
   when: additional_addresses is defined
 
+- name: Disable IPv4 TCP Fast Open
+  copy: src=50-tcp_fastopen.conf dest={{ chroot_path }}/etc/sysctl.d/50-tcp_fastopen.conf owner=root group=root mode=0644
+  notify:
+    - Restart systemd-sysctl
+  when: network_disable_ipv4_tcp_fast_open
+
 - name: Create symlink to resolv.conf
   file: src=/run/systemd/resolve/stub-resolv.conf dest={{ chroot_path }}/etc/resolv.conf state=link force=yes follow=no owner=root group=root
 
diff --git a/roles/networking/templates/10-static-ethernet.network.j2 b/roles/networking/templates/10-static-ethernet.network.j2
index 50cf96585..3f89755d4 100644
--- a/roles/networking/templates/10-static-ethernet.network.j2
+++ b/roles/networking/templates/10-static-ethernet.network.j2
@@ -3,7 +3,7 @@ Name={{ network_interface }}
 
 [Network]
 Gateway={{ ipv4_gateway }}
-{% if ipv6_gateway is defined %}
+{% if ipv6_gateway is defined and ipv6_interface is not defined %}
 Gateway={{ ipv6_gateway }}
 {% endif %}
 {% if ipv6_ignore_ra|default(false) is true %}
@@ -17,12 +17,12 @@ Address={{ ipv4_address }}{{ ipv4_netmask }}
 Peer={{ ipv4_gateway }}{{ ipv4_netmask}}
 {% endif %}
 
-{% if ipv6_address is defined %}
+{% if ipv6_address is defined and ipv6_interface is not defined %}
 [Address]
 Address={{ ipv6_address }}{{ ipv6_netmask }}
 {% endif %}
 
-{% if ipv6_gateway is defined and not ipv6_gateway.startswith("fe80") %}
+{% if ipv6_gateway is defined and not ipv6_gateway.startswith("fe80") and ipv6_interface is not defined %}
 [Route]
 Destination={{ ipv6_gateway }}
 {% endif %}
diff --git a/roles/networking/templates/10-static6-ethernet.network.j2 b/roles/networking/templates/10-static6-ethernet.network.j2
new file mode 100644
index 000000000..0fe9a87ee
--- /dev/null
+++ b/roles/networking/templates/10-static6-ethernet.network.j2
@@ -0,0 +1,14 @@
+[Match]
+Name={{ ipv6_interface }}
+
+[Network]
+Gateway={{ ipv6_gateway }}
+{% if ipv6_ignore_ra|default(false) is true %}
+IPv6AcceptRA=false
+{% endif %}
+
+[Address]
+{% if ipv6_netmask != "/64" %}
+Peer={{ ipv6_gateway }}/128
+{% endif %}
+Address={{ ipv6_address }}{{ ipv6_netmask }}
diff --git a/roles/sshd/tasks/main.yml b/roles/sshd/tasks/main.yml
index 063bd0c77..bc15501d4 100644
--- a/roles/sshd/tasks/main.yml
+++ b/roles/sshd/tasks/main.yml
@@ -13,7 +13,7 @@
   service: name=sshd enabled=yes state=started
 
 - name: Open firewall holes
-  ansible.posix.firewalld: service={{ 'ssh' if ansible_port is not defined else omit }} port={{ "%d/tcp" | format(ansible_port) if ansible_port is defined else omit }} permanent=true state=enabled immediate=yes
+  ansible.posix.firewalld: service={{ 'ssh' if sshd_port == 22 else omit }} port={{ "%d/tcp" | format(sshd_port) if sshd_port != 22 else omit }} permanent=true state=enabled immediate=yes
   when: configure_firewall is defined and configure_firewall
   tags:
     - firewall
diff --git a/roles/sshd/templates/sshd_config.j2 b/roles/sshd/templates/sshd_config.j2
index 6e5a53c27..3734c4ef4 100644
--- a/roles/sshd/templates/sshd_config.j2
+++ b/roles/sshd/templates/sshd_config.j2
@@ -1,4 +1,4 @@
-Port {{ ansible_port | default(22) }}
+Port {{ sshd_port }}
 LogLevel VERBOSE
 PasswordAuthentication no
 ClientAliveInterval 30
diff --git a/tf-stage1/archlinux.tf b/tf-stage1/archlinux.tf
index bbc325adf..dd9417868 100644
--- a/tf-stage1/archlinux.tf
+++ b/tf-stage1/archlinux.tf
@@ -419,6 +419,9 @@ locals {
       ipv4_address = "147.75.84.133"
       ipv6_address = "2604:1380:4601:7d00::1"
     }
+    repro4 = {
+      ipv6_address = "2001:1470:fffd:3050::189:1"
+    }
     www = {
       ipv4_address = hcloud_server.machine["homedir.archlinux.org"].ipv4_address
       ipv6_address = hcloud_server.machine["homedir.archlinux.org"].ipv6_address
diff --git a/tf-stage1/templates.tf b/tf-stage1/templates.tf
index 7e588ebf4..636e95364 100644
--- a/tf-stage1/templates.tf
+++ b/tf-stage1/templates.tf
@@ -57,7 +57,9 @@ resource "hetznerdns_record" "archlinux_page_aaaa" {
 }
 
 resource "hetznerdns_record" "pkgbuild_com_a" {
-  for_each = local.pkgbuild_com_a_aaaa
+  for_each = {
+    for k, v in local.pkgbuild_com_a_aaaa : k => v if try(v.ipv4_address != "", false)
+  }
 
   zone_id = hetznerdns_zone.pkgbuild.id
   name    = each.key
-- 
GitLab