Skip to content

Initial Setup

While a home network wouldn't typically be considered priority or critical enough to warrant a need to take extra precautions for a project like this, I didn't want to anger the rest of the household by killing the Internet connection. This is especially the case as I tend to swap between projects and completion timelines aren't entirely set in stone.

With that in mind, I decided to develop this automation by first replicating it into a virtualized (testing) environment in GNS3. As I had originally setup a GNS3 server for use for my CCNA studies, I thought it best to utilize it now to stand up a testing environment for building my Ansible playbook(s).

Since we are integrating with tools in a virtual testing environment, a particular setup had to be devised in order to ease development while also ensuring that we could get the environment as close to production as humanely possible.

In the end, we settled with the following for the server and networking setup:

flowchart TD

    %%%%%%%%%%%
    %% NODES %%
    %%%%%%%%%%%

    %% DEFINE TITLE NODES %%

    PHN_Block_Title@{ shape: doc, label: "PRODUCTION HOME NETWORK" }
    GNS_Block_Title@{ shape: doc, label: "GNS3 SERVER<br/>(Virtual Network Lab)" }
    Proxmox_Block_Title@{ shape: doc, label: "PROXMOX VE SERVER<br/>(VM/CTs)" }

    %% Define Production Home Network Nodes

    PRD_OPNSense["OPNSense Firewall/Router"]
    PRD_Switching["LAN(s)"]
    DEV_Workstation["Dev Workstation<br/>(VSCode)"]

    %% Define Proxmox Server Nodes

    PVE_LXC["Ubuntu 24.04 LXC Container<br/>(Ansible Control Node)"]

    %% Define GNS3 Server Nodes

    VIRT_OPNSense["OPNSense Virtual Appliance<br/>(Ansible Managed Node)"]
    VIRT_Switching["LAN(s)"]

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% DEFINE SUBGRAPH STRUCTURES %%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %% Define Internet Subgraph

    subgraph Internet
    end

    %% Define Production Home Network Subgraph (and any nested/formatting-type subgraphs)

    %%{ init: { 'flowchart': { 'curve': 'stepBefore' } } }%%
    subgraph Production_Home_Network [" "]

        PHN_Block_Title

        PRD_OPNSense
        PRD_Switching
        DEV_Workstation

        %% Define Proxmox VE Server Block
        subgraph Proxmox_VE_Server [" "]
            direction TB
            PVE_LXC
            Proxmox_Block_Title
        end

        %% Define GNS3 Server Block
        subgraph GNS3_Server [" "]
            direction TB
            VIRT_OPNSense
            VIRT_Switching
            GNS_Block_Title
        end
    end

    %%%%%%%%%%%%%%%%%%%%%%
    %% Link Definitions %%
    %%%%%%%%%%%%%%%%%%%%%%

    %% Link ID: 0 (INTERNET TO OPNSENSE PROD FIREWALL)
    Internet === PRD_OPNSense

    %% Link ID: 1 (OPSENSE PROD FIREWALL TO PROD LAN)
    PRD_OPNSense === PRD_Switching

    %% Link ID: 2 and 3 (PROD LAN TO VIRTUAL OPNSENSE APPLIANCE)
    PRD_Switching === VIRT_OPNSense
    PRD_Switching === VIRT_OPNSense

    %% Link ID: 4 (VIRTUAL OPNSENSE APPLIANCE TO VIRTUAL LAN)
    VIRT_OPNSense === VIRT_Switching

    %% Link ID: 5 (PROD LAN TO DEVELOPMENT WORKSTATION)
    PRD_Switching === DEV_Workstation

    %% Link ID: 6 (PROD LAN TO PROXMOX LXC)
    PRD_Switching === PVE_LXC

    %% Link ID: 7, 8, 9 (TITLES)
    VIRT_Switching ~~~ GNS_Block_Title
    PVE_LXC ~~~ Proxmox_Block_Title

    %%%%%%%%%%%%
    %% Styles %%
    %%%%%%%%%%%%

    %% Hidden Nodes Style
    classDef hidden fill:#0000,stroke:#0000

    %% VLAN Trunk Link Style
    linkStyle 1,4 stroke-width:7px,stroke:blue

    %% OPNSense Virtual Appliance MGMT Link Style
    linkStyle 2,6 stroke-width:7px,stroke:red

    %% OPNSense Virtual Appliance WAN Link Style
    linkStyle 3 stroke-width:7px,stroke:green

    %% 'Other' Link Style
    linkStyle 0,5 stroke-width:7px

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% Class-Based Style Applications %%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    Production_Home_Network:::PROD

