Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions pkg/synapse.service
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,14 @@ Group=root
NoNewPrivileges=false
PrivateTmp=false

# File system access - minimal restrictions for XDP/BPF
# File system access - disabled for XDP/BPF compatibility
# ReadWritePaths/ReadOnlyPaths create mount namespaces that fail if /sys/fs/bpf doesn't exist
ProtectSystem=false
ProtectHome=false
# XDP/BPF requires access to /sys/fs/bpf and network interfaces
ReadWritePaths=/var/log/synapse /var/run /var/lib/synapse /etc/synapse/certs /sys/fs/bpf
ReadOnlyPaths=/sys/class/net /sys/devices /proc/sys/net

# Capabilities (required for XDP/BPF)
AmbientCapabilities=CAP_NET_ADMIN CAP_SYS_ADMIN CAP_BPF CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_ADMIN CAP_SYS_ADMIN CAP_BPF CAP_NET_BIND_SERVICE
# Capabilities (required for XDP/BPF and iptables)
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_ADMIN CAP_BPF CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_ADMIN CAP_BPF CAP_NET_BIND_SERVICE

# Network - must have full network access for XDP
PrivateNetwork=false
Expand Down
15 changes: 13 additions & 2 deletions src/firewall/nftables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,19 @@ table inet {table} {{

if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
log::error!("Failed to initialize nftables: {}", stderr);
return Err(format!("Failed to initialize nftables: {}", stderr).into());

// Check for common error patterns and provide user-friendly messages
if stderr.contains("Operation not supported") {
log::debug!("nftables kernel support not available: {}", stderr);
return Err("nftables kernel support not available (Operation not supported) - this is common in containers or systems without nf_tables kernel module".into());
} else if stderr.contains("Permission denied") {
return Err("nftables permission denied - ensure synapse runs as root with CAP_NET_ADMIN".into());
} else if stderr.contains("No such file or directory") {
return Err("nftables failed - nft command or required files not found".into());
} else {
log::debug!("nftables initialization failed: {}", stderr);
return Err(format!("nftables initialization failed: {}", stderr.lines().next().unwrap_or("unknown error")).into());
}
}

Ok(())
Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ async fn async_main(args: Args, config: Config) -> Result<()> {
if config.network.disable_xdp {
log::warn!("XDP disabled by config, will use nftables fallback");
} else {
// Suppress libbpf output - errors will be handled gracefully with fallback to nftables/iptables
libbpf_rs::set_print(None);

for iface in &iface_names {
let boxed_open: Box<MaybeUninit<libbpf_rs::OpenObject>> = Box::new(MaybeUninit::uninit());
let open_object: &'static mut MaybeUninit<libbpf_rs::OpenObject> = Box::leak(boxed_open);
Expand Down