Neon beach at night

~*+ AquaOctet +*~

dominic's tech log // from the neon depths

NEW POST >>BUILDING THE IDEAL ROUTER FROM SCRATCHPROJECT >>OpenZephyrPROJECT >>Jordle4 TRANSMISSIONS IN ARCHIVE#OPENWRT#NETWORKING#HOMELAB#5G#LTE#WIFI6STACK >>Kubernetes / Terraform / Docker / Helm / ArgoCD / AnsibleALSO >>Deploy Open WebUI in Docker Swarm with Chroma DB and OllamaALSO >>Install Gitlab Runners on KubernetesNEW POST >>BUILDING THE IDEAL ROUTER FROM SCRATCHPROJECT >>OpenZephyrPROJECT >>Jordle4 TRANSMISSIONS IN ARCHIVE#OPENWRT#NETWORKING#HOMELAB#5G#LTE#WIFI6STACK >>Kubernetes / Terraform / Docker / Helm / ArgoCD / AnsibleALSO >>Deploy Open WebUI in Docker Swarm with Chroma DB and OllamaALSO >>Install Gitlab Runners on Kubernetes

>> LATEST TRANSMISSIONS <<

Protectli VP2420 + Quectel RM520N-GL + MediaTek MT7921 + OpenWRT

[date] 03.25.2026[mood] hacker mode
[music] Perturbator - Dangerous Days
#openwrt#networking#homelab#5g#lte#wifi6

A complete walkthrough of hardware selection, why we ditched OPNsense, getting 5G working via QMI, WiFi 6 in AP mode, and dual-WAN failover with mwan3.

reading: building the ideal router from scratch
Building the Ideal Router from Scratch

Why Build Your Own Router?

Consumer routers are a compromise. They're designed to be sold, not engineered to perform. Cheap plastic, locked firmware, mediocre drivers, and security patches that arrive six months late -- if at all.

When you're working remotely, routing traffic through a VPN, running a homelab, or travelling internationally with a SIM card, you need hardware you can actually trust and fully control.

This build was born from a specific problem: a travel router that could accept a local SIM card, broadcast WiFi, handle dual-WAN failover, and still be light enough to throw in a bag. The answer wasn't a consumer router. It was a small-form-factor x86 box running proper open-source firmware.

This guide follows the exact path from unboxing a Protectli VP2420 to a fully operational dual-WAN 5G + WiFi 6 router. Every gotcha, dead-end, and working config is documented here.


The Hardware Stack

Everything in this build was chosen deliberately. Here's what we're working with and why.

| Component | Choice | Details | |---|---|---| | Base Unit | Protectli VP2420 | Intel Elkhart Lake J6412, 4x 2.5GbE, fanless | | 5G Modem (M.2 B-Key) | Quectel RM520N-GL | 5G Sub-6, global bands, QMI/MBIM | | WiFi Card (M.2 E-Key) | MediaTek MT7921 | WiFi 6, 2.4 + 5GHz, full AP mode on OpenWRT | | Operating System | OpenWRT | Linux-based, opkg packages, native QMI | | Primary WAN | Rakuten Mobile | 5G/LTE, Band 3 + n77, APN: rakuten.jp | | Secondary WAN | Ethernet (ISP/Tether) | mwan3 failover + load balancing |

Why the VP2420?

The VP2420 ships with four Intel I225-V 2.5GbE NICs, fanless passive cooling, and -- crucially -- two separate M.2 slots: one B-Key for LTE/5G modems and one E-Key (2230) for WiFi. Both can coexist, no tradeoffs.

The Elkhart Lake J6412 is no powerhouse, but for routing, NAT, and firewall duty it's more than sufficient. AES-NI hardware acceleration handles VPN tunnels without breaking a sweat.

Why the Quectel RM520N-GL?

The RM520N-GL is a global 5G module covering Band 3 and n77 (Rakuten Japan), AT&T/T-Mobile bands (North America), and Telstra bands (Australia). If you move between countries, this is the modem that doesn't force you to choose a region.

More importantly: it communicates via QMI protocol, which OpenWRT supports natively. This is the key distinction that makes the rest of this guide work.

Why the MT7921 over Intel AX200/AX210?