VLANS / Connections

COLOR VLAN Name VLAN ID
BLUE VLAN Trunks (RoAS or Router-On-A-Stick) N/A
GREEN OPNSense Virtual Appliance WAN 200
RED OPNSense Virtual Appliance MGMT 210
BLACK OTHER N/A

Network Format (VLANS)

NETWORK GATEWAY/DNS ADDRESSES DHCP RANGE
172.99.[VLAN ID].200/24 .254 .100-.199

Device IP Addresses

LEASING SCHEME IP ADDRESS DEVICE
STATIC 172.99.210.200/24 Proxmox VE Ubuntu LXC Interface
STATIC 172.99.210.201/24 OPNSense Virtual Appliance MGMT Interface
DHCP DYNAMIC OPNSense Virtual Appliance WAN Interface

The original production network consisted of an OPNSense firewall in an RoAS configuration with multiple VLAN-trunked Unifi switches providing access to end devices and servers in the household.

In starting this project, the idea was to automate the setup of that production firewall by connecting downstream of its default LAN interface and running the playbook against the interface IP address (192.168.1.1/24). However, if I tried to replicate that same configuration in GNS3, I would've had to resort to using a GNS3 appliance to develop my playbooks(s). While I could've looked at some configuration for passing the virtual environment's LAN back to the production network (by providing a physical interface out to the network), I wanted to avoid that looped configuration due to the possibility of the virtual LAN's network segment overlapping with the production's network (as it's the default LAN is in use in production for management of the current Unifi stack).

With that in mind, I used a CLI Debian-based appliance within GNS3 for development. However, I got tired of it pretty quickly due to the headaches involved in CLI navigation and looked to using Visual Studio Code as I was quite comfortable with it from my time working on NGF Records. However, at the same time, I didn't feel that it was good to bloat that appliance with a GUI for development when I was using an old gaming PC as my workstation locally. Instead, I looked to having a separate management interface setup (with minimal configuration) on the OPNSense appliance and having that interface connected to a production VLAN (ID: 210) that my development workstation could access (from it's place on another production VLAN not named here).

That setup looked good so far but I realized that I couldn't use my Windows 11-based workstation as a control node (it was feasible with WSL or Windows Subsystem for Linux but I didn't want to use a setup that Ansible designated as unsupported). At that point, I got around it by setting up an Ubuntu LXC container on my Proxmox hypervisor (configured as a part of my homelab) and connected it to the same management VLAN. I jumped at this setup as I had realized from past experience that Visual Studio Code could use SSH to remote into another environment for development. At the same time, the isolated nature of using a container for development made it an optimal choice for acting as the Ansible control node (and host for both the code and documentation repositories). In the end, I simplified (and secured) the setup even further by making use of SSH agent forwarding to keep SSH keys local to my development workstation.

I also introducted another production VLAN (ID: 200) and address range that I could use for the GNS3 OPNSense appliance WAN. As we were going to be building automations against a virtual firewall whose WAN address was handed down by a production VLAN through DHCP by a bare-metal firewall, I wanted to avoid the possibility of configuring an existing VLAN whose network segment overlapped with the address used by the virtual appliance's WAN connection (my environment used 10.19.50.0/24 originally as an experimentation VLAN in production and that would've conflicted with automation development if we needed to configure that on one VLAN interface while the WAN was also using an address from that same segment.)