From 5114488ad291fe322d2ae9f27c60bb475006629f Mon Sep 17 00:00:00 2001 From: naprelsky85 Date: Mon, 31 Aug 2026 11:04:54 +0300 Subject: [PATCH 1/2] Set the profiles file mode explicitly in the credential permissions test. os.WriteFile applies the process umask, so under a strict umask the 0444 profiles file lands as 0400. The group and other bits that the second Load call is supposed to reject are then never set, Load succeeds, and the test fails on its own negative assertion: --- FAIL: TestLoadAcceptsSystemdCredentialReadPermissions config_test.go:248: group/other-readable profiles file outside a credential directory was accepted This is reachable from a normal installation: deploy/install.sh sets umask 077 on its first line and later runs go test ./..., so a fresh install aborts before building the relay. Chmod the file after writing it, so the test asserts what it means regardless of the caller's umask. Co-Authored-By: Claude Opus 5 --- internal/config/config_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/config/config_test.go b/internal/config/config_test.go index d977312..f61be21 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -234,6 +234,14 @@ func TestLoadAcceptsSystemdCredentialReadPermissions(t *testing.T) { if err := os.WriteFile(profiles, []byte(content), 0444); err != nil { t.Fatal(err) } + // os.WriteFile applies the process umask. Under a strict umask, and + // deploy/install.sh sets 0077 before running the suite, the file lands as + // 0400, so the group/other bits the second Load call must reject are never + // set and the negative assertion below fails. Set the mode explicitly so + // the test states what it means regardless of the caller's umask. + if err := os.Chmod(profiles, 0444); err != nil { + t.Fatal(err) + } t.Setenv("CREDENTIALS_DIRECTORY", credentials) server := `{"public_hostname":"proxy.example.com","public_dir":"public","profiles_file":"credentials/profiles.json"}` path := filepath.Join(directory, "config.json") From 69b9ef649a6aba560e940a8d49a5962565475fd4 Mon Sep 17 00:00:00 2001 From: naprelsky85 Date: Mon, 31 Aug 2026 11:04:55 +0300 Subject: [PATCH 2/2] Grant the mtproxy user access to the built MTProxy binary. make runs under the umask inherited from deploy/install.sh, which is 077, so it creates objs/ and objs/bin/ as 0700 and the binary as 0700. The subsequent chown -R root:root leaves them owned by root with no group or other bits, and mtproxy.service runs as User=mtproxy. systemd cannot execute the binary and reports status=203/EXEC, mtproxy hits its restart limit, and the relay stays at /readyz 503 "backend unavailable" while install.sh ends with "tproxy-server did not become ready". Set root:mtproxy 0750 on the two directories and the binary, reusing the scheme this installer already applies to /etc/mtproxy. The commands run on every invocation rather than only after a rebuild, because the rebuild guard tests -x as root, which passes on a 0700 binary, so an affected host cannot otherwise be repaired by re-running the installer. Co-Authored-By: Claude Opus 5 --- deploy/install-mtproxy.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/deploy/install-mtproxy.sh b/deploy/install-mtproxy.sh index 141ec08..c69362e 100755 --- a/deploy/install-mtproxy.sh +++ b/deploy/install-mtproxy.sh @@ -48,6 +48,17 @@ if [[ ! -x "$source_directory/objs/bin/mtproto-proxy" ]] || rm -rf "$temporary" fi +# make runs under the installer's umask, and deploy/install.sh sets 0077, so +# objs/, objs/bin/ and the binary end up mode 0700, and the chown above leaves +# them root:root. mtproxy.service runs as User=mtproxy, which can neither +# traverse those directories nor execute the binary: systemd reports +# status=203/EXEC and the relay stays at /readyz 503. Grant the runtime group +# exactly what it needs, reusing the root:mtproxy 0750 scheme this installer +# already applies to /etc/mtproxy. This runs on every invocation, not only +# after a rebuild, so re-running the installer repairs an affected host. +chown root:mtproxy "$source_directory/objs" "$source_directory/objs/bin" "$source_directory/objs/bin/mtproto-proxy" +chmod 0750 "$source_directory/objs" "$source_directory/objs/bin" "$source_directory/objs/bin/mtproto-proxy" + install -d -o root -g mtproxy -m 0750 /etc/mtproxy secret_temp="$(mktemp /etc/mtproxy/proxy-secret.XXXXXX)" config_temp="$(mktemp /etc/mtproxy/proxy-multi.conf.XXXXXX)"