From: Christoph Liebender Subject: Re: www/anubis: add unveil(2) restrictions To: Omar Polo Cc: ports@openbsd.org Date: Tue, 20 May 2025 19:27:16 +0200 Am 19.05.25 um 19:48 schrieb Omar Polo: > Usually we try to keep these kind of changes local to the ports tree > because upstream may not care and then it could break easily. However, > in golang this is a bit weird to do. So, you already have Unveil in > golang.org/x/sys, which is a "indirect" dependency of anubis, but > relying on it could break if future release stops depending on it. On > the other hand, i don't think we have a way to add a dependency to an > existing go project for the build. www/anubis builds from a vendored tarball anyway so manually adding a go module would probably complicate the Makefile even more. Getting go.port.mk to build with this vendored tarball was already complicated enough, imho. > second thing, the usage pattern of unveil is thought to be along the > lines of > > if (unveil(path, perm) == -1) > err(1, "unveil"); > > and your unveil binding is lacking the error checking. I think you > should bubble up the errors returned by unveil(2) and call log.Fatal if > they fail, as upstream already does for other failing points. Yes, it makes sense to be pedantic about unveil calls failing. After all, it indicates misconfiguration to the user early on when starting the daemon. I've attached an updated diff. - Christoph diff --git a/www/anubis/Makefile b/www/anubis/Makefile index 8e352641089..0f2d0beac90 100644 --- a/www/anubis/Makefile +++ b/www/anubis/Makefile @@ -3,6 +3,7 @@ COMMENT= proof-of-work proxy to protect web resources from scrapers V= 1.18.0 DISTNAME= anubis-src-vendor-npm-$V PKGNAME= anubis-$V +REVISION= 0 CATEGORIES= www diff --git a/www/anubis/patches/patch-cmd_anubis_main_go b/www/anubis/patches/patch-cmd_anubis_main_go new file mode 100644 index 00000000000..e3950b97778 --- /dev/null +++ b/www/anubis/patches/patch-cmd_anubis_main_go @@ -0,0 +1,68 @@ +Index: cmd/anubis/main.go +--- cmd/anubis/main.go.orig ++++ cmd/anubis/main.go +@@ -37,6 +37,31 @@ import ( + "github.com/prometheus/client_golang/prometheus/promhttp" + ) + ++// #include ++// #include ++import "C" ++import "unsafe" ++ ++func unveil(path string, permissions string) { ++ if path == "" && permissions == "" { ++ ret, err := C.unveil(nil, nil) ++ if ret == -1 { ++ log.Fatalf("unveil(NULL, NULL) failed: %s", err) ++ } ++ return ++ } ++ ++ cpath := C.CString(path) ++ cpermissions := C.CString(permissions) ++ defer C.free(unsafe.Pointer(cpath)) ++ defer C.free(unsafe.Pointer(cpermissions)) ++ ++ ret, err := C.unveil(cpath, cpermissions) ++ if ret == -1 { ++ log.Fatalf("unveil(%s, %s) failed: %s", path, permissions, err) ++ } ++} ++ + var ( + basePrefix = flag.String("base-prefix", "", "base prefix (root URL) the application is served under e.g. /myapp") + bind = flag.String("bind", ":8923", "network address to bind HTTP to") +@@ -335,6 +360,32 @@ func main() { + log.Printf("cannot shut down: %v", err) + } + }() ++ ++ bindUnix := *bindNetwork == "unix" ++ metricsBindUnix := *metricsBindNetwork == "unix" ++ targetUnix := strings.HasPrefix(*target, "unix://") ++ targetIP := net.ParseIP(*target) != nil ++ if bindUnix { ++ unveil(*bind, "c") ++ } ++ if metricsBindUnix { ++ unveil(*metricsBind, "c") ++ } ++ if targetUnix { ++ unveil(strings.TrimPrefix(*target, "unix://"), "rw") ++ } ++ if !targetUnix && !targetIP { ++ rpaths := []string{ ++ "/etc/resolv.conf", ++ "/etc/hosts", ++ "/etc/ssl/openssl.cnf", ++ "/etc/ssl/cert.pem", ++ } ++ for _, rpath := range rpaths { ++ unveil(rpath, "r") ++ } ++ } ++ unveil("", "") + + if err := srv.Serve(listener); !errors.Is(err, http.ErrServerClosed) { + log.Fatal(err)