Fix Bluetooth permission error with AmbientCapabilities and enhanced postinst

- Add AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN to systemd service files
- Add sensorpajen user to bluetooth group in postinst
- Improve setcap error handling in postinst with clearer messaging
- Add comprehensive troubleshooting section for Bluetooth permission errors

This fixes the 'Operation not permitted' error when the service tries to
access Bluetooth hardware. The fix uses two layers of protection:
1. systemd AmbientCapabilities (modern, robust)
2. File capabilities via setcap (traditional, wider compatibility)
This commit is contained in:
2026-02-20 08:57:28 +01:00
parent a6029456fa
commit 773453bd51
4 changed files with 58 additions and 22 deletions

39
debian/README.md vendored
View File

@@ -287,16 +287,51 @@ Common issues:
- sensors.json is empty - sensors.json is empty
- Bluetooth adapter not available - Bluetooth adapter not available
### Bluetooth Capability Not Set ### Bluetooth Permission Error: "Operation not permitted"
If the service fails with `PermissionError: [Errno 1] Operation not permitted`:
```bash ```bash
# Manually set capability # Check current capabilities
getcap $(readlink -f /opt/sensorpajen/venv/bin/python3)
# Should show: cap_net_admin,cap_net_raw+eip
```
**Solution 1: Re-apply file capabilities** (Quick fix)
```bash
# Set capabilities on Python executable
sudo setcap cap_net_raw,cap_net_admin+eip $(readlink -f /opt/sensorpajen/venv/bin/python3) sudo setcap cap_net_raw,cap_net_admin+eip $(readlink -f /opt/sensorpajen/venv/bin/python3)
# Verify # Verify
getcap $(readlink -f /opt/sensorpajen/venv/bin/python3) getcap $(readlink -f /opt/sensorpajen/venv/bin/python3)
# Restart service
sudo systemctl restart sensorpajen
``` ```
**Solution 2: Add user to bluetooth group**
```bash
sudo usermod -aG bluetooth sensorpajen
sudo systemctl restart sensorpajen
```
**Solution 3: Verify systemd capabilities**
The service file uses `AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN` as a fallback. Verify it's configured:
```bash
sudo systemctl cat sensorpajen | grep -A2 Capabilities
```
**Why this happens**: File capabilities can be lost when:
- Python is upgraded/reinstalled
- Filesystem is mounted with `nosuid`
- The venv is recreated
The systemd service now uses both `AmbientCapabilities` (modern approach) and file capabilities (setcap) for maximum compatibility.
## Development Workflow ## Development Workflow
### Making Changes ### Making Changes

20
debian/postinst vendored
View File

@@ -9,6 +9,12 @@ case "$1" in
echo "Created system user: sensorpajen" echo "Created system user: sensorpajen"
fi fi
# Add sensorpajen user to bluetooth group if it exists (for BLE access)
if getent group bluetooth > /dev/null; then
usermod -aG bluetooth sensorpajen || true
echo "Added sensorpajen user to bluetooth group"
fi
# Create config directory with proper permissions # Create config directory with proper permissions
mkdir -p /etc/sensorpajen mkdir -p /etc/sensorpajen
chown sensorpajen:sensorpajen /etc/sensorpajen chown sensorpajen:sensorpajen /etc/sensorpajen
@@ -77,14 +83,20 @@ case "$1" in
chown -R sensorpajen:sensorpajen /opt/sensorpajen chown -R sensorpajen:sensorpajen /opt/sensorpajen
# Set Bluetooth capabilities on Python executable (after ownership change) # Set Bluetooth capabilities on Python executable (after ownership change)
# Note: The systemd service also uses AmbientCapabilities as a fallback
PYTHON_PATH=$(readlink -f /opt/sensorpajen/venv/bin/python3) PYTHON_PATH=$(readlink -f /opt/sensorpajen/venv/bin/python3)
if command -v setcap >/dev/null 2>&1; then if command -v setcap >/dev/null 2>&1; then
setcap cap_net_raw,cap_net_admin+eip "$PYTHON_PATH" || { if setcap cap_net_raw,cap_net_admin+eip "$PYTHON_PATH" 2>/dev/null; then
echo "Warning: setcap failed. You may need to run Bluetooth operations as root." echo "Bluetooth capabilities set on $PYTHON_PATH"
echo "Try: sudo setcap cap_net_raw,cap_net_admin+eip $PYTHON_PATH" getcap "$PYTHON_PATH" || true
} else
echo "Warning: setcap failed. Relying on systemd AmbientCapabilities instead."
echo "If Bluetooth access fails, manually run:"
echo " sudo setcap cap_net_raw,cap_net_admin+eip $PYTHON_PATH"
fi
else else
echo "Warning: setcap not found (install libcap2-bin package)" echo "Warning: setcap not found (install libcap2-bin package)"
echo "Relying on systemd AmbientCapabilities for Bluetooth access"
fi fi
# v2 installed a unit into /etc/systemd/system/, which overrides packaged units # v2 installed a unit into /etc/systemd/system/, which overrides packaged units

View File

@@ -14,7 +14,8 @@ ExecStart=/opt/sensorpajen/venv/bin/python -m sensorpajen.main
Restart=always Restart=always
RestartSec=10 RestartSec=10
# Bluetooth capabilities require this to be false # Bluetooth capabilities
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
NoNewPrivileges=false NoNewPrivileges=false
# Logging # Logging

View File

@@ -12,21 +12,9 @@ ExecStart=%h/sensorpajen/.venv/bin/python -m sensorpajen.main
Restart=always Restart=always
RestartSec=10 RestartSec=10
# Bluetooth capabilities (alternative to setcap) # Bluetooth capabilities
# Note: This requires systemd to be run with proper permissions AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
# If this doesn't work, use setcap on the Python binary instead NoNewPrivileges=false
#AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=sensorpajen
# Security
# Note: NoNewPrivileges=true can prevent file capabilities from working
# We need capabilities for Bluetooth access, so we can't use it
#NoNewPrivileges=true
PrivateTmp=true
[Install] [Install]
WantedBy=default.target WantedBy=default.target