Fix MTR failing under systemd: grant CAP_NET_RAW via ambient capabilities
mtr ran fine as the mtr-backend user in a shell but failed under the systemd service with: mtr-packet: Failure to open IPv4 sockets: Permission denied Cause: the unit sets NoNewPrivileges=yes, which strips file capabilities, and AmbientCapabilities/CapabilityBoundingSet were empty — so mtr-packet (the helper that opens the raw ICMP socket) had no CAP_NET_RAW. Interactive runs worked because they had no NoNewPrivileges. - Grant CAP_NET_RAW the systemd-native way (AmbientCapabilities + CapabilityBoundingSet), which survives NoNewPrivileges. Fixed in both the full installer and the patch service unit. - setcap now also targets mtr-packet, not just mtr. - Add proxy_intercept_errors off to the diag /api/mtr location: the server-level "proxy_intercept_errors on" was rewriting a backend 500 into an HTML 404, which broke the frontend's response.json() and left the client IP stuck on "detecting…". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
fb68047c02
commit
906822b42b
+13
-1
@@ -488,6 +488,10 @@ server {
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 120s;
|
||||
proxy_send_timeout 120s;
|
||||
# Let the backend's JSON error bodies through; the server-level
|
||||
# "proxy_intercept_errors on" would otherwise rewrite a 500 into an HTML
|
||||
# 404 and break the frontend's response.json() parse.
|
||||
proxy_intercept_errors off;
|
||||
}
|
||||
location ^~ ${diag_path}api/st/up {
|
||||
if (\$diag_auth = 0) { return 404; }
|
||||
@@ -614,7 +618,9 @@ id mtr-backend &>/dev/null || \
|
||||
useradd --system --no-create-home --shell /usr/sbin/nologin mtr-backend
|
||||
|
||||
if command -v setcap &>/dev/null; then
|
||||
setcap cap_net_raw+ep "$(command -v mtr)" 2>/dev/null || true
|
||||
# mtr-packet is the helper that actually opens the raw socket
|
||||
setcap cap_net_raw+ep "$(command -v mtr)" 2>/dev/null || true
|
||||
setcap cap_net_raw+ep "$(command -v mtr-packet)" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
cat > /etc/systemd/system/mtr-backend.service <<EOF
|
||||
@@ -633,6 +639,12 @@ NoNewPrivileges=yes
|
||||
PrivateTmp=yes
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/tmp
|
||||
# mtr-packet opens raw ICMP sockets. NoNewPrivileges=yes strips the file
|
||||
# capability off the mtr binary, so grant CAP_NET_RAW the systemd-native way
|
||||
# (ambient caps survive NoNewPrivileges). Without this mtr fails with
|
||||
# "Failure to open IPv4 sockets: Permission denied".
|
||||
AmbientCapabilities=CAP_NET_RAW
|
||||
CapabilityBoundingSet=CAP_NET_RAW
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
Reference in New Issue
Block a user