From 0e723e2da8bf6621a3a441c51e429649cab29d7a Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Sun, 3 May 2026 15:55:15 +0200 Subject: [PATCH] feat(amd): add opencode web server at opencode.amd.hoyer.world Mirror of the sgx opencode setup: systemd service on port 4196 fronted by nginx with a per-host ACME cert (DNS-01 via internetbs). Adds amd key + path rule to .sops.yaml so secrets under .secrets/amd/ encrypt for the host. --- .secrets/amd/internetbs.yaml | 34 +++++++++++++++++++ .secrets/amd/opencode-web.yaml | 34 +++++++++++++++++++ .sops.yaml | 7 ++++ systems/x86_64-linux/amd/acme.nix | 11 +++++++ systems/x86_64-linux/amd/default.nix | 7 ++++ systems/x86_64-linux/amd/nginx.nix | 18 ++++++++++ systems/x86_64-linux/amd/opencode.nix | 47 +++++++++++++++++++++++++++ 7 files changed, 158 insertions(+) create mode 100644 .secrets/amd/internetbs.yaml create mode 100644 .secrets/amd/opencode-web.yaml create mode 100644 systems/x86_64-linux/amd/acme.nix create mode 100644 systems/x86_64-linux/amd/nginx.nix create mode 100644 systems/x86_64-linux/amd/opencode.nix diff --git a/.secrets/amd/internetbs.yaml b/.secrets/amd/internetbs.yaml new file mode 100644 index 0000000..f833693 --- /dev/null +++ b/.secrets/amd/internetbs.yaml @@ -0,0 +1,34 @@ +internetbs: ENC[AES256_GCM,data:HTTxPwcGWFo/WkWD6UZhE6qUaBmJSVFzDux3EFn2uH1mCPoW0vKykfUbbMCJo0tWMvQszetAuO5jnQJJBrIkM6vaXX06ZlDUWluh+sPavqKFeq9HDobgf9qhhaaSHgrD/hLgz+dJ+Lj87/huEMhWj8KrnPY1Hj5uDUFVaJOMgNzczSt6iLA/mdL/cEiBT5st8qk8,iv:Ug59B4G7p0zVEAuMQlEYk+GcOjy/QOxEvxbdLnRTgpA=,tag:Z/7ceoVgr3ciNFKSlncjpA==,type:str] +sops: + age: + - recipient: age1u2glh4g65qjvlcan7u7qmhdlpvxqkc2h48m5zka8nafjrfnt5e3ss494vt + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzV08vMTJrazQyRjNVaHRR + KzRJcFBlRWJjanhCRk16Q25DcExzUHl0Y2tNCjlzS2dnbWUwWERORWtZOFB3R0ZT + VEZvUjZpVVVOWkVSZHdUaWdaMHAxaW8KLS0tIFF5VThaU0lyWkh2MXVpTGtlOWwz + K2h0dXVFRWJ3NXkrNmw5TkpKZFJUbUUKxRBQN7jewc0knpSa4wKtcbfP3kUbWBoC + a0zUUXb+Ooa76Sg0tK+gz5BDUqcxcPNbwhUwWaMz4FlRHMtMkQGoaQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dwcz3fmp29ju4svy0t0wz4ylhpwlqa8xpw4l7t4gmgqr0ev37qrsfn840l + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwNnJaaUh4UDgxVzFIK1dD + RUFjKzVOTDU1TUhqZEN5SW9NcXFSTHlkNkNNCnprMXY5cDI3TC9PakZyNkY5NG00 + SGhXbkJxQ2FUOUthcjNzMmQxVVg1WmcKLS0tIG16ZjFWSW5tQUw5SXV5WTgvVkt5 + WFlyeTRBS3p4N0pVOW11NXh5M1RkZ3cKDR9dB36DavUmChJUriFOTCWN7+M9xwoK + 2dRb1O4N0qouYpAxef8vwL7VQUXOF0pqb+F7KF87EqRtir+SmbqCfg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1cpm9xhgue7sjvq7zyeeaxwr96c93sfzxxxj76sxsq7s7kgnygvcq5jxren + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYT1FYNEJmSFhOaEtRZ3ZH + TWtxeVd2cVVqeURLTEk2d2tOWUFCNnRMS3gwCis1QUIzOHpLQW5tUzI0Nzk4N0VQ + N3lIZkVYWDU5VlAvWXNFR2w4ZTNFTTAKLS0tIFNsdG5jcHNtWjYzVHgwcjBSOTYr + RGZ3aTdwUi83blNCbjQwR1phd2UzdVkKpxSOiGK1cyRKdzd+d7jiTxYGwkpgB6OO + 6TyY896Eht2iL34w7jXyH+eKJ8fzQrftpyARHy54r7LDS3TBhEFVxA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-12-06T08:50:35Z" + mac: ENC[AES256_GCM,data:Tz1EutxDgl2DQgNWNJWap5cwSAgR/Y4EjLUva7qHtXIMWa5jKPKqimY2IQhcsbqYv1zZmm+OnbO+OCIdZRbpnDCk5waBhywQNxNxjGAbv9fo/hbRFg9cm/vwA2BrXk9BR1L+gMcejRyZnnlMwEK+NomBkqAkpDZDlKjE7ebHoz0=,iv:Lk9kE3opD9y4oheETzLOiPn6Z5dLx8JEAuyCaYbkpQ4=,tag:/KtGrq7sGUxfi7BaJObhOQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/.secrets/amd/opencode-web.yaml b/.secrets/amd/opencode-web.yaml new file mode 100644 index 0000000..eaab057 --- /dev/null +++ b/.secrets/amd/opencode-web.yaml @@ -0,0 +1,34 @@ +opencode-web-password: ENC[AES256_GCM,data:u1Rw15snERc7+zkW2rZS91fadbuLk1msfEBIqe+bHVno6cdJabXoznsxtPyDnN/4G1+hHMZvBIWCSzNzoB78XMh4P/hmRr8=,iv:snqYkpsUQZL020wqitNneD3v2E3eM2VddzkrzaUEwBw=,tag:eAkktHW3bdYcwvWrjhppxw==,type:str] +sops: + age: + - recipient: age1u2glh4g65qjvlcan7u7qmhdlpvxqkc2h48m5zka8nafjrfnt5e3ss494vt + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvRGkxeHdKUDZ3U3ZZM1Bu + cGxiTlNLMk5seWVrTW80WHgyVGhTRDVKWUFJCkROYkhnaVBONjVidHEwdUVSWVlk + dG53V0xkV3JlRjh0N01HbGxHbFdvUHMKLS0tIFVuQkZWRi8vTmJXbnc3Mjc1TlNy + YnFKRk5DbUZrNEVLWUZ0UWRQWE9ZZlkKCav6B/v1Gf1mPn8bgUVgFHqTACbIVzZX + 8BODNMIbGYKRzLRWYr/UDMGnNONW+2i9o4Czei0yeb0sT9yZ9EozBQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1dwcz3fmp29ju4svy0t0wz4ylhpwlqa8xpw4l7t4gmgqr0ev37qrsfn840l + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhY1BCTUFJR2x2OEowcU5M + L0xCcUxZR2lzb3lBamJNR3hQMTZSRDlGeEY4Cm5Ea0hZQjI2SmRiTGw2bUZZT1Rn + SWhUTlJjNE1ZWmhDa05FSGRnV1A4L0kKLS0tIDRKK3l0VXE5aGkvNnNpbnVXUmNY + bmk0ekNuRzA2S2VFY0NhR0ZVRVhFWkUKyM/iL60iQ+qcxW4EtM6q7gkm+rqyMDqX + 8rgh5sjjz03r7LujFkSyoXEEdylHsqW57Pp4sDyxpPcSeBbG1ubyNw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1cpm9xhgue7sjvq7zyeeaxwr96c93sfzxxxj76sxsq7s7kgnygvcq5jxren + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJYm1vS2dja3V4emtSTzh4 + ZUlCckxQbi9vNkE3M1lvcjFTRVlDRGxaaVRJCjQrU1JnUDlmZVBYbkJ5TTJuTnd5 + MXBTbFhLRlFGWTJjbDZQZHBzUmdGclkKLS0tIHRoSmZ0Sm9hd3M4MVpiSkh4VjJK + T094Q0pWdWozRnZJd0ZKSisvQmlDUXcKRIvz33dKoJuP4YEEcNEkMMMmQZ3/bp9y + eDoUR+35e4/Q60NeUJzlNYfW/wobggUbx0fijXkTSbp+7C7YGkSgyQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-05-03T13:14:50Z" + mac: ENC[AES256_GCM,data:VQ9TMo0QtPpgmkbYOJEwPG/RDPbScHCsJhFO+bhRJ64dazMwIKxO1DAsHF1298YeTbY5/EXly+8FS1kE5dQY1cGSy64fcSusM14k0a9Js0GxCz1NuJNlwzJVCZv5zjP8koH2B7PdIUhgI45zGIAuNcfP6dmtgy2vfGXcFg2cZpU=,iv:6cR1mYKoIkpVYrLN9z1Dd5CBOuizlhjau1TNbRqg2zA=,tag:7eKKsi6gS7PdIMZ0UOt90g==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.1 diff --git a/.sops.yaml b/.sops.yaml index cd9a64b..258f720 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -1,6 +1,7 @@ keys: - &server_hetzner age1qur4kh3gay9ryk3jh2snvjp6x9eq94zdrmgkrfcv4fzsu7l6lumq4tr3uy - &server_sgx age149fqcw5jze00vd7jauylrp4j5xyv7amlu57jjfuzghkqtzlnxajs704uz3 + - &server_amd age1u2glh4g65qjvlcan7u7qmhdlpvxqkc2h48m5zka8nafjrfnt5e3ss494vt - &server_t15 age1f2yu0cc826ej7hs4g865y29zy9uqfy0yp32f2m80typpk2pxqp7sfcffj4 - &server_x1 age1z87u2na6vts0sqg6sc73p9ym6e5g9a0gf3hp9e7ha47e83zy4efqcjhk0y - &harald age1dwcz3fmp29ju4svy0t0wz4ylhpwlqa8xpw4l7t4gmgqr0ev37qrsfn840l @@ -18,6 +19,12 @@ creation_rules: - *server_sgx - *harald - *harald_ssh + - path_regex: .secrets/amd/[^/]+\.(yaml|json|env|ini)$ + key_groups: + - age: + - *server_amd + - *harald + - *harald_ssh - path_regex: .secrets/t15/[^/]+\.(yaml|json|env|ini)$ key_groups: - age: diff --git a/systems/x86_64-linux/amd/acme.nix b/systems/x86_64-linux/amd/acme.nix new file mode 100644 index 0000000..fefc75d --- /dev/null +++ b/systems/x86_64-linux/amd/acme.nix @@ -0,0 +1,11 @@ +{ + config, + ... +}: +{ + sops.secrets.internetbs = { + sopsFile = ../../../.secrets/amd/internetbs.yaml; + }; + + metacfg.services.acmeBase.credentialsFile = config.sops.secrets.internetbs.path; +} diff --git a/systems/x86_64-linux/amd/default.nix b/systems/x86_64-linux/amd/default.nix index e1dc4b3..13f998d 100644 --- a/systems/x86_64-linux/amd/default.nix +++ b/systems/x86_64-linux/amd/default.nix @@ -10,12 +10,17 @@ with lib.metacfg; ./hardware-configuration.nix ./xremap.nix ./sound.nix + ./acme.nix + ./nginx.nix + ./opencode.nix ]; powerManagement.cpuFreqGovernor = "performance"; services.rustdesk-server.signal.enable = false; networking.firewall.allowedTCPPorts = [ + 80 + 443 22000 ]; @@ -29,6 +34,8 @@ with lib.metacfg; services.resolved.enable = true; metacfg = { + services.nginxBase.enable = true; + services.acmeBase.enable = true; hardware.wooting.enable = true; base.enable = true; gui.enable = true; diff --git a/systems/x86_64-linux/amd/nginx.nix b/systems/x86_64-linux/amd/nginx.nix new file mode 100644 index 0000000..1e0d0c5 --- /dev/null +++ b/systems/x86_64-linux/amd/nginx.nix @@ -0,0 +1,18 @@ +{ + ... +}: +{ + services.nginx.virtualHosts = { + "opencode.amd.hoyer.world" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:4196"; + proxyWebsockets = true; + extraConfig = '' + proxy_buffering off; + ''; + }; + }; + }; +} diff --git a/systems/x86_64-linux/amd/opencode.nix b/systems/x86_64-linux/amd/opencode.nix new file mode 100644 index 0000000..68f62f4 --- /dev/null +++ b/systems/x86_64-linux/amd/opencode.nix @@ -0,0 +1,47 @@ +{ + config, + pkgs, + lib, + ... +}: + +let + port = 4196; + user = "harald"; + homeDir = "/home/harald"; +in +{ + systemd.services.opencode-serve = { + description = "OpenCode Web Server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = { + HOME = homeDir; + }; + + serviceConfig = { + Type = "simple"; + User = user; + Group = "users"; + WorkingDirectory = homeDir; + ExecStart = "${pkgs.opencode}/bin/opencode serve --hostname 127.0.0.1 --port ${toString port}"; + Restart = "always"; + RestartSec = 5; + EnvironmentFile = config.sops.secrets.opencode-web-password.path; + + # Security hardening + PrivateTmp = true; + ProtectSystem = "strict"; + ProtectHome = false; + NoNewPrivileges = true; + ReadWritePaths = [ homeDir ]; + }; + }; + + sops.secrets.opencode-web-password = { + sopsFile = ../../../.secrets/amd/opencode-web.yaml; + owner = user; + restartUnits = [ "opencode-serve.service" ]; + }; +}