Intel WiFi cards look attractive on paper -- WiFi 6E, widely available, cheap. The problem is their Linux driver (iwlwifi) has severe limitations in Access Point mode. It's designed for client devices (laptops), not APs. On OpenWRT, Intel cards effectively cap out at 2.4GHz in AP mode and often behave unreliably with multiple clients.

The MediaTek MT7921 uses the open-source mt76 driver with first-class OpenWRT support and full AP mode on both 2.4GHz and 5GHz. It's the correct choice for this use case.


The OPNsense Problem

The original plan was to run OPNsense -- it's polished, well-documented, and familiar to anyone coming from pfSense. But when we tried to connect the Quectel RM520N-GL, we hit a wall that turned out to be fundamental rather than configurable.

OPNsense and pfSense do not support QMI or MBIM protocols. Both rely exclusively on PPP for cellular modem communication -- an older, slower serial protocol. Since OPNsense 24.7, even PPP with internal LTE modems has been broken for many users, with debug errors like label not found in the MPD daemon.

The real-world performance difference is severe:

| OS | Protocol | Download | Upload | Status | |---|---|---|---|---| | OPNsense | PPP (only option) | ~9-21 Mbps | ~8-12 Mbps | Broken in 24.7+ | | OpenWRT | QMI (native) | ~80-100 Mbps | ~30-50 Mbps | Works perfectly |

The verdict is clear. OPNsense is a fine firewall OS when you're using Ethernet WAN. For embedded cellular modems, it's the wrong tool. OpenWRT was designed with this use case in mind from the start.


Installing OpenWRT on the VP2420

The VP2420 is an x86_64 machine, so you'll use the generic x86 OpenWRT image -- not a device-specific build.

Download the image

Get the latest stable x86/64 combined image from downloads.openwrt.org. Look for:

openwrt-x86-64-generic-ext4-combined-efi.img.gz

The EFI variant works reliably with the VP2420's BIOS.

Flash and install

  1. Decompress the image:
gunzip openwrt-*.img.gz
  1. Flash to a USB drive:
dd if=openwrt-*.img of=/dev/sdX bs=4M status=progress
  1. Boot the VP2420 from USB (press F11 at POST for the boot menu)

  2. Once booted, identify your internal SSD:

lsblk
  1. Flash to internal storage:
dd if=openwrt-*.img of=/dev/sda bs=4M
  1. Reboot and remove the USB drive.

By default, OpenWRT only creates a small root partition. After first boot, expand it with parted and resize2fs to use your full SSD. You'll need the space for packages.

First boot access

Connect your laptop directly to port 1 (eth0) with an Ethernet cable. OpenWRT's default LAN IP is 192.168.1.1.

ssh [email protected]

No password is set initially -- set one immediately:

passwd
opkg update

Configuring the Quectel Modem via QMI

With the RM520N-GL installed in the B-Key M.2 slot, OpenWRT should enumerate the device automatically. Verify it's present:

lsusb | grep -i quectel
# Expected: Quectel Wireless Solutions Co., Ltd.

ls /dev/cdc-wdm*
# Expected: /dev/cdc-wdm0

Install QMI tools

opkg update
opkg install kmod-usb-net-qmi-wwan uqmi luci-proto-qmi

Verify the connection manually first

# Start the data connection
uqmi -d /dev/cdc-wdm0 --start-network --apn rakuten.jp --keep-client-id wds

# Confirm connected
uqmi -d /dev/cdc-wdm0 --get-data-status
# Expected: "connected"

# Bring up the interface and get an IP
ip link set wwan0 up
udhcpc -i wwan0

# Test connectivity
ping -I wwan0 8.8.8.8

Seeing "disconnected" from --get-data-status? Run --start-network first. The modem won't auto-connect until the interface is formally requested.

Persistent config via UCI

Once confirmed working, set it up permanently:

uci set network.wwan=interface
uci set network.wwan.proto='qmi'
uci set network.wwan.device='/dev/cdc-wdm0'
uci set network.wwan.apn='rakuten.jp'
uci set network.wwan.pdptype='ipv4v6'
uci set network.wwan.auth='none'
uci commit network

# Add to WAN firewall zone
uci add_list firewall.@zone[1].network='wwan'
uci commit firewall

/etc/init.d/network restart

Check signal quality

uqmi -d /dev/cdc-wdm0 --get-signal-info

