Skip to content

Releases: renaudallard/sniproxy

sniproxy 0.13.5

Choose a tag to compare

@github-actions github-actions released this 02 Jul 15:52

Fixes and one new option from a deep security audit.
Highlights:

  • New per_ip_ipv6_prefix option (default 64): the per-IP rate limit
    and connection cap now group native IPv6 clients by prefix, so a
    client cannot rotate through its allocation (typically a /64) to
    evade them. IPv4 is unaffected; set the prefix to 128 for the old
    per-address behaviour.

  • The per-IP connection cap now fails closed when its hash chain is
    full, closing a bypass where the count check kept allowing colliding
    addresses that it could no longer track.

  • Smaller robustness fixes: the encrypted logger channel is torn down
    on a partial send instead of desyncing, and backend lists are
    swapped safely on reload. See the ChangeLog for details.

sniproxy 0.13.4

Choose a tag to compare

@github-actions github-actions released this 11 Jun 06:15

Fixes from a deep source, documentation, build and CI audit.
Highlights:

  • Linux seccomp: helper processes restarted at runtime were killed by
    the inherited main filter before they could install their own, so a
    single resolver crash permanently disabled DNS resolution.

  • DNS over TLS: resolver sockets are now non-blocking, so an
    unreachable or stalling DoT server can no longer freeze all DNS
    resolution, failover and shutdown.

  • The privileged binder confines root-created unix sockets to /run
    and /var/run only when actually binding, so unix listeners in
    user-writable directories start again. Unix listeners clean up
    their socket files, stale leftovers are replaced on the next start,
    and reuseport now works for listeners bound through the binder.

  • Configuration handling: the last directive of a file without a
    trailing newline is no longer dropped, duplicate table names and
    undefined table references are rejected at load, a failed reload
    no longer switches the error log, and invalid dot:// nameserver
    entries fail config test instead of crash-looping the resolver
    child.

  • Released tarballs ship the Perl integration tests again, plus many
    smaller logger, pidfile, HTTP/2, idle timer, buffer limit,
    documentation and CI fixes; see the ChangeLog for the full list.

sniproxy 0.13.3

Choose a tag to compare

@github-actions github-actions released this 30 May 12:52

Security and correctness fixes from a multi-pass source audit.
Highlights:

  • Reject "source client" combined with proxy_protocol: the untrusted
    PROXY header must not drive the IP_TRANSPARENT source bind, which
    would otherwise allow source-address spoofing toward backends.

  • IPC channels now derive per-instance keys, so a restarted logger,
    resolver or binder child no longer reuses the previous instance's
    ChaCha20-Poly1305 (key, nonce) keystream.

  • UDP/DTLS resolution now honors the global and per-client DNS query
    limits, and UDP sessions are matched per receiving listener.

  • Numerous resolver, sandbox (seccomp/pledge) and file-descriptor
    hardening fixes; see the ChangeLog for the full list.

sniproxy 0.13.2

Choose a tag to compare

@github-actions github-actions released this 22 May 08:59

OpenBSD fixes:

  • Initialize the IPC master key in the parent before forking the
    logger and binder children. The children pledged before calling
    ipc_crypto_channel_init(), and the first call would try to mlock
    the master key, which is not covered by any pledge promise and
    aborts the child. Pre-initializing in the parent lets the
    children inherit the locked state and avoid the mlock path.

sniproxy 0.13.1

Choose a tag to compare

@github-actions github-actions released this 04 May 07:06

Build fixes for 0.13.0:

  • Include libgen.h unconditionally so dirname() and basename() are
    declared on FreeBSD. The 0.13.0 Capsicum pidfile-cleanup code
    guarded the include behind #ifdef OpenBSD, breaking the
    FreeBSD build.

  • Require seccomp.h to be present before defining HAVE_SECCOMP. On
    distros where libseccomp ships its header in a separate package
    (notably SUSE BCI), 0.13.0 detected the library, defined
    HAVE_SECCOMP, then failed to compile seccomp.c when the header
    was missing.

  • Tests / CI:

    • Add a logger_post_fork_child_disinherit stub to
      resolver_response_fuzz; without it the harness fails to link
      after the 0.13.0 disinherit hook in resolv.c.
    • The continuous-fuzzing workflow only files an issue when
      actual crash/leak/timeout artifacts exist, so build failures
      no longer auto-file false-positive 'fuzzer crash' issues.

No source changes affect the daemon's runtime behavior.

sniproxy 0.13.0

Choose a tag to compare

@github-actions github-actions released this 03 May 18:40

