dashboard / nomad / feat(git): anubis sidecar #9 rss

accepted · opened on 2026-06-25 by in0rdr
Help
checkout latest patchset:
ssh pr.in0rdr.ch print pr-9 | git am -3
checkout any patchset in a patch request:
ssh pr.in0rdr.ch print ps-X | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.in0rdr.ch pr add 9
add review to patch request:
git format-patch main --stdout | ssh pr.in0rdr.ch pr add --review 9
accept PR:
ssh pr.in0rdr.ch pr accept 9
close PR:
ssh pr.in0rdr.ch pr close 9

Logs

in0rdr created pr with ps-9 on 2026-06-25
in0rdr changed status on 2026-06-25 {"status":"accepted"}

Patchsets

ps-9 by in0rdr on 2026-06-25T20:14:40Z

feat(git): anubis sidecar

* https://board.in0rdr.ch/task/133
hcl/default/git/git.nomad link
+49 -5
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
diff --git a/hcl/default/git/git.nomad b/hcl/default/git/git.nomad
index 46d3499..f2cb137 100644
--- a/hcl/default/git/git.nomad
+++ b/hcl/default/git/git.nomad
@@ -1,6 +1,8 @@
 job "git" {
   datacenters = ["dc1"]
 
+  vault {}
+
   priority = 80
 
   constraint {
@@ -32,14 +34,20 @@ job "git" {
     }
 
     network {
-      port "stagit" {
-        to = 443
-        static = 44328
-      }
       port "smarthttp" {
         to = 443
         static = 44318
       }
+      port "stagithttps" {
+        static = 44328
+        to = 443
+      }
+      port "stagithttp" {
+        to = 80
+      }
+      port "anubis" {
+        to = 8923
+      }
     }
 
     task "smarthttp" {
@@ -86,7 +94,7 @@ job "git" {
       config {
         image = "127.0.0.1:5000/git:latest"
         force_pull = true
-        ports = ["stagit"]
+        ports = ["stagithttp", "stagithttps"]
         volumes = [
           # mount the templated config from the task directory to the container
           "local/stagit.conf:/etc/apache2/conf.d/stagit.conf",
@@ -117,5 +125,41 @@ job "git" {
         cpu    = 100
       }
     }
+
+    task "anubis" {
+      driver = "podman"
+
+      config {
+        image = "docker://ghcr.io/techarohq/anubis:v1.25.0"
+        ports = ["anubis"]
+        volumes = [
+          # mount the templated config from the task directory to the container
+          "local/challenge-any.yml:/etc/anubis/challenge-any.yml",
+        ]
+      }
+
+      template {
+        destination = "${NOMAD_TASK_DIR}/challenge-any.yml"
+        data = file("./templates/challenge-any.yml.tmpl")
+      }
+
+      template {
+        destination = "${NOMAD_SECRETS_DIR}/default.env"
+        env = true
+        data = <<EOT
+DIFFICULTY=4
+TARGET=http://{{ env "NOMAD_ADDR_stagithttp" }}
+HS512_SECRET="{{with secret "kv/anubis"}}{{index .Data.data.HS512_SECRET}}{{end}}"
+COOKIE_DYNAMIC_DOMAIN=True
+POLICY_FNAME=/etc/anubis/challenge-any.yml
+EOT
+      }
+
+      resources {
+        memory = 128
+        memory_max = 256
+        cpu    = 200
+      }
+    }
   }
 }
hcl/default/git/templates/challenge-any.yml.tmpl link
+12 -0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
diff --git a/hcl/default/git/templates/challenge-any.yml.tmpl b/hcl/default/git/templates/challenge-any.yml.tmpl
new file mode 100644
index 0000000..686c186
--- /dev/null
+++ b/hcl/default/git/templates/challenge-any.yml.tmpl
@@ -0,0 +1,12 @@
+bots:
+  - name: any
+    action: CHALLENGE
+    user_agent_regex: .*
+
+status_codes:
+  CHALLENGE: 403
+  DENY: 403
+
+thresholds: []
+
+dnsbl: false
hcl/default/git/templates/stagit.conf.tmpl link
+45 -12
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
diff --git a/hcl/default/git/templates/stagit.conf.tmpl b/hcl/default/git/templates/stagit.conf.tmpl
index d74eb24..3326e4a 100644
--- a/hcl/default/git/templates/stagit.conf.tmpl
+++ b/hcl/default/git/templates/stagit.conf.tmpl
@@ -1,16 +1,49 @@
-<VirtualHost *:443>
-DocumentRoot /var/www/localhost/htdocs
-ServerName code.in0rdr.ch
-
 ErrorLog /dev/stderr
 TransferLog /dev/stdout
 
-SSLCertificateFile "/etc/letsencrypt/live/code.in0rdr.ch/fullchain.pem"
-SSLCertificateKeyFile "/etc/letsencrypt/live/code.in0rdr.ch/privkey.pem"
-                                     
-<Directory /var/www/localhost/htdocs>
-    Order allow,deny
-    Allow from all     
-    Require all granted
-</Directory>
+LogFormat "%{X-Real-Ip}i %h %l %u %t \"%r\" %>s %b" common
+
+# HTTPS listener that forwards to Anubis
+<IfModule mod_proxy.c>
+  <VirtualHost *:443>
+    ServerName code.in0rdr.ch
+    SSLCertificateFile "/etc/letsencrypt/live/code.in0rdr.ch/fullchain.pem"
+    SSLCertificateKeyFile "/etc/letsencrypt/live/code.in0rdr.ch/privkey.pem"
+
+    # HAProxy sends real ip (send-proxy)
+    # https://www.haproxy.com/documentation/haproxy-configuration-manual/latest/#send-proxy
+    # https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html#remoteipproxyprotocol
+    RemoteIPProxyProtocol On
+
+    # These headers need to be set or else Anubis will
+    # throw an "admin misconfiguration" error.
+    # https://anubis.techaro.lol/docs/admin/environments/apache
+    RequestHeader     set X-Real-Ip expr=%{REMOTE_ADDR}
+    RequestHeader     set X-Forwarded-Proto "https"
+    RequestHeader     set X-Http-Version "%{SERVER_PROTOCOL}s"
+    ProxyPreserveHost On
+    ProxyRequests     Off
+    ProxyVia          Off
+
+    ProxyPass             /  http://{{ env "NOMAD_ADDR_anubis" }}/
+    ProxyPassReverse      /  http://{{ env "NOMAD_ADDR_anubis" }}/
+  </VirtualHost>
+</IfModule>
+
+<VirtualHost *:80>
+  DocumentRoot /var/www/localhost/htdocs
+
+  # HAProxy and Podman default bridge network
+  # https://docs.podman.io/en/stable/markdown/podman-network.1.html
+  RemoteIPHeader        X-Real-Ip
+  RemoteIPTrustedProxy  127.0.0.1/32
+  RemoteIPInternalProxy 10.0.0.0/24
+  RemoteIPInternalProxy 10.0.0.1
+  RemoteIPInternalProxy 10.88.0.1
+
+  <Directory /var/www/localhost/htdocs>
+      Order allow,deny
+      Allow from all
+      Require all granted
+  </Directory>
 </VirtualHost>