Good signal targets: RSSI above -70 dBm, RSRP above -90 dBm, SNR above 15 dB.

APN reference by carrier

| Carrier | APN | Auth | |---|---|---| | Rakuten Mobile (JP) | rakuten.jp | None | | IIJmio (JP) | iijmio.jp | CHAP | | T-Mobile (US) | fast.t-mobile.com | None | | Telstra (AU) | telstra.internet | None |


Adding WiFi 6 with the MT7921

The MT7921 fits the VP2420's M.2 2230 E-Key slot. You'll also need two antenna cables (IPEX/MHF4) routed to the pre-drilled antenna holes on the VP2420 chassis -- Protectli includes these holes specifically for this purpose.

Install the driver and hostapd

opkg update
opkg remove wpad-basic-wolfssl   # remove the limited default
opkg install kmod-mt7921e wpad-openssl

reboot

After reboot, verify the card is detected:

dmesg | grep mt7921
iw dev

The interface creation quirk

On some OpenWRT builds with the MT7921, the phy0-ap0 virtual interface expected by hostapd doesn't get created automatically. Confirm this is your issue:

hostapd -dd /var/run/hostapd-phy0.conf 2>&1 | head -20
# If you see: "Could not read interface phy0-ap0: No such device"
# -> proceed with the fix below

Create the interface manually and test:

iw phy phy0 interface add wlan0 type __ap
ip link set wlan0 up

# Update the hostapd config to use wlan0 instead
sed -i 's/phy0-ap0/wlan0/' /var/run/hostapd-phy0.conf

# Run hostapd -- should show AP-ENABLED
hostapd -dd /var/run/hostapd-phy0.conf 2>&1 | grep -E "ENABLED|ERROR"

To make it persistent across reboots:

cat << 'EOF' > /etc/rc.local
# Create wireless interface for MT7921
iw phy phy0 interface add wlan0 type __ap
ip link set wlan0 up
exit 0
EOF

Configure the wireless network via LuCI

Navigate to Network > Wireless in LuCI. Click Add on your radio and configure:

  • Mode: Access Point
  • SSID: your network name
  • Band: 5GHz (802.11ax / WiFi 6)
  • Channel: 36 or auto
  • Width: 80MHz
  • Security: WPA2/WPA3 Mixed + strong passphrase
  • Network: Assign to lan

Channel 36 at 80MHz width gives the best balance of speed and interference avoidance in dense urban environments. The MT7921 supports 2.4GHz and 5GHz in AP mode -- 6GHz is not available in AP mode on this card.


Dual WAN with mwan3

With the cellular modem as primary WAN and an Ethernet connection as WAN2, you can configure intelligent traffic routing. mwan3 handles health checking, failover, and load balancing between both connections.

Install mwan3

opkg install mwan3 luci-app-mwan3
/etc/init.d/mwan3 enable

Full mwan3 config

Edit /etc/config/mwan3:

config globals 'globals'
    option mmx_mask '0x3F00'

config interface 'wwan'
    option enabled '1'
    option family 'ipv4'
    list track_ip '8.8.8.8'
    list track_ip '1.1.1.1'
    option track_method 'ping'
    option reliability '1'
    option count '3'
    option timeout '2'
    option interval '5'
    option down '3'
    option up '3'

config interface 'wan2'
    option enabled '1'
    option family 'ipv4'
    list track_ip '8.8.8.8'
    option track_method 'ping'
    option reliability '1'
    option count '3'
    option timeout '2'
    option interval '5'
    option down '3'
    option up '3'

config member 'cellular_primary'
    option interface 'wwan'
    option metric '1'
    option weight '2'

config member 'ethernet_primary'
    option interface 'wan2'
    option metric '1'
    option weight '3'

config policy 'balanced'
    list use_member 'cellular_primary'
    list use_member 'ethernet_primary'

config policy 'cellular_only'
    list use_member 'cellular_primary'

config rule 'default_rule'
    option dest_ip '0.0.0.0/0'
    option use_policy 'balanced'
    option proto 'all'

config rule 'ipv6_default'
    option family 'ipv6'
    option proto 'all'
    option use_policy 'cellular_only'

Apply and verify:

/etc/init.d/mwan3 restart
mwan3 status