Security:

  • TLS parser: reject renegotiation_info even when the SNI extension
    appears earlier in the ClientHello extension list. The parser used
    to return immediately on SNI, bypassing the renegotiation rejection
    check. A client could place a non-empty renegotiated_connection
    alongside SNI and get the connection routed instead of rejected.

  • TLS parser: reject empty SNI server_name list (RFC 6066 section 3)
    and validate the inner length matches the remaining bytes.

  • PROXY protocol v2: reject unknown command values (only LOCAL and
    PROXY are defined by the spec).

  • IPC channel: close orphan fds in SCM_RIGHTS ancillary data so a
    malformed peer cannot exhaust the receiver's fd table. Validate
    cmsg_len before extracting fd, check MSG_CTRUNC on the prefix
    recvmsg, wipe partial ciphertext on seal failure.

Reliability:

  • Logger: stop the binder and resolver children from SIGKILLing the
    parent's logger child via inherited IPC state. The resolver child's
    first notice() at startup triggered this on every launch when file
    or syslog logging was configured.

  • Logger: do not SIGKILL the logger PID on waitpid ECHILD - the PID
    may have been recycled to an unrelated process.

  • HTTP/2: return -1 (incomplete, wait for more data) instead of -2
    (no host) when the buffer ends mid-request, so clients that split
    preface, SETTINGS and HEADERS across TCP segments are not aborted.

  • Configuration tokenizer: reject embedded NUL bytes (raw or via
    backslash escape) so tokens cannot silently truncate.

FreeBSD / Capsicum:

  • Connect to syslog at openlog() time with LOG_NDELAY so the syslog
    socket is open before cap_enter() forbids path-based connect.

  • Pre-open the pidfile parent directory; remove on shutdown via
    unlinkat. Register cleanup via atexit so fatal() also removes it.

  • Use unlinkat for connection-dump cleanup paths.

  • Limit cap_rights on parent-side IPC sockets.

  • Warn (rather than silently drop) when the logger child cannot
    open a new file sink in capability mode.

OpenBSD:

  • Keep cpath in the post-tightening pledge so the pidfile can be
    removed at exit. Otherwise the daemon SIGABRTed on every shutdown.

Configuration:

  • dot://ADDRESS/SNI/tls1.2|tls1.3 syntax now parses correctly
    (previously the documented third URI segment was rejected by the
    parent before reaching the resolver child).

Packaging:

  • Add libseccomp build dependency to debian/control,
    redhat/sniproxy.spec, alpine/APKBUILD, and the matching install
    lines in release-packages.yml. Without this, every Linux package
    release was being built without the seccomp sandbox.

  • Detect libssl in configure instead of hardcoding -lssl.

  • Actually clear hardening flags when sanitizers are enabled
    (the conflict-resolution branch had no effect).

  • Point package metadata at the renaudallard fork.

Tests / CI:

  • Tighten resolv_test, ipc_crypto_debug_test and tls_test
    assertions so silent regressions are caught. The lenient tls_test
    assertion is what previously masked the renegotiation_info bypass.

  • Wire ipc_crypto_debug_test, ipc_crypto_rekey_test, and
    ipc_crypto_time_rekey_test into TESTS / check_PROGRAMS.

  • Cover dtls and ipc_crypto tests in the valgrind workflow.

  • Fix functional_test connection-dump file lookup, xmpp_test
    off-by-one length, config_test TMPDIR honoring.

  • Remove broken orphan test files.

Other:

  • Rate limit buckets now track is_v4 to mirror ConnCountBucket and
    avoid v4/v6 cross-match on hash collision.

  • Skip destructive sink swap when REOPEN produced no new file.

  • Avoid double ev_timer_again in UDP validating fast-path.

  • Use _exit in manual daemonize fork-and-exit fallback.

  • Forward-declare struct Logger in listener.h.

  • Parenthesize IS_TEMPORARY_SOCKERR macro argument.

sniproxy 0.12.0

Choose a tag to compare

@github-actions github-actions released this 20 Mar 12:14
  • FreeBSD Capsicum sandboxing: mainloop, resolver, and logger processes
    enter capability mode after initialization. IPC sockets are restricted
    to minimum required rights. Config reload and log rotation use
    pre-opened directory fds with openat(). Binder is excluded (needs VFS
    for bind). Set SNIPROXY_DISABLE_CAPSICUM=1 to disable.

  • FreeBSD rc.d startup script (scripts/sniproxy.rc) for service
    management via rc.subr.

  • Build system fix: AC_CANONICAL_HOST was missing, so seccomp (Linux)
    and Capsicum (FreeBSD) were never detected. Also link libm for
    isfinite() on FreeBSD.

  • FreeBSD package added to release workflow.

