about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArun Isaac2026-08-03 00:12:01 +0100
committerArun Isaac2026-08-03 16:39:34 +0100
commit1428dba0716232aa593ed73b702322d0b591d1d2 (patch)
treec6141fa7b26ecdef3e6d5d622ea38a772e05d181
parentfef1b61f25707c8da5e77d46ff8e5fc146e7d3b0 (diff)
downloadguix-forge-1428dba0716232aa593ed73b702322d0b591d1d2.tar.gz
guix-forge-1428dba0716232aa593ed73b702322d0b591d1d2.tar.lz
guix-forge-1428dba0716232aa593ed73b702322d0b591d1d2.zip
anubis: Add an Anubis service.
-rw-r--r--doc/forge.skb15
-rw-r--r--guix/forge/anubis.scm65
2 files changed, 78 insertions, 2 deletions
diff --git a/doc/forge.skb b/doc/forge.skb
index c628fde..986b7d7 100644
--- a/doc/forge.skb
+++ b/doc/forge.skb
@@ -593,7 +593,20 @@ environment])
            (record-field "mappings"
              [List of ,(code [<file-system-mapping>]) objects describing
 additional directories that should be shared with the container
-gunicorn is run in]))))))
+gunicorn is run in])))))
+    (section :title [Anubis AI firewall service]
+             :ident "section-anubis-ai-firewall-service"
+      (p [Anubis is a web AI firewall utility that uses a combination of
+heuristics and challenges to identify and block bots before they take your
+website down. Anubis is as lightweight as possible and is designed to help
+protect the small internet from the endless storm of requests that flood in from
+AI companies. This service runs Anubis in ,(ref :url
+"https://anubis.techaro.lol/docs/admin/configuration/subrequest-auth/" :text
+"subrequest authentication mode").])
+      (description
+       (record-documentation "guix/forge/anubis.scm" '<anubis-configuration>
+         (record-field "package"
+           [,(code [anubis]) package to use])))))
   (chapter :title [Reference]
            :ident "chapter-reference"
     (description
diff --git a/guix/forge/anubis.scm b/guix/forge/anubis.scm
index 5f79f37..63f7a54 100644
--- a/guix/forge/anubis.scm
+++ b/guix/forge/anubis.scm
@@ -20,11 +20,22 @@
 
 (define-module (forge anubis)
   #:use-module ((gnu packages golang) #:select (go-1.26))
+  #:use-module (gnu services)
+  #:use-module (gnu services shepherd)
+  #:use-module (gnu system file-systems)
   #:use-module (guix build-system gnu)
   #:use-module (guix download)
   #:use-module (guix gexp)
+  #:use-module (guix least-authority)
   #:use-module ((guix licenses) #:prefix license:)
-  #:use-module (guix packages))
+  #:use-module (guix packages)
+  #:use-module (guix records)
+  #:use-module (ice-9 match)
+  #:export (anubis-configuration
+            anubis-configuration?
+            anubis-configuration-package
+            anubis-service-type
+            %anubis-unix-socket))
 
 ;; TODO: Unbundle vendored node and go dependencies. See work in progress at
 ;; https://codeberg.org/guix/guix/pulls/2572
@@ -77,3 +88,55 @@ and challenges to identify and block bots before they take your website down.
 Anubis is as lightweight as possible and is designed to help protect the small
 internet from the endless storm of requests that flood in from AI companies.")
     (license license:expat)))
+
+(define-record-type* <anubis-configuration>
+  anubis-configuration make-anubis-configuration
+  anubis-configuration?
+  (package anubis-configuration-package
+           (default anubis-ai-firewall)))
+
+;; TODO: Do not hard-code.
+(define %anubis-unix-socket
+  "/var/run/anubis/socket")
+
+(define (anubis-activation config)
+  #~(begin
+      (let ((user (getpw "nginx")))
+        (mkdir-p (dirname #$%anubis-unix-socket))
+        (chown (dirname #$%anubis-unix-socket)
+               (passwd:uid user)
+               (passwd:gid user)))))
+
+(define anubis-shepherd-service
+  (match-lambda
+    (($ <anubis-configuration> package)
+     (shepherd-service
+       (documentation "Run the Anubis AI firewall.")
+       (provision '(anubis))
+       (requirement '(networking))
+       (start #~(make-forkexec-constructor
+                 (list #$(least-authority-wrapper
+                          (file-append package "/bin/anubis")
+                          #:name "anubis-pola-wrapper"
+                          #:mappings (list (file-system-mapping
+                                             (source (dirname %anubis-unix-socket))
+                                             (target source)
+                                             (writable? #t))))
+                       "-bind" #$%anubis-unix-socket
+                       "-bind-network" "unix"
+                       "-target" " ")
+                 #:user "nginx"
+                 #:group "nginx"
+                 #:log-file "/var/log/anubis.log"))
+       (stop #~(make-kill-destructor))))))
+
+(define anubis-service-type
+  (service-type
+   (name 'anubis)
+   (description "Run the Anubis AI firewall.")
+   (extensions
+    (list (service-extension activation-service-type
+                             anubis-activation)
+          (service-extension shepherd-root-service-type
+                             (compose list anubis-shepherd-service))))
+   (default-value (anubis-configuration))))