All IPv6 traffic is routed through the cellular interface -- Rakuten provides native IPv6 (240b:: prefix) while most secondary connections are IPv4-only via CGNAT.

Fix LAN connectivity after enabling mwan3

If clients lose internet access after enabling mwan3, the WAN interfaces likely aren't in the firewall's wan zone:

uci add_list firewall.@zone[1].network='wwan'
uci add_list firewall.@zone[1].network='wan2'
uci commit firewall
/etc/init.d/firewall restart

DNS and Cloudflare Setup

OpenWRT uses dnsmasq as its local DNS resolver. By default it forwards queries to whatever the WAN interface provides. We'll override this with Cloudflare's DNS and lock it down so WAN interfaces can't overwrite it.

Configure upstream DNS resolvers

uci set dhcp.@dnsmasq[0].noresolv='1'
uci del dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server='1.1.1.1'
uci add_list dhcp.@dnsmasq[0].server='1.0.0.1'
uci add_list dhcp.@dnsmasq[0].server='2606:4700:4700::1111'
uci add_list dhcp.@dnsmasq[0].server='2606:4700:4700::1001'
uci commit dhcp
/etc/init.d/dnsmasq restart

Prevent WAN interfaces from overwriting DNS

uci set network.wwan.peerdns='0'
uci set network.wan2.peerdns='0'
uci commit network

Enable DNSSEC

uci set dhcp.@dnsmasq[0].dnssec='1'
uci set dhcp.@dnsmasq[0].dnsseccheckunsigned='1'
uci commit dhcp
/etc/init.d/dnsmasq restart

Verify:

nslookup cloudflare.com 127.0.0.1

Final Architecture

[ Internet ]
      |
      +---- 5G/LTE (Rakuten) -------- Quectel RM520N-GL (M.2 B-Key)
      |                                -> QMI -> wwan0 interface
      |
      +---- Ethernet WAN2 ----------- eth3 (VP2420 port 4)
                                       -> DHCP -> wan2 interface
              | both via mwan3 load balancer
[ Protectli VP2420 ]  <-  OpenWRT
      |
      +---- LAN (eth0-eth2)  ->  Wired clients
      |
      +---- WiFi AP (wlan0)  ->  MediaTek MT7921
                                  -> 5GHz 802.11ax / WiFi 6
                                     Bridged to br-lan

DNS:  dnsmasq -> 1.1.1.1 / 1.0.0.1 (Cloudflare + DNSSEC)
IPv6: Routed via cellular (Rakuten native dual-stack)

Performance results

| Test | Result | Notes | |---|---|---| | Cellular (Rakuten 5G/LTE) | ~80-100 Mbps down / 30-50 Mbps up | QMI protocol, Tokyo coverage | | WiFi throughput (iperf3) | ~400-600 Mbps | 5GHz 80MHz, MT7921 AP mode | | mwan3 failover time | < 10 seconds | Ping-based, 3 failures to trigger | | Idle power consumption | ~8-12W | Fanless passive cooling |

Key packages installed

opkg install \
  kmod-usb-net-qmi-wwan uqmi luci-proto-qmi \
  kmod-mt7921e wpad-openssl \
  mwan3 luci-app-mwan3 \
  luci-app-firewall luci-app-opkg \
  tcpdump iperf3 htop

Total cost estimate: VP2420 (~$350) + RM520N-GL (~$120) + MT7921 (~$25) + antennas (~$15) + SSD (~$30) = ~$540. You get enterprise-grade routing that will outlast any consumer device and can be fully reconfigured at the OS level.


Troubleshooting quick reference

| Problem | Likely Cause | Fix | |---|---|---| | Modem shows disconnected | Interface not started | uqmi --start-network --apn ... | | WiFi AP not broadcasting | phy0-ap0 interface missing | iw phy phy0 interface add wlan0 type __ap | | LAN clients have no internet | WAN not in firewall zone | uci add_list firewall.@zone[1].network='wwan' | | DNS not resolving correctly | peerdns overwriting config | uci set network.wwan.peerdns='0' | | OPNsense modem not connecting | No QMI support in BSD | Switch to OpenWRT |


Router hostname: KeyToVoid -- Running OpenWRT -- Tokyo, Japan

permalink: /posts/building-ideal-router-from-scratch

