OPNsense Forum

English Forums => Tutorials and FAQs => Topic started by: ProximusAl on August 15, 2026, 10:12:32 PM

Title: Remote OPNsense serial console using a QNAP NAS
Post by: ProximusAl on August 15, 2026, 10:12:32 PM
I have an OPNsense DEC750v2 which is a truly headless appliance. There are no HDMI, DisplayPort or VGA outputs - local console access is via the Mini-USB serial console port.

Normally this isn't a problem, but it becomes more important when something goes wrong during an upgrade. If OPNsense won't boot properly and both the WebGUI and SSH are unavailable, the serial console may be the only way to see what is happening and interact with the boot loader.

This is particularly relevant now that OPNsense supports ZFS snapshots/boot environments. I can create a snapshot before an upgrade, but if the upgrade goes badly enough that OPNsense is inaccessible, I still need some way of reaching the console to select and boot the previous environment.

I wanted a way of accessing that serial console without having to physically connect a laptop to the DEC750v2 every time.

I already had a QNAP NAS sitting next to the firewall, so I used Container Station/Docker to turn it into a simple network-accessible serial console server.

The setup is:

DEC750v2 Mini-USB console
        |
        v
QNAP /dev/ttyACM0
        |
        v
Docker container (Alpine)
        |
        +--- ser2net TCP 7001 ---> PuTTY (Raw TCP)
        |
        +--- ttyd TCP 7681 ------> Web browser


OPNsense configuration

In OPNsense I went to:

System -> Settings -> Administration -> Console

and configured:

Primary Console: Serial Console
Secondary Console: EFI Console
Serial Speed: 115200
USB-based serial: Disabled
Console menu: Password protect enabled

Once saved, the normal OPNsense console menu became available over the DEC750v2 serial connection.


QNAP configuration

I connected the DEC750v2 Mini-USB console port to a USB port on the QNAP.

On the QNAP this appeared as:

/dev/ttyACM0

I created the following directory:

/share/Container/opnsense-console

In that directory I created a file called:

Dockerfile

Containing:

FROM alpine:3.24

RUN apk add --no-cache ser2net ttyd netcat-openbsd

COPY ser2net.yaml /etc/ser2net.yaml

CMD sh -c 'ser2net -n -c /etc/ser2net.yaml & exec ttyd -W -p 7681 nc 127.0.0.1 7001'


I then created:

ser2net.yaml

Containing:

connection: &opnsense
  accepter: tcp,7001
  enable: on
  connector: serialdev,/dev/ttyACM0,115200n81,local


I built the Docker image with:

cd /share/Container/opnsense-console

sudo docker build --pull --no-cache -t opnsense-console:latest .


Then created the container:

sudo docker run -d \
  --name opnsense-console \
  --restart unless-stopped \
  --device=/dev/ttyACM0:/dev/ttyACM0 \
  -p 7001:7001 \
  -p 7681:7681 \
  opnsense-console:latest

The "--restart unless-stopped" option means the console container automatically comes back after the QNAP reboots.


PuTTY access

I can connect using PuTTY with:

Host: QNAP-IP
Port: 7001
Connection type: Raw

This gives me the normal interactive OPNsense serial console through PuTTY.


Web console

I also added ttyd to provide a proper browser-based terminal.

This is accessed using:

http://QNAP-IP:7681

I always use IP because OPNSense is my DNS server too...

This works particularly well from Safari on an iPad/iPhone and gives me a proper interactive terminal with the normal on-screen keyboard.

Both methods ultimately connect to the same serial console:

PuTTY -> TCP 7001 -> ser2net -> /dev/ttyACM0 -> DEC750v2

or:

Browser -> ttyd -> netcat -> ser2net -> /dev/ttyACM0 -> DEC750v2


Why I wanted this

My main reason for doing this is safer OPNsense upgrades.

Before upgrading I can create a ZFS snapshot/boot environment.

If an upgrade then breaks OPNsense badly enough that the WebGUI and SSH aren't available, I still have access to the physical serial console.

The particularly useful part is that the serial connection is available throughout a reboot. This means I can see the DEC/FreeBSD boot process and interrupt the boot loader if necessary.

I can therefore reboot the DEC, interrupt the FreeBSD loader and select the previous ZFS boot environment without having to physically connect another machine to the firewall.

Obviously this isn't true out-of-band management because the QNAP is still accessed over my normal LAN. However, my network is a flat LAN and devices retain their IP addresses while the firewall is rebooting or unavailable.

This means I can still access another machine on the LAN by IP and from there access the QNAP console server even if OPNsense itself isn't working.


Security

There are a couple of important security considerations.

TCP 7001 is raw, unencrypted and unauthenticated.

The basic ttyd configuration on TCP 7681 is also HTTP and unauthenticated.

I only expose these on my trusted internal LAN.

I would absolutely not port-forward either of these ports or expose them directly to the Internet.

I also have password protection enabled on the OPNsense console menu itself.


Other hardware

Although I happened to use a QNAP NAS, there's nothing particularly QNAP-specific about the actual solution.

Any always-on machine capable of running Docker and accessing the USB serial device should be able to do essentially the same thing.

For me it's effectively turned an existing NAS sitting next to the firewall into a small dedicated OPNsense console server, with both PuTTY and browser access.

I hope this might help or inspire someone else...