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:
39
debian/README.md
vendored
39
debian/README.md
vendored
@@ -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
20
debian/postinst
vendored
@@ -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
|
||||||
|
|||||||
3
debian/sensorpajen.service
vendored
3
debian/sensorpajen.service
vendored
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user