Streamline AI Model Hosting with Docker Swarm, Chroma DB, and Ollama

[date] 11.16.2024
#docker#swarm#ollama#chromadb#ai#self-hosted

Learn how to deploy Open WebUI seamlessly within a Docker Swarm deployment, integrating Chroma DB for efficient vector database management and Ollama for AI model hosting.

reading: deploy open webui in docker swarm with c...
Deploy Open WebUI in Docker Swarm with Chroma DB and Ollama

Deploy OpenWebUI, Ollama, and Chroma Containers to a Docker Swarm

Deploying AI tools like OpenWebUI, Ollama, and ChromaDB in a Docker Swarm can seem daunting. This guide simplifies the process by providing a streamlined method using a Docker stack file to deploy three containers as services. Whether you're using GPU or CPU, this guide ensures a smooth setup.

Overview

This deployment method leverages Docker Swarm to create isolated services for OpenWebUI, Ollama, and ChromaDB. With pre-configured environment variables and detailed instructions, you can get your AI tools running with minimal effort.

Prerequisites

  1. Basic understanding of Docker Swarm.
  2. Docker Swarm configured on your host system.
  3. Proper directories or volumes created for data storage:
    mkdir -p data/open-webui data/chromadb data/ollama
    
  4. GPU support (optional) with NVIDIA Container Toolkit installed and configured.

Deployment Steps

Step 1: Prepare Your Environment

  • With GPU Support: Ensure your host system has GPU support configured:

    • Enable CUDA for your OS and GPU.
    • Install the NVIDIA Container Toolkit.
    • Edit /etc/docker/daemon.json to include:
      {
        "NVIDIA-GPU": "GPU-<YOUR_GPU_NUMBER>"
      }
      
    • Enable GPU resource advertising in /etc/nvidia-container-runtime/config.toml by uncommenting:
      swarm-resource = "DOCKER_RESOURCE_GPU"
      
    • Restart the Docker daemon:
      sudo service docker restart
      
  • With CPU Support: Modify the docker-stack.yaml file to remove GPU-specific lines (lines 70-76).

Step 2: Configure the Docker Stack

Below is a sample docker-stack.yaml file for deploying the three services:

version: '3.9'
services:
  openWebUI:
    image: ghcr.io/open-webui/open-webui:main
    depends_on:
      - chromadb
      - ollama
    volumes:
      - ./data/open-webui:/app/backend/data
    environment:
      DATA_DIR: /app/backend/data
      OLLAMA_BASE_URLS: http://ollama:11434
      CHROMA_HTTP_PORT: 8000
      CHROMA_HTTP_HOST: chromadb
      CHROMA_TENANT: default_tenant
      VECTOR_DB: chroma
      WEBUI_NAME: Awesome ChatBot
      CORS_ALLOW_ORIGIN: "*"
      RAG_EMBEDDING_ENGINE: ollama
      RAG_EMBEDDING_MODEL: nomic-embed-text-v1.5
      RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE: "True"
    ports:
      - target: 8080
        published: 8080
        mode: overlay
    deploy:
      replicas: 1
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 3

  chromadb:
    hostname: chromadb
    image: chromadb/chroma:0.5.15
    volumes:
      - ./data/chromadb:/chroma/chroma
    environment:
      - IS_PERSISTENT=TRUE
      - ALLOW_RESET=TRUE
      - PERSIST_DIRECTORY=/chroma/chroma
    ports:
      - target: 8000
        published: 8000
        mode: overlay
    deploy:
      replicas: 1
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 3
    healthcheck:
      test: ["CMD-SHELL", "curl localhost:8000/api/v1/heartbeat || exit 1"]
      interval: 10s
      retries: 2
      start_period: 5s
      timeout: 10s

  ollama:
    image: ollama/ollama:latest
    hostname: ollama
    ports:
      - target: 11434
        published: 11434
        mode: overlay
    deploy:
      resources:
        reservations:
          generic_resources:
            - discrete_resource_spec:
                kind: "NVIDIA-GPU"
                value: 0
      replicas: 1
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 3
    volumes:
      - ./data/ollama:/root/.ollama

Step 3: Deploy the Stack

  • Deploy the stack with GPU support:

    docker stack deploy -c docker-stack.yaml -d super-awesome-ai
    
  • Deploy with CPU support (after modifying the stack file):

    docker stack deploy -c docker-stack.yaml -d super-awesome-ai
    

