about summary refs log tree commit diff
path: root/guix/forge/anubis.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix/forge/anubis.scm')
-rw-r--r--guix/forge/anubis.scm142
1 files changed, 142 insertions, 0 deletions
diff --git a/guix/forge/anubis.scm b/guix/forge/anubis.scm
new file mode 100644
index 0000000..63f7a54
--- /dev/null
+++ b/guix/forge/anubis.scm
@@ -0,0 +1,142 @@
+;;; guix-forge --- Guix software forge meta-service
+;;; Copyright © 2026 Ashish Shukla <ashish.is@lostca.se>
+;;; Copyright © 2026 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; This file is part of guix-forge.
+;;;
+;;; guix-forge is free software: you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published
+;;; by the Free Software Foundation, either version 3 of the License,
+;;; or (at your option) any later version.
+;;;
+;;; guix-forge is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;;; General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with guix-forge.  If not, see
+;;; <https://www.gnu.org/licenses/>.
+
+(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 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
+;; This package is based on https://codeberg.org/group/guix-modules/src/commit/137fe9d6dcdad1582c64a70c6f8a052c9251a590/guix/abbe/packages/golang.scm#L902
+(define-public anubis-ai-firewall
+  (package
+    (name "anubis-ai-firewall")
+    (version "1.26.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "https://github.com/TecharoHQ/anubis/releases/download/v"
+                           version "/anubis-src-vendor-npm-" version ".tar.gz"))
+       (sha256
+        (base32 "1yab3z58vgi16313wmx7g32xk6nv158lqic54qds43l63y6lmf92"))))
+    (build-system gnu-build-system)
+    (arguments
+     (list #:phases
+           #~(modify-phases %standard-phases
+               (delete 'configure)
+               (add-after 'unpack 'patch-Makefile
+                 (lambda _
+                   (substitute* "Makefile"
+                     (("\\(GO\\) build" all)
+                      (string-append all " -trimpath")))))
+               (replace 'build
+                 (lambda _
+                   (let ((tmpdir "/tmp"))
+                     (setenv "TMPDIR" tmpdir)
+                     (setenv "GOPATH" (string-append tmpdir "/go"))
+                     (setenv "GOCACHE" (string-append tmpdir "/go-cache"))
+                     (invoke "make" "prebaked-build"))))
+               (replace 'check
+                 (lambda* (#:key tests? #:allow-other-keys)
+                   (when tests?
+                     (invoke "go" "test" "./..."
+                             ;; This test requires network access.
+                             "-skip" "TestLookup"))))
+               (replace 'install
+                 (lambda _
+                   (install-file "var/anubis"
+                                 (string-append #$output "/bin")))))))
+    (native-inputs
+     (list go-1.26))
+    (home-page "https://anubis.techaro.lol/")
+    (synopsis "Identify and block HTTP requests from AI bots")
+    (description
+     "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.")
+    (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))))