sniproxy 0.11.1

Choose a tag to compare

@github-actions github-actions released this 17 Mar 10:47
  • Bugfix: Fix IPV6_V6ONLY not effective when binding privileged ports
    via binder child process. On Linux, setsockopt(IPV6_V6ONLY) after
    bind() is rejected with EINVAL, so the option must be set before
    bind(). The ipv6_v6only flag is now passed to the binder child which
    sets it before calling bind().

sniproxy 0.11.0

Choose a tag to compare

@github-actions github-actions released this 16 Mar 18:21
  • Feature: Add DTLS (TLS over UDP) protocol support. Proxies DTLS
    connections by extracting the SNI extension from the DTLS ClientHello
    datagram, enabling hostname-based routing for WebRTC, OpenConnect VPN,
    CoAP, and other UDP/DTLS protocols without decrypting traffic.
    Configure with protocol dtls in listener blocks.
  • Security: Add DTLS source validation to prevent UDP reflection and
    amplification attacks. New UDP sessions require a retransmission
    from the client before the backend is contacted. Spoofed sources
    never retransmit and are silently dropped after 3 seconds. This
    eliminates ~10-20x amplification via backend ServerHello responses.
  • Security: Add per-IP rate limiting and connection counting to UDP
    sessions, matching the TCP path. Previously an attacker from a single
    IP could exhaust all UDP sessions and file descriptors.
  • Security: Tighten seccomp filter for the logger child process,
    restricting it to syslog and IPC-only network syscalls instead of the
    full network set.
  • Security: Disable TLS session tickets for DNS-over-TLS connections
    to preserve forward secrecy.
  • Security: Add missing sendfd and recvfd pledge promises on
    OpenBSD for binder fd passing during SIGHUP reload. The sendfd
    promise must also be in the parent's pledge set so the binder child
    can inherit it after fork.
  • Security: Cap UDP pending datagram size to 4KB to limit memory when
    many sessions are in RESOLVING state simultaneously.
  • Hardening: Detect explicit_bzero in configure so secure_memzero uses
    the compiler-safe variant instead of the volatile pointer loop
    fallback.
  • Hardening: Wipe IPC send buffer before free to prevent ciphertext
    lingering in freed memory.
  • Hardening: Set SOCK_CLOEXEC on DoT sockets in resolver child.
  • Hardening: Add bounds check on Huffman tree int16_t cast.
  • Hardening: Add compiler flags -Wshadow, -Wimplicit-fallthrough,
    -Wnull-dereference, -Wundef, -fno-delete-null-pointer-checks.
  • Hardening: Harden systemd service with ProtectKernelTunables,
    ProtectKernelModules, ProtectKernelLogs, ProtectControlGroups,
    ProtectClock, ProtectHostname, PrivateDevices, RestrictNamespaces,
    RestrictRealtime, RestrictSUIDSGID, MemoryDenyWriteExecute, and
    LockPersonality.
  • Hardening: Use memcpy for IPv6 address hashing in UDP session lookup
    for strict-alignment portability.
  • Fix: Add underflow guard on conn_count_free_count in connection rate
    limiter, matching the existing guard in rate_limit_bucket_acquire.
  • Fix: Check for partial writes in resolver child send, matching the
    parent-side pattern.
  • Fix: Hold resolver_queries_lock across both resolver_attach_query and
    resolver_emit_query in query resubmission, matching the documented
    atomicity invariant.
  • Fix: Exit resolver child on ev_loop_new failure instead of falling
    back to the parent's event loop.
  • Fix: Check sock->failed early in DoT read/write callbacks to avoid
    calling SSL on known-broken connections.
  • Fix: Warn when reuseport or ipv6_v6only changes on SIGHUP reload
    since these socket options cannot be changed on a live bound socket.
  • Fix: Warn when resolver config changes on SIGHUP reload since the
    resolver child is not restarted.
  • Fix: Annotate intentional switch fallthroughs for clang
    -Wimplicit-fallthrough compatibility.

sniproxy 0.10.0

Choose a tag to compare