Additional Resources

permalink: /posts/open-webui-docker-swarm

Gitlab 16.0+ Method for creating Gitlab Runners on Kubernetes

[date] 08.07.2023[mood] deploying things
[music] Carpenter Brut - Turbo Killer
#gitlab#kubernetes#helm#devops#ci-cd#runners

A walkthrough of the new GitLab 16.0+ runner creation workflow using authentication tokens, Kubernetes secrets, and Helm charts to deploy runners on your cluster.

reading: install gitlab runners on kubernetes
Install Gitlab Runners on Kubernetes

As the title suggests, there are new ways of configuring Gitlab Runners. In GitLab 16.0, a new runner creation workflow was introduced that uses authentication tokens to register runners. The legacy workflow that uses registration tokens is deprecated and will be removed in GitLab 17.0.

We will be starting the process in the GitLab Web GUI.

  1. Go to Settings > CI/CD in a Project
  2. Select Runners > New Runner
  3. Select Linux; Write a tag, description, and edit configurations if desired.

NOTE: Runner TAGS are deprecated in the TOML/HELM, so this is where they are set now.

Copy the runner token, and save it in 1Pass or Vault. If you are using Kubernetes, we will need it for the next step.

Encoding the Token

Follow the steps below -- in order to use this runner token in Kubernetes, you will need to Base64 encode it for the Secret.

echo -n 'glrt-isC-rVy7MUy1cWoxrV4b' | base64

Creating the Namespace

Depending if one exists, we may need to make a namespace. Make sure you use this namespace throughout this deployment:

kubectl create namespace gitlab-runner

Creating the Secret

Create the Kubernetes manifest for the Secret in the namespace for the gitlab runner, we will call it secret.yml:

apiVersion: v1
kind: Secret
metadata:
  name: gitlab-runner-secret
  namespace: gitlab-runner
  type: Opaque
data:
  runner-registration-token: "" # need to leave as an empty string for compatibility reasons
  runner-token: "Z2xydC1pc0MtclZ5N01VeTFjV294clY0Yg==" # This is our Base64 string

Apply the secret to the namespace:

kubectl apply -f secret.yml

Helm Chart

This is the fun part. We will be using a Helmfile for this deployment, which uses the helm chart by GitLab for the deployment of the app gitlab-runner.

Here is the helmfile.yml using the external values file (recommended since we have RBAC also attached):

repositories:
  - name: gitlab
    url: https://charts.gitlab.io
releases:
  - name: gitlab-runner
    chart: gitlab/gitlab-runner
    namespace: gitlab-runner
    createNamespace: true
    version: 0.55.0
    installed: true
    values:
      - gl-runner-values.yaml

Runner Values

While there are many values and settings we can set, only crucial ones will be listed here. For a full list of available values, see the ArtifactHUB Chart.

## GitLab Runner Image
image:
  registry: registry.gitlab.com
  image: gitlab-org/gitlab-runner

imagePullPolicy: IfNotPresent

gitlabUrl: https://gitlab.com/

unregisterRunners: true

replicas: 1

concurrent: 10

## RBAC
rbac:
  create: true
  rules:
    - resources: ["deployments", "configmaps", "pods", "pods/attach", "pods/exec",
                  "secrets", "services", "namespaces", "serviceaccounts"]
      apiGroups: ["*"]
      verbs: ["get", "list", "watch", "create", "patch", "delete", "update"]
    - resources: ["clusterroles", "clusterrolebindings", "secrets", "events"]
      apiGroups: ["*"]
      verbs: ["get", "patch", "update", "create", "list", "watch"]

  clusterWideAccess: true
  serviceAccountName: gitlab-runner

## Runner Configuration
runners:
  config: |
    [[runners]]
      [runners.kubernetes]
        namespace = "{{.Release.Namespace}}"
        image = "ubuntu:16.04"
        service_account = "gitlab-runner"
        service_account_overwrite_allowed = ".*"
        pull_policy = ["always", "if-not-present"]

  executor: kubernetes
  name: "gitlab-new-runner"
  secret: gitlab-runner-secret

Apply the Helmfile:

helmfile apply -f helmfile.yml

