Features

cmnSense manages the parts of Linux that make a firewall, nftables, netlink, FRR, strongSwan, WireGuard, Kea, chrony, IPVS, as one system with one configuration. Everything below is configured from the same file, the CLI and the web interface.

Firewall

ASA-style extended access-lists, one per interface and named after it, applied inbound and evaluated top to bottom. The whole ruleset is compiled to nftables and replaced atomically, so there is never a moment with half a policy loaded.

  • Addresses as hosts, prefixes, object groups or interface shortcuts: lan:network, wan:address, wan:vip and self.
  • Host names in object groups (network-object fqdn), resolved every minute through the configured name servers and enforced as the addresses they resolve to.
  • Permit, deny or reject, where reject answers with a TCP reset or an ICMP error so clients fail fast.
  • Nested network and service object groups with remarks, schedules with time-range, DSCP and ICMP type matching.
  • Per-rule logging, FTP protocol inspection, and a connection table you can browse and flush.
  • Anti-lockout: management-access keeps SSH and HTTPS open on the interface you choose, whatever the rules say.
access-lists
object-group network rfc1918
  network-object 10.0.0.0/8
  network-object 172.16.0.0/12
  network-object 192.168.0.0/16
!
access-list lan extended permit ip lan:network any
access-list wan extended permit tcp any object-group web-servers eq 443
access-list wan extended permit icmp any self
!
management-access lan

NAT

One ordered NAT list with ASA-style (from,to) interface pairs. Each rule translates one address family, so adding IPv6 never silently turns on NAT66.

  • Dynamic source NAT to the interface, the VRRP virtual address, an address or a pool, with port ranges and persistent mappings.
  • Static port forwards, including to an object group with round-robin distribution.
  • Hairpin NAT per forward (hairpin), so hosts on the inside reach a forwarded service through its public address.
  • NAT64 port forwards: a port of an IPv6 address of the firewall forwarded to an IPv4 host, TCP and UDP.
  • NAT exemptions with none, and explicit NAT66 for IPv6 when you really need it.

Routing

Static and policy routing are built in; dynamic routing is FRR, configured in FRR's own syntax inside the cmnSense configuration and checked so that what FRR runs is exactly what the file says.

  • Gateways and gateway groups with tiers, health monitoring and automatic failover.
  • Policy routing to send traffic out of a chosen gateway or group.
  • BGP, OSPF, OSPFv3, IS-IS and BFD, with prefix-lists and route-maps.
  • Firewall permits for the routing protocols are added automatically for the interfaces they run on.
router blocks
router ospf 1
  ospf router-id 10.99.0.1
  network 10.99.0.0/24 area 0
  passive-interface eth2
  redistribute connected
!
router bgp 65000
  bgp router-id 10.99.0.1
  neighbor 10.99.0.2 remote-as internal
  neighbor 10.99.0.2 bfd profile fast

High availability

Two firewalls as an active/standby pair. The standby takes over the virtual addresses when the primary fails and, because the connection table is synchronised, established sessions carry on.

  • VRRP for IPv4 and IPv6 on any interface, with priorities and descriptions.
  • Connection state synchronisation of forwarded flows over a dedicated link.
  • Configuration sync: change the primary and the secondary follows, keeping its own interfaces, addresses and VRRP priorities. DHCP servers on a pair run Kea failover.
  • Maintenance mode to move traffic away before working on a unit, and a drained standby in dynamic routing.
an HA pair
interface eth2
  nameif lan
  ip address 10.10.0.2/24
  vrrp 1 ip 10.10.0.1
  vrrp 1 priority 200
!
redundancy
  interface eth1
  peer 10.99.0.2
  config-sync
A high availability pairTwo cmnSense firewalls share virtual addresses on the WAN and the LAN with VRRP. The primary holds them and forwards traffic. Over a dedicated sync link it sends connection state to the standby and pushes configuration changes. If the primary fails, the standby takes over the virtual addresses and the synchronised connections continue.InternetWAN VIPLAN VIPprimaryVRRP masterholds the virtual addressesforwards trafficstandbyVRRP backupholds the same connectionstakes over on failurestate syncconfig syncdedicated sync linkLANdefault gateway: the VIP

VPN

Site-to-site and remote links over the protocols worth running, each configured the same way as everything else.

  • WireGuard interfaces with named peers, allowed IPs, endpoints and keepalives.
  • Route-based IPsec IKEv2 with strongSwan: a tunnel interface per peer, named proposals and modern ciphers.
  • L2TPv3 pseudowires over IP or UDP, which can be bundled into an LACP port-channel for a resilient layer 2 link.

Interfaces

Physical ports keep their kernel names and get a nameif, the name every rule, NAT entry and service refers to.

  • VLANs, VLAN-aware bridges with access and trunk ports, and LACP port-channels.
  • GRE, GRETAP and VXLAN tunnels, loopbacks, and TCP MSS clamping per interface.
  • Static IPv4 and IPv6 addresses, IPv6 autoconfiguration, DHCP and DHCPv6 clients, and PPPoE for uplinks.
  • Interface names pinned to MAC addresses, so a new NIC never renumbers the others.

