Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b86b235
added port drop to ebpf file
Gepsonka Nov 27, 2025
3aa29d7
added port drop to product
Gepsonka Nov 28, 2025
9db666f
Merge branch 'main' into port-ban-feature
pigri Dec 1, 2025
cdad86e
added inbound and outbound port ban
Gepsonka Dec 3, 2025
1aae191
dev container fix, rate limiting
Gepsonka Dec 12, 2025
617015e
Merge branch 'main' into port-ban-feature
Gepsonka Jan 14, 2026
46fdcc0
fixed ebpf structure
Gepsonka Jan 14, 2026
ef9dc6b
merge structural fix from port ban
Gepsonka Jan 14, 2026
1eff93e
adjusted structure
Gepsonka Jan 14, 2026
eec6f71
fixing pipeline...
Gepsonka Jan 16, 2026
3aeb418
fixed pipeline
Gepsonka Jan 16, 2026
9cac3b8
refactoring xdp code for maintainabhlilty and extendability
Gepsonka Jan 19, 2026
852d942
tail calls
Gepsonka Jan 23, 2026
6e2a29b
refactored ebpf, finished syn rate limiter
Gepsonka Jan 23, 2026
2abb226
refactor: reorganize project structure and enhance logging capabilities
pigri Jan 25, 2026
f572329
feat: add timeout configurations for upstream connections and enhance…
pigri Jan 25, 2026
ecf8128
refactor: update header management in proxy configuration to support …
pigri Jan 25, 2026
4dc67a6
feat: implement weighted load balancing using Pingora's algorithm
pigri Jan 25, 2026
7bab4d9
feat: enhance logging system with bounded channel support and metrics…
pigri Jan 25, 2026
70ce562
refactor: implement PeriodicTask trait for improved periodic worker m…
pigri Jan 25, 2026
07bb3c2
Merge remote-tracking branch 'origin/refactor_v2' into rate-limiting-…
Gepsonka Jan 26, 2026
7629083
progress snapshot
Gepsonka Jan 27, 2026
add05ba
added xdp ratelimiter to config file code and dashboard access rules …
Gepsonka Jan 28, 2026
7fb821a
remider todo
Gepsonka Jan 28, 2026
0db0305
fixed verifier issues, added mutex around XdpSkel, fixed config defau…
Gepsonka Jan 29, 2026
fdaf4de
merge refactor branch
Gepsonka Feb 2, 2026
32e6175
merged rebase branch, applied fixes
Gepsonka Feb 2, 2026
9d1f852
xdp ratelimiter config fetch
Gepsonka Feb 3, 2026
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
1 change: 1 addition & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
sudo \
clangd-12 \
&& rm -rf /var/lib/apt/lists/*

# Build bpftool from source
Expand Down
25 changes: 25 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/src/bpf/include",
"${workspaceFolder}/src/bpf/lib",
"/usr/include",
"/usr/include/x86_64-linux-gnu",
"/usr/include/bpf",
"/usr/local/include/bpf"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++14",
"intelliSenseMode": "linux-clang-x64",
"compilerArgs": [
"-Wno-int-conversion"
]
}
],
"version": 4
}
8 changes: 3 additions & 5 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
{
// Point rust-analyzer at the actual crate(s) in this workspace
"rust-analyzer.linkedProjects": [
"synapse/Cargo.toml"
"Cargo.toml"
],
// Enable all features if your crate uses optional features
"rust-analyzer.cargo.allFeatures": true,
// Run clippy on save for quick lint feedback (optional)
"rust-analyzer.checkOnSave.command": "clippy",
"rust-analyzer.checkOnSave": true,
// Use the local toolchain when available
"rust-analyzer.rustc.source": "discover"
}
}
63 changes: 45 additions & 18 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,21 @@ homepage = "https://gen0sec.com"
repository = "https://github.com/gen0sec/synapse"
version = "0.4.2"
edition = "2024"
keywords = ["bpf", "firewall", "reverse-proxy", "tls", "proxy", "proxy-protocol", "content-scanning", "threat-intelligence", "captcha", "hcaptcha", "recaptcha", "cloudflare-turnstile", "runtime"]
keywords = [
"bpf",
"firewall",
"reverse-proxy",
"tls",
"proxy",
"proxy-protocol",
"content-scanning",
"threat-intelligence",
"captcha",
"hcaptcha",
"recaptcha",
"cloudflare-turnstile",
"runtime",
]
readme = "README.md"

[target.'cfg(unix)'.build-dependencies]
Expand All @@ -25,19 +39,19 @@ tokio = { version = "1", features = [
] }
anyhow = "1"
hyper = { version = "1", features = ["http1", "server"] }
hyper-util = { version = "0.1", features = [
"server",
"tokio",
"http1",
] }
hyper-util = { version = "0.1", features = ["server", "tokio", "http1"] }
http-body-util = "0.1"
plain = "0.2.3"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"
clap = { version = "4.5.54", features = ["derive"] }
nix = { version = "0.31.1", features = ["net", "fs"] }
redis = { version = "1.0", features = ["tokio-native-tls-comp", "connection-manager", "r2d2"]}
nix = { version = "0.31.1", features = ["net", "fs", "resource"] }
redis = { version = "1.0", features = [
"tokio-native-tls-comp",
"connection-manager",
"r2d2",
] }
native-tls = "0.2"
tokio-rustls = "0.26.4"
rustls = { version = "0.23.36", default-features = false, features = [
Expand Down Expand Up @@ -65,15 +79,24 @@ gethostname = "1.1.0"
local-ip-address = "0.6.9"
flate2 = "1.1"
log = "0.4.29"
env_logger = { version = "0.11", default-features = false, features = ["auto-color", "humantime"] }
log4rs = { version = "1.3", features = ["console_appender", "file_appender", "rolling_file_appender", "json_encoder", "gzip"] }
env_logger = { version = "0.11", default-features = false, features = [
"auto-color",
"humantime",
] }
log4rs = { version = "1.3", features = [
"console_appender",
"file_appender",
"rolling_file_appender",
"json_encoder",
"gzip",
] }
syslog = "7.0"
jsonwebtoken = { version = "10.1", features = ["rust_crypto"] }
uuid = { version = "1.20", features = ["v4", "serde"] }
url = "2.5"
clamav-tcp = "0.2"
multer = "3.0"
proxy-protocol = { git = "https://github.com/gen0sec/proxy-protocol", rev = "ac28b27d317088f0e9e89805ada3b9f5cfbf5673"}
proxy-protocol = { git = "https://github.com/gen0sec/proxy-protocol", rev = "ac28b27d317088f0e9e89805ada3b9f5cfbf5673" }
rand = "0.9"
regex = "1.0"
daemonize = "0.5.0"
Expand All @@ -85,13 +108,17 @@ daemonize = "0.5.0"
# pingora-http = { path = "../pingora/pingora-http" }
# pingora-memory-cache = { path = "../pingora/pingora-memory-cache" }

wirefilter-engine = { git = "https://github.com/gen0sec/wirefilter" , rev = "ab901470a24aad789cb9c03dd214d6c7d4cab589" }
pingora = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81", features = ["lb", "openssl", "proxy"] }
pingora-core = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81"}
pingora-proxy = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81"}
pingora-limits = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81"}
pingora-http = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81"}
pingora-memory-cache = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81"}
wirefilter-engine = { git = "https://github.com/gen0sec/wirefilter", rev = "ab901470a24aad789cb9c03dd214d6c7d4cab589" }
pingora = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81", features = [
"lb",
"openssl",
"proxy",
] }
pingora-core = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81" }
pingora-proxy = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81" }
pingora-limits = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81" }
pingora-http = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81" }
pingora-memory-cache = { git = "https://github.com/gen0sec/pingora", rev = "c92146d621542303dd9b93a4cb5252e1eef46c81" }

# JA4+ fingerprinting library
# nstealth = { path = "../nstealth" }
Expand Down
Binary file added bin/act
Binary file not shown.
26 changes: 18 additions & 8 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::path::{Path, PathBuf};
#[cfg(all(unix, feature = "bpf"))]
use libbpf_cargo::SkeletonBuilder;

const SRC: &str = "src/security/firewall/bpf/filter.bpf.c";
const SRC: &str = "src/security/firewall/bpf/xdp.bpf.c";
const HEADER_DIR: &str = "src/security/firewall/bpf";

fn main() {
Expand Down Expand Up @@ -47,25 +47,35 @@ fn main() {
assert!(Path::new(&vmlinux_include).exists(), "vmlinux.h not found");

let bpf_include = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()).join(HEADER_DIR);
let include = bpf_include.join("include");
let lib = bpf_include.join("lib");

// ✅ Construct full output path in OUT_DIR
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let skel_path = out_dir.join("filter.skel.rs");
let skel_path = out_dir.join("xdp.skel.rs");

// ✅ Pass the full path to build_and_generate
SkeletonBuilder::new()
.source(SRC)
.clang_args([
OsStr::new("-I"),
vmlinux_include.as_os_str(),
OsStr::new("-I"),
bpf_include.as_os_str(),
OsStr::new("-O3"), // Max optimizations to reduce program size
OsStr::new("-fno-unroll-loops"), // Reduce instruction count
OsStr::new("-Wall"),
OsStr::new("-Wextra"),
OsStr::new("-DBPF_NO_PRESERVE_ACCESS_INDEX"), // Older clang compat
OsStr::new("-Ubpf"), // Avoid macro collision
OsStr::new("-I"),
include.as_os_str(),
OsStr::new("-I"),
lib.as_os_str(),
OsStr::new("-O3"), // Maximum optimizations to reduce program size
OsStr::new("-fno-unroll-loops"), // Prevent loop unrolling to reduce instruction count
OsStr::new("-Wall"), // Enable all warnings
OsStr::new("-Wextra"), // Extra warnings
OsStr::new("-DBPF_NO_PRESERVE_ACCESS_INDEX"), // Disable preserve_access_index for older clang
OsStr::new("-Ubpf"), // Undefine bpf macro to avoid conflict with struct netns_bpf bpf
])
.build_and_generate(skel_path.to_str().expect("Invalid UTF-8 in path"))
.expect("Failed to generate skeleton");

println!("✅ Wrote skeleton to: {:?}", skel_path);
}
}
108 changes: 60 additions & 48 deletions config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,61 +28,73 @@
# Backward compatibility: AX_ prefix and AX_ARXIGNIS_ prefix are still supported
# but will log deprecation warnings.


# Application operating mode
# - agent: Only access rules and monitoring (no proxy, pingora disabled)
# - proxy: Full reverse proxy functionality (default)
mode: "agent"

# Network Configuration
network:
# The network interface to attach the XDP program to
iface: "eth0"
# The network interface to attach the XDP program to
iface: "eth0"

# Additional network interfaces for XDP attach (overrides iface if set)
ifaces: []

# IP version support mode: "ipv4", "ipv6", or "both" (default: "both")
# Note: XDP requires IPv6 to be enabled at kernel level for attachment,
# even in IPv4-only mode. This is a kernel limitation. When set to "ipv4",
# the system will attempt to enable IPv6 on the interface just for XDP
# attachment (not system-wide), allowing IPv4-only operation elsewhere.
# Options:
# - "ipv4": Process IPv4 packets only (IPv6 still required for XDP attachment)
# - "ipv6": Process IPv6 packets only
# - "both": Process both IPv4 and IPv6 packets (default)
ip_version: "both"
# IP version support mode: "ipv4", "ipv6", or "both" (default: "both")
# Note: XDP requires IPv6 to be enabled at kernel level for attachment,
# even in IPv4-only mode. This is a kernel limitation. When set to "ipv4",
# the system will attempt to enable IPv6 on the interface just for XDP
# attachment (not system-wide), allowing IPv4-only operation elsewhere.
# Options:
# - "ipv4": Process IPv4 packets only (IPv6 still required for XDP attachment)
# - "ipv6": Process IPv6 packets only
# - "both": Process both IPv4 and IPv6 packets (default)
ip_version: "both"

# Firewall Configuration
firewall:
# Firewall backend mode: auto, xdp, nftables, iptables, none
# - auto: Automatically select best available (XDP > nftables > iptables > none)
# - xdp: Force XDP/BPF backend (highest performance, requires kernel support)
# - nftables: Force nftables backend (requires nft command and kernel support)
# - iptables: Force iptables backend (legacy, most compatible)
# - none: Disable kernel firewall, userland enforcement only
mode: "auto"

# Disable XDP packet filtering (run without BPF/XDP)
disable_xdp: false
# Firewall backend mode: auto, xdp, nftables, iptables, none
# - auto: Automatically select best available (XDP > nftables > iptables > none)
# - xdp: Force XDP/BPF backend (highest performance, requires kernel support)
# - nftables: Force nftables backend (requires nft command and kernel support)
# - iptables: Force iptables backend (legacy, most compatible)
# - none: Disable kernel firewall, userland enforcement only
mode: "auto"

# Disable XDP packet filtering (run without BPF/XDP)
disable_xdp: false

# XDP Rate Limiter Configuration
ratelimiter:
# Enable XDP rate limiter (0 = disabled, 1 = enabled)
status: 0
# Requests per second per IP
request_per_sec: 1000
# Burst factor (capacity = request_per_sec * burst_factor)
burst_factor: 3.0
# Map size for IPv4 addresses (max unique IPs). Requires restart to change.
ipv4_map_size: 50000
# Map size for IPv6 addresses (max unique IPs). Requires restart to change.
ipv6_map_size: 50000

# Gen0Sec Platform Configuration
# Note: 'arxignis' is also accepted for backward compatibility but deprecated
platform:
# API key for Gen0Sec service
api_key: ""
# API key for Gen0Sec service
api_key: ""

# Base URL for Gen0Sec API
base_url: "https://api.gen0sec.com/v1"
# Base URL for Gen0Sec API
base_url: "https://api.gen0sec.com/v1"

# Enable sending access logs to platform server
log_sending_enabled: true
# Enable sending access logs to platform server
log_sending_enabled: true

# Include response body in access logs
include_response_body: true
# Include response body in access logs
include_response_body: true

# Maximum size for request/response bodies in access logs (bytes) - Don't override in Basic plan that's the maximum allowed by the plan.
max_body_size: 1048576
# Maximum size for request/response bodies in access logs (bytes) - Don't override in Basic plan that's the maximum allowed by the plan.
max_body_size: 1048576

# Threat MMDB Configuration (used by platform threat intelligence)
threat:
Expand All @@ -102,8 +114,8 @@ platform:

# Logging Configuration
logging:
# Log level: error, warn, info, debug, trace
level: "info"
# Log level: error, warn, info, debug, trace
level: "info"

# Enable file-based logging with separate files for errors and access logs
# When enabled, logs will be written to separate files with automatic rotation and gzip compression
Expand Down Expand Up @@ -198,23 +210,23 @@ logging:

# Daemon Configuration
daemon:
# Enable daemon mode (run as background process)
enabled: true
# Enable daemon mode (run as background process)
enabled: true

# PID file path
pid_file: "/var/run/synapse.pid"
# PID file path
pid_file: "/var/run/synapse.pid"

# Working directory for daemon
working_directory: "/var/lib/synapse"

# User to run daemon as (optional, e.g., "nobody")
user: root
# User to run daemon as (optional, e.g., "nobody")
user: root

# Group to run daemon as (optional, e.g., "daemon")
group: root
# Group to run daemon as (optional, e.g., "daemon")
group: root

# Change ownership of PID file to daemon user/group
chown_pid_file: true
# Change ownership of PID file to daemon user/group
chown_pid_file: true

# Proxy Configuration (proxy mode features)
# Note: 'pingora' is also accepted for backward compatibility but deprecated
Expand All @@ -231,9 +243,9 @@ proxy:
# TLS suite grade (high, medium, unsafe)
tls_grade: "medium"

# Default fallback SSL certificate name (file stem without extension, e.g., "default" for default.crt)
# If not specified, the first valid certificate will be used as default
default_certificate: "default"
# Default fallback SSL certificate name (file stem without extension, e.g., "default" for default.crt)
# If not specified, the first valid certificate will be used as default
default_certificate: "default"

# Redis Configuration (for ACME certificate storage)
redis:
Expand Down
Loading