If done correctly, you should see these runners in your GitLab!

Documentation

permalink: /posts/gitlab-runners-kubernetes

Open Source your blackbox Cisco firewall

[date] 02.14.2022[mood] hacker mode
[music] Perturbator - Dangerous Days
#networking#cisco#opnsense#linux#homelab#hardware

Free your Cisco ASA from closed-source firmware and put Linux/BSD on it instead. A step-by-step guide to bypassing ROMMON and installing OPNSense on a Cisco ASA-5555X.

reading: install opnsense and linux on cisco asa
Install OPNSense and Linux on Cisco ASA

Install OPNSense or Linux on Cisco ASA

Cisco is a great network solution for most, but I don't think it is a "one-size-fits-all" solution as most would believe.

Pay-Walls, Closed Source, and Black Box technologies will be the death of Privacy and Security. While Cisco has done a lot and is considered the "gold standard," it isn't ideal for those who care for privacy due to its relation with IBM.

During my search for this deemed "impossible" task, I have found a lot of unusual hate surrounding this topic. I don't understand why, but I hope to save others from the hive-minded's trouble towards questioning and wasting any more precious time.

Some of you reading this may think I am an absurd lunatic, and to a degree, that is totally valid; however, that is beside the point! This article's "point" is to help the curious and interested in tinkering, learning, or even furthering the community and the technologies available. In my opinion, this could be the beginning of what could revolutionize the way admins think of "dated" devices. This is a matter of unlocking doorways and reintroducing the mindset of "what can one make this device do" rather than just using it as is.

This "impossible" task may seem complicated, but I assure you it is a cakewalk! Once opened up, it's as easy as 1-2-3!

Requirements

  1. Patience, this is a base requirement in general.
  2. A live image of OPNSense flashed to a USB (or whatever OS you want to use)
    • Make sure you review base requirements for your Operating System of choice, I am using OPNSense.
  3. Storage device, I used an SSD; you can use an HDD or a USB drive as your storage. This will go in your ASA and serve as its storage device.
  4. IDC 16 PIN to VGA Adapter ($6 USD from PCCABLES.com)

Get started

  1. Identify your Device (Cisco ASA Model):

    • Open the ASA up, read documents (that you can find) on your model, look into the specifications
    • On the motherboard, you should see a PINOUT for VGA (16 PIN IDC). This PINOUT will be your entryway into the machine and allow you to bypass ROMMON.
  2. Make your Bootable device:

    • I used Rufus and the VGA OPNSense image. If you are here, I assume you already understand this topic, so I will leave you to your own devices.
  3. Add your parts to the CISCO ASA:

    • I added an SSD to the front of it, 250GB should be more than enough
    • Add RAM if you want; I have 32GB already in mine but it depends on the specs/limits of your device
    • Attach your Adapter and connect the VGA to a screen
    • Attach a keyboard and your bootable device

Show time

  1. Power on your device and enter the bios (Hitting F2 for me)
    • Boot screen took almost a minute to appear after power-on
  2. In BIOS, Disable ROMMON.
  3. Switch the boot order; Make the USB the primary and HDD (boot device) as secondary.
  4. Save changes and reboot.
  5. Enjoy the POWER! Powering the ASA back on should find the bootable device.
    • Install your Operating system!

Conclusion

As of writing this, I have OPNSense running on my CISCO ASA-5555X! These modifications have turned this once scrapped device into a fantastic multi-purpose machine for my home network, free of the subscriptions and closed source limitations. The best part is I have control over the device the way I want to have it.

I hope this helps; feel free to reach out -- I love to collaborate and conversate! Let me know your experiences, I have seen ESXi running on these mini powerhouses, which is brilliant!

All the best, Dominic

Links

permalink: /posts/asa-modding-opnsense
_x
>> GUESTBOOK.exe <<

*~* leave a transmission via github issues *~*

entries are pulled from github issues labeled 'guestbook'.

sign the guestbook by opening a new issue:

>> SIGN GUESTBOOK ON GITHUB <<

fetching transmissions from the void

loading...

=====[ END OF TRANSMISSION ]=====

(c) 2004-2026 AquaOctet // dominic

~ visitors ~

∞∞∞∞∞∞

tracked via cloudflare

~* you have reached the bottom of the ocean *~