@github-actions github-actions released this 15 Mar 08:56
  • Feature: Add per_ip_max_connections global directive to limit the
    number of simultaneously active connections from a single source IP.
    Prevents a single client from exhausting all connection slots. The
    default is 0 (disabled). Distinct from per_ip_connection_rate which
    limits the rate of new connections.
  • Feature: Add tcp_fastopen on global directive to enable TCP Fast Open
    on listener sockets (server side, Linux/FreeBSD) and backend connect
    sockets (client side, Linux 4.11+). Reduces connection latency for
    clients and backends that support TFO.
  • Feature: Add backend_acl global directive to restrict which backend
    addresses sniproxy may connect to after DNS resolution. Supports
    allow_except and deny_except policies with CIDR ranges, preventing
    abuse as an open proxy to reach internal hosts.
  • Feature: Randomly select from multiple DNS results when resolving
    backend hostnames, distributing connections across DNS round-robin
    backends instead of always using the first record.
  • Feature: Add backend_affinity on table directive for session
    persistence. When DNS returns multiple records for a backend, the
    client IP is hashed to consistently select the same backend.
  • Feature: Auto-anchor literal hostname patterns in table entries.
    Bare hostnames like example.com are now compiled as ^example\.com$
    so they match exactly, not as substrings of other hostnames. Patterns
    containing regex metacharacters are left as-is.
  • Feature: Accept incoming PROXY protocol headers (v1 text and v2 binary
    auto-detected) on listeners via proxy_protocol on directive.
  • Feature: Add PROXY protocol v2 (binary) output support for table backends
    and fallback addresses via proxy_protocol_v2 keyword.
  • Feature: Add Minecraft Java Edition protocol support for routing
    Minecraft connections by hostname without decrypting traffic.
  • Feature: Add SIGCHLD handler to reap zombie child processes.
  • Doc: Document HTTP/2 connection coalescing limitation and workarounds.
  • Security: Fix broken binary search and missing host header detection
    in HPACK decoder. The static name index was sorted incorrectly for the
    binary search comparator, and literal Host headers were only detected
    by pointer comparison instead of string comparison.
  • Security: Add missing recvfd pledge promise in logger child on
    OpenBSD. Without this, the kernel kills the logger child with SIGABRT
    when it receives file descriptors via SCM_RIGHTS.
  • Security: Fix use-after-free in resolve_server_address on synchronous
    DNS failure.
  • Security: Fix per-IP conn_count mismatch when PROXY protocol is used
    (connections were counted under the proxy address, not the real client).
  • Fix: Enforce RFC 7541 dynamic table size update limits in HPACK decoder.
  • Fix: Restart logger child on health check failure instead of fatal exit.
  • Fix: Use non-blocking poll in logger health check to avoid stalling the
    event loop for up to 100ms every 30 seconds.
  • Fix: Close unexpected file descriptors in logger child NEW_SINK handler.
  • Fix: Handle ECHILD when killing logger child after daemonize.
  • Fix: Fix stderr log messages silently lost when routed via logger child.
  • Fix: Resolve relative config path before daemonize so SIGHUP reload
    works after chdir("/").
  • Fix: Check pidfile write for errors.
  • Fix: Fix -T 1.3 rejecting all TLS connections (legacy_version check
    blocked before supported_versions extension was examined).
  • Fix: Fix fallback address losing port number on SIGHUP reload.
  • Fix: Reject stray closing brace at config top level.
  • Fix: Fix EAGAIN on logger IPC permanently killing logger child.
  • Fix: Fix server buffer growing 4x instead of intended 2x on resize.
  • Fix: Fix IPC crypto context leak in resolver init on socketpair/fork
    failure.
  • Fix: Preserve errno across accept cleanup so EMFILE backoff triggers.
  • Fix: Fix resolver IPC max payload length to include header.
  • Fix: Use TOCTOU-safe directory validation for /var/run/sniproxy.
  • Fix: Wipe all derived keys on IPC channel init failure.
  • Fix: Fix resource leak on strdup failure in DoT server registration.
  • Fix: Add overflow check to iovec total length in DoT send path.
  • Fix: Snapshot protocol at accept time to prevent mismatch during reload.
  • Fix: Fail backend init when literal pattern anchoring malloc fails.
  • Fix: Fix ensure_logger_process return value after resend failure.
  • Fix: Chown log files before dropping privileges so SIGHUP log rotation
    works.
  • Fix: Emit PROXY TCP4 instead of TCP6 for IPv4-mapped IPv6 addresses.
  • Hardening: Use reallocarray() for overflow-safe allocation throughout.
  • Hardening: Replace assert() with proper runtime error handling.
  • Hardening: Check setsockopt, fcntl, and inet_ntop return values.
  • Hardening: Add closefrom to AC_CHECK_FUNCS for efficient fd cleanup.
  • Build: Add missing OpenSSL and libbsd build dependencies.
  • Build: Clean up unused functions, dead code, and redundant includes.