It's also nice to be able to access your own services while travelling. The operation of a publicly accessible service installed in the local network can be realised ingeniously simply with a Let's Encrypt certificate and HAProxy on the OPNsense firewall.
Nevertheless: This expansion stage is now suitable for public operation, but it has to be updated and maintained regularly now. Nothing is worse than an outdated and thus vulnerable installation.
Last updated:
TCP port
was set to 8443 under System - Settings - Administration
(previously 443)Firewall - Rules - WAN
. (Protocol: TCP, Source: Any, Destination: This Firewall, Port: 443)Overrides
in Unbound
under Services
.This makes the setup look like this:
┌─────────────────────────────┐
│ TrueNAS / FreeBSD │
┌──────────────────────┐ │ ┌─────────────────────────┐ │
│ OPNsense │ │ │ YESils/YESilname │ │
WAN: 0.0.0.0:80 ─┼─► acme.sh:80 ───────┼─ LAN: IP:PORT ─┼─┼─► service │ │
WAN: 0.0.0.0:443 ─┼─► HAProxy:443 │ │ │ │ │
└──────────────────────┘ │ └─────────────────────────┘ │
└─────────────────────────────┘
With the ACME Client Plugin (os-acme-client) OPNsense is able to create and renew Let's Encrypt certificates automatically. The huge advantage is that we have a central certificate management, don't need a separate management on each internal target system and don't need to configure NAT or other firewall settings.
To get a certificate for your own domain, only a few steps are necessary under Services - ACME Client
. For this we change to the area Services - ACME Client - Settings
of the OPNsense and set the following checkmarks:
Enable Plugin: YES
Auto Renewal: YES
This activates the plugin and sets the automatic renewal of certificates.
We then switch to the Services - ACME Client - Accounts'
area and create a new account with the +
sign.
Enabled: YES
Name: ACCOUNTNAME
E-Mail Address: EMAIL
ACME CA: Let's Encrypt [default]
The account must be registered once. On the far right you will find the Register account
button. If successful, the account will then be labelled OK (registered)
under Status.
Tip: One registration is enough, no matter how many certificates we need in the end.
Next, we specify how the challenge should take place. This is done in the section Services - ACME Client - Challenge Types
.
Again, we create a new challenge with the following settings by pressing the +
sign:
Enabled: YES
Name: HOSTNAME
Challenge Type: HTTP-01
HTTP Service: OPNsense Web Service (automatic port forward)
Interface: WAN
A new entry is created under Services - ACME Client - Automations
.
Name: Restart HAProxy
Run Command: Restart HAProxy
The last step is to create the certificate. For this we change to Services - ACME Client - Certificates
and create again a new entry by the +
sign.
In the field ACME Account
we select the account we just created, in the field Challange Type
we select the created challange. We select the remaining settings as follows:
Enabled: YES
Common Name: EXTERNHOSTNAME
ACME Account: ACCOUNTNAME (from Accounts)
Challenge Type: HOSTNAME (from Challenge Types)
Key Length: ec-384
Automations: Restart HAProxy
Now all settings are done and the certificate can be created on the right side with the button Issue or renew certificate
. If successful (this takes a few minutes) the certificate will be marked with OK
at Last ACME Status
.
Done! The certificate is now renewed fully automatically every 90 days according to the settings.
HAProxy receives the calls for port 443 from the outside, encrypts the connection and forwards it to the internal Gitea server on port 3000. The nice thing is that here again the administration takes place centrally, the certificates can be used without any effort from Let's Encrypt and several services can be provided at the same time on port 443. The difference is made by the called external hostname. This makes it possible that e.g. https://service.domain.de is forwarded to the service and https://domain.de to the actual website, although both actually require port 443 on the same external IP address.
The task of HAProxy here is:
The process is: Public Service (EXTERNHOSTNAME:443) ─► Condition ─► Rule ─► Pool ─► HOSTNAME:PORT
Now to get a forwarding of the EXTERNALHOSTNAME to the internal Gitea, only a few steps are necessary under Services - HAProxy
:
In the first step we define a server under Services - HAProxy - Settings
in the tab Real Servers
. Again, this is done by pressing the +
button.
Enable HAProxy: YES
Let's start with the service, this gets the following entries:
Name: server_HOSTNAME
Description: IP address of the local server
Type: static
FQDN or IP: IP
Port: PORT
In the second step we create the Backend Pools
, this we do under Services - HAProxy - Settings
in the tab Virtual Services
the entry Backend Pools
.
Name: pool_HOSTNAME
Description: Pool of local Vaultwarden servers (there is only one)
Servers: server_HOSTNAME
Now we define the set of rules that determine which incoming connections are forwarded to which service.
To do this, we select the Conditions
entry under Services - HAProxy - Settings
in the Rules & Checks
tab and create two conditions:
Name: HOSTNAME host check
Description: Check if the EXTERNHOSTNAME has been called
Condition type: Host matches
Path Regex: EXTERNHOSTNAME
These conditions are checked by a rule.
We create rules as follows under Services - HAProxy - Settings
in the Rules & Checks
tab in the Rules
entry by pressing the +
button:
Name: HOSTNAME host rule
Description: Forward external access to the direct server (in the pool)
Select conditions: HOSTNAME host check
Execute function: Use specified Backend Pool
Use backend pool: pool_HOSTNAME
Finally we create a Public Services
under Services - HAProxy - Settings
in the tab Virtual Services
the entry ´Public Services
:
Name: service_https
Description: Server on port 443 that accepts all external requests
Listen Addresses: 0.0.0.0:443
Default Backend Pool: none
Certificates: EXTERNHOSTNAME (ACME Client)
Default certificate: EXTERNHOSTNAME (ACME Client)
Cipher List: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
Cipher Suites: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
Enable HSTS: YES
HSTS includeSubDomains: YES
Select Rules: HOSTNAME host rule
Tip: If there are several internal servers, Select Rules
can receive multiple entries.
With Apply
the configuration is written and the HAProxy service is started.
Now external access to the Gitea is set up and allowed.
Please remember to allow port 443 in the firewall.
Voilá