The firewall takes its uplink however the provider hands it out, with IPv4 and IPv6 side by side and the internal networks numbered from what the provider delegates.

  • PPPoE for DSL and fibre, IPv4 and IPv6 (IPv6CP), over a port, a VLAN or a port-channel, with a default route, the provider's name servers and TCP MSS clamping set up automatically.
  • DHCP for IPv4, and DHCPv6 for an address and a delegated prefix, alongside router advertisements.
  • Prefix delegation: name the prefix on the uplink, give each internal network an address from it, and router advertisements follow the prefix the provider assigns.
  • pppd runs sandboxed and is only ever started from a validated request: the management server cannot hand it options of its own.
  • Dynamic DNS keeps names pointing at the uplink's address or at a VRRP virtual address: dyndns2 (any compatible service, self-hosted ones too), Cloudflare, or any HTTPS URL. Updates go out over verified TLS from a sandboxed updater, and on an HA pair only the active unit publishes the virtual address.
a PPPoE uplink with a delegated prefix and dynamic DNS
ip ddns update method home
  server ddns.example.com
  username fw
  password "…"
!
interface pppoe0
  nameif wan
  pppoe device eth0
  pppoe username user@provider.example
  pppoe password "…"
  ip address negotiated
  ipv6 address autoconfig
  ipv6 dhcp client pd WAN-PD
  ip ddns update fw.example.com home
!
interface eth1
  nameif lan
  ip address 10.10.0.1/24
  ipv6 address WAN-PD ::1/64
  ipv6 nd ra

Network services

The services a network expects from its firewall, with the firewall permits they need added for you.

  • DHCPv4 and DHCPv6 servers per interface with Kea.
  • A caching DNS resolver for the networks behind the firewall.
  • NTP client and server with chrony, including NTS-authenticated time.
  • IPv6 router advertisements on any interface.

Load balancing

A full layer 4 load balancer built in, running in the kernel with IPVS rather than as a proxy, so it costs almost nothing per connection. Its grammar follows Cisco ACE: real servers, probes, server farms and virtual servers.

  • Server farms scheduled by Maglev hashing, round-robin, least connections or source hash, with per-member weights, connection limits and draining.
  • TCP and HTTP health probes with failure and recovery thresholds; a failing member stops taking new connections while existing ones finish.
  • Virtual servers on any address the firewall owns, VRRP addresses included, with source stickiness and source restrictions. The firewall permits follow automatically.
  • NAT, direct routing or IP-in-IP forwarding.
  • High availability included: the IPVS connection table is synchronised to the standby, so load-balanced sessions survive a failover.
  • show virtual-server and show serverfarm report live member health and connections, and the web interface has a load balancer page of its own.
a load-balanced service
rserver host web1
  ip address 10.10.0.11
!
probe http web-health
  interval 2
  request get /healthz
  expect status 200 299
!
serverfarm host web
  predictor maglev
  probe web-health
  rserver web1 8080 weight 20 max-conns 1000
!
virtual-server www
  virtual wan:vip tcp 443
  serverfarm web
  forward nat
  sticky source 300
How the load balancer worksClients connect to a virtual server on the firewall's virtual address. The kernel's IPVS picks a member of the server farm with Maglev hashing and forwards the connection. Health probes take failing members out of the farm, draining members finish their existing connections, and the IPVS connection table is synchronised to the standby firewall.Clients443virtual-server wwwwan:vip tcp 443sticky source 300serverfarm webpredictor maglevprobe web-healthweb1 :8080up · weight 20web2 :8080inactive · drainingweb3 :8080down · probe failingin the kernel: IPVS over netlinkTCP or HTTP health probesconnection table synchronised to the standby: sessions survive a failover

Passkeys

The web interface signs in with passkeys (WebAuthn): Touch ID, Face ID, Windows Hello, a phone or a hardware security key. A passkey only works on the firewall it was made for, so a lookalike phishing page gets nothing.

  • Username-less sign-in: the browser offers the passkeys it holds for this firewall, so there is no username to probe and nothing reveals which accounts exist.
  • User verification, a PIN or biometrics, is always required, and failed attempts count towards the same login throttle as passwords.
  • Adding a passkey requires the account password again, so a stolen session cannot plant a permanent way back in.
  • Only public keys are stored, in the configuration like every other credential; removing a passkey ends that user's other sessions.
  • On a high availability pair, passkeys belong to the name on the virtual address, so the same passkeys sign in to whichever firewall is active.

Management and security

The web interface and the CLI are two views of one configuration, served by an unprivileged, sandboxed management server.

  • Users with administrator or read-only roles, argon2id passwords, passkeys for the web interface and SSH keys for the CLI.
  • Logins over SSH land in the CLI, never a shell. Brute-force attempts are blocked automatically.
  • A running and a startup configuration, a history of the last 100 versions with who changed what, and rollback.
  • Backup and restore, ping, traceroute, a connection table browser and the system logs, in the browser.
  • A live topology diagram of the interfaces: ports, bonds, bridges and VLANs with their members, addresses and VRRP state, readable on a phone too.
  • A certificate manager with an internal CA, and ACME certificates for the web interface.