Opnsense
I am no longer use Opnsense for my router therefore this document will likely not be updated anymore.
BGP
Instead of using Metallb for L2/L3 load balancer IPs I am using the Kubernetes Calico CNI with BGP which allows me to advertise load balancer IPs directly over BGP. This has some benefits like having equal cost multipath (ECMP) for scaled workloads in my cluster.
- Routing > BPG | General
enable=trueBGP AS Number=64512Network=192.168.42.0/24(Subnet your Kubernetes nodes are on)- Save
- Routing > BGP | Neighbors
- Add a neighbor for each Kubernetes node
Enabled=truePeer-IP=192.168.42.x(Kubernetes Node IP)Remote AS=64512Update-Source Interface=HOME_SERVER(VLAN of Kubernetes nodes)- Save
- Continue adding neighbors until all your nodes are present
- Add a neighbor for each Kubernetes node
- Routing > General
Enable=true- Save
- System > Settings > Tunables
- Add
net.route.multipathand set the value to1 - Save
- Add
- Reboot
- Verify
- Routing > Diagnostics | Summary
Without updating the configuration described in step 4 the routes from a client will only take a single path to your Kubernetes workloads even if they are scaled to more than one.
HAProxy
While kube-vip is very nice for having a API server ready to go and running in your cluster I had issues with mixing layer 2 and layer 3 between Calico in BGP and kube-vip using L2 ARP. You also cannot run Calico in BGP with kube-vip in BGP, they will fight and you will lose. Instead I choose to use Haproxy which you can install from the Opnsense Plugins.
- Services > HAProxy | Real Servers
- Add a server for each master node in your Kubernetes cluster
Enabled=trueName or Prefix=k8s-apiserver-xFQDN or IP=192.168.42.xPort=6443Verify SSL Certificate=false- Apply/Save
- Continue adding servers until all your master nodes are present
- Add a server for each master node in your Kubernetes cluster
- Services > HAProxy | Rules & Checks > Health Monitors
Name=k8s-apiserver-healthSSL preferences=Force SSL for health checksPort to check=6443HTTP method=GETRequest URI=/healthzHTTP version=HTTP/1.1- Apply/Save
- Services > HAProxy | Virtual Services > Backend Pools
Enabled=trueName=k8s-apiserver-beMode=TCP (Layer 4)Servers=k8s-apiserver-x... (Add one for each server you created. Use TAB key to complete typing each server)Source address=192.168.1.1(Your Opnsense IP address)Enable Health Checking=trueHealth Monitor=k8s-apiserver-health- Apply/Save
- Services > HAProxy | Virtual Services > Public Services
Enabled=trueName=k8s-apiserver-feListen Addresses=192.168.1.1:6443(Your Opnsense IP address. Use TAB key to complete typing a listen address)Type=TCPDefault Backend Pool=k8s-apiserver-be- Apply/Save
- Services > HAProxy | Settings > Service
Enable HAProxy=true- Apply/Save
- Services > HAProxy | Settings > Global Parameters
Verify SSL Server Certificates=disable-verify- Apply/Save
- Services > HAProxy | Settings > Default Parameters
Client Timeout=4hConnection Timeout=10sServer Timeout=4h- Apply/Save
Receive Side Scaling (RSS)
RSS is used to distribute packets over CPU cores using a hashing function – either with support in the hardware which offloads the hashing for you, or in software. Click here to learn more about it.
- System > Settings > Tunables
- Add
net.inet.rss.enabledand set the value to1 - Add
net.inet.rss.bitsand set to2 - Add
net.isr.dispatchand set tohybrid - Add
net.isr.bindthreadsand set to1 - Add
net.isr.maxthreadsand set to-1 - Save
- Add
- Reboot
- Verify with
sudo netstat -QConfiguration: Setting Current Limit Thread count 8 8 Default queue limit 256 10240 Dispatch policy hybrid n/a Threads bound to CPUs enabled n/a
Syslog
Firewall logs are being sent to Vector which is running in my Kubernetes cluster. Vector is then shipping the logs to Loki which is also running in my cluster.
- System > Settings > Logging / targets
- Add new logging target
Enabled=trueTransport=UDP(4)Applications=filter (filterlog)Hostname=192.168.69.111(Loki's Load Balancer IP)Port=5140rfc5424=true- Save
- Add new logging target
SMTP Relay
To ease the use of application configuration I have a SMTP Relay running on Opnsense using the Postfix plugin. From applications deployed in my Kubernetes cluster, to my nas, to my printer, all use the same configuration for SMTP without authentication.
- System > Services > Postfix > General
SMTP Client Security=encryptSmart Host=[smtp.fastmail.com]:465Enable SMTP Authentication=trueAuthentication Username=devin@<email-domain>Authentication Password=<app-password>Permit SASL Authenticated=false- Save
- System > Services > Postfix > Domains
- Add new domain
Domainname=<email-domain>Destination=[smtp.fastmail.com]:465- Save
- Apply
- Add new domain
- System > Services > Postfix > Senders
- Add new sender
Enabled=trueSender Address=admin@<email-domain>- Save
- Apply
- Add new sender
- Verify
swaks --server opnsense.turbo.ac --port 25 --to <email-address> --from <email-address>