<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mediawiki.comfac.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Justinaquino</id>
	<title>MediawikiCIT - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://mediawiki.comfac.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Justinaquino"/>
	<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php/Special:Contributions/Justinaquino"/>
	<updated>2026-06-05T09:47:03Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Organizing_Coder_Terminals&amp;diff=259</id>
		<title>Organizing Coder Terminals</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Organizing_Coder_Terminals&amp;diff=259"/>
		<updated>2026-05-02T08:13:26Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Added RCA: tmux send-keys broke launchers, fixed with direct exec; ce-char-gen troubleshooting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
When running multiple AI coding agents (Claude, Kimi, Qwen, OpenCode) in separate GNOME Terminal windows, every tab looks identical — usually titled by the running process name (e.g., &amp;quot;Kimi Code&amp;quot;). After opening 3–4 terminals, it becomes impossible to tell at a glance which terminal belongs to which project without clicking into each one.&lt;br /&gt;
&lt;br /&gt;
GNOME Terminal 3.44+ removed the &amp;quot;Set Title&amp;quot; option from the tab right-click menu, eliminating the old manual workaround.&lt;br /&gt;
&lt;br /&gt;
== Solution ==&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;tmux&#039;&#039;&#039; inside every terminal:&lt;br /&gt;
* One named tmux session per project (e.g., &amp;lt;code&amp;gt;claude&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;kimi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;qwen&amp;lt;/code&amp;gt;)&lt;br /&gt;
* A &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; bash command that renames both the tmux window and the terminal title&lt;br /&gt;
* Persistent panes — if an AI agent crashes, the pane stays alive and can be respawned&lt;br /&gt;
&lt;br /&gt;
== Quick Start ==&lt;br /&gt;
&lt;br /&gt;
=== Launch All Agents at Once ===&lt;br /&gt;
&lt;br /&gt;
Run on the Ubuntu desktop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
~/start_dev_env.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This opens 5 GNOME Terminal windows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Window Title !! Tmux Session !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Claude Code — tmux || claude || Claude Code AI agent&lt;br /&gt;
|-&lt;br /&gt;
| 2 || OpenCode Claude — tmux || opencode-claude || OpenCode (Claude provider)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || OpenCode Kimi — tmux || kimi || OpenCode (Kimi provider)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || OpenCode Qwen — tmux || qwen || OpenCode (Qwen provider)&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Tmux — General || general || Plain bash for git, docker, file ops&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each session survives even if the GNOME Terminal window is closed.&lt;br /&gt;
&lt;br /&gt;
=== Launch Individual Agents ===&lt;br /&gt;
&lt;br /&gt;
Double-click any desktop launcher:&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/claude.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/kimi.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/opencode.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/Qwen.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each launcher auto-creates or reattaches to its tmux session.&lt;br /&gt;
&lt;br /&gt;
== How to Title Your Session ==&lt;br /&gt;
&lt;br /&gt;
=== The Default Title Is the Command Itself ===&lt;br /&gt;
&lt;br /&gt;
Every new terminal opens with the title:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
title &amp;quot;project&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is intentional — the &#039;&#039;&#039;default title is the command reminder&#039;&#039;&#039;. You never forget the syntax because it&#039;s staring at you from the tab.&lt;br /&gt;
&lt;br /&gt;
=== Change It ===&lt;br /&gt;
&lt;br /&gt;
Inside any terminal, type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
title &amp;quot;ce char gen&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This does two things:&lt;br /&gt;
# Renames the tmux window (visible in the green status bar at the bottom)&lt;br /&gt;
# Sets the GNOME Terminal tab/window title&lt;br /&gt;
&lt;br /&gt;
Change it anytime:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
title &amp;quot;mneme shipgen&amp;quot;&lt;br /&gt;
title &amp;quot;IT-knowledge docs&amp;quot;&lt;br /&gt;
title &amp;quot;$(hostname)&amp;quot;   # reset to hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The title auto-resets after every shell prompt, so AI agents cannot overwrite it.&lt;br /&gt;
&lt;br /&gt;
=== Tmux-Only Renaming ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tmux rename-window &amp;quot;my project&amp;quot;     # rename current window&lt;br /&gt;
tmux rename-session &amp;quot;newname&amp;quot;       # rename entire session&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Key Shortcuts ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b , || Rename current window (interactive prompt)&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b r || Respawn pane (restart AI agent if it crashed)&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b d || Detach session (keeps it running in background)&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b | || Split pane horizontally&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b - || Split pane vertically&lt;br /&gt;
|-&lt;br /&gt;
| Alt+Arrow || Switch panes&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b R || Reload tmux config&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Reattaching to Sessions ==&lt;br /&gt;
&lt;br /&gt;
If a terminal window is closed, the tmux session keeps running:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tmux list-sessions&lt;br /&gt;
tmux attach-session -t claude&lt;br /&gt;
tmux attach-session -t kimi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aliases added to &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tls     # list sessions&lt;br /&gt;
tas claude    # attach to claude session&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuration Files ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! File !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.tmux.conf&amp;lt;/code&amp;gt; || Tmux settings (status bar, mouse, key bindings)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;title()&amp;lt;/code&amp;gt; function + auto-reset + tmux aliases&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.config/tmux-launcher.sh&amp;lt;/code&amp;gt; || Helper script for desktop launchers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Symptom !! Cause !! Fix&lt;br /&gt;
|-&lt;br /&gt;
| Title shows &amp;quot;Kimi Code&amp;quot; instead of custom || AI resets it via escape sequences || &amp;lt;code&amp;gt;PROMPT_COMMAND&amp;lt;/code&amp;gt; auto-resets after every prompt&lt;br /&gt;
|-&lt;br /&gt;
| Tab right-click has no &amp;quot;Set Title&amp;quot; || GNOME Terminal 3.44+ removed it || Use &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; bash command or &amp;lt;code&amp;gt;Ctrl+b ,&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; command not found || &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; not loaded || Start an interactive shell, or run &amp;lt;code&amp;gt;source ~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Default title shows &amp;lt;code&amp;gt;title &amp;quot;project&amp;quot;&amp;lt;/code&amp;gt; || Working as designed — syntax reminder || Type &amp;lt;code&amp;gt;title &amp;quot;your real project&amp;quot;&amp;lt;/code&amp;gt; to replace it&lt;br /&gt;
|-&lt;br /&gt;
| Tmux status bar shows &amp;lt;b&amp;gt;&amp;quot;ce char gen&amp;quot;&amp;lt;/b&amp;gt; || Old &amp;lt;code&amp;gt;~/.tmux.conf&amp;lt;/code&amp;gt; on host hardcoded the title || Replace host &amp;lt;code&amp;gt;~/.tmux.conf&amp;lt;/code&amp;gt; with container&#039;s clean version&lt;br /&gt;
|-&lt;br /&gt;
| AI agent crashed and pane is dead || Process exited || Press &amp;lt;code&amp;gt;Ctrl+b r&amp;lt;/code&amp;gt; to respawn&lt;br /&gt;
|-&lt;br /&gt;
| Session already exists || Previous session still running || &amp;lt;code&amp;gt;tmux attach -t &amp;amp;lt;name&amp;amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;tmux kill-session -t &amp;amp;lt;name&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RCA: Why Tmux Broke the Original Launch Scripts ==&lt;br /&gt;
&lt;br /&gt;
=== What Worked Before (No Tmux) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
distrobox enter agent260411 -- bash -c &#039;cd /home/justin/opencode260220 &amp;amp;&amp;amp; ./csb.sh; exec bash&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;./csb.sh&amp;lt;/code&amp;gt; does &amp;lt;code&amp;gt;exec claude&amp;lt;/code&amp;gt;, which replaces the shell with the interactive AI agent. Claude owns the TTY and runs until the user exits.&lt;br /&gt;
&lt;br /&gt;
=== What Broke (First Tmux Attempt) ===&lt;br /&gt;
The initial &amp;lt;code&amp;gt;tmux-launcher.sh&amp;lt;/code&amp;gt; used &amp;lt;code&amp;gt;tmux send-keys&amp;lt;/code&amp;gt; to type commands into a detached session:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tmux new-session -s &amp;quot;$SESSION&amp;quot; -n &amp;quot;$WINDOW&amp;quot; -d&lt;br /&gt;
tmux send-keys -t &amp;quot;$SESSION:$WINDOW&amp;quot; &amp;quot;./csb.sh&amp;quot; C-m&lt;br /&gt;
tmux attach-session -t &amp;quot;$SESSION&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Why This Failed ===&lt;br /&gt;
# &#039;&#039;&#039;Race condition&#039;&#039;&#039;: &amp;lt;code&amp;gt;send-keys&amp;lt;/code&amp;gt; types faster than the shell initializes. The command often arrived before bash was ready, causing &amp;quot;command not found&amp;quot; or silent failure.&lt;br /&gt;
# &#039;&#039;&#039;No TTY guarantee&#039;&#039;&#039;: Interactive apps (Claude, Kimi) need a controlling terminal. &amp;lt;code&amp;gt;send-keys&amp;lt;/code&amp;gt; provides a pane but doesn&#039;t guarantee the app receives proper TTY initialization before the keystrokes land.&lt;br /&gt;
# &#039;&#039;&#039;Exit timing&#039;&#039;&#039;: If the app started before attach, the user attached to a pane that was already dead or mid-execution.&lt;br /&gt;
&lt;br /&gt;
=== The Fix ===&lt;br /&gt;
Replace &amp;lt;code&amp;gt;send-keys&amp;lt;/code&amp;gt; with direct command execution via a wrapper script. This gives tmux the full command upfront, so it initializes the TTY properly before the app starts — exactly like the original scripts, just wrapped in tmux.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[IT Knowledge Base]]&lt;br /&gt;
* [[Forgejo]]&lt;br /&gt;
* [[Docker Stacks]]&lt;br /&gt;
&lt;br /&gt;
[[Category:System Administration]]&lt;br /&gt;
[[Category:Development Environment]]&lt;br /&gt;
[[Category:AI Agents]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=258</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=258"/>
		<updated>2026-05-02T07:31:02Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Added Organizing Coder Terminals to IT index&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f8f9fa; border:1px solid #ddd; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
Welcome to the &#039;&#039;&#039;Comfac IT Knowledge Base&#039;&#039;&#039;. Use the sections below to find guides, SOPs, and references organized by topic.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ERPNext / Frappe ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Frappe HRMS]] — &#039;&#039;&#039;HR &amp;amp; Payroll&#039;&#039;&#039; (with Philippine Localization)&lt;br /&gt;
* [[Frappe ERPNext/Webshop]] — &#039;&#039;&#039;E-Commerce Webshop&#039;&#039;&#039; (setup, architecture, chapters)&lt;br /&gt;
* [[Manufacturing v16 260125]]&lt;br /&gt;
* [[ERpnext Asset Management Procedure 260113]]&lt;br /&gt;
* [[ERPNext HR Module Outline]]&lt;br /&gt;
* [[ERPNEXT Payroll POC 251212]]&lt;br /&gt;
* [[Comfac ERPNext Strategy Canvas (Expanded)]]&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — PAD/AI-agentic implementation strategy for Frappe ERPNext&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — Local Docker setup for evaluation, testing, and student use&lt;br /&gt;
* [[Frappe Links and References]]&lt;br /&gt;
* [[Using Frappe Wiki]]&lt;br /&gt;
* [https://docs.frappe.io/cloud/guidelines-for-contributing-regional-compliance-app Guidelines for Contributing Regional Compliance App]&lt;br /&gt;
* [https://docs.frappe.io/cloud/what-are-benches-and-bench-groups What are Benches?]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Administration &amp;amp; Self-Hosting ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Networking PfSense Index]] — Consolidated index of all networking, pfSense, DNS, and infrastructure guides&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]]&lt;br /&gt;
* [[Controller Systems 251213-01]]&lt;br /&gt;
* [[Power Distribution Tree 251213]]&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]]&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]]&lt;br /&gt;
* [[Mailcow SOGo: Creating Filters for Events, Approvals, and Organizational Emails]]&lt;br /&gt;
* [[Spoof Timezone Extension – Setup Guide for Comfac Staff]]&lt;br /&gt;
* [[Viber Focus-Stealing]]&lt;br /&gt;
* [[🌐 WordPress Website — *You Own Everything, Learn Everything*]]&lt;br /&gt;
* [[Portainer to Docker Compose Migration Guide]]&lt;br /&gt;
* [[Organizing Coder Terminals]] — Tmux + dynamic titles for managing multiple AI agent terminals&lt;br /&gt;
* [[Editing Mastodon Docker Deployment Guide 260402]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Storage &amp;amp; Hardware ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[TrueNAS Configuration Options &amp;amp; Scale Options 251130]]&lt;br /&gt;
* [[TrueNAS Business Plan: Project 251212]]&lt;br /&gt;
* [[Comparison: TrueNAS Mini X+ vs Dell Precision 3680 Tower (2025)]]&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification]]&lt;br /&gt;
* [[Industrial Controllers and Water Utilities 251011]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== AI &amp;amp; Machine Learning ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[OpenWebUI - 251128-justin]]&lt;br /&gt;
* [[Comfac GPU Scaling and AI Research Goals]]&lt;br /&gt;
* [[🧠 Process: Selecting and Installing the Right Ollama Model for Your Hardware]]&lt;br /&gt;
* [[Ollama GNOME System Tray Panel 260401]] — GNOME system tray toggle to start/stop Ollama and reclaim VRAM&lt;br /&gt;
* [[Proceedural Agentic Development Methodology 260304]] — Methodology for systematic agent use&lt;br /&gt;
* [[Project OpenCoder: AI Independence Initiative]] — Strategic roadmap for manufacturing intelligence&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 Modelfile fix for tool calling in OpenCode; thinking mode suppression; HDD vs SSD findings&lt;br /&gt;
* [[OpenCode Multi-Provider Configuration Guide 260401]] — Dual-mode AI coding setup with Kimi cloud + Ollama local models via Distrobox&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — Procedural Agentic Development for Frappe/ERPNext configuration and deployment&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Descriptions ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Job Descriptions]] — Index of all official job descriptions (IT, Engineering, Sales)&lt;br /&gt;
* [[JD IT Project Staff]] — IT Project Staff&lt;br /&gt;
* [[JD Security Compliance Assistant 260224]] — Security and Compliance Assistant (SCA)&lt;br /&gt;
* [[JD Engineering Designer 260108]] — Engineering Designer&lt;br /&gt;
* [[JD Engineering Supervisor 260109]] — Engineering Supervisor&lt;br /&gt;
* [[JD Technical Sales 260112]] — Technical Sales Engineer&lt;br /&gt;
* [[JD Marketing Assistant 251119]] — Marketing Assistant&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IT Operations &amp;amp; SOPs ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[SCA Program Plan 260320]] — Security &amp;amp; Compliance Assistant Program Plan v3 (ISO 9001/27001, PDCA, distributed audit model)&lt;br /&gt;
* [[SOP: Inter-Company Ordering and Production Process 260203]] — Ordering and production workflow between Sister Companies and the Cabuyao Plant&lt;br /&gt;
* [[Memo: Team Roles &amp;amp; Reporting Process Clarification 260320]] — Role boundaries, data ownership, and the new ERPNext-driven reporting paradigm&lt;br /&gt;
* [[Standard Operating Procedure: Distributed Minute Taking &amp;amp; Task Ownership 251208]]&lt;br /&gt;
* [[Business Continuity]]&lt;br /&gt;
* [[Procedure: CC-Blast Data Breach Prevention]]&lt;br /&gt;
* [[8D (Eight Discipline) Problem Solving Procedure]]&lt;br /&gt;
* [[Offline Malware Remediation &amp;amp; Data Recovery]]&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [[Steps to Repair and OCR a Scanned or Corrupted PDF in Ubuntu]]&lt;br /&gt;
* [[IT IMPORTS PROCESSES]]&lt;br /&gt;
* [[IT Purchase Requests 241126]]&lt;br /&gt;
* [[IT REQUEST (OP-ERP-ITR) - EDITED 250801]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sales &amp;amp; Business ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Comfac Sales Knowledge Base]]&lt;br /&gt;
* [[Comfac CRM – Customer Qualification &amp;amp; Conversion Process]]&lt;br /&gt;
* [[Partner Reseller Pricing 251109]]&lt;br /&gt;
* [[Biz Analysis Methodology 251109]]&lt;br /&gt;
* [[2026 MIS IT KRA KPI Biz Plan]]&lt;br /&gt;
* [[SALES INVOICE TAX OUTPUT 250829]]&lt;br /&gt;
* [[Projects in Process Report 251023]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools &amp;amp; Productivity ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Excel Description Filler Tool 📝]]&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/comfac-studies Comfac Studies - Spaced Repetiton Active Recall]&lt;br /&gt;
* [[LibreOffice / Nextcloud Office – &amp;quot;Due Tasks&amp;quot; Conditional Formatting]]&lt;br /&gt;
* [[Google Drive and Shared Drive Training]]&lt;br /&gt;
* [[260108 CGG- GitHub Administration Guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wiki &amp;amp; Documentation ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Mediawiki Setting Up Guide]]&lt;br /&gt;
* [[Contributing to Only Office 260307]]&lt;br /&gt;
* [[Mediawiki Additional Configuration]]&lt;br /&gt;
* [[Mediawiki Docker Migration Guide]]&lt;br /&gt;
* [[Home]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Claude Code Isolation and Burner Workflow 260211]] — Secure AI development environment setup&lt;br /&gt;
* [[Opencode isolation and burner workflow 260216]] — OpenCode CLI isolation procedures&lt;br /&gt;
* [[LibreOffice Calc NumToWords Extension Complete Guide]] — Extension development&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — ERPNext v15 local Docker setup (students, evaluators, thin-client demos)&lt;br /&gt;
* [[Erpnextv15-SSH-setup-241111]] — ERPNext v15 SSH/Portainer production setup&lt;br /&gt;
* [[Git-Mediawiki Local Editing 260223]] — Wiki editing with Git&lt;br /&gt;
* [[Understanding &amp;amp; Fixing Kernel Panics 260212]] — System debugging&lt;br /&gt;
* [[OpenCode in Android Termux 260303]] — OpenCode in Android&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 agentic setup: Modelfile, tool calling fix, storage impact&lt;br /&gt;
* [[Lora Basics 260304]] — LORA research&lt;br /&gt;
* [https://github.com/anomalyco/opencode/issues/4283#issuecomment-4083399210 Opencode Copy-paste Clipboard doesnt Work - Solution]   https://github.com/anomalyco/opencode/issues/4283#issuecomment-4083399210&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Research ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Ladybird Browser]] — Browser engine development&lt;br /&gt;
* [[Computing Architecture]] — System design principles&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification 260219]] — Drive reliability analysis&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== For Users Only ==&lt;br /&gt;
* [[Private:Private Ngani]]&lt;br /&gt;
* [[Private:Private Nganipart2]]&lt;br /&gt;
&lt;br /&gt;
== CIT-OJT Project Documentations ==&lt;br /&gt;
* [[OJTDocs: For OJTs only]]&lt;br /&gt;
&lt;br /&gt;
== Need Help? ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents MediaWiki User&#039;s Guide]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Organizing_Coder_Terminals&amp;diff=257</id>
		<title>Organizing Coder Terminals</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Organizing_Coder_Terminals&amp;diff=257"/>
		<updated>2026-05-02T07:27:04Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Updated: default title is now the command reminder &amp;#039;title &amp;quot;project&amp;quot;&amp;#039; (2026-05-02)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
When running multiple AI coding agents (Claude, Kimi, Qwen, OpenCode) in separate GNOME Terminal windows, every tab looks identical — usually titled by the running process name (e.g., &amp;quot;Kimi Code&amp;quot;). After opening 3–4 terminals, it becomes impossible to tell at a glance which terminal belongs to which project without clicking into each one.&lt;br /&gt;
&lt;br /&gt;
GNOME Terminal 3.44+ removed the &amp;quot;Set Title&amp;quot; option from the tab right-click menu, eliminating the old manual workaround.&lt;br /&gt;
&lt;br /&gt;
== Solution ==&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;tmux&#039;&#039;&#039; inside every terminal:&lt;br /&gt;
* One named tmux session per project (e.g., &amp;lt;code&amp;gt;claude&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;kimi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;qwen&amp;lt;/code&amp;gt;)&lt;br /&gt;
* A &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; bash command that renames both the tmux window and the terminal title&lt;br /&gt;
* Persistent panes — if an AI agent crashes, the pane stays alive and can be respawned&lt;br /&gt;
&lt;br /&gt;
== Quick Start ==&lt;br /&gt;
&lt;br /&gt;
=== Launch All Agents at Once ===&lt;br /&gt;
&lt;br /&gt;
Run on the Ubuntu desktop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
~/start_dev_env.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This opens 5 GNOME Terminal windows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Window Title !! Tmux Session !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Claude Code — tmux || claude || Claude Code AI agent&lt;br /&gt;
|-&lt;br /&gt;
| 2 || OpenCode Claude — tmux || opencode-claude || OpenCode (Claude provider)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || OpenCode Kimi — tmux || kimi || OpenCode (Kimi provider)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || OpenCode Qwen — tmux || qwen || OpenCode (Qwen provider)&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Tmux — General || general || Plain bash for git, docker, file ops&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each session survives even if the GNOME Terminal window is closed.&lt;br /&gt;
&lt;br /&gt;
=== Launch Individual Agents ===&lt;br /&gt;
&lt;br /&gt;
Double-click any desktop launcher:&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/claude.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/kimi.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/opencode.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/Qwen.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each launcher auto-creates or reattaches to its tmux session.&lt;br /&gt;
&lt;br /&gt;
== How to Title Your Session ==&lt;br /&gt;
&lt;br /&gt;
=== The Default Title Is the Command Itself ===&lt;br /&gt;
&lt;br /&gt;
Every new terminal opens with the title:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
title &amp;quot;project&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is intentional — the &#039;&#039;&#039;default title is the command reminder&#039;&#039;&#039;. You never forget the syntax because it&#039;s staring at you from the tab.&lt;br /&gt;
&lt;br /&gt;
=== Change It ===&lt;br /&gt;
&lt;br /&gt;
Inside any terminal, type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
title &amp;quot;ce char gen&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This does two things:&lt;br /&gt;
# Renames the tmux window (visible in the green status bar at the bottom)&lt;br /&gt;
# Sets the GNOME Terminal tab/window title&lt;br /&gt;
&lt;br /&gt;
Change it anytime:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
title &amp;quot;mneme shipgen&amp;quot;&lt;br /&gt;
title &amp;quot;IT-knowledge docs&amp;quot;&lt;br /&gt;
title &amp;quot;$(hostname)&amp;quot;   # reset to hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The title auto-resets after every shell prompt, so AI agents cannot overwrite it.&lt;br /&gt;
&lt;br /&gt;
=== Tmux-Only Renaming ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tmux rename-window &amp;quot;my project&amp;quot;     # rename current window&lt;br /&gt;
tmux rename-session &amp;quot;newname&amp;quot;       # rename entire session&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Key Shortcuts ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b , || Rename current window (interactive prompt)&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b r || Respawn pane (restart AI agent if it crashed)&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b d || Detach session (keeps it running in background)&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b | || Split pane horizontally&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b - || Split pane vertically&lt;br /&gt;
|-&lt;br /&gt;
| Alt+Arrow || Switch panes&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b R || Reload tmux config&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Reattaching to Sessions ==&lt;br /&gt;
&lt;br /&gt;
If a terminal window is closed, the tmux session keeps running:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tmux list-sessions&lt;br /&gt;
tmux attach-session -t claude&lt;br /&gt;
tmux attach-session -t kimi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aliases added to &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tls     # list sessions&lt;br /&gt;
tas claude    # attach to claude session&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuration Files ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! File !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.tmux.conf&amp;lt;/code&amp;gt; || Tmux settings (status bar, mouse, key bindings)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;title()&amp;lt;/code&amp;gt; function + auto-reset + tmux aliases&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.config/tmux-launcher.sh&amp;lt;/code&amp;gt; || Helper script for desktop launchers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Symptom !! Cause !! Fix&lt;br /&gt;
|-&lt;br /&gt;
| Title shows &amp;quot;Kimi Code&amp;quot; instead of custom || AI resets it via escape sequences || &amp;lt;code&amp;gt;PROMPT_COMMAND&amp;lt;/code&amp;gt; auto-resets after every prompt&lt;br /&gt;
|-&lt;br /&gt;
| Tab right-click has no &amp;quot;Set Title&amp;quot; || GNOME Terminal 3.44+ removed it || Use &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; bash command or &amp;lt;code&amp;gt;Ctrl+b ,&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; command not found || &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; not loaded || Start an interactive shell, or run &amp;lt;code&amp;gt;source ~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Default title shows &amp;lt;code&amp;gt;title &amp;quot;project&amp;quot;&amp;lt;/code&amp;gt; || Working as designed — it&#039;s the syntax reminder || Type &amp;lt;code&amp;gt;title &amp;quot;your real project&amp;quot;&amp;lt;/code&amp;gt; to replace it&lt;br /&gt;
|-&lt;br /&gt;
| AI agent crashed and pane is dead || Process exited || Press &amp;lt;code&amp;gt;Ctrl+b r&amp;lt;/code&amp;gt; to respawn&lt;br /&gt;
|-&lt;br /&gt;
| Session already exists || Previous session still running || &amp;lt;code&amp;gt;tmux attach -t &amp;amp;lt;name&amp;amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;tmux kill-session -t &amp;amp;lt;name&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[IT Knowledge Base]]&lt;br /&gt;
* [[Forgejo]]&lt;br /&gt;
* [[Docker Stacks]]&lt;br /&gt;
&lt;br /&gt;
[[Category:System Administration]]&lt;br /&gt;
[[Category:Development Environment]]&lt;br /&gt;
[[Category:AI Agents]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Organizing_Coder_Terminals&amp;diff=256</id>
		<title>Organizing Coder Terminals</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Organizing_Coder_Terminals&amp;diff=256"/>
		<updated>2026-05-02T07:09:30Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created article on organizing coder terminals with tmux (2026-05-02)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
When running multiple AI coding agents (Claude, Kimi, Qwen, OpenCode) in separate GNOME Terminal windows, every tab looks identical — usually titled by the running process name (e.g., &amp;quot;Kimi Code&amp;quot;). After opening 3–4 terminals, it becomes impossible to tell at a glance which terminal belongs to which project without clicking into each one.&lt;br /&gt;
&lt;br /&gt;
GNOME Terminal 3.44+ removed the &amp;quot;Set Title&amp;quot; option from the tab right-click menu, eliminating the old manual workaround.&lt;br /&gt;
&lt;br /&gt;
== Solution ==&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;tmux&#039;&#039;&#039; inside every terminal:&lt;br /&gt;
* One named tmux session per project (e.g., &amp;lt;code&amp;gt;claude&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;kimi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;qwen&amp;lt;/code&amp;gt;)&lt;br /&gt;
* A &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; bash command that renames both the tmux window and the terminal title&lt;br /&gt;
* Persistent panes — if an AI agent crashes, the pane stays alive and can be respawned&lt;br /&gt;
&lt;br /&gt;
== Quick Start ==&lt;br /&gt;
&lt;br /&gt;
=== Launch All Agents at Once ===&lt;br /&gt;
&lt;br /&gt;
Run on the Ubuntu desktop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
~/start_dev_env.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This opens 5 GNOME Terminal windows:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! # !! Window Title !! Tmux Session !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Claude Code — tmux || claude || Claude Code AI agent&lt;br /&gt;
|-&lt;br /&gt;
| 2 || OpenCode Claude — tmux || opencode-claude || OpenCode (Claude provider)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || OpenCode Kimi — tmux || kimi || OpenCode (Kimi provider)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || OpenCode Qwen — tmux || qwen || OpenCode (Qwen provider)&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Tmux — General || general || Plain bash for git, docker, file ops&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each session survives even if the GNOME Terminal window is closed.&lt;br /&gt;
&lt;br /&gt;
=== Launch Individual Agents ===&lt;br /&gt;
&lt;br /&gt;
Double-click any desktop launcher:&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/claude.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/kimi.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/opencode.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;~/Desktop/Qwen.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each launcher auto-creates or reattaches to its tmux session.&lt;br /&gt;
&lt;br /&gt;
== How to Title Your Session ==&lt;br /&gt;
&lt;br /&gt;
Inside any terminal, type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
title &amp;quot;ce char gen&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This does two things:&lt;br /&gt;
# Renames the tmux window (visible in the green status bar at the bottom)&lt;br /&gt;
# Sets the GNOME Terminal tab/window title&lt;br /&gt;
&lt;br /&gt;
Change it anytime:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
title &amp;quot;mneme shipgen&amp;quot;&lt;br /&gt;
title &amp;quot;IT-knowledge docs&amp;quot;&lt;br /&gt;
title &amp;quot;$(hostname)&amp;quot;   # reset to hostname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The title auto-resets after every shell prompt, so AI agents cannot overwrite it.&lt;br /&gt;
&lt;br /&gt;
=== Tmux-Only Renaming ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tmux rename-window &amp;quot;my project&amp;quot;     # rename current window&lt;br /&gt;
tmux rename-session &amp;quot;newname&amp;quot;       # rename entire session&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Key Shortcuts ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b , || Rename current window (interactive prompt)&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b r || Respawn pane (restart AI agent if it crashed)&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b d || Detach session (keeps it running in background)&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b | || Split pane horizontally&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b - || Split pane vertically&lt;br /&gt;
|-&lt;br /&gt;
| Alt+Arrow || Switch panes&lt;br /&gt;
|-&lt;br /&gt;
| Ctrl+b R || Reload tmux config&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Reattaching to Sessions ==&lt;br /&gt;
&lt;br /&gt;
If a terminal window is closed, the tmux session keeps running:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tmux list-sessions&lt;br /&gt;
tmux attach-session -t claude&lt;br /&gt;
tmux attach-session -t kimi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aliases added to &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tls     # list sessions&lt;br /&gt;
tas claude    # attach to claude session&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuration Files ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! File !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.tmux.conf&amp;lt;/code&amp;gt; || Tmux settings (status bar, mouse, key bindings)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.bashrc&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;title()&amp;lt;/code&amp;gt; function + auto-reset + tmux aliases&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.config/tmux-launcher.sh&amp;lt;/code&amp;gt; || Helper script for desktop launchers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Symptom !! Cause !! Fix&lt;br /&gt;
|-&lt;br /&gt;
| Title shows &amp;quot;Kimi Code&amp;quot; instead of custom || AI resets it via escape sequences || &amp;lt;code&amp;gt;PROMPT_COMMAND&amp;lt;/code&amp;gt; auto-resets after every prompt&lt;br /&gt;
|-&lt;br /&gt;
| Tab right-click has no &amp;quot;Set Title&amp;quot; || GNOME Terminal 3.44+ removed it || Use &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; bash command or &amp;lt;code&amp;gt;Ctrl+b ,&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| AI agent crashed and pane is dead || Process exited || Press &amp;lt;code&amp;gt;Ctrl+b r&amp;lt;/code&amp;gt; to respawn&lt;br /&gt;
|-&lt;br /&gt;
| Session already exists || Previous session still running || &amp;lt;code&amp;gt;tmux attach -t &amp;amp;lt;name&amp;amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;tmux kill-session -t &amp;amp;lt;name&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[IT Knowledge Base]]&lt;br /&gt;
* [[Forgejo]]&lt;br /&gt;
* [[Docker Stacks]]&lt;br /&gt;
&lt;br /&gt;
[[Category:System Administration]]&lt;br /&gt;
[[Category:Development Environment]]&lt;br /&gt;
[[Category:AI Agents]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Forgejo_Pages&amp;diff=255</id>
		<title>Forgejo Pages</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Forgejo_Pages&amp;diff=255"/>
		<updated>2026-04-28T13:24:36Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Added Forgejo Pages setup guide&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Forgejo Pages — Complete Setup Guide =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;**Wiki:** wiki.gi7b.org | **Last updated:** 2026-04-28&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;**Status:** Production — `pages.gi7b.org` live on PC03&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Forgejo does &#039;&#039;&#039;not&#039;&#039;&#039; have a built-in static site server. To serve Pages, you run a&lt;br /&gt;
separate &amp;lt;code&amp;gt;ronmi/forgejo-pages&amp;lt;/code&amp;gt; container alongside Forgejo. It reads files from a&lt;br /&gt;
special branch in each repo via the Forgejo API and serves them over HTTP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
Browser → Cloudflare DNS → NPM (SSL) → forgejo-pages:8080 → Forgejo API → repo branch&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* **Forgejo:** `https://git.gi7b.org` (container: `forgejo`, internal port 3000)&lt;br /&gt;
* **Pages server:** `https://pages.gi7b.org` (container: `forgejo-pages`, internal port 8080)&lt;br /&gt;
* **Routing:** path-based — `https://pages.gi7b.org/{owner}/{repo}/`&lt;br /&gt;
* **Branch name:** `static-pages` (exact, hardcoded default in this image)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Gotchas — Read This First ==&lt;br /&gt;
&lt;br /&gt;
=== 1. There is no built-in Pages in Forgejo ===&lt;br /&gt;
&amp;lt;code&amp;gt;ENABLE_FORGEJO_PAGES = true&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;app.ini&amp;lt;/code&amp;gt; does nothing. It is not a real setting.&lt;br /&gt;
You need the external &amp;lt;code&amp;gt;ronmi/forgejo-pages&amp;lt;/code&amp;gt; container.&lt;br /&gt;
&lt;br /&gt;
=== 2. Branch must be named exactly `static-pages` ===&lt;br /&gt;
Not &amp;lt;code&amp;gt;gh-pages&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;pages&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;static_pages&amp;lt;/code&amp;gt;. The image default is &amp;lt;code&amp;gt;static-pages&amp;lt;/code&amp;gt;.&lt;br /&gt;
If the branch doesn&#039;t exist in the repo, the server returns 404.&lt;br /&gt;
&lt;br /&gt;
=== 3. Use two separate tokens ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Token !! Scope !! Used by&lt;br /&gt;
|-&lt;br /&gt;
| `forgejo-pages` service token | `repository: read` | Docker container reads repo files via API&lt;br /&gt;
|-&lt;br /&gt;
| `git-push` personal token | `repository: read+write` + `user: read` | You/AI push code via git CLI&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Never use your account password for git CLI over HTTPS — it will be rejected.&lt;br /&gt;
&lt;br /&gt;
=== 4. NPM forward port is the internal container port ===&lt;br /&gt;
When NPM uses the container DNS name (&amp;lt;code&amp;gt;forgejo-pages&amp;lt;/code&amp;gt;), forward to port &amp;lt;code&amp;gt;8080&amp;lt;/code&amp;gt; (internal).&lt;br /&gt;
If using the host IP (&amp;lt;code&amp;gt;192.168.196.76&amp;lt;/code&amp;gt;), forward to port &amp;lt;code&amp;gt;8585&amp;lt;/code&amp;gt; (exposed host port).&lt;br /&gt;
Mixing these up causes 502 Bad Gateway.&lt;br /&gt;
&lt;br /&gt;
=== 5. Remove NPM Access List from git.gi7b.org ===&lt;br /&gt;
HTTP Basic Auth at the NPM layer blocks git CLI, API calls, and webhooks.&lt;br /&gt;
Forgejo&#039;s own auth (tokens, SSH keys, 2FA) is the correct security layer for a git host.&lt;br /&gt;
&lt;br /&gt;
=== 6. SSH is more reliable than HTTPS for git push ===&lt;br /&gt;
HTTPS git auth has multiple failure modes (token scopes, credential helpers, NPM layers).&lt;br /&gt;
SSH just works. Set it up once per machine and never deal with tokens for pushing again.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Docker Compose Setup ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;File:&#039;&#039;&#039; &amp;lt;code&amp;gt;/home/user/forgejo/compose.yml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  server:&lt;br /&gt;
    image: codeberg.org/forgejo/forgejo:13&lt;br /&gt;
    container_name: forgejo&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    environment:&lt;br /&gt;
      - USER_UID=1000&lt;br /&gt;
      - USER_GID=1000&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./data:/data&lt;br /&gt;
      - /etc/localtime:/etc/localtime:ro&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3001:3000&amp;quot;&lt;br /&gt;
      - &amp;quot;223:22&amp;quot;&lt;br /&gt;
    networks:&lt;br /&gt;
      - internal&lt;br /&gt;
      - proxy&lt;br /&gt;
&lt;br /&gt;
  pages:&lt;br /&gt;
    image: ronmi/forgejo-pages&lt;br /&gt;
    container_name: forgejo-pages&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    command: serve --server http://forgejo:3000 --token ${FORGEJO_PAGES_TOKEN} --bind :8080&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;8585:8080&amp;quot;&lt;br /&gt;
    networks:&lt;br /&gt;
      - internal&lt;br /&gt;
      - proxy&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - server&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  internal:&lt;br /&gt;
    driver: bridge&lt;br /&gt;
  proxy:&lt;br /&gt;
    external: true&lt;br /&gt;
    name: npm_proxy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;File:&#039;&#039;&#039; &amp;lt;code&amp;gt;/home/user/forgejo/.env&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
FORGEJO_PAGES_TOKEN=your_read_only_repository_token_here&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Tokens ==&lt;br /&gt;
&lt;br /&gt;
=== Service Token (for forgejo-pages container) ===&lt;br /&gt;
Generated in Forgejo → Settings → Applications:&lt;br /&gt;
* **Name:** `forgejo-pages-service`&lt;br /&gt;
* **Repository and Organization Access:** All&lt;br /&gt;
* **Permissions:** `repository: Read` only, everything else No access&lt;br /&gt;
* Goes in `/home/user/forgejo/.env` as `FORGEJO_PAGES_TOKEN`&lt;br /&gt;
&lt;br /&gt;
=== Personal Push Token (for git CLI / AI agents) ===&lt;br /&gt;
Generated in Forgejo → Settings → Applications:&lt;br /&gt;
* **Name:** `git-push-{machinename}`&lt;br /&gt;
* **Repository and Organization Access:** All&lt;br /&gt;
* **Permissions:** `repository: Read and Write`, `user: Read`, everything else No access&lt;br /&gt;
* Used as the **password** when git prompts, or embedded in SSH-less workflows&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== NPM Proxy Host — pages.gi7b.org ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Details tab:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Domain Names | `pages.gi7b.org`&lt;br /&gt;
|-&lt;br /&gt;
| Scheme | `http`&lt;br /&gt;
|-&lt;br /&gt;
| Forward Hostname / IP | `forgejo-pages` (container name) OR `192.168.196.76` (host IP)&lt;br /&gt;
|-&lt;br /&gt;
| Forward Port | `8080` if using container name / `8585` if using host IP&lt;br /&gt;
|-&lt;br /&gt;
| Cache Assets | ✅ On&lt;br /&gt;
|-&lt;br /&gt;
| Block Common Exploits | ✅ On&lt;br /&gt;
|-&lt;br /&gt;
| Websockets Support | Off&lt;br /&gt;
|-&lt;br /&gt;
| Access List | **Publicly Accessible** (no HTTP Basic Auth)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SSL tab:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| SSL Certificate | `pages.gi7b.org` (Let&#039;s Encrypt)&lt;br /&gt;
|-&lt;br /&gt;
| Force SSL | ✅ On&lt;br /&gt;
|-&lt;br /&gt;
| HTTP/2 Support | ✅ On&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== SSH Setup for Git Push (per machine) ==&lt;br /&gt;
&lt;br /&gt;
Run once on each machine that needs to push to Forgejo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Generate key&lt;br /&gt;
ssh-keygen -t ed25519 -C &amp;quot;{machinename}-git&amp;quot; -f ~/.ssh/id_ed25519 -N &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Show public key to add to Forgejo&lt;br /&gt;
cat ~/.ssh/id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the public key in Forgejo → Settings → SSH / GPG Keys → Add Key.&lt;br /&gt;
&lt;br /&gt;
Set remote URL to SSH (note custom port 223):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git remote set-url origin ssh://git@192.168.196.76:223/{owner}/{repo}.git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Use the ZeroTier IP `192.168.196.76` directly — port 223 is not forwarded through&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;the public relay (PC06). SSH over ZeroTier is reliable for internal machines.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;For external machines, either forward port 223 through PC06 or use HTTPS with a token.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Publishing a Page (Repeatable Workflow) ==&lt;br /&gt;
&lt;br /&gt;
=== New repo — first time ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git clone ssh://git@192.168.196.76:223/{owner}/{repo}.git&lt;br /&gt;
cd {repo}&lt;br /&gt;
&lt;br /&gt;
# Create orphan branch (no shared history with main)&lt;br /&gt;
git checkout --orphan static-pages&lt;br /&gt;
git rm -rf . 2&amp;gt;/dev/null || true&lt;br /&gt;
&lt;br /&gt;
# Create your site&lt;br /&gt;
mkdir -p .&lt;br /&gt;
cat &amp;gt; index.html &amp;lt;&amp;lt;&#039;EOF&#039;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&amp;lt;title&amp;gt;My Page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Hello from Forgejo Pages&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
git add .&lt;br /&gt;
git commit -m &amp;quot;Initial pages content&amp;quot;&lt;br /&gt;
git push -u origin static-pages&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Live immediately at: &amp;lt;code&amp;gt;https://pages.gi7b.org/{owner}/{repo}/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Update existing pages ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git checkout static-pages&lt;br /&gt;
# edit files&lt;br /&gt;
git add .&lt;br /&gt;
git commit -m &amp;quot;Update pages&amp;quot;&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Via Forgejo Web UI (no git needed) ===&lt;br /&gt;
&lt;br /&gt;
1. Open repo → click &#039;&#039;&#039;New File&#039;&#039;&#039;&lt;br /&gt;
2. Filename: &amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt;, add content&lt;br /&gt;
3. In commit section: select &#039;&#039;&#039;&amp;quot;Create a new branch&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
4. Branch name: &amp;lt;code&amp;gt;static-pages&amp;lt;/code&amp;gt;&lt;br /&gt;
5. Commit&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Local test (on PC03)&lt;br /&gt;
curl -i http://localhost:8585/{owner}/{repo}/&lt;br /&gt;
&lt;br /&gt;
# Expected: HTTP/1.1 200 OK + your HTML&lt;br /&gt;
&lt;br /&gt;
# Check pages server logs&lt;br /&gt;
docker logs forgejo-pages --tail 20&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Browser: &amp;lt;code&amp;gt;https://pages.gi7b.org/{owner}/{repo}/&amp;lt;/code&amp;gt; (trailing slash matters)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Symptom !! Cause !! Fix&lt;br /&gt;
|-&lt;br /&gt;
| 400 Bad Request | No valid owner/repo path in URL | URL must be `/{owner}/{repo}/`&lt;br /&gt;
|-&lt;br /&gt;
| 404 Not Found | `static-pages` branch missing or no `index.html` at root | Create branch, push `index.html` to root&lt;br /&gt;
|-&lt;br /&gt;
| 502 Bad Gateway | NPM port mismatch or container not on `npm_proxy` network | Check forward port (8080 internal / 8585 host). Verify: `docker network inspect npm_proxy \ | grep forgejo`&lt;br /&gt;
|-&lt;br /&gt;
| Auth failed (git push) | Wrong token scope or using account password | Use personal push token with `repository: write`. Use SSH instead.&lt;br /&gt;
|-&lt;br /&gt;
| SSH connection refused | Port 223 not reachable from external machine | Use ZeroTier IP for internal machines. Forward port via PC06 for external.&lt;br /&gt;
|-&lt;br /&gt;
| Pages container crash-looping | Missing `serve` command or bad token | Check `docker logs forgejo-pages`. Verify `.env` token is correct.&lt;br /&gt;
|-&lt;br /&gt;
| Stale content | Browser cache | Hard refresh (Ctrl+Shift+R) or test with `curl`&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Buzz_Transcription&amp;diff=254</id>
		<title>Buzz Transcription</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Buzz_Transcription&amp;diff=254"/>
		<updated>2026-04-24T18:43:50Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Add Buzz meeting transcription guide + Vulkan GPU &amp;amp; OOM investigation (2026-04-25)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Buzz is an open-source, offline-capable audio/meeting transcription tool powered by OpenAI Whisper (via whisper.cpp). On this system it is installed as a Flatpak and runs with Vulkan GPU acceleration on the AMD RX 7600.&lt;br /&gt;
&lt;br /&gt;
== How to Transcribe a Meeting ==&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Buzz installed (Flatpak: &amp;lt;code&amp;gt;io.github.chidiwilliams.Buzz&amp;lt;/code&amp;gt;)&lt;br /&gt;
* A model downloaded — recommended: &amp;lt;code&amp;gt;ggml-large-v3-turbo&amp;lt;/code&amp;gt; for quality, &amp;lt;code&amp;gt;ggml-tiny&amp;lt;/code&amp;gt; for speed&lt;br /&gt;
* Models are stored at &amp;lt;code&amp;gt;~/.var/app/io.github.chidiwilliams.Buzz/cache/Buzz/models/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Transcription (Meeting Recording) ===&lt;br /&gt;
# Launch Buzz from the application menu or run: &amp;lt;code&amp;gt;flatpak run io.github.chidiwilliams.Buzz&amp;lt;/code&amp;gt;&lt;br /&gt;
# Go to &#039;&#039;&#039;File → Import Media&#039;&#039;&#039; and select your meeting recording (MP3, WAV, M4A, etc.)&lt;br /&gt;
# In the transcription dialog:&lt;br /&gt;
#* &#039;&#039;&#039;Model&#039;&#039;&#039;: Select &amp;lt;code&amp;gt;large-v3-turbo&amp;lt;/code&amp;gt; (best quality for meetings)&lt;br /&gt;
#* &#039;&#039;&#039;Task&#039;&#039;&#039;: Transcribe&lt;br /&gt;
#* &#039;&#039;&#039;Language&#039;&#039;&#039;: Select your language or leave on Auto&lt;br /&gt;
#* &#039;&#039;&#039;Extract Speech&#039;&#039;&#039;: &#039;&#039;&#039;Leave unchecked&#039;&#039;&#039; for files longer than ~30 minutes (see [[#OOM Crash with Large Files|OOM Crash]] below)&lt;br /&gt;
#* &#039;&#039;&#039;Output&#039;&#039;&#039;: SRT, VTT, or TXT depending on your need&lt;br /&gt;
# Click &#039;&#039;&#039;Transcribe&#039;&#039;&#039;&lt;br /&gt;
# When complete, the transcript appears in the main window and is saved alongside the source file&lt;br /&gt;
&lt;br /&gt;
=== Live Transcription (Real-Time) ===&lt;br /&gt;
# Go to &#039;&#039;&#039;File → Record and Transcribe&#039;&#039;&#039;&lt;br /&gt;
# Select your microphone input&lt;br /&gt;
# Choose model and language&lt;br /&gt;
# Click &#039;&#039;&#039;Record&#039;&#039;&#039; — transcription appears live on screen&lt;br /&gt;
# Stop recording when done; export via &#039;&#039;&#039;File → Export&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Recommended Settings for Meetings ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Value !! Reason&lt;br /&gt;
|-&lt;br /&gt;
| Model || large-v3-turbo || Best accuracy; 1.6 GB VRAM, runs on RX 7600&lt;br /&gt;
|-&lt;br /&gt;
| Extract Speech || &#039;&#039;&#039;Off&#039;&#039;&#039; for files &amp;amp;gt;30 min || Demucs uses 8–15 GB RAM for long files (OOM risk)&lt;br /&gt;
|-&lt;br /&gt;
| Language || Set explicitly || Faster than auto-detect&lt;br /&gt;
|-&lt;br /&gt;
| Task || Transcribe || Use Translate only if you need English output from another language&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Before Each Session: Clear Swap ===&lt;br /&gt;
Prior transcription sessions can leave stale pages in swap. Run this before starting a long transcription:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo swapoff -a &amp;amp;&amp;amp; sudo swapon -a&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is safe when free RAM exceeds swap used (typical on this system: 15+ GB free, 8 GB swap).&lt;br /&gt;
&lt;br /&gt;
== GPU Acceleration ==&lt;br /&gt;
&lt;br /&gt;
Buzz&#039;s Flatpak installation includes a Vulkan-enabled &amp;lt;code&amp;gt;whisper-cli&amp;lt;/code&amp;gt;. On this system, GPU inference is automatically active — no configuration needed.&lt;br /&gt;
&lt;br /&gt;
* GPU in use: &#039;&#039;&#039;AMD RX 7600 (RDNA3, RADV NAVI33)&#039;&#039;&#039;&lt;br /&gt;
* Confirmed by: &amp;lt;code&amp;gt;whisper_backend_init_gpu: using Vulkan0 backend&amp;lt;/code&amp;gt; in runtime output&lt;br /&gt;
* Buzz checks for Vulkan at startup (&amp;lt;code&amp;gt;IS_VULKAN_SUPPORTED&amp;lt;/code&amp;gt;) and omits the &amp;lt;code&amp;gt;--no-gpu&amp;lt;/code&amp;gt; flag when found&lt;br /&gt;
&lt;br /&gt;
To force CPU inference (for debugging):&lt;br /&gt;
&amp;lt;pre&amp;gt;flatpak override --user io.github.chidiwilliams.Buzz --env=BUZZ_FORCE_CPU=true&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To revert:&lt;br /&gt;
&amp;lt;pre&amp;gt;flatpak override --user --reset io.github.chidiwilliams.Buzz&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OOM Crash with Large Files ==&lt;br /&gt;
&lt;br /&gt;
=== Symptom ===&lt;br /&gt;
When selecting &amp;lt;code&amp;gt;ggml-large-v3-turbo&amp;lt;/code&amp;gt; in Buzz and starting a transcription on a long file, the application crashes. VRAM usage never visibly climbs before the crash.&lt;br /&gt;
&lt;br /&gt;
=== Root Cause ===&lt;br /&gt;
The crash is caused by the &#039;&#039;&#039;Extract Speech (Demucs)&#039;&#039;&#039; pre-processing step, not the large model.&lt;br /&gt;
&lt;br /&gt;
Demucs is a PyTorch-based music source separation model that strips background noise from audio before passing it to the transcription engine. It processes raw PCM audio at full float32 precision entirely in RAM:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Audio Duration !! Compressed Size !! RAM Required (Demucs)&lt;br /&gt;
|-&lt;br /&gt;
| 1 hour MP3 || ~60 MB || 500 MB – 1 GB&lt;br /&gt;
|-&lt;br /&gt;
| 3–4 hour session || ~220 MB || 8–15 GB peak&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The combination that caused the crash:&lt;br /&gt;
# Swap already exhausted from previous sessions&lt;br /&gt;
# Extract Speech (Demucs) triggered on a ~220 MB MP3 (~3–4 hours of audio)&lt;br /&gt;
# Python RAM usage exceeded available RAM + swap ceiling&lt;br /&gt;
# OOM killer terminated the process at 22 GB RSS&lt;br /&gt;
# &amp;lt;code&amp;gt;whisper-cli&amp;lt;/code&amp;gt; was never launched → no VRAM activity observed&lt;br /&gt;
&lt;br /&gt;
=== Why VRAM Never Climbed ===&lt;br /&gt;
&amp;lt;code&amp;gt;whisper-cli&amp;lt;/code&amp;gt; runs as a subprocess of the Python GUI. The OOM kill happened during Demucs pre-processing — &amp;lt;code&amp;gt;whisper-cli&amp;lt;/code&amp;gt; was never started, so no VRAM allocation occurred.&lt;br /&gt;
&lt;br /&gt;
From the Buzz log at crash time:&lt;br /&gt;
&amp;lt;pre&amp;gt;~/.var/app/io.github.chidiwilliams.Buzz/.local/state/Buzz/log/logs.txt&amp;lt;/pre&amp;gt;&lt;br /&gt;
The last entry was &amp;lt;code&amp;gt;Will extract speech&amp;lt;/code&amp;gt; — the log never reached &amp;lt;code&amp;gt;Starting whisper file transcription&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Fix ===&lt;br /&gt;
&#039;&#039;&#039;Uncheck &amp;quot;Extract Speech&amp;quot;&#039;&#039;&#039; in the Buzz transcription dialog for any file longer than ~30 minutes. The &amp;lt;code&amp;gt;large-v3-turbo&amp;lt;/code&amp;gt; model has built-in noise tolerance that makes Demucs pre-processing unnecessary in most cases.&lt;br /&gt;
&lt;br /&gt;
Optionally, grow the swapfile if you need Extract Speech for shorter files:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo swapoff /swap.img&lt;br /&gt;
sudo fallocate -l 16G /swap.img&lt;br /&gt;
sudo mkswap /swap.img&lt;br /&gt;
sudo swapon /swap.img&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Environment Variables ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Default !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;BUZZ_FORCE_CPU&amp;lt;/code&amp;gt; || false || Set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; to disable GPU inference&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;BUZZ_WHISPERCPP_N_THREADS&amp;lt;/code&amp;gt; || cpu_count / 2 || Override thread count for whisper-cli&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Set via: &amp;lt;code&amp;gt;flatpak override --user io.github.chidiwilliams.Buzz --env=VAR=value&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Key File Paths ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Path !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/var/lib/flatpak/app/io.github.chidiwilliams.Buzz/.../buzz/whisper_cpp/whisper-cli&amp;lt;/code&amp;gt; || Bundled Vulkan whisper-cli (libwhisper 1.8.3)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.var/app/io.github.chidiwilliams.Buzz/cache/Buzz/models/&amp;lt;/code&amp;gt; || Buzz model cache (ggml binaries)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.var/app/io.github.chidiwilliams.Buzz/.local/state/Buzz/log/logs.txt&amp;lt;/code&amp;gt; || Buzz application log&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.var/app/io.github.chidiwilliams.Buzz/config/Buzz.conf&amp;lt;/code&amp;gt; || Buzz settings&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/whisper.cpp/build/bin/whisper-cli&amp;lt;/code&amp;gt; || Custom Vulkan-enabled whisper.cpp build&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/bin/whisper-cli-vulkan&amp;lt;/code&amp;gt; || Wrapper script for custom build (sets &amp;lt;code&amp;gt;LD_LIBRARY_PATH&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;~/.local/share/pipx/venvs/buzz-captions/lib/python3.12/site-packages/buzz/whisper_cpp/&amp;lt;/code&amp;gt; || pipx install whisper_cpp directory (directly modifiable)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Investigation Summary ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Question !! Finding&lt;br /&gt;
|-&lt;br /&gt;
| Is Buzz using the RX 7600? || &#039;&#039;&#039;Yes.&#039;&#039;&#039; &amp;lt;code&amp;gt;using Vulkan0 backend&amp;lt;/code&amp;gt; confirmed inside the Flatpak sandbox.&lt;br /&gt;
|-&lt;br /&gt;
| Was &amp;lt;code&amp;gt;--no-gpu&amp;lt;/code&amp;gt; being added? || &#039;&#039;&#039;No.&#039;&#039;&#039; &amp;lt;code&amp;gt;IS_VULKAN_SUPPORTED = True&amp;lt;/code&amp;gt; in the sandbox; flag is never appended.&lt;br /&gt;
|-&lt;br /&gt;
| Does the large model load correctly? || &#039;&#039;&#039;Yes.&#039;&#039;&#039; 1.6 GB to VRAM, transcribes in ~1.25s on a short clip.&lt;br /&gt;
|-&lt;br /&gt;
| What caused the crash? || &#039;&#039;&#039;Extract Speech (Demucs) OOM.&#039;&#039;&#039; Python killed at 22 GB RSS before whisper-cli launched.&lt;br /&gt;
|-&lt;br /&gt;
| Why was VRAM not climbing? || &amp;lt;code&amp;gt;whisper-cli&amp;lt;/code&amp;gt; was never started — process died during Demucs pre-processing.&lt;br /&gt;
|-&lt;br /&gt;
| Fix? || &#039;&#039;&#039;Uncheck Extract Speech&#039;&#039;&#039; for long files. Clear swap before sessions.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Investigation date: 2026-04-25. System: Ubuntu 24.04, AMD RX 7600, Buzz 1.4.4 (Flatpak).&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=PfSense_Sales_Training_Material&amp;diff=253</id>
		<title>PfSense Sales Training Material</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=PfSense_Sales_Training_Material&amp;diff=253"/>
		<updated>2026-04-23T11:59:49Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Restructure: client-friendly networking table, expand myths section, add 5-Pillar Scoping Framework&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= pfSense Sales Training Material =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reference:&#039;&#039;&#039; [https://chatgpt.com/share/67c82515-7074-800e-b29c-0df75f5492f3 Full Session Log]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 1. Introduction ==&lt;br /&gt;
&lt;br /&gt;
; Objective&lt;br /&gt;
: Provide a clear, layman-friendly explanation of what a firewall is, why pfSense is a powerful solution, and how its key features protect networks.&lt;br /&gt;
&lt;br /&gt;
; Audience&lt;br /&gt;
: Sales teams, marketing, and non-technical staff who need to explain the technology to potential customers — non-technical decision-makers, IT managers, and SMB owners.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 2. Network Basics ==&lt;br /&gt;
&lt;br /&gt;
; Definition&lt;br /&gt;
: Networking is the ability to connect computers and systems together. It occurs when more than one device communicates with another device or group of devices.&lt;br /&gt;
&lt;br /&gt;
=== Networking Disciplines ===&lt;br /&gt;
&lt;br /&gt;
==== ECE (Electronics and Communication Engineering) ====&lt;br /&gt;
* Focuses on how electronic devices work and on designing/building network hardware from basic components.&lt;br /&gt;
* In the Philippines, a PRC ECE license is required to sign off plans for CCTV installations — the only legally mandated network designs (CCTV and phone lines).&lt;br /&gt;
* &#039;&#039;&#039;Sales Note:&#039;&#039;&#039; Clients needing custom electronic solutions (for automation or high-security requirements) will require ECE expertise.&lt;br /&gt;
&lt;br /&gt;
==== IT (Information Technology) ====&lt;br /&gt;
* Specializes in deploying and integrating off-the-shelf networking equipment.&lt;br /&gt;
* Advanced configurations improve reliability, scalability (hundreds to thousands of users), and automation for convenience.&lt;br /&gt;
* &#039;&#039;&#039;Sales Note:&#039;&#039;&#039; Larger-scale deployments and convenience features command higher-level IT skills and corresponding investment.&lt;br /&gt;
&lt;br /&gt;
=== Networking Functions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Function&lt;br /&gt;
! What This Means for Your Business&lt;br /&gt;
! Technical Role&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Connecting to the Internet&#039;&#039;&#039;&amp;lt;br/&amp;gt;(WAN — Wide Area Network)&lt;br /&gt;
| Your business&#039;s door to the outside world — controls what comes in and what goes out.&lt;br /&gt;
| Connects the facility to external networks (Internet or other sites).&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Connecting Your Devices Together&#039;&#039;&#039;&amp;lt;br/&amp;gt;(LAN — Local Area Network)&lt;br /&gt;
| Lets computers, printers, servers, and phones talk to each other inside your office.&lt;br /&gt;
| Connects devices within the facility for internal communications.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Staying Online Even When Hardware Fails&#039;&#039;&#039;&amp;lt;br/&amp;gt;(High Availability)&lt;br /&gt;
| Prevents downtime — if one device fails, another takes over automatically.&lt;br /&gt;
| Builds redundancy and resilience so services stay online despite failures.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Controlling Who Can Access What&#039;&#039;&#039;&amp;lt;br/&amp;gt;(User Management)&lt;br /&gt;
| Staff, guests, and contractors each see only what they&#039;re supposed to see.&lt;br /&gt;
| Implements captive portals, LDAP, RADIUS to organize users by roles and privileges.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Protecting Against Attacks and Breaches&#039;&#039;&#039;&amp;lt;br/&amp;gt;(Security)&lt;br /&gt;
| Keeps threats out and sensitive data in — separates risky zones from critical systems.&lt;br /&gt;
| Establishes hardened systems using DMZs (buffer zones) and proxy servers.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Wireless Connectivity&#039;&#039;&#039;&amp;lt;br/&amp;gt;(Wi-Fi)&lt;br /&gt;
| Lets staff and devices connect without cables — can be segmented by department or role.&lt;br /&gt;
| Deploys mesh or enterprise Wi-Fi for convenient, flexible connectivity.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Wired Connectivity&#039;&#039;&#039;&amp;lt;br/&amp;gt;(Ethernet/LAN Cabling)&lt;br /&gt;
| High-speed, reliable connections for servers, workstations, and critical equipment.&lt;br /&gt;
| Provides high-bandwidth, low-latency connections for critical systems.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 3. Key Myths &amp;amp; Objections ==&lt;br /&gt;
&lt;br /&gt;
Understanding and countering these objections is critical in every sales conversation.&lt;br /&gt;
&lt;br /&gt;
=== Myth 1: &amp;quot;We&#039;re too small — we don&#039;t need a firewall&amp;quot; ===&lt;br /&gt;
; Reality&lt;br /&gt;
: Small and medium businesses are the most targeted precisely because attackers know they have weak defenses. Anyone hosting a web server, NAS, ERP system, or remote workers needs a firewall. Size is not protection.&lt;br /&gt;
&lt;br /&gt;
=== Myth 2: &amp;quot;Our ISP router/modem is enough&amp;quot; ===&lt;br /&gt;
; Reality&lt;br /&gt;
: ISP-provided routers are consumer-grade equipment with no intrusion detection, no network segmentation, no VPN capability, and no traffic monitoring. They are designed for convenience, not security.&lt;br /&gt;
&lt;br /&gt;
=== Myth 3: &amp;quot;Firewalls only block traffic&amp;quot; ===&lt;br /&gt;
; Reality&lt;br /&gt;
: Modern firewalls do far more — they segment your network into zones, prioritize critical traffic (e.g., video calls over casual browsing), detect intrusions in real time, and enable secure VPN access for remote workers.&lt;br /&gt;
&lt;br /&gt;
=== Myth 4: &amp;quot;A VPN is all the security I need&amp;quot; ===&lt;br /&gt;
; Reality&lt;br /&gt;
: A VPN only encrypts traffic between two points. It does nothing to protect your internal network from threats already inside, compromised devices, or unauthorized users on-site.&lt;br /&gt;
&lt;br /&gt;
=== Myth 5: &amp;quot;The cloud handles our security&amp;quot; ===&lt;br /&gt;
; Reality&lt;br /&gt;
: Cloud providers secure their own infrastructure. Your office network, on-site devices, servers, and traffic between locations remain entirely your responsibility.&lt;br /&gt;
&lt;br /&gt;
=== Myth 6: &amp;quot;Hardware firewalls are different from software firewalls&amp;quot; ===&lt;br /&gt;
; Reality&lt;br /&gt;
: All firewalls are computers running software. A &amp;quot;hardware firewall&amp;quot; is simply dedicated hardware optimized to run firewall software. Performance scales by upgrading network interface cards: 100 Mbps → 1 Gbps → 10 Gbps → 100 Gbps.&lt;br /&gt;
&lt;br /&gt;
=== Myth 7: &amp;quot;Competitor products are better out-of-the-box&amp;quot; ===&lt;br /&gt;
; Reality&lt;br /&gt;
: Competitors like Fortinet and Cisco lock key features behind annual licenses that expire. When you stop paying, features stop working. pfSense delivers enterprise-grade features permanently — only updates and support require payment.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 4. Why pfSense? ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Open Source:&#039;&#039;&#039; No recurring feature licenses; you pay only for support and updates. When support lapses, pfSense continues to work — only security updates stop.&lt;br /&gt;
* &#039;&#039;&#039;Enterprise Features:&#039;&#039;&#039;&lt;br /&gt;
** LAN/WAN routing and segmentation&lt;br /&gt;
** VPN (remote access and site-to-site)&lt;br /&gt;
** IDS/IPS (intrusion detection and prevention)&lt;br /&gt;
** High Availability &amp;amp; Load Balancing&lt;br /&gt;
** DHCP, DNS, and user Authentication&lt;br /&gt;
* &#039;&#039;&#039;No License Lock-in:&#039;&#039;&#039; Other vendors &amp;quot;rent&amp;quot; features that expire with licenses. pfSense features remain available indefinitely.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 5. Core Functions &amp;amp; Features ==&lt;br /&gt;
&lt;br /&gt;
=== Primary Functions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Function&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;LAN&#039;&#039;&#039;&lt;br /&gt;
| Segments and protects internal network traffic to enforce security zones.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;WAN&#039;&#039;&#039;&lt;br /&gt;
| Controls access to the Internet; filters inbound/outbound traffic.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;VPN&#039;&#039;&#039;&lt;br /&gt;
| Creates encrypted tunnels for secure remote access or site-to-site links.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;IDS/IPS&#039;&#039;&#039;&lt;br /&gt;
| Monitors traffic for threats and automatically blocks or alerts on intrusions.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Secondary Features ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Integrates with Active Directory, LDAP, RADIUS for user-based firewall policies.&lt;br /&gt;
* &#039;&#039;&#039;DHCP:&#039;&#039;&#039; Assigns IP addresses automatically to devices on the network.&lt;br /&gt;
* &#039;&#039;&#039;DNS:&#039;&#039;&#039; Acts as resolver or forwarder to improve name lookup speed and security.&lt;br /&gt;
* &#039;&#039;&#039;Load Balancer / HA:&#039;&#039;&#039; Distributes traffic across multiple WAN links or appliances and provides failover.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 6. The 5-Pillar Scoping Framework ==&lt;br /&gt;
&lt;br /&gt;
Use this framework on every prospect conversation. Work through each pillar in order — each answer builds context for the next. The goal is to understand the client&#039;s situation before recommending any hardware or solution.&lt;br /&gt;
&lt;br /&gt;
=== Pillar 1: Stakes ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Budget equals stakes. Before pricing anything, establish what is at risk.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; Key Questions&lt;br /&gt;
: &amp;quot;What happens to your business if the network goes down for a full day?&amp;quot;&lt;br /&gt;
: &amp;quot;What data do you store or process — customer records, financial data, health information?&amp;quot;&lt;br /&gt;
: &amp;quot;Have you experienced a breach or outage before? What did it cost you?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
; What It Tells You&lt;br /&gt;
: The client&#039;s tolerance for risk and the true value of the protection being sold. A business that loses 50,000 PHP per hour of downtime has very different stakes than one running a small shared drive.&lt;br /&gt;
&lt;br /&gt;
; How It Maps to pfSense&lt;br /&gt;
: &#039;&#039;&#039;High stakes&#039;&#039;&#039; → High Availability setup, IDS/IPS, VLAN segmentation, full TAC support.&lt;br /&gt;
: &#039;&#039;&#039;Lower stakes&#039;&#039;&#039; → Single appliance, basic firewall rules, standard support.&lt;br /&gt;
&lt;br /&gt;
; Sales Note&lt;br /&gt;
: This pillar justifies the budget. Never skip it — without establishing stakes, you are selling on price alone and will always lose to the cheapest option.&lt;br /&gt;
&lt;br /&gt;
=== Pillar 2: Devices &amp;amp; Users ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Knowing the scale determines the hardware tier.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; Key Questions&lt;br /&gt;
: &amp;quot;How many staff members use the network daily?&amp;quot;&lt;br /&gt;
: &amp;quot;What devices are connected — computers, phones, tablets, IP cameras, printers, servers, POS terminals?&amp;quot;&lt;br /&gt;
: &amp;quot;Do you have remote workers or multiple office locations?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
; What It Tells You&lt;br /&gt;
: Scale of deployment, number of network interfaces needed, and whether user management features (captive portal, RADIUS) are required.&lt;br /&gt;
&lt;br /&gt;
; How It Maps to pfSense&lt;br /&gt;
: &amp;lt;10 users → Entry-level appliance.&lt;br /&gt;
: 10–100 users → Mid-range (Netgate 4200 series).&lt;br /&gt;
: 100–500 users → HA pair (2× Netgate 4200 MAX, ~120k PHP one-time).&lt;br /&gt;
: 500+ users or ISP → Netgate 6100 series or higher.&lt;br /&gt;
&lt;br /&gt;
=== Pillar 3: Bandwidth &amp;amp; Traffic ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Traffic type matters as much as raw speed.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; Key Questions&lt;br /&gt;
: &amp;quot;What is your current internet plan speed (download/upload)?&amp;quot;&lt;br /&gt;
: &amp;quot;What do people do on the network — video calls, large file transfers, cloud apps, IP cameras streaming 24/7?&amp;quot;&lt;br /&gt;
: &amp;quot;Do you have peak hours where the network slows down noticeably?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
; What It Tells You&lt;br /&gt;
: WAN capacity requirements, whether QoS (Quality of Service) is needed to prioritize traffic types, and the processing load for IDS/IPS inspection.&lt;br /&gt;
&lt;br /&gt;
; How It Maps to pfSense&lt;br /&gt;
: Heavy video/VoIP usage → QoS rules to prioritize real-time traffic.&lt;br /&gt;
: Heavy cloud usage → WAN load balancing for redundancy and speed.&lt;br /&gt;
: Many IP cameras → Dedicated VLAN and allocated bandwidth.&lt;br /&gt;
&lt;br /&gt;
=== Pillar 4: Hardware Compatibility ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Existing infrastructure must integrate — not be replaced.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; Key Questions&lt;br /&gt;
: &amp;quot;What servers do you have on-site — web servers, NAS, ERP, database?&amp;quot;&lt;br /&gt;
: &amp;quot;Do you have CCTV systems, POS terminals, VoIP phones, or other specialty devices?&amp;quot;&lt;br /&gt;
: &amp;quot;What network switches and access points are currently deployed?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
; What It Tells You&lt;br /&gt;
: VLAN design requirements, potential conflicts with existing devices, number of network interfaces needed, and whether any equipment requires a DMZ or special firewall rules.&lt;br /&gt;
&lt;br /&gt;
; How It Maps to pfSense&lt;br /&gt;
: &#039;&#039;&#039;NAS or web server&#039;&#039;&#039; → DMZ or isolated VLAN with strict inbound rules.&lt;br /&gt;
: &#039;&#039;&#039;CCTV system&#039;&#039;&#039; → Isolated VLAN with no internet access (security best practice).&lt;br /&gt;
: &#039;&#039;&#039;POS terminals&#039;&#039;&#039; → Segmented from general office traffic (PCI-DSS compliance).&lt;br /&gt;
: &#039;&#039;&#039;VoIP phones&#039;&#039;&#039; → Dedicated VLAN with QoS priority to prevent call drops.&lt;br /&gt;
&lt;br /&gt;
=== Pillar 5: Features &amp;amp; Functions Needed ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Match the pfSense feature set to the client&#039;s actual workflow.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; Key Questions&lt;br /&gt;
: &amp;quot;Do staff work remotely and need secure access to office systems?&amp;quot;&lt;br /&gt;
: &amp;quot;Do you have a second office location that needs to connect to the main office?&amp;quot;&lt;br /&gt;
: &amp;quot;Do guests or contractors need network access, separate from staff?&amp;quot;&lt;br /&gt;
: &amp;quot;Are there compliance requirements — PCI, HIPAA, data privacy laws?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
; What It Tells You&lt;br /&gt;
: Which pfSense features to highlight in the proposal and configure in the deployment.&lt;br /&gt;
&lt;br /&gt;
; How It Maps to pfSense&lt;br /&gt;
: Remote workers → VPN (OpenVPN or WireGuard).&lt;br /&gt;
: Multiple sites → Site-to-site VPN.&lt;br /&gt;
: Guest or contractor access → Captive portal with time or bandwidth limits.&lt;br /&gt;
: Compliance requirements → IDS/IPS, logging, VLAN segmentation, audit trails.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 7. Sizing &amp;amp; Total Cost of Ownership (TCO) ==&lt;br /&gt;
&lt;br /&gt;
=== Sizing Guidelines ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Company Size / Bandwidth&lt;br /&gt;
! Recommended Model&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Under 1 Gbps Internet&lt;br /&gt;
| Netgate 6100 Series&lt;br /&gt;
| Fits most small-to-medium offices&lt;br /&gt;
|-&lt;br /&gt;
| Up to 500 Users&lt;br /&gt;
| 2× Netgate 4200 MAX (HA setup)&lt;br /&gt;
| ~120k PHP one-time cost for both appliances&lt;br /&gt;
|-&lt;br /&gt;
| Large Networks / ISPs (&amp;gt;1 Gbps)&lt;br /&gt;
| Netgate 6100+ or higher&lt;br /&gt;
| Only ISPs or large enterprises need these models&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Example: Makati Office (200 Users) ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Hardware Cost:&#039;&#039;&#039; 2×4200 MAX for HA → &#039;&#039;&#039;120,000 PHP&#039;&#039;&#039; (one-time)&lt;br /&gt;
* &#039;&#039;&#039;Annual Costs:&#039;&#039;&#039;&lt;br /&gt;
** License Renewal: 7,500 PHP × 2 = &#039;&#039;&#039;15,000 PHP/year&#039;&#039;&#039;&lt;br /&gt;
** TAC Support: &#039;&#039;&#039;45,000 PHP/year&#039;&#039;&#039; (one needed in HA)&lt;br /&gt;
** Snort Subscription: 24,000 PHP × 2 = &#039;&#039;&#039;48,000 PHP/year&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;Total Annual: ~84,000 PHP/year&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Note|&#039;&#039;&#039;Competitor Comparison:&#039;&#039;&#039; Fortinet equivalent: 150k PHP hardware + 200k PHP/year support → pfSense is more cost-effective.}}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 8. Next Steps for Sales ==&lt;br /&gt;
&lt;br /&gt;
# Work through the [[#The 5-Pillar Scoping Framework|5-Pillar Scoping Framework]] with the client before recommending any hardware.&lt;br /&gt;
# Select the right appliance based on scoping output (6100 vs 4200 MAX vs higher models).&lt;br /&gt;
# Prepare TCO comparison (pfSense vs competitor).&lt;br /&gt;
# Send proposal template and service brochure.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Resources &amp;amp; References ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.comfac-it.com/services/netgate-pfsense-setup Setup Services]&lt;br /&gt;
* [https://www.comfac-it.com/blog-post/making-sense-of-unified-threat-management-utm UTM Deep Dive]&lt;br /&gt;
* [https://www.pfsense.org/products/ Netgate Product Info]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=PfSense_Training_Project_Tracker&amp;diff=252</id>
		<title>PfSense Training Project Tracker</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=PfSense_Training_Project_Tracker&amp;diff=252"/>
		<updated>2026-04-23T10:43:07Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Update Phase 1: Decision made to use dedicated training machine instead of 200-core server; add hardware selection tasks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#fff8e1; border:1px solid #ffcc80; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Project Tracker&#039;&#039;&#039; for Comfac&#039;s pfSense Practical Training System implementation. This page tracks all tasks from material conversion to infrastructure deployment and course delivery.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Phase 0: Material Conversion (FUND001 → Wiki) ==&lt;br /&gt;
Convert all Netgate FUND001 training PDFs into CITWiki pages with detailed summaries. Each wiki page should include: learning objectives, key concepts, step-by-step lab instructions adapted for virtual environment, and troubleshooting tips.&lt;br /&gt;
&lt;br /&gt;
=== Slide Decks ===&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG1 — Introduction to pfSense&#039;&#039;&#039; → [[Training: pfSense Introduction]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG2 — Interfaces, VIPs, and Rules&#039;&#039;&#039; → [[Training: Interfaces and Firewall Rules]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG3 — NAT and VIPs&#039;&#039;&#039; → [[Training: NAT and Virtual IPs]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG4 — pfSense Services&#039;&#039;&#039; → [[Training: pfSense Services]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG5 — VPNs and IPsec&#039;&#039;&#039; → [[Training: IPsec VPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG6 — OpenVPN&#039;&#039;&#039; → [[Training: OpenVPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG7 — WireGuard&#039;&#039;&#039; → [[Training: WireGuard]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG8 — Multi-WAN&#039;&#039;&#039; → [[Training: Multi-WAN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG9 — Traffic Shaping&#039;&#039;&#039; → [[Training: Traffic Shaping]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG10 — High Availability&#039;&#039;&#039; → [[Training: High Availability]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG11 — Other Features&#039;&#039;&#039; → [[Training: Monitoring and Packages]]&lt;br /&gt;
&lt;br /&gt;
=== Labs ===&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 1 — Intro, Getting Started, Backup/Restore&#039;&#039;&#039; → [[Training Lab 1: Introduction and Backup Restore]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 2 — Interfaces, Firewall Rules, Aliases&#039;&#039;&#039; → [[Training Lab 2: Firewall Rules and Aliases]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 3 — Virtual IPs and NAT&#039;&#039;&#039; → [[Training Lab 3: NAT and Virtual IPs]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 4 — Services and Branch Network Setup&#039;&#039;&#039; → [[Training Lab 4: Services and Branch Network]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 5 — IPsec&#039;&#039;&#039; → [[Training Lab 5: IPsec VPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 6 — OpenVPN&#039;&#039;&#039; → [[Training Lab 6: OpenVPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 7 — WireGuard&#039;&#039;&#039; → [[Training Lab 7: WireGuard]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 8 — Multi-WAN&#039;&#039;&#039; → [[Training Lab 8: Multi-WAN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 9 — Traffic Shaping&#039;&#039;&#039; → [[Training Lab 9: Traffic Shaping]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 10 — High Availability&#039;&#039;&#039; → [[Training Lab 10: High Availability]]&lt;br /&gt;
&lt;br /&gt;
=== Comfac Original Content ===&lt;br /&gt;
* [x] &#039;&#039;&#039;Introduction Training (Module 0)&#039;&#039;&#039; → [[Training: Setting Up a Firewall for Yourself]] — Personal/small business firewall&lt;br /&gt;
* [ ] &#039;&#039;&#039;the-pfsense-documentation.pdf&#039;&#039;&#039; → Summarize into [[Training: pfSense Complete Reference]] or link as external reference&lt;br /&gt;
* [ ] &#039;&#039;&#039;WindowsTrainingSupportFiles.zip&#039;&#039;&#039; → Extract and document client software requirements ([[Training: Client Software Requirements]])&lt;br /&gt;
* [ ] &#039;&#039;&#039;Training Videos (4× .mkv)&#039;&#039;&#039; → Catalog timestamps and link from relevant wiki pages&lt;br /&gt;
&lt;br /&gt;
== Phase 1: Infrastructure Setup ==&lt;br /&gt;
Build the virtual training environment on a &#039;&#039;&#039;dedicated training machine&#039;&#039;&#039; — NOT the 200-core / 1TB RAM production server. The 200-core machine should remain fully available for ERPNext, AI workloads, and production services.&lt;br /&gt;
&lt;br /&gt;
=== Resource Analysis (Completed) ===&lt;br /&gt;
* [x] &#039;&#039;&#039;R.1&#039;&#039;&#039; Compare Pure Linux (FOSS) vs Windows stacks -&amp;gt; [[Networking PfSense Index#Resource Estimates Per Student]]&lt;br /&gt;
* [x] &#039;&#039;&#039;R.2&#039;&#039;&#039; Calculate 20% server utilization targets -&amp;gt; 13 students (Linux), 6 students (Windows)&lt;br /&gt;
* [x] &#039;&#039;&#039;R.3&#039;&#039;&#039; Analyze container-based alternatives -&amp;gt; LXC for Linux routers; KVM still required for pfSense&lt;br /&gt;
* [x] &#039;&#039;&#039;R.4&#039;&#039;&#039; Define exercise-limited deployment model -&amp;gt; Right-size per lab; 0-4 vCPUs per student&lt;br /&gt;
* [x] &#039;&#039;&#039;R.5&#039;&#039;&#039; Specify smaller server options for 10 students -&amp;gt; Dell R630 (Linux) / R740 (Windows)&lt;br /&gt;
* [x] &#039;&#039;&#039;R.6&#039;&#039;&#039; Design AI evaluation pipeline -&amp;gt; Qwen 3.5 Coder 9GB + DeepSeek + OpenCode for automated readiness&lt;br /&gt;
* [x] &#039;&#039;&#039;R.7&#039;&#039;&#039; Decide against using 200-core server -&amp;gt; Training will run on dedicated used server or repurposed desktop&lt;br /&gt;
&lt;br /&gt;
=== Hardware Selection ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.1&#039;&#039;&#039; Audit retiring desktops from Win2Lin migration for reuse as training server&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.2&#039;&#039;&#039; If no suitable desktop: procure used Dell R630/R640 (32c/64GB) or HP DL360 Gen9&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.3&#039;&#039;&#039; If rack space/noise is issue: procure 3x Intel N100 mini-PCs for silent cluster&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.4&#039;&#039;&#039; Install Intel i350-T4 quad-port NIC if machine only has 1 Ethernet port&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.5&#039;&#039;&#039; Label machine as CIT-TRAINING-01; document in asset inventory&lt;br /&gt;
&lt;br /&gt;
=== Host Preparation ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.1&#039;&#039;&#039; Install Ubuntu Server LTS 22.04/24.04 on training hardware&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.2&#039;&#039;&#039; Configure KVM/libvirt with storage pools (NVMe for golden images, SSD for ephemeral clones)&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.3&#039;&#039;&#039; Set up network bridges: br-mgmt, br-lan, br-wan, br-dmz, br-internet&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.4&#039;&#039;&#039; Configure VLANs for student isolation (one VLAN per student or per lab)&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.5&#039;&#039;&#039; Install and configure Ansible controller (host or Docker container)&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.6&#039;&#039;&#039; Verify training machine has no dependency on 200-core server (standalone)&lt;br /&gt;
&lt;br /&gt;
=== Base Images ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.1&#039;&#039;&#039; Download pfSense CE ISO and create qcow2 golden image (1 vCPU, 512 MB RAM, 4 GB disk - microVM)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.2&#039;&#039;&#039; Create Alpine Linux LXC golden image (0.5 vCPU, 256 MB RAM, 1 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.3&#039;&#039;&#039; Create Debian XFCE LXC golden image for NoVNC client (0.5 vCPU, 256 MB RAM, 2 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.4&#039;&#039;&#039; Create Ubuntu Server LXC golden image (0.5 vCPU, 256 MB RAM, 1 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.5&#039;&#039;&#039; Create &amp;quot;Internet Router&amp;quot; LXC golden image (0.5 vCPU, 128 MB RAM, 0.5 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.6&#039;&#039;&#039; Test each golden image boots and functions correctly&lt;br /&gt;
&lt;br /&gt;
=== Automation ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.1&#039;&#039;&#039; Write Ansible playbook: lab1-student-env.yml (1 pfSense microVM + 1 LXC client)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.2&#039;&#039;&#039; Write Ansible playbook: lab2-student-env.yml (1 pfSense + 1 client + 1 server LXC)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.3&#039;&#039;&#039; Write Ansible playbook: lab3-student-env.yml (1 pfSense + 1 server + internet router LXC)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.4&#039;&#039;&#039; Write Ansible playbook: lab4-student-env.yml (2 pfSense + 2 clients + 1 server)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.5&#039;&#039;&#039; Write Ansible playbooks for Labs 5-10 (VPNs, Multi-WAN, Shaping, HA)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.6&#039;&#039;&#039; Write Ansible playbook: cleanup-student-env.yml (destroy VMs/LXCs, free resources)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.7&#039;&#039;&#039; Write Ansible playbook: reset-student-env.yml (revert to snapshot/linked clone base)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.8&#039;&#039;&#039; Test all playbooks end-to-end with a single student ID&lt;br /&gt;
&lt;br /&gt;
=== NoVNC Portal ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.1&#039;&#039;&#039; Evaluate Kimchi vs Apache Guacamole vs custom NoVNC proxy&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.2&#039;&#039;&#039; Install and configure chosen NoVNC solution&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.3&#039;&#039;&#039; Integrate NoVNC with student authentication (LDAP, local wiki accounts, or simple token-based)&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.4&#039;&#039;&#039; Build student dashboard: list of phases/labs, &amp;quot;Launch Lab&amp;quot; button, countdown timer&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.5&#039;&#039;&#039; Test 5 concurrent NoVNC sessions for stability&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.6&#039;&#039;&#039; Test 20 concurrent NoVNC sessions for performance&lt;br /&gt;
&lt;br /&gt;
=== AI Evaluation Pipeline ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.1&#039;&#039;&#039; Deploy Qwen 3.5 Instruct Coder 9GB on GPU box or 200-core host&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.2&#039;&#039;&#039; Build pytest + Selenium test suite for pfSense GUI validation&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.3&#039;&#039;&#039; Build SSH-based health check suite for VM/LXC connectivity&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.4&#039;&#039;&#039; Integrate DeepSeek or OpenCode for playbook syntax validation&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.5&#039;&#039;&#039; Create readiness dashboard (pass/fail per lab, resource usage graphs)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.6&#039;&#039;&#039; Schedule automated nightly tests of all lab environments&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Phase 2: Curriculum Development ==&lt;br /&gt;
Design the student-facing training program.&lt;br /&gt;
&lt;br /&gt;
=== Introduction Course (Most Common Use Case) ===&lt;br /&gt;
* [x] &#039;&#039;&#039;E.1&#039;&#039;&#039; Define &amp;quot;Setting Up a Firewall for Yourself&amp;quot; scope: home office / small business&lt;br /&gt;
* [x] &#039;&#039;&#039;E.2&#039;&#039;&#039; Write Module 0: Why You Need a Firewall (threats, NAT basics, basic topology)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.3&#039;&#039;&#039; Write Module 1: Install pfSense on Old PC or VM (hardware requirements, USB install, first boot wizard)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.4&#039;&#039;&#039; Write Module 2: Basic WAN + LAN Setup (DHCP, DNS, first internet connection)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.5&#039;&#039;&#039; Write Module 3: Essential Firewall Rules (block incoming, allow outgoing, ICMP)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.6&#039;&#039;&#039; Write Module 4: Port Forwarding for Common Services (game server, camera, NAS)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.7&#039;&#039;&#039; Write Module 5: VPN for Remote Access (WireGuard road warrior setup)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.8&#039;&#039;&#039; Write Module 6: Backup and Updates (config.xml backup, update schedule)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.9&#039;&#039;&#039; Create hands-on lab for Introduction Course (single pfSense + 1 client VM)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.10&#039;&#039;&#039; Record or source video walkthroughs for each module&lt;br /&gt;
&lt;br /&gt;
=== Full FUND001 Adaptation ===&lt;br /&gt;
* [x] &#039;&#039;&#039;F.1&#039;&#039;&#039; Map each SEG slide deck to a wiki training page with summary + key takeaways&lt;br /&gt;
* [x] &#039;&#039;&#039;F.2&#039;&#039;&#039; Adapt Netgate labs from physical/virtualbox environment to KVM/Ansible environment&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.3&#039;&#039;&#039; Update IP addressing schema for Comfac virtual lab (avoid conflicts with production)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.4&#039;&#039;&#039; Write pre-lab briefing pages (what you&#039;ll learn, expected outcomes)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.5&#039;&#039;&#039; Write post-lab review pages (common mistakes, verification steps, &amp;quot;show me&amp;quot; checklist)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.6&#039;&#039;&#039; Create quiz questions for each phase (5–10 questions, auto-graded if possible)&lt;br /&gt;
&lt;br /&gt;
== Phase 3: Pilot &amp;amp; Refinement ==&lt;br /&gt;
Run the training with a small group before full rollout.&lt;br /&gt;
&lt;br /&gt;
=== Internal Pilot ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.1&#039;&#039;&#039; Recruit 3–5 internal Comfac IT staff as pilot students&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.2&#039;&#039;&#039; Run Phase 1 (Foundations) with pilot group — collect feedback&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.3&#039;&#039;&#039; Run Phase 2 (NAT &amp;amp; Services) with pilot group — collect feedback&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.4&#039;&#039;&#039; Run one VPN lab (IPsec or OpenVPN) with pilot group — test resource limits&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.5&#039;&#039;&#039; Document all bugs, confusion points, and timeouts&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.6&#039;&#039;&#039; Refine playbooks and wiki pages based on pilot feedback&lt;br /&gt;
&lt;br /&gt;
=== Resource Tuning ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.1&#039;&#039;&#039; Measure actual CPU/RAM/disk usage per student during pilot&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.2&#039;&#039;&#039; Adjust VM specs if over- or under-provisioned&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.3&#039;&#039;&#039; Test memory overcommit ratios for safe concurrency scaling&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.4&#039;&#039;&#039; Document maximum safe concurrent student count&lt;br /&gt;
&lt;br /&gt;
== Phase 4: Deployment &amp;amp; Operations ==&lt;br /&gt;
Prepare for regular training delivery.&lt;br /&gt;
&lt;br /&gt;
=== Student Onboarding ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.1&#039;&#039;&#039; Create student onboarding guide (how to access portal, use NoVNC, reset lab)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.2&#039;&#039;&#039; Create instructor guide (how to monitor progress, assist students, grade labs)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.3&#039;&#039;&#039; Set up scheduling system (book lab time slots, prevent over-allocation)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.4&#039;&#039;&#039; Create completion certificates or badges&lt;br /&gt;
&lt;br /&gt;
=== Monitoring &amp;amp; Maintenance ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.1&#039;&#039;&#039; Set up host monitoring (Prometheus/Grafana or simple `libvirt` stats)&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.2&#039;&#039;&#039; Configure alerts for host resource exhaustion&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.3&#039;&#039;&#039; Schedule weekly base image updates (pfSense patches, OS updates)&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.4&#039;&#039;&#039; Document disaster recovery (rebuild host from Ansible, restore golden images)&lt;br /&gt;
&lt;br /&gt;
== Quick Status Dashboard ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Phase !! Status !! % Complete !! Blockers&lt;br /&gt;
|-&lt;br /&gt;
| Phase 0: Material Conversion || 🟢 Done (22/23) || 96% || Pending: reference PDF, support files, videos&lt;br /&gt;
|-&lt;br /&gt;
| Phase 1: Infrastructure Setup || 🟡 In Progress || 20% || Hardware decision made; acquire dedicated training machine&lt;br /&gt;
|-&lt;br /&gt;
| Phase 2: Curriculum Development || 🟡 In Progress || 65% || Need video recordings, quizzes, pre/post lab pages&lt;br /&gt;
|-&lt;br /&gt;
| Phase 3: Pilot &amp;amp; Refinement || 🔴 Not Started || 0% || Waiting on Phase 1 + 2&lt;br /&gt;
|-&lt;br /&gt;
| Phase 4: Deployment &amp;amp; Operations || 🔴 Not Started || 0% || Waiting on Phase 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Resource Summary ==&lt;br /&gt;
&#039;&#039;&#039;Per-student minimum:&#039;&#039;&#039; 6 vCPUs, 6.5 GB RAM, 62 GB disk&lt;br /&gt;
&#039;&#039;&#039;Per-student full lab:&#039;&#039;&#039; 10 vCPUs, 10.5 GB RAM, 110 GB disk&lt;br /&gt;
&#039;&#039;&#039;200-core / 1TB capacity:&#039;&#039;&#039; 20–40 concurrent students (conservative to optimized)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Next Actions (This Week):&#039;&#039;&#039;&lt;br /&gt;
# Summarize the-pfsense-documentation.pdf into a reference page&lt;br /&gt;
# Document WindowsTrainingSupportFiles.zip contents&lt;br /&gt;
# Catalog training video timestamps&lt;br /&gt;
# Begin Ansible playbook drafting for Lab 1 environment&lt;br /&gt;
# Evaluate Kimchi vs Guacamole for NoVNC portal&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=251</id>
		<title>Networking PfSense Index</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=251"/>
		<updated>2026-04-23T10:42:09Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Add Dedicated Training Server Strategy: recommend separate machine instead of 200-core server; include mini-PC cluster, used server, desktop repurpose, ARM SBC options; cost-benefit analysis&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f0f7ff; border:1px solid #b8d4f0; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Consolidated index&#039;&#039;&#039; for all networking infrastructure guides, pfSense documentation, DNS/ad-blocking resources, and network equipment references at Comfac IT.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== pfSense Core Guides ==&lt;br /&gt;
* [[pfSense Sales Training Material]] — Product knowledge and sales positioning for Netgate/pfSense hardware and software&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS &amp;amp; ACME]] — Enterprise Wi-Fi captive portal with RADIUS authentication and Let&#039;s Encrypt SSL&lt;br /&gt;
* [[pfSense CE → pfSense Plus Upgrade Guide]] — Step-by-step migration from Community Edition to pfSense Plus&lt;br /&gt;
* [[SOP: Network Troubleshooting &amp;amp; pfSense Monitoring 251130]] — Standard operating procedures for network diagnostics and pfSense health monitoring&lt;br /&gt;
&lt;br /&gt;
== Network Infrastructure &amp;amp; Equipment ==&lt;br /&gt;
* [[Tplink Mikrotik Equivalent]] — Cross-reference of TP-Link and MikroTik models for network deployments&lt;br /&gt;
* [[Controller Systems 251213-01]] — Network and infrastructure controller systems&lt;br /&gt;
* [[Power Distribution Tree 251213]] — Power architecture for network and server racks&lt;br /&gt;
* [[NPM Migration to Homelab VPS Relay 260401]] — Nginx Proxy Manager migration; VPS as iptables/ZeroTier relay with homelab redundancy&lt;br /&gt;
&lt;br /&gt;
== DNS, Ad Blocking &amp;amp; Pi-hole ==&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/pi-hole Comfac Pi-hole Repository] — GitHub repository for Pi-hole DNS sinkhole deployment&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/pi-hole/blob/master/How%20this%20Works.md How Pi-hole Works] — Technical overview of the Pi-hole DNS filtering architecture&lt;br /&gt;
&lt;br /&gt;
== Training &amp;amp; Skills ==&lt;br /&gt;
* [[Skills and Competencies for IT Staff Trained in pfSense]] — Required competencies and certification path for pfSense-administering staff&lt;br /&gt;
* [[PfSense Training Project Tracker]] — &#039;&#039;&#039;Implementation tracker&#039;&#039;&#039; for the NoVNC virtual lab, material conversion, and curriculum development&lt;br /&gt;
&lt;br /&gt;
== Practical Training System (NoVNC Virtual Lab) ==&lt;br /&gt;
&#039;&#039;&#039;Goal:&#039;&#039;&#039; Build a self-hosted, virtualized pfSense training environment where Comfac trainees can learn hands-on without physical hardware. All labs run via NoVNC in a browser, orchestrated on Comfac&#039;s 200-core / 1TB RAM machine.&lt;br /&gt;
&lt;br /&gt;
=== Training Architecture Vision ===&lt;br /&gt;
Each student gets an isolated virtual network sandbox containing:&lt;br /&gt;
* 2× pfSense VMs (HQ HA pair or HQ + Branch)&lt;br /&gt;
* 1–2× Client VMs (Windows/Linux desktop)&lt;br /&gt;
* 1× Server VM (web/DNS/target)&lt;br /&gt;
* 1× Simulated &amp;quot;Internet&amp;quot; router VM&lt;br /&gt;
&lt;br /&gt;
Access is through a NoVNC web portal. Students click a lab, and their environment is provisioned automatically via Ansible/Terraform or Docker/KVM.&lt;br /&gt;
&lt;br /&gt;
=== Resource Estimates Per Student ===&lt;br /&gt;
&lt;br /&gt;
==== Stack A: Pure Linux / FOSS (Recommended for Comfac) ====&lt;br /&gt;
All components run on open-source software. Clients are lightweight Linux VMs or LXC containers. No Windows licensing required.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! vCPUs !! RAM !! Disk !! Virtualization !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| pfSense VM || 1 || 512 MB || 4 GB || KVM microVM || FreeBSD requires KVM; use tiny QEMU args&lt;br /&gt;
|-&lt;br /&gt;
| Linux Client (LXC) || 0.5 || 256 MB || 1 GB || LXC container || Alpine or Debian with XFCE; NoVNC access&lt;br /&gt;
|-&lt;br /&gt;
| Linux Server (LXC) || 0.5 || 256 MB || 1 GB || LXC container || nginx, BIND, or simple Python HTTP&lt;br /&gt;
|-&lt;br /&gt;
| Internet Router (LXC) || 0.5 || 128 MB || 0.5 GB || LXC container || Static routes only; FRR optional&lt;br /&gt;
|-&lt;br /&gt;
| NoVNC Proxy (Docker) || 0.5 || 256 MB || 0.5 GB || Docker container || websockify + nginx&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total per student&#039;&#039;&#039; || &#039;&#039;&#039;3&#039;&#039;&#039; || &#039;&#039;&#039;1.4 GB&#039;&#039;&#039; || &#039;&#039;&#039;7 GB&#039;&#039;&#039; || — || Thin-provisioned; linked clones&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Stack B: Windows Client (Full Desktop Experience) ====&lt;br /&gt;
For trainees who need a Windows desktop for browser-based management or specific client software.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! vCPUs !! RAM !! Disk !! Virtualization !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| pfSense VM || 2 || 1 GB || 8 GB || KVM || Standard qcow2 image&lt;br /&gt;
|-&lt;br /&gt;
| Windows Client || 2 || 4 GB || 40 GB || KVM || Windows 10/11 thin client; needs GPU if GUI-heavy&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu Server || 1 || 1 GB || 10 GB || KVM || Full VM for compatibility&lt;br /&gt;
|-&lt;br /&gt;
| Internet Router || 1 || 512 MB || 4 GB || KVM || Ubuntu with static routes&lt;br /&gt;
|-&lt;br /&gt;
| NoVNC Proxy || 0.5 || 256 MB || 0.5 GB || Docker || Shared across students&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total per student&#039;&#039;&#039; || &#039;&#039;&#039;6.5&#039;&#039;&#039; || &#039;&#039;&#039;6.8 GB&#039;&#039;&#039; || &#039;&#039;&#039;63 GB&#039;&#039;&#039; || — || Higher resource cost&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Stack C: Hybrid — Containers for Linux Router Exercises ====&lt;br /&gt;
For basic routing/firewall concept labs only (not pfSense-specific), replace pfSense with Linux routers in containers.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! vCPUs !! RAM !! Disk !! Virtualization !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Linux Router (LXC) || 0.5 || 128 MB || 0.5 GB || LXC || Alpine + iptables/nftables + WireGuard&lt;br /&gt;
|-&lt;br /&gt;
| Linux Client (LXC) || 0.5 || 256 MB || 1 GB || LXC || Alpine or Debian&lt;br /&gt;
|-&lt;br /&gt;
| Linux Server (LXC) || 0.5 || 256 MB || 1 GB || LXC || nginx, BIND&lt;br /&gt;
|-&lt;br /&gt;
| Internet Router (LXC) || 0.5 || 128 MB || 0.5 GB || LXC || Static routes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total per student&#039;&#039;&#039; || &#039;&#039;&#039;2&#039;&#039;&#039; || &#039;&#039;&#039;768 MB&#039;&#039;&#039; || &#039;&#039;&#039;3 GB&#039;&#039;&#039; || — || Cannot teach pfSense GUI; teaches concepts only&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; pfSense is FreeBSD-based and cannot run in Linux containers (Docker/LXC). Stack C is suitable for teaching routing/VPN concepts using Linux tools (iptables, nftables, WireGuard, strongSwan), but not for teaching the pfSense web interface. For pfSense GUI training, use Stack A or B.&lt;br /&gt;
&lt;br /&gt;
=== Server Capacity: 20% Utilization Target ===&lt;br /&gt;
The goal is to run the training environment using only 20% of the 200-core / 1TB RAM server, leaving 80% for other Comfac workloads (ERPNext, AI models, file services).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;20% of available resources:&#039;&#039;&#039;&lt;br /&gt;
* 40 vCPUs (20% of 200)&lt;br /&gt;
* 200 GB RAM (20% of 1 TB)&lt;br /&gt;
* ~2 TB SSD (assuming 10 TB array, 20% = 2 TB)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Concurrent student capacity at 20% utilization:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Stack !! Per-Student Resources !! Students at 20% CPU !! Students at 20% RAM !! Limiting Factor&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;A: Pure Linux&#039;&#039;&#039; || 3 vCPU / 1.4 GB || 13 || 142 || &#039;&#039;&#039;CPU: 13 students&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;B: Windows&#039;&#039;&#039; || 6.5 vCPU / 6.8 GB || 6 || 29 || &#039;&#039;&#039;CPU: 6 students&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;C: Containers&#039;&#039;&#039; || 2 vCPU / 0.8 GB || 20 || 250 || &#039;&#039;&#039;CPU: 20 students&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendation:&#039;&#039;&#039; Use Stack A (Pure Linux) for all labs. This yields ~13 concurrent students within the 20% budget, or up to ~30 students if spread across time slots (not everyone needs a lab simultaneously).&lt;br /&gt;
&lt;br /&gt;
=== Smaller Server: What Hardware for 10 Students? ===&lt;br /&gt;
If buying a dedicated training server instead of using the 200-core machine:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Stack !! CPU !! RAM !! Storage !! NICs !! Example Hardware&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;A: Pure Linux&#039;&#039;&#039; || 32 cores || 32 GB || 500 GB NVMe || 2x 1GbE || Used Dell R630/R640 (~$300-500)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;B: Windows&#039;&#039;&#039; || 64 cores || 96 GB || 1 TB NVMe || 2x 1GbE || Used Dell R740 / HP DL360 (~$600-900)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;C: Containers&#039;&#039;&#039; || 16 cores || 16 GB || 250 GB NVMe || 2x 1GbE || Old desktop + Intel NIC (~$100-200)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Dedicated Training Server Strategy (Recommended) ===&lt;br /&gt;
The 200-core / 1TB RAM machine is Comfac&#039;s primary production server (ERPNext, AI models, file services, build pipelines). Running training labs on it consumes resources that could be used for revenue-generating workloads.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendation: Do NOT run training on the 200-core server.&#039;&#039;&#039; Instead, deploy training on a dedicated, smaller machine.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !! Hardware !! Cost (Used) !! Capacity (Stack A) !! Power !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;A. Mini-PC Cluster&#039;&#039;&#039; || 3× Intel N100/N305 mini-PCs (4c/8t, 16GB RAM, 512GB SSD each) || ~$450 total || 12 students || ~45W total || Silent, no rack needed. One PC fails = 4 students affected.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;B. Single Used Server&#039;&#039;&#039; || Dell R630 / HP DL360 Gen9 (2× E5-2680v4, 64GB RAM, 1TB NVMe) || ~$400-600 || 15-20 students || ~150W || Rackmount, redundant PSU, IPMI.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;C. Desktop Repurpose&#039;&#039;&#039; || Old Comfac desktop (i5-8400, 32GB RAM, 500GB SSD) + Intel i350-T4 NIC || $0 + $50 NIC || 6-8 students || ~65W || Free if you have spare desktops.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;D. ARM SBC Cluster&#039;&#039;&#039; || 4× Raspberry Pi 5 (4GB) + 1× Pi 5 (8GB as controller) || ~$300 total || 4-6 students || ~25W total || Cannot run x86 pfSense; must use Linux routers (Stack C only).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Best choice for Comfac: Option B (Single Used Server) or Option C (Repurpose Desktop).&#039;&#039;&#039;&lt;br /&gt;
* Option B gives headroom for growth to 20 students&lt;br /&gt;
* Option C is free if you have retiring desktops from the Win2Lin migration&lt;br /&gt;
* Both keep the 200-core server 100% free for production&lt;br /&gt;
&lt;br /&gt;
=== Cost-Benefit: 200-Core Server vs Dedicated Training Box ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Factor !! Training on 200-Core Server !! Dedicated Training Server&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Hardware Cost&#039;&#039;&#039; || $0 (already owned) || $0-$600&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Power Cost&#039;&#039;&#039; || Already running || +$10-30/month&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Opportunity Cost&#039;&#039;&#039; || &#039;&#039;&#039;High&#039;&#039;&#039; — 20% of server unavailable for ERPNext/AI/builds || &#039;&#039;&#039;Zero&#039;&#039;&#039; — production server untouched&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Risk&#039;&#039;&#039; || Training crashes could affect production VMs || Isolated; training issues contained&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Noise/Location&#039;&#039;&#039; || Must stay in server room || Mini-PC or desktop can sit in training room&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Maintenance Window&#039;&#039;&#039; || Must coordinate with production || Anytime; reboot freely&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Verdict:&#039;&#039;&#039; A $400 used server or a $0 repurposed desktop pays for itself in 1-2 months by keeping the 200-core machine fully available for production workloads.&lt;br /&gt;
&lt;br /&gt;
=== Cluster-in-a-Box: Old PC + Proxmox VE ===&lt;br /&gt;
For the absolute lowest cost (repurposed old PC):&lt;br /&gt;
# Install Proxmox VE (Debian-based hypervisor with web GUI)&lt;br /&gt;
# Create LXC templates for Alpine/Debian clients&lt;br /&gt;
# Create KVM VMs for pfSense microVMs&lt;br /&gt;
# Install NoVNC via Proxmox built-in console or add Kimchi/Guacamole&lt;br /&gt;
# Students access via browser to the Proxmox web UI&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Specs needed for 8 students (Stack A):&#039;&#039;&#039;&lt;br /&gt;
* CPU: 6-core / 12-thread (Intel 6th-gen i5 or better; AMD Ryzen 5)&lt;br /&gt;
* RAM: 32 GB DDR4&lt;br /&gt;
* Storage: 500 GB NVMe or SSD&lt;br /&gt;
* NIC: Intel i350-T4 quad-port (for VLANs and bridges)&lt;br /&gt;
* Cost: $0 (old PC) + $50 (NIC) if you already have the PC&lt;br /&gt;
&lt;br /&gt;
This is the path of least resistance for Comfac given the Win2Lin migration will free up desktops.&lt;br /&gt;
&lt;br /&gt;
=== Exercise-Limited Deployment (Right-Sizing per Lab) ===&lt;br /&gt;
Not every lab needs the full sandbox. Deploy only what is needed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Lab !! Stack A Deployed !! vCPUs Used !! RAM Used !! Disk Used&lt;br /&gt;
|-&lt;br /&gt;
| Day 1 — Theory only || None (wiki only) || 0 || 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
| Lab 1 (Intro/Backup) || 1 pfSense + 1 client || 1.5 || 768 MB || 5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 2 (Rules) || 1 pfSense + 1 client + 1 server || 2 || 1 GB || 6 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 3 (NAT) || 1 pfSense + 1 server + router || 2 || 900 MB || 5.5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 4 (Services) || 2 pfSense + 2 clients + 1 server || 4 || 2.1 GB || 11 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 5-7 (VPNs) || 2 pfSense + 2 clients || 3 || 1.5 GB || 10 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 8 (Multi-WAN) || 1 pfSense + 1 client + router || 2 || 900 MB || 5.5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 9 (Shaping) || 1 pfSense + 2 clients || 2.5 || 1.3 GB || 6 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 10 (HA) || 2 pfSense + 1 client || 2.5 || 1.3 GB || 9 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Scheduling strategy:&#039;&#039;&#039; If students are scheduled in 1-hour slots and labs are provisioned on-demand, the same 40 vCPUs / 200 GB RAM can serve 40-60 student-slots per day (not concurrently, but sequentially).&lt;br /&gt;
&lt;br /&gt;
=== Phase 1: Resource Setup Validation ===&lt;br /&gt;
Before full student rollout, validate the resource model with these tests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test !! Purpose !! Command / Method !! Pass Criteria&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T1: MicroVM Boot&#039;&#039;&#039; || Verify pfSense runs in 512MB/1vCPU || qemu-system-x86_64 -m 512 -smp 1 -drive file=pfsense.qcow2 || Boots to login in &amp;lt; 120s&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T2: LXC Container Spawn&#039;&#039;&#039; || Verify sub-1GB containers work || lxc launch images:alpine/3.19 client || Starts in &amp;lt; 10s; SSH reachable&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T3: NoVNC Session&#039;&#039;&#039; || Verify one student can access console || websockify + TigerVNC || 640x480 responsive; &amp;lt; 500ms latency&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T4: 5 Concurrent Students&#039;&#039;&#039; || Validate 20% CPU/RAM budget || Ansible: deploy 5x Stack A || Total &amp;lt; 8 vCPU, &amp;lt; 7 GB RAM&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T5: Lab 4 Full Deploy&#039;&#039;&#039; || Heaviest lab (2 pfSense + 2 clients + server) || ansible-playbook lab4.yml || Deploys in &amp;lt; 5 min; all VMs pingable&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T6: Snapshot Reset Speed&#039;&#039;&#039; || Time to reset between students || virsh snapshot-revert + virsh start || &amp;lt; 60 seconds total&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T7: AI Evaluation Readiness&#039;&#039;&#039; || Validate environment for automated testing || See AI Evaluation section below || All labs pass synthetic health checks&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AI Evaluation: Automated Readiness Testing ===&lt;br /&gt;
Before students arrive, AI agents will validate that each lab environment is functional. This replaces manual smoke-testing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Evaluation Stack:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Qwen 3.5 Instruct Coder (9GB)&#039;&#039;&#039; — Runs locally on the 200-core server or a dedicated GPU box. Evaluates: pfSense GUI accessibility, rule syntax, VPN handshake status, config.xml validity.&lt;br /&gt;
* &#039;&#039;&#039;DeepSeek Coder (optional)&#039;&#039;&#039; — Cloud or local. Validates Ansible playbook correctness, network topology logic, resource allocation math.&lt;br /&gt;
* &#039;&#039;&#039;OpenCode (local agent)&#039;&#039;&#039; — Executes shell commands inside VMs/containers via SSH/API. Performs end-to-end tests: ping, curl, ipsec status, wg show, etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Automated Test Sequence (per lab):&#039;&#039;&#039;&lt;br /&gt;
# Deploy lab environment via Ansible&lt;br /&gt;
# AI agent logs into pfSense (admin credentials)&lt;br /&gt;
# Screenshot/check each configured page matches expected state&lt;br /&gt;
# Run connectivity tests from client VMs&lt;br /&gt;
# Verify services are listening on correct ports&lt;br /&gt;
# Generate pass/fail report with specific error details&lt;br /&gt;
# Destroy lab environment&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Benefits:&#039;&#039;&#039;&lt;br /&gt;
* Catch broken base images before students arrive&lt;br /&gt;
* Validate that config.xml injections work correctly&lt;br /&gt;
* Ensure network isolation between students&lt;br /&gt;
* Measure actual resource usage vs. estimates&lt;br /&gt;
* Generate readiness dashboard for instructors&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Implementation:&#039;&#039;&#039;&lt;br /&gt;
* Python + Selenium/Playwright for pfSense GUI testing&lt;br /&gt;
* Paramiko/fabric for SSH-based VM tests&lt;br /&gt;
* pytest framework for test organization&lt;br /&gt;
* GitHub Actions or local Cron for scheduled runs&lt;br /&gt;
* Output: Markdown report posted to wiki or sent via Matrix/Email&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related Infrastructure ==&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]] — Server migration and infrastructure hardening&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]] — Self-hosted email infrastructure context&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]] — Email server deployment&lt;br /&gt;
* [[Portainer to Docker Compose Migration Guide]] — Container orchestration for network services&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&#039;&#039;This index consolidates networking resources previously scattered across the [[Main Page]]. Last updated: 260423.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=PfSense_Training_Project_Tracker&amp;diff=250</id>
		<title>PfSense Training Project Tracker</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=PfSense_Training_Project_Tracker&amp;diff=250"/>
		<updated>2026-04-23T10:14:45Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Update Phase 1: Resource analysis completed (R.1-R.6), add AI evaluation pipeline tasks, update status dashboard&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#fff8e1; border:1px solid #ffcc80; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Project Tracker&#039;&#039;&#039; for Comfac&#039;s pfSense Practical Training System implementation. This page tracks all tasks from material conversion to infrastructure deployment and course delivery.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Phase 0: Material Conversion (FUND001 → Wiki) ==&lt;br /&gt;
Convert all Netgate FUND001 training PDFs into CITWiki pages with detailed summaries. Each wiki page should include: learning objectives, key concepts, step-by-step lab instructions adapted for virtual environment, and troubleshooting tips.&lt;br /&gt;
&lt;br /&gt;
=== Slide Decks ===&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG1 — Introduction to pfSense&#039;&#039;&#039; → [[Training: pfSense Introduction]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG2 — Interfaces, VIPs, and Rules&#039;&#039;&#039; → [[Training: Interfaces and Firewall Rules]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG3 — NAT and VIPs&#039;&#039;&#039; → [[Training: NAT and Virtual IPs]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG4 — pfSense Services&#039;&#039;&#039; → [[Training: pfSense Services]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG5 — VPNs and IPsec&#039;&#039;&#039; → [[Training: IPsec VPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG6 — OpenVPN&#039;&#039;&#039; → [[Training: OpenVPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG7 — WireGuard&#039;&#039;&#039; → [[Training: WireGuard]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG8 — Multi-WAN&#039;&#039;&#039; → [[Training: Multi-WAN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG9 — Traffic Shaping&#039;&#039;&#039; → [[Training: Traffic Shaping]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG10 — High Availability&#039;&#039;&#039; → [[Training: High Availability]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG11 — Other Features&#039;&#039;&#039; → [[Training: Monitoring and Packages]]&lt;br /&gt;
&lt;br /&gt;
=== Labs ===&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 1 — Intro, Getting Started, Backup/Restore&#039;&#039;&#039; → [[Training Lab 1: Introduction and Backup Restore]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 2 — Interfaces, Firewall Rules, Aliases&#039;&#039;&#039; → [[Training Lab 2: Firewall Rules and Aliases]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 3 — Virtual IPs and NAT&#039;&#039;&#039; → [[Training Lab 3: NAT and Virtual IPs]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 4 — Services and Branch Network Setup&#039;&#039;&#039; → [[Training Lab 4: Services and Branch Network]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 5 — IPsec&#039;&#039;&#039; → [[Training Lab 5: IPsec VPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 6 — OpenVPN&#039;&#039;&#039; → [[Training Lab 6: OpenVPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 7 — WireGuard&#039;&#039;&#039; → [[Training Lab 7: WireGuard]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 8 — Multi-WAN&#039;&#039;&#039; → [[Training Lab 8: Multi-WAN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 9 — Traffic Shaping&#039;&#039;&#039; → [[Training Lab 9: Traffic Shaping]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 10 — High Availability&#039;&#039;&#039; → [[Training Lab 10: High Availability]]&lt;br /&gt;
&lt;br /&gt;
=== Comfac Original Content ===&lt;br /&gt;
* [x] &#039;&#039;&#039;Introduction Training (Module 0)&#039;&#039;&#039; → [[Training: Setting Up a Firewall for Yourself]] — Personal/small business firewall&lt;br /&gt;
* [ ] &#039;&#039;&#039;the-pfsense-documentation.pdf&#039;&#039;&#039; → Summarize into [[Training: pfSense Complete Reference]] or link as external reference&lt;br /&gt;
* [ ] &#039;&#039;&#039;WindowsTrainingSupportFiles.zip&#039;&#039;&#039; → Extract and document client software requirements ([[Training: Client Software Requirements]])&lt;br /&gt;
* [ ] &#039;&#039;&#039;Training Videos (4× .mkv)&#039;&#039;&#039; → Catalog timestamps and link from relevant wiki pages&lt;br /&gt;
&lt;br /&gt;
== Phase 1: Infrastructure Setup ==&lt;br /&gt;
Build the virtual training environment on Comfac&#039;s 200-core / 1TB RAM machine.&lt;br /&gt;
&lt;br /&gt;
=== Resource Analysis (Completed) ===&lt;br /&gt;
* [x] &#039;&#039;&#039;R.1&#039;&#039;&#039; Compare Pure Linux (FOSS) vs Windows stacks -&amp;gt; [[Networking PfSense Index#Resource Estimates Per Student]]&lt;br /&gt;
* [x] &#039;&#039;&#039;R.2&#039;&#039;&#039; Calculate 20% server utilization targets -&amp;gt; 13 students (Linux), 6 students (Windows)&lt;br /&gt;
* [x] &#039;&#039;&#039;R.3&#039;&#039;&#039; Analyze container-based alternatives -&amp;gt; LXC for Linux routers; KVM still required for pfSense&lt;br /&gt;
* [x] &#039;&#039;&#039;R.4&#039;&#039;&#039; Define exercise-limited deployment model -&amp;gt; Right-size per lab; 0-4 vCPUs per student&lt;br /&gt;
* [x] &#039;&#039;&#039;R.5&#039;&#039;&#039; Specify smaller server options for 10 students -&amp;gt; Dell R630 (Linux) / R740 (Windows)&lt;br /&gt;
* [x] &#039;&#039;&#039;R.6&#039;&#039;&#039; Design AI evaluation pipeline -&amp;gt; Qwen 3.5 Coder 9GB + DeepSeek + OpenCode for automated readiness&lt;br /&gt;
&lt;br /&gt;
=== Host Preparation ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.1&#039;&#039;&#039; Install Ubuntu Server LTS on 200-core host&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.2&#039;&#039;&#039; Configure KVM/libvirt with storage pools (NVMe for images, SSD for ephemeral clones)&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.3&#039;&#039;&#039; Set up network bridges: br-mgmt, br-lan, br-wan, br-dmz, br-internet&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.4&#039;&#039;&#039; Configure VLANs for student isolation (one VLAN per student or per lab)&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.5&#039;&#039;&#039; Install and configure Ansible controller (host or container)&lt;br /&gt;
&lt;br /&gt;
=== Base Images ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.1&#039;&#039;&#039; Download pfSense CE ISO and create qcow2 golden image (1 vCPU, 512 MB RAM, 4 GB disk - microVM)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.2&#039;&#039;&#039; Create Alpine Linux LXC golden image (0.5 vCPU, 256 MB RAM, 1 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.3&#039;&#039;&#039; Create Debian XFCE LXC golden image for NoVNC client (0.5 vCPU, 256 MB RAM, 2 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.4&#039;&#039;&#039; Create Ubuntu Server LXC golden image (0.5 vCPU, 256 MB RAM, 1 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.5&#039;&#039;&#039; Create &amp;quot;Internet Router&amp;quot; LXC golden image (0.5 vCPU, 128 MB RAM, 0.5 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.6&#039;&#039;&#039; Test each golden image boots and functions correctly&lt;br /&gt;
&lt;br /&gt;
=== Automation ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.1&#039;&#039;&#039; Write Ansible playbook: lab1-student-env.yml (1 pfSense microVM + 1 LXC client)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.2&#039;&#039;&#039; Write Ansible playbook: lab2-student-env.yml (1 pfSense + 1 client + 1 server LXC)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.3&#039;&#039;&#039; Write Ansible playbook: lab3-student-env.yml (1 pfSense + 1 server + internet router LXC)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.4&#039;&#039;&#039; Write Ansible playbook: lab4-student-env.yml (2 pfSense + 2 clients + 1 server)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.5&#039;&#039;&#039; Write Ansible playbooks for Labs 5-10 (VPNs, Multi-WAN, Shaping, HA)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.6&#039;&#039;&#039; Write Ansible playbook: cleanup-student-env.yml (destroy VMs/LXCs, free resources)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.7&#039;&#039;&#039; Write Ansible playbook: reset-student-env.yml (revert to snapshot/linked clone base)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.8&#039;&#039;&#039; Test all playbooks end-to-end with a single student ID&lt;br /&gt;
&lt;br /&gt;
=== NoVNC Portal ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.1&#039;&#039;&#039; Evaluate Kimchi vs Apache Guacamole vs custom NoVNC proxy&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.2&#039;&#039;&#039; Install and configure chosen NoVNC solution&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.3&#039;&#039;&#039; Integrate NoVNC with student authentication (LDAP, local wiki accounts, or simple token-based)&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.4&#039;&#039;&#039; Build student dashboard: list of phases/labs, &amp;quot;Launch Lab&amp;quot; button, countdown timer&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.5&#039;&#039;&#039; Test 5 concurrent NoVNC sessions for stability&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.6&#039;&#039;&#039; Test 20 concurrent NoVNC sessions for performance&lt;br /&gt;
&lt;br /&gt;
=== AI Evaluation Pipeline ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.1&#039;&#039;&#039; Deploy Qwen 3.5 Instruct Coder 9GB on GPU box or 200-core host&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.2&#039;&#039;&#039; Build pytest + Selenium test suite for pfSense GUI validation&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.3&#039;&#039;&#039; Build SSH-based health check suite for VM/LXC connectivity&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.4&#039;&#039;&#039; Integrate DeepSeek or OpenCode for playbook syntax validation&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.5&#039;&#039;&#039; Create readiness dashboard (pass/fail per lab, resource usage graphs)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.6&#039;&#039;&#039; Schedule automated nightly tests of all lab environments&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Phase 2: Curriculum Development ==&lt;br /&gt;
Design the student-facing training program.&lt;br /&gt;
&lt;br /&gt;
=== Introduction Course (Most Common Use Case) ===&lt;br /&gt;
* [x] &#039;&#039;&#039;E.1&#039;&#039;&#039; Define &amp;quot;Setting Up a Firewall for Yourself&amp;quot; scope: home office / small business&lt;br /&gt;
* [x] &#039;&#039;&#039;E.2&#039;&#039;&#039; Write Module 0: Why You Need a Firewall (threats, NAT basics, basic topology)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.3&#039;&#039;&#039; Write Module 1: Install pfSense on Old PC or VM (hardware requirements, USB install, first boot wizard)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.4&#039;&#039;&#039; Write Module 2: Basic WAN + LAN Setup (DHCP, DNS, first internet connection)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.5&#039;&#039;&#039; Write Module 3: Essential Firewall Rules (block incoming, allow outgoing, ICMP)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.6&#039;&#039;&#039; Write Module 4: Port Forwarding for Common Services (game server, camera, NAS)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.7&#039;&#039;&#039; Write Module 5: VPN for Remote Access (WireGuard road warrior setup)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.8&#039;&#039;&#039; Write Module 6: Backup and Updates (config.xml backup, update schedule)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.9&#039;&#039;&#039; Create hands-on lab for Introduction Course (single pfSense + 1 client VM)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.10&#039;&#039;&#039; Record or source video walkthroughs for each module&lt;br /&gt;
&lt;br /&gt;
=== Full FUND001 Adaptation ===&lt;br /&gt;
* [x] &#039;&#039;&#039;F.1&#039;&#039;&#039; Map each SEG slide deck to a wiki training page with summary + key takeaways&lt;br /&gt;
* [x] &#039;&#039;&#039;F.2&#039;&#039;&#039; Adapt Netgate labs from physical/virtualbox environment to KVM/Ansible environment&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.3&#039;&#039;&#039; Update IP addressing schema for Comfac virtual lab (avoid conflicts with production)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.4&#039;&#039;&#039; Write pre-lab briefing pages (what you&#039;ll learn, expected outcomes)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.5&#039;&#039;&#039; Write post-lab review pages (common mistakes, verification steps, &amp;quot;show me&amp;quot; checklist)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.6&#039;&#039;&#039; Create quiz questions for each phase (5–10 questions, auto-graded if possible)&lt;br /&gt;
&lt;br /&gt;
== Phase 3: Pilot &amp;amp; Refinement ==&lt;br /&gt;
Run the training with a small group before full rollout.&lt;br /&gt;
&lt;br /&gt;
=== Internal Pilot ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.1&#039;&#039;&#039; Recruit 3–5 internal Comfac IT staff as pilot students&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.2&#039;&#039;&#039; Run Phase 1 (Foundations) with pilot group — collect feedback&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.3&#039;&#039;&#039; Run Phase 2 (NAT &amp;amp; Services) with pilot group — collect feedback&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.4&#039;&#039;&#039; Run one VPN lab (IPsec or OpenVPN) with pilot group — test resource limits&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.5&#039;&#039;&#039; Document all bugs, confusion points, and timeouts&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.6&#039;&#039;&#039; Refine playbooks and wiki pages based on pilot feedback&lt;br /&gt;
&lt;br /&gt;
=== Resource Tuning ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.1&#039;&#039;&#039; Measure actual CPU/RAM/disk usage per student during pilot&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.2&#039;&#039;&#039; Adjust VM specs if over- or under-provisioned&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.3&#039;&#039;&#039; Test memory overcommit ratios for safe concurrency scaling&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.4&#039;&#039;&#039; Document maximum safe concurrent student count&lt;br /&gt;
&lt;br /&gt;
== Phase 4: Deployment &amp;amp; Operations ==&lt;br /&gt;
Prepare for regular training delivery.&lt;br /&gt;
&lt;br /&gt;
=== Student Onboarding ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.1&#039;&#039;&#039; Create student onboarding guide (how to access portal, use NoVNC, reset lab)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.2&#039;&#039;&#039; Create instructor guide (how to monitor progress, assist students, grade labs)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.3&#039;&#039;&#039; Set up scheduling system (book lab time slots, prevent over-allocation)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.4&#039;&#039;&#039; Create completion certificates or badges&lt;br /&gt;
&lt;br /&gt;
=== Monitoring &amp;amp; Maintenance ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.1&#039;&#039;&#039; Set up host monitoring (Prometheus/Grafana or simple `libvirt` stats)&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.2&#039;&#039;&#039; Configure alerts for host resource exhaustion&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.3&#039;&#039;&#039; Schedule weekly base image updates (pfSense patches, OS updates)&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.4&#039;&#039;&#039; Document disaster recovery (rebuild host from Ansible, restore golden images)&lt;br /&gt;
&lt;br /&gt;
== Quick Status Dashboard ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Phase !! Status !! % Complete !! Blockers&lt;br /&gt;
|-&lt;br /&gt;
| Phase 0: Material Conversion || 🟢 Done (22/23) || 96% || Pending: reference PDF, support files, videos&lt;br /&gt;
|-&lt;br /&gt;
| Phase 1: Infrastructure Setup || 🟡 In Progress || 15% || Resource analysis complete; need host access for image builds&lt;br /&gt;
|-&lt;br /&gt;
| Phase 2: Curriculum Development || 🟡 In Progress || 65% || Need video recordings, quizzes, pre/post lab pages&lt;br /&gt;
|-&lt;br /&gt;
| Phase 3: Pilot &amp;amp; Refinement || 🔴 Not Started || 0% || Waiting on Phase 1 + 2&lt;br /&gt;
|-&lt;br /&gt;
| Phase 4: Deployment &amp;amp; Operations || 🔴 Not Started || 0% || Waiting on Phase 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Resource Summary ==&lt;br /&gt;
&#039;&#039;&#039;Per-student minimum:&#039;&#039;&#039; 6 vCPUs, 6.5 GB RAM, 62 GB disk&lt;br /&gt;
&#039;&#039;&#039;Per-student full lab:&#039;&#039;&#039; 10 vCPUs, 10.5 GB RAM, 110 GB disk&lt;br /&gt;
&#039;&#039;&#039;200-core / 1TB capacity:&#039;&#039;&#039; 20–40 concurrent students (conservative to optimized)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Next Actions (This Week):&#039;&#039;&#039;&lt;br /&gt;
# Summarize the-pfsense-documentation.pdf into a reference page&lt;br /&gt;
# Document WindowsTrainingSupportFiles.zip contents&lt;br /&gt;
# Catalog training video timestamps&lt;br /&gt;
# Begin Ansible playbook drafting for Lab 1 environment&lt;br /&gt;
# Evaluate Kimchi vs Guacamole for NoVNC portal&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=249</id>
		<title>Networking PfSense Index</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=249"/>
		<updated>2026-04-23T10:10:50Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Update Resource Estimates: Add Linux FOSS vs Windows stacks, 20% utilization target, container analysis, AI evaluation, exercise-limited deployment&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f0f7ff; border:1px solid #b8d4f0; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Consolidated index&#039;&#039;&#039; for all networking infrastructure guides, pfSense documentation, DNS/ad-blocking resources, and network equipment references at Comfac IT.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== pfSense Core Guides ==&lt;br /&gt;
* [[pfSense Sales Training Material]] — Product knowledge and sales positioning for Netgate/pfSense hardware and software&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS &amp;amp; ACME]] — Enterprise Wi-Fi captive portal with RADIUS authentication and Let&#039;s Encrypt SSL&lt;br /&gt;
* [[pfSense CE → pfSense Plus Upgrade Guide]] — Step-by-step migration from Community Edition to pfSense Plus&lt;br /&gt;
* [[SOP: Network Troubleshooting &amp;amp; pfSense Monitoring 251130]] — Standard operating procedures for network diagnostics and pfSense health monitoring&lt;br /&gt;
&lt;br /&gt;
== Network Infrastructure &amp;amp; Equipment ==&lt;br /&gt;
* [[Tplink Mikrotik Equivalent]] — Cross-reference of TP-Link and MikroTik models for network deployments&lt;br /&gt;
* [[Controller Systems 251213-01]] — Network and infrastructure controller systems&lt;br /&gt;
* [[Power Distribution Tree 251213]] — Power architecture for network and server racks&lt;br /&gt;
* [[NPM Migration to Homelab VPS Relay 260401]] — Nginx Proxy Manager migration; VPS as iptables/ZeroTier relay with homelab redundancy&lt;br /&gt;
&lt;br /&gt;
== DNS, Ad Blocking &amp;amp; Pi-hole ==&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/pi-hole Comfac Pi-hole Repository] — GitHub repository for Pi-hole DNS sinkhole deployment&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/pi-hole/blob/master/How%20this%20Works.md How Pi-hole Works] — Technical overview of the Pi-hole DNS filtering architecture&lt;br /&gt;
&lt;br /&gt;
== Training &amp;amp; Skills ==&lt;br /&gt;
* [[Skills and Competencies for IT Staff Trained in pfSense]] — Required competencies and certification path for pfSense-administering staff&lt;br /&gt;
* [[PfSense Training Project Tracker]] — &#039;&#039;&#039;Implementation tracker&#039;&#039;&#039; for the NoVNC virtual lab, material conversion, and curriculum development&lt;br /&gt;
&lt;br /&gt;
== Practical Training System (NoVNC Virtual Lab) ==&lt;br /&gt;
&#039;&#039;&#039;Goal:&#039;&#039;&#039; Build a self-hosted, virtualized pfSense training environment where Comfac trainees can learn hands-on without physical hardware. All labs run via NoVNC in a browser, orchestrated on Comfac&#039;s 200-core / 1TB RAM machine.&lt;br /&gt;
&lt;br /&gt;
=== Training Architecture Vision ===&lt;br /&gt;
Each student gets an isolated virtual network sandbox containing:&lt;br /&gt;
* 2× pfSense VMs (HQ HA pair or HQ + Branch)&lt;br /&gt;
* 1–2× Client VMs (Windows/Linux desktop)&lt;br /&gt;
* 1× Server VM (web/DNS/target)&lt;br /&gt;
* 1× Simulated &amp;quot;Internet&amp;quot; router VM&lt;br /&gt;
&lt;br /&gt;
Access is through a NoVNC web portal. Students click a lab, and their environment is provisioned automatically via Ansible/Terraform or Docker/KVM.&lt;br /&gt;
&lt;br /&gt;
=== Resource Estimates Per Student ===&lt;br /&gt;
&lt;br /&gt;
==== Stack A: Pure Linux / FOSS (Recommended for Comfac) ====&lt;br /&gt;
All components run on open-source software. Clients are lightweight Linux VMs or LXC containers. No Windows licensing required.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! vCPUs !! RAM !! Disk !! Virtualization !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| pfSense VM || 1 || 512 MB || 4 GB || KVM microVM || FreeBSD requires KVM; use tiny QEMU args&lt;br /&gt;
|-&lt;br /&gt;
| Linux Client (LXC) || 0.5 || 256 MB || 1 GB || LXC container || Alpine or Debian with XFCE; NoVNC access&lt;br /&gt;
|-&lt;br /&gt;
| Linux Server (LXC) || 0.5 || 256 MB || 1 GB || LXC container || nginx, BIND, or simple Python HTTP&lt;br /&gt;
|-&lt;br /&gt;
| Internet Router (LXC) || 0.5 || 128 MB || 0.5 GB || LXC container || Static routes only; FRR optional&lt;br /&gt;
|-&lt;br /&gt;
| NoVNC Proxy (Docker) || 0.5 || 256 MB || 0.5 GB || Docker container || websockify + nginx&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total per student&#039;&#039;&#039; || &#039;&#039;&#039;3&#039;&#039;&#039; || &#039;&#039;&#039;1.4 GB&#039;&#039;&#039; || &#039;&#039;&#039;7 GB&#039;&#039;&#039; || — || Thin-provisioned; linked clones&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Stack B: Windows Client (Full Desktop Experience) ====&lt;br /&gt;
For trainees who need a Windows desktop for browser-based management or specific client software.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! vCPUs !! RAM !! Disk !! Virtualization !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| pfSense VM || 2 || 1 GB || 8 GB || KVM || Standard qcow2 image&lt;br /&gt;
|-&lt;br /&gt;
| Windows Client || 2 || 4 GB || 40 GB || KVM || Windows 10/11 thin client; needs GPU if GUI-heavy&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu Server || 1 || 1 GB || 10 GB || KVM || Full VM for compatibility&lt;br /&gt;
|-&lt;br /&gt;
| Internet Router || 1 || 512 MB || 4 GB || KVM || Ubuntu with static routes&lt;br /&gt;
|-&lt;br /&gt;
| NoVNC Proxy || 0.5 || 256 MB || 0.5 GB || Docker || Shared across students&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total per student&#039;&#039;&#039; || &#039;&#039;&#039;6.5&#039;&#039;&#039; || &#039;&#039;&#039;6.8 GB&#039;&#039;&#039; || &#039;&#039;&#039;63 GB&#039;&#039;&#039; || — || Higher resource cost&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Stack C: Hybrid — Containers for Linux Router Exercises ====&lt;br /&gt;
For basic routing/firewall concept labs only (not pfSense-specific), replace pfSense with Linux routers in containers.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! vCPUs !! RAM !! Disk !! Virtualization !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Linux Router (LXC) || 0.5 || 128 MB || 0.5 GB || LXC || Alpine + iptables/nftables + WireGuard&lt;br /&gt;
|-&lt;br /&gt;
| Linux Client (LXC) || 0.5 || 256 MB || 1 GB || LXC || Alpine or Debian&lt;br /&gt;
|-&lt;br /&gt;
| Linux Server (LXC) || 0.5 || 256 MB || 1 GB || LXC || nginx, BIND&lt;br /&gt;
|-&lt;br /&gt;
| Internet Router (LXC) || 0.5 || 128 MB || 0.5 GB || LXC || Static routes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total per student&#039;&#039;&#039; || &#039;&#039;&#039;2&#039;&#039;&#039; || &#039;&#039;&#039;768 MB&#039;&#039;&#039; || &#039;&#039;&#039;3 GB&#039;&#039;&#039; || — || Cannot teach pfSense GUI; teaches concepts only&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; pfSense is FreeBSD-based and cannot run in Linux containers (Docker/LXC). Stack C is suitable for teaching routing/VPN concepts using Linux tools (iptables, nftables, WireGuard, strongSwan), but not for teaching the pfSense web interface. For pfSense GUI training, use Stack A or B.&lt;br /&gt;
&lt;br /&gt;
=== Server Capacity: 20% Utilization Target ===&lt;br /&gt;
The goal is to run the training environment using only 20% of the 200-core / 1TB RAM server, leaving 80% for other Comfac workloads (ERPNext, AI models, file services).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;20% of available resources:&#039;&#039;&#039;&lt;br /&gt;
* 40 vCPUs (20% of 200)&lt;br /&gt;
* 200 GB RAM (20% of 1 TB)&lt;br /&gt;
* ~2 TB SSD (assuming 10 TB array, 20% = 2 TB)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Concurrent student capacity at 20% utilization:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Stack !! Per-Student Resources !! Students at 20% CPU !! Students at 20% RAM !! Limiting Factor&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;A: Pure Linux&#039;&#039;&#039; || 3 vCPU / 1.4 GB || 13 || 142 || &#039;&#039;&#039;CPU: 13 students&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;B: Windows&#039;&#039;&#039; || 6.5 vCPU / 6.8 GB || 6 || 29 || &#039;&#039;&#039;CPU: 6 students&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;C: Containers&#039;&#039;&#039; || 2 vCPU / 0.8 GB || 20 || 250 || &#039;&#039;&#039;CPU: 20 students&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendation:&#039;&#039;&#039; Use Stack A (Pure Linux) for all labs. This yields ~13 concurrent students within the 20% budget, or up to ~30 students if spread across time slots (not everyone needs a lab simultaneously).&lt;br /&gt;
&lt;br /&gt;
=== Smaller Server: What Hardware for 10 Students? ===&lt;br /&gt;
If buying a dedicated training server instead of using the 200-core machine:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Stack !! CPU !! RAM !! Storage !! NICs !! Example Hardware&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;A: Pure Linux&#039;&#039;&#039; || 32 cores || 32 GB || 500 GB NVMe || 2x 1GbE || Used Dell R630/R640 (~$300-500)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;B: Windows&#039;&#039;&#039; || 64 cores || 96 GB || 1 TB NVMe || 2x 1GbE || Used Dell R740 / HP DL360 (~$600-900)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;C: Containers&#039;&#039;&#039; || 16 cores || 16 GB || 250 GB NVMe || 2x 1GbE || Old desktop + Intel NIC (~$100-200)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Exercise-Limited Deployment (Right-Sizing per Lab) ===&lt;br /&gt;
Not every lab needs the full sandbox. Deploy only what is needed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Lab !! Stack A Deployed !! vCPUs Used !! RAM Used !! Disk Used&lt;br /&gt;
|-&lt;br /&gt;
| Day 1 — Theory only || None (wiki only) || 0 || 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
| Lab 1 (Intro/Backup) || 1 pfSense + 1 client || 1.5 || 768 MB || 5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 2 (Rules) || 1 pfSense + 1 client + 1 server || 2 || 1 GB || 6 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 3 (NAT) || 1 pfSense + 1 server + router || 2 || 900 MB || 5.5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 4 (Services) || 2 pfSense + 2 clients + 1 server || 4 || 2.1 GB || 11 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 5-7 (VPNs) || 2 pfSense + 2 clients || 3 || 1.5 GB || 10 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 8 (Multi-WAN) || 1 pfSense + 1 client + router || 2 || 900 MB || 5.5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 9 (Shaping) || 1 pfSense + 2 clients || 2.5 || 1.3 GB || 6 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 10 (HA) || 2 pfSense + 1 client || 2.5 || 1.3 GB || 9 GB&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Scheduling strategy:&#039;&#039;&#039; If students are scheduled in 1-hour slots and labs are provisioned on-demand, the same 40 vCPUs / 200 GB RAM can serve 40-60 student-slots per day (not concurrently, but sequentially).&lt;br /&gt;
&lt;br /&gt;
=== Phase 1: Resource Setup Validation ===&lt;br /&gt;
Before full student rollout, validate the resource model with these tests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test !! Purpose !! Command / Method !! Pass Criteria&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T1: MicroVM Boot&#039;&#039;&#039; || Verify pfSense runs in 512MB/1vCPU || qemu-system-x86_64 -m 512 -smp 1 -drive file=pfsense.qcow2 || Boots to login in &amp;lt; 120s&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T2: LXC Container Spawn&#039;&#039;&#039; || Verify sub-1GB containers work || lxc launch images:alpine/3.19 client || Starts in &amp;lt; 10s; SSH reachable&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T3: NoVNC Session&#039;&#039;&#039; || Verify one student can access console || websockify + TigerVNC || 640x480 responsive; &amp;lt; 500ms latency&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T4: 5 Concurrent Students&#039;&#039;&#039; || Validate 20% CPU/RAM budget || Ansible: deploy 5x Stack A || Total &amp;lt; 8 vCPU, &amp;lt; 7 GB RAM&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T5: Lab 4 Full Deploy&#039;&#039;&#039; || Heaviest lab (2 pfSense + 2 clients + server) || ansible-playbook lab4.yml || Deploys in &amp;lt; 5 min; all VMs pingable&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T6: Snapshot Reset Speed&#039;&#039;&#039; || Time to reset between students || virsh snapshot-revert + virsh start || &amp;lt; 60 seconds total&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;T7: AI Evaluation Readiness&#039;&#039;&#039; || Validate environment for automated testing || See AI Evaluation section below || All labs pass synthetic health checks&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AI Evaluation: Automated Readiness Testing ===&lt;br /&gt;
Before students arrive, AI agents will validate that each lab environment is functional. This replaces manual smoke-testing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Evaluation Stack:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Qwen 3.5 Instruct Coder (9GB)&#039;&#039;&#039; — Runs locally on the 200-core server or a dedicated GPU box. Evaluates: pfSense GUI accessibility, rule syntax, VPN handshake status, config.xml validity.&lt;br /&gt;
* &#039;&#039;&#039;DeepSeek Coder (optional)&#039;&#039;&#039; — Cloud or local. Validates Ansible playbook correctness, network topology logic, resource allocation math.&lt;br /&gt;
* &#039;&#039;&#039;OpenCode (local agent)&#039;&#039;&#039; — Executes shell commands inside VMs/containers via SSH/API. Performs end-to-end tests: ping, curl, ipsec status, wg show, etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Automated Test Sequence (per lab):&#039;&#039;&#039;&lt;br /&gt;
# Deploy lab environment via Ansible&lt;br /&gt;
# AI agent logs into pfSense (admin credentials)&lt;br /&gt;
# Screenshot/check each configured page matches expected state&lt;br /&gt;
# Run connectivity tests from client VMs&lt;br /&gt;
# Verify services are listening on correct ports&lt;br /&gt;
# Generate pass/fail report with specific error details&lt;br /&gt;
# Destroy lab environment&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Benefits:&#039;&#039;&#039;&lt;br /&gt;
* Catch broken base images before students arrive&lt;br /&gt;
* Validate that config.xml injections work correctly&lt;br /&gt;
* Ensure network isolation between students&lt;br /&gt;
* Measure actual resource usage vs. estimates&lt;br /&gt;
* Generate readiness dashboard for instructors&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Implementation:&#039;&#039;&#039;&lt;br /&gt;
* Python + Selenium/Playwright for pfSense GUI testing&lt;br /&gt;
* Paramiko/fabric for SSH-based VM tests&lt;br /&gt;
* pytest framework for test organization&lt;br /&gt;
* GitHub Actions or local Cron for scheduled runs&lt;br /&gt;
* Output: Markdown report posted to wiki or sent via Matrix/Email&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related Infrastructure ==&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]] — Server migration and infrastructure hardening&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]] — Self-hosted email infrastructure context&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]] — Email server deployment&lt;br /&gt;
* [[Portainer to Docker Compose Migration Guide]] — Container orchestration for network services&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&#039;&#039;This index consolidates networking resources previously scattered across the [[Main Page]]. Last updated: 260423.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=PfSense_Training_Project_Tracker&amp;diff=248</id>
		<title>PfSense Training Project Tracker</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=PfSense_Training_Project_Tracker&amp;diff=248"/>
		<updated>2026-04-23T07:22:44Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Update tracker - Phase 0 material conversion 96% complete&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#fff8e1; border:1px solid #ffcc80; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Project Tracker&#039;&#039;&#039; for Comfac&#039;s pfSense Practical Training System implementation. This page tracks all tasks from material conversion to infrastructure deployment and course delivery.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Phase 0: Material Conversion (FUND001 → Wiki) ==&lt;br /&gt;
Convert all Netgate FUND001 training PDFs into CITWiki pages with detailed summaries. Each wiki page should include: learning objectives, key concepts, step-by-step lab instructions adapted for virtual environment, and troubleshooting tips.&lt;br /&gt;
&lt;br /&gt;
=== Slide Decks ===&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG1 — Introduction to pfSense&#039;&#039;&#039; → [[Training: pfSense Introduction]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG2 — Interfaces, VIPs, and Rules&#039;&#039;&#039; → [[Training: Interfaces and Firewall Rules]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG3 — NAT and VIPs&#039;&#039;&#039; → [[Training: NAT and Virtual IPs]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG4 — pfSense Services&#039;&#039;&#039; → [[Training: pfSense Services]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG5 — VPNs and IPsec&#039;&#039;&#039; → [[Training: IPsec VPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG6 — OpenVPN&#039;&#039;&#039; → [[Training: OpenVPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG7 — WireGuard&#039;&#039;&#039; → [[Training: WireGuard]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG8 — Multi-WAN&#039;&#039;&#039; → [[Training: Multi-WAN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG9 — Traffic Shaping&#039;&#039;&#039; → [[Training: Traffic Shaping]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG10 — High Availability&#039;&#039;&#039; → [[Training: High Availability]]&lt;br /&gt;
* [x] &#039;&#039;&#039;SEG11 — Other Features&#039;&#039;&#039; → [[Training: Monitoring and Packages]]&lt;br /&gt;
&lt;br /&gt;
=== Labs ===&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 1 — Intro, Getting Started, Backup/Restore&#039;&#039;&#039; → [[Training Lab 1: Introduction and Backup Restore]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 2 — Interfaces, Firewall Rules, Aliases&#039;&#039;&#039; → [[Training Lab 2: Firewall Rules and Aliases]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 3 — Virtual IPs and NAT&#039;&#039;&#039; → [[Training Lab 3: NAT and Virtual IPs]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 4 — Services and Branch Network Setup&#039;&#039;&#039; → [[Training Lab 4: Services and Branch Network]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 5 — IPsec&#039;&#039;&#039; → [[Training Lab 5: IPsec VPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 6 — OpenVPN&#039;&#039;&#039; → [[Training Lab 6: OpenVPN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 7 — WireGuard&#039;&#039;&#039; → [[Training Lab 7: WireGuard]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 8 — Multi-WAN&#039;&#039;&#039; → [[Training Lab 8: Multi-WAN]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 9 — Traffic Shaping&#039;&#039;&#039; → [[Training Lab 9: Traffic Shaping]]&lt;br /&gt;
* [x] &#039;&#039;&#039;Lab 10 — High Availability&#039;&#039;&#039; → [[Training Lab 10: High Availability]]&lt;br /&gt;
&lt;br /&gt;
=== Comfac Original Content ===&lt;br /&gt;
* [x] &#039;&#039;&#039;Introduction Training (Module 0)&#039;&#039;&#039; → [[Training: Setting Up a Firewall for Yourself]] — Personal/small business firewall&lt;br /&gt;
* [ ] &#039;&#039;&#039;the-pfsense-documentation.pdf&#039;&#039;&#039; → Summarize into [[Training: pfSense Complete Reference]] or link as external reference&lt;br /&gt;
* [ ] &#039;&#039;&#039;WindowsTrainingSupportFiles.zip&#039;&#039;&#039; → Extract and document client software requirements ([[Training: Client Software Requirements]])&lt;br /&gt;
* [ ] &#039;&#039;&#039;Training Videos (4× .mkv)&#039;&#039;&#039; → Catalog timestamps and link from relevant wiki pages&lt;br /&gt;
&lt;br /&gt;
== Phase 1: Infrastructure Setup ==&lt;br /&gt;
Build the virtual training environment on Comfac&#039;s 200-core / 1TB RAM machine.&lt;br /&gt;
&lt;br /&gt;
=== Host Preparation ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.1&#039;&#039;&#039; Install Ubuntu Server LTS on 200-core host&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.2&#039;&#039;&#039; Configure KVM/libvirt with storage pools (NVMe for images, SSD for ephemeral clones)&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.3&#039;&#039;&#039; Set up network bridges: `br-mgmt`, `br-lan`, `br-wan`, `br-dmz`, `br-internet`&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.4&#039;&#039;&#039; Configure VLANs for student isolation (one VLAN per student or per lab)&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.5&#039;&#039;&#039; Install and configure Ansible controller (host or container)&lt;br /&gt;
&lt;br /&gt;
=== Base Images ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.1&#039;&#039;&#039; Download pfSense CE ISO and create qcow2 golden image (2 vCPU, 1 GB RAM, 8 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.2&#039;&#039;&#039; Create Ubuntu Server 22.04/24.04 golden image (1 vCPU, 1 GB RAM, 10 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.3&#039;&#039;&#039; Create Windows 10/11 thin client golden image (2 vCPU, 4 GB RAM, 40 GB disk) — OR decide to use Linux clients only&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.4&#039;&#039;&#039; Create &amp;quot;Internet Router&amp;quot; golden image (Ubuntu with FRR/Quagga or simple static routes, 1 vCPU, 512 MB RAM)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.5&#039;&#039;&#039; Test each golden image boots and functions correctly&lt;br /&gt;
&lt;br /&gt;
=== Automation ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.1&#039;&#039;&#039; Write Ansible playbook: `lab1-student-env.yml` (1 pfSense + 1 client)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.2&#039;&#039;&#039; Write Ansible playbook: `lab2-student-env.yml` (1 pfSense + 1 client + 1 server)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.3&#039;&#039;&#039; Write Ansible playbook: `lab3-student-env.yml` (1 pfSense + 1 server + internet)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.4&#039;&#039;&#039; Write Ansible playbook: `lab4-student-env.yml` (2 pfSense + 2 clients + 1 server)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.5&#039;&#039;&#039; Write Ansible playbooks for Labs 5–10 (VPNs, Multi-WAN, Shaping, HA)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.6&#039;&#039;&#039; Write Ansible playbook: `cleanup-student-env.yml` (destroy VMs, free resources)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.7&#039;&#039;&#039; Write Ansible playbook: `reset-student-env.yml` (revert to snapshot/linked clone base)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.8&#039;&#039;&#039; Test all playbooks end-to-end with a single student ID&lt;br /&gt;
&lt;br /&gt;
=== NoVNC Portal ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.1&#039;&#039;&#039; Evaluate Kimchi vs Apache Guacamole vs custom NoVNC proxy&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.2&#039;&#039;&#039; Install and configure chosen NoVNC solution&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.3&#039;&#039;&#039; Integrate NoVNC with student authentication (LDAP, local wiki accounts, or simple token-based)&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.4&#039;&#039;&#039; Build student dashboard: list of phases/labs, &amp;quot;Launch Lab&amp;quot; button, countdown timer&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.5&#039;&#039;&#039; Test 5 concurrent NoVNC sessions for stability&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.6&#039;&#039;&#039; Test 20 concurrent NoVNC sessions for performance&lt;br /&gt;
&lt;br /&gt;
== Phase 2: Curriculum Development ==&lt;br /&gt;
Design the student-facing training program.&lt;br /&gt;
&lt;br /&gt;
=== Introduction Course (Most Common Use Case) ===&lt;br /&gt;
* [x] &#039;&#039;&#039;E.1&#039;&#039;&#039; Define &amp;quot;Setting Up a Firewall for Yourself&amp;quot; scope: home office / small business&lt;br /&gt;
* [x] &#039;&#039;&#039;E.2&#039;&#039;&#039; Write Module 0: Why You Need a Firewall (threats, NAT basics, basic topology)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.3&#039;&#039;&#039; Write Module 1: Install pfSense on Old PC or VM (hardware requirements, USB install, first boot wizard)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.4&#039;&#039;&#039; Write Module 2: Basic WAN + LAN Setup (DHCP, DNS, first internet connection)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.5&#039;&#039;&#039; Write Module 3: Essential Firewall Rules (block incoming, allow outgoing, ICMP)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.6&#039;&#039;&#039; Write Module 4: Port Forwarding for Common Services (game server, camera, NAS)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.7&#039;&#039;&#039; Write Module 5: VPN for Remote Access (WireGuard road warrior setup)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.8&#039;&#039;&#039; Write Module 6: Backup and Updates (config.xml backup, update schedule)&lt;br /&gt;
* [x] &#039;&#039;&#039;E.9&#039;&#039;&#039; Create hands-on lab for Introduction Course (single pfSense + 1 client VM)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.10&#039;&#039;&#039; Record or source video walkthroughs for each module&lt;br /&gt;
&lt;br /&gt;
=== Full FUND001 Adaptation ===&lt;br /&gt;
* [x] &#039;&#039;&#039;F.1&#039;&#039;&#039; Map each SEG slide deck to a wiki training page with summary + key takeaways&lt;br /&gt;
* [x] &#039;&#039;&#039;F.2&#039;&#039;&#039; Adapt Netgate labs from physical/virtualbox environment to KVM/Ansible environment&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.3&#039;&#039;&#039; Update IP addressing schema for Comfac virtual lab (avoid conflicts with production)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.4&#039;&#039;&#039; Write pre-lab briefing pages (what you&#039;ll learn, expected outcomes)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.5&#039;&#039;&#039; Write post-lab review pages (common mistakes, verification steps, &amp;quot;show me&amp;quot; checklist)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.6&#039;&#039;&#039; Create quiz questions for each phase (5–10 questions, auto-graded if possible)&lt;br /&gt;
&lt;br /&gt;
== Phase 3: Pilot &amp;amp; Refinement ==&lt;br /&gt;
Run the training with a small group before full rollout.&lt;br /&gt;
&lt;br /&gt;
=== Internal Pilot ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.1&#039;&#039;&#039; Recruit 3–5 internal Comfac IT staff as pilot students&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.2&#039;&#039;&#039; Run Phase 1 (Foundations) with pilot group — collect feedback&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.3&#039;&#039;&#039; Run Phase 2 (NAT &amp;amp; Services) with pilot group — collect feedback&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.4&#039;&#039;&#039; Run one VPN lab (IPsec or OpenVPN) with pilot group — test resource limits&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.5&#039;&#039;&#039; Document all bugs, confusion points, and timeouts&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.6&#039;&#039;&#039; Refine playbooks and wiki pages based on pilot feedback&lt;br /&gt;
&lt;br /&gt;
=== Resource Tuning ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.1&#039;&#039;&#039; Measure actual CPU/RAM/disk usage per student during pilot&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.2&#039;&#039;&#039; Adjust VM specs if over- or under-provisioned&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.3&#039;&#039;&#039; Test memory overcommit ratios for safe concurrency scaling&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.4&#039;&#039;&#039; Document maximum safe concurrent student count&lt;br /&gt;
&lt;br /&gt;
== Phase 4: Deployment &amp;amp; Operations ==&lt;br /&gt;
Prepare for regular training delivery.&lt;br /&gt;
&lt;br /&gt;
=== Student Onboarding ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.1&#039;&#039;&#039; Create student onboarding guide (how to access portal, use NoVNC, reset lab)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.2&#039;&#039;&#039; Create instructor guide (how to monitor progress, assist students, grade labs)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.3&#039;&#039;&#039; Set up scheduling system (book lab time slots, prevent over-allocation)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.4&#039;&#039;&#039; Create completion certificates or badges&lt;br /&gt;
&lt;br /&gt;
=== Monitoring &amp;amp; Maintenance ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.1&#039;&#039;&#039; Set up host monitoring (Prometheus/Grafana or simple `libvirt` stats)&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.2&#039;&#039;&#039; Configure alerts for host resource exhaustion&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.3&#039;&#039;&#039; Schedule weekly base image updates (pfSense patches, OS updates)&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.4&#039;&#039;&#039; Document disaster recovery (rebuild host from Ansible, restore golden images)&lt;br /&gt;
&lt;br /&gt;
== Quick Status Dashboard ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Phase !! Status !! % Complete !! Blockers&lt;br /&gt;
|-&lt;br /&gt;
| Phase 0: Material Conversion || 🟢 Done (22/23) || 96% || Pending: reference PDF, support files, videos&lt;br /&gt;
|-&lt;br /&gt;
| Phase 1: Infrastructure Setup || 🔴 Not Started || 0% || Need 200-core host access&lt;br /&gt;
|-&lt;br /&gt;
| Phase 2: Curriculum Development || 🟡 In Progress || 65% || Need video recordings, quizzes, pre/post lab pages&lt;br /&gt;
|-&lt;br /&gt;
| Phase 3: Pilot &amp;amp; Refinement || 🔴 Not Started || 0% || Waiting on Phase 1 + 2&lt;br /&gt;
|-&lt;br /&gt;
| Phase 4: Deployment &amp;amp; Operations || 🔴 Not Started || 0% || Waiting on Phase 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Resource Summary ==&lt;br /&gt;
&#039;&#039;&#039;Per-student minimum:&#039;&#039;&#039; 6 vCPUs, 6.5 GB RAM, 62 GB disk&lt;br /&gt;
&#039;&#039;&#039;Per-student full lab:&#039;&#039;&#039; 10 vCPUs, 10.5 GB RAM, 110 GB disk&lt;br /&gt;
&#039;&#039;&#039;200-core / 1TB capacity:&#039;&#039;&#039; 20–40 concurrent students (conservative to optimized)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Next Actions (This Week):&#039;&#039;&#039;&lt;br /&gt;
# Summarize the-pfsense-documentation.pdf into a reference page&lt;br /&gt;
# Document WindowsTrainingSupportFiles.zip contents&lt;br /&gt;
# Catalog training video timestamps&lt;br /&gt;
# Begin Ansible playbook drafting for Lab 1 environment&lt;br /&gt;
# Evaluate Kimchi vs Guacamole for NoVNC portal&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_Setting_Up_a_Firewall_for_Yourself&amp;diff=247</id>
		<title>Training: Setting Up a Firewall for Yourself</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_Setting_Up_a_Firewall_for_Yourself&amp;diff=247"/>
		<updated>2026-04-23T07:21:00Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Create Introduction Training Module 0 - personal/small business firewall setup&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#fff3e0; border:1px solid #ffb74d; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Comfac Entry-Level Training: Module 0&#039;&#039;&#039; — Setting Up a Firewall for Yourself. The most common, practical starting point before advancing to the full FUND001 curriculum.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Target Audience ==&lt;br /&gt;
* Home users who want to secure their network&lt;br /&gt;
* Small business owners (1–10 employees)&lt;br /&gt;
* IT staff new to networking before they tackle enterprise deployments&lt;br /&gt;
* Anyone who has never configured a router or firewall before&lt;br /&gt;
&lt;br /&gt;
== Learning Objectives ==&lt;br /&gt;
By the end of this module, you will be able to:&lt;br /&gt;
* Explain why a firewall is necessary for homes and small offices&lt;br /&gt;
* Install pfSense on an old PC or VM with minimum hardware&lt;br /&gt;
* Configure basic WAN and LAN interfaces&lt;br /&gt;
* Set up essential firewall rules (allow outgoing, block incoming)&lt;br /&gt;
* Configure port forwarding for common services&lt;br /&gt;
* Set up a basic WireGuard VPN for remote access&lt;br /&gt;
* Back up and update the firewall configuration&lt;br /&gt;
* Diagnose common connectivity problems&lt;br /&gt;
&lt;br /&gt;
== Module 0: Why You Need a Firewall ==&lt;br /&gt;
=== The Threats at Home and Small Office ===&lt;br /&gt;
Most people rely on the &amp;quot;router&amp;quot; provided by their ISP. These devices are:&lt;br /&gt;
* &#039;&#039;&#039;Minimally configured&#039;&#039;&#039; — often with default passwords and outdated firmware&lt;br /&gt;
* &#039;&#039;&#039;Poorly maintained&#039;&#039;&#039; — ISPs rarely push security updates promptly&lt;br /&gt;
* &#039;&#039;&#039;Limited in features&#039;&#039;&#039; — no VPN, no traffic logging, no intrusion detection&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Common risks:&#039;&#039;&#039;&lt;br /&gt;
* Unauthorized remote access to cameras, NAS, printers&lt;br /&gt;
* Malware spreading between family/employee devices&lt;br /&gt;
* Cryptojacking, ransomware, botnet participation&lt;br /&gt;
* Data exfiltration from poorly secured IoT devices&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What a firewall gives you:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Stateful inspection&#039;&#039;&#039; — only allows return traffic for connections you initiated&lt;br /&gt;
* &#039;&#039;&#039;Network segmentation&#039;&#039;&#039; — isolate guests, IoT, and work devices&lt;br /&gt;
* &#039;&#039;&#039;VPN access&#039;&#039;&#039; — securely access your home/office network from anywhere&lt;br /&gt;
* &#039;&#039;&#039;Logging &amp;amp; visibility&#039;&#039;&#039; — see what devices are doing on your network&lt;br /&gt;
* &#039;&#039;&#039;Ad and malware blocking&#039;&#039;&#039; — integrate with DNS blocklists (Pi-hole)&lt;br /&gt;
&lt;br /&gt;
== Module 1: Hardware and Installation ==&lt;br /&gt;
=== Minimum Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! Minimum !! Recommended&lt;br /&gt;
|-&lt;br /&gt;
| CPU || 64-bit, 1 GHz || 64-bit, 2+ cores, AES-NI support&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 1 GB || 4 GB&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 8 GB SSD/USB || 32 GB SSD&lt;br /&gt;
|-&lt;br /&gt;
| NICs || 2 Ethernet ports || Intel i210/i350 dual/quad port NIC&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Good sources of cheap hardware:&#039;&#039;&#039;&lt;br /&gt;
* Old office desktops (Dell OptiPlex, HP EliteDesk)&lt;br /&gt;
* Thin clients with PCIe slot for NIC&lt;br /&gt;
* Used 1U servers (noisy but cheap)&lt;br /&gt;
* Protectli/Qotom mini-PCs (purpose-built, fanless)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Installation methods:&#039;&#039;&#039;&lt;br /&gt;
# Download pfSense CE ISO from https://www.pfsense.org/downloads&lt;br /&gt;
# Write to USB with Rufus (Windows) or dd (Linux)&lt;br /&gt;
# Boot from USB, install to SSD/HDD&lt;br /&gt;
# Remove USB, reboot&lt;br /&gt;
# Default LAN: 192.168.1.1&lt;br /&gt;
&lt;br /&gt;
== Module 2: First Boot and Basic Setup ==&lt;br /&gt;
=== The Setup Wizard ===&lt;br /&gt;
# Connect laptop to LAN port&lt;br /&gt;
# Browse to https://192.168.1.1&lt;br /&gt;
# Log in: admin / pfsense&lt;br /&gt;
# Complete the wizard:&lt;br /&gt;
#* &#039;&#039;&#039;General Info&#039;&#039;&#039; — Set hostname (e.g., homefw), domain (local)&lt;br /&gt;
#* &#039;&#039;&#039;Time Server&#039;&#039;&#039; — Use default or local NTP&lt;br /&gt;
#* &#039;&#039;&#039;WAN&#039;&#039;&#039; — Select DHCP (most home/DSL) or PPPoE (some fiber)&lt;br /&gt;
#* &#039;&#039;&#039;LAN&#039;&#039;&#039; — Leave 192.168.1.1/24 or change to obscure subnet (e.g., 10.47.83.1/24)&lt;br /&gt;
#* &#039;&#039;&#039;Password&#039;&#039;&#039; — Change from default immediately&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Why change from 192.168.1.1?&#039;&#039;&#039; If you later connect via VPN from a coffee shop that also uses 192.168.1.x, your traffic may not route correctly. Using an obscure subnet avoids this.&lt;br /&gt;
&lt;br /&gt;
=== Essential Post-Setup ===&lt;br /&gt;
# &#039;&#039;&#039;System -&amp;gt; General Setup&#039;&#039;&#039; — Set timezone, language&lt;br /&gt;
# &#039;&#039;&#039;System -&amp;gt; Advanced -&amp;gt; Networking&#039;&#039;&#039; — Disable NAT reflection if not needed&lt;br /&gt;
# &#039;&#039;&#039;System -&amp;gt; Update&#039;&#039;&#039; — Check for updates immediately&lt;br /&gt;
# &#039;&#039;&#039;Diagnostics -&amp;gt; Backup &amp;amp; Restore&#039;&#039;&#039; — Download first config backup&lt;br /&gt;
&lt;br /&gt;
== Module 3: Essential Firewall Rules ==&lt;br /&gt;
=== Default Rules (pfSense handles these automatically) ===&lt;br /&gt;
* &#039;&#039;&#039;LAN&#039;&#039;&#039; — Allow all (default)&lt;br /&gt;
* &#039;&#039;&#039;WAN&#039;&#039;&#039; — Block all (implicit, not shown)&lt;br /&gt;
&lt;br /&gt;
=== Best Practice: Restrict LAN Outbound ===&lt;br /&gt;
For a more secure home/small office, replace &amp;quot;LAN allow all&amp;quot; with specific allowed protocols:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Protocol !! Port !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| TCP/UDP || 53 || DNS&lt;br /&gt;
|-&lt;br /&gt;
| TCP/UDP || 123 || NTP&lt;br /&gt;
|-&lt;br /&gt;
| TCP/UDP || 443 || HTTPS&lt;br /&gt;
|-&lt;br /&gt;
| TCP || 80 || HTTP (optional)&lt;br /&gt;
|-&lt;br /&gt;
| TCP/UDP || 5222 || XMPP/chat (optional)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to do it:&#039;&#039;&#039;&lt;br /&gt;
# Firewall -&amp;gt; Rules -&amp;gt; LAN&lt;br /&gt;
# Delete the default &amp;quot;Allow All&amp;quot; rule&lt;br /&gt;
# Add rules for each protocol/port above&lt;br /&gt;
# Add a final &amp;quot;Block&amp;quot; rule at the bottom (with logging enabled)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; This breaks some apps/games. For a family home, &amp;quot;Allow All&amp;quot; outbound is usually fine. For a business, restrict outbound.&lt;br /&gt;
&lt;br /&gt;
== Module 4: Port Forwarding ===&lt;br /&gt;
=== Common Scenarios ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Service !! External Port !! Internal IP !! Internal Port !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Minecraft server || 25565 || 192.168.1.50 || 25565 || Gaming&lt;br /&gt;
|-&lt;br /&gt;
| Camera/DVR || 8080 || 192.168.1.60 || 80 || Change default port&lt;br /&gt;
|-&lt;br /&gt;
| NAS/Web || 443 || 192.168.1.70 || 443 || Use reverse proxy if multiple services&lt;br /&gt;
|-&lt;br /&gt;
| Plex || 32400 || 192.168.1.80 || 32400 || Remote streaming&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps:&#039;&#039;&#039;&lt;br /&gt;
# Firewall -&amp;gt; NAT -&amp;gt; Port Forward&lt;br /&gt;
# Click Add&lt;br /&gt;
# Interface: WAN&lt;br /&gt;
# Protocol: TCP (or TCP/UDP)&lt;br /&gt;
# Destination: WAN Address&lt;br /&gt;
# Destination Port Range: external port&lt;br /&gt;
# Redirect Target IP: internal server IP&lt;br /&gt;
# Redirect Target Port: internal port&lt;br /&gt;
# Save → Apply&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Security tip:&#039;&#039;&#039; Don&#039;t forward RDP (3389) or SSH (22) directly. Use a VPN instead.&lt;br /&gt;
&lt;br /&gt;
== Module 5: WireGuard VPN (Road Warrior) ==&lt;br /&gt;
=== Why VPN beats port forwarding ===&lt;br /&gt;
* One secure tunnel instead of many open ports&lt;br /&gt;
* Access your entire network as if you were there&lt;br /&gt;
* Works on phones, laptops, tablets&lt;br /&gt;
* No need to expose individual services&lt;br /&gt;
&lt;br /&gt;
=== Setup Steps ===&lt;br /&gt;
# Install &#039;&#039;&#039;WireGuard package&#039;&#039;&#039; — System -&amp;gt; Package Manager -&amp;gt; Available Packages&lt;br /&gt;
# VPN -&amp;gt; WireGuard -&amp;gt; Settings → Enable&lt;br /&gt;
# Tunnels → Add Tunnel&lt;br /&gt;
#* Name: RoadWarrior&lt;br /&gt;
#* Listen Port: 51820&lt;br /&gt;
#* Interface Keys: Generate key pair&lt;br /&gt;
# Save&lt;br /&gt;
# Assign interface — Interfaces -&amp;gt; Assignments → add wg0 as OPTx&lt;br /&gt;
# Enable interface, set static IP: 10.200.200.1/24&lt;br /&gt;
# Peers → Add Peer&lt;br /&gt;
#* Tunnel: RoadWarrior&lt;br /&gt;
#* Public Key: [client&#039;s public key]&lt;br /&gt;
#* Allowed IPs: 10.200.200.2/32&lt;br /&gt;
#* Endpoint: [blank for roaming clients]&lt;br /&gt;
# Firewall -&amp;gt; Rules -&amp;gt; WireGuard interface → Allow All&lt;br /&gt;
# Firewall -&amp;gt; Rules -&amp;gt; LAN → Allow from WireGuard net&lt;br /&gt;
# Firewall -&amp;gt; NAT -&amp;gt; Outbound → Manual → Add rule for WireGuard net → WAN&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Client config (phone/laptop):&#039;&#039;&#039;&lt;br /&gt;
* Install WireGuard app&lt;br /&gt;
* Create tunnel, scan QR code or paste config&lt;br /&gt;
* Peer: [server public key], Endpoint: your-public-ip:51820&lt;br /&gt;
* Allowed IPs: 0.0.0.0/0 (full tunnel) or 192.168.1.0/24 (split tunnel)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Opening the port:&#039;&#039;&#039;&lt;br /&gt;
# Firewall -&amp;gt; Rules -&amp;gt; WAN&lt;br /&gt;
# Add rule: Protocol UDP, Port 51820, Source Any, Destination WAN Address&lt;br /&gt;
&lt;br /&gt;
== Module 6: Backup and Maintenance ==&lt;br /&gt;
=== Monthly Checklist ===&lt;br /&gt;
* [ ] System -&amp;gt; Update: Check for updates&lt;br /&gt;
* [ ] Diagnostics -&amp;gt; Backup &amp;amp; Restore: Download config backup&lt;br /&gt;
* [ ] Check Dashboard for interface errors, high CPU, or memory usage&lt;br /&gt;
* [ ] Review Firewall logs for blocked suspicious traffic&lt;br /&gt;
* [ ] Verify VPN clients can still connect&lt;br /&gt;
&lt;br /&gt;
=== Yearly Checklist ===&lt;br /&gt;
* [ ] Rotate WireGuard keys&lt;br /&gt;
* [ ] Review all port forwards — remove unused ones&lt;br /&gt;
* [ ] Check certificate expiry (if using ACME/Let&#039;s Encrypt)&lt;br /&gt;
* [ ] Audit user accounts and passwords&lt;br /&gt;
* [ ] Test restore from backup on a spare VM&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting Common Problems ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Problem !! Likely Cause !! Fix&lt;br /&gt;
|-&lt;br /&gt;
| No Internet after install || WAN not getting IP || Check cable; set WAN to DHCP or PPPoE&lt;br /&gt;
|-&lt;br /&gt;
| Can&#039;t access web GUI || Wrong IP; HTTPS blocked || Try http://192.168.1.1; check laptop IP&lt;br /&gt;
|-&lt;br /&gt;
| Port forward not working || ISP CGNAT || Check WAN IP vs public IP; use VPN instead&lt;br /&gt;
|-&lt;br /&gt;
| VPN connects but no LAN access || Missing firewall/NAT rule || Add allow rule on WireGuard iface; add outbound NAT&lt;br /&gt;
|-&lt;br /&gt;
| Slow Internet || Hardware too weak || Check CPU usage; upgrade NIC or whole box&lt;br /&gt;
|-&lt;br /&gt;
| Can&#039;t reach some websites || DNS issue || Use 1.1.1.1 or 8.8.8.8 in DNS Resolver forwarders&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Build Your Own Firewall — Capstone Exercise ==&lt;br /&gt;
&#039;&#039;&#039;Scenario:&#039;&#039;&#039; You have an old Dell OptiPlex, a 2-port Intel NIC, and a home fiber connection.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Requirements:&#039;&#039;&#039;&lt;br /&gt;
# Install pfSense CE&lt;br /&gt;
# Configure WAN (DHCP) and LAN (static 10.47.83.1/24)&lt;br /&gt;
# Set admin password&lt;br /&gt;
# Enable DNS Resolver with forwarding to Cloudflare (1.1.1.1)&lt;br /&gt;
# Create firewall rules: allow DNS, HTTPS, NTP outbound only&lt;br /&gt;
# Set up WireGuard for 2 devices (phone + laptop)&lt;br /&gt;
# Forward port 32400 to a Plex server at 10.47.83.50&lt;br /&gt;
# Enable AutoConfigBackup (or manual monthly backups)&lt;br /&gt;
# Document everything in a simple runbook&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Success criteria:&#039;&#039;&#039;&lt;br /&gt;
* Family can browse web normally&lt;br /&gt;
* You can VPN in from outside and access LAN resources&lt;br /&gt;
* Plex is accessible remotely&lt;br /&gt;
* Configuration is backed up&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
Once comfortable with this module, advance to the full &#039;&#039;&#039;FUND001 curriculum&#039;&#039;&#039;:&lt;br /&gt;
# [[Training: pfSense Introduction]] — Phase 1, Day 1&lt;br /&gt;
# [[Training Lab 1: Introduction and Backup Restore]] — Hands-on lab&lt;br /&gt;
&lt;br /&gt;
Or explore specialized topics:&lt;br /&gt;
* [[Training: pfSense Services]] — DHCP, DNS, Dynamic DNS deep dive&lt;br /&gt;
* [[Training: Multi-WAN]] — Add a backup ISP connection&lt;br /&gt;
* [[Networking PfSense Index]] — All Comfac networking resources&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&#039;&#039;This module was created for Comfac IT practical training. Built on real-world frequency of problems encountered from personal to small-business networks.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_Monitoring_and_Packages&amp;diff=246</id>
		<title>Training: Monitoring and Packages</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_Monitoring_and_Packages&amp;diff=246"/>
		<updated>2026-04-23T07:16:09Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#1e3a5f; color:#fff; padding:12px; border-radius:6px; margin-bottom:16px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:1.2em; font-weight:bold;&amp;quot;&amp;gt;📘 Netgate pfSense Training — Module 11&amp;lt;/span&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
System Monitoring, Logging, and the Package System&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Learning Objectives ==&lt;br /&gt;
&lt;br /&gt;
By the end of this module, you should be able to:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Objective&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Monitor system health&lt;br /&gt;
| Use built-in Status pages, Traffic Graphs, and RRD Graphs to observe system performance.&lt;br /&gt;
|-&lt;br /&gt;
| Configure logging&lt;br /&gt;
| Access system logs and export them to an external log aggregation server.&lt;br /&gt;
|-&lt;br /&gt;
| Understand SNMP&lt;br /&gt;
| Enable and use SNMP for remote monitoring and integration with NMS tools.&lt;br /&gt;
|-&lt;br /&gt;
| Manage packages&lt;br /&gt;
| Install, update, and remove packages to extend pfSense functionality.&lt;br /&gt;
|-&lt;br /&gt;
| Evaluate package maturity&lt;br /&gt;
| Interpret version numbers (e.g., 0.x = young package) and assess stability.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Monitoring ==&lt;br /&gt;
&lt;br /&gt;
=== Status Pages ===&lt;br /&gt;
&lt;br /&gt;
pfSense provides many built-in &#039;&#039;&#039;Status&#039;&#039;&#039; pages that give real-time and historical insight into system behavior:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Dashboard&#039;&#039;&#039; — customizable overview with widgets for system info, interfaces, services, and gateways.&lt;br /&gt;
* &#039;&#039;&#039;Traffic Graph&#039;&#039;&#039; — live view of traffic per interface.&lt;br /&gt;
* &#039;&#039;&#039;RRD Graphs&#039;&#039;&#039; — historical data for CPU, memory, interface traffic, packets, states, and quality.&lt;br /&gt;
* &#039;&#039;&#039;System Logs&#039;&#039;&#039; — consolidated logging for the firewall, DHCP, DNS, VPN, and other services.&lt;br /&gt;
&lt;br /&gt;
=== RRD Graphs ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RRDtool&#039;&#039;&#039; is integrated into pfSense to store and graph time-series data. Available graphs include:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Category&lt;br /&gt;
! Metrics&lt;br /&gt;
|-&lt;br /&gt;
| System&lt;br /&gt;
| CPU usage, memory usage, swap usage, load average&lt;br /&gt;
|-&lt;br /&gt;
| Traffic&lt;br /&gt;
| Inbound/outbound bytes and packets per interface&lt;br /&gt;
|-&lt;br /&gt;
| Packets&lt;br /&gt;
| Passed, blocked, and error packet counts&lt;br /&gt;
|-&lt;br /&gt;
| Quality&lt;br /&gt;
| Gateway latency and packet loss over time&lt;br /&gt;
|-&lt;br /&gt;
| States&lt;br /&gt;
| Current firewall state table size&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SNMP Monitoring ===&lt;br /&gt;
&lt;br /&gt;
pfSense includes an &#039;&#039;&#039;SNMP service&#039;&#039;&#039; (via &#039;&#039;&#039;bsnmpd&#039;&#039;&#039;) that allows remote monitoring with tools such as:&lt;br /&gt;
&lt;br /&gt;
* Zabbix&lt;br /&gt;
* Nagios / Icinga&lt;br /&gt;
* Cacti&lt;br /&gt;
* PRTG&lt;br /&gt;
* LibreNMS&lt;br /&gt;
&lt;br /&gt;
Enable SNMP under &#039;&#039;&#039;Services → SNMP&#039;&#039;&#039; and configure community strings, traps, and binding interfaces as needed.&lt;br /&gt;
&lt;br /&gt;
=== Logging ===&lt;br /&gt;
&lt;br /&gt;
System logs are available under the &#039;&#039;&#039;Status → System Logs&#039;&#039;&#039; menu. Key capabilities:&lt;br /&gt;
&lt;br /&gt;
* View logs by category (Firewall, DHCP, DNS Resolver, VPN, etc.)&lt;br /&gt;
* Adjust log verbosity and retention&lt;br /&gt;
* &#039;&#039;&#039;Export logs&#039;&#039;&#039; to an external log aggregation server (e.g., Syslog, Graylog, ELK stack, Splunk) for centralized analysis&lt;br /&gt;
&lt;br /&gt;
== Package System ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Package System&#039;&#039;&#039; extends pfSense beyond the base installation. Packages are installed from the official Netgate repository via &#039;&#039;&#039;System → Package Manager&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Common and Popular Packages ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Package&lt;br /&gt;
! Purpose&lt;br /&gt;
! Category&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;pfBlockerNG&#039;&#039;&#039;&lt;br /&gt;
| IP and DNS-based blocking for geo-location, threat feeds, and ad blocking&lt;br /&gt;
| Security / Filtering&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Suricata&#039;&#039;&#039;&lt;br /&gt;
| High-performance Network IDS/IPS with rule-based threat detection&lt;br /&gt;
| Security&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Snort&#039;&#039;&#039;&lt;br /&gt;
| Network intrusion detection and prevention system&lt;br /&gt;
| Security&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;HAProxy&#039;&#039;&#039;&lt;br /&gt;
| TCP/HTTP load balancer and reverse proxy&lt;br /&gt;
| Traffic Management&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Squid / SquidGuard&#039;&#039;&#039;&lt;br /&gt;
| Web proxy with content filtering and access control&lt;br /&gt;
| Proxy / Filtering&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;pfSense-pkg-FRR&#039;&#039;&#039;&lt;br /&gt;
| Routing protocols (BGP, OSPF, RIP)&lt;br /&gt;
| Routing&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;ntopng&#039;&#039;&#039;&lt;br /&gt;
| Network traffic probe and flow analysis&lt;br /&gt;
| Monitoring&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;NRPE / Zabbix Agent&#039;&#039;&#039;&lt;br /&gt;
| Client agents for remote monitoring integration&lt;br /&gt;
| Monitoring&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;ACME&#039;&#039;&#039;&lt;br /&gt;
| Automatic SSL/TLS certificate issuance via Let&#039;s Encrypt&lt;br /&gt;
| Certificates&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Telegraf&#039;&#039;&#039;&lt;br /&gt;
| Metrics collection agent for InfluxDB/Prometheus&lt;br /&gt;
| Monitoring&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Package Installation Best Practices ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Pay attention to version numbers!&#039;&#039;&#039; A version of &#039;&#039;&#039;0.n&#039;&#039;&#039; typically indicates a young or experimental package.&lt;br /&gt;
* Install packages only from the official repository or trusted sources.&lt;br /&gt;
* Use &#039;&#039;&#039;Backup / Restore&#039;&#039;&#039; to preserve package states for reinstallation after upgrades.&lt;br /&gt;
* Review package documentation before installing in production.&lt;br /&gt;
&lt;br /&gt;
=== Backup and Restore for Packages ===&lt;br /&gt;
&lt;br /&gt;
pfSense&#039;s built-in backup system includes an option to reinstall packages automatically after a restore. Ensure this option is enabled under &#039;&#039;&#039;Diagnostics → Backup &amp;amp; Restore&#039;&#039;&#039; when creating configuration backups.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* pfSense provides robust &#039;&#039;&#039;system monitoring&#039;&#039;&#039; through Status pages, Traffic Graphs, &#039;&#039;&#039;RRD Graphs&#039;&#039;&#039;, and &#039;&#039;&#039;SNMP&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;System logs&#039;&#039;&#039; can be viewed locally or exported to external aggregation servers for centralized analysis.&lt;br /&gt;
* The &#039;&#039;&#039;Package System&#039;&#039;&#039; dramatically extends pfSense capabilities with popular additions such as &#039;&#039;&#039;pfBlockerNG&#039;&#039;&#039;, &#039;&#039;&#039;Suricata&#039;&#039;&#039;, &#039;&#039;&#039;HAProxy&#039;&#039;&#039;, and &#039;&#039;&#039;Squid&#039;&#039;&#039;.&lt;br /&gt;
* Always evaluate &#039;&#039;&#039;package maturity&#039;&#039;&#039; (version numbers) and maintain &#039;&#039;&#039;backups&#039;&#039;&#039; before making significant changes.&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
&lt;br /&gt;
* Previous: [[Training: Firewall Rules and NAT]]&lt;br /&gt;
* Next: [[Training: VPN Configuration]]&lt;br /&gt;
* Return to [[Training: pfSense Course Index]]&lt;br /&gt;
&lt;br /&gt;
== Source Attribution ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Source:&#039;&#039;&#039; Netgate pfSense Training Material&lt;br /&gt;
* &#039;&#039;&#039;Document:&#039;&#039;&#039; FUND001-LIVE-SLIDE-SEG11-OTHER.pdf&lt;br /&gt;
* &#039;&#039;&#039;Section:&#039;&#039;&#039; 11 — Other Features (Monitoring, Logging, Packages)&lt;br /&gt;
* &#039;&#039;&#039;Copyright:&#039;&#039;&#039; © 2017 Rubicon Communications dba Netgate&lt;br /&gt;
* &#039;&#039;&#039;Conversion Date:&#039;&#039;&#039; {{CURRENTYEAR}}-{{CURRENTMONTH}}-{{CURRENTDAY}}&lt;br /&gt;
&lt;br /&gt;
[[Category:pfSense Training]]&lt;br /&gt;
[[Category:Network Security]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_Monitoring_and_Packages&amp;diff=245</id>
		<title>Training: Monitoring and Packages</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_Monitoring_and_Packages&amp;diff=245"/>
		<updated>2026-04-23T07:14:48Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created page with &amp;quot;__NOTOC__ &amp;lt;div style=&amp;quot;background:#1e3a5f; color:#fff; padding:12px; border-radius:6px; margin-bottom:16px;&amp;quot;&amp;gt; &amp;lt;span style=&amp;quot;font-size:1.2em; font-weight:bold;&amp;quot;&amp;gt;📘 Netgate pfSense Training — Module 11&amp;lt;/span&amp;gt;&amp;lt;br/&amp;gt; System Monitoring, Logging, and the Package System &amp;lt;/div&amp;gt;  == Learning Objectives ==  By the end of this module, you should be able to:  {| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot; |- ! Objective ! Description |- | Monitor system health | Use built-in Status pages...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#1e3a5f; color:#fff; padding:12px; border-radius:6px; margin-bottom:16px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:1.2em; font-weight:bold;&amp;quot;&amp;gt;📘 Netgate pfSense Training — Module 11&amp;lt;/span&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
System Monitoring, Logging, and the Package System&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Learning Objectives ==&lt;br /&gt;
&lt;br /&gt;
By the end of this module, you should be able to:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Objective&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Monitor system health&lt;br /&gt;
| Use built-in Status pages, Traffic Graphs, and RRD Graphs to observe system performance.&lt;br /&gt;
|-&lt;br /&gt;
| Configure logging&lt;br /&gt;
| Access system logs and export them to an external log aggregation server.&lt;br /&gt;
|-&lt;br /&gt;
| Understand SNMP&lt;br /&gt;
| Enable and use SNMP for remote monitoring and integration with NMS tools.&lt;br /&gt;
|-&lt;br /&gt;
| Manage packages&lt;br /&gt;
| Install, update, and remove packages to extend pfSense functionality.&lt;br /&gt;
|-&lt;br /&gt;
| Evaluate package maturity&lt;br /&gt;
| Interpret version numbers (e.g., 0.x = young package) and assess stability.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Monitoring ==&lt;br /&gt;
&lt;br /&gt;
=== Status Pages ===&lt;br /&gt;
&lt;br /&gt;
pfSense provides many built-in &#039;&#039;&#039;Status&#039;&#039;&#039; pages that give real-time and historical insight into system behavior:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Dashboard&#039;&#039;&#039; — customizable overview with widgets for system info, interfaces, services, and gateways.&lt;br /&gt;
* &#039;&#039;&#039;Traffic Graph&#039;&#039;&#039; — live view of traffic per interface.&lt;br /&gt;
* &#039;&#039;&#039;RRD Graphs&#039;&#039;&#039; — historical data for CPU, memory, interface traffic, packets, states, and quality.&lt;br /&gt;
* &#039;&#039;&#039;System Logs&#039;&#039;&#039; — consolidated logging for the firewall, DHCP, DNS, VPN, and other services.&lt;br /&gt;
&lt;br /&gt;
=== RRD Graphs ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RRDtool&#039;&#039;&#039; is integrated into pfSense to store and graph time-series data. Available graphs include:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Category&lt;br /&gt;
! Metrics&lt;br /&gt;
|-&lt;br /&gt;
| System&lt;br /&gt;
| CPU usage, memory usage, swap usage, load average&lt;br /&gt;
|-&lt;br /&gt;
| Traffic&lt;br /&gt;
| Inbound/outbound bytes and packets per interface&lt;br /&gt;
|-&lt;br /&gt;
| Packets&lt;br /&gt;
| Passed, blocked, and error packet counts&lt;br /&gt;
|-&lt;br /&gt;
| Quality&lt;br /&gt;
| Gateway latency and packet loss over time&lt;br /&gt;
|-&lt;br /&gt;
| States&lt;br /&gt;
| Current firewall state table size&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SNMP Monitoring ===&lt;br /&gt;
&lt;br /&gt;
pfSense includes an &#039;&#039;&#039;SNMP service&#039;&#039;&#039; (via &#039;&#039;&#039;bsnmpd&#039;&#039;&#039;) that allows remote monitoring with tools such as:&lt;br /&gt;
&lt;br /&gt;
* Zabbix&lt;br /&gt;
* Nagios / Icinga&lt;br /&gt;
* Cacti&lt;br /&gt;
* PRTG&lt;br /&gt;
* LibreNMS&lt;br /&gt;
&lt;br /&gt;
Enable SNMP under &#039;&#039;&#039;Services → SNMP&#039;&#039;&#039; and configure community strings, traps, and binding interfaces as needed.&lt;br /&gt;
&lt;br /&gt;
=== Logging ===&lt;br /&gt;
&lt;br /&gt;
System logs are available under the &#039;&#039;&#039;Status → System Logs&#039;&#039;&#039; menu. Key capabilities:&lt;br /&gt;
&lt;br /&gt;
* View logs by category (Firewall, DHCP, DNS Resolver, VPN, etc.)&lt;br /&gt;
* Adjust log verbosity and retention&lt;br /&gt;
* &#039;&#039;&#039;Export logs&#039;&#039;&#039; to an external log aggregation server (e.g., Syslog, Graylog, ELK stack, Splunk) for centralized analysis&lt;br /&gt;
&lt;br /&gt;
== Package System ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Package System&#039;&#039;&#039; extends pfSense beyond the base installation. Packages are installed from the official Netgate repository via &#039;&#039;&#039;System → Package Manager&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Common and Popular Packages ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Package&lt;br /&gt;
! Purpose&lt;br /&gt;
! Category&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;pfBlockerNG&#039;&#039;&#039;&lt;br /&gt;
| IP and DNS-based blocking for geo-location, threat feeds, and ad blocking&lt;br /&gt;
| Security / Filtering&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Suricata&#039;&#039;&#039;&lt;br /&gt;
| High-performance Network IDS/IPS with rule-based threat detection&lt;br /&gt;
| Security&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Snort&#039;&#039;&#039;&lt;br /&gt;
| Network intrusion detection and prevention system&lt;br /&gt;
| Security&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;HAProxy&#039;&#039;&#039;&lt;br /&gt;
| TCP/HTTP load balancer and reverse proxy&lt;br /&gt;
| Traffic Management&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Squid / SquidGuard&#039;&#039;&#039;&lt;br /&gt;
| Web proxy with content filtering and access control&lt;br /&gt;
| Proxy / Filtering&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;pfSense-pkg-FRR&#039;&#039;&#039;&lt;br /&gt;
| Routing protocols (BGP, OSPF, RIP)&lt;br /&gt;
| Routing&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;ntopng&#039;&#039;&#039;&lt;br /&gt;
| Network traffic probe and flow analysis&lt;br /&gt;
| Monitoring&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;NRPE / Zabbix Agent&#039;&#039;&#039;&lt;br /&gt;
| Client agents for remote monitoring integration&lt;br /&gt;
| Monitoring&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;ACME&#039;&#039;&#039;&lt;br /&gt;
| Automatic SSL/TLS certificate issuance via Let&#039;s Encrypt&lt;br /&gt;
| Certificates&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Telegraf&#039;&#039;&#039;&lt;br /&gt;
| Metrics collection agent for InfluxDB/Prometheus&lt;br /&gt;
| Monitoring&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Package Installation Best Practices ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Pay attention to version numbers!&#039;&#039;&#039; A version of &#039;&#039;&#039;0.n&#039;&#039;&#039; typically indicates a young or experimental package.&lt;br /&gt;
* Install packages only from the official repository or trusted sources.&lt;br /&gt;
* Use &#039;&#039;&#039;Backup / Restore&#039;&#039;&#039; to preserve package states for reinstallation after upgrades.&lt;br /&gt;
* Review package documentation before installing in production.&lt;br /&gt;
&lt;br /&gt;
=== Backup and Restore for Packages ===&lt;br /&gt;
&lt;br /&gt;
pfSense&#039;s built-in backup system includes an option to reinstall packages automatically after a restore. Ensure this option is enabled under &#039;&#039;&#039;Diagnostics → Backup&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_9:_Traffic_Shaping&amp;diff=244</id>
		<title>Training Lab 9: Traffic Shaping</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_9:_Traffic_Shaping&amp;diff=244"/>
		<updated>2026-04-23T07:10:26Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Imported from FUND001-LIVE-Lab9-TrafficShaping.pdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#005500; color:white; padding:12px; border-radius:6px; margin-bottom:16px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Netgate pfSense Plus Fundamentals — Lab 9: Traffic Shaping&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;Training lab manual: FUND001-LIVE-Lab9-TrafficShaping.pdf&amp;lt;/small&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This lab covers limiters and traffic shaping at an introductory level.&lt;br /&gt;
&lt;br /&gt;
We will configure limiters to restrict HQ LAN hosts to &#039;&#039;&#039;2 Mb down / 512 Kb up&#039;&#039;&#039;. The mask option of limiters is used to configure this limit on a &#039;&#039;&#039;per-IP basis&#039;&#039;&#039; — so each IP in the LAN gets its own 2 Mb down, 512 Kb up pipe.&lt;br /&gt;
&lt;br /&gt;
== Understanding Limiter Direction ==&lt;br /&gt;
&lt;br /&gt;
Limiters are applied to firewall rules by specifying them under &#039;&#039;&#039;In&#039;&#039;&#039; and &#039;&#039;&#039;Out&#039;&#039;&#039; in the advanced options. The direction of traffic is from the perspective of that interface of the firewall.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Traffic coming into the LAN NIC&#039;&#039;&#039; = upload traffic&lt;br /&gt;
* &#039;&#039;&#039;Traffic leaving the LAN NIC&#039;&#039;&#039; = download traffic&lt;br /&gt;
&lt;br /&gt;
The mask of limiters can be configured on a &#039;&#039;&#039;source address&#039;&#039;&#039; or &#039;&#039;&#039;destination address&#039;&#039;&#039; basis:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Limiter !! Mask Setting !! Reason&lt;br /&gt;
|-&lt;br /&gt;
| Download (2M-down) || Destination addresses || Traffic leaving the LAN interface has internal clients&#039; IPs as the destination.&lt;br /&gt;
|-&lt;br /&gt;
| Upload (512K-up) || Source addresses || Traffic entering the LAN interface is sourced from internal clients&#039; IPs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configuring Limiters ==&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;fw1-HQ&#039;&#039;&#039;, browse to &#039;&#039;&#039;Firewall → Traffic Shaper → Limiters&#039;&#039;&#039; tab. Click &#039;&#039;&#039;New Limiter&#039;&#039;&#039; to add a new limiter.&lt;br /&gt;
&lt;br /&gt;
=== Download Limiter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name || 2M-down&lt;br /&gt;
|-&lt;br /&gt;
| Enable || (checked)&lt;br /&gt;
|-&lt;br /&gt;
| Bandwidth || 2 Mbit/s&lt;br /&gt;
|-&lt;br /&gt;
| Mask || Destination addresses&lt;br /&gt;
|-&lt;br /&gt;
| Description || 2 Mb down per-IP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Leave the remainder at defaults and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Upload Limiter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name || 512K-up&lt;br /&gt;
|-&lt;br /&gt;
| Enable || (checked)&lt;br /&gt;
|-&lt;br /&gt;
| Bandwidth || 512 Kbps&lt;br /&gt;
|-&lt;br /&gt;
| Mask || Source addresses&lt;br /&gt;
|-&lt;br /&gt;
| Description || 512 Kb up per-IP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Leave the remainder at defaults, click &#039;&#039;&#039;Save&#039;&#039;&#039;, then &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Applying Limiters to Firewall Rules ==&lt;br /&gt;
&lt;br /&gt;
Just configuring the limiters doesn&#039;t make them active. They must be assigned to a firewall rule to be applied.&lt;br /&gt;
&lt;br /&gt;
# Browse to &#039;&#039;&#039;Firewall → Rules → LAN&#039;&#039;&#039;.&lt;br /&gt;
# Edit the &#039;&#039;&#039;&amp;quot;Default allow LAN to any&amp;quot;&#039;&#039;&#039; rule.&lt;br /&gt;
# Scroll down under &#039;&#039;&#039;Advanced&#039;&#039;&#039;, and click the &#039;&#039;&#039;Advanced&#039;&#039;&#039; button to the right of &#039;&#039;&#039;In/Out&#039;&#039;&#039;.&lt;br /&gt;
# For the &#039;&#039;&#039;In&#039;&#039;&#039; limiter, choose &#039;&#039;&#039;512K-up&#039;&#039;&#039;.&lt;br /&gt;
# For the &#039;&#039;&#039;Out&#039;&#039;&#039; limiter, choose &#039;&#039;&#039;2M-down&#039;&#039;&#039;.&lt;br /&gt;
# Click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Back at the LAN firewall rules screen, you&#039;ll see the &#039;&#039;&#039;(a)&#039;&#039;&#039; icon to the left of the default LAN rule, meaning one or more advanced options are specified on that rule. Hover your mouse cursor over that button to see what is configured.&lt;br /&gt;
&lt;br /&gt;
== Testing Limiters ==&lt;br /&gt;
&lt;br /&gt;
# Pull up &#039;&#039;&#039;Status → Traffic Graph → WAN&#039;&#039;&#039; on fw1-HQ.&lt;br /&gt;
# Run a speed test (e.g., speedtest.net).&lt;br /&gt;
# You should see speeds of approximately &#039;&#039;&#039;2 Mb down, 512 Kb up&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Traffic Shaper Basic Configuration (Wizard) ==&lt;br /&gt;
&lt;br /&gt;
In this section we configure a basic traffic shaping setup prioritizing VoIP over all else at the branch location (fw1-branch).&lt;br /&gt;
&lt;br /&gt;
=== Wizard Setup ===&lt;br /&gt;
&lt;br /&gt;
# Browse to &#039;&#039;&#039;Firewall → Traffic Shaper → Wizards&#039;&#039;&#039;.&lt;br /&gt;
# Choose &#039;&#039;&#039;traffic_shaper_wizard_multi_all.xml&#039;&#039;&#039;.&lt;br /&gt;
# At the first screen, specify &#039;&#039;&#039;1&#039;&#039;&#039; for the number of WAN and LAN connections and click &#039;&#039;&#039;Next&#039;&#039;&#039;.&lt;br /&gt;
# Choose &#039;&#039;&#039;PRIQ&#039;&#039;&#039; for both download and upload schedulers.&lt;br /&gt;
# Specify connection bandwidth as &#039;&#039;&#039;100 Mbit/s&#039;&#039;&#039; upload and download.&lt;br /&gt;
# Click &#039;&#039;&#039;Next&#039;&#039;&#039;.&lt;br /&gt;
# Check &#039;&#039;&#039;&amp;quot;Prioritize Voice over IP traffic&amp;quot;&#039;&#039;&#039;. Fill in &#039;&#039;&#039;128 Kbit/s&#039;&#039;&#039; for upload and download bandwidth (not actually used with PRIQ).&lt;br /&gt;
# Click &#039;&#039;&#039;Next&#039;&#039;&#039; three times past penalty box, peer-to-peer networking, and network games.&lt;br /&gt;
# At the &#039;&#039;&#039;&amp;quot;Raise or lower other applications&amp;quot;&#039;&#039;&#039; screen, enable it and choose &#039;&#039;&#039;VNC&#039;&#039;&#039; as higher priority.&lt;br /&gt;
# Click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Reviewing Firewall Rule Shaping Configuration ==&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall → Rules → Floating&#039;&#039;&#039; to see the traffic shaper rules added by the wizard. These are match rules which specify the appropriate queue for each type of traffic.&lt;br /&gt;
&lt;br /&gt;
* The VoIP traffic classification ends up as a rule matching all UDP traffic from any source to any destination, with queue &#039;&#039;&#039;qVoIP&#039;&#039;&#039;.&lt;br /&gt;
* All traffic not matching a floating rule specifying a queue will go into the &#039;&#039;&#039;default queue&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Reviewing Shaper Queue Configuration ==&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall → Traffic Shaper&#039;&#039;&#039;. The &#039;&#039;&#039;By Interface&#039;&#039;&#039; and &#039;&#039;&#039;By Queue&#039;&#039;&#039; tabs both show configured queues (two different layouts of the same data).&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;By Queue&#039;&#039;&#039; is typically used for manual configuration.&lt;br /&gt;
* &#039;&#039;&#039;By Interface&#039;&#039;&#039; is the standard review view.&lt;br /&gt;
* You can click &#039;&#039;&#039;&amp;quot;Remove Shaper&amp;quot;&#039;&#039;&#039; on the &#039;&#039;&#039;By Interface&#039;&#039;&#039; tab to remove and disable traffic shaping.&lt;br /&gt;
&lt;br /&gt;
== Testing and Checking Status ==&lt;br /&gt;
&lt;br /&gt;
# Reset all states: &#039;&#039;&#039;Diagnostics → States → Reset States&#039;&#039;&#039; tab → click &#039;&#039;&#039;Reset&#039;&#039;&#039;.&lt;br /&gt;
# Browse to &#039;&#039;&#039;Status → Queues&#039;&#039;&#039; and monitor while generating traffic.&lt;br /&gt;
# Run a speed test — the speed test traffic will fall into the &#039;&#039;&#039;default queue&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Generating SIP Traffic ==&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;SIPp&#039;&#039;&#039; on the test systems:&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;remote-host&#039;&#039;&#039; (100.64.0.50):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@remote-host:~$ sipp -sn uas&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;branch-client&#039;&#039;&#039; (172.18.1.100):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@branch-client:~$ sipp -sn uac 100.64.0.50&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These commands initiate 10 SIP calls per second indefinitely. View &#039;&#039;&#039;Status → Queues&#039;&#039;&#039; while running to see traffic in the VoIP queue.&lt;br /&gt;
&lt;br /&gt;
== Long-term Monitoring ==&lt;br /&gt;
&lt;br /&gt;
When traffic shaping is enabled, RRD graphs include queue statistics and queue drops.&lt;br /&gt;
&lt;br /&gt;
# Browse to &#039;&#039;&#039;Status → Monitoring&#039;&#039;&#039; and click the wrench icon.&lt;br /&gt;
# For &#039;&#039;&#039;Left Axis&#039;&#039;&#039;, choose &#039;&#039;&#039;Queues&#039;&#039;&#039;.&lt;br /&gt;
# The &#039;&#039;&#039;Queue Drops&#039;&#039;&#039; graph shows packets dropped from each queue.&lt;br /&gt;
&lt;br /&gt;
Ideally, you want to see &#039;&#039;&#039;0 drops&#039;&#039;&#039; across all high-priority queues, with drops limited to lower or default priority traffic.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f0f8ff; padding:10px; border-left:4px solid #005500;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Previous Module:&#039;&#039;&#039; [[Training:_Traffic_Shaping|Section 9 — Traffic Shaping (Slides)]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Source Attribution ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Document:&#039;&#039;&#039; FUND001-LIVE-Lab9-TrafficShaping.pdf&lt;br /&gt;
* &#039;&#039;&#039;Course:&#039;&#039;&#039; pfSense Plus Fundamentals and Practical Applications&lt;br /&gt;
* &#039;&#039;&#039;Copyright:&#039;&#039;&#039; © 2021 Rubicon Communications, LLC (Netgate)&lt;br /&gt;
* &#039;&#039;&#039;Extracted and formatted for internal training wiki.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_Traffic_Shaping&amp;diff=243</id>
		<title>Training: Traffic Shaping</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_Traffic_Shaping&amp;diff=243"/>
		<updated>2026-04-23T07:10:06Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Imported from FUND001-LIVE-SLIDE-SEG9-SHAPE.pdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#003366; color:white; padding:12px; border-radius:6px; margin-bottom:16px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Netgate pfSense Plus Fundamentals — Section 9: Traffic Shaping&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;Training slide deck: FUND001-LIVE-SLIDE-SEG9-SHAPE.pdf&amp;lt;/small&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Traffic Shaping — Overview ==&lt;br /&gt;
&lt;br /&gt;
Traffic shaping is a form of &#039;&#039;&#039;managed unfairness of bandwidth&#039;&#039;&#039;. It helps avoid the default FIFO queueing behavior imposed by ISPs.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Queues&#039;&#039;&#039; define traffic priorities.&lt;br /&gt;
* &#039;&#039;&#039;Rules&#039;&#039;&#039; assign traffic to queues.&lt;br /&gt;
* There are two separate methods for shaping:&lt;br /&gt;
** &#039;&#039;&#039;Limiters&#039;&#039;&#039; (dummynet pipes)&lt;br /&gt;
** &#039;&#039;&#039;Traffic Shaper&#039;&#039;&#039; (ALTQ)&lt;br /&gt;
&lt;br /&gt;
== Limiters ==&lt;br /&gt;
&lt;br /&gt;
Limiters provide a quick, easy means of imposing &#039;&#039;&#039;hard bandwidth limits&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* Can be applied on a &#039;&#039;&#039;group or per-IP basis&#039;&#039;&#039;.&lt;br /&gt;
* Optionally &#039;&#039;&#039;schedule-based&#039;&#039;&#039;.&lt;br /&gt;
* Advanced options include:&lt;br /&gt;
** Queue size&lt;br /&gt;
** Delay&lt;br /&gt;
** Packet Loss&lt;br /&gt;
&lt;br /&gt;
== Traffic Shaping Rules ==&lt;br /&gt;
&lt;br /&gt;
* Rules are evaluated from the &#039;&#039;&#039;point of view of traffic leaving an interface&#039;&#039;&#039;.&lt;br /&gt;
* Typically use &#039;&#039;&#039;floating rules&#039;&#039;&#039; to apply shaping.&lt;br /&gt;
* &#039;&#039;&#039;In/Out&#039;&#039;&#039; options under advanced rule options are used to assign queues.&lt;br /&gt;
* Matches only assign queues — they do not control access.&lt;br /&gt;
&lt;br /&gt;
== Traffic Shaping Wizards ==&lt;br /&gt;
&lt;br /&gt;
The wizards offer an easy way to implement queueing and attempt to automate common scenarios.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Wizard Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Multiple LAN/WAN || Most common scenario&lt;br /&gt;
|-&lt;br /&gt;
| Dedicated Links || For dedicated link configurations&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Traffic Shaping Schedulers ==&lt;br /&gt;
&lt;br /&gt;
Schedulers are methods of handling queueing. The following schedulers are available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Scheduler !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| HFSC || Hierarchical Fair Service Curve&lt;br /&gt;
|-&lt;br /&gt;
| CBQ || Class-Based Queueing&lt;br /&gt;
|-&lt;br /&gt;
| FAIRQ || Legacy scheduler&lt;br /&gt;
|-&lt;br /&gt;
| CODELQ || Legacy scheduler&lt;br /&gt;
|-&lt;br /&gt;
| PRIQ || &#039;&#039;&#039;Easiest solution — recommended wherever possible&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Section 9 Summary ==&lt;br /&gt;
&lt;br /&gt;
* Try to keep configurations as simple as possible.&lt;br /&gt;
* Use &#039;&#039;&#039;PRIQ&#039;&#039;&#039; wherever possible.&lt;br /&gt;
* Limiter rules can be on a schedule.&lt;br /&gt;
* Limiters can be per-IP or per-network (masking).&lt;br /&gt;
* Ensure appropriate rule matches.&lt;br /&gt;
* Clear states if needed after making changes.&lt;br /&gt;
* Check the Traffic-Shaping section of the book for more details.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f0f8ff; padding:10px; border-left:4px solid #003366;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Next Module:&#039;&#039;&#039; [[Training_Lab_9:_Traffic_Shaping|Lab 9 — Traffic Shaping (Hands-on)]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Source Attribution ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Document:&#039;&#039;&#039; FUND001-LIVE-SLIDE-SEG9-SHAPE.pdf&lt;br /&gt;
* &#039;&#039;&#039;Course:&#039;&#039;&#039; pfSense Plus Fundamentals and Practical Applications&lt;br /&gt;
* &#039;&#039;&#039;Copyright:&#039;&#039;&#039; © 2017 Rubicon Communications, LLC dba Netgate&lt;br /&gt;
* &#039;&#039;&#039;Extracted and formatted for internal training wiki.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_7:_WireGuard&amp;diff=242</id>
		<title>Training Lab 7: WireGuard</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_7:_WireGuard&amp;diff=242"/>
		<updated>2026-04-23T07:09:24Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created page with &amp;quot;__NOTOC__  &amp;lt;div style=&amp;quot;background:#e7f3ff;border:1px solid #a3c6ff;padding:10px;margin-bottom:15px;&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Training Lab 7: WireGuard Site-to-Site VPN&amp;#039;&amp;#039;&amp;#039; — pfSense Plus Fundamentals and Practical Application &amp;lt;/div&amp;gt;  == Overview ==  This lab goes through an example configuration of WireGuard for site-to-site VPNs.  WireGuard has no concept of sessions or connections. The protocol uses public and private keys to authenticate and route traffic. WireGuard instances consist of...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#e7f3ff;border:1px solid #a3c6ff;padding:10px;margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Training Lab 7: WireGuard Site-to-Site VPN&#039;&#039;&#039; — pfSense Plus Fundamentals and Practical Application&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This lab goes through an example configuration of WireGuard for site-to-site VPNs.&lt;br /&gt;
&lt;br /&gt;
WireGuard has no concept of sessions or connections. The protocol uses public and private keys to authenticate and route traffic. WireGuard instances consist of a tunnel and one or more peer definitions which contain the necessary keys and other configuration data that allows the two sides to communicate.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Delete OpenVPN ==&lt;br /&gt;
&lt;br /&gt;
First, since we have an OpenVPN configured here already, we need to delete it so it doesn’t interfere with our WireGuard setup. On both fw1-HQ and fw1-branch, browse to &#039;&#039;&#039;VPN → OpenVPN&#039;&#039;&#039; and delete all client and server instances.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Configure WireGuard Settings ==&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;VPN → WireGuard → Settings&#039;&#039;&#039; on both firewalls and:&lt;br /&gt;
&lt;br /&gt;
* Click the &#039;&#039;&#039;Enable&#039;&#039;&#039; checkbox&lt;br /&gt;
* For Interface Group Membership, choose &#039;&#039;&#039;Only Unassigned Tunnels&#039;&#039;&#039;&lt;br /&gt;
* Uncheck &#039;&#039;&#039;Hide Secrets&#039;&#039;&#039; and &#039;&#039;&#039;Hide Peers&#039;&#039;&#039;&lt;br /&gt;
* Scroll down and click &#039;&#039;&#039;Save&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Step 3: Add a New Tunnel on Both Firewalls ==&lt;br /&gt;
&lt;br /&gt;
On FW1-HQ and Branch-FW, navigate to &#039;&#039;&#039;VPN → WireGuard → Tunnels&#039;&#039;&#039; and click the green &#039;&#039;&#039;+Add Tunnel&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Enabled || checked&lt;br /&gt;
|-&lt;br /&gt;
| Description || Site-to-Site VPN&lt;br /&gt;
|-&lt;br /&gt;
| Listen Port || 51820&lt;br /&gt;
|-&lt;br /&gt;
| Interface Keys || Press the blue Generate button&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Make a note of the public key on &#039;&#039;&#039;BOTH&#039;&#039;&#039; firewalls, as this will be required later. Then click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Step 4: Configure a Peer on FW1-HQ ==&lt;br /&gt;
&lt;br /&gt;
Edit the tunnel on FW1-HQ and click &#039;&#039;&#039;+Add Peer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Enable || checked&lt;br /&gt;
|-&lt;br /&gt;
| Description || Branch Office Peer&lt;br /&gt;
|-&lt;br /&gt;
| Dynamic Endpoint || unchecked&lt;br /&gt;
|-&lt;br /&gt;
| Endpoint || 203.0.113.10&lt;br /&gt;
|-&lt;br /&gt;
| Endpoint Port || 51820&lt;br /&gt;
|-&lt;br /&gt;
| Public Key || (paste public key from Branch-FW)&lt;br /&gt;
|-&lt;br /&gt;
| Pre-shared Key || (blank)&lt;br /&gt;
|-&lt;br /&gt;
| Allowed IPs || 10.6.210.0/30 (Tunnel Network), 172.18.1.0/24 (Branch LAN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Scroll down and click &#039;&#039;&#039;Save Peer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Step 5: Configure a Peer on Branch-FW ==&lt;br /&gt;
&lt;br /&gt;
Edit the tunnel on Branch-FW and click &#039;&#039;&#039;+Add Peer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Enable || checked&lt;br /&gt;
|-&lt;br /&gt;
| Description || HQ Peer&lt;br /&gt;
|-&lt;br /&gt;
| Dynamic Endpoint || unchecked&lt;br /&gt;
|-&lt;br /&gt;
| Endpoint || 192.0.2.2&lt;br /&gt;
|-&lt;br /&gt;
| Endpoint Port || 51820&lt;br /&gt;
|-&lt;br /&gt;
| Public Key || (paste public key from FW1-HQ)&lt;br /&gt;
|-&lt;br /&gt;
| Pre-shared Key || (blank)&lt;br /&gt;
|-&lt;br /&gt;
| Allowed IPs || 10.6.210.0/30 (Tunnel Network), 172.17.1.0/24 (HQ LAN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Scroll down and click &#039;&#039;&#039;Save Peer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Step 6: Assign Interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== Select Default Gateways ===&lt;br /&gt;
&lt;br /&gt;
On both firewalls, navigate to &#039;&#039;&#039;System → Routing&#039;&#039;&#039; and set Default Gateway IPv4 to a specific gateway, such as WANGW. Click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Assign WireGuard Interface on FW1-HQ ===&lt;br /&gt;
&lt;br /&gt;
Navigate to &#039;&#039;&#039;Interfaces → Assignments&#039;&#039;&#039;, choose the tun_gw0 interface, and click &#039;&#039;&#039;+Add&#039;&#039;&#039; (creates OPT4). Configure OPT4:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Enable || checked&lt;br /&gt;
|-&lt;br /&gt;
| Description || BRANCH_VPN&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Configuration Type || Static IPv4&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Address || 10.6.210.1/30&lt;br /&gt;
|-&lt;br /&gt;
| Gateway Name || VPN_BRANCHGW&lt;br /&gt;
|-&lt;br /&gt;
| Gateway IPv4 || 10.6.210.2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Assign WireGuard Interface on Branch-FW ===&lt;br /&gt;
&lt;br /&gt;
Navigate to &#039;&#039;&#039;Interfaces → Assignments&#039;&#039;&#039;, choose the tun_gw0 interface, and click &#039;&#039;&#039;+Add&#039;&#039;&#039; (creates OPT1). Configure OPT1:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Enable || checked&lt;br /&gt;
|-&lt;br /&gt;
| Description || HQ_VPN&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Configuration Type || Static IPv4&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Address || 10.6.210.2/30&lt;br /&gt;
|-&lt;br /&gt;
| Gateway Name || VPN_HQGW&lt;br /&gt;
|-&lt;br /&gt;
| Gateway IPv4 || 10.6.210.1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 7: Create Firewall Rules on WAN ==&lt;br /&gt;
&lt;br /&gt;
On both firewalls, navigate to &#039;&#039;&#039;Firewall → Rules → WAN&#039;&#039;&#039; and add a rule to the top:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || UDP&lt;br /&gt;
|-&lt;br /&gt;
| Source || Any&lt;br /&gt;
|-&lt;br /&gt;
| Destination || WAN Address&lt;br /&gt;
|-&lt;br /&gt;
| Destination Port || 51820&lt;br /&gt;
|-&lt;br /&gt;
| Description || Pass traffic to WireGuard&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Step 8: Add Routing Between Sites ==&lt;br /&gt;
&lt;br /&gt;
=== HQ-FW1 Static Route ===&lt;br /&gt;
&lt;br /&gt;
Navigate to &#039;&#039;&#039;System → Routing → Static Routes&#039;&#039;&#039; and click &#039;&#039;&#039;+Add&#039;&#039;&#039;:&lt;br /&gt;
* Destination Network: 172.18.1.0/24&lt;br /&gt;
* Gateway: VPN_BRANCHGW&lt;br /&gt;
&lt;br /&gt;
=== Branch-FW Static Route ===&lt;br /&gt;
&lt;br /&gt;
Navigate to &#039;&#039;&#039;System → Routing → Static Routes&#039;&#039;&#039; and click &#039;&#039;&#039;+Add&#039;&#039;&#039;:&lt;br /&gt;
* Destination Network: 172.17.1.0/24&lt;br /&gt;
* Gateway: VPN_HQGW&lt;br /&gt;
&lt;br /&gt;
== Step 9: Allow Tunnel Traffic ==&lt;br /&gt;
&lt;br /&gt;
=== HQ-FW1 Tunnel Rule ===&lt;br /&gt;
&lt;br /&gt;
On HQ-FW1, navigate to &#039;&#039;&#039;Firewall → Rules → BRANCH_VPN&#039;&#039;&#039; and add:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || BRANCH_VPN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || Any&lt;br /&gt;
|-&lt;br /&gt;
| Source || Any&lt;br /&gt;
|-&lt;br /&gt;
| Destination || Any&lt;br /&gt;
|-&lt;br /&gt;
| Description || Allow WireGuard VPN Traffic&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Branch-FW Tunnel Rule ===&lt;br /&gt;
&lt;br /&gt;
On Branch-FW, navigate to &#039;&#039;&#039;Firewall → Rules → HQ_VPN&#039;&#039;&#039; and add the same rule (Interface: HQ_VPN).&lt;br /&gt;
&lt;br /&gt;
== Step 10: Testing ==&lt;br /&gt;
&lt;br /&gt;
WireGuard doesn’t have much status information. In most cases it either works if you configured it properly, or it does not. One place to look is for the existence of a recent “handshake.”&lt;br /&gt;
&lt;br /&gt;
=== Check Status ===&lt;br /&gt;
&lt;br /&gt;
On each firewall, navigate to &#039;&#039;&#039;VPN → WireGuard → Status&#039;&#039;&#039;. One of the only indicators that the VPN is up is the presence of the peer’s handshake.&lt;br /&gt;
&lt;br /&gt;
=== Try to Ping Across ===&lt;br /&gt;
&lt;br /&gt;
From the HQ-Client, try to ping the Branch-FW LAN interface at &#039;&#039;&#039;172.18.1.1&#039;&#039;&#039;. If the tunnel is up, your pings should be successful.&lt;br /&gt;
&lt;br /&gt;
If the pings failed, you have a configuration issue and need to check your configuration.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
Due to its stateless nature, WireGuard doesn’t have status screens, and there is very little logging to be consulted. If your tunnel fails:&lt;br /&gt;
&lt;br /&gt;
* Check the peer settings on both sides, paying particular attention to the public keys of the far-end peers&lt;br /&gt;
* Check for an active WireGuard state by navigating to &#039;&#039;&#039;Diagnostics → States&#039;&#039;&#039; and searching for a state that matches port 51820&lt;br /&gt;
&lt;br /&gt;
The existence of this state can indicate that the VPN is connected. This state may age out, so you may need to try your ping again to bring it back up.&lt;br /&gt;
&lt;br /&gt;
Once you are satisfied that WireGuard is working, you may delete it in order to simplify the next labs.&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
* [[Training: WireGuard|← Back to Training: WireGuard]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;small&amp;gt;&#039;&#039;&#039;Source:&#039;&#039;&#039; Netgate pfSense Training — FUND001-LIVE-Lab7-WireGuard.pdf (© 2015-2021 Electric Sheep Fencing LLC)&amp;lt;/small&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_WireGuard&amp;diff=241</id>
		<title>Training: WireGuard</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_WireGuard&amp;diff=241"/>
		<updated>2026-04-23T07:09:24Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created page with &amp;quot;__NOTOC__  &amp;lt;div style=&amp;quot;background:#e7f3ff;border:1px solid #a3c6ff;padding:10px;margin-bottom:15px;&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Training Module: WireGuard (Section 7)&amp;#039;&amp;#039;&amp;#039; — pfSense Plus Fundamentals and Practical Application &amp;lt;/div&amp;gt;  == Introduction ==  WireGuard is a very new VPN technology that is entirely stateless.  * Tends to be very performant * Lives in the kernel space * Uses “Crypto-Key Routing” * Ensures routing traffic to correct destination * Very little status info — it work...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#e7f3ff;border:1px solid #a3c6ff;padding:10px;margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Training Module: WireGuard (Section 7)&#039;&#039;&#039; — pfSense Plus Fundamentals and Practical Application&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
WireGuard is a very new VPN technology that is entirely stateless.&lt;br /&gt;
&lt;br /&gt;
* Tends to be very performant&lt;br /&gt;
* Lives in the kernel space&lt;br /&gt;
* Uses “Crypto-Key Routing”&lt;br /&gt;
* Ensures routing traffic to correct destination&lt;br /&gt;
* Very little status info — it works or it doesn’t&lt;br /&gt;
* Easy roaming between networks&lt;br /&gt;
* Endpoint IP always updated&lt;br /&gt;
* Configuration may be more time-consuming&lt;br /&gt;
&lt;br /&gt;
== Simplified Codebase ==&lt;br /&gt;
&lt;br /&gt;
WireGuard has a dramatically smaller codebase compared to traditional VPN solutions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Protocol !! Lines of Code&lt;br /&gt;
|-&lt;br /&gt;
| IPsec || ~ 400,000&lt;br /&gt;
|-&lt;br /&gt;
| OpenVPN || ~ 600,000&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;WireGuard&#039;&#039;&#039; || &#039;&#039;&#039;~ 4,000&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Less Code = Greater Efficiency&lt;br /&gt;
&lt;br /&gt;
== Rigid Crypto Protocols ==&lt;br /&gt;
&lt;br /&gt;
WireGuard uses modern, rigidly defined cryptographic protocols:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ChaCha20&#039;&#039;&#039; for symmetric encryption, authenticated with &#039;&#039;&#039;Poly1305&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Curve25519&#039;&#039;&#039; for ECDH&lt;br /&gt;
* &#039;&#039;&#039;BLAKE2s&#039;&#039;&#039; for hashing and keyed hashing&lt;br /&gt;
* &#039;&#039;&#039;SipHash24&#039;&#039;&#039; for hashtable keys&lt;br /&gt;
* &#039;&#039;&#039;HKDF&#039;&#039;&#039; for key derivation&lt;br /&gt;
&lt;br /&gt;
== Site-to-Site ==&lt;br /&gt;
&lt;br /&gt;
WireGuard creates a local wg0 interface. Peers have their own public &amp;amp; private keys.&lt;br /&gt;
&lt;br /&gt;
* Exchange public key with peers&lt;br /&gt;
* Crypto-key routing — looks up peer wg0 address and public key&lt;br /&gt;
* Forwards traffic out local wg0 interface to peer&lt;br /&gt;
&lt;br /&gt;
== Local Setup ==&lt;br /&gt;
&lt;br /&gt;
Some assembly required:&lt;br /&gt;
&lt;br /&gt;
# Activate the service&lt;br /&gt;
# Give wg0 a local IP/mask&lt;br /&gt;
# Generate Public/Private keys&lt;br /&gt;
# Assign wg0 to an OPT interface&lt;br /&gt;
# Create a gateway&lt;br /&gt;
# Open WG port on firewall&lt;br /&gt;
# Create firewall rules to allow traffic&lt;br /&gt;
&lt;br /&gt;
== Peer Setup ==&lt;br /&gt;
&lt;br /&gt;
Required information for peer configuration:&lt;br /&gt;
&lt;br /&gt;
* Peer’s initial end-point IP&lt;br /&gt;
* Peer’s public key&lt;br /&gt;
* Peer’s wg0 IP (typically same as allowed IPs)&lt;br /&gt;
&lt;br /&gt;
Assuming peer’s firewall is setup, try ping!&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* WireGuard is completely stateless&lt;br /&gt;
* Updated crypto protocols&lt;br /&gt;
* Uses crypto-key routing — routing table not a factor&lt;br /&gt;
* Requires its own OPT interface and gateway&lt;br /&gt;
* Very limited status information&lt;br /&gt;
* &#039;&#039;&#039;It works, or it doesn’t&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
* [[Training Lab 7: WireGuard|Lab 7: WireGuard — Site-to-Site VPN Configuration]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;small&amp;gt;&#039;&#039;&#039;Source:&#039;&#039;&#039; Netgate pfSense Training — FUND001-LIVE-SLIDE-SEG7-WG.pdf (© 2017 Rubicon Communications dba Netgate)&amp;lt;/small&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_6:_OpenVPN&amp;diff=240</id>
		<title>Training Lab 6: OpenVPN</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_6:_OpenVPN&amp;diff=240"/>
		<updated>2026-04-23T07:08:32Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Automated upload of Netgate pfSense training content&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#e7f3ff; border-left:6px solid #2196F3; padding:10px; margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Training Lab 6: OpenVPN&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Hands-on lab covering site-to-site SSL/TLS VPN, remote access VPN, certificate infrastructure, and testing in pfSense.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This lab goes through example configurations of OpenVPN for site-to-site and remote access.&lt;br /&gt;
&lt;br /&gt;
== OpenVPN SSL/TLS Site-to-Site VPN ==&lt;br /&gt;
&lt;br /&gt;
We’re going to configure OpenVPN to connect the HQ and branch networks. HQ will run the server, and the branch will be the client.&lt;br /&gt;
&lt;br /&gt;
There is no functional difference in whether HQ or branch runs the server side. Most often people put the server instances on the main location’s end. If one end has a dynamic IP and one static, run the server on the static IP side. If one end is behind NAT, that end should be the client. In this case, the server side will be on the fw1-hq firewall.&lt;br /&gt;
&lt;br /&gt;
=== Delete IPsec ===&lt;br /&gt;
&lt;br /&gt;
First, since we have an IPsec VPN configured here already, IPsec needs to be disabled. On both fw1-HQ and fw1-branch, browse to &#039;&#039;&#039;VPN &amp;gt; IPsec&#039;&#039;&#039;. Put a check mark by each IPsec tunnel and click &#039;&#039;&#039;Delete P1s&#039;&#039;&#039;. Click &#039;&#039;&#039;Save&#039;&#039;&#039;, then &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Create the Certificate Infrastructure ===&lt;br /&gt;
&lt;br /&gt;
OpenVPN makes use of a certificate infrastructure in authenticating the session as well as routing traffic to and from member sites. On the server we must create a new Certificate Authority (CA), as well as server and client certificate/key pairs. This will be done on fw1-hq.&lt;br /&gt;
&lt;br /&gt;
==== Create the Certificate Authority (CA) ====&lt;br /&gt;
&lt;br /&gt;
Navigate to &#039;&#039;&#039;System &amp;gt; Cert Manager&#039;&#039;&#039; and click the green &#039;&#039;&#039;+Add&#039;&#039;&#039; button to add a new CA.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Descriptive Name || S2SCA&lt;br /&gt;
|-&lt;br /&gt;
| Method || Create an Internal Certificate Authority&lt;br /&gt;
|-&lt;br /&gt;
| Randomize Serial || (checked)&lt;br /&gt;
|-&lt;br /&gt;
| Key Type || RSA 2048&lt;br /&gt;
|-&lt;br /&gt;
| Digest Algorithm || sha256&lt;br /&gt;
|-&lt;br /&gt;
| Lifetime || 3650&lt;br /&gt;
|-&lt;br /&gt;
| Common Name || S2SCA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Leave the rest blank and click &#039;&#039;&#039;Save&#039;&#039;&#039;.)&lt;br /&gt;
&lt;br /&gt;
==== Create the Server Certificate ====&lt;br /&gt;
&lt;br /&gt;
Next, click on the &#039;&#039;&#039;Certificates&#039;&#039;&#039; tab, and click the green &#039;&#039;&#039;+Add/Sign&#039;&#039;&#039; button near the bottom.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Method || Create an internal server certificate&lt;br /&gt;
|-&lt;br /&gt;
| Descriptive Name || VPNserver&lt;br /&gt;
|-&lt;br /&gt;
| Certificate Authority || S2SCA&lt;br /&gt;
|-&lt;br /&gt;
| Key Type || RSA 2048&lt;br /&gt;
|-&lt;br /&gt;
| Digest Algorithm || sha256&lt;br /&gt;
|-&lt;br /&gt;
| Lifetime || 398&lt;br /&gt;
|-&lt;br /&gt;
| Common Name || VPNserver&lt;br /&gt;
|-&lt;br /&gt;
| Certificate Type || Server Certificate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Scroll down and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Create the Client Certificate ====&lt;br /&gt;
&lt;br /&gt;
While still on the &#039;&#039;&#039;Certificates&#039;&#039;&#039; tab, click the green &#039;&#039;&#039;+Add/Sign&#039;&#039;&#039; button near the bottom to create the client certificate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Method || Create an internal certificate&lt;br /&gt;
|-&lt;br /&gt;
| Descriptive Name || VPNclient&lt;br /&gt;
|-&lt;br /&gt;
| Certificate Authority || S2SCA&lt;br /&gt;
|-&lt;br /&gt;
| Key Type || RSA 2048&lt;br /&gt;
|-&lt;br /&gt;
| Digest Algorithm || sha256&lt;br /&gt;
|-&lt;br /&gt;
| Lifetime || 3650&lt;br /&gt;
|-&lt;br /&gt;
| Common Name || VPNclient&lt;br /&gt;
|-&lt;br /&gt;
| Certificate Type || User Certificate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Scroll down and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Export Certificates and Keys ====&lt;br /&gt;
&lt;br /&gt;
The next task is to export the certificates and keys which the client requires when connecting to the OpenVPN server.&lt;br /&gt;
&lt;br /&gt;
# Navigate to &#039;&#039;&#039;System &amp;gt; Cert Manager &amp;gt; CAs&#039;&#039;&#039; and find the S2SCA. Click the export button to save the CA certificate to the downloads folder on HQ-Client.&lt;br /&gt;
# Next, click on the &#039;&#039;&#039;Certificates&#039;&#039;&#039; tab and scroll down until you see the VPNclient certificate entry. Click the export button to save the certificate data and the key data to the Downloads folder on HQ-Client.&lt;br /&gt;
&lt;br /&gt;
=== Configure Server on fw1-HQ ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;VPN &amp;gt; OpenVPN&#039;&#039;&#039; on fw1-HQ. On the &#039;&#039;&#039;Server&#039;&#039;&#039; tab, click &#039;&#039;&#039;+Add&#039;&#039;&#039; to add a new server instance.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Server Mode || Peer to Peer (SSL/TLS)&lt;br /&gt;
|-&lt;br /&gt;
| Description || HQ to Branch VPN&lt;br /&gt;
|-&lt;br /&gt;
| TLS Configuration || (checked)&lt;br /&gt;
|-&lt;br /&gt;
| Automatically generate TLS key || (checked)&lt;br /&gt;
|-&lt;br /&gt;
| Peer Certificate Authority || S2SCA&lt;br /&gt;
|-&lt;br /&gt;
| Server Certificate || VPNserver&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Tunnel Network || 172.17.6.0/24&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Local Network(s) || 172.17.1.0/24, 172.17.2.0/24, 172.18.1.0/24&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Remote Network(s) || 172.18.1.0/24&lt;br /&gt;
|-&lt;br /&gt;
| Inactive || 0 (connections can stay up indefinitely)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039; at the bottom, then click the edit icon to edit the server you just created. Highlight and copy the entire contents of the &#039;&#039;&#039;TLS Key&#039;&#039;&#039; box. Paste it into a file called &#039;&#039;&#039;TLS.key&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This TLS key will be needed on the client side of the connection.&lt;br /&gt;
&lt;br /&gt;
=== Create Client-Specific Overrides ===&lt;br /&gt;
&lt;br /&gt;
The purpose of the Client-Specific Override (CSO) is to tie a client’s subnet to their certificate. Navigate to &#039;&#039;&#039;VPN &amp;gt; OpenVPN&#039;&#039;&#039; and click the &#039;&#039;&#039;Client Specific Overrides&#039;&#039;&#039; tab. Click the green &#039;&#039;&#039;+Add&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Server List || HQ to Branch VPN&lt;br /&gt;
|-&lt;br /&gt;
| Common Name || VPNclient&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Remote Network || 172.18.1.0/24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Leave everything else blank or default, scroll down and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Permit Traffic to Server ===&lt;br /&gt;
&lt;br /&gt;
Now we need to add a firewall rule to permit the outside portion of the VPN, from the client to the server. On fw1-HQ, browse to &#039;&#039;&#039;Firewall &amp;gt; Rules &amp;gt; WAN&#039;&#039;&#039;. Click &#039;&#039;&#039;Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || UDP&lt;br /&gt;
|-&lt;br /&gt;
| Source || 203.0.113.10&lt;br /&gt;
|-&lt;br /&gt;
| Source port || any&lt;br /&gt;
|-&lt;br /&gt;
| Destination || WAN address&lt;br /&gt;
|-&lt;br /&gt;
| Destination port || 1194&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow branch OpenVPN site to site&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Then click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Permit Traffic within VPN ===&lt;br /&gt;
&lt;br /&gt;
Traffic within OpenVPN connections is filtered by the firewall rules on the OpenVPN tab. Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules &amp;gt; OpenVPN&#039;&#039;&#039;. Click &#039;&#039;&#039;Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || OpenVPN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || Any&lt;br /&gt;
|-&lt;br /&gt;
| Source || Network, 172.18.0.0/16&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow branch network&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The server-side configuration is now complete.&lt;br /&gt;
&lt;br /&gt;
=== Configure Client on fw1-branch ===&lt;br /&gt;
&lt;br /&gt;
Before we can create the client side of the VPN, we must first import the CA and Client Certificate and Keys into the fw1-branch firewall.&lt;br /&gt;
&lt;br /&gt;
==== Import the CA Certificate ====&lt;br /&gt;
&lt;br /&gt;
Click on &#039;&#039;&#039;System &amp;gt; Cert Manager&#039;&#039;&#039; and click the green &#039;&#039;&#039;+Add&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Descriptive Name || S2SCA&lt;br /&gt;
|-&lt;br /&gt;
| Method || Import an existing Certificate Authority&lt;br /&gt;
|-&lt;br /&gt;
| Certificate Data || Paste contents of S2SCA.crt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Highlight all the contents of the &#039;&#039;&#039;S2SCA.crt&#039;&#039;&#039; file, and paste it into the &#039;&#039;&#039;Certificate Data&#039;&#039;&#039; field on fw1-branch, and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Import the Client Certificate and Key ====&lt;br /&gt;
&lt;br /&gt;
Click on the &#039;&#039;&#039;Certificates&#039;&#039;&#039; tab and click the green &#039;&#039;&#039;+Add/Sign&#039;&#039;&#039; button near the bottom to import your Client Certificate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Method || Import an existing certificate&lt;br /&gt;
|-&lt;br /&gt;
| Descriptive Name || VPNclient&lt;br /&gt;
|-&lt;br /&gt;
| Certificate Data || Paste contents of VPNclient.crt&lt;br /&gt;
|-&lt;br /&gt;
| Certificate Key || Paste contents of VPNclient.key&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Create the OpenVPN Client ====&lt;br /&gt;
&lt;br /&gt;
Navigate to &#039;&#039;&#039;VPN &amp;gt; OpenVPN&#039;&#039;&#039; and click on the &#039;&#039;&#039;Clients&#039;&#039;&#039; tab. Click the green &#039;&#039;&#039;+Add&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Server Mode || Peer to Peer (SSL/TLS)&lt;br /&gt;
|-&lt;br /&gt;
| Device Mode || tun&lt;br /&gt;
|-&lt;br /&gt;
| Server host or address || 192.0.2.2&lt;br /&gt;
|-&lt;br /&gt;
| Description || Branch to HQ VPN&lt;br /&gt;
|-&lt;br /&gt;
| Automatically generate a TLS key || UNCHECKED&lt;br /&gt;
|-&lt;br /&gt;
| Peer Certificate Authority || S2SCA&lt;br /&gt;
|-&lt;br /&gt;
| Client Certificate || VPNclient&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Here, you will edit the OpenVPN server configuration on fw1-hq, and copy the TLS key data from that server configuration into this client’s TLS key box. You may have saved this file on your HQ-Client as &#039;&#039;&#039;TLS.key&#039;&#039;&#039;.)&lt;br /&gt;
&lt;br /&gt;
Scroll down and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Permit Traffic within VPN ====&lt;br /&gt;
&lt;br /&gt;
Add a firewall rule to permit traffic within the VPN, same as the other side but changing the source to HQ’s 172.17.0.0/16.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || OpenVPN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || Any&lt;br /&gt;
|-&lt;br /&gt;
| Source || 172.17.0.0/16&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Description || Allow HQ&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Check Status and Test ===&lt;br /&gt;
&lt;br /&gt;
On fw1-branch, browse to &#039;&#039;&#039;Status &amp;gt; OpenVPN&#039;&#039;&#039;. There you should see the status as up. If not, skip to the troubleshooting section.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Testing:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From HQ-client, try to ping fw1-branch and branch-client:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@hq-client:~$ ping -c 3 172.18.1.1&lt;br /&gt;
PING 172.18.1.1 (172.18.1.1) 56(84) bytes of data.&lt;br /&gt;
64 bytes from 172.18.1.1: icmp_seq=1 ttl=63 time=2.40 ms&lt;br /&gt;
...&lt;br /&gt;
--- 172.18.1.1 ping statistics ---&lt;br /&gt;
3 packets transmitted, 3 received, 0% packet loss, time 2004ms&lt;br /&gt;
rtt min/avg/max/mdev = 2.406/3.841/4.843/1.043 ms&lt;br /&gt;
&lt;br /&gt;
training@hq-client:~$ ping -c 3 172.18.1.100&lt;br /&gt;
PING 172.18.1.100 (172.18.1.100) 56(84) bytes of data.&lt;br /&gt;
64 bytes from 172.18.1.100: icmp_seq=1 ttl=62 time=4.26 ms&lt;br /&gt;
...&lt;br /&gt;
--- 172.18.1.100 ping statistics ---&lt;br /&gt;
3 packets transmitted, 3 received, 0% packet loss, time 2003ms&lt;br /&gt;
rtt min/avg/max/mdev = 3.783/4.309/4.877/0.447 ms&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then from branch-client, try to ping HQ-client and server1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@branch-client:~$ ping -c 3 172.17.1.100&lt;br /&gt;
PING 172.17.1.100 (172.17.1.100) 56(84) bytes of data.&lt;br /&gt;
64 bytes from 172.17.1.100: icmp_seq=1 ttl=62 time=3.73 ms&lt;br /&gt;
64 bytes from 172.17.1.100: icmp_seq=2 ttl=62 time=5.21 ms&lt;br /&gt;
64 bytes from 172.17.1.100: icmp_seq=3 ttl=62 time=5.14 ms&lt;br /&gt;
--- 172.17.1.100 ping statistics ---&lt;br /&gt;
3 packets transmitted, 3 received, 0% packet loss, time 2003ms&lt;br /&gt;
rtt min/avg/max/mdev = 3.730/4.698/5.219/0.685 ms&lt;br /&gt;
&lt;br /&gt;
training@branch-client:~$ ping -c 3 172.17.2.10&lt;br /&gt;
PING 172.17.2.10 (172.17.2.10) 56(84) bytes of data.&lt;br /&gt;
64 bytes from 172.17.2.10: icmp_seq=1 ttl=62 time=4.02 ms&lt;br /&gt;
64 bytes from 172.17.2.10: icmp_seq=2 ttl=62 time=4.01 ms&lt;br /&gt;
64 bytes from 172.17.2.10: icmp_seq=3 ttl=62 time=5.19 ms&lt;br /&gt;
--- 172.17.2.10 ping statistics ---&lt;br /&gt;
3 packets transmitted, 3 received, 0% packet loss, time 2004ms&lt;br /&gt;
rtt min/avg/max/mdev = 4.011/4.408/5.192/0.554 ms&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also try browsing to server1 from branch-client: &amp;lt;code&amp;gt;http://172.17.2.10&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
If the client side status doesn’t show as up, check the troubleshooting section of the OpenVPN chapter in the book for guidance. The most likely causes are an incorrect or missing firewall rule on the WAN of the server (port 1194 rule created above). Check fw1-HQ firewall logs for any blocks. If it’s not getting blocked, and connectivity between the sites works in general, something in the OpenVPN server or client configuration is the likely cause. Double check your configuration on both the client and server, and ensure the shared key was pasted over correctly.&lt;br /&gt;
&lt;br /&gt;
== OpenVPN Remote Access VPN ==&lt;br /&gt;
&lt;br /&gt;
In this section we’re going to set up an OpenVPN remote access server for remote mobile clients.&lt;br /&gt;
&lt;br /&gt;
=== Server Setup Wizard ===&lt;br /&gt;
&lt;br /&gt;
On fw1-HQ, browse to &#039;&#039;&#039;VPN &amp;gt; OpenVPN&#039;&#039;&#039;, and click the &#039;&#039;&#039;Wizard&#039;&#039;&#039; tab.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Backend ===&lt;br /&gt;
&lt;br /&gt;
Choose &#039;&#039;&#039;Local User Access&#039;&#039;&#039; and click &#039;&#039;&#039;Next&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Create New Certificate Authority ===&lt;br /&gt;
&lt;br /&gt;
Fill in these values as desired. The locale information has no functional impact and generally isn’t visible anywhere unless you go looking for it.&lt;br /&gt;
&lt;br /&gt;
=== Create New Server Certificate ===&lt;br /&gt;
&lt;br /&gt;
Again, fill in these values as desired.&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN Server Configuration ===&lt;br /&gt;
&lt;br /&gt;
Most things can be left at defaults here. The port must be changed, since we’re already using port 1194 for the site-to-site VPN server.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Local Port || 1195&lt;br /&gt;
|-&lt;br /&gt;
| Description || Remote Access VPN&lt;br /&gt;
|-&lt;br /&gt;
| Tunnel Network || 172.17.4.0/24&lt;br /&gt;
|-&lt;br /&gt;
| Local Network || 172.16.0.0/12&lt;br /&gt;
|-&lt;br /&gt;
| DNS Server 1 || 172.17.1.1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Leave everything not listed above at defaults and click &#039;&#039;&#039;Next&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Firewall Rule Configuration ===&lt;br /&gt;
&lt;br /&gt;
The last step of the wizard prompts whether you want to add a rule to allow traffic from clients to the OpenVPN server, and allow traffic inside the VPN from clients when connected. Check both boxes and click &#039;&#039;&#039;Next&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039; on the last page.&lt;br /&gt;
&lt;br /&gt;
=== Configuration Complete ===&lt;br /&gt;
&lt;br /&gt;
The configuration is now complete. The last screen reminds you to install the OpenVPN Client Export package if you’d like to use it. It’s already pre-installed on this system to save time. Click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules&#039;&#039;&#039; to see the rules added by the wizard. On the &#039;&#039;&#039;WAN&#039;&#039;&#039; tab, you’ll see the rule allowing traffic to reach the OpenVPN server instance. Then click the &#039;&#039;&#039;OpenVPN&#039;&#039;&#039; tab to see the rule added to permit traffic from the connected clients.&lt;br /&gt;
&lt;br /&gt;
This may be overly-permissive for real world scenarios since it allows all traffic coming in via OpenVPN from any source to any destination. In a real world setup, you may need to restrict this rule.&lt;br /&gt;
&lt;br /&gt;
=== Special Configuration for Older Clients ===&lt;br /&gt;
&lt;br /&gt;
Although this is rarely necessary, some older OpenVPN clients, like the one installed on your remote-host, will require some extra configuration in the OpenVPN server. Click the &#039;&#039;&#039;Edit&#039;&#039;&#039; button under the Remote Access VPN, and scroll down to the bottom of the screen. Place this into the &#039;&#039;&#039;Custom Options&#039;&#039;&#039; box and Save:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tls-version-min 1.0;&lt;br /&gt;
tls-cipher DEFAULT:@SECLEVEL=0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== User Setup ===&lt;br /&gt;
&lt;br /&gt;
Users need a certificate from the RemoteVPNCA to connect. We’ll add a certificate to the &#039;&#039;&#039;vpntest&#039;&#039;&#039; account created during the IPsec lab. Browse to &#039;&#039;&#039;System &amp;gt; User Manager&#039;&#039;&#039;, and edit the vpntest user. Then click the &#039;&#039;&#039;Add&#039;&#039;&#039; button next to &#039;&#039;&#039;User Certificate&#039;&#039;&#039; to create the certificate.&lt;br /&gt;
&lt;br /&gt;
Choose method &#039;&#039;&#039;Create an internal certificate.&#039;&#039;&#039; Both &#039;&#039;&#039;Descriptive name&#039;&#039;&#039; and &#039;&#039;&#039;Common Name&#039;&#039;&#039; should be set to the username. The other fields can be left to defaults.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| User || vpntest&lt;br /&gt;
|-&lt;br /&gt;
| Certificate Method || Create an internal certificate&lt;br /&gt;
|-&lt;br /&gt;
| Descriptive Name || vpntest&lt;br /&gt;
|-&lt;br /&gt;
| Common Name || vpntest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039;. Back at the user edit screen, you’ll see the user’s certificate. Click &#039;&#039;&#039;Save&#039;&#039;&#039; to save the user changes.&lt;br /&gt;
&lt;br /&gt;
=== Client Configuration ===&lt;br /&gt;
&lt;br /&gt;
The OpenVPN Client Export utility eases the process of client configuration. It’s a package that comes pre-installed on the lab VMs, but will need to be installed under &#039;&#039;&#039;System &amp;gt; Packages&#039;&#039;&#039; on your other systems.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;VPN &amp;gt; OpenVPN&#039;&#039;&#039;, and click the &#039;&#039;&#039;Client Export&#039;&#039;&#039; tab.&lt;br /&gt;
&lt;br /&gt;
For our lab purposes, all other settings can be left at their defaults. Scroll down to the bottom to find the vpntest user’s client export options.&lt;br /&gt;
&lt;br /&gt;
For Windows systems, the Windows installer is what you’ll want. Choose x86 for 32 bit versions of Windows and x64 for 64 bit versions. The Viscosity bundle is for Windows or Mac OS X clients running the Viscosity client. The inline configuration options are most commonly used for iOS and Android clients.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Standard Configuration&#039;&#039;&#039; Archive option downloads a zip containing the user’s certificate, TLS key for the server, and OpenVPN config file.&lt;br /&gt;
&lt;br /&gt;
Here you will see the remote access server just created in the wizard. Because the RemoteHost’s VPN client is older, we need to scroll down the page and make sure to put a check mark on &#039;&#039;&#039;Legacy Client&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Testing ===&lt;br /&gt;
&lt;br /&gt;
In this lab environment, the only machine that’s available in the circumstance of a typical client out on the Internet is the remote-host VM. First, add it to the &#039;&#039;&#039;RemoteAdmin&#039;&#039;&#039; alias on fw1-HQ so you can log into fw1-HQ from that host to ease getting the OpenVPN configuration onto the client. Browse to &#039;&#039;&#039;Firewall &amp;gt; Aliases&#039;&#039;&#039;, and edit the RemoteAdmin alias. Add &#039;&#039;&#039;100.64.0.50/32&#039;&#039;&#039; to that alias, save, then apply changes.&lt;br /&gt;
&lt;br /&gt;
Now connect with VNC to &#039;&#039;&#039;100.64.0.50&#039;&#039;&#039; (remote-host) to begin the client-side setup. Bring up its web browser and browse to &#039;&#039;&#039;https://192.0.2.2&#039;&#039;&#039;. Log in and browse to &#039;&#039;&#039;VPN &amp;gt; OpenVPN &amp;gt; Client Export&#039;&#039;&#039; tab. Export the &#039;&#039;&#039;Configuration Archive&#039;&#039;&#039; option for the vpntest user.&lt;br /&gt;
&lt;br /&gt;
Make a folder called OpenVPN in your Documents folder, and save the zip file there. Right click the zip file and choose &#039;&#039;&#039;Extract Here&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Click the Network Manager icon → VPN Connections → Configure VPN.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Add&#039;&#039;&#039; and scroll down to &#039;&#039;&#039;Import a Saved Configuration&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Navigate to the folder where the OpenVPN configuration archive was extracted. Click on the &#039;&#039;&#039;.ovpn&#039;&#039;&#039; file and choose &#039;&#039;&#039;Open&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Fill in the username and password portions of the next screen, and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You may get prompted to choose a password for a new keyring. If so, just enter “password” in both blanks and click &#039;&#039;&#039;Continue&#039;&#039;&#039; and then &#039;&#039;&#039;Close&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now connect to the OpenVPN server by clicking on the Network Manager → VPN Connections and choosing your VPN configuration.&lt;br /&gt;
&lt;br /&gt;
Enter your password and click &#039;&#039;&#039;Ok&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now you should verify you can reach things on the HQ LAN and DMZ networks. Try HQ-client at &#039;&#039;&#039;172.17.1.100&#039;&#039;&#039;, server1 at &#039;&#039;&#039;172.17.2.10&#039;&#039;&#039; and server2 at &#039;&#039;&#039;172.17.2.20&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Once you have verified that the OpenVPN connection is functioning as expected, please disconnect the OpenVPN session on the remote host.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
This concludes Lab 6.&lt;br /&gt;
&lt;br /&gt;
== Source Attribution ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Source: Netgate pfSense Training Material — FUND001-LIVE-Lab6-OpenVPN.pdf © 2021 Rubicon Communications, LLC (Netgate)&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_OpenVPN&amp;diff=239</id>
		<title>Training: OpenVPN</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_OpenVPN&amp;diff=239"/>
		<updated>2026-04-23T07:08:32Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Automated upload of Netgate pfSense training content&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#e7f3ff; border-left:6px solid #2196F3; padding:10px; margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Training Module: OpenVPN (Section 6)&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This page covers the fundamentals of OpenVPN in pfSense — intro, site-to-site, remote access, and the Client Export Utility.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
OpenVPN is an SSL/TLS open source VPN solution.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Not&#039;&#039;&#039; a browser-based SSL VPN&lt;br /&gt;
* Supports site-to-site and remote access&lt;br /&gt;
* Uses client and server roles&lt;br /&gt;
* Runs over TCP or UDP (UDP is preferable)&lt;br /&gt;
* Built on a client/server relationship&lt;br /&gt;
&lt;br /&gt;
== Remote Access ==&lt;br /&gt;
&lt;br /&gt;
The OpenVPN Wizard in pfSense takes all the guess-work out of configuration.&lt;br /&gt;
&lt;br /&gt;
* Install the &#039;&#039;&#039;Client Export Utility&#039;&#039;&#039;&lt;br /&gt;
* Users will need a &#039;&#039;&#039;user certificate&#039;&#039;&#039;&lt;br /&gt;
* Simple status screen&lt;br /&gt;
* Log files for troubleshooting&lt;br /&gt;
&lt;br /&gt;
== Site-to-Site ==&lt;br /&gt;
&lt;br /&gt;
=== Server-Side Requirements ===&lt;br /&gt;
&lt;br /&gt;
* Must have a publicly-reachable TCP or UDP port&lt;br /&gt;
* Static IP is preferred (dynamic DNS is possible)&lt;br /&gt;
&lt;br /&gt;
=== Client-Side Requirements ===&lt;br /&gt;
&lt;br /&gt;
* Only needs outbound Internet access&lt;br /&gt;
* Works behind NAT or firewall with no issue&lt;br /&gt;
* Setup is initiated by Client → Server&lt;br /&gt;
* Remarkably simple configuration&lt;br /&gt;
&lt;br /&gt;
=== Important Changes ===&lt;br /&gt;
&lt;br /&gt;
* Peer-to-Peer (Shared Key) mode is &#039;&#039;&#039;deprecated&#039;&#039;&#039;&lt;br /&gt;
* Peer-to-Peer (SSL/TLS) is the only supported mode moving forward&lt;br /&gt;
* This opens the door to new capabilities like &#039;&#039;&#039;DCO&#039;&#039;&#039; (Data Channel Offload)&lt;br /&gt;
&lt;br /&gt;
=== Configuration Checklist ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Server Information Needed&lt;br /&gt;
|-&lt;br /&gt;
| CA and Certificate Infrastructure || Required for trust&lt;br /&gt;
|-&lt;br /&gt;
| Server and Client Certificates || Authenticate both ends&lt;br /&gt;
|-&lt;br /&gt;
| Server Mode || Peer to Peer (SSL/TLS)&lt;br /&gt;
|-&lt;br /&gt;
| TLS Key || Automatically created&lt;br /&gt;
|-&lt;br /&gt;
| Tunnel Network || Subnet for the VPN tunnel&lt;br /&gt;
|-&lt;br /&gt;
| Local Network || Networks on the server side&lt;br /&gt;
|-&lt;br /&gt;
| Remote Network || Networks on the client side&lt;br /&gt;
|-&lt;br /&gt;
| Client-Specific Overrides || Tie client subnets to certificates&lt;br /&gt;
|-&lt;br /&gt;
| Firewall Rules || Don’t forget to allow traffic!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Client Information Needed&lt;br /&gt;
|-&lt;br /&gt;
| CA and Certificate/Keys from server || Import the server&#039;s CA&lt;br /&gt;
|-&lt;br /&gt;
| Server Mode || Peer to Peer (SSL/TLS)&lt;br /&gt;
|-&lt;br /&gt;
| TLS Key || Copy from the server side&lt;br /&gt;
|-&lt;br /&gt;
| Server IP Address || Public address of the server&lt;br /&gt;
|-&lt;br /&gt;
| Peer CA || Same CA as server&lt;br /&gt;
|-&lt;br /&gt;
| Client Certificate/Key || Generated for this client&lt;br /&gt;
|-&lt;br /&gt;
| Firewall Rules || Don’t forget to allow traffic!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Section Summary ==&lt;br /&gt;
&lt;br /&gt;
* Pay attention to crypto settings — they &#039;&#039;&#039;must agree&#039;&#039;&#039; on both sides&lt;br /&gt;
* Very simple setup&lt;br /&gt;
* Very tenacious — comes up and recovers quickly&lt;br /&gt;
* Routed VPN instead of policy-based&lt;br /&gt;
* Can co-exist with IPsec&lt;br /&gt;
* &#039;&#039;&#039;Cannot&#039;&#039;&#039; route the same networks! (Policy &amp;gt; Routed)&lt;br /&gt;
* Still need firewall rules to allow traffic to pass&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
&lt;br /&gt;
→ Continue to &#039;&#039;&#039;[[Training_Lab_6:_OpenVPN|Lab 6: OpenVPN]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Source Attribution ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Source: Netgate pfSense Training Material — FUND001-LIVE-SLIDE-SEG6-OVPN.pdf © 2017 Rubicon Communications dba Netgate&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_5:_IPsec_VPN&amp;diff=238</id>
		<title>Training Lab 5: IPsec VPN</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_5:_IPsec_VPN&amp;diff=238"/>
		<updated>2026-04-23T07:07:12Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Imported from Netgate pfSense training PDF via bot&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #fff3cd; border-left: 6px solid #ffc107; padding: 10px; margin-bottom: 15px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Netgate pfSense Plus Fundamentals — Lab 5: IPsec VPN&amp;lt;/strong&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Hands-on lab covering site-to-site IPsec with pre-shared key and mobile IPsec remote access configuration.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Lab 5: IPsec =&lt;br /&gt;
&lt;br /&gt;
In this lab, we connect the &#039;&#039;&#039;HQ&#039;&#039;&#039; and &#039;&#039;&#039;branch&#039;&#039;&#039; networks with a site-to-site IPsec VPN, then configure mobile IPsec to offer a remote access option for mobile clients.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lab topology references:&#039;&#039;&#039;&lt;br /&gt;
* HQ WAN IP: &#039;&#039;&#039;192.0.2.2&#039;&#039;&#039;&lt;br /&gt;
* Branch WAN IP: &#039;&#039;&#039;203.0.113.10&#039;&#039;&#039;&lt;br /&gt;
* HQ network: 172.17.0.0/16&lt;br /&gt;
* Branch network: 172.18.0.0/16&lt;br /&gt;
&lt;br /&gt;
= Part 1: IPsec Pre-Shared Key Site-to-Site VPN =&lt;br /&gt;
&lt;br /&gt;
== Enable fw1-HQ IPsec ==&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;fw1-HQ&#039;&#039;&#039;, browse to &#039;&#039;&#039;VPN &amp;gt; IPsec&#039;&#039;&#039;. Click &#039;&#039;&#039;+Add P1&#039;&#039;&#039; to add a new Phase 1 configuration.&lt;br /&gt;
&lt;br /&gt;
=== HQ Phase 1 Configuration ===&lt;br /&gt;
&lt;br /&gt;
At the resulting Edit Phase 1 screen:&lt;br /&gt;
* &#039;&#039;&#039;Remote Gateway:&#039;&#039;&#039; Branch WAN IP (203.0.113.10)&lt;br /&gt;
* &#039;&#039;&#039;Interface:&#039;&#039;&#039; WAN&lt;br /&gt;
* &#039;&#039;&#039;Description:&#039;&#039;&#039; (your choice)&lt;br /&gt;
&lt;br /&gt;
=== Phase 1 Proposal Configuration ===&lt;br /&gt;
&lt;br /&gt;
Scroll down to the Phase 1 proposal configuration.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Generating Pre-Shared Key:&#039;&#039;&#039;&lt;br /&gt;
* Click the yellow button to generate your pre-shared key automatically&lt;br /&gt;
* Make note of it — it will be needed to configure the other end of the VPN&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Advanced Options:&#039;&#039;&#039;&lt;br /&gt;
* Leave &#039;&#039;&#039;NAT Traversal&#039;&#039;&#039; to &#039;&#039;&#039;Auto&#039;&#039;&#039;&lt;br /&gt;
* The underlying strongSwan service will determine if NAT-T is required and automatically enable it if so&lt;br /&gt;
&lt;br /&gt;
Leave the other settings at their defaults, then click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Adding HQ Phase 2 ==&lt;br /&gt;
&lt;br /&gt;
Back at the IPsec Tunnels tab, click the &#039;&#039;&#039;+&#039;&#039;&#039; under the newly-created Phase 1 to expose the Phase 2 configuration, then click &#039;&#039;&#039;+Add P2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Configuring HQ Phase 2 ===&lt;br /&gt;
&lt;br /&gt;
For local and remote networks, use the /16 network summarizing all available IP subnets for each location:&lt;br /&gt;
* &#039;&#039;&#039;Local Network:&#039;&#039;&#039; Type: Network, &#039;&#039;&#039;172.17.0.0/16&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Remote Network:&#039;&#039;&#039; Type: Network, &#039;&#039;&#039;172.18.0.0/16&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Phase 2 Proposal Configuration ===&lt;br /&gt;
&lt;br /&gt;
Choose specific parameters for each area rather than having multiple options enabled. This is always best for site-to-site VPNs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Recommendation&lt;br /&gt;
|-&lt;br /&gt;
| Encryption || AES-256 (single option)&lt;br /&gt;
|-&lt;br /&gt;
| Hash || SHA256 (single option)&lt;br /&gt;
|-&lt;br /&gt;
| PFS || On (match group)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Having multiple options enabled could lead to a less secure, slower algorithm like 3DES being chosen over a faster, more secure option like AES-256.&lt;br /&gt;
&lt;br /&gt;
=== Automatically Ping Host ===&lt;br /&gt;
&lt;br /&gt;
Enter an IP address within the remote subnet to keep the VPN alive:&lt;br /&gt;
* Use &#039;&#039;&#039;fw1-branch LAN IP&#039;&#039;&#039; (e.g., 172.18.1.1)&lt;br /&gt;
* IPsec is &amp;quot;dial-on-demand&amp;quot; — it doesn&#039;t try to connect unless traffic is trying to traverse the VPN&lt;br /&gt;
* The IP doesn&#039;t have to reply; it&#039;s the initiation of the request that triggers the VPN to come up&lt;br /&gt;
&lt;br /&gt;
Then click &#039;&#039;&#039;Save&#039;&#039;&#039;, and at the main IPsec Tunnels screen click &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Configure HQ IPsec Firewall Rules ==&lt;br /&gt;
&lt;br /&gt;
Traffic coming in via IPsec is filtered by the firewall rules on the &#039;&#039;&#039;IPsec tab&#039;&#039;&#039;. By default, this contains no rules, so all VPN traffic will be blocked.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules&#039;&#039;&#039;, IPsec tab. Click &#039;&#039;&#039;Add&#039;&#039;&#039; and configure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || IPsec&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || any&lt;br /&gt;
|-&lt;br /&gt;
| Source || 172.18.0.0/16&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow branch network in via IPsec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039;, and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
* The outer portion of the VPN requires UDP port 500 and ESP protocol on WAN — these rules are handled automatically&lt;br /&gt;
* Traffic is allowed out from HQ to branch by the default LAN rule&lt;br /&gt;
* The HQ DMZ subnet will not be able to initiate connections to the remote branch network because of the DMZ rule rejecting private network destinations&lt;br /&gt;
&lt;br /&gt;
== Configure fw1-branch IPsec ==&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;https://172.18.1.1&#039;&#039;&#039; to reach fw1-branch.&lt;br /&gt;
&lt;br /&gt;
=== Add Phase 1 Entry ===&lt;br /&gt;
&lt;br /&gt;
Add a new Phase 1 entry for the HQ VPN:&lt;br /&gt;
* &#039;&#039;&#039;Remote Gateway:&#039;&#039;&#039; fw1-HQ&#039;s WAN IP — &#039;&#039;&#039;192.0.2.2&#039;&#039;&#039;&lt;br /&gt;
* Match all other parameters exactly with fw1-HQ&lt;br /&gt;
&lt;br /&gt;
=== Phase 1 Proposal and Advanced ===&lt;br /&gt;
&lt;br /&gt;
All Phase 1 proposal settings must match exactly to fw1-HQ. After matching up everything, click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Branch Phase 2 Configuration ===&lt;br /&gt;
&lt;br /&gt;
Add a new Phase 2 entry under the Phase 1 just added. Everything is identical to HQ&#039;s Phase 2, except flip local and remote networks:&lt;br /&gt;
* &#039;&#039;&#039;Local Network:&#039;&#039;&#039; 172.18.0.0/16&lt;br /&gt;
* &#039;&#039;&#039;Remote Network:&#039;&#039;&#039; 172.17.0.0/16&lt;br /&gt;
&lt;br /&gt;
Leave &#039;&#039;&#039;Automatically ping host&#039;&#039;&#039; blank on this side (the other end will keep the tunnel active).&lt;br /&gt;
&lt;br /&gt;
Then click &#039;&#039;&#039;Save&#039;&#039;&#039;, and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Add IPsec Firewall Rule ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules&#039;&#039;&#039;, IPsec tab, and add an allow-all rule:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || IPsec&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || any&lt;br /&gt;
|-&lt;br /&gt;
| Source || Network, 172.17.0.0/16&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow HQ in via VPN&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
== Testing the VPN ==&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Status &amp;gt; IPsec&#039;&#039;&#039; on the branch firewall. If the status shows &amp;quot;Disconnected&amp;quot;, click the &#039;&#039;&#039;Connect VPN&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
Once something attempts to bring up the VPN, it should change status to &#039;&#039;&#039;ESTABLISHED&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
If the VPN does not come up:&lt;br /&gt;
* Closely review all settings in Phase 1 and Phase 2 on both sides&lt;br /&gt;
* Check for typos in IP addresses&lt;br /&gt;
* Verify the pre-shared key was pasted correctly&lt;br /&gt;
* Ensure no inadvertently mismatched settings&lt;br /&gt;
&lt;br /&gt;
=== Passing Traffic Across VPN ===&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;HQ-client&#039;&#039;&#039;, test connectivity:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@hq-client:~$ ping -c 3 172.18.1.1&lt;br /&gt;
training@hq-client:~$ ping -c 3 172.18.1.100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;branch-client&#039;&#039;&#039;, ping back:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@branch-client:~$ ping -c 3 172.17.1.1&lt;br /&gt;
training@branch-client:~$ ping -c 3 172.17.1.100&lt;br /&gt;
training@branch-client:~$ ping -c 3 172.17.2.10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should also be able to browse to web servers in the HQ DMZ network from branch-client.&lt;br /&gt;
&lt;br /&gt;
= Part 2: IPsec Remote Access VPN =&lt;br /&gt;
&lt;br /&gt;
Next, configure IPsec for mobile clients. This works with any standard IPsec clients, specifically focused towards the Cisco IPsec clients built into Mac OS X and Apple iOS. The Shrew Soft client is used in this lab.&lt;br /&gt;
&lt;br /&gt;
== User and Group Setup ==&lt;br /&gt;
&lt;br /&gt;
IPsec remote-access users require the &#039;&#039;&#039;&amp;quot;IPsec xauth Dialin&amp;quot;&#039;&#039;&#039; privilege.&lt;br /&gt;
&lt;br /&gt;
=== Add IPsec Mobile Group ===&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;fw1-HQ&#039;&#039;&#039;, browse to &#039;&#039;&#039;System &amp;gt; User Manager&#039;&#039;&#039;, Groups tab. Click &#039;&#039;&#039;+Add&#039;&#039;&#039;:&lt;br /&gt;
* Give the group a name (e.g., &amp;quot;Mobile_IPsec&amp;quot;) and description&lt;br /&gt;
* Save&lt;br /&gt;
* Edit the group and under &#039;&#039;&#039;Assigned Privileges&#039;&#039;&#039;, click &#039;&#039;&#039;Add&#039;&#039;&#039;&lt;br /&gt;
* Choose only the &#039;&#039;&#039;&amp;quot;VPN - IPsec xauth Dialin&amp;quot;&#039;&#039;&#039; privilege&lt;br /&gt;
* Save again&lt;br /&gt;
&lt;br /&gt;
=== Creating User for VPN ===&lt;br /&gt;
&lt;br /&gt;
Go to the Users tab, click &#039;&#039;&#039;+Add&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Username:&#039;&#039;&#039; vpntest&lt;br /&gt;
* &#039;&#039;&#039;Password:&#039;&#039;&#039; password&lt;br /&gt;
* &#039;&#039;&#039;Group:&#039;&#039;&#039; Mobile_IPsec&lt;br /&gt;
* Save&lt;br /&gt;
&lt;br /&gt;
== Server Configuration ==&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;fw1-HQ&#039;&#039;&#039;, browse to &#039;&#039;&#039;VPN &amp;gt; IPsec&#039;&#039;&#039;, click the &#039;&#039;&#039;Mobile clients&#039;&#039;&#039; tab:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Enable IPsec Mobile Client Support || Checked&lt;br /&gt;
|-&lt;br /&gt;
| User Authentication || Local Database&lt;br /&gt;
|-&lt;br /&gt;
| Group Authentication || Checked&lt;br /&gt;
|-&lt;br /&gt;
| Authentication Groups || Rights for Mobile IPsec (Mobile_IPsec)&lt;br /&gt;
|-&lt;br /&gt;
| Virtual Address Pool || 172.17.5.0/24&lt;br /&gt;
|-&lt;br /&gt;
| Network List || Checked — &amp;quot;Provide a list of accessible networks to clients&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| DNS Default Domain || example.com&lt;br /&gt;
|-&lt;br /&gt;
| DNS Servers || 172.17.1.1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Leave all other fields at defaults and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Phase 1 Creation ==&lt;br /&gt;
&lt;br /&gt;
After saving, you will see a prompt to create a Phase 1 definition for mobile clients. Click &#039;&#039;&#039;Create Phase 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Key Exchange Version || IKEv1&lt;br /&gt;
|-&lt;br /&gt;
| Description || Mobile clients&lt;br /&gt;
|-&lt;br /&gt;
| Authentication Method || Mutual PSK + Xauth&lt;br /&gt;
|-&lt;br /&gt;
| My Identifier || My IP address&lt;br /&gt;
|-&lt;br /&gt;
| Peer Identifier || User distinguished name, vpn@example.com&lt;br /&gt;
|-&lt;br /&gt;
| Pre-Shared Key || Generate new (make note)&lt;br /&gt;
|-&lt;br /&gt;
| Encryption Algorithm || AES 128 bit&lt;br /&gt;
|-&lt;br /&gt;
| Hash Algorithm || SHA1&lt;br /&gt;
|-&lt;br /&gt;
| DH Group || 2&lt;br /&gt;
|-&lt;br /&gt;
| Lifetime || 86400&lt;br /&gt;
|-&lt;br /&gt;
| NAT Traversal || Force&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Leave all else at defaults, and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Configure Phase 2 ==&lt;br /&gt;
&lt;br /&gt;
Back at the IPsec Tunnels screen, expand the mobile Phase 1 and click &#039;&#039;&#039;+Add P2&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Mode || Tunnel IPv4&lt;br /&gt;
|-&lt;br /&gt;
| Local Network || Type: Network, 0.0.0.0/0&lt;br /&gt;
|-&lt;br /&gt;
| Encryption || AES 128&lt;br /&gt;
|-&lt;br /&gt;
| Hash || SHA1&lt;br /&gt;
|-&lt;br /&gt;
| PFS || off&lt;br /&gt;
|-&lt;br /&gt;
| Lifetime || 28800&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The Phase 2 &amp;quot;Local Network&amp;quot; determines what networks are sent to the client. &#039;&#039;&#039;0.0.0.0/0&#039;&#039;&#039; sends all traffic across the VPN. To send only internal traffic, use &#039;&#039;&#039;172.17.0.0/16&#039;&#039;&#039; or &#039;&#039;&#039;172.16.0.0/12&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Then click &#039;&#039;&#039;Save&#039;&#039;&#039;, and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;. The server-side IPsec configuration is now complete.&lt;br /&gt;
&lt;br /&gt;
== Firewall Rule Configuration ==&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules&#039;&#039;&#039;, IPsec tab. Add a new rule:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || IPsec&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || Any&lt;br /&gt;
|-&lt;br /&gt;
| Source || Network 172.17.5.0/24&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow in mobile client IPsec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Then Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
== Client Configuration ==&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;remote-host&#039;&#039;&#039;, launch &#039;&#039;&#039;Shrew Soft VPN Access Manager&#039;&#039;&#039;. Click &#039;&#039;&#039;Add&#039;&#039;&#039; to create a new configuration.&lt;br /&gt;
&lt;br /&gt;
=== General Tab ===&lt;br /&gt;
* Fill in the WAN IP of fw1-HQ: &#039;&#039;&#039;192.0.2.2&#039;&#039;&#039;&lt;br /&gt;
* Leave all else at defaults&lt;br /&gt;
&lt;br /&gt;
=== Authentication Tab ===&lt;br /&gt;
* &#039;&#039;&#039;Authentication Method:&#039;&#039;&#039; Mutual PSK + XAuth&lt;br /&gt;
* &#039;&#039;&#039;Local Identity:&#039;&#039;&#039; User Fully Qualified Domain Name — &#039;&#039;&#039;vpn@example.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Remote Identity Tab ===&lt;br /&gt;
* Choose &#039;&#039;&#039;Identification type:&#039;&#039;&#039; IP address&lt;br /&gt;
&lt;br /&gt;
=== Credentials Tab ===&lt;br /&gt;
* Enter or paste the PSK generated during Phase 1 creation&lt;br /&gt;
&lt;br /&gt;
=== Phase 1 Tab ===&lt;br /&gt;
* Change &#039;&#039;&#039;DH Exchange&#039;&#039;&#039; to &#039;&#039;&#039;group 2&#039;&#039;&#039;&lt;br /&gt;
* Leave all else at defaults&lt;br /&gt;
&lt;br /&gt;
=== Phase 2 Tab ===&lt;br /&gt;
* Set &#039;&#039;&#039;Lifetime&#039;&#039;&#039; to &#039;&#039;&#039;28800&#039;&#039;&#039; seconds&lt;br /&gt;
* Leave everything else at defaults&lt;br /&gt;
&lt;br /&gt;
Then click &#039;&#039;&#039;Save&#039;&#039;&#039;. You can rename the connection (e.g., &amp;quot;HQ VPN&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Select the connection and click &#039;&#039;&#039;Connect&#039;&#039;&#039;. Fill in:&lt;br /&gt;
* &#039;&#039;&#039;Username:&#039;&#039;&#039; vpntest&lt;br /&gt;
* &#039;&#039;&#039;Password:&#039;&#039;&#039; password&lt;br /&gt;
&lt;br /&gt;
Then click &#039;&#039;&#039;Connect&#039;&#039;&#039;. If you see &amp;quot;tunnel enabled&amp;quot; as the last line in the status, it&#039;s connected successfully.&lt;br /&gt;
&lt;br /&gt;
Try to ping across to HQ-client (172.17.1.100) and server1 (172.17.2.10).&lt;br /&gt;
&lt;br /&gt;
This concludes the IPsec lab.&lt;br /&gt;
&lt;br /&gt;
= Next Module =&lt;br /&gt;
&lt;br /&gt;
* [[Training:_IPsec_VPN|Section 5: IPsec VPN Concepts]] (review)&lt;br /&gt;
&lt;br /&gt;
= Source Attribution =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Document:&#039;&#039;&#039; FUND001-LIVE-Lab5-IPsec.pdf&lt;br /&gt;
* &#039;&#039;&#039;Course:&#039;&#039;&#039; pfSense Plus Fundamentals and Practical Application&lt;br /&gt;
* &#039;&#039;&#039;Copyright:&#039;&#039;&#039; © 2021 Rubicon Communications, LLC (Netgate)&lt;br /&gt;
* &#039;&#039;&#039;Extracted:&#039;&#039;&#039; 2026-04-23 via pdftotext&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_IPsec_VPN&amp;diff=237</id>
		<title>Training: IPsec VPN</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_IPsec_VPN&amp;diff=237"/>
		<updated>2026-04-23T07:07:11Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Imported from Netgate pfSense training PDF via bot&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #e7f3fe; border-left: 6px solid #2196F3; padding: 10px; margin-bottom: 15px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Netgate pfSense Plus Fundamentals — Section 5: VPNs and IPsec&amp;lt;/strong&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
This page covers VPN concepts, IPsec remote access, site-to-site configurations, and IKE phase negotiations.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= VPNs and IPsec =&lt;br /&gt;
&lt;br /&gt;
== VPNs — Remote Access ==&lt;br /&gt;
&lt;br /&gt;
Remote access VPNs provide connectivity for mobile or remote users, enabling secure tunneling over untrusted networks.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Use cases:&#039;&#039;&#039;&lt;br /&gt;
* Tunneling for access or performance reasons&lt;br /&gt;
* Additional wireless protection&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Available options:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !! Best For&lt;br /&gt;
|-&lt;br /&gt;
| IPsec || Built-in clients (OS X, iOS, Android)&lt;br /&gt;
|-&lt;br /&gt;
| OpenVPN || Ease of client configuration&lt;br /&gt;
|-&lt;br /&gt;
| WireGuard || Good performance for simple setup&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The best option is largely a matter of &#039;&#039;&#039;personal preference&#039;&#039;&#039; and the specific client ecosystem in use.&lt;br /&gt;
&lt;br /&gt;
== VPNs — Site to Site ==&lt;br /&gt;
&lt;br /&gt;
Site-to-site VPNs provide a permanent connection between networks, commonly used for:&lt;br /&gt;
* Multiple company offices or data centers&lt;br /&gt;
* Service providers&lt;br /&gt;
* Partners&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Available options:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !! Best For&lt;br /&gt;
|-&lt;br /&gt;
| IPsec || Widely interoperable&lt;br /&gt;
|-&lt;br /&gt;
| OpenVPN || Client behind NAT&lt;br /&gt;
|-&lt;br /&gt;
| WireGuard || Client behind NAT, modern crypto&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Again, the best option depends on personal preference and a weighing of strengths and weaknesses. If a client is behind NAT, OpenVPN or WireGuard may be preferable. For wide interoperability, IPsec is the standard.&lt;br /&gt;
&lt;br /&gt;
= About IPsec =&lt;br /&gt;
&lt;br /&gt;
IPsec is a widely interoperable VPN protocol that typically offers higher performance than most alternatives.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Key characteristics:&#039;&#039;&#039;&lt;br /&gt;
* Peer-to-peer relationship&lt;br /&gt;
* Typically &#039;&#039;&#039;policy-based&#039;&#039;&#039; (but can be &#039;&#039;&#039;VTI / route-based&#039;&#039;&#039;)&lt;br /&gt;
* &#039;&#039;&#039;Phase 1&#039;&#039;&#039; protects IKE messages between peers&lt;br /&gt;
* &#039;&#039;&#039;Phase 2&#039;&#039;&#039; protects IP traffic between endpoints&lt;br /&gt;
* Establishes a &#039;&#039;&#039;Security Association (SA)&#039;&#039;&#039; between networks&lt;br /&gt;
* The SA determines which traffic traverses the tunnel&lt;br /&gt;
&lt;br /&gt;
== IPsec Phase 1 ==&lt;br /&gt;
&lt;br /&gt;
Phase 1 protects IKE messages between peers.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Key points:&#039;&#039;&#039;&lt;br /&gt;
* Peers are typically a single IP address&lt;br /&gt;
* Encryption and authentication protocols are required&lt;br /&gt;
* Common example: &#039;&#039;&#039;AES-256 / SHA256&#039;&#039;&#039;&lt;br /&gt;
* Provides a secure path for Phase 2 negotiation&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter !! Typical Value&lt;br /&gt;
|-&lt;br /&gt;
| Encryption || AES-256&lt;br /&gt;
|-&lt;br /&gt;
| Authentication || SHA256&lt;br /&gt;
|-&lt;br /&gt;
| DH Group || 14 (2048-bit) or higher&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IPsec Phase 2 ==&lt;br /&gt;
&lt;br /&gt;
Phase 2 protects IP traffic between endpoints.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Key points:&#039;&#039;&#039;&lt;br /&gt;
* Security Association is formed between networks&lt;br /&gt;
* Encryption is optional for Phase 2 traffic — but strongly recommended&lt;br /&gt;
* Authentication method is still required&lt;br /&gt;
&lt;br /&gt;
= IPsec — How It Looks =&lt;br /&gt;
&lt;br /&gt;
Conceptually, IPsec creates an encrypted tunnel between two peer gateways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Network A] --- [Gateway A] ====== encrypted tunnel ====== [Gateway B] --- [Network B]&lt;br /&gt;
                    ↑                                    ↑&lt;br /&gt;
              Phase 1 (IKE)                        Phase 1 (IKE)&lt;br /&gt;
              Phase 2 (ESP/AH)                     Phase 2 (ESP/AH)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Section 5 Summary =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Point !! Detail&lt;br /&gt;
|-&lt;br /&gt;
| Style || Peer-to-peer VPN&lt;br /&gt;
|-&lt;br /&gt;
| Routing || Can be policy-based or route-based (VTI)&lt;br /&gt;
|-&lt;br /&gt;
| Routing table || Not considered if policy-based&lt;br /&gt;
|-&lt;br /&gt;
| Agreement || As long as both sides agree, the tunnel will come up&lt;br /&gt;
|-&lt;br /&gt;
| Firewall || Still need a firewall rule to allow tunnel traffic&lt;br /&gt;
|-&lt;br /&gt;
| Performance || Consider taking advantage of AES-NI for performance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Next Module =&lt;br /&gt;
&lt;br /&gt;
* [[Training_Lab_5:_IPsec_VPN|Lab 5: IPsec VPN Hands-On]]&lt;br /&gt;
&lt;br /&gt;
= Source Attribution =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Document:&#039;&#039;&#039; FUND001-LIVE-SLIDE-SEG5-IPSEC.pdf&lt;br /&gt;
* &#039;&#039;&#039;Course:&#039;&#039;&#039; pfSense Plus Fundamentals and Practical Application&lt;br /&gt;
* &#039;&#039;&#039;Copyright:&#039;&#039;&#039; © 2017 Rubicon Communications, LLC dba Netgate&lt;br /&gt;
* &#039;&#039;&#039;Extracted:&#039;&#039;&#039; 2026-04-23 via pdftotext&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_10:_High_Availability&amp;diff=236</id>
		<title>Training Lab 10: High Availability</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_10:_High_Availability&amp;diff=236"/>
		<updated>2026-04-23T07:07:10Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created from Netgate pfSense training PDF&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#003366; color:#ffffff; padding:10px; border-radius:5px; margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Netgate pfSense Plus Fundamentals — Lab 10: High Availability&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
In this lab, we add high availability at HQ by configuring a secondary firewall (&#039;&#039;&#039;fw2-HQ&#039;&#039;&#039;) to operate as the backup in an active/passive HA pair.&lt;br /&gt;
&lt;br /&gt;
== Configuring fw2-HQ ==&lt;br /&gt;
&lt;br /&gt;
From your machine or HQ-client, log into fw2-HQ at &#039;&#039;&#039;https://172.17.1.3&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Interface Assignment ===&lt;br /&gt;
&lt;br /&gt;
On fw2-HQ, browse to &#039;&#039;&#039;Interfaces &amp;gt; Assign&#039;&#039;&#039; and verify that your 5 interfaces are assigned correctly.&lt;br /&gt;
&lt;br /&gt;
=== Interface Configuration ===&lt;br /&gt;
&lt;br /&gt;
==== WAN ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Description || WAN&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Configuration Type || Static IPv4&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Address || 192.0.2.3/24&lt;br /&gt;
|-&lt;br /&gt;
| Gateway || GW_WAN — 192.0.2.1 (default gateway)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Then Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
==== DMZ ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Description || DMZ&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Configuration Type || Static IPv4&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Address || 172.17.2.3/24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
==== WAN2 ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Description || WAN2&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Configuration Type || Static IPv4&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Address || 198.51.100.3/24&lt;br /&gt;
|-&lt;br /&gt;
| Gateway || GW_WAN2 — 198.51.100.1 (not default gateway)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
==== SYNC ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Description || SYNC&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Configuration Type || Static IPv4&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Address || 172.17.3.3/24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
=== HA Sync Configuration (fw2-HQ) ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;System &amp;gt; High Avail Sync&#039;&#039;&#039;. Only the top portion is configured on the secondary, enabling it to send and receive state synchronization traffic.&lt;br /&gt;
&lt;br /&gt;
* Check &#039;&#039;&#039;Synchronize States&#039;&#039;&#039;&lt;br /&gt;
* Choose &#039;&#039;&#039;Synchronize Interface&#039;&#039;&#039; = SYNC&lt;br /&gt;
* &#039;&#039;&#039;pfsync Synchronize Peer IP&#039;&#039;&#039;: 172.17.3.2&lt;br /&gt;
&lt;br /&gt;
Then click Save at the very bottom of the page.&lt;br /&gt;
&lt;br /&gt;
=== Increase FW2 GUI Processes ===&lt;br /&gt;
&lt;br /&gt;
Navigate to &#039;&#039;&#039;System &amp;gt; Advanced&#039;&#039;&#039; and change &#039;&#039;&#039;Max Processes&#039;&#039;&#039; from the default 2 to &#039;&#039;&#039;5&#039;&#039;&#039;, to account for the extra work of sync and configuration.&lt;br /&gt;
&lt;br /&gt;
=== Firewall Rule Configuration (fw2-HQ) ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules&#039;&#039;&#039;, SYNC tab, and click Add to allow the initial config sync:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || SYNC&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || any&lt;br /&gt;
|-&lt;br /&gt;
| Source || any&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Then Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
fw2-HQ is now ready.&lt;br /&gt;
&lt;br /&gt;
== Configuring fw1-HQ ==&lt;br /&gt;
&lt;br /&gt;
Switch over to fw1-HQ to continue the configuration.&lt;br /&gt;
&lt;br /&gt;
=== Assign and Configure Sync Interface ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Interfaces &amp;gt; Assign&#039;&#039;&#039; and verify the SYNC interface is assigned.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Interfaces &amp;gt; OPT3&#039;&#039;&#039; and configure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Enable || checked&lt;br /&gt;
|-&lt;br /&gt;
| Description || SYNC&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Configuration Type || Static IPv4&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Address || 172.17.3.2/24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
=== Add Sync Firewall Rules (fw1-HQ) ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules&#039;&#039;&#039;, Sync tab. Add:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || Sync&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || any&lt;br /&gt;
|-&lt;br /&gt;
| Source || any&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow sync&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
=== Change Interface IPs (fw1-HQ) ===&lt;br /&gt;
&lt;br /&gt;
The gateway IPs on the internal interfaces need to be CARP IPs so they fail over. Change the LAN and DMZ interface IPs:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;LAN&#039;&#039;&#039;: change from 172.17.1.1 to &#039;&#039;&#039;172.17.1.2&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;DMZ&#039;&#039;&#039;: change from 172.17.2.1 to &#039;&#039;&#039;172.17.2.2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The .1 IPs will be added back as CARP IPs in the next step. Save and apply changes after each interface.&lt;br /&gt;
&lt;br /&gt;
=== Add CARP VIPs (fw1-HQ) ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Virtual IPs&#039;&#039;&#039;, and click &#039;&#039;&#039;+Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== LAN CARP VIP ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Type || CARP&lt;br /&gt;
|-&lt;br /&gt;
| Interface || LAN&lt;br /&gt;
|-&lt;br /&gt;
| IP Address || 172.17.1.1/24&lt;br /&gt;
|-&lt;br /&gt;
| Virtual IP Password || random characters (syncs automatically)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Leave the remainder at defaults. Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
==== DMZ CARP VIP ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Type || CARP&lt;br /&gt;
|-&lt;br /&gt;
| Interface || DMZ&lt;br /&gt;
|-&lt;br /&gt;
| IP Address || 172.17.2.1/24&lt;br /&gt;
|-&lt;br /&gt;
| Virtual IP Password || random string&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note the VHID group increments to 2. Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
=== Edit Existing WAN VIPs (fw1-HQ) ===&lt;br /&gt;
&lt;br /&gt;
==== WAN .4 VIP ====&lt;br /&gt;
&lt;br /&gt;
Edit 192.0.2.4: change type from IP Alias to CARP, subnet mask /24, VHID Group 3, random Virtual IP Password. Save.&lt;br /&gt;
&lt;br /&gt;
==== WAN .5 and .6 VIPs ====&lt;br /&gt;
&lt;br /&gt;
Edit 192.0.2.5 and 192.0.2.6: keep as IP Alias but change parent interface to the WAN CARP IP (192.0.2.4). Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
==== WAN2 CARP VIPs ====&lt;br /&gt;
&lt;br /&gt;
Change 198.51.100.4 to CARP, and change the interface of 198.51.100.5 and .6 to 198.51.100.4.&lt;br /&gt;
&lt;br /&gt;
=== Configure HA Sync (fw1-HQ) ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;System &amp;gt; High Avail. Sync&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Synchronize States || checked&lt;br /&gt;
|-&lt;br /&gt;
| Synchronize Interface || SYNC&lt;br /&gt;
|-&lt;br /&gt;
| pfsync Synchronize Peer IP || 172.17.3.3&lt;br /&gt;
|-&lt;br /&gt;
| Synchronize Config to IP || 172.17.3.3&lt;br /&gt;
|-&lt;br /&gt;
| Remote System Username || admin&lt;br /&gt;
|-&lt;br /&gt;
| Remote System Password || pfsense&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;toggle all&#039;&#039;&#039; to check all synchronize configuration boxes, then click Save.&lt;br /&gt;
&lt;br /&gt;
Configuration and state synchronization are now fully enabled. Do not make config changes directly on the secondary from here out, as they’ll be overwritten by the primary.&lt;br /&gt;
&lt;br /&gt;
=== Configure Outbound NAT ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; NAT&#039;&#039;&#039;, Outbound tab. Edit rules so traffic is NATed to IPs that fail over:&lt;br /&gt;
&lt;br /&gt;
* Edit &amp;quot;HQ 172.17./16 out via WAN IP&amp;quot; — change Translation to &#039;&#039;&#039;192.0.2.6&#039;&#039;&#039;&lt;br /&gt;
* Edit &amp;quot;HQ 172.17./16 out via WAN2 IP&amp;quot; — change Translation to &#039;&#039;&#039;198.51.100.6&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Configure LAN DHCP ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Services &amp;gt; DHCP Server&#039;&#039;&#039;, LAN tab:&lt;br /&gt;
&lt;br /&gt;
* Set default gateway to the LAN CARP VIP &#039;&#039;&#039;172.17.1.1&#039;&#039;&#039;&lt;br /&gt;
* Set &#039;&#039;&#039;Failover Peer IP&#039;&#039;&#039; to fw2-HQ LAN IP &#039;&#039;&#039;172.17.1.3&#039;&#039;&#039;&lt;br /&gt;
* Save&lt;br /&gt;
&lt;br /&gt;
== Check Status ==&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Status &amp;gt; CARP&#039;&#039;&#039; on both fw1-HQ and fw2-HQ. All CARP IPs should show:&lt;br /&gt;
* &#039;&#039;&#039;master&#039;&#039;&#039; status on fw1-HQ&lt;br /&gt;
* &#039;&#039;&#039;backup&#039;&#039;&#039; status on fw2-HQ&lt;br /&gt;
&lt;br /&gt;
== Testing Failover ==&lt;br /&gt;
&lt;br /&gt;
=== Force Failover by Disabling CARP on Primary ===&lt;br /&gt;
&lt;br /&gt;
On fw1-HQ, browse to &#039;&#039;&#039;Status &amp;gt; CARP&#039;&#039;&#039; and click &#039;&#039;&#039;Temporarily Disable CARP&#039;&#039;&#039;. After reload, all CARP IPs change to &amp;quot;disabled.&amp;quot; Check fw2-HQ — they should all show master status.&lt;br /&gt;
&lt;br /&gt;
=== Force Failover by Simulating Power Removal ===&lt;br /&gt;
&lt;br /&gt;
Navigate to &#039;&#039;&#039;Diagnostics &amp;gt; Halt System&#039;&#039;&#039; and click &#039;&#039;&#039;Reboot&#039;&#039;&#039; on the primary. Within a second after rebooting, fw2-HQ should show master status on all CARP IPs. After fw1-HQ reboots, it will regain master status automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#e6f2ff; padding:10px; border-left:4px solid #003366; margin-top:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Previous Module:&#039;&#039;&#039; [[Training: High Availability|Training: High Availability — HA Overview and Concepts]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Source Attribution ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Netgate pfSense Plus Fundamentals and Practical Application&#039;&#039;&lt;br /&gt;
* © 2021 Rubicon Communications, LLC (Netgate)&lt;br /&gt;
* Source PDF: FUND001-LIVE-Lab10-HA.pdf&lt;br /&gt;
* Reference fw2-HQ IPs: WAN 192.0.2.3, LAN 172.17.1.3, DMZ 172.17.2.3&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_High_Availability&amp;diff=235</id>
		<title>Training: High Availability</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_High_Availability&amp;diff=235"/>
		<updated>2026-04-23T07:07:10Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created from Netgate pfSense training PDF&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#003366; color:#ffffff; padding:10px; border-radius:5px; margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Netgate pfSense Plus Fundamentals — Section 10: High Availability&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
High Availability (HA) in pfSense uses an &#039;&#039;&#039;active/passive pair&#039;&#039;&#039; of firewalls to provide hardware redundancy. This architecture offers:&lt;br /&gt;
&lt;br /&gt;
* Increased redundancy options&lt;br /&gt;
* Less painful upgrades&lt;br /&gt;
* Seamless failover capabilities&lt;br /&gt;
&lt;br /&gt;
HA relies on &#039;&#039;&#039;three separate functions&#039;&#039;&#039; working together:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Function !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;CARP&#039;&#039;&#039; || Provides redundant IP addresses (Virtual IPs) shared between HA members&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;pfSync&#039;&#039;&#039; || Synchronizes the state table between HA members for seamless failover&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;XMLRPC&#039;&#039;&#039; || Synchronizes configuration from the primary to secondary firewalls&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CARP (Common Address Redundancy Protocol) ==&lt;br /&gt;
&lt;br /&gt;
* Uses multicast for announcements&lt;br /&gt;
* Every CARP VIP has a unique &#039;&#039;&#039;VHID&#039;&#039;&#039; (Virtual Host ID)&lt;br /&gt;
* CARP VIP is shared between VHID members&lt;br /&gt;
* VHID groups are password protected&lt;br /&gt;
* At least &#039;&#039;&#039;3 public IPs required&#039;&#039;&#039; per WAN&lt;br /&gt;
* WAN needs at least a &#039;&#039;&#039;/29&#039;&#039;&#039; subnet&lt;br /&gt;
&lt;br /&gt;
== pfSync ==&lt;br /&gt;
&lt;br /&gt;
* Syncs state table between the two HA members&lt;br /&gt;
* Enables seamless failover during an outage&lt;br /&gt;
* Can use multicast or unicast for updates&lt;br /&gt;
* No authentication for updates&lt;br /&gt;
* &#039;&#039;&#039;Likes a dedicated interface&#039;&#039;&#039; (recommended)&lt;br /&gt;
&lt;br /&gt;
== XMLRPC (Configuration Sync) ==&lt;br /&gt;
&lt;br /&gt;
* Syncs configuration between HA members&lt;br /&gt;
* Syncs from primary to secondaries&lt;br /&gt;
* Only need to configure one firewall&lt;br /&gt;
* May not sync everything — &#039;&#039;&#039;packages are responsible for their own config sync&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== CARP Configuration Requirements ==&lt;br /&gt;
&lt;br /&gt;
* At least one CARP VIP on WAN&lt;br /&gt;
* At least one CARP VIP on LAN&lt;br /&gt;
* Manual Outbound NAT to CARP VIP&lt;br /&gt;
* DHCP adjustments needed (use CARP VIP as default gateway)&lt;br /&gt;
&lt;br /&gt;
== Typical Topology ==&lt;br /&gt;
&lt;br /&gt;
=== Single WAN ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISP1&lt;br /&gt;
  |&lt;br /&gt;
[ HA Pair ] — LAN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multi-WAN ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISP1     ISP2&lt;br /&gt;
  |        |&lt;br /&gt;
[   HA Pair   ] — LAN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Failures ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Dual master&#039;&#039;&#039; on CARP VIPs&lt;br /&gt;
* Loss of active connections on failover&lt;br /&gt;
* Loss of connectivity on failover&lt;br /&gt;
&lt;br /&gt;
== Section 10 Summary ==&lt;br /&gt;
&lt;br /&gt;
* Active/Passive pair&lt;br /&gt;
* Will need at least &#039;&#039;&#039;/29&#039;&#039;&#039; of network space per WAN&lt;br /&gt;
* Use a &#039;&#039;&#039;unique VHID&#039;&#039;&#039; for every CARP VIP&lt;br /&gt;
* Use a &#039;&#039;&#039;separate private interface&#039;&#039;&#039; for pfSync data&lt;br /&gt;
* Packages are responsible for their own config sync&lt;br /&gt;
* Outbound NAT to CARP VIP&lt;br /&gt;
* DHCP adjusted for CARP VIP as default gateway&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#e6f2ff; padding:10px; border-left:4px solid #003366; margin-top:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Next Module:&#039;&#039;&#039; [[Training Lab 10: High Availability|Training Lab 10: High Availability — Hands-on Configuration and Failover Testing]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Source Attribution ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Netgate pfSense Plus Fundamentals and Practical Application&#039;&#039;&lt;br /&gt;
* © 2017–2021 Rubicon Communications, LLC (Netgate)&lt;br /&gt;
* Source PDF: FUND001-LIVE-SLIDE-SEG10-HA.pdf&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_8:_Multi-WAN&amp;diff=234</id>
		<title>Training Lab 8: Multi-WAN</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_8:_Multi-WAN&amp;diff=234"/>
		<updated>2026-04-23T07:06:59Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created page with &amp;quot;__NOTOC__  &amp;lt;div style=&amp;quot;background:#fff3e6;border:1px solid #ff9900;padding:10px;margin-bottom:15px;&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Netgate pfSense Plus Fundamentals — Lab 8: Multi-WAN&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt; &amp;lt;i&amp;gt;Adding WAN2, configuring gateway groups, failover, failback, firewall rules, NAT, and testing.&amp;lt;/i&amp;gt; &amp;lt;/div&amp;gt;  This lab covers adding a second WAN interface to HQ, configuring the interface, gateway groups, firewall rules, NAT and related topics for multi-WAN, then testing its failover and failback.  == Con...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#fff3e6;border:1px solid #ff9900;padding:10px;margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Netgate pfSense Plus Fundamentals — Lab 8: Multi-WAN&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;i&amp;gt;Adding WAN2, configuring gateway groups, failover, failback, firewall rules, NAT, and testing.&amp;lt;/i&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This lab covers adding a second WAN interface to HQ, configuring the interface, gateway groups, firewall rules, NAT and related topics for multi-WAN, then testing its failover and failback.&lt;br /&gt;
&lt;br /&gt;
== Configuring WAN2 Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Adding the WAN2 Interface ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Interfaces &amp;gt; Assign&#039;&#039;&#039;, and verify that your OPT2 interface is assigned to vtnet3. Browse to &#039;&#039;&#039;Interfaces &amp;gt; OPT2&#039;&#039;&#039;. Configure the interface as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Enable || check&lt;br /&gt;
|-&lt;br /&gt;
| Description || WAN2&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Type || Static&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Address || 198.51.100.2/24&lt;br /&gt;
|-&lt;br /&gt;
| Gateway || add new&lt;br /&gt;
|-&lt;br /&gt;
| — Name || GW_WAN2&lt;br /&gt;
|-&lt;br /&gt;
| — IP || 198.51.100.1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and Apply Changes.&lt;br /&gt;
&lt;br /&gt;
=== Verifying WAN2 Connectivity ===&lt;br /&gt;
&lt;br /&gt;
After adding a new WAN, the fastest way to verify it’s online is by browsing to &#039;&#039;&#039;Status &amp;gt; Gateways&#039;&#039;&#039;. It should show green and online there. To verify Internet connectivity, browse to &#039;&#039;&#039;Diagnostics &amp;gt; Ping&#039;&#039;&#039;. Enter any Internet host that replies to pings in the “Host” box (such as google.com), choose Source Address &#039;&#039;&#039;WAN2&#039;&#039;&#039;, and click Ping. You should receive replies.&lt;br /&gt;
&lt;br /&gt;
== Configuring DNS Servers ==&lt;br /&gt;
&lt;br /&gt;
At least one DNS server must be reachable via each WAN so a single connection&#039;s failure doesn&#039;t result in DNS failing.&lt;br /&gt;
&lt;br /&gt;
* In a production environment, at least one DNS server should be assigned to each WAN.&lt;br /&gt;
* In this lab network, DNS servers are local to the WAN and WAN2 networks, so we will not assign them to specific gateways.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;System &amp;gt; General Setup&#039;&#039;&#039;. There you will see the existing entry for 192.0.2.1. In a real production environment, you may consider assigning this to GW_WAN, however that is not possible or necessary here as 192.0.2.1 exists in the same network as the WAN.&lt;br /&gt;
&lt;br /&gt;
Add &#039;&#039;&#039;198.51.100.1&#039;&#039;&#039; as a secondary DNS server. In a real production environment, you may consider assigning this to GW_WAN2, however that is not possible or necessary here as 198.51.100.1 exists in the same network as the WANs.&lt;br /&gt;
&lt;br /&gt;
Click Save.&lt;br /&gt;
&lt;br /&gt;
== Configuring Monitor IPs ==&lt;br /&gt;
&lt;br /&gt;
The system will ping its monitor IP for each gateway to determine gateway status. By default, the gateway&#039;s IP is used. For multi-WAN scenarios, that is probably not a good choice.&lt;br /&gt;
&lt;br /&gt;
* Your default gateway may be a local router within your facility, unlikely to ever go down when your Internet goes down.&lt;br /&gt;
* Or problems in your ISP&#039;s network further upstream could cause loss of connectivity.&lt;br /&gt;
* Using an IP out on the Internet as the monitor IP offers a better test of connectivity.&lt;br /&gt;
&lt;br /&gt;
Use of anycasted IPs is best:&lt;br /&gt;
* Google public DNS: 8.8.8.8 and 8.8.4.4&lt;br /&gt;
* OpenDNS: 208.67.220.220 and 208.67.222.222&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;System &amp;gt; Routing&#039;&#039;&#039;. Edit &#039;&#039;&#039;GW_WAN&#039;&#039;&#039;. For monitor IP, fill in &#039;&#039;&#039;8.8.8.8&#039;&#039;&#039;. Save. Then edit &#039;&#039;&#039;GW_WAN2&#039;&#039;&#039;, and set its monitor IP to &#039;&#039;&#039;8.8.4.4&#039;&#039;&#039;. Save, then Apply Changes.&lt;br /&gt;
&lt;br /&gt;
== Configuring Gateway Groups ==&lt;br /&gt;
&lt;br /&gt;
Configure three gateway groups for use at HQ:&lt;br /&gt;
# One that prefers WAN and fails over to WAN2.&lt;br /&gt;
# One that prefers WAN2 and fails over to WAN.&lt;br /&gt;
# One that load balances across both.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;System &amp;gt; Routing&#039;&#039;&#039;, and click the &#039;&#039;&#039;Groups&#039;&#039;&#039; tab. Click &#039;&#039;&#039;+Add&#039;&#039;&#039; to add a new group.&lt;br /&gt;
&lt;br /&gt;
=== WAN to WAN2 ===&lt;br /&gt;
&lt;br /&gt;
This gateway group prefers WAN (tier 1) and fails over to WAN2 (tier 2). Then click Save.&lt;br /&gt;
&lt;br /&gt;
=== WAN2 to WAN ===&lt;br /&gt;
&lt;br /&gt;
Click the duplicate symbol to the right of the WANtoWAN2 group to create a new group based on this one, then flip the tiers, group name and description. This prefers WAN2, and fails over to WAN.&lt;br /&gt;
&lt;br /&gt;
=== Load Balance ===&lt;br /&gt;
&lt;br /&gt;
This load balances across both WAN and WAN2. If a WAN fails, it&#039;s removed from the load balancing pool.&lt;br /&gt;
&lt;br /&gt;
== Configure NAT for Multi-WAN ==&lt;br /&gt;
&lt;br /&gt;
The NAT configuration is all on a per-interface basis, specifying one particular interface and having IP information that&#039;s specific to that interface. When you add a new WAN, you also need NAT configuration specific to that new WAN.&lt;br /&gt;
&lt;br /&gt;
=== Configuring Virtual IPs on WAN2 ===&lt;br /&gt;
&lt;br /&gt;
WAN2 will have 3 virtual IPs configured as IP aliases:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! IP/mask !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 198.51.100.4/32 || server1 WAN2 external address&lt;br /&gt;
|-&lt;br /&gt;
| 198.51.100.5/32 || server2 WAN2 external address&lt;br /&gt;
|-&lt;br /&gt;
| 198.51.100.6/32 || extra WAN2 external address&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Repeat the process for the remaining IPs.&lt;br /&gt;
&lt;br /&gt;
=== Configuring Port Forwards on WAN2 ===&lt;br /&gt;
&lt;br /&gt;
To open the same ports on WAN2 as on WAN, duplicate the existing port forward entries and change their interface from WAN to WAN2.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; NAT&#039;&#039;&#039;, &#039;&#039;&#039;Port Forwards&#039;&#039;&#039; tab. Click the duplicate symbol to the right of the “VNC to hqclient” entry. In the resulting screen, change the interface from WAN to WAN2. Note how the destination address automatically changes to “WAN2 address.” Verify that change, update the description if desired, then save.&lt;br /&gt;
&lt;br /&gt;
Repeat that process for the port 222 SSH port forward to hq-client.&lt;br /&gt;
&lt;br /&gt;
=== Configuring 1:1 NAT on WAN2 ===&lt;br /&gt;
&lt;br /&gt;
Configure 1:1 NAT for server1 and server2 on WAN2.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! server1 !! server2&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN2 || WAN2&lt;br /&gt;
|-&lt;br /&gt;
| External IP || 198.51.100.4 || 198.51.100.5&lt;br /&gt;
|-&lt;br /&gt;
| Internal IP || 172.17.2.10 || 172.17.2.20&lt;br /&gt;
|-&lt;br /&gt;
| Description || server1.example.com WAN2 || server2.example.com WAN2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
=== Configuring Outbound NAT on WAN2 ===&lt;br /&gt;
&lt;br /&gt;
Since the configuration is using manual outbound NAT, add outbound NAT rules for WAN2.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; NAT&#039;&#039;&#039;, &#039;&#039;&#039;Outbound&#039;&#039;&#039; tab. Click the duplicate symbol to the right of “hq-client out via .6” to add a new entry based on that one. Change the interface to WAN2, and the Translation address to 198.51.100.6.&lt;br /&gt;
&lt;br /&gt;
Repeat the same process for the two other outbound NAT rules.&lt;br /&gt;
&lt;br /&gt;
== Configuring WAN2 Firewall Rules ==&lt;br /&gt;
&lt;br /&gt;
We want the same external access on WAN2 as is already active on WAN, permitting certain traffic through the 1:1 NATs for server1 and server2. Interface groupings do not support return routing at this time, so the rules must be kept on each WAN separately.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules&#039;&#039;&#039;, WAN tab. Click the duplicate symbol to the right of “allow web ports to public web servers” to duplicate it, change the interface from WAN to WAN2, and click Save. Because the NAT applies first, the firewall rule is otherwise identical to the one on WAN.&lt;br /&gt;
&lt;br /&gt;
Repeat the same process for rules “allow pings to public web servers” and “allow SSH to web servers from remote admin.”&lt;br /&gt;
&lt;br /&gt;
== Configure Firewall Rules for Outbound Traffic ==&lt;br /&gt;
&lt;br /&gt;
In a multi-WAN environment, outbound traffic is directed to a particular WAN or gateway group via policy routing with firewall rules.&lt;br /&gt;
&lt;br /&gt;
=== Test WAN2 with Single Client ===&lt;br /&gt;
&lt;br /&gt;
First, send only HQ-client out via WAN2. It&#039;s generally best to first test a new WAN with a single client.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules&#039;&#039;&#039;, LAN tab, and click Add to add a rule to the top of the list:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || LAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || any&lt;br /&gt;
|-&lt;br /&gt;
| Source || Single host or alias, 172.17.1.100&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Description || hq-client1 prefer WAN2&lt;br /&gt;
|-&lt;br /&gt;
| Gateway (Advanced Options) || WAN2toWAN&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
=== Testing LAN out WAN2 ===&lt;br /&gt;
&lt;br /&gt;
Open hq-client1&#039;s web browser and browse to http://100.64.0.50. You should be able to connect, and see you&#039;re coming from 198.51.100.6, the WAN2 VIP where hq-client1 is NATed.&lt;br /&gt;
&lt;br /&gt;
=== Configure LAN for Failover Group ===&lt;br /&gt;
&lt;br /&gt;
The “hq-client1 prefer WAN2” rule was only for testing. Delete that rule now.&lt;br /&gt;
&lt;br /&gt;
Then edit the “Default allow LAN to any” rule, and choose Gateway &#039;&#039;&#039;WANtoWAN2&#039;&#039;&#039;. Verify Internet connectivity is still functioning from hq-client1.&lt;br /&gt;
&lt;br /&gt;
=== LAN to DMZ Connectivity ===&lt;br /&gt;
&lt;br /&gt;
Try to ping 172.17.2.10 from hq-client1. You won&#039;t receive a successful reply because traffic matching a firewall rule specifying a gateway is forced to that gateway. The attempt to get to DMZ is actually being sent to the WAN ISP&#039;s router, which can&#039;t route internal traffic.&lt;br /&gt;
&lt;br /&gt;
=== Add LocalNetworks Alias ===&lt;br /&gt;
&lt;br /&gt;
Add an alias containing destinations that will not be policy-routed to the Internet.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Aliases&#039;&#039;&#039; and click &#039;&#039;&#039;+Add&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name || LocalNetworks&lt;br /&gt;
|-&lt;br /&gt;
| Description || networks that will not be policy routed to Internet&lt;br /&gt;
|-&lt;br /&gt;
| Type || Network&lt;br /&gt;
|-&lt;br /&gt;
| Network 1 || 172.17.0.0/16 (HQ)&lt;br /&gt;
|-&lt;br /&gt;
| Network 2 || 172.18.0.0/16 (branch)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
=== Add Firewall Rule for Negation ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Rules&#039;&#039;&#039;, LAN, and click Add to add a new rule to the top of the list:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action || Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface || LAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || any&lt;br /&gt;
|-&lt;br /&gt;
| Source || LAN net&lt;br /&gt;
|-&lt;br /&gt;
| Destination || Single host or alias, LocalNetworks alias&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow local networks with no policy routing&lt;br /&gt;
|-&lt;br /&gt;
| Gateway || Leave at default&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Start a new ping to 172.17.2.10 and it will reply. If you still aren&#039;t getting a ping reply, it&#039;s probably because of an old firewall state. Reset states under &#039;&#039;&#039;Diagnostics &amp;gt; States&#039;&#039;&#039;, or delete those specific states, and try again.&lt;br /&gt;
&lt;br /&gt;
== Default Gateway Switching ==&lt;br /&gt;
&lt;br /&gt;
At this point, all traffic sourced from inside the LAN or DMZ destined for the internet will follow the policy route. However, the default route on the firewall is still pointing to WAN1. In the event of a WAN1 failure, traffic sourced by the firewall itself will not be able to reach the internet.&lt;br /&gt;
&lt;br /&gt;
Navigate to &#039;&#039;&#039;System &amp;gt; Routing&#039;&#039;&#039; and set &#039;&#039;&#039;Default gateway IPv4&#039;&#039;&#039; to &#039;&#039;&#039;Automatic&#039;&#039;&#039; and click Save.&lt;br /&gt;
&lt;br /&gt;
== Testing Failover ==&lt;br /&gt;
&lt;br /&gt;
Now that failover is configured, it&#039;s important to test it. Create a failure on WAN to verify it switches over to WAN2.&lt;br /&gt;
&lt;br /&gt;
In the virtual lab environment, shutdown the WAN1 NIC on “Lab Internet router.” Point your web browser to your Lab Internet Router (http://100.64.0.1) and browse to &#039;&#039;&#039;Interfaces &amp;gt; HQ_WAN1&#039;&#039;&#039;. Uncheck the Enable box at the top and click OK, then Apply.&lt;br /&gt;
&lt;br /&gt;
Now browse to &#039;&#039;&#039;Status &amp;gt; Gateways&#039;&#039;&#039; on fw1-HQ. Within a few seconds, WAN should show as offline. Once it does, try to browse out from LAN to the Internet. You should now be using WAN2.&lt;br /&gt;
&lt;br /&gt;
Once tested, normalize your lab by logging back into your Lab Internet Router (http://100.64.0.1) and check the Enable box in the HQ-WAN1 interface. Your WAN gateway should then come back online.&lt;br /&gt;
&lt;br /&gt;
This completes the multi-WAN lab.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f0f0f0;border:1px solid #ccc;padding:8px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Source:&#039;&#039;&#039; Netgate pfSense Plus Fundamentals and Practical Application — Lab 8 (Multi-WAN).&amp;lt;br/&amp;gt;&lt;br /&gt;
© 2021 Rubicon Communications, LLC (Netgate).&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Reference WAN2 IP:&#039;&#039;&#039; 198.51.100.2/24, Gateway: 198.51.100.1&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Previous Module:&#039;&#039;&#039; [[Training:_Multi-WAN|Training: Multi-WAN]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_Multi-WAN&amp;diff=233</id>
		<title>Training: Multi-WAN</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_Multi-WAN&amp;diff=233"/>
		<updated>2026-04-23T07:06:59Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created page with &amp;quot;__NOTOC__  &amp;lt;div style=&amp;quot;background:#e6f3ff;border:1px solid #0066cc;padding:10px;margin-bottom:15px;&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Netgate pfSense Plus Fundamentals — Section 8: Multi-WAN&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt; &amp;lt;i&amp;gt;Overview, redundancy, load balancing, gateway groups, and best practices for multiple Internet connections.&amp;lt;/i&amp;gt; &amp;lt;/div&amp;gt;  == Multi-WAN Overview ==  Use of multiple Internet connections for: * &amp;#039;&amp;#039;&amp;#039;Redundancy&amp;#039;&amp;#039;&amp;#039; (common) * &amp;#039;&amp;#039;&amp;#039;Bandwidth aggregation&amp;#039;&amp;#039;&amp;#039; * &amp;#039;&amp;#039;&amp;#039;Load balancing&amp;#039;&amp;#039;&amp;#039;  == Multi-WAN Best Practices ==...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#e6f3ff;border:1px solid #0066cc;padding:10px;margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Netgate pfSense Plus Fundamentals — Section 8: Multi-WAN&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;i&amp;gt;Overview, redundancy, load balancing, gateway groups, and best practices for multiple Internet connections.&amp;lt;/i&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Multi-WAN Overview ==&lt;br /&gt;
&lt;br /&gt;
Use of multiple Internet connections for:&lt;br /&gt;
* &#039;&#039;&#039;Redundancy&#039;&#039;&#039; (common)&lt;br /&gt;
* &#039;&#039;&#039;Bandwidth aggregation&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Load balancing&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Multi-WAN Best Practices ==&lt;br /&gt;
&lt;br /&gt;
Internet connectivity selection considerations:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Consideration !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Performance || Evaluate throughput, latency, and reliability of each link.&lt;br /&gt;
|-&lt;br /&gt;
| Cable path || Use physically diverse paths to avoid single points of failure.&lt;br /&gt;
|-&lt;br /&gt;
| Disparate ISP networks || Use different ISPs to reduce the risk of a common outage.&lt;br /&gt;
|-&lt;br /&gt;
| Plan for failure! || Always design with failure scenarios in mind.&lt;br /&gt;
|-&lt;br /&gt;
| Usage scenarios for load balancing || Understand traffic patterns before implementing load balancing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Multi-WAN Gateways ==&lt;br /&gt;
&lt;br /&gt;
Each gateway defines an Internet connection.&lt;br /&gt;
&lt;br /&gt;
* Monitor IP can be changed.&lt;br /&gt;
* Advanced parameters available (latency and packet loss thresholds).&lt;br /&gt;
&lt;br /&gt;
== Multi-WAN Gateway Groups ==&lt;br /&gt;
&lt;br /&gt;
Gateway groups are containers of gateways (Internet connections).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Attribute !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Tiers 1-5 || Lowest tier number is highest priority.&lt;br /&gt;
|-&lt;br /&gt;
| One or more gateways per tier || Multiple gateways can share a tier.&lt;br /&gt;
|-&lt;br /&gt;
| Usage || Applied via policy routing, IPsec, OpenVPN, Dynamic DNS.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Multi-WAN Outbound Traffic ==&lt;br /&gt;
&lt;br /&gt;
Controlled via &#039;&#039;&#039;policy routing&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* Firewall rules specifying a gateway.&lt;br /&gt;
* Matching traffic is forced to the specified gateway.&lt;br /&gt;
* Overrides routing table in all circumstances.&lt;br /&gt;
&lt;br /&gt;
== Multi-WAN Inbound Traffic ==&lt;br /&gt;
&lt;br /&gt;
* Port forwards and 1:1 NAT are specific to one WAN.&lt;br /&gt;
* Duplicate port forwards for additional WANs.&lt;br /&gt;
* Add 1:1 NAT entries for additional WANs.&lt;br /&gt;
* Update how traffic comes in (DNS updates).&lt;br /&gt;
* Dynamic DNS on gateway group.&lt;br /&gt;
* Multiple inbound options always live (e.g., email — one MX record per WAN).&lt;br /&gt;
&lt;br /&gt;
== Section 8 Summary ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key Point !! Detail&lt;br /&gt;
|-&lt;br /&gt;
| Rule ordering || First match wins.&lt;br /&gt;
|-&lt;br /&gt;
| Bypass rule || A bypass rule may be required.&lt;br /&gt;
|-&lt;br /&gt;
| Gateway forcing || Matching traffic is forced to gateway.&lt;br /&gt;
|-&lt;br /&gt;
| Monitor IP || Use appropriate monitor IP per WAN.&lt;br /&gt;
|-&lt;br /&gt;
| Load balancing || Load-balance over equal-size links.&lt;br /&gt;
|-&lt;br /&gt;
| Per-flow balancing || Load-balancing is per-flow, not per-packet.&lt;br /&gt;
|-&lt;br /&gt;
| Reference || Check the Multi-WAN section of the book!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f0f0f0;border:1px solid #ccc;padding:8px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Source:&#039;&#039;&#039; Netgate pfSense Plus Fundamentals and Practical Application — Section 8 (Multi-WAN).&amp;lt;br/&amp;gt;&lt;br /&gt;
© 2017 Rubicon Communications, LLC dba Netgate.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Next Module:&#039;&#039;&#039; [[Training_Lab_8:_Multi-WAN|Training Lab 8: Multi-WAN]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_4:_Services_and_Branch_Network&amp;diff=232</id>
		<title>Training Lab 4: Services and Branch Network</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_4:_Services_and_Branch_Network&amp;diff=232"/>
		<updated>2026-04-23T07:01:36Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created from Netgate pfSense training PDFs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #fff3cd; border-left: 6px solid #ffc107; padding: 15px; margin-bottom: 20px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Lab:&amp;lt;/strong&amp;gt; Lab 4 — Services and Branch Network Setup&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Course:&amp;lt;/strong&amp;gt; Netgate FUND001-LIVE — pfSense Plus Fundamentals and Practical Application&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Objective:&amp;lt;/strong&amp;gt; Configure common pfSense Plus services (DNS Resolver, DHCP Server) and bring up a branch network for use in the next lab.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lab Overview ==&lt;br /&gt;
&lt;br /&gt;
In this lab, we will go through a couple of the common services used on pfSense Plus, then bring up the branch network to be used in the next lab.&lt;br /&gt;
&lt;br /&gt;
The exercises cover:&lt;br /&gt;
&lt;br /&gt;
* Configuring the &#039;&#039;&#039;DNS Resolver&#039;&#039;&#039; (domain overrides, host overrides)&lt;br /&gt;
* Configuring the &#039;&#039;&#039;DHCP Server&#039;&#039;&#039; (changing scope, adding static mappings)&lt;br /&gt;
* &#039;&#039;&#039;Branch network setup&#039;&#039;&#039; and remote management&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
* Access to fw1-HQ (172.17.1.1)&lt;br /&gt;
* Access to HQ-client (DHCP client on HQ-LAN)&lt;br /&gt;
* Access to branch firewall (172.18.1.1)&lt;br /&gt;
* Default admin/pfsense credentials&lt;br /&gt;
&lt;br /&gt;
== Exercise 1: DNS Resolver Configuration ==&lt;br /&gt;
&lt;br /&gt;
The DNS Resolver provides a local caching DNS resolver on the firewall. On smaller networks with no local DNS servers, using the local DNS Resolver as your clients&#039; DNS server — rather than directly assigning DNS servers on the Internet — is preferable.&lt;br /&gt;
&lt;br /&gt;
It provides:&lt;br /&gt;
&lt;br /&gt;
* A local DNS cache&lt;br /&gt;
* Ability to query multiple DNS servers simultaneously, returning the fastest response&lt;br /&gt;
* Security protections such as DNS rebinding protection and DNSSEC&lt;br /&gt;
&lt;br /&gt;
=== 1.1 DNS Server Configuration ===&lt;br /&gt;
&lt;br /&gt;
By default, the DNS Resolver queries root DNS servers directly and does not use DNS servers configured under &#039;&#039;&#039;System &amp;amp;gt; General Setup&#039;&#039;&#039; or those obtained automatically from a dynamic WAN.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; Browse to &#039;&#039;&#039;System &amp;amp;gt; General Setup&#039;&#039;&#039; on fw1-HQ.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Review the DNS server configuration. Currently, fw1-HQ is statically configured to use the DNS Resolver on lab-internet-router.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; The &#039;&#039;&#039;&amp;quot;Allow DNS server list to be overridden by DHCP/PPP on WAN&amp;quot;&#039;&#039;&#039; checkbox is checked by default. Since these systems do not have dynamic WANs, this option has no effect. &#039;&#039;&#039;Uncheck&#039;&#039;&#039; this option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 4:&#039;&#039;&#039; Leave the remaining settings as they are and click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 1.2 Domain Overrides ===&lt;br /&gt;
&lt;br /&gt;
Domain overrides allow you to configure specific DNS servers to use for particular domains.&lt;br /&gt;
&lt;br /&gt;
In this exercise, we will forward &#039;&#039;&#039;example.lan&#039;&#039;&#039; to &#039;&#039;&#039;172.17.2.10&#039;&#039;&#039;. This is functionally equivalent to what you would do in a Small Business Server (SBS) scenario for Active Directory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; On HQ-client, open a terminal and test resolution &#039;&#039;&#039;before&#039;&#039;&#039; adding the domain override:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@HQ-client:~$ host server1.example.lan&lt;br /&gt;
Host server1.example.lan not found: 3(NXDOMAIN)&lt;br /&gt;
training@HQ-client:~$ host server2.example.lan&lt;br /&gt;
Host server2.example.lan not found: 3(NXDOMAIN)&lt;br /&gt;
training@HQ-client:~$ host hq-client.example.lan&lt;br /&gt;
Host hq-client.example.lan not found: 3(NXDOMAIN)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NXDOMAIN means &amp;quot;no such name exists.&amp;quot; To resolve example.lan, we must tell the DNS Resolver where to send those queries.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; On fw1-HQ, browse to &#039;&#039;&#039;Services &amp;amp;gt; DNS Resolver&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Scroll down to &#039;&#039;&#039;Domain Overrides&#039;&#039;&#039; and click &#039;&#039;&#039;+Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 4:&#039;&#039;&#039; Configure the domain override:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Domain&lt;br /&gt;
| example.lan&lt;br /&gt;
|-&lt;br /&gt;
| IP Address&lt;br /&gt;
| 172.17.2.10&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 5:&#039;&#039;&#039; Click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 1.3 Testing Domain Override ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; On HQ-client, open a terminal and test resolution again:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@hq-client:~$ host server1.example.lan&lt;br /&gt;
server1.example.lan has address 172.17.2.10&lt;br /&gt;
training@hq-client:~$ host server2.example.lan&lt;br /&gt;
server2.example.lan has address 172.17.2.20&lt;br /&gt;
training@hq-client:~$ host hq-client.example.lan&lt;br /&gt;
hq-client.example.lan has address 172.17.1.100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These queries go to the DNS Resolver on fw1-HQ, which uses the domain override to send example.lan queries to server1. Server1 replies to the DNS Resolver, which replies back to HQ-client.&lt;br /&gt;
&lt;br /&gt;
=== 1.4 Host Overrides ===&lt;br /&gt;
&lt;br /&gt;
Host overrides allow you to configure how a specific hostname is resolved by the DNS Resolver. A common use is &#039;&#039;&#039;split DNS&#039;&#039;&#039;: resolving public DNS hostnames to private IPs internally to eliminate the need for NAT reflection.&lt;br /&gt;
&lt;br /&gt;
In this lab:&lt;br /&gt;
&lt;br /&gt;
* www.example.com is hosted in the HQ DMZ on server1&lt;br /&gt;
* www.example.com publicly resolves to 192.0.2.4&lt;br /&gt;
* Without NAT reflection, HQ internal hosts cannot reach 192.0.2.4&lt;br /&gt;
* We will add a host override to resolve www.example.com to the internal IP 172.17.2.10&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; On fw1-HQ, browse to &#039;&#039;&#039;Services &amp;amp;gt; DNS Resolver&#039;&#039;&#039;, scroll down to &#039;&#039;&#039;Host Overrides&#039;&#039;&#039;, and click &#039;&#039;&#039;+Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Configure the host override:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Host&lt;br /&gt;
| (leave blank)&lt;br /&gt;
|-&lt;br /&gt;
| Domain&lt;br /&gt;
| example.com&lt;br /&gt;
|-&lt;br /&gt;
| IP address&lt;br /&gt;
| 172.17.2.10&lt;br /&gt;
|-&lt;br /&gt;
| Alias Host&lt;br /&gt;
| www&lt;br /&gt;
|-&lt;br /&gt;
| Alias Domain&lt;br /&gt;
| example.com&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 1.5 Testing Host Override ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; On HQ-client, test resolution:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@HQ-client:~$ host www.example.com&lt;br /&gt;
www.example.com has address 172.17.2.10&lt;br /&gt;
training@HQ-client:~$ host example.com&lt;br /&gt;
example.com has address 172.17.2.10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Open &#039;&#039;&#039;www.example.com&#039;&#039;&#039; in your web browser on HQ-client. The page should load, showing it is from server1 and displaying your source IP.&lt;br /&gt;
&lt;br /&gt;
== Exercise 2: DHCP Server Configuration ==&lt;br /&gt;
&lt;br /&gt;
The DHCP Server comes enabled by default on LAN, assigning IP information, a default gateway, and DNS server to LAN clients.&lt;br /&gt;
&lt;br /&gt;
HQ-client is a DHCP client currently obtaining an IP from the general pool. Because it is the first and only device on HQ-LAN, it gets the first IP: &#039;&#039;&#039;172.17.1.100&#039;&#039;&#039;. We want to ensure HQ-client is always assigned the .100 IP and that it cannot be assigned to any other host.&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Checking DHCP Status ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; On fw1-HQ, browse to &#039;&#039;&#039;Status &amp;amp;gt; DHCP Leases&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Locate the lease for HQ-client.&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Changing DHCP Scope ===&lt;br /&gt;
&lt;br /&gt;
The underlying DHCP server (ISC dhcpd) requires statically mapped IPs to be &#039;&#039;&#039;outside of the DHCP scope&#039;&#039;&#039;. Since .100 is part of the currently active range, we must change the range to exclude it.&lt;br /&gt;
&lt;br /&gt;
Note: Doing so will not immediately impact HQ-client. It will retain its existing .100 IP until its next renewal.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; Browse to &#039;&#039;&#039;Services &amp;amp;gt; DHCP Server&#039;&#039;&#039; and click the &#039;&#039;&#039;LAN&#039;&#039;&#039; tab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Change the &#039;&#039;&#039;Start of the range&#039;&#039;&#039; to &#039;&#039;&#039;172.17.1.101&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now .100 will be available for a DHCP reservation.&lt;br /&gt;
&lt;br /&gt;
=== 2.3 Adding DHCP Static Mapping for HQ-client ===&lt;br /&gt;
&lt;br /&gt;
First, we need to renew the DHCP lease on HQ-client so it re-populates in the DHCP leases screen (its lease for .100 was deleted after changing the scope).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; On HQ-client, click the network icon in the top right corner and click &#039;&#039;&#039;&amp;quot;Ifupdown (eth0)&amp;quot;&#039;&#039;&#039; to renew the lease.&lt;br /&gt;
&lt;br /&gt;
Note: Your VNC session will be dropped. Wait a few seconds.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; On fw1-HQ, refresh &#039;&#039;&#039;Status &amp;amp;gt; DHCP Leases&#039;&#039;&#039;. After 20-30 seconds, you should see HQ-client obtained a lease for &#039;&#039;&#039;172.17.1.101&#039;&#039;&#039;. Reconnect to VNC using the .101 IP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Browse to &#039;&#039;&#039;Status &amp;amp;gt; DHCP Leases&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 4:&#039;&#039;&#039; Click the &#039;&#039;&#039;+&#039;&#039;&#039; to the right of the HQ-client lease to add a DHCP static mapping.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 5:&#039;&#039;&#039; At the &amp;quot;Edit static mapping&amp;quot; screen, fill in:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| IP address&lt;br /&gt;
| 172.17.1.100&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 6:&#039;&#039;&#039; Click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 2.4 Renewing DHCP Lease on HQ-client ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; Force HQ-client to renew its DHCP lease again (click network icon → &amp;quot;Ifupdown (eth0)&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Note: This will drop your VNC session again. Wait a few seconds for it to pick up the lease for the static mapping, then reconnect using &#039;&#039;&#039;172.17.1.100&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Browse to &#039;&#039;&#039;Status &amp;amp;gt; DHCP Leases&#039;&#039;&#039; on fw1-HQ and verify HQ-client&#039;s static mapping status.&lt;br /&gt;
&lt;br /&gt;
== Exercise 3: Branch Network Setup ==&lt;br /&gt;
&lt;br /&gt;
Here we will bring the branch network online to be ready for use in the next lab.&lt;br /&gt;
&lt;br /&gt;
=== 3.1 Initial Branch Firewall Access ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; Browse to &#039;&#039;&#039;https://172.18.1.1&#039;&#039;&#039; from your system.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Add an exception for the self-signed certificate.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Log in with the default credentials &#039;&#039;&#039;admin / pfsense&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note: This will not trigger the setup wizard, as this VM comes pre-configured past that point.&lt;br /&gt;
&lt;br /&gt;
=== 3.2 Setting Up Remote Management ===&lt;br /&gt;
&lt;br /&gt;
We will have a VPN connected into this location in the next lab. However, it is usually best to have a means into remote offices&#039; firewalls without requiring a VPN, limited to specific trusted source IPs.&lt;br /&gt;
&lt;br /&gt;
==== Add RemoteAdmin Alias ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; Browse to &#039;&#039;&#039;Firewall &amp;amp;gt; Aliases&#039;&#039;&#039; and click &#039;&#039;&#039;+Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Create the alias with the following parameters:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| RemoteAdmin&lt;br /&gt;
|-&lt;br /&gt;
| Type&lt;br /&gt;
| Networks&lt;br /&gt;
|-&lt;br /&gt;
| Members&lt;br /&gt;
| 192.0.2.0/24 (HQ WAN)&amp;lt;br&amp;gt;198.51.100.0/24 (HQ WAN2)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Add Firewall Rule ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; Browse to &#039;&#039;&#039;Firewall &amp;amp;gt; Rules&#039;&#039;&#039;, click the &#039;&#039;&#039;WAN&#039;&#039;&#039; tab, and click &#039;&#039;&#039;Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Configure the rule:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action&lt;br /&gt;
| Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface&lt;br /&gt;
| WAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol&lt;br /&gt;
| any&lt;br /&gt;
|-&lt;br /&gt;
| Source&lt;br /&gt;
| Single host or alias → RemoteAdmin&lt;br /&gt;
|-&lt;br /&gt;
| Destination&lt;br /&gt;
| WAN address&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| allow remote administration from trusted IPs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 3.3 Test Remote Administration ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; On HQ-client, browse to &#039;&#039;&#039;https://203.0.113.10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; It should load, allowing you to log in and manage the branch system from HQ.&lt;br /&gt;
&lt;br /&gt;
You have now reached the end of this lab.&lt;br /&gt;
&lt;br /&gt;
== Lab Summary ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Exercise&lt;br /&gt;
! What We Did&lt;br /&gt;
! Key Takeaway&lt;br /&gt;
|-&lt;br /&gt;
| DNS Resolver&lt;br /&gt;
| Configured domain overrides and host overrides&lt;br /&gt;
| Use overrides for internal domains and split DNS&lt;br /&gt;
|-&lt;br /&gt;
| DHCP Server&lt;br /&gt;
| Changed scope and added static mapping&lt;br /&gt;
| Static IPs must be outside the DHCP pool&lt;br /&gt;
|-&lt;br /&gt;
| Branch Setup&lt;br /&gt;
| Brought branch firewall online, added remote admin access&lt;br /&gt;
| Restrict remote admin to trusted source IPs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
&lt;br /&gt;
Continue to the next lab for VPN configuration and connecting the branch network.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Source: Netgate FUND001-LIVE-Lab4-Services.pdf&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Training]]&lt;br /&gt;
[[Category:pfSense]]&lt;br /&gt;
[[Category:Networking]]&lt;br /&gt;
[[Category:Lab]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_pfSense_Services&amp;diff=231</id>
		<title>Training: pfSense Services</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_pfSense_Services&amp;diff=231"/>
		<updated>2026-04-23T07:01:36Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created from Netgate pfSense training PDFs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #e7f3fe; border-left: 6px solid #2196F3; padding: 15px; margin-bottom: 20px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Module:&amp;lt;/strong&amp;gt; Section 4 — pfSense Plus Services&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Course:&amp;lt;/strong&amp;gt; Netgate FUND001-LIVE — pfSense Plus Fundamentals and Practical Application&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Topics Covered:&amp;lt;/strong&amp;gt; DHCP, DNS Resolver/Forwarder, Dynamic DNS, NTP, SNMP, UPnP / NAT-PMP, IGMP Proxy, PPPoE Server, Wake on LAN&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Objective:&amp;lt;/strong&amp;gt; Understand the built-in services available on pfSense Plus and how to configure and secure them.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Learning Objectives ==&lt;br /&gt;
&lt;br /&gt;
By the end of this module, you will be able to:&lt;br /&gt;
&lt;br /&gt;
* Identify the core network services built into pfSense Plus&lt;br /&gt;
* Understand the difference between DHCP Server and DHCP Relay&lt;br /&gt;
* Configure the DNS Resolver for local caching and recursion&lt;br /&gt;
* Explain the purpose of Dynamic DNS, NTP, SNMP, and UPnP&lt;br /&gt;
* Apply security best practices for exposed services&lt;br /&gt;
&lt;br /&gt;
== Overview of pfSense Plus Services ==&lt;br /&gt;
&lt;br /&gt;
pfSense Plus includes a rich set of network services that can be enabled and configured as needed. These services help manage client connectivity, name resolution, time synchronization, monitoring, and more.&lt;br /&gt;
&lt;br /&gt;
The available services include:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHCP Server&#039;&#039;&#039; — Assigns IP addresses and network information to clients&lt;br /&gt;
* &#039;&#039;&#039;DHCP Relay&#039;&#039;&#039; — Forwards DHCP requests to servers on another network&lt;br /&gt;
* &#039;&#039;&#039;DNS Forwarder (legacy)&#039;&#039;&#039; — Forwards DNS queries to external servers&lt;br /&gt;
* &#039;&#039;&#039;DNS Resolver&#039;&#039;&#039; — Caching DNS resolver with recursion support&lt;br /&gt;
* &#039;&#039;&#039;Dynamic DNS&#039;&#039;&#039; — Updates DNS records automatically when the WAN IP changes&lt;br /&gt;
* &#039;&#039;&#039;IGMP Proxy&#039;&#039;&#039; — Forwards IGMP multicast traffic between interfaces&lt;br /&gt;
* &#039;&#039;&#039;NTP Server&#039;&#039;&#039; — Provides Network Time Protocol services to local clients&lt;br /&gt;
* &#039;&#039;&#039;PPPoE Server&#039;&#039;&#039; — Terminates PPPoE client connections&lt;br /&gt;
* &#039;&#039;&#039;SNMP&#039;&#039;&#039; — Integrates with network monitoring systems&lt;br /&gt;
* &#039;&#039;&#039;UPnP / NAT-PMP&#039;&#039;&#039; — Allows internal clients to automatically open NAT ports&lt;br /&gt;
* &#039;&#039;&#039;Wake on LAN&#039;&#039;&#039; — Sends magic packets to wake up sleeping devices&lt;br /&gt;
&lt;br /&gt;
== DHCP Service ==&lt;br /&gt;
&lt;br /&gt;
=== DHCP Server ===&lt;br /&gt;
&lt;br /&gt;
The DHCP Server assigns IP addresses and other network information (subnet mask, gateway, DNS) to clients. It is &#039;&#039;&#039;enabled by default on the LAN interface&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Key points:&lt;br /&gt;
&lt;br /&gt;
* Supports many extensible options (custom DHCP options)&lt;br /&gt;
* Static mappings can reserve specific IPs for known MAC addresses&lt;br /&gt;
* The underlying server is ISC dhcpd&lt;br /&gt;
&lt;br /&gt;
=== DHCP Relay ===&lt;br /&gt;
&lt;br /&gt;
DHCP Relay sends DHCP requests from clients on one network to DHCP server(s) on another network, then returns the DHCP reply to the requesting client.&lt;br /&gt;
&lt;br /&gt;
* Simple concept but very useful in segmented networks&lt;br /&gt;
* Only one of DHCP Server or DHCP Relay can be enabled on an interface (not both)&lt;br /&gt;
&lt;br /&gt;
== DNS Resolver ==&lt;br /&gt;
&lt;br /&gt;
The DNS Resolver (unbound) is the &#039;&#039;&#039;recommended DNS solution&#039;&#039;&#039; for pfSense Plus.&lt;br /&gt;
&lt;br /&gt;
* It is a &#039;&#039;&#039;caching DNS resolver&#039;&#039;&#039;&lt;br /&gt;
* Requires DNS servers for recursion (queries root servers directly by default)&lt;br /&gt;
* Queries all configured DNS servers and takes the fastest response&lt;br /&gt;
* Should be configured for &#039;&#039;&#039;internal-only access&#039;&#039;&#039; to avoid reflected DDoS exploit risks&lt;br /&gt;
* Supports DNSSEC for verifiable and trustworthy DNS results&lt;br /&gt;
* Offers DNS rebinding protection&lt;br /&gt;
&lt;br /&gt;
Key configuration options:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Domain Overrides&#039;&#039;&#039; — Forward queries for specific domains to specific DNS servers&lt;br /&gt;
* &#039;&#039;&#039;Host Overrides&#039;&#039;&#039; — Resolve specific hostnames to custom IPs (useful for split DNS)&lt;br /&gt;
* &#039;&#039;&#039;DNS Query Forwarding&#039;&#039;&#039; — Optionally forward all queries to upstream DNS servers instead of querying roots directly&lt;br /&gt;
&lt;br /&gt;
== DNS Forwarder (Legacy) ==&lt;br /&gt;
&lt;br /&gt;
The DNS Forwarder (dnsmasq) is the legacy DNS option. The DNS Resolver is preferred for new deployments.&lt;br /&gt;
&lt;br /&gt;
== Dynamic DNS ==&lt;br /&gt;
&lt;br /&gt;
Dynamic DNS automatically updates DNS records when the WAN IP address changes. This is essential for:&lt;br /&gt;
&lt;br /&gt;
* Hosting services on dynamic IP connections&lt;br /&gt;
* Remote access to networks with non-static public IPs&lt;br /&gt;
&lt;br /&gt;
== NTP Server ==&lt;br /&gt;
&lt;br /&gt;
The Network Time Protocol (NTP) Server provides time synchronization services to local clients.&lt;br /&gt;
&lt;br /&gt;
* Time synchronization is &#039;&#039;&#039;very important&#039;&#039;&#039; for logging, certificates, and authentication&lt;br /&gt;
* Supports serial GPS as a time source&lt;br /&gt;
* The host&#039;s own NTP server is configured under &#039;&#039;&#039;System &amp;amp;gt; General Setup&#039;&#039;&#039;&lt;br /&gt;
* Status can be checked under &#039;&#039;&#039;Status &amp;amp;gt; NTP&#039;&#039;&#039;&lt;br /&gt;
* It is easy to offer NTP services to clients — enable the service and allow the traffic&lt;br /&gt;
&lt;br /&gt;
== SNMP ==&lt;br /&gt;
&lt;br /&gt;
SNMP (Simple Network Management Protocol) integrates pfSense Plus with network monitoring platforms.&lt;br /&gt;
&lt;br /&gt;
Best practices:&lt;br /&gt;
&lt;br /&gt;
* Use a &#039;&#039;&#039;strong community string&#039;&#039;&#039;&lt;br /&gt;
* Configure to send traps and allow polling as needed&lt;br /&gt;
* &#039;&#039;&#039;Protect with firewall rules&#039;&#039;&#039; or bind to specific interfaces&lt;br /&gt;
* &#039;&#039;&#039;Do not expose SNMP to the WAN!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== UPnP / NAT-PMP ==&lt;br /&gt;
&lt;br /&gt;
UPnP (Universal Plug and Play) and NAT-PMP (NAT Port Mapping Protocol) allow internal clients to automatically request port forwards from the firewall.&lt;br /&gt;
&lt;br /&gt;
* Useful for gaming consoles, VoIP, and peer-to-peer applications&lt;br /&gt;
* Can be a security risk if not properly restricted&lt;br /&gt;
* Consider limiting to specific interfaces and restricting port ranges&lt;br /&gt;
&lt;br /&gt;
== Other Services ==&lt;br /&gt;
&lt;br /&gt;
=== IGMP Proxy ===&lt;br /&gt;
&lt;br /&gt;
Forwards IGMP multicast traffic between interfaces. Used for IPTV and other multicast applications.&lt;br /&gt;
&lt;br /&gt;
=== PPPoE Server ===&lt;br /&gt;
&lt;br /&gt;
Terminates PPPoE client connections. Used in ISP and WISP environments.&lt;br /&gt;
&lt;br /&gt;
=== Wake on LAN ===&lt;br /&gt;
&lt;br /&gt;
Sends magic packets to wake up sleeping devices on the local network.&lt;br /&gt;
&lt;br /&gt;
== Security Best Practices ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Service&lt;br /&gt;
! Best Practice&lt;br /&gt;
|-&lt;br /&gt;
| DNS Resolver&lt;br /&gt;
| Bind to internal interfaces only; enable DNSSEC&lt;br /&gt;
|-&lt;br /&gt;
| SNMP&lt;br /&gt;
| Use strong community strings; do not expose to WAN&lt;br /&gt;
|-&lt;br /&gt;
| NTP&lt;br /&gt;
| Restrict to internal networks; use authenticated NTP where possible&lt;br /&gt;
|-&lt;br /&gt;
| UPnP&lt;br /&gt;
| Limit to trusted interfaces; restrict port ranges&lt;br /&gt;
|-&lt;br /&gt;
| DHCP&lt;br /&gt;
| Use static mappings for critical infrastructure&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Use the &#039;&#039;&#039;DNS Resolver&#039;&#039;&#039; as your primary DNS solution — it can point to internal DNS servers and offers caching, DNSSEC, and security protections&lt;br /&gt;
* Integrate pfSense Plus with &#039;&#039;&#039;network monitoring platforms&#039;&#039;&#039; via SNMP&lt;br /&gt;
* &#039;&#039;&#039;Protect SNMP, NTP, and DNS Resolver&#039;&#039;&#039; with firewall rules and interface bindings&lt;br /&gt;
* &#039;&#039;&#039;Offer NTP services to clients&#039;&#039;&#039; — it is easy to enable and critical for network operations&lt;br /&gt;
* Choose between DHCP Server and DHCP Relay based on your network topology&lt;br /&gt;
* Restrict or avoid exposing services to the WAN unless absolutely necessary&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
&lt;br /&gt;
Continue to &#039;&#039;&#039;[[Training_Lab_4:_Services_and_Branch_Network|Lab 4: Services and Branch Network Setup]]&#039;&#039;&#039; for hands-on exercises configuring the DNS Resolver, DHCP Server, and bringing up a branch network.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Source: Netgate FUND001-LIVE-SLIDE-SEG4-SERVICES.pdf&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Training]]&lt;br /&gt;
[[Category:pfSense]]&lt;br /&gt;
[[Category:Networking]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_3:_NAT_and_Virtual_IPs&amp;diff=230</id>
		<title>Training Lab 3: NAT and Virtual IPs</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_3:_NAT_and_Virtual_IPs&amp;diff=230"/>
		<updated>2026-04-23T06:58:56Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created from Netgate pfSense training PDF&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #fff3e0; border-left: 6px solid #FF9800; padding: 16px; margin-bottom: 20px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Lab Overview:&amp;lt;/strong&amp;gt; This hands-on lab covers Virtual IPs, Port Forwards, 1:1 NAT, and Outbound NAT in pfSense Plus. You will configure VIPs on the WAN subnet &amp;lt;code&amp;gt;192.0.2.0/24&amp;lt;/code&amp;gt; and implement various NAT scenarios using Virtual IPs &amp;lt;code&amp;gt;192.0.2.4&amp;lt;/code&amp;gt;–&amp;lt;code&amp;gt;192.0.2.6&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lab Environment ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ WAN Subnet Allocation&lt;br /&gt;
|-&lt;br /&gt;
! IP Address !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 192.0.2.1 || ISP router (default gateway)&lt;br /&gt;
|-&lt;br /&gt;
| 192.0.2.2 || fw1-HQ WAN IP&lt;br /&gt;
|-&lt;br /&gt;
| 192.0.2.3 || Reserved for fw2-HQ (Advanced Application class)&lt;br /&gt;
|-&lt;br /&gt;
| 192.0.2.4 || Virtual IP — server1 WAN external address&lt;br /&gt;
|-&lt;br /&gt;
| 192.0.2.5 || Virtual IP — server2 WAN external address&lt;br /&gt;
|-&lt;br /&gt;
| 192.0.2.6 || Virtual IP — hq-client / VoIP PBX alternate outbound&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Exercise 1: Configuring Virtual IPs ==&lt;br /&gt;
&lt;br /&gt;
At HQ, we have a /24 public IP subnet assigned by our ISP: &amp;lt;code&amp;gt;192.0.2.0/24&amp;lt;/code&amp;gt;. In most real-world networks, this will be a smaller subnet such as a /29, /28, or /27. The concepts are the same regardless of subnet size.&lt;br /&gt;
&lt;br /&gt;
Our WAN1 ISP router has IP &amp;lt;code&amp;gt;192.0.2.1&amp;lt;/code&amp;gt;, used as the default gateway. fw1-HQ has a WAN IP of &amp;lt;code&amp;gt;192.0.2.2&amp;lt;/code&amp;gt;. In order for us to use additional IPs in the WAN1 subnet, the firewall must answer ARP requests for those addresses — this tells the ISP router to send traffic destined to those addresses to the firewall.&lt;br /&gt;
&lt;br /&gt;
=== Step 1.1 — Add VIP 192.0.2.4 ===&lt;br /&gt;
&lt;br /&gt;
On fw1-HQ, browse to &#039;&#039;&#039;Firewall → Virtual IPs&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;+ Add&#039;&#039;&#039; to add a new VIP.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ VIP Configuration for server1&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Type || IP alias&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| IP Address || 192.0.2.4/32&lt;br /&gt;
|-&lt;br /&gt;
| Description || server1 WAN external address&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You can enter the IP without choosing a mask; the JavaScript on the page will automatically set the mask to /32 after detecting an IPv4 address.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039;, then click &#039;&#039;&#039;+ Add&#039;&#039;&#039; again to add the second VIP.&lt;br /&gt;
&lt;br /&gt;
=== Step 1.2 — Add VIP 192.0.2.5 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ VIP Configuration for server2&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Type || IP alias&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| IP Address || 192.0.2.5/32&lt;br /&gt;
|-&lt;br /&gt;
| Description || server2 WAN external&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039;, then add the third VIP.&lt;br /&gt;
&lt;br /&gt;
=== Step 1.3 — Add VIP 192.0.2.6 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ VIP Configuration for PBX / alternate outbound&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Type || IP alias&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| IP Address || 192.0.2.6/32&lt;br /&gt;
|-&lt;br /&gt;
| Description || VoIP PBX / alternate outbound IP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039;, then click &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now &amp;lt;code&amp;gt;192.0.2.4&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;192.0.2.5&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;192.0.2.6&amp;lt;/code&amp;gt; are available for use. Adding VIPs only makes the firewall answer on the configured addresses; they are not yet used for NAT.&lt;br /&gt;
&lt;br /&gt;
== Exercise 2: Configuring a Basic Port Forward ==&lt;br /&gt;
&lt;br /&gt;
We will set up a port forward allowing remote desktop access from the host machine to hq-client using VNC.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Opening VNC to the Internet is not recommended in production. Use a VPN instead. This is for demonstration purposes only.&lt;br /&gt;
&lt;br /&gt;
=== Step 2.1 — Create VNC Port Forward ===&lt;br /&gt;
&lt;br /&gt;
On fw1-HQ, browse to &#039;&#039;&#039;Firewall → NAT&#039;&#039;&#039;, Port Forward tab. Click &#039;&#039;&#039;Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ VNC Port Forward Rule&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || TCP&lt;br /&gt;
|-&lt;br /&gt;
| Source || any&lt;br /&gt;
|-&lt;br /&gt;
| Destination || WAN address&lt;br /&gt;
|-&lt;br /&gt;
| Destination port || 5900&lt;br /&gt;
|-&lt;br /&gt;
| Redirect target IP || 172.17.1.100&lt;br /&gt;
|-&lt;br /&gt;
| Redirect target port || 5900&lt;br /&gt;
|-&lt;br /&gt;
| Description || forward VNC to hq-client&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039;, and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Step 2.2 — Verify the Port Forward ===&lt;br /&gt;
&lt;br /&gt;
From your host OS or the internet-host VM, connect to &amp;lt;code&amp;gt;192.0.2.2:5900&amp;lt;/code&amp;gt; with VNC Viewer.&lt;br /&gt;
&lt;br /&gt;
On fw1-HQ, browse to &#039;&#039;&#039;Diagnostics → States&#039;&#039;&#039; and filter for &amp;lt;code&amp;gt;:5900&amp;lt;/code&amp;gt;. You will see two states: inbound (WAN) and outbound (LAN).&lt;br /&gt;
&lt;br /&gt;
== Exercise 3: Port Forward on a Different External Port ==&lt;br /&gt;
&lt;br /&gt;
Sometimes you need to use a different external port than the internal port. For example, opening SSH on port 222 externally to port 22 internally reduces SSH brute-force log noise.&lt;br /&gt;
&lt;br /&gt;
=== Step 3.1 — Create Alternate SSH Port Forward ===&lt;br /&gt;
&lt;br /&gt;
Instead of clicking &#039;&#039;&#039;Add&#039;&#039;&#039;, click the &#039;&#039;&#039;copy&#039;&#039;&#039; icon to the right of the VNC port forward to duplicate it. Then change:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Alternate SSH Port Forward Rule&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Destination port || 222&lt;br /&gt;
|-&lt;br /&gt;
| Redirect target port || 22&lt;br /&gt;
|-&lt;br /&gt;
| Description || external SSH port 222 to hq-client&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Save&#039;&#039;&#039; and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Step 3.2 — Test SSH Connection ===&lt;br /&gt;
&lt;br /&gt;
From your computer, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh -p 222 training@192.0.2.2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or from Windows, use PuTTY with IP &amp;lt;code&amp;gt;192.0.2.2&amp;lt;/code&amp;gt; and port &amp;lt;code&amp;gt;222&amp;lt;/code&amp;gt;, ensuring SSH is selected.&lt;br /&gt;
&lt;br /&gt;
== Exercise 4: Restricted Source Port Forward ==&lt;br /&gt;
&lt;br /&gt;
Restrict the hq-client VNC port forward to the RemoteAdmins alias.&lt;br /&gt;
&lt;br /&gt;
=== Step 4.1 — Edit VNC Port Forward ===&lt;br /&gt;
&lt;br /&gt;
Edit the VNC port forward. In the &#039;&#039;&#039;Source&#039;&#039;&#039; field, click &#039;&#039;&#039;Advanced&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* Type: &#039;&#039;&#039;Single host or alias&#039;&#039;&#039;&lt;br /&gt;
* Address: Type &amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt; to populate the &#039;&#039;&#039;RemoteAdmin&#039;&#039;&#039; alias&lt;br /&gt;
* Source port: &#039;&#039;&#039;any&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
=== Step 4.2 — Verify Restriction ===&lt;br /&gt;
&lt;br /&gt;
* From the remote-host VM (if not in RemoteAdmin alias): connection should fail&lt;br /&gt;
* From the host OS (if in RemoteAdmin alias): connection should succeed&lt;br /&gt;
&lt;br /&gt;
== Exercise 5: Alternate External IP Port Forward ==&lt;br /&gt;
&lt;br /&gt;
Use the Virtual IPs added earlier instead of the WAN IP.&lt;br /&gt;
&lt;br /&gt;
=== Step 5.1 — Create HTTP Port Forward on VIP ===&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Add&#039;&#039;&#039; to add a new port forward.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ HTTP to server1 via VIP&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || TCP&lt;br /&gt;
|-&lt;br /&gt;
| Source || any&lt;br /&gt;
|-&lt;br /&gt;
| Destination || 192.0.2.4&lt;br /&gt;
|-&lt;br /&gt;
| Destination port || 80&lt;br /&gt;
|-&lt;br /&gt;
| Redirect target IP || 172.17.2.10&lt;br /&gt;
|-&lt;br /&gt;
| Redirect target port || 80&lt;br /&gt;
|-&lt;br /&gt;
| Description || HTTP to server1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
=== Step 5.2 — Verify HTTP Access ===&lt;br /&gt;
&lt;br /&gt;
Browse to &amp;lt;code&amp;gt;http://192.0.2.4&amp;lt;/code&amp;gt; from your host OS or internet-host VM. It should display the server1 page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; Reflection is not yet configured, so this will only work from outside the network.&lt;br /&gt;
&lt;br /&gt;
== Exercise 6: Configuring 1:1 NAT ==&lt;br /&gt;
&lt;br /&gt;
1:1 NAT maps one external IP to one internal IP. Port forwards take precedence over 1:1 NAT where they overlap.&lt;br /&gt;
&lt;br /&gt;
=== Step 6.1 — Delete Overlapping Port Forward ===&lt;br /&gt;
&lt;br /&gt;
First, delete the &#039;&#039;&#039;HTTP to server1&#039;&#039;&#039; port forward entry, then apply changes. This is preferable to letting 1:1 NAT handle the traffic.&lt;br /&gt;
&lt;br /&gt;
=== Step 6.2 — Configure 1:1 NAT for server1 ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall → NAT&#039;&#039;&#039;, 1:1 tab. Click &#039;&#039;&#039;Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ 1:1 NAT for server1&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| External || 192.0.2.4&lt;br /&gt;
|-&lt;br /&gt;
| Internal || 172.17.2.10&lt;br /&gt;
|-&lt;br /&gt;
| Description || server1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; Adding a 1:1 NAT entry only defines how traffic is translated. Without firewall rules, no traffic will pass in or out.&lt;br /&gt;
&lt;br /&gt;
=== Step 6.3 — Configure 1:1 NAT for server2 ===&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Add&#039;&#039;&#039; to add another 1:1 NAT entry.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ 1:1 NAT for server2&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| External || 192.0.2.5&lt;br /&gt;
|-&lt;br /&gt;
| Internal || 172.17.2.20&lt;br /&gt;
|-&lt;br /&gt;
| Description || server2.example.com&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
== Exercise 7: Firewall Rules for 1:1 NAT ==&lt;br /&gt;
&lt;br /&gt;
=== Step 7.1 — Allow Pings to Public Web Servers ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall → Rules&#039;&#039;&#039;, WAN tab. Click &#039;&#039;&#039;Add&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ ICMP Rule for Web Servers&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || ICMP&lt;br /&gt;
|-&lt;br /&gt;
| ICMP Type || Echo request&lt;br /&gt;
|-&lt;br /&gt;
| Source || any&lt;br /&gt;
|-&lt;br /&gt;
| Destination || Single host or alias — WebServers alias&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow pings to public web servers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
Test by pinging &amp;lt;code&amp;gt;192.0.2.4&amp;lt;/code&amp;gt; from your host machine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ping 192.0.2.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the ping running and browse to &#039;&#039;&#039;Diagnostics → States&#039;&#039;&#039;. Filter for &amp;lt;code&amp;gt;192.0.2.100:&amp;lt;/code&amp;gt; (if from host OS) and observe the states. Traffic sourced from &amp;lt;code&amp;gt;192.0.2.100&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;192.0.2.4&amp;lt;/code&amp;gt; is translated to &amp;lt;code&amp;gt;172.17.2.10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Step 7.2 — Allow SSH to Web Servers from RemoteAdmins ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ SSH Rule for RemoteAdmins&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || TCP&lt;br /&gt;
|-&lt;br /&gt;
| Source || Single host or alias — RemoteAdmins alias&lt;br /&gt;
|-&lt;br /&gt;
| Destination || Single host or alias — WebServers alias&lt;br /&gt;
|-&lt;br /&gt;
| Destination port || 22&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow SSH to web servers from remote admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
From your host machine, test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh training@192.0.2.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 7.3 — Allow Web Access to Public Web Servers ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ HTTP/HTTPS Rule for Web Servers&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol || TCP&lt;br /&gt;
|-&lt;br /&gt;
| Source || any&lt;br /&gt;
|-&lt;br /&gt;
| Destination || Single host or alias — WebServers&lt;br /&gt;
|-&lt;br /&gt;
| Destination port || WebPorts alias&lt;br /&gt;
|-&lt;br /&gt;
| Description || allow web ports to public web servers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save and apply changes.&lt;br /&gt;
&lt;br /&gt;
Now browse to &amp;lt;code&amp;gt;http://192.0.2.4&amp;lt;/code&amp;gt; (server1) and &amp;lt;code&amp;gt;http://192.0.2.5&amp;lt;/code&amp;gt; (server2).&lt;br /&gt;
&lt;br /&gt;
== Exercise 8: Configuring Outbound NAT ==&lt;br /&gt;
&lt;br /&gt;
Outbound NAT defines whether and how the source IP of matching traffic will be translated when it leaves an interface.&lt;br /&gt;
&lt;br /&gt;
=== Step 8.1 — Switch to Manual Outbound NAT ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall → NAT&#039;&#039;&#039;, Outbound tab. Select &#039;&#039;&#039;Manual Outbound NAT&#039;&#039;&#039;, then click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The system auto-populates the outbound NAT ruleset with the rules it was automatically generating previously. The configured manual rules take effect only upon applying changes.&lt;br /&gt;
&lt;br /&gt;
=== Step 8.2 — Clean Up Auto-Generated Rules ===&lt;br /&gt;
&lt;br /&gt;
The auto-generated rules include:&lt;br /&gt;
&lt;br /&gt;
* LAN subnet, DMZ subnet, and loopback &amp;lt;code&amp;gt;127.0.0.0/8&amp;lt;/code&amp;gt;&lt;br /&gt;
* IPv6 rules&lt;br /&gt;
* Static port for UDP port 500 (for non-NAT-T IPsec VPN clients)&lt;br /&gt;
&lt;br /&gt;
Clean up by:&lt;br /&gt;
&lt;br /&gt;
* Deleting the &amp;lt;code&amp;gt;127.0.0.0/8&amp;lt;/code&amp;gt; rule (unusual circumstance)&lt;br /&gt;
* Deleting IPv6 rules (not using IPv6)&lt;br /&gt;
* Deleting UDP port 500 rules (nearly unheard of today)&lt;br /&gt;
* Replacing LAN and DMZ subnets with the summarized &amp;lt;code&amp;gt;172.17.0.0/16&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Edit the &#039;&#039;&#039;LAN to WAN&#039;&#039;&#039; rule:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Consolidated Outbound NAT Rule&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| Source || 172.17.0.0/16&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Translation || Interface address&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Delete all other outbound NAT rules. Your list should have one rule.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; 1:1 NAT entries take precedence over outbound NAT. server1 traffic goes out via &amp;lt;code&amp;gt;192.0.2.4&amp;lt;/code&amp;gt; and server2 via &amp;lt;code&amp;gt;192.0.2.5&amp;lt;/code&amp;gt; regardless of outbound NAT rules.&lt;br /&gt;
&lt;br /&gt;
=== Step 8.3 — Send hq-client Out via Alternate IP ===&lt;br /&gt;
&lt;br /&gt;
Click the top &#039;&#039;&#039;Add&#039;&#039;&#039; button to add the new rule at the top of the list.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Outbound NAT for hq-client&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface || WAN&lt;br /&gt;
|-&lt;br /&gt;
| Source || 172.17.1.100/32&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Translation || 192.0.2.6&lt;br /&gt;
|-&lt;br /&gt;
| Description || hq-client out via .6&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ensure this rule is above the &amp;lt;code&amp;gt;172.17.0.0/16&amp;lt;/code&amp;gt; rule, since the first match wins.&lt;br /&gt;
&lt;br /&gt;
=== Step 8.4 — Static Port for VoIP PBX ===&lt;br /&gt;
&lt;br /&gt;
NAT can break VoIP. If rewriting source ports breaks SIP/RTP, configure static port for the PBX.&lt;br /&gt;
&lt;br /&gt;
Assume a PBX at &amp;lt;code&amp;gt;172.17.1.200&amp;lt;/code&amp;gt;. Click the &#039;&#039;&#039;copy&#039;&#039;&#039; icon next to the hq-client outbound NAT rule, then change:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Outbound NAT for VoIP PBX&lt;br /&gt;
|-&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Source || 172.17.1.200/32&lt;br /&gt;
|-&lt;br /&gt;
| Destination || any&lt;br /&gt;
|-&lt;br /&gt;
| Translation || Address 192.0.2.6, Static port checked&lt;br /&gt;
|-&lt;br /&gt;
| Description || VoIP PBX static port&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ensure this rule is above the &amp;lt;code&amp;gt;172.17.0.0/16&amp;lt;/code&amp;gt; rule.&lt;br /&gt;
&lt;br /&gt;
== Lab Summary ==&lt;br /&gt;
&lt;br /&gt;
In this lab, you learned to:&lt;br /&gt;
&lt;br /&gt;
* Configure IP Alias Virtual IPs on the WAN interface&lt;br /&gt;
* Create Port Forwards (same port, alternate port, restricted source, alternate external IP)&lt;br /&gt;
* Configure 1:1 NAT mappings&lt;br /&gt;
* Add firewall rules to permit traffic through 1:1 NAT&lt;br /&gt;
* Switch from Automatic to Manual Outbound NAT&lt;br /&gt;
* Configure alternate outbound IPs and static port for VoIP&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
&lt;br /&gt;
Proceed to the next training module. Return to the &#039;&#039;&#039;[[Training:_NAT_and_Virtual_IPs|NAT and Virtual IPs — Lecture Slides]]&#039;&#039;&#039; for review.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Source: Netgate FUND001-LIVE-SLIDE-SEG3-NATVIP.pdf / FUND001-LIVE-Lab3-NATandVIPs.pdf&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_NAT_and_Virtual_IPs&amp;diff=229</id>
		<title>Training: NAT and Virtual IPs</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_NAT_and_Virtual_IPs&amp;diff=229"/>
		<updated>2026-04-23T06:58:55Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created from Netgate pfSense training PDF&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #e7f3ff; border-left: 6px solid #2196F3; padding: 16px; margin-bottom: 20px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt;Module Overview:&amp;lt;/strong&amp;gt; This module covers Network Address Translation (NAT) and Virtual IPs (VIPs) in pfSense Plus. You will learn the different types of NAT, how NAT interacts with firewall rules, and best practices for configuring translation in production networks.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Learning Objectives ==&lt;br /&gt;
&lt;br /&gt;
By the end of this module, you will be able to:&lt;br /&gt;
&lt;br /&gt;
* Explain what NAT is and how it modifies IP packet headers&lt;br /&gt;
* Identify common uses for NAT (Internet access, conflicting networks, routing issues)&lt;br /&gt;
* Distinguish between NAT rules and firewall rules&lt;br /&gt;
* Describe Port Forwards, 1:1 NAT, and Outbound NAT&lt;br /&gt;
* Understand NAT Reflection and why it should be avoided&lt;br /&gt;
* Troubleshoot common NAT problems&lt;br /&gt;
&lt;br /&gt;
== What is NAT? ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Network Address Translation (NAT)&#039;&#039;&#039; is the modification of IP packet headers. It involves the replacement of:&lt;br /&gt;
&lt;br /&gt;
* Source and/or destination IP addresses&lt;br /&gt;
* Source and/or destination ports for TCP and UDP&lt;br /&gt;
&lt;br /&gt;
=== Common Uses of NAT ===&lt;br /&gt;
&lt;br /&gt;
* Internet access for private networks&lt;br /&gt;
* Connection of conflicting networks (overlapping IP ranges)&lt;br /&gt;
* Working around routing issues&lt;br /&gt;
&lt;br /&gt;
== NAT and Firewall Rules ==&lt;br /&gt;
&lt;br /&gt;
NAT rules are &#039;&#039;&#039;not&#039;&#039;&#039; firewall rules. NAT rules only define translation. You still need firewall rules to allow traffic to pass.&lt;br /&gt;
&lt;br /&gt;
=== Key Points ===&lt;br /&gt;
&lt;br /&gt;
* NAT rules and firewall rules are matched in a top-down fashion&lt;br /&gt;
* &#039;&#039;&#039;LAN rules&#039;&#039;&#039; are evaluated &#039;&#039;&#039;pre-NAT&#039;&#039;&#039; (using private source IPs)&lt;br /&gt;
* &#039;&#039;&#039;WAN rules&#039;&#039;&#039; are evaluated &#039;&#039;&#039;post-NAT&#039;&#039;&#039; (using private destination IPs)&lt;br /&gt;
* Port forwards — pfSense Plus can automatically add corresponding firewall rules&lt;br /&gt;
&lt;br /&gt;
== Types of NAT ==&lt;br /&gt;
&lt;br /&gt;
=== Port Forwards ===&lt;br /&gt;
&lt;br /&gt;
Port forwards provide traffic redirection. Common use cases include:&lt;br /&gt;
&lt;br /&gt;
* Traditional port forward (e.g., external port to internal server)&lt;br /&gt;
* Transparent HTTP proxy&lt;br /&gt;
* Redirection of SMTP, DNS&lt;br /&gt;
&lt;br /&gt;
=== 1:1 NAT ===&lt;br /&gt;
&lt;br /&gt;
1:1 NAT is a mapping of one internal IP to one external IP. Key characteristics:&lt;br /&gt;
&lt;br /&gt;
* Can also map one internal network to one external network&lt;br /&gt;
* Configured on a per-interface basis&lt;br /&gt;
* Can optionally be limited to specific destinations&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ 1:1 NAT Example&lt;br /&gt;
|-&lt;br /&gt;
! Type !! External IP !! Internal IP&lt;br /&gt;
|-&lt;br /&gt;
| Host || 200.100.1.12 || 192.168.1.99&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Outbound NAT ===&lt;br /&gt;
&lt;br /&gt;
Outbound NAT controls how traffic leaving the firewall is translated.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Automatic outbound&#039;&#039;&#039; — Default behavior; pfSense Plus automatically creates rules&lt;br /&gt;
* &#039;&#039;&#039;Manual outbound&#039;&#039;&#039; — Administrator defines all rules explicitly&lt;br /&gt;
* &#039;&#039;&#039;Hybrid mode&#039;&#039;&#039; — Combines automatic and manual rules&lt;br /&gt;
&lt;br /&gt;
Outbound NAT rule options include:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Static port&#039;&#039;&#039; — Preserve the original source port&lt;br /&gt;
* &#039;&#039;&#039;Pool options&#039;&#039;&#039; — Distribute translation across multiple IPs&lt;br /&gt;
&lt;br /&gt;
== NAT Reflection ==&lt;br /&gt;
&lt;br /&gt;
NAT Reflection allows accessing services via their public IP from inside the network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Best Practice:&#039;&#039;&#039; NAT Reflection should be avoided whenever possible because it:&lt;br /&gt;
&lt;br /&gt;
* Adds unnecessary overhead&lt;br /&gt;
* Loses the original source IP information&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Alternative:&#039;&#039;&#039; Use Split DNS (internal DNS server resolving to private IPs) instead.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting NAT ==&lt;br /&gt;
&lt;br /&gt;
Remember these key troubleshooting steps:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;First match wins&#039;&#039;&#039; — Rules are evaluated top-down&lt;br /&gt;
* Ensure the correct interface is selected&lt;br /&gt;
* Review firewall states (Diagnostics → States)&lt;br /&gt;
* Verify Virtual IP configuration if applicable&lt;br /&gt;
* Use Packet Capture for detailed inspection&lt;br /&gt;
* See the troubleshooting section in the NAT chapter of the pfSense book&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
* NAT rules are &#039;&#039;&#039;not&#039;&#039;&#039; firewall rules&lt;br /&gt;
* Both are still matched in a top-down fashion&lt;br /&gt;
* You still need firewall rules to allow traffic to pass&lt;br /&gt;
* NAT Reflection is suboptimal — use an internal DNS server instead&lt;br /&gt;
* 1:1 NAT can be host-to-host or network-to-network&lt;br /&gt;
* NAT is interface-specific&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
&lt;br /&gt;
Continue to &#039;&#039;&#039;[[Training_Lab_3:_NAT_and_Virtual_IPs|Lab 3: NAT and Virtual IPs]]&#039;&#039;&#039; for hands-on exercises configuring Virtual IPs, Port Forwards, 1:1 NAT, and Outbound NAT.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Source: Netgate FUND001-LIVE-SLIDE-SEG3-NATVIP.pdf / FUND001-LIVE-Lab3-NATandVIPs.pdf&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_2:_Firewall_Rules_and_Aliases&amp;diff=228</id>
		<title>Training Lab 2: Firewall Rules and Aliases</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_2:_Firewall_Rules_and_Aliases&amp;diff=228"/>
		<updated>2026-04-23T06:58:28Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created page with &amp;quot;__NOTOC__  &amp;lt;div style=&amp;quot;background-color:#fff3e6; border:1px solid #cc6600; padding:10px; margin-bottom:15px;&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Lab 2: Interfaces, Firewall Rules, and Aliases&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt; This hands-on lab covers configuring the HQ DMZ interface, building firewall rules, creating aliases, and applying restrictive access policies. All configuration is performed on &amp;#039;&amp;#039;&amp;#039;fw1-HQ&amp;#039;&amp;#039;&amp;#039; at &amp;lt;code&amp;gt;https://172.17.1.1&amp;lt;/code&amp;gt;. &amp;lt;/div&amp;gt;  == Prerequisites ==  * Lab topology from Training_Lab_1:_Initial_Confi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color:#fff3e6; border:1px solid #cc6600; padding:10px; margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Lab 2: Interfaces, Firewall Rules, and Aliases&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
This hands-on lab covers configuring the HQ DMZ interface, building firewall rules, creating aliases, and applying restrictive access policies. All configuration is performed on &#039;&#039;&#039;fw1-HQ&#039;&#039;&#039; at &amp;lt;code&amp;gt;https://172.17.1.1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
* Lab topology from [[Training_Lab_1:_Initial_Configuration|Training Lab 1]] is in place&lt;br /&gt;
* &#039;&#039;&#039;HQ LAN:&#039;&#039;&#039; &amp;lt;code&amp;gt;172.17.1.0/24&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;HQ DMZ:&#039;&#039;&#039; &amp;lt;code&amp;gt;172.17.2.0/24&amp;lt;/code&amp;gt;&lt;br /&gt;
* Access to fw1-HQ web interface and VPN connection&lt;br /&gt;
&lt;br /&gt;
== Lab Overview ==&lt;br /&gt;
&lt;br /&gt;
This lab starts with configuring the DMZ interface at HQ, going through the steps to assign and configure a new interface. This new interface will be used as an example of configuring an additional internal interface treated as a DMZ, with significant restrictions to the other internal networks.&lt;br /&gt;
&lt;br /&gt;
Then we&#039;ll go through use cases and examples for firewall rules and aliases. Some firewall rules come in the context of NAT, which is covered in a later lab.&lt;br /&gt;
&lt;br /&gt;
== Exercise 1: Configure the DMZ Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Review Interface Assignments ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Interfaces &amp;gt; Assign&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The firewall&#039;s interfaces are assigned in order, from &amp;lt;code&amp;gt;vtnet0&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;vtnet4&amp;lt;/code&amp;gt;. Our DMZ interface will be &#039;&#039;&#039;OPT1&#039;&#039;&#039;, which is assigned to &amp;lt;code&amp;gt;vtnet2&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Enable and Configure OPT1 ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Interfaces &amp;gt; OPT1&#039;&#039;&#039; and configure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Enable&lt;br /&gt;
| ✓ Checked&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| DMZ&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Configuration Type&lt;br /&gt;
| Static IPv4&lt;br /&gt;
|-&lt;br /&gt;
| IPv4 Address&lt;br /&gt;
| 172.17.2.1/24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Save and Apply Changes.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After saving, OPT1 is still the underlying identifier in &amp;lt;code&amp;gt;config.xml&amp;lt;/code&amp;gt;, but the interface is displayed as &#039;&#039;&#039;DMZ&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Exercise 2: Test Connectivity to DMZ ==&lt;br /&gt;
&lt;br /&gt;
=== Ping the DMZ Gateway ===&lt;br /&gt;
&lt;br /&gt;
From the HQ-Client VM:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@hq-client:~$ ping 172.17.2.1&lt;br /&gt;
PING 172.17.2.1 (172.17.2.1) 56(84) bytes of data.&lt;br /&gt;
64 bytes from 172.17.2.1: icmp_seq=1 ttl=64 time=0.298 ms&lt;br /&gt;
64 bytes from 172.17.2.1: icmp_seq=2 ttl=64 time=0.979 ms&lt;br /&gt;
64 bytes from 172.17.2.1: icmp_seq=3 ttl=64 time=1.27 ms&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ping server1 from HQ-Client ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@hq-client:~$ ping -c 5 172.17.2.10&lt;br /&gt;
PING 172.17.2.10 (172.17.2.10) 56(84) bytes of data.&lt;br /&gt;
64 bytes from 172.17.2.10: icmp_seq=1 ttl=63 time=0.711 ms&lt;br /&gt;
64 bytes from 172.17.2.10: icmp_seq=2 ttl=63 time=1.75 ms&lt;br /&gt;
...&lt;br /&gt;
5 packets transmitted, 5 received, 0% packet loss&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This ping traverses two virtual networks, so latency is roughly doubled. Steady replies indicate good connectivity.&lt;br /&gt;
&lt;br /&gt;
== Exercise 3: Connectivity from DMZ Network ==&lt;br /&gt;
&lt;br /&gt;
=== Verify Default Block Behavior ===&lt;br /&gt;
&lt;br /&gt;
Newly-added interfaces have &#039;&#039;&#039;no firewall rules by default&#039;&#039;&#039;. All traffic initiated on that interface is blocked.&lt;br /&gt;
&lt;br /&gt;
Log in to server1 via SSH from HQ-client:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@hq-client:~$ ssh training@172.17.2.10&lt;br /&gt;
Password for training@server1: password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From server1, attempt to ping:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@server1:~ % ping -c 5 172.17.2.1&lt;br /&gt;
PING 172.17.2.1 (172.17.2.1): 56 data bytes&lt;br /&gt;
--- 172.17.2.1 ping statistics ---&lt;br /&gt;
5 packets transmitted, 0 packets received, 100.0% packet loss&lt;br /&gt;
&lt;br /&gt;
training@server1:~ % ping google.com&lt;br /&gt;
ping: cannot resolve google.com: Host name lookup failure&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting: Check ARP Cache ===&lt;br /&gt;
&lt;br /&gt;
Check the ARP cache to confirm Layer 2 connectivity:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@server1:~ % arp -an&lt;br /&gt;
? (172.17.2.10) at 08:00:27:ec:c0:6b on em0 permanent [ethernet]&lt;br /&gt;
? (172.17.2.1) at 08:00:27:59:b4:35 on em0 expires in 139 seconds [ethernet]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A valid MAC address for the gateway confirms the server is on the correct network segment. An &#039;&#039;&#039;incomplete&#039;&#039;&#039; entry indicates a Layer 2 issue.&lt;br /&gt;
&lt;br /&gt;
=== Check Firewall Logs ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Status &amp;gt; System Logs &amp;gt; Firewall&#039;&#039;&#039; on fw1-HQ to see blocked traffic.&lt;br /&gt;
&lt;br /&gt;
=== Add Temporary Allow-All Rule ===&lt;br /&gt;
&lt;br /&gt;
On &#039;&#039;&#039;Firewall &amp;gt; Rules &amp;gt; DMZ&#039;&#039;&#039;, add a temporary rule:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action&lt;br /&gt;
| Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface&lt;br /&gt;
| DMZ&lt;br /&gt;
|-&lt;br /&gt;
| Protocol&lt;br /&gt;
| any&lt;br /&gt;
|-&lt;br /&gt;
| Source&lt;br /&gt;
| any&lt;br /&gt;
|-&lt;br /&gt;
| Destination&lt;br /&gt;
| any&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Save and Apply Changes.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verify connectivity from server1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@server1:~ % ping -c 3 172.17.2.1&lt;br /&gt;
training@server1:~ % ping -c 3 google.com&lt;br /&gt;
training@server1:~ % ping -c 3 172.17.1.100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three should succeed with the allow-all rule in place.&lt;br /&gt;
&lt;br /&gt;
== Exercise 4: Create Aliases ==&lt;br /&gt;
&lt;br /&gt;
Aliases ease management by grouping IPs, networks, or ports.&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Firewall &amp;gt; Aliases&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Alias: PrivateNetworks ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| PrivateNetworks&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| All RFC1918 private IP space&lt;br /&gt;
|-&lt;br /&gt;
| Type&lt;br /&gt;
| Network&lt;br /&gt;
|-&lt;br /&gt;
| Members&lt;br /&gt;
| 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Alias: server1 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| server1&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| server1.example.com&lt;br /&gt;
|-&lt;br /&gt;
| Type&lt;br /&gt;
| Host&lt;br /&gt;
|-&lt;br /&gt;
| Member&lt;br /&gt;
| 172.17.2.10&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Alias: server2 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| server2&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| server2.example.com&lt;br /&gt;
|-&lt;br /&gt;
| Type&lt;br /&gt;
| Host&lt;br /&gt;
|-&lt;br /&gt;
| Member&lt;br /&gt;
| 172.17.2.20&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Alias: DNSservers ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| DNSservers&lt;br /&gt;
|-&lt;br /&gt;
| Type&lt;br /&gt;
| Host&lt;br /&gt;
|-&lt;br /&gt;
| Members&lt;br /&gt;
| server1, server2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Alias: SMTPservers ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| SMTPservers&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| authorized outbound SMTP servers&lt;br /&gt;
|-&lt;br /&gt;
| Type&lt;br /&gt;
| Host&lt;br /&gt;
|-&lt;br /&gt;
| Members&lt;br /&gt;
| server1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Alias: RemoteAdmin ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| RemoteAdmin&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| IPs authorized for remote management&lt;br /&gt;
|-&lt;br /&gt;
| Type&lt;br /&gt;
| Host&lt;br /&gt;
|-&lt;br /&gt;
| Members&lt;br /&gt;
| 192.0.2.100 (student&#039;s system)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Alias: WebServers ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| WebServers&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| publicly-reachable web servers&lt;br /&gt;
|-&lt;br /&gt;
| Type&lt;br /&gt;
| Host&lt;br /&gt;
|-&lt;br /&gt;
| Members&lt;br /&gt;
| server1, server2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Alias: WebPorts ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| WebPorts&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| allowed ports to public web servers&lt;br /&gt;
|-&lt;br /&gt;
| Type&lt;br /&gt;
| Ports&lt;br /&gt;
|-&lt;br /&gt;
| Members&lt;br /&gt;
| 80, 443&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Save each alias, then Apply Changes.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Exercise 5: Allow Remote Firewall Administration ==&lt;br /&gt;
&lt;br /&gt;
Add a rule on &#039;&#039;&#039;Firewall &amp;gt; Rules &amp;gt; WAN&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Interface&lt;br /&gt;
| WAN&lt;br /&gt;
|-&lt;br /&gt;
| Protocol&lt;br /&gt;
| any&lt;br /&gt;
|-&lt;br /&gt;
| Source&lt;br /&gt;
| Single host or alias — RemoteAdmin&lt;br /&gt;
|-&lt;br /&gt;
| Destination&lt;br /&gt;
| WAN address&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| allow all from remote admin IPs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Save and Apply Changes.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verify from your host:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ ping 192.0.2.2&lt;br /&gt;
$ curl -I https://192.0.2.2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exercise 6: Configure Restrictive DMZ Rules ==&lt;br /&gt;
&lt;br /&gt;
Remove the temporary allow-all rule (or ensure it is at the top, to be deleted later). Then add the following rules in order using the &#039;&#039;&#039;Add&#039;&#039;&#039; button (add to bottom):&lt;br /&gt;
&lt;br /&gt;
=== Rule 1: Allow Ping to Firewall DMZ IP ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action&lt;br /&gt;
| Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface&lt;br /&gt;
| DMZ&lt;br /&gt;
|-&lt;br /&gt;
| Protocol&lt;br /&gt;
| ICMP&lt;br /&gt;
|-&lt;br /&gt;
| ICMP Type&lt;br /&gt;
| Echo request&lt;br /&gt;
|-&lt;br /&gt;
| Source&lt;br /&gt;
| DMZ net&lt;br /&gt;
|-&lt;br /&gt;
| Destination&lt;br /&gt;
| DMZ address&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| Allow ping to firewall&#039;s DMZ IP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Rule 2: Allow DNS to DMZ IP ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action&lt;br /&gt;
| Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface&lt;br /&gt;
| DMZ&lt;br /&gt;
|-&lt;br /&gt;
| Protocol&lt;br /&gt;
| TCP/UDP&lt;br /&gt;
|-&lt;br /&gt;
| Source&lt;br /&gt;
| DMZ net&lt;br /&gt;
|-&lt;br /&gt;
| Destination&lt;br /&gt;
| DMZ address&lt;br /&gt;
|-&lt;br /&gt;
| Destination Port&lt;br /&gt;
| DNS (53)&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| Allow DNS lookups to DNS Resolver&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Rule 3: Reject All Else to Private Networks ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action&lt;br /&gt;
| Reject&lt;br /&gt;
|-&lt;br /&gt;
| Interface&lt;br /&gt;
| DMZ&lt;br /&gt;
|-&lt;br /&gt;
| Protocol&lt;br /&gt;
| any&lt;br /&gt;
|-&lt;br /&gt;
| Source&lt;br /&gt;
| any&lt;br /&gt;
|-&lt;br /&gt;
| Destination&lt;br /&gt;
| Single host or alias — PrivateNetworks&lt;br /&gt;
|-&lt;br /&gt;
| Log&lt;br /&gt;
| ✓ Checked&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| Reject all else from DMZ to private networks&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This prevents DMZ hosts from reaching any other internal services and logs blocked attempts.&lt;br /&gt;
&lt;br /&gt;
=== Rule 4: Allow DNS Outbound to Internet ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action&lt;br /&gt;
| Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface&lt;br /&gt;
| DMZ&lt;br /&gt;
|-&lt;br /&gt;
| Protocol&lt;br /&gt;
| TCP/UDP&lt;br /&gt;
|-&lt;br /&gt;
| Source&lt;br /&gt;
| Single host or alias — DNSservers&lt;br /&gt;
|-&lt;br /&gt;
| Destination&lt;br /&gt;
| any&lt;br /&gt;
|-&lt;br /&gt;
| Destination Port&lt;br /&gt;
| DNS (53)&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| Allow recursive queries from DNS servers to Internet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Rule 5: Allow SMTP Outbound to Internet ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action&lt;br /&gt;
| Pass&lt;br /&gt;
|-&lt;br /&gt;
| Interface&lt;br /&gt;
| DMZ&lt;br /&gt;
|-&lt;br /&gt;
| Protocol&lt;br /&gt;
| TCP&lt;br /&gt;
|-&lt;br /&gt;
| Source&lt;br /&gt;
| Single host or alias — SMTPservers&lt;br /&gt;
|-&lt;br /&gt;
| Destination&lt;br /&gt;
| any&lt;br /&gt;
|-&lt;br /&gt;
| Destination Port&lt;br /&gt;
| SMTP (25)&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| Allow SMTP servers to send to Internet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Rule 6: Allow HTTP Outbound for Management (Disabled) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Action&lt;br /&gt;
| Pass&lt;br /&gt;
|-&lt;br /&gt;
| Disabled&lt;br /&gt;
| ✓ Checked&lt;br /&gt;
|-&lt;br /&gt;
| Interface&lt;br /&gt;
| DMZ&lt;br /&gt;
|-&lt;br /&gt;
| Protocol&lt;br /&gt;
| TCP&lt;br /&gt;
|-&lt;br /&gt;
| Source&lt;br /&gt;
| DMZ net&lt;br /&gt;
|-&lt;br /&gt;
| Destination&lt;br /&gt;
| any&lt;br /&gt;
|-&lt;br /&gt;
| Destination Port&lt;br /&gt;
| HTTP (80)&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| Management — temp allow HTTP outbound from servers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This rule is disabled by default and should only be enabled during updates.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Save and Apply Changes after each rule.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Exercise 7: Verify Restrictive Ruleset ==&lt;br /&gt;
&lt;br /&gt;
=== Review Rule Order ===&lt;br /&gt;
&lt;br /&gt;
Ensure the temporary allow-all rule is at the top. With it at the top, all traffic matches it first and the restrictive rules are ineffective.&lt;br /&gt;
&lt;br /&gt;
From server1, start a constant ping to HQ-client:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
training@server1:~ % ping 172.17.1.100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replies confirm the allow-all rule is passing traffic.&lt;br /&gt;
&lt;br /&gt;
=== Delete Allow-All Rule ===&lt;br /&gt;
&lt;br /&gt;
Delete the temporary allow-all rule and &#039;&#039;&#039;Apply Changes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The restrictive ruleset is now enforced for all &#039;&#039;&#039;new&#039;&#039;&#039; connections. The running ping is still permitted because the firewall is stateful — already-permitted connections are never re-evaluated.&lt;br /&gt;
&lt;br /&gt;
=== Kill the Ping State ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Diagnostics &amp;gt; States&#039;&#039;&#039;. Filter for &amp;lt;code&amp;gt;172.17.2.10:&amp;lt;/code&amp;gt; (note the colon to avoid matching similar IPs). Click the &#039;&#039;&#039;✕&#039;&#039;&#039; symbol next to the ping state to delete it.&lt;br /&gt;
&lt;br /&gt;
The ping stops immediately.&lt;br /&gt;
&lt;br /&gt;
=== Check Firewall Logs ===&lt;br /&gt;
&lt;br /&gt;
Browse to &#039;&#039;&#039;Status &amp;gt; System Logs &amp;gt; Firewall&#039;&#039;&#039;. Log entries show the blocked traffic.&lt;br /&gt;
&lt;br /&gt;
Click the red &#039;&#039;&#039;X&#039;&#039;&#039; in the Action column on a log entry to see which rule blocked the connection. User-defined rules show &amp;lt;code&amp;gt;USER_RULE&amp;lt;/code&amp;gt; with the configured description.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting Reference ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Symptom&lt;br /&gt;
! Likely Cause&lt;br /&gt;
! Resolution&lt;br /&gt;
|-&lt;br /&gt;
| Cannot ping gateway from DMZ host&lt;br /&gt;
| No firewall rules on DMZ interface&lt;br /&gt;
| Add pass rule or verify existing rules&lt;br /&gt;
|-&lt;br /&gt;
| Cannot resolve DNS from DMZ&lt;br /&gt;
| DNS port blocked; no DNS rule&lt;br /&gt;
| Add TCP/UDP pass rule to DMZ address port 53&lt;br /&gt;
|-&lt;br /&gt;
| Can reach Internet but not HQ LAN&lt;br /&gt;
| Reject rule to PrivateNetworks is working&lt;br /&gt;
| Verify rule order and alias contents&lt;br /&gt;
|-&lt;br /&gt;
| Ping stops after deleting allow-all rule&lt;br /&gt;
| Stateful firewall; existing state was killed&lt;br /&gt;
| Expected behavior — new connections follow current rules&lt;br /&gt;
|-&lt;br /&gt;
| Cannot SSH to server1&lt;br /&gt;
| Layer 2 / ARP issue or VPN problem&lt;br /&gt;
| Check &amp;lt;code&amp;gt;arp -an&amp;lt;/code&amp;gt; on server1; verify MAC address&lt;br /&gt;
|-&lt;br /&gt;
| Firewall web UI unreachable from WAN&lt;br /&gt;
| No WAN allow rule for remote admin&lt;br /&gt;
| Add WAN rule with RemoteAdmin alias as source&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IP Addressing Quick Reference ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Host / Network&lt;br /&gt;
! IP Address / Range&lt;br /&gt;
|-&lt;br /&gt;
| fw1-HQ LAN&lt;br /&gt;
| 172.17.1.1/24&lt;br /&gt;
|-&lt;br /&gt;
| fw1-HQ DMZ&lt;br /&gt;
| 172.17.2.1/24&lt;br /&gt;
|-&lt;br /&gt;
| fw1-HQ WAN&lt;br /&gt;
| 192.0.2.2&lt;br /&gt;
|-&lt;br /&gt;
| HQ-Client&lt;br /&gt;
| 172.17.1.100&lt;br /&gt;
|-&lt;br /&gt;
| server1&lt;br /&gt;
| 172.17.2.10&lt;br /&gt;
|-&lt;br /&gt;
| server2&lt;br /&gt;
| 172.17.2.20&lt;br /&gt;
|-&lt;br /&gt;
| RemoteAdmin&lt;br /&gt;
| 192.0.2.100&lt;br /&gt;
|-&lt;br /&gt;
| HQ LAN Network&lt;br /&gt;
| 172.17.1.0/24&lt;br /&gt;
|-&lt;br /&gt;
| HQ DMZ Network&lt;br /&gt;
| 172.17.2.0/24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lab Completion Checklist ==&lt;br /&gt;
&lt;br /&gt;
* [ ] DMZ interface enabled and configured (172.17.2.1/24)&lt;br /&gt;
* [ ] Connectivity tested from HQ-Client to DMZ&lt;br /&gt;
* [ ] Default block behavior verified from DMZ&lt;br /&gt;
* [ ] Aliases created (PrivateNetworks, DNSservers, SMTPservers, RemoteAdmin, WebServers, WebPorts, server1, server2)&lt;br /&gt;
* [ ] Remote admin rule added on WAN&lt;br /&gt;
* [ ] Restrictive DMZ rules configured and applied&lt;br /&gt;
* [ ] Stateful behavior demonstrated (ping continues after rule change, stops after state kill)&lt;br /&gt;
* [ ] Firewall logs reviewed and interpreted&lt;br /&gt;
&lt;br /&gt;
This concludes Lab 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Previous Module:&#039;&#039;&#039; [[Training:_Interfaces_and_Firewall_Rules|Section 2 — Interfaces and Firewall Rules]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Source: Netgate FUND001-LIVE-Lab2-Rules.pdf&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_Interfaces_and_Firewall_Rules&amp;diff=227</id>
		<title>Training: Interfaces and Firewall Rules</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_Interfaces_and_Firewall_Rules&amp;diff=227"/>
		<updated>2026-04-23T06:58:28Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created page with &amp;quot;__NOTOC__  &amp;lt;div style=&amp;quot;background-color:#e6f3ff; border:1px solid #0066cc; padding:10px; margin-bottom:15px;&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Module: FUND001-LIVE Section 2 — Interfaces, VIPs, and Firewall Rules&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt; This training module covers pfSense interface configuration, Virtual IP types, firewall rules, aliases, and best practices for rule management. &amp;lt;/div&amp;gt;  == Learning Objectives ==  By the end of this module, you will be able to:  * Understand OS interface names versus pfSense interfa...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color:#e6f3ff; border:1px solid #0066cc; padding:10px; margin-bottom:15px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Module: FUND001-LIVE Section 2 — Interfaces, VIPs, and Firewall Rules&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
This training module covers pfSense interface configuration, Virtual IP types, firewall rules, aliases, and best practices for rule management.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Learning Objectives ==&lt;br /&gt;
&lt;br /&gt;
By the end of this module, you will be able to:&lt;br /&gt;
&lt;br /&gt;
* Understand OS interface names versus pfSense interface identifiers&lt;br /&gt;
* Configure and manage interfaces in pfSense&lt;br /&gt;
* Identify and apply appropriate Virtual IP (VIP) types&lt;br /&gt;
* Create and manage firewall rules with proper ordering&lt;br /&gt;
* Use aliases to simplify and streamline rulesets&lt;br /&gt;
* Apply firewall best practices and troubleshooting techniques&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
=== OS Interface Names vs. Interface Identifiers ===&lt;br /&gt;
&lt;br /&gt;
In pfSense, network interfaces have two naming conventions:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;OS Interface Names&#039;&#039;&#039; — Physical or virtual NIC names assigned by the operating system (e.g., &amp;lt;code&amp;gt;igb0&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;re1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ixl2&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &#039;&#039;&#039;Interface Identifiers&#039;&#039;&#039; — User-friendly labels assigned within pfSense (e.g., &amp;lt;code&amp;gt;LAN&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WAN&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OPT1&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Key tasks:&lt;br /&gt;
* Interface Assignments — mapping OS names to pfSense identifiers&lt;br /&gt;
* Configuring Interfaces — setting IP addresses, enabling/disabling, and renaming&lt;br /&gt;
&lt;br /&gt;
== Virtual IPs (VIPs) ==&lt;br /&gt;
&lt;br /&gt;
Virtual IPs allow multiple IP addresses to be assigned to a single interface.&lt;br /&gt;
&lt;br /&gt;
=== VIP Types ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! VIP Type&lt;br /&gt;
! MAC Address Binding&lt;br /&gt;
! NAT Service&lt;br /&gt;
! ARP&lt;br /&gt;
! HA&lt;br /&gt;
! Ping&lt;br /&gt;
! Single/Range&lt;br /&gt;
|-&lt;br /&gt;
| IP Alias&lt;br /&gt;
| Parent NIC&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Single&lt;br /&gt;
|-&lt;br /&gt;
| CARP&lt;br /&gt;
| Shared vMAC&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Single&lt;br /&gt;
|-&lt;br /&gt;
| Proxy ARP&lt;br /&gt;
| Parent NIC&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Either&lt;br /&gt;
|-&lt;br /&gt;
| Other&lt;br /&gt;
| N/A&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Either&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IP Alias&#039;&#039;&#039; — Most common type; binds additional IPs to the parent NIC&lt;br /&gt;
* &#039;&#039;&#039;CARP&#039;&#039;&#039; — Used for high availability; shares a virtual MAC address between redundant firewalls&lt;br /&gt;
* &#039;&#039;&#039;Proxy ARP&#039;&#039;&#039; — Responds to ARP requests on behalf of another IP; no service binding&lt;br /&gt;
* &#039;&#039;&#039;Other&#039;&#039;&#039; — For miscellaneous purposes such as 1:1 NAT without ARP&lt;br /&gt;
&lt;br /&gt;
== Firewall Rules ==&lt;br /&gt;
&lt;br /&gt;
=== Core Concepts ===&lt;br /&gt;
&lt;br /&gt;
* Rules apply &#039;&#039;&#039;inbound&#039;&#039;&#039; on the interface where traffic is sourced&lt;br /&gt;
* &#039;&#039;&#039;First match wins&#039;&#039;&#039; — all subsequent rules are ignored for matching traffic&lt;br /&gt;
* &#039;&#039;&#039;Stateful filtering&#039;&#039;&#039; — pfSense tracks connection states automatically&lt;br /&gt;
* Actions: &#039;&#039;&#039;Pass&#039;&#039;&#039;, &#039;&#039;&#039;Block&#039;&#039;&#039;, and &#039;&#039;&#039;Reject&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Default Rules ===&lt;br /&gt;
&lt;br /&gt;
The following default rules are present on a new installation:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Block private networks&#039;&#039;&#039; — Blocks RFC 1918 traffic on WAN&lt;br /&gt;
* &#039;&#039;&#039;Block bogon networks&#039;&#039;&#039; — Blocks unassigned/reserved IP space&lt;br /&gt;
* &#039;&#039;&#039;Anti-lockout rule&#039;&#039;&#039; — Prevents administrators from locking themselves out&lt;br /&gt;
* &#039;&#039;&#039;Default LAN Allow rule&#039;&#039;&#039; — Permits all outbound traffic from LAN&lt;br /&gt;
&lt;br /&gt;
=== Rule Evaluation Order ===&lt;br /&gt;
&lt;br /&gt;
# Floating Rules&lt;br /&gt;
# Interface Group Rules&lt;br /&gt;
# Single Interface Rules&lt;br /&gt;
&lt;br /&gt;
=== Floating Rules ===&lt;br /&gt;
&lt;br /&gt;
* Can apply to &#039;&#039;&#039;all interfaces&#039;&#039;&#039;&lt;br /&gt;
* Checked &#039;&#039;&#039;first&#039;&#039;&#039; in evaluation order&lt;br /&gt;
* Extra &#039;&#039;&#039;&amp;quot;match&amp;quot;&#039;&#039;&#039; action available&lt;br /&gt;
* Can set traffic attributes (limiters, queues, etc.)&lt;br /&gt;
* &#039;&#039;&#039;Not meant for regular access rules&#039;&#039;&#039; — primarily for traffic-shaping and advanced filtering&lt;br /&gt;
&lt;br /&gt;
=== Interface Groups ===&lt;br /&gt;
&lt;br /&gt;
* Association of multiple interfaces&lt;br /&gt;
* &#039;&#039;&#039;Shared firewall ruleset&#039;&#039;&#039; across grouped interfaces&lt;br /&gt;
* Eliminates need to duplicate rules between interfaces&lt;br /&gt;
&lt;br /&gt;
=== Advanced Settings ===&lt;br /&gt;
&lt;br /&gt;
Firewall rules support numerous advanced options:&lt;br /&gt;
&lt;br /&gt;
* Source OS (TCP only)&lt;br /&gt;
* Diffserv Code Point (DSCP)&lt;br /&gt;
* State type&lt;br /&gt;
* TCP flags&lt;br /&gt;
* No XMLRPC Sync&lt;br /&gt;
* 802.1p&lt;br /&gt;
* Schedule&lt;br /&gt;
* Gateway&lt;br /&gt;
* Limiters (In/Out)&lt;br /&gt;
* ACK queue / Queue&lt;br /&gt;
&lt;br /&gt;
== Aliases ==&lt;br /&gt;
&lt;br /&gt;
Aliases simplify firewall rule management by grouping IPs, networks, hostnames, or ports under a single name.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
* Ease management&lt;br /&gt;
* Faster, less error-prone updates&lt;br /&gt;
* Shorter, more manageable rulesets&lt;br /&gt;
&lt;br /&gt;
=== Configuration Options ===&lt;br /&gt;
&lt;br /&gt;
* Statically configured&lt;br /&gt;
* URL — one-time import, suitable for small lists&lt;br /&gt;
* URL table — configurable update frequency, supports large and small lists&lt;br /&gt;
* Nesting of aliases (aliases within aliases)&lt;br /&gt;
* Bulk import&lt;br /&gt;
&lt;br /&gt;
== Best Practices ==&lt;br /&gt;
&lt;br /&gt;
* Follow &#039;&#039;&#039;default deny philosophy&#039;&#039;&#039; — allow only what is required, block all else&lt;br /&gt;
* Keep rulesets &#039;&#039;&#039;short and clean&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Periodic review&#039;&#039;&#039; of rules (recommended: quarterly)&lt;br /&gt;
* Remember rules apply on the &#039;&#039;&#039;interface where traffic is sourced&#039;&#039;&#039;&lt;br /&gt;
* Use &#039;&#039;&#039;aliases&#039;&#039;&#039; extensively in your rules&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
When diagnosing firewall issues:&lt;br /&gt;
&lt;br /&gt;
* Remember: &#039;&#039;&#039;first match wins&#039;&#039;&#039;&lt;br /&gt;
* Verify rules apply on the correct interface&lt;br /&gt;
* &#039;&#039;&#039;Enable logging&#039;&#039;&#039; on suspect rules&lt;br /&gt;
* Check &#039;&#039;&#039;states&#039;&#039;&#039; (Diagnostics &amp;gt; States)&lt;br /&gt;
* Review &#039;&#039;&#039;System Logs &amp;gt; Firewall&#039;&#039;&#039; for blocked traffic&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key Takeaway&lt;br /&gt;
! Details&lt;br /&gt;
|-&lt;br /&gt;
| VIP Selection&lt;br /&gt;
| Use appropriate VIP types (IP Alias, CARP, Proxy ARP) based on needs&lt;br /&gt;
|-&lt;br /&gt;
| Rule Ordering&lt;br /&gt;
| Evaluation order: Floating → Interface Group → Single Interface&lt;br /&gt;
|-&lt;br /&gt;
| Aliases&lt;br /&gt;
| Use aliases to keep rulesets manageable and reduce errors&lt;br /&gt;
|-&lt;br /&gt;
| Review Schedule&lt;br /&gt;
| Check rules quarterly for accuracy and relevance&lt;br /&gt;
|-&lt;br /&gt;
| Interface Awareness&lt;br /&gt;
| Rules apply on the interface where traffic is sourced&lt;br /&gt;
|-&lt;br /&gt;
| Floating Rules&lt;br /&gt;
| Primarily for traffic-shaping, not regular access control&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This concludes Section 2.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Next Module:&#039;&#039;&#039; [[Training_Lab_2:_Firewall_Rules_and_Aliases|Lab 2 — Firewall Rules and Aliases]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Source: Netgate FUND001-LIVE-SLIDE-SEG2-RULES.pdf&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training_Lab_1:_Introduction_and_Backup_Restore&amp;diff=226</id>
		<title>Training Lab 1: Introduction and Backup Restore</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training_Lab_1:_Introduction_and_Backup_Restore&amp;diff=226"/>
		<updated>2026-04-23T06:52:40Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Convert FUND001 Lab1 to wiki training lab&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#e8f5e9; border:1px solid #a5d6a7; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Hands-On Lab: Phase 1, Day 2&#039;&#039;&#039; — Lab Environment Introduction, Initial Configuration, Backup and Restore. Based on Netgate FUND001-LIVE-Lab1-Intro.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Learning Objectives ==&lt;br /&gt;
By the end of this lab, you will be able to:&lt;br /&gt;
* Navigate the virtual lab environment and understand its topology&lt;br /&gt;
* Complete the pfSense setup wizard&lt;br /&gt;
* Verify basic connectivity through the firewall&lt;br /&gt;
* Create manual configuration backups&lt;br /&gt;
* Enable and configure AutoConfigBackup&lt;br /&gt;
* Restore a previous configuration from web interface and console&lt;br /&gt;
&lt;br /&gt;
== Lab Environment Overview ==&lt;br /&gt;
This lab uses a simulated corporate network with headquarters (HQ) and one branch office.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Network Topology:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;4 firewalls&#039;&#039;&#039; — fw1-HQ, fw2-HQ (HA pair), fw1-branch, lab-internet-router&lt;br /&gt;
* &#039;&#039;&#039;2 desktops&#039;&#039;&#039; — HQ-client, Branch-client&lt;br /&gt;
* &#039;&#039;&#039;2 servers&#039;&#039;&#039; — server1, server2 (DMZ)&lt;br /&gt;
* &#039;&#039;&#039;1 simulated Internet host&#039;&#039;&#039; — RemoteHost&lt;br /&gt;
* &#039;&#039;&#039;8 total networks&#039;&#039;&#039; — WAN, LAN, DMZ, sync, remote access, branch LAN, etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lab access:&#039;&#039;&#039;&lt;br /&gt;
In the Netgate original lab, desktops are accessed via NoVNC at http://100.64.0.100/remote. In Comfac&#039;s virtual lab, you will access your student sandbox through the NoVNC portal.&lt;br /&gt;
&lt;br /&gt;
== IP Addressing Scheme ==&lt;br /&gt;
&#039;&#039;&#039;Public/&amp;quot;Internet&amp;quot; IPs (RFC 5737 documentation ranges):&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Subnet !! Assignment&lt;br /&gt;
|-&lt;br /&gt;
| 192.0.2.0/24 || HQ WAN&lt;br /&gt;
|-&lt;br /&gt;
| 198.51.100.0/24 || HQ WAN2&lt;br /&gt;
|-&lt;br /&gt;
| 203.0.113.0/24 || Branch WAN&lt;br /&gt;
|-&lt;br /&gt;
| 100.64.0.0/24 || Remote Internet (CGNAT range)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Private Internal IPs (RFC 1918):&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Subnet !! Assignment&lt;br /&gt;
|-&lt;br /&gt;
| 172.17.1.0/24 || HQ LAN&lt;br /&gt;
|-&lt;br /&gt;
| 172.17.2.0/24 || HQ DMZ&lt;br /&gt;
|-&lt;br /&gt;
| 172.17.3.0/24 || HQ Sync (HA)&lt;br /&gt;
|-&lt;br /&gt;
| 172.17.4.0/24 || HQ Remote Access OpenVPN&lt;br /&gt;
|-&lt;br /&gt;
| 172.17.5.0/24 || HQ Remote Access IPsec&lt;br /&gt;
|-&lt;br /&gt;
| 172.17.6.0/24 || OpenVPN Site-to-Site tunnel&lt;br /&gt;
|-&lt;br /&gt;
| 172.18.1.0/24 || Branch LAN&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Why use obscure subnets?&#039;&#039;&#039; Using 172.17.x.x instead of common 192.168.1.x minimizes VPN conflicts when remote users connect from home networks.&lt;br /&gt;
&lt;br /&gt;
== Firewall VM Details ==&lt;br /&gt;
&#039;&#039;&#039;Default credentials for all firewalls:&#039;&#039;&#039;&lt;br /&gt;
* Username: &#039;&#039;&#039;admin&#039;&#039;&#039;&lt;br /&gt;
* Password: &#039;&#039;&#039;netgate&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== fw1-HQ (Primary HQ Firewall) ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Interface !! Assignment !! Initial IP !! HA IP (later)&lt;br /&gt;
|-&lt;br /&gt;
| vtnet0 || WAN || 192.0.2.2 || no change&lt;br /&gt;
|-&lt;br /&gt;
| vtnet1 || LAN || 172.17.1.1 || 172.17.1.2&lt;br /&gt;
|-&lt;br /&gt;
| vtnet2 || DMZ || 172.17.2.1 || 172.17.2.2&lt;br /&gt;
|-&lt;br /&gt;
| vtnet3 || WAN2 || 198.51.100.2 || no change&lt;br /&gt;
|-&lt;br /&gt;
| vtnet4 || Sync || 172.17.3.2 || no change&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== fw2-HQ (Secondary HQ Firewall) ===&lt;br /&gt;
Initially inactive; configured in Advanced/HA lab later.&lt;br /&gt;
* WAN: 192.0.2.3&lt;br /&gt;
* LAN: 172.17.1.3&lt;br /&gt;
* DMZ: 172.17.2.3&lt;br /&gt;
* WAN2: 198.51.100.3&lt;br /&gt;
* Sync: 172.17.3.3&lt;br /&gt;
&lt;br /&gt;
=== fw1-branch (Branch Office Firewall) ===&lt;br /&gt;
* WAN: 203.0.113.10&lt;br /&gt;
* LAN: 172.18.1.1&lt;br /&gt;
&lt;br /&gt;
=== lab-internet-router (Simulated ISP) ===&lt;br /&gt;
Represents 4 ISP routers + Internet. Pre-configured; no lab changes needed.&lt;br /&gt;
* HQ-WAN1: 192.0.2.1&lt;br /&gt;
* HQ-WAN2: 198.51.100.1&lt;br /&gt;
* Branch-WAN: 203.0.113.1&lt;br /&gt;
* Remote Internet: 100.64.0.1&lt;br /&gt;
&lt;br /&gt;
== Client &amp;amp; Server VMs ==&lt;br /&gt;
&#039;&#039;&#039;HQ-client (Xubuntu Linux desktop):&#039;&#039;&#039;&lt;br /&gt;
* IP: 172.17.1.100&lt;br /&gt;
* Credentials: training / password&lt;br /&gt;
* Purpose: Primary management workstation&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Branch-client (Xubuntu Linux desktop):&#039;&#039;&#039;&lt;br /&gt;
* IP: 172.18.1.100&lt;br /&gt;
* Credentials: training / password&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet host / RemoteHost (Xubuntu):&#039;&#039;&#039;&lt;br /&gt;
* IP: 100.64.0.50&lt;br /&gt;
* Credentials: training / password&lt;br /&gt;
* Purpose: Simulated external client + web server for testing&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;server1 &amp;amp; server2 (FreeBSD):&#039;&#039;&#039;&lt;br /&gt;
* server1: 172.17.2.10&lt;br /&gt;
* server2: 172.17.2.20&lt;br /&gt;
* Credentials: training / password (root: password)&lt;br /&gt;
* Pre-configured with nginx/PHP and BIND DNS&lt;br /&gt;
&lt;br /&gt;
== Exercise 1: Initial Setup Wizard ==&lt;br /&gt;
&#039;&#039;&#039;Prerequisites:&#039;&#039;&#039; Your student environment should have fw1-HQ and HQ-client running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps:&#039;&#039;&#039;&lt;br /&gt;
# From HQ-client, open browser and navigate to https://172.17.1.1&lt;br /&gt;
# Accept the self-signed certificate warning&lt;br /&gt;
# Log in with admin / netgate&lt;br /&gt;
# The setup wizard will launch automatically&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wizard configuration:&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;General Information&#039;&#039;&#039; — Leave defaults (hostname: fw1-hq.example.com, DNS: lab-internet-router)&lt;br /&gt;
# &#039;&#039;&#039;Time Information&#039;&#039;&#039; — Leave NTP server as 0.pfsense.pool.ntp.org; set timezone as needed (e.g., Asia/Manila)&lt;br /&gt;
# &#039;&#039;&#039;WAN Configuration&#039;&#039;&#039; — Verify static IP: 192.0.2.2/24, gateway 192.0.2.1&lt;br /&gt;
#* &#039;&#039;&#039;Important:&#039;&#039;&#039; Leave &amp;quot;Block bogon networks&amp;quot; and &amp;quot;Block private networks&amp;quot; unchecked (these are documentation IPs, not real public IPs)&lt;br /&gt;
# &#039;&#039;&#039;LAN Configuration&#039;&#039;&#039; — Verify 172.17.1.1/24&lt;br /&gt;
# &#039;&#039;&#039;Admin Password&#039;&#039;&#039; — Change to a secure password (or leave default for lab)&lt;br /&gt;
# &#039;&#039;&#039;Reload&#039;&#039;&#039; — Click Reload to apply settings&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Verification:&#039;&#039;&#039;&lt;br /&gt;
* HQ-client should be able to browse the real Internet through NAT&lt;br /&gt;
* Try browsing to any external website to confirm&lt;br /&gt;
&lt;br /&gt;
== Exercise 2: Manual Configuration Backup ==&lt;br /&gt;
# Browse to Diagnostics -&amp;gt; Backup &amp;amp; Restore&lt;br /&gt;
# Click Download configuration as XML&lt;br /&gt;
# Save the config.xml file to HQ-client&lt;br /&gt;
# &#039;&#039;&#039;What this contains:&#039;&#039;&#039; Entire system configuration — interfaces, rules, NAT, users, certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Exercise 3: Config History ==&lt;br /&gt;
# Stay on Diagnostics -&amp;gt; Backup &amp;amp; Restore&lt;br /&gt;
# Click the Config History tab&lt;br /&gt;
# You should see at least one revision (from the setup wizard)&lt;br /&gt;
# Click the diff icon to compare two revisions&lt;br /&gt;
# This shows exactly what changed between configurations&lt;br /&gt;
&lt;br /&gt;
== Exercise 4: AutoConfigBackup (ACB) ==&lt;br /&gt;
AutoConfigBackup is Netgate&#039;s encrypted cloud backup service. Every configuration change is automatically backed up offsite.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preparation (lab-specific step):&#039;&#039;&#039;&lt;br /&gt;
# Go to Diagnostics -&amp;gt; Command Prompt&lt;br /&gt;
# Run: rm /etc/ssh/ssh_host_* &amp;amp;&amp;amp; /etc/rc.restart_sshd&lt;br /&gt;
# This regenerates SSH keys for ACB compatibility in the lab environment&lt;br /&gt;
#* &#039;&#039;Note: Not needed in production environments&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Enable ACB:&#039;&#039;&#039;&lt;br /&gt;
# Go to Services -&amp;gt; AutoConfigBackup&lt;br /&gt;
# Check Enable ACB&lt;br /&gt;
# Enter an encryption password (remember this!)&lt;br /&gt;
# Optional: Add a plain-text identifier to help Netgate support locate your backups&lt;br /&gt;
# Click Save&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Verify backup:&#039;&#039;&#039;&lt;br /&gt;
# Click the Backup Now tab -&amp;gt; Backup&lt;br /&gt;
# Go to Restore tab — your backup should appear in the list&lt;br /&gt;
# Note your Device ID — save it securely with your encryption password&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; If you lose the encryption password, backups are unrecoverable. If you lose the Device ID, Netgate support can help locate it using your identifier.&lt;br /&gt;
&lt;br /&gt;
== Exercise 5: Configuration Restore ==&lt;br /&gt;
&#039;&#039;&#039;Scenario:&#039;&#039;&#039; You misconfigured something and need to roll back.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method A — Web Interface (if you can still reach it):&#039;&#039;&#039;&lt;br /&gt;
# Diagnostics -&amp;gt; Backup &amp;amp; Restore -&amp;gt; Config History&lt;br /&gt;
# Find the revision before your mistake&lt;br /&gt;
# Click Restore&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method B — AutoConfigBackup (longer history):&#039;&#039;&#039;&lt;br /&gt;
# Services -&amp;gt; AutoConfigBackup -&amp;gt; Restore tab&lt;br /&gt;
# Select a previous backup&lt;br /&gt;
# Click Restore&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method C — Console (emergency, no web access):&#039;&#039;&#039;&lt;br /&gt;
# Access console via SSH or physical access&lt;br /&gt;
# Choose option 15: &amp;quot;Restore recent configuration&amp;quot;&lt;br /&gt;
# Choose option 1 to view recent configs&lt;br /&gt;
# Choose option 2 to restore a specific revision&lt;br /&gt;
# Enter the revision number&lt;br /&gt;
# Confirm with Y&lt;br /&gt;
# Reboot (option 5) to ensure clean application&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Problem !! Solution&lt;br /&gt;
|-&lt;br /&gt;
| Can&#039;t reach https://172.17.1.1 || Check HQ-client IP (should be DHCP 172.17.1.x); verify cable/VLAN&lt;br /&gt;
|-&lt;br /&gt;
| Wizard doesn&#039;t start || Already completed; go to System -&amp;gt; Setup Wizard to re-run&lt;br /&gt;
|-&lt;br /&gt;
| No Internet from HQ-client || Verify WAN IP/gateway; check lab-internet-router is running&lt;br /&gt;
|-&lt;br /&gt;
| ACB won&#039;t enable || Run SSH key regeneration command first&lt;br /&gt;
|-&lt;br /&gt;
| Restore fails || Ensure restoring to equal or newer version; check encryption password&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Verification Checklist ==&lt;br /&gt;
Before finishing this lab, confirm:&lt;br /&gt;
* [ ] Setup wizard completed successfully&lt;br /&gt;
* [ ] HQ-client can browse Internet&lt;br /&gt;
* [ ] Manual config backup downloaded&lt;br /&gt;
* [ ] Config History shows revisions&lt;br /&gt;
* [ ] AutoConfigBackup enabled and backup completed&lt;br /&gt;
* [ ] Device ID recorded&lt;br /&gt;
* [ ] Successfully restored a previous configuration (optional practice)&lt;br /&gt;
&lt;br /&gt;
== Key Takeaways ==&lt;br /&gt;
* The lab simulates a real multi-site corporate network&lt;br /&gt;
* Using RFC 5737 documentation IPs prevents accidentally affecting real networks&lt;br /&gt;
* Always backup before making changes&lt;br /&gt;
* AutoConfigBackup provides 100 revisions of encrypted offsite backups&lt;br /&gt;
* Console restore (option 15) is your emergency recovery method&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
* [[Training: Interfaces and Firewall Rules]] — Phase 1, Day 3&lt;br /&gt;
* [[Training Lab 2: Firewall Rules and Aliases]] — Hands-on lab&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&#039;&#039;Source: Netgate FUND001-LIVE-Lab1-Intro.pdf&#039;&#039;&lt;br /&gt;
&#039;&#039;Comfac Virtual Lab Adaptation: VMs provisioned via Ansible; NoVNC access through student portal&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Training:_pfSense_Introduction&amp;diff=225</id>
		<title>Training: pfSense Introduction</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Training:_pfSense_Introduction&amp;diff=225"/>
		<updated>2026-04-23T06:50:06Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Convert FUND001 SEG1 Introduction slides to wiki training module&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#e3f2fd; border:1px solid #90caf9; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Training Module: Phase 1, Day 1&#039;&#039;&#039; — Introduction to pfSense Plus. Based on Netgate FUND001-LIVE-SLIDE-SEG1.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Learning Objectives ==&lt;br /&gt;
By the end of this module, you will be able to:&lt;br /&gt;
* Explain what pfSense Plus is and its core value proposition&lt;br /&gt;
* Describe the project history and difference between pfSense CE and pfSense Plus&lt;br /&gt;
* Identify supported platforms and hardware requirements&lt;br /&gt;
* Perform initial setup using the web-based setup wizard&lt;br /&gt;
* Create and restore configuration backups&lt;br /&gt;
* Understand upgrade procedures and risks&lt;br /&gt;
&lt;br /&gt;
== What is pfSense Plus? ==&lt;br /&gt;
pfSense Plus is a commercial, FreeBSD-based network firewall and routing platform developed by Netgate. It ties together multiple open-source networking components into a unified, entirely web-managed system.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Key Characteristics:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;FreeBSD-based&#039;&#039;&#039; — Uses the same trusted OS platform as Juniper, NetApp, Citrix, and Netflix&lt;br /&gt;
* &#039;&#039;&#039;Web-managed&#039;&#039;&#039; — Complete configuration through a browser-based GUI; no CLI required for day-to-day tasks&lt;br /&gt;
* &#039;&#039;&#039;Feature-rich&#039;&#039;&#039; — Richer feature set than most commercial firewalls at a fraction of the cost&lt;br /&gt;
* &#039;&#039;&#039;Open source core&#039;&#039;&#039; — Built on open-source components (pf, OpenVPN, WireGuard, etc.) made easy to use&lt;br /&gt;
&lt;br /&gt;
== Project History ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Year !! Milestone&lt;br /&gt;
|-&lt;br /&gt;
| 2004 || Project started as a fork of m0n0wall&lt;br /&gt;
|-&lt;br /&gt;
| Feb 2008 || pfSense 1.2 released (FreeBSD 6.2)&lt;br /&gt;
|-&lt;br /&gt;
| Sept 2011 || pfSense 2.0 released (FreeBSD 8.1)&lt;br /&gt;
|-&lt;br /&gt;
| Oct 2017 || pfSense 2.4 released (FreeBSD 11.1)&lt;br /&gt;
|-&lt;br /&gt;
| Feb 2021 || &#039;&#039;&#039;pfSense Plus 21.02&#039;&#039;&#039; forks from pfSense CE; commercial-only; adds WireGuard&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;pfSense Plus vs pfSense CE:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;pfSense Plus&#039;&#039;&#039; — Commercial license; available on Netgate hardware or Home+Lab (non-commercial); receives updates first&lt;br /&gt;
* &#039;&#039;&#039;pfSense CE&#039;&#039;&#039; — Community Edition; open source; free for all uses&lt;br /&gt;
&lt;br /&gt;
== Platforms &amp;amp; Hardware ==&lt;br /&gt;
&#039;&#039;&#039;Installation Media:&#039;&#039;&#039;&lt;br /&gt;
* Full installer (CD or USB memstick)&lt;br /&gt;
* 64-bit only&lt;br /&gt;
* No Live CD or NanoBSD (deprecated)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hardware Options:&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;Netgate Official Hardware&#039;&#039;&#039; — Pre-installed, pre-configured, fully optimized&lt;br /&gt;
# &#039;&#039;&#039;DIY/Custom Build&#039;&#039;&#039; — Check compatibility list at [https://docs.netgate.com/pfsense/en/latest/hardware docs.netgate.com]&lt;br /&gt;
# &#039;&#039;&#039;Home+Lab Edition&#039;&#039;&#039; — Free for non-commercial use; available from [https://www.pfsense.org/downloads pfsense.org]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Key hardware considerations:&#039;&#039;&#039;&lt;br /&gt;
* CPU selection (AES-NI support recommended for VPN performance)&lt;br /&gt;
* NIC quality and driver support (Intel i210/i350 preferred)&lt;br /&gt;
* RAM (1 GB minimum; 2+ GB for packages/VPN)&lt;br /&gt;
* Storage (SSD recommended; 8 GB minimum)&lt;br /&gt;
&lt;br /&gt;
== Initial Setup ==&lt;br /&gt;
&#039;&#039;&#039;Default LAN configuration:&#039;&#039;&#039;&lt;br /&gt;
* LAN IP: &#039;&#039;&#039;192.168.1.1/24&#039;&#039;&#039;&lt;br /&gt;
* DHCP server enabled on LAN&lt;br /&gt;
* Web interface: &#039;&#039;&#039;https://192.168.1.1&#039;&#039;&#039;&lt;br /&gt;
* Default credentials: &#039;&#039;&#039;admin / pfsense&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Setup Wizard steps:&#039;&#039;&#039;&lt;br /&gt;
# Connect to LAN port; obtain DHCP address&lt;br /&gt;
# Browse to https://192.168.1.1&lt;br /&gt;
# Log in with default credentials&lt;br /&gt;
# Complete wizard: General Info → Time Server → WAN Config → LAN Config → Admin Password → Reload&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; Always change the default admin password in production.&lt;br /&gt;
&lt;br /&gt;
== Configuration Backup &amp;amp; Restore ==&lt;br /&gt;
&#039;&#039;&#039;Why back up?&#039;&#039;&#039;&lt;br /&gt;
* Hardware failure recovery&lt;br /&gt;
* Pre-upgrade safety net&lt;br /&gt;
* Configuration migration to new hardware&lt;br /&gt;
* Rollback after misconfiguration&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Backup methods:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method !! Location !! Retention !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Manual download || Diagnostics → Backup/Restore || N/A (local file) || Full config.xml download&lt;br /&gt;
|-&lt;br /&gt;
| Config History || Diagnostics → Backup/Restore → Config History || 30 revisions (configurable) || Local to device&lt;br /&gt;
|-&lt;br /&gt;
| AutoConfigBackup (ACB) || Services → AutoConfigBackup || 100 revisions || Cloud backup; encrypted&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Backup best practices:&#039;&#039;&#039;&lt;br /&gt;
* Always backup &#039;&#039;&#039;before&#039;&#039;&#039; upgrades&lt;br /&gt;
* Store encryption password and Device ID safely (for ACB)&lt;br /&gt;
* Never restore to an &#039;&#039;&#039;older&#039;&#039;&#039; pfSense version; only equal or newer&lt;br /&gt;
* When restoring to different hardware, interface assignments will differ&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Console restore (emergency):&#039;&#039;&#039;&lt;br /&gt;
* Option 15 at console menu — &amp;quot;Restore recent configuration&amp;quot;&lt;br /&gt;
* Useful when web interface is unreachable&lt;br /&gt;
* May require reboot after restore&lt;br /&gt;
&lt;br /&gt;
== Upgrades ==&lt;br /&gt;
&#039;&#039;&#039;Pre-upgrade checklist:&#039;&#039;&#039;&lt;br /&gt;
# Create configuration backup&lt;br /&gt;
# Read release notes&lt;br /&gt;
# Check upgrade guide at [https://docs.netgate.com/pfsense/en/latest/install/upgrade-guide.html docs.netgate.com]&lt;br /&gt;
# Verify auto-upgrade URL (for Plus)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Upgrade methods:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Auto-Update&#039;&#039;&#039; — Web GUI: System → Update&lt;br /&gt;
* &#039;&#039;&#039;Console Update&#039;&#039;&#039; — Option 13 at console menu&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Upgrade risks (rare but possible):&#039;&#039;&#039;&lt;br /&gt;
* Hardware failure during reboot&lt;br /&gt;
* Package complications&lt;br /&gt;
* Hardware-specific regressions&lt;br /&gt;
* Dependency on bug fixes from current version&lt;br /&gt;
&lt;br /&gt;
== Key Takeaways ==&lt;br /&gt;
* pfSense Plus is commercial-only; Home+Lab available for non-commercial use&lt;br /&gt;
* Always check hardware compatibility before DIY builds&lt;br /&gt;
* &#039;&#039;&#039;Backup before every upgrade&#039;&#039;&#039; — non-negotiable&lt;br /&gt;
* Restore only to equal or newer versions&lt;br /&gt;
* Use AutoConfigBackup for offsite, encrypted cloud backups&lt;br /&gt;
* Keep encryption password and Device ID in a safe place&lt;br /&gt;
&lt;br /&gt;
== Quiz (Self-Check) ==&lt;br /&gt;
# What operating system is pfSense Plus based on?&lt;br /&gt;
# What is the difference between pfSense Plus and pfSense CE?&lt;br /&gt;
# Why should you avoid restoring a backup to an older pfSense version?&lt;br /&gt;
# Where do you find the Config History feature?&lt;br /&gt;
# What two pieces of information must you save when using AutoConfigBackup?&lt;br /&gt;
&lt;br /&gt;
== Next Module ==&lt;br /&gt;
* [[Training: Interfaces and Firewall Rules]] — Phase 1, Day 2–3&lt;br /&gt;
* [[Training Lab 1: Introduction and Backup Restore]] — Hands-on lab&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&#039;&#039;Source: Netgate FUND001-LIVE-SLIDE-SEG1-INTRO.pdf&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=224</id>
		<title>Networking PfSense Index</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=224"/>
		<updated>2026-04-23T06:38:23Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Add link to PfSense Training Project Tracker&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f0f7ff; border:1px solid #b8d4f0; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Consolidated index&#039;&#039;&#039; for all networking infrastructure guides, pfSense documentation, DNS/ad-blocking resources, and network equipment references at Comfac IT.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== pfSense Core Guides ==&lt;br /&gt;
* [[pfSense Sales Training Material]] — Product knowledge and sales positioning for Netgate/pfSense hardware and software&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS &amp;amp; ACME]] — Enterprise Wi-Fi captive portal with RADIUS authentication and Let&#039;s Encrypt SSL&lt;br /&gt;
* [[pfSense CE → pfSense Plus Upgrade Guide]] — Step-by-step migration from Community Edition to pfSense Plus&lt;br /&gt;
* [[SOP: Network Troubleshooting &amp;amp; pfSense Monitoring 251130]] — Standard operating procedures for network diagnostics and pfSense health monitoring&lt;br /&gt;
&lt;br /&gt;
== Network Infrastructure &amp;amp; Equipment ==&lt;br /&gt;
* [[Tplink Mikrotik Equivalent]] — Cross-reference of TP-Link and MikroTik models for network deployments&lt;br /&gt;
* [[Controller Systems 251213-01]] — Network and infrastructure controller systems&lt;br /&gt;
* [[Power Distribution Tree 251213]] — Power architecture for network and server racks&lt;br /&gt;
* [[NPM Migration to Homelab VPS Relay 260401]] — Nginx Proxy Manager migration; VPS as iptables/ZeroTier relay with homelab redundancy&lt;br /&gt;
&lt;br /&gt;
== DNS, Ad Blocking &amp;amp; Pi-hole ==&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/pi-hole Comfac Pi-hole Repository] — GitHub repository for Pi-hole DNS sinkhole deployment&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/pi-hole/blob/master/How%20this%20Works.md How Pi-hole Works] — Technical overview of the Pi-hole DNS filtering architecture&lt;br /&gt;
&lt;br /&gt;
== Training &amp;amp; Skills ==&lt;br /&gt;
* [[Skills and Competencies for IT Staff Trained in pfSense]] — Required competencies and certification path for pfSense-administering staff&lt;br /&gt;
* [[PfSense Training Project Tracker]] — &#039;&#039;&#039;Implementation tracker&#039;&#039;&#039; for the NoVNC virtual lab, material conversion, and curriculum development&lt;br /&gt;
&lt;br /&gt;
== Practical Training System (NoVNC Virtual Lab) ==&lt;br /&gt;
&#039;&#039;&#039;Goal:&#039;&#039;&#039; Build a self-hosted, virtualized pfSense training environment where Comfac trainees can learn hands-on without physical hardware. All labs run via NoVNC in a browser, orchestrated on Comfac&#039;s 200-core / 1TB RAM machine.&lt;br /&gt;
&lt;br /&gt;
=== Training Architecture Vision ===&lt;br /&gt;
Each student gets an isolated virtual network sandbox containing:&lt;br /&gt;
* 2× pfSense VMs (HQ HA pair or HQ + Branch)&lt;br /&gt;
* 1–2× Client VMs (Windows/Linux desktop)&lt;br /&gt;
* 1× Server VM (web/DNS/target)&lt;br /&gt;
* 1× Simulated &amp;quot;Internet&amp;quot; router VM&lt;br /&gt;
&lt;br /&gt;
Access is through a NoVNC web portal. Students click a lab, and their environment is provisioned automatically via Ansible/Terraform or Docker/KVM.&lt;br /&gt;
&lt;br /&gt;
=== Resource Estimates Per Student ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! vCPUs !! RAM !! Disk !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| pfSense VM || 2 || 1 GB || 8 GB || One per firewall; labs need 2–4&lt;br /&gt;
|-&lt;br /&gt;
| Windows Client || 2 || 4 GB || 40 GB || Can be replaced with thin Linux client&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu Server || 1 || 1 GB || 10 GB || DNS/web/target server&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;Internet&amp;quot; Router || 1 || 512 MB || 4 GB || Simulated upstream ISP&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total (minimal)&#039;&#039;&#039; || &#039;&#039;&#039;6&#039;&#039;&#039; || &#039;&#039;&#039;6.5 GB&#039;&#039;&#039; || &#039;&#039;&#039;62 GB&#039;&#039;&#039; || 2 firewalls + 1 client + 1 server + internet&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total (full lab)&#039;&#039;&#039; || &#039;&#039;&#039;10&#039;&#039;&#039; || &#039;&#039;&#039;10.5 GB&#039;&#039;&#039; || &#039;&#039;&#039;110 GB&#039;&#039;&#039; || 4 firewalls + 2 clients + 2 servers + internet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cluster capacity (200 core / 1 TB RAM):&#039;&#039;&#039;&lt;br /&gt;
* Conservative (10 cores + 10 GB per student): ~20 concurrent students&lt;br /&gt;
* Optimized (6 cores + 6.5 GB per student): ~30 concurrent students&lt;br /&gt;
* With memory overcommit and thin-provisioned disks: potentially 40+ students&lt;br /&gt;
&lt;br /&gt;
=== Zero-Touch Provisioning / Infra-as-Code Strategy ===&lt;br /&gt;
Given constrained materials (old PCs, limited budget), the deployment stack should be:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option A: KVM + Ansible (Recommended for Comfac)&#039;&#039;&#039;&lt;br /&gt;
* KVM/libvirt on Ubuntu host&lt;br /&gt;
* qcow2 base images for pfSense, Windows, Ubuntu&lt;br /&gt;
* Ansible playbooks per lab:&lt;br /&gt;
** Clone base images (linked clones for disk efficiency)&lt;br /&gt;
** Configure VLANs/internal networks via libvirt&lt;br /&gt;
** Start VMs in correct order&lt;br /&gt;
** Inject pfSense config.xml for each lab stage&lt;br /&gt;
* NoVNC via &#039;&#039;&#039;Kimchi&#039;&#039;&#039; or &#039;&#039;&#039;Apache Guacamole&#039;&#039;&#039; as the web portal&lt;br /&gt;
* Students get a unique URL + credentials; VMs are destroyed/re-created per session&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option B: Docker + GNS3/EVE-NG (Alternative)&#039;&#039;&#039;&lt;br /&gt;
* pfSense can run in QEMU inside Docker&lt;br /&gt;
* More complex networking; less stable than KVM&lt;br /&gt;
* Better for Cisco/Juniper labs, not ideal for pfSense web-GUI training&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option C: Proxmox VE Cluster (If hardware allows)&#039;&#039;&#039;&lt;br /&gt;
* Best UX but requires dedicated Proxmox host(s)&lt;br /&gt;
* Good for the 200-core machine, not for old PCs&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Chosen Path for Comfac: Option A (KVM/Ansible)&#039;&#039;&#039;&lt;br /&gt;
* Old PCs become thin clients (any PC with a browser)&lt;br /&gt;
* Heavy lifting happens on the 200-core host&lt;br /&gt;
* Ansible manages:&lt;br /&gt;
** VM lifecycle (create/start/stop/destroy)&lt;br /&gt;
** Network topology (bridges, VLANs, isolated libvirt networks)&lt;br /&gt;
** Student access (NoVNC tokens, time limits)&lt;br /&gt;
** Snapshot/reset between sessions&lt;br /&gt;
&lt;br /&gt;
=== Training Phases / Legs (1 Hour Per Day) ===&lt;br /&gt;
The FUND001 curriculum is broken into digestible daily modules.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Phase !! Day !! Topic !! Slide !! Lab !! VMs Required&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &#039;&#039;&#039;Phase 1: Foundations&#039;&#039;&#039; || 1 || Intro to pfSense: What, Why, History, Certifications || SEG1 || — || —&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Interfaces, IPs, VLANs, Virtual IPs || SEG2 || Lab 1 (Intro + Backup/Restore) || 1 pfSense + 1 client&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Firewall Rules, Aliases, Best Practices || SEG2 || Lab 2 (Rules + Aliases) || 1 pfSense + 1 client + 1 server&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &#039;&#039;&#039;Phase 2: NAT &amp;amp; Services&#039;&#039;&#039; || 4 || NAT Overview: Outbound, Port Forwards, 1:1 NAT || SEG3 || Lab 3 (NAT + VIPs) || 1 pfSense + 1 server + internet&lt;br /&gt;
|-&lt;br /&gt;
| 5 || DHCP, DNS Resolver, Dynamic DNS, NTP || SEG4 || Lab 4 (Services + Branch Setup) || 2 pfSense + 2 clients + 1 server&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Package System, Common Packages (pfBlocker, Suricata intro) || SEG11 || — || 1 pfSense&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | &#039;&#039;&#039;Phase 3: VPNs&#039;&#039;&#039; || 7 || VPN Concepts: IPsec, OpenVPN, WireGuard compared || SEG5 || — || —&lt;br /&gt;
|-&lt;br /&gt;
| 8 || IPsec Site-to-Site + Mobile Remote Access || SEG5 || Lab 5 (IPsec) || 2 pfSense + 2 clients&lt;br /&gt;
|-&lt;br /&gt;
| 9 || OpenVPN Site-to-Site + Remote Access with Client Export || SEG6 || Lab 6 (OpenVPN) || 2 pfSense + 2 clients&lt;br /&gt;
|-&lt;br /&gt;
| 10 || WireGuard Site-to-Site || SEG7 || Lab 7 (WireGuard) || 2 pfSense + 2 clients&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &#039;&#039;&#039;Phase 4: Resilience&#039;&#039;&#039; || 11 || Multi-WAN: Failover, Load Balancing, Gateway Groups || SEG8 || Lab 8 (Multi-WAN) || 1 pfSense + 2 WANs + client&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Traffic Shaping &amp;amp; Limiters (ALTQ + dummynet) || SEG9 || Lab 9 (Traffic Shaping) || 1 pfSense + multiple clients&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &#039;&#039;&#039;Phase 5: Advanced&#039;&#039;&#039; || 13 || High Availability: CARP, XMLRPC, pfsync || SEG10 || Lab 10 (HA) || 2 pfSense (HA pair) + client&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Monitoring, SNMP, RRD, Log Aggregation, Packages || SEG11 || — || 1 pfSense + monitoring target&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Phase 6: Capstone&#039;&#039;&#039; || 15 || Build Your Own Firewall: Design, Implement, Present || — || Capstone || Full lab (4 pfSense + clients + servers)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sub-Phases for Comfac Internal Use (ZTP/IaC Focus) ===&lt;br /&gt;
These are shorter, targeted sessions for staff who will build and maintain the training platform.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sub-Phase !! Topic !! Duration !! Deliverable&lt;br /&gt;
|-&lt;br /&gt;
| A.1 || KVM/libvirt Setup on 200-Core Host || 2 hrs || Host provisioned with bridges and storage pools&lt;br /&gt;
|-&lt;br /&gt;
| A.2 || Base Image Creation: pfSense, Windows, Ubuntu || 2 hrs || qcow2 golden images ready for cloning&lt;br /&gt;
|-&lt;br /&gt;
| A.3 || Ansible Playbook: Lab 1 Environment || 3 hrs || `ansible-playbook lab1.yml --extra-vars student_id=01`&lt;br /&gt;
|-&lt;br /&gt;
| A.4 || NoVNC Portal: Kimchi or Guacamole Integration || 3 hrs || Browser-based console access working&lt;br /&gt;
|-&lt;br /&gt;
| A.5 || Automated Cleanup &amp;amp; Snapshot Reset || 2 hrs || VMs destroyed/recreated between sessions&lt;br /&gt;
|-&lt;br /&gt;
| A.6 || Monitoring &amp;amp; Quota: Per-Student Resource Limits || 2 hrs || cgroups/libvirt quotas enforced&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Required Containers / VMs Summary ===&lt;br /&gt;
&#039;&#039;&#039;Per-Lab VM Inventory&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Lab !! pfSense !! Clients !! Servers !! Internet Router !! Total vCPUs !! Total RAM&lt;br /&gt;
|-&lt;br /&gt;
| Lab 1 (Intro) || 1 || 1 || 0 || 0 || 4 || 5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 2 (Rules) || 1 || 1 || 1 || 0 || 5 || 6 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 3 (NAT/VIP) || 1 || 0 || 1 || 1 || 5 || 6.5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 4 (Services) || 2 || 2 || 1 || 0 || 10 || 13 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 5 (IPsec) || 2 || 2 || 0 || 0 || 10 || 12 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 6 (OpenVPN) || 2 || 2 || 0 || 0 || 10 || 12 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 7 (WireGuard) || 2 || 2 || 0 || 0 || 10 || 12 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 8 (Multi-WAN) || 1 || 1 || 0 || 1 || 5 || 6.5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 9 (Shaping) || 1 || 2+ || 0 || 0 || 6+ || 9+ GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 10 (HA) || 2 || 1 || 0 || 0 || 6 || 7 GB&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Capstone&#039;&#039;&#039; || &#039;&#039;&#039;4&#039;&#039;&#039; || &#039;&#039;&#039;2&#039;&#039;&#039; || &#039;&#039;&#039;2&#039;&#039;&#039; || &#039;&#039;&#039;1&#039;&#039;&#039; || &#039;&#039;&#039;18&#039;&#039;&#039; || &#039;&#039;&#039;21 GB&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Containerization Notes:&#039;&#039;&#039;&lt;br /&gt;
* pfSense runs on FreeBSD; must use full KVM virtualization (not containers)&lt;br /&gt;
* Clients can be Linux containers (LXC) if only CLI/SSH access needed; Windows requires KVM&lt;br /&gt;
* NoVNC proxy can run in Docker for easy deployment&lt;br /&gt;
* Ansible controller can be a Docker container or the host itself&lt;br /&gt;
&lt;br /&gt;
== Related Infrastructure ==&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]] — Server migration and infrastructure hardening&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]] — Self-hosted email infrastructure context&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]] — Email server deployment&lt;br /&gt;
* [[Portainer to Docker Compose Migration Guide]] — Container orchestration for network services&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&#039;&#039;This index consolidates networking resources previously scattered across the [[Main Page]]. Last updated: 260423.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=PfSense_Training_Project_Tracker&amp;diff=223</id>
		<title>PfSense Training Project Tracker</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=PfSense_Training_Project_Tracker&amp;diff=223"/>
		<updated>2026-04-23T06:37:36Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Create project tracker for pfSense practical training system implementation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#fff8e1; border:1px solid #ffcc80; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Project Tracker&#039;&#039;&#039; for Comfac&#039;s pfSense Practical Training System implementation. This page tracks all tasks from material conversion to infrastructure deployment and course delivery.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Phase 0: Material Conversion (FUND001 → Wiki) ==&lt;br /&gt;
Convert all Netgate FUND001 training PDFs into CITWiki pages with detailed summaries. Each wiki page should include: learning objectives, key concepts, step-by-step lab instructions adapted for virtual environment, and troubleshooting tips.&lt;br /&gt;
&lt;br /&gt;
=== Slide Decks ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG1 — Introduction to pfSense&#039;&#039;&#039; → [[Training: pfSense Introduction]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG2 — Interfaces, VIPs, and Rules&#039;&#039;&#039; → [[Training: Interfaces and Firewall Rules]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG3 — NAT and VIPs&#039;&#039;&#039; → [[Training: NAT and Virtual IPs]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG4 — pfSense Services&#039;&#039;&#039; → [[Training: pfSense Services]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG5 — VPNs and IPsec&#039;&#039;&#039; → [[Training: IPsec VPN]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG6 — OpenVPN&#039;&#039;&#039; → [[Training: OpenVPN]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG7 — WireGuard&#039;&#039;&#039; → [[Training: WireGuard]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG8 — Multi-WAN&#039;&#039;&#039; → [[Training: Multi-WAN]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG9 — Traffic Shaping&#039;&#039;&#039; → [[Training: Traffic Shaping]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG10 — High Availability&#039;&#039;&#039; → [[Training: High Availability]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;SEG11 — Other Features&#039;&#039;&#039; → [[Training: Monitoring and Packages]]&lt;br /&gt;
&lt;br /&gt;
=== Labs ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 1 — Intro, Getting Started, Backup/Restore&#039;&#039;&#039; → [[Training Lab 1: Introduction and Backup Restore]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 2 — Interfaces, Firewall Rules, Aliases&#039;&#039;&#039; → [[Training Lab 2: Firewall Rules and Aliases]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 3 — Virtual IPs and NAT&#039;&#039;&#039; → [[Training Lab 3: NAT and Virtual IPs]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 4 — Services and Branch Network Setup&#039;&#039;&#039; → [[Training Lab 4: Services and Branch Network]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 5 — IPsec&#039;&#039;&#039; → [[Training Lab 5: IPsec VPN]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 6 — OpenVPN&#039;&#039;&#039; → [[Training Lab 6: OpenVPN]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 7 — WireGuard&#039;&#039;&#039; → [[Training Lab 7: WireGuard]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 8 — Multi-WAN&#039;&#039;&#039; → [[Training Lab 8: Multi-WAN]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 9 — Traffic Shaping&#039;&#039;&#039; → [[Training Lab 9: Traffic Shaping]]&lt;br /&gt;
* [ ] &#039;&#039;&#039;Lab 10 — High Availability&#039;&#039;&#039; → [[Training Lab 10: High Availability]]&lt;br /&gt;
&lt;br /&gt;
=== Reference Materials ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;the-pfsense-documentation.pdf&#039;&#039;&#039; → Summarize into [[Training: pfSense Complete Reference]] or link as external reference&lt;br /&gt;
* [ ] &#039;&#039;&#039;WindowsTrainingSupportFiles.zip&#039;&#039;&#039; → Extract and document client software requirements ([[Training: Client Software Requirements]])&lt;br /&gt;
* [ ] &#039;&#039;&#039;Training Videos (4× .mkv)&#039;&#039;&#039; → Catalog timestamps and link from relevant wiki pages&lt;br /&gt;
&lt;br /&gt;
== Phase 1: Infrastructure Setup ==&lt;br /&gt;
Build the virtual training environment on Comfac&#039;s 200-core / 1TB RAM machine.&lt;br /&gt;
&lt;br /&gt;
=== Host Preparation ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.1&#039;&#039;&#039; Install Ubuntu Server LTS on 200-core host&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.2&#039;&#039;&#039; Configure KVM/libvirt with storage pools (NVMe for images, SSD for ephemeral clones)&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.3&#039;&#039;&#039; Set up network bridges: `br-mgmt`, `br-lan`, `br-wan`, `br-dmz`, `br-internet`&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.4&#039;&#039;&#039; Configure VLANs for student isolation (one VLAN per student or per lab)&lt;br /&gt;
* [ ] &#039;&#039;&#039;A.5&#039;&#039;&#039; Install and configure Ansible controller (host or container)&lt;br /&gt;
&lt;br /&gt;
=== Base Images ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.1&#039;&#039;&#039; Download pfSense CE ISO and create qcow2 golden image (2 vCPU, 1 GB RAM, 8 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.2&#039;&#039;&#039; Create Ubuntu Server 22.04/24.04 golden image (1 vCPU, 1 GB RAM, 10 GB disk)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.3&#039;&#039;&#039; Create Windows 10/11 thin client golden image (2 vCPU, 4 GB RAM, 40 GB disk) — OR decide to use Linux clients only&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.4&#039;&#039;&#039; Create &amp;quot;Internet Router&amp;quot; golden image (Ubuntu with FRR/Quagga or simple static routes, 1 vCPU, 512 MB RAM)&lt;br /&gt;
* [ ] &#039;&#039;&#039;B.5&#039;&#039;&#039; Test each golden image boots and functions correctly&lt;br /&gt;
&lt;br /&gt;
=== Automation ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.1&#039;&#039;&#039; Write Ansible playbook: `lab1-student-env.yml` (1 pfSense + 1 client)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.2&#039;&#039;&#039; Write Ansible playbook: `lab2-student-env.yml` (1 pfSense + 1 client + 1 server)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.3&#039;&#039;&#039; Write Ansible playbook: `lab3-student-env.yml` (1 pfSense + 1 server + internet)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.4&#039;&#039;&#039; Write Ansible playbook: `lab4-student-env.yml` (2 pfSense + 2 clients + 1 server)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.5&#039;&#039;&#039; Write Ansible playbooks for Labs 5–10 (VPNs, Multi-WAN, Shaping, HA)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.6&#039;&#039;&#039; Write Ansible playbook: `cleanup-student-env.yml` (destroy VMs, free resources)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.7&#039;&#039;&#039; Write Ansible playbook: `reset-student-env.yml` (revert to snapshot/linked clone base)&lt;br /&gt;
* [ ] &#039;&#039;&#039;C.8&#039;&#039;&#039; Test all playbooks end-to-end with a single student ID&lt;br /&gt;
&lt;br /&gt;
=== NoVNC Portal ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.1&#039;&#039;&#039; Evaluate Kimchi vs Apache Guacamole vs custom NoVNC proxy&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.2&#039;&#039;&#039; Install and configure chosen NoVNC solution&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.3&#039;&#039;&#039; Integrate NoVNC with student authentication (LDAP, local wiki accounts, or simple token-based)&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.4&#039;&#039;&#039; Build student dashboard: list of phases/labs, &amp;quot;Launch Lab&amp;quot; button, countdown timer&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.5&#039;&#039;&#039; Test 5 concurrent NoVNC sessions for stability&lt;br /&gt;
* [ ] &#039;&#039;&#039;D.6&#039;&#039;&#039; Test 20 concurrent NoVNC sessions for performance&lt;br /&gt;
&lt;br /&gt;
== Phase 2: Curriculum Development ==&lt;br /&gt;
Design the student-facing training program.&lt;br /&gt;
&lt;br /&gt;
=== Introduction Course (Most Common Use Case) ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.1&#039;&#039;&#039; Define &amp;quot;Setting Up a Firewall for Yourself&amp;quot; scope: home office / small business&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.2&#039;&#039;&#039; Write Module 0: Why You Need a Firewall (threats, NAT basics, basic topology)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.3&#039;&#039;&#039; Write Module 1: Install pfSense on Old PC or VM (hardware requirements, USB install, first boot wizard)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.4&#039;&#039;&#039; Write Module 2: Basic WAN + LAN Setup (DHCP, DNS, first internet connection)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.5&#039;&#039;&#039; Write Module 3: Essential Firewall Rules (block incoming, allow outgoing, ICMP)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.6&#039;&#039;&#039; Write Module 4: Port Forwarding for Common Services (game server, camera, NAS)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.7&#039;&#039;&#039; Write Module 5: VPN for Remote Access (WireGuard road warrior setup)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.8&#039;&#039;&#039; Write Module 6: Backup and Updates (config.xml backup, update schedule)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.9&#039;&#039;&#039; Create hands-on lab for Introduction Course (single pfSense + 1 client VM)&lt;br /&gt;
* [ ] &#039;&#039;&#039;E.10&#039;&#039;&#039; Record or source video walkthroughs for each module&lt;br /&gt;
&lt;br /&gt;
=== Full FUND001 Adaptation ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.1&#039;&#039;&#039; Map each SEG slide deck to a wiki training page with summary + key takeaways&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.2&#039;&#039;&#039; Adapt Netgate labs from physical/virtualbox environment to KVM/Ansible environment&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.3&#039;&#039;&#039; Update IP addressing schema for Comfac virtual lab (avoid conflicts with production)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.4&#039;&#039;&#039; Write pre-lab briefing pages (what you&#039;ll learn, expected outcomes)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.5&#039;&#039;&#039; Write post-lab review pages (common mistakes, verification steps, &amp;quot;show me&amp;quot; checklist)&lt;br /&gt;
* [ ] &#039;&#039;&#039;F.6&#039;&#039;&#039; Create quiz questions for each phase (5–10 questions, auto-graded if possible)&lt;br /&gt;
&lt;br /&gt;
== Phase 3: Pilot &amp;amp; Refinement ==&lt;br /&gt;
Run the training with a small group before full rollout.&lt;br /&gt;
&lt;br /&gt;
=== Internal Pilot ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.1&#039;&#039;&#039; Recruit 3–5 internal Comfac IT staff as pilot students&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.2&#039;&#039;&#039; Run Phase 1 (Foundations) with pilot group — collect feedback&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.3&#039;&#039;&#039; Run Phase 2 (NAT &amp;amp; Services) with pilot group — collect feedback&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.4&#039;&#039;&#039; Run one VPN lab (IPsec or OpenVPN) with pilot group — test resource limits&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.5&#039;&#039;&#039; Document all bugs, confusion points, and timeouts&lt;br /&gt;
* [ ] &#039;&#039;&#039;G.6&#039;&#039;&#039; Refine playbooks and wiki pages based on pilot feedback&lt;br /&gt;
&lt;br /&gt;
=== Resource Tuning ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.1&#039;&#039;&#039; Measure actual CPU/RAM/disk usage per student during pilot&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.2&#039;&#039;&#039; Adjust VM specs if over- or under-provisioned&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.3&#039;&#039;&#039; Test memory overcommit ratios for safe concurrency scaling&lt;br /&gt;
* [ ] &#039;&#039;&#039;H.4&#039;&#039;&#039; Document maximum safe concurrent student count&lt;br /&gt;
&lt;br /&gt;
== Phase 4: Deployment &amp;amp; Operations ==&lt;br /&gt;
Prepare for regular training delivery.&lt;br /&gt;
&lt;br /&gt;
=== Student Onboarding ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.1&#039;&#039;&#039; Create student onboarding guide (how to access portal, use NoVNC, reset lab)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.2&#039;&#039;&#039; Create instructor guide (how to monitor progress, assist students, grade labs)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.3&#039;&#039;&#039; Set up scheduling system (book lab time slots, prevent over-allocation)&lt;br /&gt;
* [ ] &#039;&#039;&#039;I.4&#039;&#039;&#039; Create completion certificates or badges&lt;br /&gt;
&lt;br /&gt;
=== Monitoring &amp;amp; Maintenance ===&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.1&#039;&#039;&#039; Set up host monitoring (Prometheus/Grafana or simple `libvirt` stats)&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.2&#039;&#039;&#039; Configure alerts for host resource exhaustion&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.3&#039;&#039;&#039; Schedule weekly base image updates (pfSense patches, OS updates)&lt;br /&gt;
* [ ] &#039;&#039;&#039;J.4&#039;&#039;&#039; Document disaster recovery (rebuild host from Ansible, restore golden images)&lt;br /&gt;
&lt;br /&gt;
== Quick Status Dashboard ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Phase !! Status !! % Complete !! Blockers&lt;br /&gt;
|-&lt;br /&gt;
| Phase 0: Material Conversion || 🟡 In Progress || 0% || Need bot/API access for bulk uploads&lt;br /&gt;
|-&lt;br /&gt;
| Phase 1: Infrastructure Setup || 🔴 Not Started || 0% || Need 200-core host access&lt;br /&gt;
|-&lt;br /&gt;
| Phase 2: Curriculum Development || 🔴 Not Started || 0% || Waiting on Phase 0 completion&lt;br /&gt;
|-&lt;br /&gt;
| Phase 3: Pilot &amp;amp; Refinement || 🔴 Not Started || 0% || Waiting on Phase 1 + 2&lt;br /&gt;
|-&lt;br /&gt;
| Phase 4: Deployment &amp;amp; Operations || 🔴 Not Started || 0% || Waiting on Phase 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Resource Summary ==&lt;br /&gt;
&#039;&#039;&#039;Per-student minimum:&#039;&#039;&#039; 6 vCPUs, 6.5 GB RAM, 62 GB disk&lt;br /&gt;
&#039;&#039;&#039;Per-student full lab:&#039;&#039;&#039; 10 vCPUs, 10.5 GB RAM, 110 GB disk&lt;br /&gt;
&#039;&#039;&#039;200-core / 1TB capacity:&#039;&#039;&#039; 20–40 concurrent students (conservative to optimized)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Next Actions (This Week):&#039;&#039;&#039;&lt;br /&gt;
# Start converting FUND001-LIVE-SLIDE-SEG1-INTRO.pdf and FUND001-LIVE-Lab1-Intro.pdf to wiki&lt;br /&gt;
# Confirm 200-core host specifications and OS&lt;br /&gt;
# Evaluate Kimchi vs Guacamole for NoVNC portal&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=222</id>
		<title>Networking PfSense Index</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=222"/>
		<updated>2026-04-23T06:36:05Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Add Practical Training System (NoVNC Virtual Lab) section with phases, resource estimates, and ZTP/IaC strategy&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f0f7ff; border:1px solid #b8d4f0; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Consolidated index&#039;&#039;&#039; for all networking infrastructure guides, pfSense documentation, DNS/ad-blocking resources, and network equipment references at Comfac IT.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== pfSense Core Guides ==&lt;br /&gt;
* [[pfSense Sales Training Material]] — Product knowledge and sales positioning for Netgate/pfSense hardware and software&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS &amp;amp; ACME]] — Enterprise Wi-Fi captive portal with RADIUS authentication and Let&#039;s Encrypt SSL&lt;br /&gt;
* [[pfSense CE → pfSense Plus Upgrade Guide]] — Step-by-step migration from Community Edition to pfSense Plus&lt;br /&gt;
* [[SOP: Network Troubleshooting &amp;amp; pfSense Monitoring 251130]] — Standard operating procedures for network diagnostics and pfSense health monitoring&lt;br /&gt;
&lt;br /&gt;
== Network Infrastructure &amp;amp; Equipment ==&lt;br /&gt;
* [[Tplink Mikrotik Equivalent]] — Cross-reference of TP-Link and MikroTik models for network deployments&lt;br /&gt;
* [[Controller Systems 251213-01]] — Network and infrastructure controller systems&lt;br /&gt;
* [[Power Distribution Tree 251213]] — Power architecture for network and server racks&lt;br /&gt;
* [[NPM Migration to Homelab VPS Relay 260401]] — Nginx Proxy Manager migration; VPS as iptables/ZeroTier relay with homelab redundancy&lt;br /&gt;
&lt;br /&gt;
== DNS, Ad Blocking &amp;amp; Pi-hole ==&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/pi-hole Comfac Pi-hole Repository] — GitHub repository for Pi-hole DNS sinkhole deployment&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/pi-hole/blob/master/How%20this%20Works.md How Pi-hole Works] — Technical overview of the Pi-hole DNS filtering architecture&lt;br /&gt;
&lt;br /&gt;
== Training &amp;amp; Skills ==&lt;br /&gt;
* [[Skills and Competencies for IT Staff Trained in pfSense]] — Required competencies and certification path for pfSense-administering staff&lt;br /&gt;
&lt;br /&gt;
== Practical Training System (NoVNC Virtual Lab) ==&lt;br /&gt;
&#039;&#039;&#039;Goal:&#039;&#039;&#039; Build a self-hosted, virtualized pfSense training environment where Comfac trainees can learn hands-on without physical hardware. All labs run via NoVNC in a browser, orchestrated on Comfac&#039;s 200-core / 1TB RAM machine.&lt;br /&gt;
&lt;br /&gt;
=== Training Architecture Vision ===&lt;br /&gt;
Each student gets an isolated virtual network sandbox containing:&lt;br /&gt;
* 2× pfSense VMs (HQ HA pair or HQ + Branch)&lt;br /&gt;
* 1–2× Client VMs (Windows/Linux desktop)&lt;br /&gt;
* 1× Server VM (web/DNS/target)&lt;br /&gt;
* 1× Simulated &amp;quot;Internet&amp;quot; router VM&lt;br /&gt;
&lt;br /&gt;
Access is through a NoVNC web portal. Students click a lab, and their environment is provisioned automatically via Ansible/Terraform or Docker/KVM.&lt;br /&gt;
&lt;br /&gt;
=== Resource Estimates Per Student ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! vCPUs !! RAM !! Disk !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| pfSense VM || 2 || 1 GB || 8 GB || One per firewall; labs need 2–4&lt;br /&gt;
|-&lt;br /&gt;
| Windows Client || 2 || 4 GB || 40 GB || Can be replaced with thin Linux client&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu Server || 1 || 1 GB || 10 GB || DNS/web/target server&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;Internet&amp;quot; Router || 1 || 512 MB || 4 GB || Simulated upstream ISP&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total (minimal)&#039;&#039;&#039; || &#039;&#039;&#039;6&#039;&#039;&#039; || &#039;&#039;&#039;6.5 GB&#039;&#039;&#039; || &#039;&#039;&#039;62 GB&#039;&#039;&#039; || 2 firewalls + 1 client + 1 server + internet&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Total (full lab)&#039;&#039;&#039; || &#039;&#039;&#039;10&#039;&#039;&#039; || &#039;&#039;&#039;10.5 GB&#039;&#039;&#039; || &#039;&#039;&#039;110 GB&#039;&#039;&#039; || 4 firewalls + 2 clients + 2 servers + internet&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cluster capacity (200 core / 1 TB RAM):&#039;&#039;&#039;&lt;br /&gt;
* Conservative (10 cores + 10 GB per student): ~20 concurrent students&lt;br /&gt;
* Optimized (6 cores + 6.5 GB per student): ~30 concurrent students&lt;br /&gt;
* With memory overcommit and thin-provisioned disks: potentially 40+ students&lt;br /&gt;
&lt;br /&gt;
=== Zero-Touch Provisioning / Infra-as-Code Strategy ===&lt;br /&gt;
Given constrained materials (old PCs, limited budget), the deployment stack should be:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option A: KVM + Ansible (Recommended for Comfac)&#039;&#039;&#039;&lt;br /&gt;
* KVM/libvirt on Ubuntu host&lt;br /&gt;
* qcow2 base images for pfSense, Windows, Ubuntu&lt;br /&gt;
* Ansible playbooks per lab:&lt;br /&gt;
** Clone base images (linked clones for disk efficiency)&lt;br /&gt;
** Configure VLANs/internal networks via libvirt&lt;br /&gt;
** Start VMs in correct order&lt;br /&gt;
** Inject pfSense config.xml for each lab stage&lt;br /&gt;
* NoVNC via &#039;&#039;&#039;Kimchi&#039;&#039;&#039; or &#039;&#039;&#039;Apache Guacamole&#039;&#039;&#039; as the web portal&lt;br /&gt;
* Students get a unique URL + credentials; VMs are destroyed/re-created per session&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option B: Docker + GNS3/EVE-NG (Alternative)&#039;&#039;&#039;&lt;br /&gt;
* pfSense can run in QEMU inside Docker&lt;br /&gt;
* More complex networking; less stable than KVM&lt;br /&gt;
* Better for Cisco/Juniper labs, not ideal for pfSense web-GUI training&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option C: Proxmox VE Cluster (If hardware allows)&#039;&#039;&#039;&lt;br /&gt;
* Best UX but requires dedicated Proxmox host(s)&lt;br /&gt;
* Good for the 200-core machine, not for old PCs&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Chosen Path for Comfac: Option A (KVM/Ansible)&#039;&#039;&#039;&lt;br /&gt;
* Old PCs become thin clients (any PC with a browser)&lt;br /&gt;
* Heavy lifting happens on the 200-core host&lt;br /&gt;
* Ansible manages:&lt;br /&gt;
** VM lifecycle (create/start/stop/destroy)&lt;br /&gt;
** Network topology (bridges, VLANs, isolated libvirt networks)&lt;br /&gt;
** Student access (NoVNC tokens, time limits)&lt;br /&gt;
** Snapshot/reset between sessions&lt;br /&gt;
&lt;br /&gt;
=== Training Phases / Legs (1 Hour Per Day) ===&lt;br /&gt;
The FUND001 curriculum is broken into digestible daily modules.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Phase !! Day !! Topic !! Slide !! Lab !! VMs Required&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &#039;&#039;&#039;Phase 1: Foundations&#039;&#039;&#039; || 1 || Intro to pfSense: What, Why, History, Certifications || SEG1 || — || —&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Interfaces, IPs, VLANs, Virtual IPs || SEG2 || Lab 1 (Intro + Backup/Restore) || 1 pfSense + 1 client&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Firewall Rules, Aliases, Best Practices || SEG2 || Lab 2 (Rules + Aliases) || 1 pfSense + 1 client + 1 server&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | &#039;&#039;&#039;Phase 2: NAT &amp;amp; Services&#039;&#039;&#039; || 4 || NAT Overview: Outbound, Port Forwards, 1:1 NAT || SEG3 || Lab 3 (NAT + VIPs) || 1 pfSense + 1 server + internet&lt;br /&gt;
|-&lt;br /&gt;
| 5 || DHCP, DNS Resolver, Dynamic DNS, NTP || SEG4 || Lab 4 (Services + Branch Setup) || 2 pfSense + 2 clients + 1 server&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Package System, Common Packages (pfBlocker, Suricata intro) || SEG11 || — || 1 pfSense&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | &#039;&#039;&#039;Phase 3: VPNs&#039;&#039;&#039; || 7 || VPN Concepts: IPsec, OpenVPN, WireGuard compared || SEG5 || — || —&lt;br /&gt;
|-&lt;br /&gt;
| 8 || IPsec Site-to-Site + Mobile Remote Access || SEG5 || Lab 5 (IPsec) || 2 pfSense + 2 clients&lt;br /&gt;
|-&lt;br /&gt;
| 9 || OpenVPN Site-to-Site + Remote Access with Client Export || SEG6 || Lab 6 (OpenVPN) || 2 pfSense + 2 clients&lt;br /&gt;
|-&lt;br /&gt;
| 10 || WireGuard Site-to-Site || SEG7 || Lab 7 (WireGuard) || 2 pfSense + 2 clients&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &#039;&#039;&#039;Phase 4: Resilience&#039;&#039;&#039; || 11 || Multi-WAN: Failover, Load Balancing, Gateway Groups || SEG8 || Lab 8 (Multi-WAN) || 1 pfSense + 2 WANs + client&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Traffic Shaping &amp;amp; Limiters (ALTQ + dummynet) || SEG9 || Lab 9 (Traffic Shaping) || 1 pfSense + multiple clients&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | &#039;&#039;&#039;Phase 5: Advanced&#039;&#039;&#039; || 13 || High Availability: CARP, XMLRPC, pfsync || SEG10 || Lab 10 (HA) || 2 pfSense (HA pair) + client&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Monitoring, SNMP, RRD, Log Aggregation, Packages || SEG11 || — || 1 pfSense + monitoring target&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Phase 6: Capstone&#039;&#039;&#039; || 15 || Build Your Own Firewall: Design, Implement, Present || — || Capstone || Full lab (4 pfSense + clients + servers)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sub-Phases for Comfac Internal Use (ZTP/IaC Focus) ===&lt;br /&gt;
These are shorter, targeted sessions for staff who will build and maintain the training platform.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sub-Phase !! Topic !! Duration !! Deliverable&lt;br /&gt;
|-&lt;br /&gt;
| A.1 || KVM/libvirt Setup on 200-Core Host || 2 hrs || Host provisioned with bridges and storage pools&lt;br /&gt;
|-&lt;br /&gt;
| A.2 || Base Image Creation: pfSense, Windows, Ubuntu || 2 hrs || qcow2 golden images ready for cloning&lt;br /&gt;
|-&lt;br /&gt;
| A.3 || Ansible Playbook: Lab 1 Environment || 3 hrs || `ansible-playbook lab1.yml --extra-vars student_id=01`&lt;br /&gt;
|-&lt;br /&gt;
| A.4 || NoVNC Portal: Kimchi or Guacamole Integration || 3 hrs || Browser-based console access working&lt;br /&gt;
|-&lt;br /&gt;
| A.5 || Automated Cleanup &amp;amp; Snapshot Reset || 2 hrs || VMs destroyed/recreated between sessions&lt;br /&gt;
|-&lt;br /&gt;
| A.6 || Monitoring &amp;amp; Quota: Per-Student Resource Limits || 2 hrs || cgroups/libvirt quotas enforced&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Required Containers / VMs Summary ===&lt;br /&gt;
&#039;&#039;&#039;Per-Lab VM Inventory&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Lab !! pfSense !! Clients !! Servers !! Internet Router !! Total vCPUs !! Total RAM&lt;br /&gt;
|-&lt;br /&gt;
| Lab 1 (Intro) || 1 || 1 || 0 || 0 || 4 || 5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 2 (Rules) || 1 || 1 || 1 || 0 || 5 || 6 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 3 (NAT/VIP) || 1 || 0 || 1 || 1 || 5 || 6.5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 4 (Services) || 2 || 2 || 1 || 0 || 10 || 13 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 5 (IPsec) || 2 || 2 || 0 || 0 || 10 || 12 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 6 (OpenVPN) || 2 || 2 || 0 || 0 || 10 || 12 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 7 (WireGuard) || 2 || 2 || 0 || 0 || 10 || 12 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 8 (Multi-WAN) || 1 || 1 || 0 || 1 || 5 || 6.5 GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 9 (Shaping) || 1 || 2+ || 0 || 0 || 6+ || 9+ GB&lt;br /&gt;
|-&lt;br /&gt;
| Lab 10 (HA) || 2 || 1 || 0 || 0 || 6 || 7 GB&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Capstone&#039;&#039;&#039; || &#039;&#039;&#039;4&#039;&#039;&#039; || &#039;&#039;&#039;2&#039;&#039;&#039; || &#039;&#039;&#039;2&#039;&#039;&#039; || &#039;&#039;&#039;1&#039;&#039;&#039; || &#039;&#039;&#039;18&#039;&#039;&#039; || &#039;&#039;&#039;21 GB&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Containerization Notes:&#039;&#039;&#039;&lt;br /&gt;
* pfSense runs on FreeBSD; must use full KVM virtualization (not containers)&lt;br /&gt;
* Clients can be Linux containers (LXC) if only CLI/SSH access needed; Windows requires KVM&lt;br /&gt;
* NoVNC proxy can run in Docker for easy deployment&lt;br /&gt;
* Ansible controller can be a Docker container or the host itself&lt;br /&gt;
&lt;br /&gt;
== Related Infrastructure ==&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]] — Server migration and infrastructure hardening&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]] — Self-hosted email infrastructure context&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]] — Email server deployment&lt;br /&gt;
* [[Portainer to Docker Compose Migration Guide]] — Container orchestration for network services&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&#039;&#039;This index consolidates networking resources previously scattered across the [[Main Page]]. Last updated: 260423.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=221</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=221"/>
		<updated>2026-04-23T06:08:47Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Consolidate networking links into Networking PfSense Index&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f8f9fa; border:1px solid #ddd; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
Welcome to the &#039;&#039;&#039;Comfac IT Knowledge Base&#039;&#039;&#039;. Use the sections below to find guides, SOPs, and references organized by topic.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ERPNext / Frappe ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Frappe HRMS]] — &#039;&#039;&#039;HR &amp;amp; Payroll&#039;&#039;&#039; (with Philippine Localization)&lt;br /&gt;
* [[Frappe ERPNext/Webshop]] — &#039;&#039;&#039;E-Commerce Webshop&#039;&#039;&#039; (setup, architecture, chapters)&lt;br /&gt;
* [[Manufacturing v16 260125]]&lt;br /&gt;
* [[ERpnext Asset Management Procedure 260113]]&lt;br /&gt;
* [[ERPNext HR Module Outline]]&lt;br /&gt;
* [[ERPNEXT Payroll POC 251212]]&lt;br /&gt;
* [[Comfac ERPNext Strategy Canvas (Expanded)]]&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — PAD/AI-agentic implementation strategy for Frappe ERPNext&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — Local Docker setup for evaluation, testing, and student use&lt;br /&gt;
* [[Frappe Links and References]]&lt;br /&gt;
* [[Using Frappe Wiki]]&lt;br /&gt;
* [https://docs.frappe.io/cloud/guidelines-for-contributing-regional-compliance-app Guidelines for Contributing Regional Compliance App]&lt;br /&gt;
* [https://docs.frappe.io/cloud/what-are-benches-and-bench-groups What are Benches?]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Administration &amp;amp; Self-Hosting ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Networking PfSense Index]] — Consolidated index of all networking, pfSense, DNS, and infrastructure guides&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]]&lt;br /&gt;
* [[Controller Systems 251213-01]]&lt;br /&gt;
* [[Power Distribution Tree 251213]]&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]]&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]]&lt;br /&gt;
* [[Mailcow SOGo: Creating Filters for Events, Approvals, and Organizational Emails]]&lt;br /&gt;
* [[Spoof Timezone Extension – Setup Guide for Comfac Staff]]&lt;br /&gt;
* [[Viber Focus-Stealing]]&lt;br /&gt;
* [[🌐 WordPress Website — *You Own Everything, Learn Everything*]]&lt;br /&gt;
* [[Portainer to Docker Compose Migration Guide]]&lt;br /&gt;
* [[Editing Mastodon Docker Deployment Guide 260402]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Storage &amp;amp; Hardware ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[TrueNAS Configuration Options &amp;amp; Scale Options 251130]]&lt;br /&gt;
* [[TrueNAS Business Plan: Project 251212]]&lt;br /&gt;
* [[Comparison: TrueNAS Mini X+ vs Dell Precision 3680 Tower (2025)]]&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification]]&lt;br /&gt;
* [[Industrial Controllers and Water Utilities 251011]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== AI &amp;amp; Machine Learning ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[OpenWebUI - 251128-justin]]&lt;br /&gt;
* [[Comfac GPU Scaling and AI Research Goals]]&lt;br /&gt;
* [[🧠 Process: Selecting and Installing the Right Ollama Model for Your Hardware]]&lt;br /&gt;
* [[Ollama GNOME System Tray Panel 260401]] — GNOME system tray toggle to start/stop Ollama and reclaim VRAM&lt;br /&gt;
* [[Proceedural Agentic Development Methodology 260304]] — Methodology for systematic agent use&lt;br /&gt;
* [[Project OpenCoder: AI Independence Initiative]] — Strategic roadmap for manufacturing intelligence&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 Modelfile fix for tool calling in OpenCode; thinking mode suppression; HDD vs SSD findings&lt;br /&gt;
* [[OpenCode Multi-Provider Configuration Guide 260401]] — Dual-mode AI coding setup with Kimi cloud + Ollama local models via Distrobox&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — Procedural Agentic Development for Frappe/ERPNext configuration and deployment&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Descriptions ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Job Descriptions]] — Index of all official job descriptions (IT, Engineering, Sales)&lt;br /&gt;
* [[JD IT Project Staff]] — IT Project Staff&lt;br /&gt;
* [[JD Security Compliance Assistant 260224]] — Security and Compliance Assistant (SCA)&lt;br /&gt;
* [[JD Engineering Designer 260108]] — Engineering Designer&lt;br /&gt;
* [[JD Engineering Supervisor 260109]] — Engineering Supervisor&lt;br /&gt;
* [[JD Technical Sales 260112]] — Technical Sales Engineer&lt;br /&gt;
* [[JD Marketing Assistant 251119]] — Marketing Assistant&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IT Operations &amp;amp; SOPs ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[SCA Program Plan 260320]] — Security &amp;amp; Compliance Assistant Program Plan v3 (ISO 9001/27001, PDCA, distributed audit model)&lt;br /&gt;
* [[SOP: Inter-Company Ordering and Production Process 260203]] — Ordering and production workflow between Sister Companies and the Cabuyao Plant&lt;br /&gt;
* [[Memo: Team Roles &amp;amp; Reporting Process Clarification 260320]] — Role boundaries, data ownership, and the new ERPNext-driven reporting paradigm&lt;br /&gt;
* [[Standard Operating Procedure: Distributed Minute Taking &amp;amp; Task Ownership 251208]]&lt;br /&gt;
* [[Business Continuity]]&lt;br /&gt;
* [[Procedure: CC-Blast Data Breach Prevention]]&lt;br /&gt;
* [[8D (Eight Discipline) Problem Solving Procedure]]&lt;br /&gt;
* [[Offline Malware Remediation &amp;amp; Data Recovery]]&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [[Steps to Repair and OCR a Scanned or Corrupted PDF in Ubuntu]]&lt;br /&gt;
* [[IT IMPORTS PROCESSES]]&lt;br /&gt;
* [[IT Purchase Requests 241126]]&lt;br /&gt;
* [[IT REQUEST (OP-ERP-ITR) - EDITED 250801]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sales &amp;amp; Business ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Comfac Sales Knowledge Base]]&lt;br /&gt;
* [[Comfac CRM – Customer Qualification &amp;amp; Conversion Process]]&lt;br /&gt;
* [[Partner Reseller Pricing 251109]]&lt;br /&gt;
* [[Biz Analysis Methodology 251109]]&lt;br /&gt;
* [[2026 MIS IT KRA KPI Biz Plan]]&lt;br /&gt;
* [[SALES INVOICE TAX OUTPUT 250829]]&lt;br /&gt;
* [[Projects in Process Report 251023]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools &amp;amp; Productivity ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Excel Description Filler Tool 📝]]&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/comfac-studies Comfac Studies - Spaced Repetiton Active Recall]&lt;br /&gt;
* [[LibreOffice / Nextcloud Office – &amp;quot;Due Tasks&amp;quot; Conditional Formatting]]&lt;br /&gt;
* [[Google Drive and Shared Drive Training]]&lt;br /&gt;
* [[260108 CGG- GitHub Administration Guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wiki &amp;amp; Documentation ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Mediawiki Setting Up Guide]]&lt;br /&gt;
* [[Contributing to Only Office 260307]]&lt;br /&gt;
* [[Mediawiki Additional Configuration]]&lt;br /&gt;
* [[Mediawiki Docker Migration Guide]]&lt;br /&gt;
* [[Home]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Claude Code Isolation and Burner Workflow 260211]] — Secure AI development environment setup&lt;br /&gt;
* [[Opencode isolation and burner workflow 260216]] — OpenCode CLI isolation procedures&lt;br /&gt;
* [[LibreOffice Calc NumToWords Extension Complete Guide]] — Extension development&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — ERPNext v15 local Docker setup (students, evaluators, thin-client demos)&lt;br /&gt;
* [[Erpnextv15-SSH-setup-241111]] — ERPNext v15 SSH/Portainer production setup&lt;br /&gt;
* [[Git-Mediawiki Local Editing 260223]] — Wiki editing with Git&lt;br /&gt;
* [[Understanding &amp;amp; Fixing Kernel Panics 260212]] — System debugging&lt;br /&gt;
* [[OpenCode in Android Termux 260303]] — OpenCode in Android&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 agentic setup: Modelfile, tool calling fix, storage impact&lt;br /&gt;
* [[Lora Basics 260304]] — LORA research&lt;br /&gt;
* [https://github.com/anomalyco/opencode/issues/4283#issuecomment-4083399210 Opencode Copy-paste Clipboard doesnt Work - Solution]   https://github.com/anomalyco/opencode/issues/4283#issuecomment-4083399210&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Research ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Ladybird Browser]] — Browser engine development&lt;br /&gt;
* [[Computing Architecture]] — System design principles&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification 260219]] — Drive reliability analysis&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== For Users Only ==&lt;br /&gt;
* [[Private:Private Ngani]]&lt;br /&gt;
* [[Private:Private Nganipart2]]&lt;br /&gt;
&lt;br /&gt;
== CIT-OJT Project Documentations ==&lt;br /&gt;
* [[OJTDocs: For OJTs only]]&lt;br /&gt;
&lt;br /&gt;
== Need Help? ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents MediaWiki User&#039;s Guide]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=220</id>
		<title>Networking PfSense Index</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Networking_PfSense_Index&amp;diff=220"/>
		<updated>2026-04-23T06:06:49Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Create consolidated Networking PfSense Index&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f0f7ff; border:1px solid #b8d4f0; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Consolidated index&#039;&#039;&#039; for all networking infrastructure guides, pfSense documentation, DNS/ad-blocking resources, and network equipment references at Comfac IT.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== pfSense Core Guides ==&lt;br /&gt;
* [[pfSense Sales Training Material]] — Product knowledge and sales positioning for Netgate/pfSense hardware and software&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS \&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=219</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=219"/>
		<updated>2026-04-06T13:38:30Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: /* Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f8f9fa; border:1px solid #ddd; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
Welcome to the &#039;&#039;&#039;Comfac IT Knowledge Base&#039;&#039;&#039;. Use the sections below to find guides, SOPs, and references organized by topic.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ERPNext / Frappe ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Frappe HRMS]] — &#039;&#039;&#039;HR &amp;amp; Payroll&#039;&#039;&#039; (with Philippine Localization)&lt;br /&gt;
* [[Frappe ERPNext/Webshop]] — &#039;&#039;&#039;E-Commerce Webshop&#039;&#039;&#039; (setup, architecture, chapters)&lt;br /&gt;
* [[Manufacturing v16 260125]]&lt;br /&gt;
* [[ERpnext Asset Management Procedure 260113]]&lt;br /&gt;
* [[ERPNext HR Module Outline]]&lt;br /&gt;
* [[ERPNEXT Payroll POC 251212]]&lt;br /&gt;
* [[Comfac ERPNext Strategy Canvas (Expanded)]]&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — PAD/AI-agentic implementation strategy for Frappe ERPNext&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — Local Docker setup for evaluation, testing, and student use&lt;br /&gt;
* [[Frappe Links and References]]&lt;br /&gt;
* [[Using Frappe Wiki]]&lt;br /&gt;
* [https://docs.frappe.io/cloud/guidelines-for-contributing-regional-compliance-app Guidelines for Contributing Regional Compliance App]&lt;br /&gt;
* [https://docs.frappe.io/cloud/what-are-benches-and-bench-groups What are Benches?]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Administration &amp;amp; Self-Hosting ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[NPM Migration to Homelab VPS Relay 260401]] — Move NPM off a compromised VPS; VPS becomes a pure iptables/ZeroTier relay with homelab redundancy&lt;br /&gt;
* [[pfSense Sales Training Material]]&lt;br /&gt;
* [[SOP: Network Troubleshooting &amp;amp; pfSense Monitoring 251130]]&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS &amp;amp; ACME]]&lt;br /&gt;
* [[pfSense CE → pfSense Plus Upgrade Guide]]&lt;br /&gt;
* [[Tplink Mikrotik Equivalent]]&lt;br /&gt;
* [[Skills and Competencies for IT Staff Trained in pfSense]]&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]]&lt;br /&gt;
* [[Controller Systems 251213-01]]&lt;br /&gt;
* [[Power Distribution Tree 251213]]&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]]&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]]&lt;br /&gt;
* [[Mailcow SOGo: Creating Filters for Events, Approvals, and Organizational Emails]]&lt;br /&gt;
* [[Spoof Timezone Extension – Setup Guide for Comfac Staff]]&lt;br /&gt;
* [[Viber Focus-Stealing]]&lt;br /&gt;
* [[🌐 WordPress Website — *You Own Everything, Learn Everything*]]&lt;br /&gt;
* [[Portainer to Docker Compose Migration Guide]]&lt;br /&gt;
* [[Editing Mastodon Docker Deployment Guide 260402]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Storage &amp;amp; Hardware ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[TrueNAS Configuration Options &amp;amp; Scale Options 251130]]&lt;br /&gt;
* [[TrueNAS Business Plan: Project 251212]]&lt;br /&gt;
* [[Comparison: TrueNAS Mini X+ vs Dell Precision 3680 Tower (2025)]]&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification]]&lt;br /&gt;
* [[Industrial Controllers and Water Utilities 251011]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== AI &amp;amp; Machine Learning ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[OpenWebUI - 251128-justin]]&lt;br /&gt;
* [[Comfac GPU Scaling and AI Research Goals]]&lt;br /&gt;
* [[🧠 Process: Selecting and Installing the Right Ollama Model for Your Hardware]]&lt;br /&gt;
* [[Ollama GNOME System Tray Panel 260401]] — GNOME system tray toggle to start/stop Ollama and reclaim VRAM&lt;br /&gt;
* [[Proceedural Agentic Development Methodology 260304]] — Methodology for systematic agent use&lt;br /&gt;
* [[Project OpenCoder: AI Independence Initiative]] — Strategic roadmap for manufacturing intelligence&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 Modelfile fix for tool calling in OpenCode; thinking mode suppression; HDD vs SSD findings&lt;br /&gt;
* [[OpenCode Multi-Provider Configuration Guide 260401]] — Dual-mode AI coding setup with Kimi cloud + Ollama local models via Distrobox&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — Procedural Agentic Development for Frappe/ERPNext configuration and deployment&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Descriptions ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Job Descriptions]] — Index of all official job descriptions (IT, Engineering, Sales)&lt;br /&gt;
* [[JD IT Project Staff]] — IT Project Staff&lt;br /&gt;
* [[JD Security Compliance Assistant 260224]] — Security and Compliance Assistant (SCA)&lt;br /&gt;
* [[JD Engineering Designer 260108]] — Engineering Designer&lt;br /&gt;
* [[JD Engineering Supervisor 260109]] — Engineering Supervisor&lt;br /&gt;
* [[JD Technical Sales 260112]] — Technical Sales Engineer&lt;br /&gt;
* [[JD Marketing Assistant 251119]] — Marketing Assistant&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IT Operations &amp;amp; SOPs ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[SCA Program Plan 260320]] — Security &amp;amp; Compliance Assistant Program Plan v3 (ISO 9001/27001, PDCA, distributed audit model)&lt;br /&gt;
* [[SOP: Inter-Company Ordering and Production Process 260203]] — Ordering and production workflow between Sister Companies and the Cabuyao Plant&lt;br /&gt;
* [[Memo: Team Roles &amp;amp; Reporting Process Clarification 260320]] — Role boundaries, data ownership, and the new ERPNext-driven reporting paradigm&lt;br /&gt;
* [[Standard Operating Procedure: Distributed Minute Taking &amp;amp; Task Ownership 251208]]&lt;br /&gt;
* [[Business Continuity]]&lt;br /&gt;
* [[Procedure: CC-Blast Data Breach Prevention]]&lt;br /&gt;
* [[8D (Eight Discipline) Problem Solving Procedure]]&lt;br /&gt;
* [[Offline Malware Remediation &amp;amp; Data Recovery]]&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [[Steps to Repair and OCR a Scanned or Corrupted PDF in Ubuntu]]&lt;br /&gt;
* [[IT IMPORTS PROCESSES]]&lt;br /&gt;
* [[IT Purchase Requests 241126]]&lt;br /&gt;
* [[IT REQUEST (OP-ERP-ITR) - EDITED 250801]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sales &amp;amp; Business ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Comfac Sales Knowledge Base]]&lt;br /&gt;
* [[Comfac CRM – Customer Qualification &amp;amp; Conversion Process]]&lt;br /&gt;
* [[Partner Reseller Pricing 251109]]&lt;br /&gt;
* [[Biz Analysis Methodology 251109]]&lt;br /&gt;
* [[2026 MIS IT KRA KPI Biz Plan]]&lt;br /&gt;
* [[SALES INVOICE TAX OUTPUT 250829]]&lt;br /&gt;
* [[Projects in Process Report 251023]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools &amp;amp; Productivity ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Excel Description Filler Tool 📝]]&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/comfac-studies Comfac Studies - Spaced Repetiton Active Recall]&lt;br /&gt;
* [[LibreOffice / Nextcloud Office – &amp;quot;Due Tasks&amp;quot; Conditional Formatting]]&lt;br /&gt;
* [[Google Drive and Shared Drive Training]]&lt;br /&gt;
* [[260108 CGG- GitHub Administration Guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wiki &amp;amp; Documentation ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Mediawiki Setting Up Guide]]&lt;br /&gt;
* [[Contributing to Only Office 260307]]&lt;br /&gt;
* [[Mediawiki Additional Configuration]]&lt;br /&gt;
* [[Mediawiki Docker Migration Guide]]&lt;br /&gt;
* [[Home]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Claude Code Isolation and Burner Workflow 260211]] — Secure AI development environment setup&lt;br /&gt;
* [[Opencode isolation and burner workflow 260216]] — OpenCode CLI isolation procedures&lt;br /&gt;
* [[LibreOffice Calc NumToWords Extension Complete Guide]] — Extension development&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — ERPNext v15 local Docker setup (students, evaluators, thin-client demos)&lt;br /&gt;
* [[Erpnextv15-SSH-setup-241111]] — ERPNext v15 SSH/Portainer production setup&lt;br /&gt;
* [[Git-Mediawiki Local Editing 260223]] — Wiki editing with Git&lt;br /&gt;
* [[Understanding &amp;amp; Fixing Kernel Panics 260212]] — System debugging&lt;br /&gt;
* [[OpenCode in Android Termux 260303]] — OpenCode in Android&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 agentic setup: Modelfile, tool calling fix, storage impact&lt;br /&gt;
* [[Lora Basics 260304]] — LORA research&lt;br /&gt;
* [https://github.com/anomalyco/opencode/issues/4283#issuecomment-4083399210 Opencode Copy-paste Clipboard doesnt Work - Solution]   https://github.com/anomalyco/opencode/issues/4283#issuecomment-4083399210&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Research ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Ladybird Browser]] — Browser engine development&lt;br /&gt;
* [[Computing Architecture]] — System design principles&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification 260219]] — Drive reliability analysis&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== For Users Only ==&lt;br /&gt;
* [[Private:Private Ngani]]&lt;br /&gt;
* [[Private:Private Nganipart2]]&lt;br /&gt;
&lt;br /&gt;
== CIT-OJT Project Documentations ==&lt;br /&gt;
* [[OJTDocs: For OJTs only]]&lt;br /&gt;
&lt;br /&gt;
== Need Help? ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents MediaWiki User&#039;s Guide]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=218</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=218"/>
		<updated>2026-04-02T12:08:47Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: /* System Administration &amp;amp; Self-Hosting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f8f9fa; border:1px solid #ddd; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
Welcome to the &#039;&#039;&#039;Comfac IT Knowledge Base&#039;&#039;&#039;. Use the sections below to find guides, SOPs, and references organized by topic.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ERPNext / Frappe ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Frappe HRMS]] — &#039;&#039;&#039;HR &amp;amp; Payroll&#039;&#039;&#039; (with Philippine Localization)&lt;br /&gt;
* [[Frappe ERPNext/Webshop]] — &#039;&#039;&#039;E-Commerce Webshop&#039;&#039;&#039; (setup, architecture, chapters)&lt;br /&gt;
* [[Manufacturing v16 260125]]&lt;br /&gt;
* [[ERpnext Asset Management Procedure 260113]]&lt;br /&gt;
* [[ERPNext HR Module Outline]]&lt;br /&gt;
* [[ERPNEXT Payroll POC 251212]]&lt;br /&gt;
* [[Comfac ERPNext Strategy Canvas (Expanded)]]&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — PAD/AI-agentic implementation strategy for Frappe ERPNext&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — Local Docker setup for evaluation, testing, and student use&lt;br /&gt;
* [[Frappe Links and References]]&lt;br /&gt;
* [[Using Frappe Wiki]]&lt;br /&gt;
* [https://docs.frappe.io/cloud/guidelines-for-contributing-regional-compliance-app Guidelines for Contributing Regional Compliance App]&lt;br /&gt;
* [https://docs.frappe.io/cloud/what-are-benches-and-bench-groups What are Benches?]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Administration &amp;amp; Self-Hosting ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[NPM Migration to Homelab VPS Relay 260401]] — Move NPM off a compromised VPS; VPS becomes a pure iptables/ZeroTier relay with homelab redundancy&lt;br /&gt;
* [[pfSense Sales Training Material]]&lt;br /&gt;
* [[SOP: Network Troubleshooting &amp;amp; pfSense Monitoring 251130]]&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS &amp;amp; ACME]]&lt;br /&gt;
* [[pfSense CE → pfSense Plus Upgrade Guide]]&lt;br /&gt;
* [[Tplink Mikrotik Equivalent]]&lt;br /&gt;
* [[Skills and Competencies for IT Staff Trained in pfSense]]&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]]&lt;br /&gt;
* [[Controller Systems 251213-01]]&lt;br /&gt;
* [[Power Distribution Tree 251213]]&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]]&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]]&lt;br /&gt;
* [[Mailcow SOGo: Creating Filters for Events, Approvals, and Organizational Emails]]&lt;br /&gt;
* [[Spoof Timezone Extension – Setup Guide for Comfac Staff]]&lt;br /&gt;
* [[Viber Focus-Stealing]]&lt;br /&gt;
* [[🌐 WordPress Website — *You Own Everything, Learn Everything*]]&lt;br /&gt;
* [[Portainer to Docker Compose Migration Guide]]&lt;br /&gt;
* [[Editing Mastodon Docker Deployment Guide 260402]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Storage &amp;amp; Hardware ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[TrueNAS Configuration Options &amp;amp; Scale Options 251130]]&lt;br /&gt;
* [[TrueNAS Business Plan: Project 251212]]&lt;br /&gt;
* [[Comparison: TrueNAS Mini X+ vs Dell Precision 3680 Tower (2025)]]&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification]]&lt;br /&gt;
* [[Industrial Controllers and Water Utilities 251011]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== AI &amp;amp; Machine Learning ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[OpenWebUI - 251128-justin]]&lt;br /&gt;
* [[Comfac GPU Scaling and AI Research Goals]]&lt;br /&gt;
* [[🧠 Process: Selecting and Installing the Right Ollama Model for Your Hardware]]&lt;br /&gt;
* [[Ollama GNOME System Tray Panel 260401]] — GNOME system tray toggle to start/stop Ollama and reclaim VRAM&lt;br /&gt;
* [[Proceedural Agentic Development Methodology 260304]] — Methodology for systematic agent use&lt;br /&gt;
* [[Project OpenCoder: AI Independence Initiative]] — Strategic roadmap for manufacturing intelligence&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 Modelfile fix for tool calling in OpenCode; thinking mode suppression; HDD vs SSD findings&lt;br /&gt;
* [[OpenCode Multi-Provider Configuration Guide 260401]] — Dual-mode AI coding setup with Kimi cloud + Ollama local models via Distrobox&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — Procedural Agentic Development for Frappe/ERPNext configuration and deployment&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Descriptions ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Job Descriptions]] — Index of all official job descriptions (IT, Engineering, Sales)&lt;br /&gt;
* [[JD IT Project Staff]] — IT Project Staff&lt;br /&gt;
* [[JD Security Compliance Assistant 260224]] — Security and Compliance Assistant (SCA)&lt;br /&gt;
* [[JD Engineering Designer 260108]] — Engineering Designer&lt;br /&gt;
* [[JD Engineering Supervisor 260109]] — Engineering Supervisor&lt;br /&gt;
* [[JD Technical Sales 260112]] — Technical Sales Engineer&lt;br /&gt;
* [[JD Marketing Assistant 251119]] — Marketing Assistant&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IT Operations &amp;amp; SOPs ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[SCA Program Plan 260320]] — Security &amp;amp; Compliance Assistant Program Plan v3 (ISO 9001/27001, PDCA, distributed audit model)&lt;br /&gt;
* [[SOP: Inter-Company Ordering and Production Process 260203]] — Ordering and production workflow between Sister Companies and the Cabuyao Plant&lt;br /&gt;
* [[Memo: Team Roles &amp;amp; Reporting Process Clarification 260320]] — Role boundaries, data ownership, and the new ERPNext-driven reporting paradigm&lt;br /&gt;
* [[Standard Operating Procedure: Distributed Minute Taking &amp;amp; Task Ownership 251208]]&lt;br /&gt;
* [[Business Continuity]]&lt;br /&gt;
* [[Procedure: CC-Blast Data Breach Prevention]]&lt;br /&gt;
* [[8D (Eight Discipline) Problem Solving Procedure]]&lt;br /&gt;
* [[Offline Malware Remediation &amp;amp; Data Recovery]]&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [[Steps to Repair and OCR a Scanned or Corrupted PDF in Ubuntu]]&lt;br /&gt;
* [[IT IMPORTS PROCESSES]]&lt;br /&gt;
* [[IT Purchase Requests 241126]]&lt;br /&gt;
* [[IT REQUEST (OP-ERP-ITR) - EDITED 250801]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sales &amp;amp; Business ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Comfac Sales Knowledge Base]]&lt;br /&gt;
* [[Comfac CRM – Customer Qualification &amp;amp; Conversion Process]]&lt;br /&gt;
* [[Partner Reseller Pricing 251109]]&lt;br /&gt;
* [[Biz Analysis Methodology 251109]]&lt;br /&gt;
* [[2026 MIS IT KRA KPI Biz Plan]]&lt;br /&gt;
* [[SALES INVOICE TAX OUTPUT 250829]]&lt;br /&gt;
* [[Projects in Process Report 251023]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools &amp;amp; Productivity ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Excel Description Filler Tool 📝]]&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/comfac-studies Comfac Studies - Spaced Repetiton Active Recall]&lt;br /&gt;
* [[LibreOffice / Nextcloud Office – &amp;quot;Due Tasks&amp;quot; Conditional Formatting]]&lt;br /&gt;
* [[Google Drive and Shared Drive Training]]&lt;br /&gt;
* [[260108 CGG- GitHub Administration Guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wiki &amp;amp; Documentation ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Mediawiki Setting Up Guide]]&lt;br /&gt;
* [[Contributing to Only Office 260307]]&lt;br /&gt;
* [[Mediawiki Additional Configuration]]&lt;br /&gt;
* [[Mediawiki Docker Migration Guide]]&lt;br /&gt;
* [[Home]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Claude Code Isolation and Burner Workflow 260211]] — Secure AI development environment setup&lt;br /&gt;
* [[Opencode isolation and burner workflow 260216]] — OpenCode CLI isolation procedures&lt;br /&gt;
* [[LibreOffice Calc NumToWords Extension Complete Guide]] — Extension development&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — ERPNext v15 local Docker setup (students, evaluators, thin-client demos)&lt;br /&gt;
* [[Erpnextv15-SSH-setup-241111]] — ERPNext v15 SSH/Portainer production setup&lt;br /&gt;
* [[Git-Mediawiki Local Editing 260223]] — Wiki editing with Git&lt;br /&gt;
* [[Understanding &amp;amp; Fixing Kernel Panics 260212]] — System debugging&lt;br /&gt;
* [[OpenCode in Android Termux 260303]] — OpenCode in Android&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 agentic setup: Modelfile, tool calling fix, storage impact&lt;br /&gt;
* [[Lora Basics 260304]] — LORA research&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Research ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Ladybird Browser]] — Browser engine development&lt;br /&gt;
* [[Computing Architecture]] — System design principles&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification 260219]] — Drive reliability analysis&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== For Users Only ==&lt;br /&gt;
* [[Private:Private Ngani]]&lt;br /&gt;
* [[Private:Private Nganipart2]]&lt;br /&gt;
&lt;br /&gt;
== CIT-OJT Project Documentations ==&lt;br /&gt;
* [[OJTDocs: For OJTs only]]&lt;br /&gt;
&lt;br /&gt;
== Need Help? ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents MediaWiki User&#039;s Guide]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Editing_Mastodon_Docker_Deployment_Guide_260402&amp;diff=217</id>
		<title>Editing Mastodon Docker Deployment Guide 260402</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Editing_Mastodon_Docker_Deployment_Guide_260402&amp;diff=217"/>
		<updated>2026-04-02T12:08:27Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created page with &amp;quot;= Mastodon on Docker — Self-Hosted Deployment Guide =  &amp;#039;&amp;#039;&amp;#039;Behind Nginx Proxy Manager with Let&amp;#039;s Encrypt SSL&amp;#039;&amp;#039;&amp;#039;  Using linuxserver.io image | Ubuntu 24 | Docker Compose  {{Tip|This guide is written so that a thinking model AI agent (such as one running on your local server via Ollama/Open WebUI) can follow these instructions step-by-step and get Mastodon running without human intervention. Every command is verified against a successful real-world deployment. Verify all...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Mastodon on Docker — Self-Hosted Deployment Guide =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behind Nginx Proxy Manager with Let&#039;s Encrypt SSL&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using linuxserver.io image | Ubuntu 24 | Docker Compose&lt;br /&gt;
&lt;br /&gt;
{{Tip|This guide is written so that a thinking model AI agent (such as one running on your local server via Ollama/Open WebUI) can follow these instructions step-by-step and get Mastodon running without human intervention. Every command is verified against a successful real-world deployment. Verify all outputs at each stage before proceeding.}}&lt;br /&gt;
&lt;br /&gt;
== Why Mastodon Is More Complex Than Other Docker Apps ==&lt;br /&gt;
&lt;br /&gt;
Most Docker apps are a single process that sits behind a reverse proxy. Mastodon is different in three important ways:&lt;br /&gt;
&lt;br /&gt;
# It runs &#039;&#039;&#039;five processes simultaneously&#039;&#039;&#039; inside one container: Rails (web), Puma (app server), Sidekiq (background jobs), a Node.js streaming server, and its own internal nginx. This is managed by s6-overlay.&lt;br /&gt;
# It assumes it owns ports 80 and 443 directly. Placing it behind NPM requires overriding its internal nginx SSL behavior, which it resists.&lt;br /&gt;
# It enforces cryptographic secrets before it will even start. Unlike most apps, Mastodon refuses to boot without SECRET_KEY_BASE, OTP_SECRET, VAPID keys, and ACTIVE_RECORD_ENCRYPTION keys all pre-generated.&lt;br /&gt;
&lt;br /&gt;
{{Warning|Mastodon also takes 30-60 seconds to fully boot. Always check logs before assuming something is wrong.}}&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
* Ubuntu 24 server (bare metal or VM)&lt;br /&gt;
* Docker and Docker Compose installed&lt;br /&gt;
* Nginx Proxy Manager (NPM) already running on ports 80 and 443&lt;br /&gt;
* A domain name with an A record pointing to your server&#039;s public IP&lt;br /&gt;
* Gmail account with an App Password generated (for SMTP)&lt;br /&gt;
&lt;br /&gt;
{{Critical|To generate a Gmail App Password: go to myaccount.google.com/apppasswords, create a new app password, and save it in a password manager immediately. Do not paste it into any chat or shared document.}}&lt;br /&gt;
&lt;br /&gt;
== Step 1 — Create the Directory ==&lt;br /&gt;
&lt;br /&gt;
All Mastodon files live in one directory. Create it and navigate into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/mastodon&lt;br /&gt;
cd /opt/mastodon&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The volume mount &amp;lt;code&amp;gt;/opt/mastodon/config:/config&amp;lt;/code&amp;gt; will be auto-created by linuxserver on first run and will populate with nginx config, keys, and logs.&lt;br /&gt;
&lt;br /&gt;
== Step 2 — Generate All Secrets Before Starting ==&lt;br /&gt;
&lt;br /&gt;
{{Warning|The linuxserver image entrypoint interferes with rails commands. Always override with &amp;lt;code&amp;gt;--entrypoint=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; and use the full path &amp;lt;code&amp;gt;/app/www/bin/rails&amp;lt;/code&amp;gt;. You must also set the working directory with &amp;lt;code&amp;gt;-w /app/www&amp;lt;/code&amp;gt; for rake tasks.}}&lt;br /&gt;
&lt;br /&gt;
=== SECRET_KEY_BASE (run once) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm --entrypoint=&amp;quot;&amp;quot; lscr.io/linuxserver/mastodon:latest /app/www/bin/rails secret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OTP_SECRET (run again for a different value) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm --entrypoint=&amp;quot;&amp;quot; lscr.io/linuxserver/mastodon:latest /app/www/bin/rails secret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== VAPID Keys ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm --entrypoint=&amp;quot;&amp;quot; -w /app/www lscr.io/linuxserver/mastodon:latest /app/www/bin/rails mastodon:webpush:generate_vapid_key&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
VAPID_PRIVATE_KEY=OqZ07QTRwoO...&lt;br /&gt;
VAPID_PUBLIC_KEY=BA7IhTSGcf0...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ACTIVE_RECORD_ENCRYPTION Keys (new requirement in Mastodon 4.3+) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker run --rm --entrypoint=&amp;quot;&amp;quot; -w /app/www lscr.io/linuxserver/mastodon:latest /app/www/bin/rails db:encryption:init&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=Xf3Rvl...&lt;br /&gt;
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=TK5DQU...&lt;br /&gt;
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=f8cyBe...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Critical|Copy all seven values now. You will not be able to change them after the database is initialized without risking data loss.}}&lt;br /&gt;
&lt;br /&gt;
== Step 3 — Create docker-compose.yml ==&lt;br /&gt;
&lt;br /&gt;
Create the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /opt/mastodon/docker-compose.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following, replacing all placeholder values with your actual secrets and domain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  mastodon:&lt;br /&gt;
    image: lscr.io/linuxserver/mastodon:latest&lt;br /&gt;
    container_name: mastodon&lt;br /&gt;
    environment:&lt;br /&gt;
      - PUID=1000&lt;br /&gt;
      - PGID=1000&lt;br /&gt;
      - TZ=Asia/Manila&lt;br /&gt;
      - LOCAL_DOMAIN=toot.yourdomain.com&lt;br /&gt;
      - NO_SSL=true&lt;br /&gt;
      - FORCE_SSL=false&lt;br /&gt;
      - TRUSTED_PROXY_IP=127.0.0.1/8,::1/128,192.168.0.0/16&lt;br /&gt;
      - REDIS_HOST=redis&lt;br /&gt;
      - REDIS_PORT=6379&lt;br /&gt;
      - DB_HOST=db&lt;br /&gt;
      - DB_USER=mastodon&lt;br /&gt;
      - DB_NAME=mastodon_production&lt;br /&gt;
      - DB_PASS=your_db_password&lt;br /&gt;
      - DB_PORT=5432&lt;br /&gt;
      - ES_ENABLED=false&lt;br /&gt;
      - SECRET_KEY_BASE=&amp;lt;from step 2&amp;gt;&lt;br /&gt;
      - OTP_SECRET=&amp;lt;from step 2&amp;gt;&lt;br /&gt;
      - VAPID_PRIVATE_KEY=&amp;lt;from step 2&amp;gt;&lt;br /&gt;
      - VAPID_PUBLIC_KEY=&amp;lt;from step 2&amp;gt;&lt;br /&gt;
      - ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=&amp;lt;from step 2&amp;gt;&lt;br /&gt;
      - ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=&amp;lt;from step 2&amp;gt;&lt;br /&gt;
      - ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=&amp;lt;from step 2&amp;gt;&lt;br /&gt;
      - SMTP_SERVER=smtp.gmail.com&lt;br /&gt;
      - SMTP_PORT=587&lt;br /&gt;
      - SMTP_LOGIN=your_gmail@gmail.com&lt;br /&gt;
      - SMTP_PASSWORD=your_gmail_app_password&lt;br /&gt;
      - SMTP_FROM_ADDRESS=notifications@yourdomain.com&lt;br /&gt;
      - SMTP_AUTH_METHOD=plain&lt;br /&gt;
      - SMTP_OPENSSL_VERIFY_MODE=peer&lt;br /&gt;
      - S3_ENABLED=false&lt;br /&gt;
    volumes:&lt;br /&gt;
      - /opt/mastodon/config:/config&lt;br /&gt;
    ports:&lt;br /&gt;
      - 8667:80&lt;br /&gt;
    networks:&lt;br /&gt;
      - mastodon-net&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - db&lt;br /&gt;
      - redis&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
  redis:&lt;br /&gt;
    image: redis:7-alpine&lt;br /&gt;
    container_name: mastodon-redis&lt;br /&gt;
    volumes:&lt;br /&gt;
      - /opt/mastodon/redis:/data&lt;br /&gt;
    networks:&lt;br /&gt;
      - mastodon-net&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
  db:&lt;br /&gt;
    image: postgres:14-alpine&lt;br /&gt;
    container_name: mastodon-db&lt;br /&gt;
    environment:&lt;br /&gt;
      - POSTGRES_DB=mastodon_production&lt;br /&gt;
      - POSTGRES_USER=mastodon&lt;br /&gt;
      - POSTGRES_PASSWORD=your_db_password&lt;br /&gt;
    volumes:&lt;br /&gt;
      - /opt/mastodon/postgres:/var/lib/postgresql/data&lt;br /&gt;
    networks:&lt;br /&gt;
      - mastodon-net&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  mastodon-net:&lt;br /&gt;
    driver: bridge&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|Port 8667:80 maps host port 8667 to the container&#039;s internal port 80. This avoids conflict with NPM which already owns ports 80 and 443. Choose any unused host port.}}&lt;br /&gt;
&lt;br /&gt;
== Step 4 — Start the Stack ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/mastodon&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Watch the logs and wait for the boot sequence to complete (30-60 seconds):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose logs -f mastodon&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A successful boot ends with lines like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Connection to localhost (127.0.0.1) 3000 port [tcp/*] succeeded!&lt;br /&gt;
[ls.io-init] done.&lt;br /&gt;
Sidekiq 8.x connecting to Redis with options...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Warning|Do not proceed until you see &amp;lt;code&amp;gt;[ls.io-init] done&amp;lt;/code&amp;gt;. Mastodon takes 30-60 seconds to fully initialize on first boot. The ACTIVE_RECORD_ENCRYPTION crash loop means those keys are missing or not being read from the compose file.}}&lt;br /&gt;
&lt;br /&gt;
== Step 5 — Fix Internal nginx SSL Conflict ==&lt;br /&gt;
&lt;br /&gt;
The linuxserver image generates an nginx config that listens on both port 80 and port 443, and passes &amp;lt;code&amp;gt;X-Forwarded-Proto: http&amp;lt;/code&amp;gt; to Rails. This causes Rails to issue a 301 redirect to HTTPS even when NO_SSL=true and FORCE_SSL=false are set. The fix is to edit the nginx config directly and hardcode X-Forwarded-Proto to https.&lt;br /&gt;
&lt;br /&gt;
{{Warning|This must be done after first boot because the config files are generated on first run into &amp;lt;code&amp;gt;/opt/mastodon/config/nginx/&amp;lt;/code&amp;gt;. You must edit both the active .conf and the .conf.sample so changes survive container restarts.}}&lt;br /&gt;
&lt;br /&gt;
=== Remove 443 listeners and hardcode X-Forwarded-Proto ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Fix active config&lt;br /&gt;
docker exec mastodon sed -i &#039;s/listen 443 ssl default_server;//g&#039; /config/nginx/site-confs/default.conf&lt;br /&gt;
docker exec mastodon sed -i &#039;s/listen \[\:\:\]:443 ssl default_server;//g&#039; /config/nginx/site-confs/default.conf&lt;br /&gt;
docker exec mastodon sed -i &#039;s/include \/config\/nginx\/ssl.conf;//g&#039; /config/nginx/site-confs/default.conf&lt;br /&gt;
docker exec mastodon sed -i &#039;s/proxy_set_header X-Forwarded-Proto $scheme;/proxy_set_header X-Forwarded-Proto https;/g&#039; /config/nginx/site-confs/default.conf&lt;br /&gt;
&lt;br /&gt;
# Fix sample so it survives restarts&lt;br /&gt;
docker exec mastodon sed -i &#039;s/listen 443 ssl default_server;//g&#039; /config/nginx/site-confs/default.conf.sample&lt;br /&gt;
docker exec mastodon sed -i &#039;s/listen \[\:\:\]:443 ssl default_server;//g&#039; /config/nginx/site-confs/default.conf.sample&lt;br /&gt;
docker exec mastodon sed -i &#039;s/include \/config\/nginx\/ssl.conf;//g&#039; /config/nginx/site-confs/default.conf.sample&lt;br /&gt;
docker exec mastodon sed -i &#039;s/proxy_set_header X-Forwarded-Proto $scheme;/proxy_set_header X-Forwarded-Proto https;/g&#039; /config/nginx/site-confs/default.conf.sample&lt;br /&gt;
&lt;br /&gt;
# Reload nginx without restarting the container&lt;br /&gt;
docker exec mastodon s6-svc -r /run/service/svc-nginx&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Verify the fix ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -v http://localhost:8667 -H &amp;quot;Host: toot.yourdomain.com&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see &amp;lt;code&amp;gt;HTTP/1.1 200 OK&amp;lt;/code&amp;gt;. If you still see &amp;lt;code&amp;gt;301 Moved Permanently&amp;lt;/code&amp;gt;, check that the sed commands ran correctly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec mastodon cat /config/nginx/site-confs/default.conf | grep -n &amp;quot;301\|https\|ssl\|443&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 6 — Configure Nginx Proxy Manager ==&lt;br /&gt;
&lt;br /&gt;
In NPM, create a new Proxy Host with these settings:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Domain Name || toot.yourdomain.com&lt;br /&gt;
|-&lt;br /&gt;
| Scheme || http&lt;br /&gt;
|-&lt;br /&gt;
| Forward Hostname / IP || Your server&#039;s LAN IP (e.g. 192.168.1.100)&lt;br /&gt;
|-&lt;br /&gt;
| Forward Port || 8667 (or whichever host port you chose)&lt;br /&gt;
|-&lt;br /&gt;
| Cache Assets || Off&lt;br /&gt;
|-&lt;br /&gt;
| Block Common Exploits || On&lt;br /&gt;
|-&lt;br /&gt;
| Websockets Support || On (critical for live feed)&lt;br /&gt;
|-&lt;br /&gt;
| SSL Certificate || Request via Let&#039;s Encrypt&lt;br /&gt;
|-&lt;br /&gt;
| Force SSL || On&lt;br /&gt;
|-&lt;br /&gt;
| HTTP/2 Support || On&lt;br /&gt;
|-&lt;br /&gt;
| HSTS Enabled || Off (optional, enable after confirming working)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Warning|Websockets Support must be On. Mastodon uses WebSockets for the live timeline feed. Without it the interface loads but does not update in real time.}}&lt;br /&gt;
&lt;br /&gt;
{{Note|The domain must already have a DNS A record pointing to your public IP before requesting a Let&#039;s Encrypt certificate. Verify with: &amp;lt;code&amp;gt;curl -s https://dns.google/resolve?name=toot.yourdomain.com | grep data&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Step 7 — Create Admin Account ==&lt;br /&gt;
&lt;br /&gt;
Mastodon starts with zero accounts. Create your owner account from the command line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec -it mastodon /app/www/bin/tootctl accounts create YOUR_USERNAME --email YOUR@EMAIL --confirmed --role Owner&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The command outputs a randomly generated password. Copy it immediately. Log in at &amp;lt;code&amp;gt;https://toot.yourdomain.com&amp;lt;/code&amp;gt; with your email and that password.&lt;br /&gt;
&lt;br /&gt;
{{Warning|After logging in you will see a &#039;pending review&#039; banner even on your own account. This is because registrations require admin approval. Approve yourself with:}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker exec -it mastodon /app/www/bin/tootctl accounts approve YOUR_USERNAME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then change your password immediately in Settings &amp;gt; Account &amp;gt; Account Settings.&lt;br /&gt;
&lt;br /&gt;
== Problems Encountered and Countermeasures ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Problem !! Cause !! Fix&lt;br /&gt;
|-&lt;br /&gt;
| Crash loop: ACTIVE_RECORD_ENCRYPTION keys missing || New requirement in Mastodon 4.3+. Container exits immediately without these three keys set. || Generate with: &amp;lt;code&amp;gt;docker run --rm --entrypoint=&amp;quot;&amp;quot; -w /app/www lscr.io/... /app/www/bin/rails db:encryption:init&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Redis: connect ECONNREFUSED 127.0.0.1:6379 || Redis service not in same compose file, or containers not on same Docker network. || Add redis service to same docker-compose.yml with a shared named network (mastodon-net).&lt;br /&gt;
|-&lt;br /&gt;
| bin/rails: no such file or directory || linuxserver entrypoint intercepts the command before rails runs. || Always use &amp;lt;code&amp;gt;--entrypoint=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; and full path: &amp;lt;code&amp;gt;/app/www/bin/rails&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| No Rakefile found error for rake tasks || Working directory not set; rake cannot find the app root. || Add &amp;lt;code&amp;gt;-w /app/www&amp;lt;/code&amp;gt; to the docker run command.&lt;br /&gt;
|-&lt;br /&gt;
| 301 redirect loop at toot.yourdomain.com || Internal nginx passes X-Forwarded-Proto: http to Rails. Rails sees HTTP and redirects to HTTPS infinitely. || Sed-edit both default.conf and default.conf.sample to hardcode X-Forwarded-Proto https. Reload nginx with s6-svc.&lt;br /&gt;
|-&lt;br /&gt;
| NO_SSL=true and FORCE_SSL=false not working || FORCE_SSL was removed in newer Mastodon. NO_SSL prevents regenerating the config but cannot fix an already-generated config. || Edit the nginx config files directly. The sample must also be edited or changes are overwritten on restart.&lt;br /&gt;
|-&lt;br /&gt;
| 403 Forbidden on curl test || Host header mismatch. Mastodon&#039;s nginx rejects requests where the Host header does not match LOCAL_DOMAIN. || Always test with: &amp;lt;code&amp;gt;curl -v http://localhost:8667 -H &amp;quot;Host: toot.yourdomain.com&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pending review banner after login || Mastodon requires admin approval for all accounts including ones created via tootctl. || Run: &amp;lt;code&amp;gt;docker exec -it mastodon /app/www/bin/tootctl accounts approve YOUR_USERNAME&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Port 80/443 already in use || NPM is already running on those ports on the host. || Map Mastodon to an unused host port (e.g. 8667:80). NPM proxies to it. Drop the 443 mapping entirely.&lt;br /&gt;
|-&lt;br /&gt;
| Container still starting when testing || Mastodon takes 30-60 seconds to fully boot. curl or browser tests fail during this window. || Watch logs: &amp;lt;code&amp;gt;docker compose logs -f mastodon&amp;lt;/code&amp;gt;. Only test after seeing [ls.io-init] done.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Instructions for AI Agent Execution ==&lt;br /&gt;
&lt;br /&gt;
If you are an AI agent following this guide, use this decision tree at each stage:&lt;br /&gt;
&lt;br /&gt;
=== At each step, verify before proceeding ===&lt;br /&gt;
&lt;br /&gt;
# Run the command exactly as written.&lt;br /&gt;
# Check the output against the expected output described.&lt;br /&gt;
# If the output does not match, consult the Problems table above before retrying.&lt;br /&gt;
# Never proceed to the next step if the current step has not produced the expected output.&lt;br /&gt;
&lt;br /&gt;
=== Key verification commands ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Is the container running?&lt;br /&gt;
docker compose ps&lt;br /&gt;
&lt;br /&gt;
# Is it fully booted?&lt;br /&gt;
docker compose logs mastodon | tail -20&lt;br /&gt;
# Look for: [ls.io-init] done.&lt;br /&gt;
&lt;br /&gt;
# Is nginx listening on port 80 inside the container?&lt;br /&gt;
docker exec mastodon netstat -tlnp&lt;br /&gt;
# Look for: 0.0.0.0:80 LISTEN nginx&lt;br /&gt;
&lt;br /&gt;
# Is Mastodon responding correctly?&lt;br /&gt;
curl -v http://localhost:8667 -H &amp;quot;Host: toot.yourdomain.com&amp;quot;&lt;br /&gt;
# Look for: HTTP/1.1 200 OK&lt;br /&gt;
# A 301 means the nginx X-Forwarded-Proto fix has not been applied yet.&lt;br /&gt;
&lt;br /&gt;
# Are all env vars present?&lt;br /&gt;
docker exec mastodon env | grep -E &#039;ACTIVE_RECORD|SECRET|VAPID|NO_SSL|FORCE&#039;&lt;br /&gt;
# All seven secrets must appear with non-empty values.&lt;br /&gt;
&lt;br /&gt;
# What ports are in use on the host?&lt;br /&gt;
docker ps --format &amp;quot;table {{.Names}}\t{{.Ports}}&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip|If the container is crash-looping, you cannot exec into it. Use &amp;lt;code&amp;gt;docker run --rm --entrypoint=&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; to run one-off commands against the image instead.}}&lt;br /&gt;
&lt;br /&gt;
== Post-Setup Checklist ==&lt;br /&gt;
&lt;br /&gt;
* [ ] Change your admin password in Settings &amp;gt; Account &amp;gt; Account Settings&lt;br /&gt;
* [ ] Enable Two-Factor Authentication in Settings &amp;gt; Account &amp;gt; Two-Factor Auth&lt;br /&gt;
* [ ] Set up server rules and description in Admin &amp;gt; Server Settings&lt;br /&gt;
* [ ] Close registrations or set to invite-only in Admin &amp;gt; Server Settings &amp;gt; Registrations&lt;br /&gt;
* [ ] Revoke any SMTP credentials exposed during setup and generate new ones&lt;br /&gt;
* [ ] Back up /opt/mastodon/config and /opt/mastodon/postgres regularly&lt;br /&gt;
* [ ] Back up your docker-compose.yml and store it in Forgejo or another version-controlled location&lt;br /&gt;
&lt;br /&gt;
{{Critical|The ACTIVE_RECORD_ENCRYPTION keys and all secrets in docker-compose.yml are the most critical backup. If these are lost and the database is intact, recovery is extremely difficult.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Open Source]]&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:Docker]]&lt;br /&gt;
[[Category:Self-Hosting]]&lt;br /&gt;
[[Category:System Administration]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Portainer_to_Docker_Compose_Migration_Guide&amp;diff=216</id>
		<title>Portainer to Docker Compose Migration Guide</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Portainer_to_Docker_Compose_Migration_Guide&amp;diff=216"/>
		<updated>2026-04-02T12:07:31Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: Created page with &amp;quot;= Migrating from Portainer to Docker Compose =  == A Field-Tested Guide with Real Mistakes and How to Fix Them ==  &amp;#039;&amp;#039;&amp;#039;Context:&amp;#039;&amp;#039;&amp;#039; This tutorial was built from a real migration of a home server (Dell Optiplex 3070 Micros) running multiple services in Portainer, moved to pure Docker Compose under &amp;lt;code&amp;gt;/opt/stacks/&amp;lt;/code&amp;gt;. It includes every mistake made along the way and how to recover.  &amp;#039;&amp;#039;&amp;#039;Target audience:&amp;#039;&amp;#039;&amp;#039; Someone who knows basic Linux and Docker but may forget steps,...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Migrating from Portainer to Docker Compose =&lt;br /&gt;
&lt;br /&gt;
== A Field-Tested Guide with Real Mistakes and How to Fix Them ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Context:&#039;&#039;&#039; This tutorial was built from a real migration of a home server (Dell Optiplex 3070 Micros) running multiple services in Portainer, moved to pure Docker Compose under &amp;lt;code&amp;gt;/opt/stacks/&amp;lt;/code&amp;gt;. It includes every mistake made along the way and how to recover.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Target audience:&#039;&#039;&#039; Someone who knows basic Linux and Docker but may forget steps, mix up machines, or make assumptions that get them in trouble.&lt;br /&gt;
&lt;br /&gt;
== The Big Picture ==&lt;br /&gt;
&lt;br /&gt;
=== What we are doing ===&lt;br /&gt;
Moving services managed by Portainer (which has its own hidden config layer) into clean, self-contained Docker Compose stacks stored under &amp;lt;code&amp;gt;/opt/stacks/&amp;lt;/code&amp;gt;. Each service gets its own folder with a &amp;lt;code&amp;gt;compose.yml&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Why this matters for backup ===&lt;br /&gt;
Everything lives under &amp;lt;code&amp;gt;/opt/stacks/&amp;lt;/code&amp;gt; — one folder to back up, one folder to restore. No hunting for Portainer&#039;s hidden volumes or config files.&lt;br /&gt;
&lt;br /&gt;
=== The 3-2-1 backup goal ===&lt;br /&gt;
* &#039;&#039;&#039;Copy 1:&#039;&#039;&#039; Live data on PC03 (primary server)&lt;br /&gt;
* &#039;&#039;&#039;Copy 2:&#039;&#039;&#039; Warm backup on PC02 (sleeps, wakes via WoL 3x/day and on failure)&lt;br /&gt;
* &#039;&#039;&#039;Copy 3:&#039;&#039;&#039; Synology NAS (cold archive, always on)&lt;br /&gt;
&lt;br /&gt;
== Before You Start: Know Your Environment ==&lt;br /&gt;
&lt;br /&gt;
=== Check which machine you are on ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
# Should print something like PC03dell3050&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Common mistake:&#039;&#039;&#039; Running commands on PC02 when you think you are on PC03, or vice versa. Always check &amp;lt;code&amp;gt;hostname&amp;lt;/code&amp;gt; before doing anything destructive.&lt;br /&gt;
&lt;br /&gt;
=== Know your folder structure ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/stacks/&lt;br /&gt;
├── wordpress/&lt;br /&gt;
│   ├── compose.yml&lt;br /&gt;
│   ├── .env&lt;br /&gt;
│   ├── wordpress_data/    ← webroot files&lt;br /&gt;
│   └── db_data/           ← database files&lt;br /&gt;
├── mediawiki/&lt;br /&gt;
├── zulip/&lt;br /&gt;
├── openwebui/&lt;br /&gt;
└── ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All data lives INSIDE the stack folder as bind mounts. No named Docker volumes. This makes backup and restore straightforward.&lt;br /&gt;
&lt;br /&gt;
=== Know your user situation ===&lt;br /&gt;
Most of these operations require root. If you are logged in as a regular user:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -i&lt;br /&gt;
# or&lt;br /&gt;
su -&lt;br /&gt;
# enter root password when prompted&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;If you cannot write to /opt/stacks/,&#039;&#039;&#039; you are not root. Do not proceed until you are.&lt;br /&gt;
&lt;br /&gt;
== Step 0: Preparation Checklist ==&lt;br /&gt;
&lt;br /&gt;
Before migrating any service, do these once:&lt;br /&gt;
&lt;br /&gt;
=== Create the shared Docker network ===&lt;br /&gt;
All services and NPM (your reverse proxy) share this network:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker network create npm_proxy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Safe to run even if it already exists — it will just say it already exists.&lt;br /&gt;
&lt;br /&gt;
=== Create the base stacks directory ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/stacks&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 1: Read the Portainer Stack ==&lt;br /&gt;
&lt;br /&gt;
In Portainer, go to &#039;&#039;&#039;Stacks → [stack name] → Editor&#039;&#039;&#039; and copy the entire compose content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What to look for:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! What it tells you&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;image:&amp;lt;/code&amp;gt; || The Docker image and version&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ports:&amp;lt;/code&amp;gt; || Host port → container port mapping&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;volumes:&amp;lt;/code&amp;gt; || Where data lives — see below&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;environment:&amp;lt;/code&amp;gt; || Credentials and config — &#039;&#039;&#039;do not lose these&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;container_name:&amp;lt;/code&amp;gt; || The exact name Docker uses — you will need this&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Understanding volumes — the most important thing ===&lt;br /&gt;
&lt;br /&gt;
Portainer stacks can use two types of volumes:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Type 1 — Named volumes&#039;&#039;&#039; (Portainer manages them, hidden location):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
volumes:&lt;br /&gt;
  - mydata:/var/lib/data&lt;br /&gt;
volumes:&lt;br /&gt;
  mydata:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The actual files are at &amp;lt;code&amp;gt;/var/lib/docker/volumes/STACKNAME_mydata/_data/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Type 2 — Bind mounts&#039;&#039;&#039; (explicit path on the host):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
volumes:&lt;br /&gt;
  - /home/user/myapp/data:/var/lib/data&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The files are exactly where the path says.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to tell which type you have:&#039;&#039;&#039; If the volume line has a full path starting with &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, it is a bind mount. If it is just a name with no &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, it is a named volume.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Find Where the Data Actually Is ==&lt;br /&gt;
&lt;br /&gt;
=== For named volumes — Portainer renames them ===&lt;br /&gt;
&#039;&#039;&#039;Critical:&#039;&#039;&#039; Portainer adds the stack name as a prefix. If your stack is named &amp;lt;code&amp;gt;wp240927&amp;lt;/code&amp;gt; and your volume is named &amp;lt;code&amp;gt;db&amp;lt;/code&amp;gt;, the actual Docker volume name is &amp;lt;code&amp;gt;wp240927_db&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Find the real names:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker volume ls | grep -i KEYWORD&lt;br /&gt;
# Example:&lt;br /&gt;
docker volume ls | grep -i wordpress&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the actual path on disk:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker volume inspect VOLUMENAME&lt;br /&gt;
# Look for &amp;quot;Mountpoint&amp;quot; in the output&lt;br /&gt;
# Example output:&lt;br /&gt;
# &amp;quot;Mountpoint&amp;quot;: &amp;quot;/var/lib/docker/volumes/wp240927_db/_data&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== For bind mounts ===&lt;br /&gt;
Just check if the path exists:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls /home/user/wp250223-8070/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create the New Stack Files ==&lt;br /&gt;
&lt;br /&gt;
=== Directory structure ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /opt/stacks/SERVICENAME/data_folder_name&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create compose.yml ===&lt;br /&gt;
Use &amp;lt;code&amp;gt;cat &amp;gt;&amp;lt;/code&amp;gt; to write the file directly in the terminal. This avoids file transfer issues:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/stacks/SERVICENAME/compose.yml &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
services:&lt;br /&gt;
  app:&lt;br /&gt;
    image: someimage:latest&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;PORT:PORT&amp;quot;&lt;br /&gt;
    environment:&lt;br /&gt;
      SOME_VAR: ${SOME_VAR}&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./data:/app/data&lt;br /&gt;
    networks:&lt;br /&gt;
      - proxy&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  proxy:&lt;br /&gt;
    external: true&lt;br /&gt;
    name: npm_proxy&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Key changes from the Portainer version:&#039;&#039;&#039;&lt;br /&gt;
* Remove &amp;lt;code&amp;gt;version:&amp;lt;/code&amp;gt; line (obsolete in modern Compose)&lt;br /&gt;
* Change &amp;lt;code&amp;gt;restart: always&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;restart: unless-stopped&amp;lt;/code&amp;gt;&lt;br /&gt;
* Move credentials out of &amp;lt;code&amp;gt;environment:&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;${VAR_NAME}&amp;lt;/code&amp;gt; syntax&lt;br /&gt;
* Change named volume paths to &amp;lt;code&amp;gt;./foldername&amp;lt;/code&amp;gt; (relative bind mounts)&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;npm_proxy&amp;lt;/code&amp;gt; network so NPM can reach the service&lt;br /&gt;
&lt;br /&gt;
=== Create .env file ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat &amp;gt; /opt/stacks/SERVICENAME/.env &amp;lt;&amp;lt; &#039;EOF&#039;&lt;br /&gt;
DB_NAME=mydb&lt;br /&gt;
DB_USER=myuser&lt;br /&gt;
DB_PASSWORD=change_this_password&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Critical:&#039;&#039;&#039; The values in &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; must match what is already inside your database files. If you copy the DB files from the old stack, use the same credentials the old stack had. Changing them will break the connection.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to find the original credentials:&#039;&#039;&#039; Before stopping the old stack, go to Portainer → Stack → Editor and read the environment variables.&lt;br /&gt;
&lt;br /&gt;
== Step 4: Copy the Data ==&lt;br /&gt;
&lt;br /&gt;
=== Stop the old Portainer stack first ===&lt;br /&gt;
Go to Portainer → Stacks → [stack name] → &#039;&#039;&#039;Stop&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do NOT delete it yet.&#039;&#039;&#039; It is your rollback. Only delete after you confirm the new stack works.&lt;br /&gt;
&lt;br /&gt;
=== For bind mount data (path already known) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rsync -av --progress \&lt;br /&gt;
  /old/path/data/ \&lt;br /&gt;
  /opt/stacks/SERVICENAME/data/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The trailing slash on the source matters.&#039;&#039;&#039; With a trailing slash, rsync copies the contents. Without it, rsync copies the folder itself (creating an extra nesting level).&lt;br /&gt;
&lt;br /&gt;
=== For named volume data (path from docker volume inspect) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rsync -av --progress \&lt;br /&gt;
  /var/lib/docker/volumes/STACKNAME_VOLUMENAME/_data/ \&lt;br /&gt;
  /opt/stacks/SERVICENAME/data/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== For data on another machine (SSH) ===&lt;br /&gt;
If rsync is available on both machines:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Run on the destination machine, pulling from source&lt;br /&gt;
rsync -av --progress -e ssh \&lt;br /&gt;
  root@SOURCE_IP:/var/lib/docker/volumes/STACKNAME_VOLUMENAME/_data/ \&lt;br /&gt;
  /opt/stacks/SERVICENAME/data/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If rsync is NOT installed on the source machine:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# On source machine: create a tar archive&lt;br /&gt;
tar -czvf /home/user/service-backup.tar.gz \&lt;br /&gt;
  /var/lib/docker/volumes/STACKNAME_vol1/_data \&lt;br /&gt;
  /var/lib/docker/volumes/STACKNAME_vol2/_data&lt;br /&gt;
&lt;br /&gt;
# Transfer via SCP from destination&lt;br /&gt;
scp root@SOURCE_IP:/home/user/service-backup.tar.gz /opt/stacks/SERVICENAME/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then extract directly into target folders:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/stacks/SERVICENAME&lt;br /&gt;
&lt;br /&gt;
tar -xzvf service-backup.tar.gz \&lt;br /&gt;
  --strip-components=6 \&lt;br /&gt;
  -C data/subfolder \&lt;br /&gt;
  var/lib/docker/volumes/STACKNAME_vol1/_data&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The &amp;lt;code&amp;gt;--strip-components&amp;lt;/code&amp;gt; number&#039;&#039;&#039; = how many path levels to strip. Count the slashes in &amp;lt;code&amp;gt;var/lib/docker/volumes/STACKNAME_vol1/_data&amp;lt;/code&amp;gt; — that is 6 components (var, lib, docker, volumes, STACKNAME_vol1, _data).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;If you cannot write to /opt/stacks/ via SFTP:&#039;&#039;&#039; Upload to &amp;lt;code&amp;gt;/home/user/&amp;lt;/code&amp;gt; instead, then move:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv /home/user/service-backup.tar.gz /opt/stacks/SERVICENAME/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fix file ownership after copying ===&lt;br /&gt;
Different services run as different users inside their containers:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Service !! uid:gid !! Why&lt;br /&gt;
|-&lt;br /&gt;
| WordPress (webroot) || 33:33 || www-data&lt;br /&gt;
|-&lt;br /&gt;
| MariaDB / MySQL || 999:999 || mysql&lt;br /&gt;
|-&lt;br /&gt;
| PostgreSQL || 70:70 || postgres&lt;br /&gt;
|-&lt;br /&gt;
| Most Node apps || 1000:1000 || node&lt;br /&gt;
|-&lt;br /&gt;
| RabbitMQ || 999:999 || rabbitmq&lt;br /&gt;
|-&lt;br /&gt;
| Redis || 999:999 || redis&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chown -R 33:33 /opt/stacks/wordpress/wordpress_data/&lt;br /&gt;
chown -R 999:999 /opt/stacks/wordpress/db_data/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 5: Start the New Stack ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/stacks/SERVICENAME&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Watch the logs:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose logs -f&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Press &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt; to stop watching logs. &#039;&#039;&#039;This does NOT stop the containers.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Test locally before checking the public URL:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -I http://localhost:PORT&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected responses:&lt;br /&gt;
* &amp;lt;code&amp;gt;200 OK&amp;lt;/code&amp;gt; — service is up and working&lt;br /&gt;
* &amp;lt;code&amp;gt;301 Moved Permanently&amp;lt;/code&amp;gt; — service is up, redirecting (usually HTTP→HTTPS, this is fine)&lt;br /&gt;
* &amp;lt;code&amp;gt;500 Internal Server Error&amp;lt;/code&amp;gt; — service is up but something is wrong (usually credentials)&lt;br /&gt;
* &amp;lt;code&amp;gt;Connection refused&amp;lt;/code&amp;gt; — container is not running or wrong port&lt;br /&gt;
&lt;br /&gt;
== Common Mistakes and How to Fix Them ==&lt;br /&gt;
&lt;br /&gt;
=== Mistake 1: Old container still running, new one cannot start ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Symptom:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Error response from daemon: Conflict. The container name &amp;quot;/myapp&amp;quot; is already in use&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause:&#039;&#039;&#039; Stopping a Portainer stack does not always stop the containers. Portainer stopped managing them but left them running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker rm -f CONTAINERNAME&lt;br /&gt;
# Then retry:&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mistake 2: Wrong credentials in .env — database refuses connection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Symptom:&#039;&#039;&#039; &amp;lt;code&amp;gt;500 Internal Server Error&amp;lt;/code&amp;gt; or &amp;quot;Error establishing database connection&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause:&#039;&#039;&#039; The &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; credentials do not match what is stored inside the database files. The database files remember what credentials they were initialized with.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diagnosis — check what the container actually sees:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose exec SERVICENAME env | grep DB_&lt;br /&gt;
# or for WordPress specifically:&lt;br /&gt;
docker compose exec wordpress env | grep WORDPRESS_DB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diagnosis — test the credentials directly:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose exec db mariadb -u USERNAME -p&#039;PASSWORD&#039; DBNAME -e &amp;quot;SELECT 1;&amp;quot;&lt;br /&gt;
# If it returns &amp;quot;1&amp;quot;, those credentials work.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix:&#039;&#039;&#039; Edit &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; to match the credentials that actually work, then do a FULL restart:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose down&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Critical:&#039;&#039;&#039; &amp;lt;code&amp;gt;docker compose restart&amp;lt;/code&amp;gt; does NOT re-read &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt;. You must use &amp;lt;code&amp;gt;down&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;up&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Mistake 3: Portainer volume names are different from what the compose file says ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Symptom:&#039;&#039;&#039; &amp;lt;code&amp;gt;docker volume inspect VOLUMENAME&amp;lt;/code&amp;gt; returns &amp;lt;code&amp;gt;no such volume&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause:&#039;&#039;&#039; Portainer prefixes volumes with the stack name. If your stack is &amp;lt;code&amp;gt;wp240927&amp;lt;/code&amp;gt; and your volume is &amp;lt;code&amp;gt;db&amp;lt;/code&amp;gt;, the real name is &amp;lt;code&amp;gt;wp240927_db&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker volume ls | grep -i KEYWORD&lt;br /&gt;
# Use the full name shown in the output&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mistake 4: Data lands in the wrong place after extraction ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Symptom:&#039;&#039;&#039; &amp;lt;code&amp;gt;ls data/postgresql/&amp;lt;/code&amp;gt; shows &amp;lt;code&amp;gt;_data&amp;lt;/code&amp;gt; instead of actual database files&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause:&#039;&#039;&#039; &amp;lt;code&amp;gt;--strip-components&amp;lt;/code&amp;gt; count was wrong, or the tar had an unexpected nesting level.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix — check what is actually there:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find /opt/stacks/SERVICENAME -name &amp;quot;PG_VERSION&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
find /opt/stacks/SERVICENAME -name &amp;quot;*.conf&amp;quot; 2&amp;gt;/dev/null | head -5&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then move the contents up:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mv data/postgresql/_data/* data/postgresql/&lt;br /&gt;
rmdir data/postgresql/_data&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mistake 5: .env changes not taking effect ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Symptom:&#039;&#039;&#039; You edited &amp;lt;code&amp;gt;.env&amp;lt;/code&amp;gt; and restarted, but the container still uses old values.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause:&#039;&#039;&#039; &amp;lt;code&amp;gt;docker compose restart&amp;lt;/code&amp;gt; only restarts the process, it does not rebuild the environment.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose down&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verify the new values are actually injected:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker compose exec SERVICENAME env | grep VARNAME&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mistake 6: NPM proxy still pointing to old IP/port after migration ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Symptom:&#039;&#039;&#039; Service is running locally (&amp;lt;code&amp;gt;curl -I http://localhost:PORT&amp;lt;/code&amp;gt; returns 200) but the public domain gives 502 Bad Gateway.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause:&#039;&#039;&#039; NPM&#039;s proxy host was pointing to the old machine&#039;s IP or old port.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix:&#039;&#039;&#039; In NPM → Proxy Hosts → Edit the domain → update Forward Hostname to the new IP or &amp;lt;code&amp;gt;localhost&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Mistake 7: Zulip/service doing HTTP→HTTPS redirect loop through NPM ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Symptom:&#039;&#039;&#039; &amp;quot;This page isn&#039;t redirecting properly&amp;quot; error in browser.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause:&#039;&#039;&#039; Service internally redirects HTTP to HTTPS, but NPM is sending HTTP. The service sends back a 301 to HTTPS, which loops.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix:&#039;&#039;&#039; In NPM, change the scheme to &amp;lt;code&amp;gt;https&amp;lt;/code&amp;gt; and expose the service&#039;s HTTPS port instead of the HTTP port. Also disable SSL verification in NPM since services often use self-signed certs.&lt;br /&gt;
&lt;br /&gt;
== Verifying Everything Works ==&lt;br /&gt;
&lt;br /&gt;
After bringing up each service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. Check containers are running&lt;br /&gt;
docker compose ps&lt;br /&gt;
&lt;br /&gt;
# 2. Check logs for errors&lt;br /&gt;
docker compose logs --tail=20&lt;br /&gt;
&lt;br /&gt;
# 3. Test local connectivity&lt;br /&gt;
curl -I http://localhost:PORT&lt;br /&gt;
&lt;br /&gt;
# 4. Check the public domain loads&lt;br /&gt;
# (Do this in your browser)&lt;br /&gt;
&lt;br /&gt;
# 5. Verify data survived (service-specific)&lt;br /&gt;
# For WordPress: log into wp-admin and check posts&lt;br /&gt;
# For Wiki: browse to a page you know exists&lt;br /&gt;
# For Zulip: log in and check message history&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== After Confirming a Service Works ==&lt;br /&gt;
&lt;br /&gt;
Wait 24–48 hours of stable operation, then:&lt;br /&gt;
&lt;br /&gt;
# In Portainer: &#039;&#039;&#039;Delete&#039;&#039;&#039; the old stack&lt;br /&gt;
# Clean up old data directories if they were bind mounts:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm -rf /home/user/old-stack-data/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Clean up orphaned named volumes:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker volume ls | grep OLDSTACKNAME&lt;br /&gt;
docker volume rm OLDSTACKNAME_volumename&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Backup Strategy (What This All Feeds Into) ==&lt;br /&gt;
&lt;br /&gt;
Once all services are under &amp;lt;code&amp;gt;/opt/stacks/&amp;lt;/code&amp;gt;, the backup is simple:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PC03 → Synology (3x daily via Restic):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
restic -r sftp:synology:/backups/pc03 backup /opt/stacks/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PC02 warm backup:&#039;&#039;&#039;&lt;br /&gt;
* PC02 sleeps most of the time&lt;br /&gt;
* Synology watchdog pings PC03 every 60s&lt;br /&gt;
* If PC03 fails 3 checks → Synology sends WoL magic packet → PC02 wakes&lt;br /&gt;
* PC06 relay (iptables DNAT) switches traffic to PC02&lt;br /&gt;
* When PC03 comes back → Restic syncs PC02→PC03 → manual confirm → traffic switches back&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PC00 desktop → Synology (daily):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
restic -r sftp:synology:/backups/pc00 backup /home/USERNAME/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Quick Reference: Ports Used ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Service !! Port !! Domain&lt;br /&gt;
|-&lt;br /&gt;
| WordPress || 8070 || blog.gi7b.org&lt;br /&gt;
|-&lt;br /&gt;
| MediaWiki || 8191 || wiki.gi7b.org&lt;br /&gt;
|-&lt;br /&gt;
| Open WebUI || 3000 || —&lt;br /&gt;
|-&lt;br /&gt;
| SearXNG || 8290 || —&lt;br /&gt;
|-&lt;br /&gt;
| Zulip || 8010 (HTTP), 8011 (HTTPS) || chat.gi7b.org&lt;br /&gt;
|-&lt;br /&gt;
| Forgejo || 3001 || —&lt;br /&gt;
|-&lt;br /&gt;
| Gemini sites || 27081 || —&lt;br /&gt;
|-&lt;br /&gt;
| Jitsi || TBD || meet.gi7b.org&lt;br /&gt;
|-&lt;br /&gt;
| Grafana || TBD || —&lt;br /&gt;
|-&lt;br /&gt;
| Frappe || TBD || —&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Giving This Context to a New AI Chat ==&lt;br /&gt;
&lt;br /&gt;
Paste this block at the start of a new conversation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
I am continuing a home server migration project. Here is the context:&lt;br /&gt;
&lt;br /&gt;
Setup:&lt;br /&gt;
- PC03 (192.168.196.76) = primary server, Dell Optiplex 3070, Ubuntu, Docker Compose&lt;br /&gt;
- PC02 (192.168.196.189) = warm backup, same hardware, sleeps until needed&lt;br /&gt;
- PC06 = Contabo Japan VPS, pure iptables DNAT relay (no NGINX), forwards traffic to PC03&lt;br /&gt;
- Synology NAS = always on, cold backup archive, runs watchdog container&lt;br /&gt;
- ZeroTier connects all machines&lt;br /&gt;
&lt;br /&gt;
All stacks live under /opt/stacks/SERVICENAME/ on PC03&lt;br /&gt;
Each stack has: compose.yml, .env, and data folders as bind mounts&lt;br /&gt;
Shared Docker network: npm_proxy (external)&lt;br /&gt;
Reverse proxy: NGINX Proxy Manager (NPM) running as its own stack on PC03&lt;br /&gt;
&lt;br /&gt;
Completed migrations (Portainer → Docker Compose):&lt;br /&gt;
- WordPress (blog.gi7b.org) → port 8070 ✓&lt;br /&gt;
- MediaWiki (wiki.gi7b.org) → port 8191 ✓ (check status)&lt;br /&gt;
- Open WebUI → port 3000 ✓&lt;br /&gt;
- SearXNG → port 8290 ✓&lt;br /&gt;
- Zulip (chat.gi7b.org) → port 8010/8011 ✓ (troubleshooting NPM HTTPS)&lt;br /&gt;
- Forgejo → port 3001 ✓ (fresh install, no data migration)&lt;br /&gt;
- Gemini-sites → port 27081 ✓&lt;br /&gt;
&lt;br /&gt;
Still to do:&lt;br /&gt;
- Jitsi (meet.gi7b.org)&lt;br /&gt;
- Grafana + Prometheus&lt;br /&gt;
- Frappe / ERPNext&lt;br /&gt;
- PC06 iptables watchdog script&lt;br /&gt;
- Synology WoL watchdog container&lt;br /&gt;
- Restic backup setup (PC03→Synology, PC02 agent, PC00→Synology)&lt;br /&gt;
- Clean up abandoned Mastodon volumes on PC03&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:Docker]]&lt;br /&gt;
[[Category:System Administration]]&lt;br /&gt;
[[Category:Self-Hosting]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=NPM_Migration_to_Homelab_VPS_Relay_260401&amp;diff=215</id>
		<title>NPM Migration to Homelab VPS Relay 260401</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=NPM_Migration_to_Homelab_VPS_Relay_260401&amp;diff=215"/>
		<updated>2026-03-31T18:20:36Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: &amp;quot;Add NPM migration to homelab VPS relay guide&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Migrating NGINX Proxy Manager Off a Compromised VPS =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A practical runbook for moving NPM to your homelab and turning your VPS into a pure relay.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Background and Lessons Learned ==&lt;br /&gt;
&lt;br /&gt;
This tutorial documents a real incident where a VPS running NGINX Proxy Manager (NPM) became compromised. The infection vector was a Minecraft server setup tutorial that turned out to be malware — it used the server&#039;s open Postfix port to send approximately 28,000 spam emails before being detected.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The core lesson:&#039;&#039;&#039; Never install experimental software directly on a bare server. Use Distrobox containers or Docker for anything you are testing or following a tutorial for. The host OS should only run what you deliberately chose to put there.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The architectural lesson:&#039;&#039;&#039; NPM is surprisingly easy to back up and restore. This means you do not need to keep it on an expensive VPS. A cheap VPS can be reduced to a pure traffic relay, with NPM and all services running on hardware you own at home.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Architecture Overview ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Internet → VPS (pure relay, iptables DNAT) → ZeroTier → Home server NPM → your services&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Component !! Role&lt;br /&gt;
|-&lt;br /&gt;
| VPS (e.g. Contabo) || Public IP relay only — iptables forwards port 80/443 over ZeroTier&lt;br /&gt;
|-&lt;br /&gt;
| PC03 (primary) || Runs NPM + all Docker services&lt;br /&gt;
|-&lt;br /&gt;
| PC02 (warm backup) || NPM mirror, ready to take over&lt;br /&gt;
|-&lt;br /&gt;
| Synology NAS || Always-on backup repository, watchdog, cold archive&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The failover flow is: &#039;&#039;&#039;detect&#039;&#039;&#039; (PC06 watchdog, 3 fails trigger) → &#039;&#039;&#039;wake&#039;&#039;&#039; (PC06 → Synology sends WoL → PC02 boots) → &#039;&#039;&#039;failover&#039;&#039;&#039; (DNAT swaps to PC02 once NPM responds). Restic runs 3×/day to Synology from PC03, and mirrors to PC02 on wake.&lt;br /&gt;
&lt;br /&gt;
=== Why this works without a static home IP ===&lt;br /&gt;
&lt;br /&gt;
Your home ISP likely does not give you a static public IP. That does not matter here. Both the VPS and your home servers are connected via ZeroTier, which assigns fixed private IPs regardless of what your ISP does. The VPS always knows where to forward traffic.&lt;br /&gt;
&lt;br /&gt;
=== Approximate hardware costs (Philippine Peso) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Hardware !! Cost&lt;br /&gt;
|-&lt;br /&gt;
| VPS (e.g. Contabo, annual) || ₱5,000/yr&lt;br /&gt;
|-&lt;br /&gt;
| Dell OptiPlex micro (16GB RAM, 256GB SSD) × 2 || ₱10,000 each&lt;br /&gt;
|-&lt;br /&gt;
| Synology NAS with 2 × 3.5TB IronWolf || ₱28,000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A system good for 7–10 years, with full redundancy, for roughly what a single mid-tier cloud server costs annually.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Part 1 — Backing Up NPM ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1 — Identify your NPM setup ===&lt;br /&gt;
&lt;br /&gt;
First confirm whether your NPM is using SQLite (simpler) or MariaDB (more common in older installs):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker ps&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you see a separate &amp;lt;code&amp;gt;mariadb&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;mariadb-aria&amp;lt;/code&amp;gt; container alongside NPM, you are on the MariaDB variant. This tutorial covers that setup.&lt;br /&gt;
&lt;br /&gt;
Find your compose file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
find /root /opt /etc/docker -name &amp;quot;docker-compose.yml&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check where NPM mounts its data:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker inspect &amp;lt;npm-container-name&amp;gt; | grep -A 20 &#039;&amp;quot;Mounts&amp;quot;&#039;&lt;br /&gt;
docker inspect &amp;lt;db-container-name&amp;gt;  | grep -A 20 &#039;&amp;quot;Mounts&amp;quot;&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt; paths — everything NPM needs is in those directories.&lt;br /&gt;
&lt;br /&gt;
=== Step 2 — Create the backup ===&lt;br /&gt;
&lt;br /&gt;
Run this as root. Replace &amp;lt;code&amp;gt;/data/compose/3&amp;lt;/code&amp;gt; with your actual mount paths if different.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Create staging directory&lt;br /&gt;
mkdir -p /root/npm-backup/zt&lt;br /&gt;
&lt;br /&gt;
# Back up ZeroTier identity (preserves your ZT IP after reformat)&lt;br /&gt;
cp /var/lib/zerotier-one/identity.secret /root/npm-backup/zt/&lt;br /&gt;
cp /var/lib/zerotier-one/identity.public  /root/npm-backup/zt/&lt;br /&gt;
&lt;br /&gt;
# Back up the compose file&lt;br /&gt;
cp /root/nginx-pm&amp;lt;your-folder&amp;gt;/docker-compose.yml /root/npm-backup/&lt;br /&gt;
&lt;br /&gt;
# Dump the database (do this while containers are running)&lt;br /&gt;
docker exec &amp;lt;db-container-name&amp;gt; \&lt;br /&gt;
  mysqldump -u npm -pnpm npm &amp;gt; /root/npm-backup/npm-db-dump.sql&lt;br /&gt;
&lt;br /&gt;
# Archive all NPM data (app config, SSL certs, MySQL files)&lt;br /&gt;
tar -czvf /root/npm-backup/npm-data.tar.gz /data/compose/3/&lt;br /&gt;
&lt;br /&gt;
# Verify&lt;br /&gt;
ls -lh /root/npm-backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check that &amp;lt;code&amp;gt;npm-db-dump.sql&amp;lt;/code&amp;gt; is not zero bytes. If it is, the dump failed silently — the raw MySQL files in &amp;lt;code&amp;gt;npm-data.tar.gz&amp;lt;/code&amp;gt; will be your restore source instead.&lt;br /&gt;
&lt;br /&gt;
=== Step 3 — Transfer to your NAS or local machine ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rsync -avz --progress \&lt;br /&gt;
  /root/npm-backup/ \&lt;br /&gt;
  user@&amp;lt;NAS-IP&amp;gt;:/volume1/backups/npm/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or compress first:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root&lt;br /&gt;
tar -czvf npm-backup.tar.gz npm-backup/&lt;br /&gt;
rsync -avz --progress npm-backup.tar.gz user@&amp;lt;NAS-IP&amp;gt;:/volume1/backups/npm/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Part 2 — Restoring NPM on a New Machine ==&lt;br /&gt;
&lt;br /&gt;
All commands run as root. The backup file goes in &amp;lt;code&amp;gt;/root/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; NPM data always restores to the same absolute path (&amp;lt;code&amp;gt;/data/compose/3/&amp;lt;/code&amp;gt;) regardless of which machine you are on. This is hardcoded in the compose file. Do not change it.&lt;br /&gt;
&lt;br /&gt;
=== Step 1 — Extract the backup ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root&lt;br /&gt;
tar -xzvf npm-backup.tar.gz&lt;br /&gt;
ls npm-backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see: &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;npm-data.tar.gz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;npm-db-dump.sql&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;zt/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 2 — Restore data files ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Extract directly to / — this recreates /data/compose/3/ automatically&lt;br /&gt;
tar -xzvf /root/npm-backup/npm-data.tar.gz -C /&lt;br /&gt;
&lt;br /&gt;
# Verify&lt;br /&gt;
ls /data/compose/3/&lt;br /&gt;
# Should show: data  letsencrypt  mysql&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3 — Deploy the stack ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p /root/nginx-pm&lt;br /&gt;
cp /root/npm-backup/docker-compose.yml /root/nginx-pm/&lt;br /&gt;
&lt;br /&gt;
cd /root/nginx-pm&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&lt;br /&gt;
docker ps&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both the NPM app container and the MariaDB container should show as running.&lt;br /&gt;
&lt;br /&gt;
=== Step 4 — Verify ===&lt;br /&gt;
&lt;br /&gt;
Open &amp;lt;code&amp;gt;http://&amp;amp;lt;machine-IP&amp;amp;gt;:81&amp;lt;/code&amp;gt; in a browser. Your proxy hosts, SSL certificates, and settings should all be present exactly as they were.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Part 3 — Setting Up the VPS as a Pure Relay ==&lt;br /&gt;
&lt;br /&gt;
After reformatting your VPS, the entire setup is:&lt;br /&gt;
&lt;br /&gt;
=== Step 1 — Install ZeroTier and join your network ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -s https://install.zerotier.com | bash&lt;br /&gt;
zerotier-cli join &amp;lt;your-network-id&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then go to your ZeroTier Central dashboard, authorize the new node, and assign it your chosen fixed IP (e.g. the same IP it had before).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note on ZeroTier IP preservation:&#039;&#039;&#039; You do not need to restore the ZeroTier identity files to keep the same IP. Simply authorize the new node in ZT Central and manually assign the same managed IP there. The identity restore is only needed if you specifically want the same node ID.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Contabo UI warning:&#039;&#039;&#039; Contabo&#039;s control panel is easy to misclick. Always double-check which server you have selected before clicking reformat. The interface can make it easy to accidentally act on the wrong server.&lt;br /&gt;
&lt;br /&gt;
=== Step 2 — Enable IP forwarding and set up relay rules ===&lt;br /&gt;
&lt;br /&gt;
Replace &amp;lt;code&amp;gt;192.168.196.76&amp;lt;/code&amp;gt; with your home server&#039;s ZeroTier IP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Enable forwarding&lt;br /&gt;
echo &amp;quot;net.ipv4.ip_forward=1&amp;quot; &amp;gt;&amp;gt; /etc/sysctl.conf&lt;br /&gt;
sysctl -p&lt;br /&gt;
&lt;br /&gt;
# Forward web traffic to home NPM&lt;br /&gt;
iptables -t nat -A PREROUTING -p tcp --dport 80  -j DNAT --to-destination 192.168.196.76:80&lt;br /&gt;
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 192.168.196.76:443&lt;br /&gt;
iptables -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
# Make rules persistent across reboots&lt;br /&gt;
apt install iptables-persistent -y&lt;br /&gt;
netfilter-persistent save&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3 — Verify ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
iptables -t nat -L -n -v&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see packet counters incrementing on the DNAT rules as traffic arrives.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Part 4 — Hardening WordPress Behind NPM ==&lt;br /&gt;
&lt;br /&gt;
After migrating, a brute force attack on &amp;lt;code&amp;gt;/wp-login.php&amp;lt;/code&amp;gt; was detected within hours. Two layers of protection:&lt;br /&gt;
&lt;br /&gt;
=== Layer 1 — Hide the login URL ===&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;WPS Hide Login&#039;&#039;&#039; plugin in WordPress:&lt;br /&gt;
&lt;br /&gt;
# WordPress admin → Plugins → Add New → search &amp;lt;code&amp;gt;WPS Hide Login&amp;lt;/code&amp;gt;&lt;br /&gt;
# Install and activate&lt;br /&gt;
# Settings → WPS Hide Login → set a custom login path (e.g. &amp;lt;code&amp;gt;/your-secret-path&amp;lt;/code&amp;gt;)&lt;br /&gt;
# Save&lt;br /&gt;
&lt;br /&gt;
The default &amp;lt;code&amp;gt;/wp-login.php&amp;lt;/code&amp;gt; now returns 404 to everyone.&lt;br /&gt;
&lt;br /&gt;
=== Layer 2 — Restrict via NPM custom location ===&lt;br /&gt;
&lt;br /&gt;
In NPM, edit your WordPress proxy host → Custom Locations tab:&lt;br /&gt;
&lt;br /&gt;
Add location: &amp;lt;code&amp;gt;/wp-login.php&amp;lt;/code&amp;gt;&lt;br /&gt;
* Forward Hostname/IP: &amp;lt;code&amp;gt;&amp;amp;lt;wordpress-server-IP&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Forward Port: &amp;lt;code&amp;gt;&amp;amp;lt;wordpress-port&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* In the gear/config box, add:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nginx&amp;quot;&amp;gt;&lt;br /&gt;
allow 192.168.196.0/24;&lt;br /&gt;
deny all;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Repeat for &amp;lt;code&amp;gt;/wp-admin/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This means even if someone discovers your hidden login URL, they cannot reach it unless they are on your ZeroTier network.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Key Takeaways ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;On security:&#039;&#039;&#039;&lt;br /&gt;
* Never follow tutorials directly on a bare server. Use Distrobox or Docker to isolate experiments.&lt;br /&gt;
* Check for open mail relays — an open Postfix is a common infection consequence.&lt;br /&gt;
* Bots scan for &amp;lt;code&amp;gt;/wp-login.php&amp;lt;/code&amp;gt; within hours of a site going live. Hide it and restrict it immediately.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;On operations:&#039;&#039;&#039;&lt;br /&gt;
* NPM is stateless enough to be fully backed up in a single tar file and restored in under 15 minutes.&lt;br /&gt;
* ZeroTier makes home servers first-class infrastructure — a cheap VPS becomes just a public IP rental.&lt;br /&gt;
* Always run &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ss -tlnp&amp;lt;/code&amp;gt; before and after a migration to confirm port ownership.&lt;br /&gt;
* When restoring, mind whether you are logged in as root or a regular user — file paths differ and commands like &amp;lt;code&amp;gt;tar -C /&amp;lt;/code&amp;gt; require root.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;On architecture:&#039;&#039;&#039;&lt;br /&gt;
* A ₱5,000/yr VPS as a pure relay is far more resilient than a ₱15–30k/yr VPS running everything. When it gets compromised again, you reformat it in 15 minutes with nothing to lose.&lt;br /&gt;
* SSL certificate renewals continue to work transparently through the relay — Let&#039;s Encrypt ACME challenges on port 80 get forwarded to your home NPM automatically.&lt;br /&gt;
&lt;br /&gt;
[[Category:System Administration]]&lt;br /&gt;
[[Category:Networking]]&lt;br /&gt;
[[Category:Docker]]&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:ZeroTier]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=214</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=214"/>
		<updated>2026-03-31T18:20:36Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: &amp;quot;Add NPM migration to homelab VPS relay guide&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f8f9fa; border:1px solid #ddd; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
Welcome to the &#039;&#039;&#039;Comfac IT Knowledge Base&#039;&#039;&#039;. Use the sections below to find guides, SOPs, and references organized by topic.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ERPNext / Frappe ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Frappe HRMS]] — &#039;&#039;&#039;HR &amp;amp; Payroll&#039;&#039;&#039; (with Philippine Localization)&lt;br /&gt;
* [[Frappe ERPNext/Webshop]] — &#039;&#039;&#039;E-Commerce Webshop&#039;&#039;&#039; (setup, architecture, chapters)&lt;br /&gt;
* [[Manufacturing v16 260125]]&lt;br /&gt;
* [[ERpnext Asset Management Procedure 260113]]&lt;br /&gt;
* [[ERPNext HR Module Outline]]&lt;br /&gt;
* [[ERPNEXT Payroll POC 251212]]&lt;br /&gt;
* [[Comfac ERPNext Strategy Canvas (Expanded)]]&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — PAD/AI-agentic implementation strategy for Frappe ERPNext&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — Local Docker setup for evaluation, testing, and student use&lt;br /&gt;
* [[Frappe Links and References]]&lt;br /&gt;
* [[Using Frappe Wiki]]&lt;br /&gt;
* [https://docs.frappe.io/cloud/guidelines-for-contributing-regional-compliance-app Guidelines for Contributing Regional Compliance App]&lt;br /&gt;
* [https://docs.frappe.io/cloud/what-are-benches-and-bench-groups What are Benches?]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Administration &amp;amp; Self-Hosting ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[NPM Migration to Homelab VPS Relay 260401]] — Move NPM off a compromised VPS; VPS becomes a pure iptables/ZeroTier relay with homelab redundancy&lt;br /&gt;
* [[pfSense Sales Training Material]]&lt;br /&gt;
* [[SOP: Network Troubleshooting &amp;amp; pfSense Monitoring 251130]]&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS &amp;amp; ACME]]&lt;br /&gt;
* [[pfSense CE → pfSense Plus Upgrade Guide]]&lt;br /&gt;
* [[Tplink Mikrotik Equivalent]]&lt;br /&gt;
* [[Skills and Competencies for IT Staff Trained in pfSense]]&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]]&lt;br /&gt;
* [[Controller Systems 251213-01]]&lt;br /&gt;
* [[Power Distribution Tree 251213]]&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]]&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]]&lt;br /&gt;
* [[Mailcow SOGo: Creating Filters for Events, Approvals, and Organizational Emails]]&lt;br /&gt;
* [[Spoof Timezone Extension – Setup Guide for Comfac Staff]]&lt;br /&gt;
* [[Viber Focus-Stealing]]&lt;br /&gt;
* [[🌐 WordPress Website — *You Own Everything, Learn Everything*]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Storage &amp;amp; Hardware ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[TrueNAS Configuration Options &amp;amp; Scale Options 251130]]&lt;br /&gt;
* [[TrueNAS Business Plan: Project 251212]]&lt;br /&gt;
* [[Comparison: TrueNAS Mini X+ vs Dell Precision 3680 Tower (2025)]]&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification]]&lt;br /&gt;
* [[Industrial Controllers and Water Utilities 251011]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== AI &amp;amp; Machine Learning ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[OpenWebUI - 251128-justin]]&lt;br /&gt;
* [[Comfac GPU Scaling and AI Research Goals]]&lt;br /&gt;
* [[🧠 Process: Selecting and Installing the Right Ollama Model for Your Hardware]]&lt;br /&gt;
* [[Ollama GNOME System Tray Panel 260401]] — GNOME system tray toggle to start/stop Ollama and reclaim VRAM&lt;br /&gt;
* [[Proceedural Agentic Development Methodology 260304]] — Methodology for systematic agent use&lt;br /&gt;
* [[Project OpenCoder: AI Independence Initiative]] — Strategic roadmap for manufacturing intelligence&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 Modelfile fix for tool calling in OpenCode; thinking mode suppression; HDD vs SSD findings&lt;br /&gt;
* [[OpenCode Multi-Provider Configuration Guide 260401]] — Dual-mode AI coding setup with Kimi cloud + Ollama local models via Distrobox&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — Procedural Agentic Development for Frappe/ERPNext configuration and deployment&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Descriptions ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Job Descriptions]] — Index of all official job descriptions (IT, Engineering, Sales)&lt;br /&gt;
* [[JD IT Project Staff]] — IT Project Staff&lt;br /&gt;
* [[JD Security Compliance Assistant 260224]] — Security and Compliance Assistant (SCA)&lt;br /&gt;
* [[JD Engineering Designer 260108]] — Engineering Designer&lt;br /&gt;
* [[JD Engineering Supervisor 260109]] — Engineering Supervisor&lt;br /&gt;
* [[JD Technical Sales 260112]] — Technical Sales Engineer&lt;br /&gt;
* [[JD Marketing Assistant 251119]] — Marketing Assistant&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IT Operations &amp;amp; SOPs ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[SCA Program Plan 260320]] — Security &amp;amp; Compliance Assistant Program Plan v3 (ISO 9001/27001, PDCA, distributed audit model)&lt;br /&gt;
* [[SOP: Inter-Company Ordering and Production Process 260203]] — Ordering and production workflow between Sister Companies and the Cabuyao Plant&lt;br /&gt;
* [[Memo: Team Roles &amp;amp; Reporting Process Clarification 260320]] — Role boundaries, data ownership, and the new ERPNext-driven reporting paradigm&lt;br /&gt;
* [[Standard Operating Procedure: Distributed Minute Taking &amp;amp; Task Ownership 251208]]&lt;br /&gt;
* [[Business Continuity]]&lt;br /&gt;
* [[Procedure: CC-Blast Data Breach Prevention]]&lt;br /&gt;
* [[8D (Eight Discipline) Problem Solving Procedure]]&lt;br /&gt;
* [[Offline Malware Remediation &amp;amp; Data Recovery]]&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [[Steps to Repair and OCR a Scanned or Corrupted PDF in Ubuntu]]&lt;br /&gt;
* [[IT IMPORTS PROCESSES]]&lt;br /&gt;
* [[IT Purchase Requests 241126]]&lt;br /&gt;
* [[IT REQUEST (OP-ERP-ITR) - EDITED 250801]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sales &amp;amp; Business ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Comfac Sales Knowledge Base]]&lt;br /&gt;
* [[Comfac CRM – Customer Qualification &amp;amp; Conversion Process]]&lt;br /&gt;
* [[Partner Reseller Pricing 251109]]&lt;br /&gt;
* [[Biz Analysis Methodology 251109]]&lt;br /&gt;
* [[2026 MIS IT KRA KPI Biz Plan]]&lt;br /&gt;
* [[SALES INVOICE TAX OUTPUT 250829]]&lt;br /&gt;
* [[Projects in Process Report 251023]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools &amp;amp; Productivity ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Excel Description Filler Tool 📝]]&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/comfac-studies Comfac Studies - Spaced Repetiton Active Recall]&lt;br /&gt;
* [[LibreOffice / Nextcloud Office – &amp;quot;Due Tasks&amp;quot; Conditional Formatting]]&lt;br /&gt;
* [[Google Drive and Shared Drive Training]]&lt;br /&gt;
* [[260108 CGG- GitHub Administration Guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wiki &amp;amp; Documentation ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Mediawiki Setting Up Guide]]&lt;br /&gt;
* [[Contributing to Only Office 260307]]&lt;br /&gt;
* [[Mediawiki Additional Configuration]]&lt;br /&gt;
* [[Mediawiki Docker Migration Guide]]&lt;br /&gt;
* [[Home]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Claude Code Isolation and Burner Workflow 260211]] — Secure AI development environment setup&lt;br /&gt;
* [[Opencode isolation and burner workflow 260216]] — OpenCode CLI isolation procedures&lt;br /&gt;
* [[LibreOffice Calc NumToWords Extension Complete Guide]] — Extension development&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — ERPNext v15 local Docker setup (students, evaluators, thin-client demos)&lt;br /&gt;
* [[Erpnextv15-SSH-setup-241111]] — ERPNext v15 SSH/Portainer production setup&lt;br /&gt;
* [[Git-Mediawiki Local Editing 260223]] — Wiki editing with Git&lt;br /&gt;
* [[Understanding &amp;amp; Fixing Kernel Panics 260212]] — System debugging&lt;br /&gt;
* [[OpenCode in Android Termux 260303]] — OpenCode in Android&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 agentic setup: Modelfile, tool calling fix, storage impact&lt;br /&gt;
* [[Lora Basics 260304]] — LORA research&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Research ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Ladybird Browser]] — Browser engine development&lt;br /&gt;
* [[Computing Architecture]] — System design principles&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification 260219]] — Drive reliability analysis&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== For Users Only ==&lt;br /&gt;
* [[Private:Private Ngani]]&lt;br /&gt;
* [[Private:Private Nganipart2]]&lt;br /&gt;
&lt;br /&gt;
== CIT-OJT Project Documentations ==&lt;br /&gt;
* [[OJTDocs: For OJTs only]]&lt;br /&gt;
&lt;br /&gt;
== Need Help? ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents MediaWiki User&#039;s Guide]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=OpenCode_Multi-Provider_Configuration_Guide_260401&amp;diff=213</id>
		<title>OpenCode Multi-Provider Configuration Guide 260401</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=OpenCode_Multi-Provider_Configuration_Guide_260401&amp;diff=213"/>
		<updated>2026-03-31T16:40:51Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: &amp;quot;Add OpenCode Multi-Provider Configuration Guide wiki entry&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= OpenCode Multi-Provider Configuration Guide =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Date:&#039;&#039;&#039; 2026-04-01&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Author:&#039;&#039;&#039; Justin / Comfac IT / CGG R&amp;amp;D &amp;amp; BD&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Status:&#039;&#039;&#039; 📋 Reference Configuration&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Related:&#039;&#039;&#039; [[OpenCoder Qwen35 Agentic Setup 260330]], [[Project OpenCoder: AI Independence Initiative]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This configuration enables a &#039;&#039;&#039;dual-mode AI coding environment&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Cloud&#039;&#039;&#039;: Kimi&#039;s managed models (&amp;lt;code&amp;gt;kimi-for-coding&amp;lt;/code&amp;gt;) via Kimi API&lt;br /&gt;
* &#039;&#039;&#039;Local&#039;&#039;&#039;: Multiple Qwen models via Ollama (running in Distrobox)&lt;br /&gt;
&lt;br /&gt;
{{mbox | type = warning | text = ⚠️ &#039;&#039;&#039;Critical Note&#039;&#039;&#039;: This setup runs inside a &#039;&#039;&#039;Distrobox container&#039;&#039;&#039; with a custom home directory mapping (non-standard &amp;lt;code&amp;gt;$HOME&amp;lt;/code&amp;gt; location). All paths in this config are relative to that mapped directory.}}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Architecture Overview ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
┌─────────────────────────────────────────┐&lt;br /&gt;
│           MCP Client (Host)             │&lt;br /&gt;
│  ┌──────────────┐    ┌──────────────┐  │&lt;br /&gt;
│  │ Kimi Managed │    │ Local Ollama │  │&lt;br /&gt;
│  │  (Cloud API) │    │  (Container) │  │&lt;br /&gt;
│  └──────────────┘    └──────────────┘  │&lt;br /&gt;
└─────────────────────────────────────────┘&lt;br /&gt;
           │&lt;br /&gt;
    ┌──────┴──────┐&lt;br /&gt;
    ▼             ▼&lt;br /&gt;
[Claude]  [OpenCode]  [Aider]  [Qwen]&lt;br /&gt;
   MCP        MCP       MCP      MCP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Key Feature&#039;&#039;&#039;: You can use &#039;&#039;&#039;Kimi as an MCP server&#039;&#039;&#039; to power other MCP clients (Claude Desktop, OpenCode, Aider, etc.) while leveraging local models.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Configuration Sections ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Default Behavior (&amp;lt;code&amp;gt;[defaults]&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
default_model = &amp;quot;kimi-code/kimi-for-coding&amp;quot;&lt;br /&gt;
default_thinking = true        # Enable reasoning/thinking tokens&lt;br /&gt;
default_yolo = false          # Require confirmation for destructive ops&lt;br /&gt;
default_editor = &amp;quot;&amp;quot;           # Auto-detect editor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{mbox | type = warning | text = ⚠️ &#039;&#039;&#039;Critical&#039;&#039;&#039;: &amp;lt;code&amp;gt;default_yolo = false&amp;lt;/code&amp;gt; is recommended for production code. Set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; only for fully automated workflows.}}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 2. Managed Provider: Kimi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[models.&amp;quot;kimi-code/kimi-for-coding&amp;quot;]&lt;br /&gt;
provider = &amp;quot;managed:kimi-code&amp;quot;&lt;br /&gt;
model = &amp;quot;kimi-for-coding&amp;quot;&lt;br /&gt;
max_context_size = 262144     # 256k context window&lt;br /&gt;
capabilities = [&amp;quot;thinking&amp;quot;, &amp;quot;image_in&amp;quot;, &amp;quot;video_in&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Key Points&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Context Size&#039;&#039;&#039;: 262144 tokens (256k) — suitable for large codebases&lt;br /&gt;
* &#039;&#039;&#039;Capabilities&#039;&#039;&#039;:&lt;br /&gt;
** &amp;lt;code&amp;gt;thinking&amp;lt;/code&amp;gt;: Reasoning/research mode&lt;br /&gt;
** &amp;lt;code&amp;gt;image_in&amp;lt;/code&amp;gt;: Screenshot/UI analysis&lt;br /&gt;
** &amp;lt;code&amp;gt;video_in&amp;lt;/code&amp;gt;: Video processing (if supported)&lt;br /&gt;
* &#039;&#039;&#039;OAuth Storage&#039;&#039;&#039;: Credentials stored in &amp;lt;code&amp;gt;oauth/kimi-code&amp;lt;/code&amp;gt; (relative to mapped home)&lt;br /&gt;
&lt;br /&gt;
{{mbox | type = notice | text = 💡 &#039;&#039;&#039;Distrobox Note&#039;&#039;&#039;: Since home is remapped, OAuth tokens persist in your chosen directory, not &amp;lt;code&amp;gt;~/.config&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 3. Local Provider: Ollama ===&lt;br /&gt;
&lt;br /&gt;
You have &#039;&#039;&#039;6 local models&#039;&#039;&#039; configured covering different use cases:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Model !! Size !! Context !! Best For&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;qwen3.5-4b&amp;lt;/code&amp;gt; || 4B || 131k || Quick tasks, low latency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;qwen3.5-9b&amp;lt;/code&amp;gt; || 9B || 131k || General coding, reasoning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;qwen3.5-9b-instruct&amp;lt;/code&amp;gt; || 9B || 32k || Instruction following&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;qwen2.5-coder-7b&amp;lt;/code&amp;gt; || 7B || 32k || Code-specific tasks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;qwen3-vl-2b&amp;lt;/code&amp;gt; || 2B || 32k || Vision + coding&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;qwen3-vl-grammar&amp;lt;/code&amp;gt; || - || 32k || Grammar/validation tasks&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[providers.ollama]&lt;br /&gt;
type = &amp;quot;openai_legacy&amp;quot;&lt;br /&gt;
base_url = &amp;quot;http://localhost:11434/v1&amp;quot;&lt;br /&gt;
api_key = &amp;quot;ollama&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{mbox | type = notice | text = 💡 &#039;&#039;&#039;Distrobox Networking&#039;&#039;&#039;: &amp;lt;code&amp;gt;localhost:11434&amp;lt;/code&amp;gt; refers to the container&#039;s localhost. Ensure Ollama is running inside the same Distrobox or exposed to the container.}}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 4. Loop Control (&amp;lt;code&amp;gt;[loop_control]&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
max_steps_per_turn = 100           # Max operations per request&lt;br /&gt;
max_retries_per_step = 3           # Retry failed operations&lt;br /&gt;
max_ralph_iterations = 0             # Legacy/compatibility setting&lt;br /&gt;
reserved_context_size = 50000        # Reserve 50k tokens for system&lt;br /&gt;
compaction_trigger_ratio = 0.85      # Compact memory at 85% usage&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tuning Tips&#039;&#039;&#039;:&lt;br /&gt;
* Increase &amp;lt;code&amp;gt;max_steps_per_turn&amp;lt;/code&amp;gt; for complex refactoring (risk: higher API costs)&lt;br /&gt;
* Lower &amp;lt;code&amp;gt;compaction_trigger_ratio&amp;lt;/code&amp;gt; to 0.75 if working with very large files&lt;br /&gt;
* &amp;lt;code&amp;gt;reserved_context_size&amp;lt;/code&amp;gt; prevents context overflow crashes&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 5. Background Processing (&amp;lt;code&amp;gt;[background]&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
max_running_tasks = 4               # Parallel background operations&lt;br /&gt;
read_max_bytes = 30000              # 30KB file read limit&lt;br /&gt;
notification_tail_lines = 20        # Lines in status notifications&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{mbox | type = notice | text = 💡 &#039;&#039;&#039;Distrobox Consideration&#039;&#039;&#039;: Background tasks write to the mapped home directory. Ensure sufficient disk space in that location.}}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 6. Moonshot Services (&amp;lt;code&amp;gt;[services.*]&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[services.moonshot_search]&lt;br /&gt;
base_url = &amp;quot;https://api.kimi.com/coding/v1/search&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[services.moonshot_fetch]&lt;br /&gt;
base_url = &amp;quot;https://api.kimi.com/coding/v1/fetch&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These enable &#039;&#039;&#039;web search&#039;&#039;&#039; and &#039;&#039;&#039;URL fetching&#039;&#039;&#039; capabilities within the Kimi ecosystem. OAuth credentials are shared with the main provider.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 7. MCP Client Settings (&amp;lt;code&amp;gt;[mcp.client]&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mcp.client]&lt;br /&gt;
tool_call_timeout_ms = 60000        # 60 second timeout for tools&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{mbox | type = notice | text = 💡 &#039;&#039;&#039;Important&#039;&#039;&#039;: When using Kimi as an MCP for local models, this timeout applies to operations triggered by the local model via Kimi&#039;s tools.}}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Advanced Usage Patterns ==&lt;br /&gt;
&lt;br /&gt;
=== Pattern 1: Kimi as MCP Server for Local Models ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Scenario&#039;&#039;&#039;: You want to use &amp;lt;code&amp;gt;qwen3.5-9b&amp;lt;/code&amp;gt; (local) for code generation, but leverage Kimi&#039;s search/fetch tools.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Setup&#039;&#039;&#039;:&lt;br /&gt;
# Configure your MCP client (Claude/OpenCode/Aider) to point to this config&lt;br /&gt;
# Set &amp;lt;code&amp;gt;default_model&amp;lt;/code&amp;gt; to an Ollama model in the client&lt;br /&gt;
# The client can still invoke Kimi&#039;s tools (search, fetch) via the MCP bridge&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Config Override&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Temporarily switch to local&lt;br /&gt;
default_model = &amp;quot;qwen3.5-9b&amp;quot;&lt;br /&gt;
default_thinking = true  # Qwen supports thinking&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Pattern 2: Distrobox Path Mapping ===&lt;br /&gt;
&lt;br /&gt;
Since your home is remapped (e.g., &amp;lt;code&amp;gt;/mnt/projects/ai-home&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;/home/user&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# OAuth paths are relative to the mapped home&lt;br /&gt;
[providers.&amp;quot;managed:kimi-code&amp;quot;.oauth]&lt;br /&gt;
storage = &amp;quot;file&amp;quot;&lt;br /&gt;
key = &amp;quot;oauth/kimi-code&amp;quot;  # Resolves to /mnt/projects/ai-home/oauth/kimi-code&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Verification&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Inside Distrobox&lt;br /&gt;
echo $HOME                    # Should show /mnt/projects/ai-home (or your mapping)&lt;br /&gt;
ls $HOME/oauth/kimi-code      # Should contain OAuth tokens&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Pattern 3: Model Switching Workflows ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# High-level architecture discussion&lt;br /&gt;
default_model = &amp;quot;kimi-code/kimi-for-coding&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Quick local edits (low latency)&lt;br /&gt;
alias_model = &amp;quot;qwen3.5-4b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Complex reasoning (local, private)&lt;br /&gt;
secure_model = &amp;quot;qwen3.5-9b&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Command Palette&#039;&#039;&#039; (if your client supports it):&lt;br /&gt;
* &amp;lt;code&amp;gt;/model kimi-code/kimi-for-coding&amp;lt;/code&amp;gt; — Cloud, full capabilities&lt;br /&gt;
* &amp;lt;code&amp;gt;/model qwen3.5-9b&amp;lt;/code&amp;gt; — Local, private, reasoning&lt;br /&gt;
* &amp;lt;code&amp;gt;/model qwen3-vl-2b&amp;lt;/code&amp;gt; — Vision tasks with local image analysis&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Distrobox-Specific Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Volume Mounts Checklist ===&lt;br /&gt;
&lt;br /&gt;
Ensure your Distrobox creation included:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
distrobox create --name ai-dev \&lt;br /&gt;
  --home /mnt/projects/ai-home \          # Matches your config&lt;br /&gt;
  --additional-flags &amp;quot;--volume /mnt/projects:/mnt/projects&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Ollama Inside Distrobox ===&lt;br /&gt;
&lt;br /&gt;
If Ollama runs in the same container:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Start Ollama before the MCP client&lt;br /&gt;
ollama serve &amp;amp;  # Binds to localhost:11434 inside container&lt;br /&gt;
&lt;br /&gt;
# Verify models are available&lt;br /&gt;
ollama list | grep qwen&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Persisting OAuth Tokens ===&lt;br /&gt;
&lt;br /&gt;
Since home is custom, tokens survive container recreation:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
tar czf oauth-backup.tar.gz $HOME/oauth/&lt;br /&gt;
&lt;br /&gt;
# Restore (new container)&lt;br /&gt;
tar xzf oauth-backup.tar.gz -C $HOME/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Security &amp;amp; Best Practices ==&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;API Keys&#039;&#039;&#039;: Empty strings in config (&amp;lt;code&amp;gt;api_key = &amp;quot;&amp;quot;&amp;lt;/code&amp;gt;) indicate OAuth-only. Never hardcode keys in the TOML file.&lt;br /&gt;
# &#039;&#039;&#039;YOLO Mode&#039;&#039;&#039;: Keep &amp;lt;code&amp;gt;default_yolo = false&amp;lt;/code&amp;gt; unless running in a fully containerized/throwaway environment.&lt;br /&gt;
# &#039;&#039;&#039;Context Window&#039;&#039;&#039;: The 256k context for Kimi vs 32k/131k for local models — be mindful when switching contexts.&lt;br /&gt;
# &#039;&#039;&#039;Distrobox Isolation&#039;&#039;&#039;: Your remapped home provides natural isolation. Sensitive data stays in your mapped directory, not system home.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Issue: &amp;quot;Ollama connection refused&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause&#039;&#039;&#039;: Ollama not running or not exposed to Distrobox&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Check if Ollama is listening&lt;br /&gt;
curl http://localhost:11434/api/tags&lt;br /&gt;
&lt;br /&gt;
# If using host Ollama from inside Distrobox, use host IP&lt;br /&gt;
# Edit base_url to: http://host.docker.internal:11434/v1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Issue: OAuth token not found ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause&#039;&#039;&#039;: Wrong home directory mapping&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix&#039;&#039;&#039;: Verify &amp;lt;code&amp;gt;$HOME&amp;lt;/code&amp;gt; inside Distrobox matches where you expect &amp;lt;code&amp;gt;oauth/&amp;lt;/code&amp;gt; to live.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Issue: Context overflow with local models ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cause&#039;&#039;&#039;: &amp;lt;code&amp;gt;max_context_size&amp;lt;/code&amp;gt; mismatch&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fix&#039;&#039;&#039;: Ensure your prompt + file contents &amp;amp;lt; model&#039;s &amp;lt;code&amp;gt;max_context_size&amp;lt;/code&amp;gt; (32k for most Qwen models vs 256k for Kimi).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Quick Reference: Model Selection ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Task !! Recommended Model !! Why&lt;br /&gt;
|-&lt;br /&gt;
| Architecture decisions || &amp;lt;code&amp;gt;kimi-code/kimi-for-coding&amp;lt;/code&amp;gt; || 256k context, reasoning&lt;br /&gt;
|-&lt;br /&gt;
| Quick bug fixes || &amp;lt;code&amp;gt;qwen3.5-4b&amp;lt;/code&amp;gt; || Fast, sufficient context&lt;br /&gt;
|-&lt;br /&gt;
| Complex refactoring || &amp;lt;code&amp;gt;qwen3.5-9b&amp;lt;/code&amp;gt; (131k) || Large context, private&lt;br /&gt;
|-&lt;br /&gt;
| Image → Code || &amp;lt;code&amp;gt;qwen3-vl-2b&amp;lt;/code&amp;gt; || Vision capabilities, local&lt;br /&gt;
|-&lt;br /&gt;
| Documentation || &amp;lt;code&amp;gt;qwen2.5-coder-7b&amp;lt;/code&amp;gt; || Code-optimized, offline&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 Modelfile fix for tool calling&lt;br /&gt;
* [[Project OpenCoder: AI Independence Initiative]] — Strategic roadmap&lt;br /&gt;
* [[Proceedural Agentic Development Methodology 260304]] — PAD methodology&lt;br /&gt;
* [[Opencode isolation and burner workflow 260216]] — Distrobox burner workflow&lt;br /&gt;
* [[Ollama GNOME System Tray Panel 260401]] — Ollama system tray toggle&lt;br /&gt;
* [[🧠 Process: Selecting and Installing the Right Ollama Model for Your Hardware]] — Model selection guide&lt;br /&gt;
&lt;br /&gt;
[[Category:AI]]&lt;br /&gt;
[[Category:OpenCode]]&lt;br /&gt;
[[Category:Ollama]]&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:Comfac IT]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=212</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=212"/>
		<updated>2026-03-31T16:40:51Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: &amp;quot;Add OpenCode Multi-Provider Configuration Guide wiki entry&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f8f9fa; border:1px solid #ddd; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
Welcome to the &#039;&#039;&#039;Comfac IT Knowledge Base&#039;&#039;&#039;. Use the sections below to find guides, SOPs, and references organized by topic.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ERPNext / Frappe ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Frappe HRMS]] — &#039;&#039;&#039;HR &amp;amp; Payroll&#039;&#039;&#039; (with Philippine Localization)&lt;br /&gt;
* [[Frappe ERPNext/Webshop]] — &#039;&#039;&#039;E-Commerce Webshop&#039;&#039;&#039; (setup, architecture, chapters)&lt;br /&gt;
* [[Manufacturing v16 260125]]&lt;br /&gt;
* [[ERpnext Asset Management Procedure 260113]]&lt;br /&gt;
* [[ERPNext HR Module Outline]]&lt;br /&gt;
* [[ERPNEXT Payroll POC 251212]]&lt;br /&gt;
* [[Comfac ERPNext Strategy Canvas (Expanded)]]&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — PAD/AI-agentic implementation strategy for Frappe ERPNext&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — Local Docker setup for evaluation, testing, and student use&lt;br /&gt;
* [[Frappe Links and References]]&lt;br /&gt;
* [[Using Frappe Wiki]]&lt;br /&gt;
* [https://docs.frappe.io/cloud/guidelines-for-contributing-regional-compliance-app Guidelines for Contributing Regional Compliance App]&lt;br /&gt;
* [https://docs.frappe.io/cloud/what-are-benches-and-bench-groups What are Benches?]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Administration &amp;amp; Self-Hosting ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[pfSense Sales Training Material]]&lt;br /&gt;
* [[SOP: Network Troubleshooting &amp;amp; pfSense Monitoring 251130]]&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS &amp;amp; ACME]]&lt;br /&gt;
* [[pfSense CE → pfSense Plus Upgrade Guide]]&lt;br /&gt;
* [[Tplink Mikrotik Equivalent]]&lt;br /&gt;
* [[Skills and Competencies for IT Staff Trained in pfSense]]&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]]&lt;br /&gt;
* [[Controller Systems 251213-01]]&lt;br /&gt;
* [[Power Distribution Tree 251213]]&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]]&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]]&lt;br /&gt;
* [[Mailcow SOGo: Creating Filters for Events, Approvals, and Organizational Emails]]&lt;br /&gt;
* [[Spoof Timezone Extension – Setup Guide for Comfac Staff]]&lt;br /&gt;
* [[Viber Focus-Stealing]]&lt;br /&gt;
* [[🌐 WordPress Website — *You Own Everything, Learn Everything*]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Storage &amp;amp; Hardware ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[TrueNAS Configuration Options &amp;amp; Scale Options 251130]]&lt;br /&gt;
* [[TrueNAS Business Plan: Project 251212]]&lt;br /&gt;
* [[Comparison: TrueNAS Mini X+ vs Dell Precision 3680 Tower (2025)]]&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification]]&lt;br /&gt;
* [[Industrial Controllers and Water Utilities 251011]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== AI &amp;amp; Machine Learning ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[OpenWebUI - 251128-justin]]&lt;br /&gt;
* [[Comfac GPU Scaling and AI Research Goals]]&lt;br /&gt;
* [[🧠 Process: Selecting and Installing the Right Ollama Model for Your Hardware]]&lt;br /&gt;
* [[Ollama GNOME System Tray Panel 260401]] — GNOME system tray toggle to start/stop Ollama and reclaim VRAM&lt;br /&gt;
* [[Proceedural Agentic Development Methodology 260304]] — Methodology for systematic agent use&lt;br /&gt;
* [[Project OpenCoder: AI Independence Initiative]] — Strategic roadmap for manufacturing intelligence&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 Modelfile fix for tool calling in OpenCode; thinking mode suppression; HDD vs SSD findings&lt;br /&gt;
* [[OpenCode Multi-Provider Configuration Guide 260401]] — Dual-mode AI coding setup with Kimi cloud + Ollama local models via Distrobox&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — Procedural Agentic Development for Frappe/ERPNext configuration and deployment&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Descriptions ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Job Descriptions]] — Index of all official job descriptions (IT, Engineering, Sales)&lt;br /&gt;
* [[JD IT Project Staff]] — IT Project Staff&lt;br /&gt;
* [[JD Security Compliance Assistant 260224]] — Security and Compliance Assistant (SCA)&lt;br /&gt;
* [[JD Engineering Designer 260108]] — Engineering Designer&lt;br /&gt;
* [[JD Engineering Supervisor 260109]] — Engineering Supervisor&lt;br /&gt;
* [[JD Technical Sales 260112]] — Technical Sales Engineer&lt;br /&gt;
* [[JD Marketing Assistant 251119]] — Marketing Assistant&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IT Operations &amp;amp; SOPs ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[SCA Program Plan 260320]] — Security &amp;amp; Compliance Assistant Program Plan v3 (ISO 9001/27001, PDCA, distributed audit model)&lt;br /&gt;
* [[SOP: Inter-Company Ordering and Production Process 260203]] — Ordering and production workflow between Sister Companies and the Cabuyao Plant&lt;br /&gt;
* [[Memo: Team Roles &amp;amp; Reporting Process Clarification 260320]] — Role boundaries, data ownership, and the new ERPNext-driven reporting paradigm&lt;br /&gt;
* [[Standard Operating Procedure: Distributed Minute Taking &amp;amp; Task Ownership 251208]]&lt;br /&gt;
* [[Business Continuity]]&lt;br /&gt;
* [[Procedure: CC-Blast Data Breach Prevention]]&lt;br /&gt;
* [[8D (Eight Discipline) Problem Solving Procedure]]&lt;br /&gt;
* [[Offline Malware Remediation &amp;amp; Data Recovery]]&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [[Steps to Repair and OCR a Scanned or Corrupted PDF in Ubuntu]]&lt;br /&gt;
* [[IT IMPORTS PROCESSES]]&lt;br /&gt;
* [[IT Purchase Requests 241126]]&lt;br /&gt;
* [[IT REQUEST (OP-ERP-ITR) - EDITED 250801]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sales &amp;amp; Business ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Comfac Sales Knowledge Base]]&lt;br /&gt;
* [[Comfac CRM – Customer Qualification &amp;amp; Conversion Process]]&lt;br /&gt;
* [[Partner Reseller Pricing 251109]]&lt;br /&gt;
* [[Biz Analysis Methodology 251109]]&lt;br /&gt;
* [[2026 MIS IT KRA KPI Biz Plan]]&lt;br /&gt;
* [[SALES INVOICE TAX OUTPUT 250829]]&lt;br /&gt;
* [[Projects in Process Report 251023]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools &amp;amp; Productivity ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Excel Description Filler Tool 📝]]&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/comfac-studies Comfac Studies - Spaced Repetiton Active Recall]&lt;br /&gt;
* [[LibreOffice / Nextcloud Office – &amp;quot;Due Tasks&amp;quot; Conditional Formatting]]&lt;br /&gt;
* [[Google Drive and Shared Drive Training]]&lt;br /&gt;
* [[260108 CGG- GitHub Administration Guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wiki &amp;amp; Documentation ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Mediawiki Setting Up Guide]]&lt;br /&gt;
* [[Contributing to Only Office 260307]]&lt;br /&gt;
* [[Mediawiki Additional Configuration]]&lt;br /&gt;
* [[Mediawiki Docker Migration Guide]]&lt;br /&gt;
* [[Home]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Claude Code Isolation and Burner Workflow 260211]] — Secure AI development environment setup&lt;br /&gt;
* [[Opencode isolation and burner workflow 260216]] — OpenCode CLI isolation procedures&lt;br /&gt;
* [[LibreOffice Calc NumToWords Extension Complete Guide]] — Extension development&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — ERPNext v15 local Docker setup (students, evaluators, thin-client demos)&lt;br /&gt;
* [[Erpnextv15-SSH-setup-241111]] — ERPNext v15 SSH/Portainer production setup&lt;br /&gt;
* [[Git-Mediawiki Local Editing 260223]] — Wiki editing with Git&lt;br /&gt;
* [[Understanding &amp;amp; Fixing Kernel Panics 260212]] — System debugging&lt;br /&gt;
* [[OpenCode in Android Termux 260303]] — OpenCode in Android&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 agentic setup: Modelfile, tool calling fix, storage impact&lt;br /&gt;
* [[Lora Basics 260304]] — LORA research&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Research ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Ladybird Browser]] — Browser engine development&lt;br /&gt;
* [[Computing Architecture]] — System design principles&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification 260219]] — Drive reliability analysis&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== For Users Only ==&lt;br /&gt;
* [[Private:Private Ngani]]&lt;br /&gt;
* [[Private:Private Nganipart2]]&lt;br /&gt;
&lt;br /&gt;
== CIT-OJT Project Documentations ==&lt;br /&gt;
* [[OJTDocs: For OJTs only]]&lt;br /&gt;
&lt;br /&gt;
== Need Help? ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents MediaWiki User&#039;s Guide]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Ollama_GNOME_System_Tray_Panel_260401&amp;diff=211</id>
		<title>Ollama GNOME System Tray Panel 260401</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Ollama_GNOME_System_Tray_Panel_260401&amp;diff=211"/>
		<updated>2026-03-31T16:38:11Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: &amp;quot;Add Ollama GNOME System Tray Panel guide&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Adding an Ollama System Tray Control to GNOME (Ubuntu) =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
When using Ollama locally, large language models (LLMs) are loaded directly into your GPU&#039;s VRAM for fast processing. However, Ollama keeps these models &amp;quot;hot&amp;quot; in memory for a period of time after you finish chatting. If you are running heavy models (like a 7B or 8B parameter model), this can easily consume 5GB+ of VRAM, leaving little room for gaming, video editing, or other GPU-intensive tasks.&lt;br /&gt;
&lt;br /&gt;
Instead of repeatedly opening a terminal to run &amp;lt;code&amp;gt;systemctl&amp;lt;/code&amp;gt; commands to kill the service, you can create a lightweight GNOME panel application (system tray icon). This utility provides a simple, two-click visual interface to start and stop the Ollama background service, immediately freeing up your VRAM when needed.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;One-Click Controls:&#039;&#039;&#039; Start or stop the Ollama systemd service directly from the top panel.&lt;br /&gt;
* &#039;&#039;&#039;Visual Status:&#039;&#039;&#039; The icon dynamically changes to show whether Ollama is currently running (&amp;lt;code&amp;gt;▶&amp;lt;/code&amp;gt;) or stopped (&amp;lt;code&amp;gt;⏸&amp;lt;/code&amp;gt;).&lt;br /&gt;
* &#039;&#039;&#039;Asynchronous Execution:&#039;&#039;&#039; Uses background threading so password prompts (&amp;lt;code&amp;gt;pkexec&amp;lt;/code&amp;gt;) do not freeze your desktop environment.&lt;br /&gt;
* &#039;&#039;&#039;Auto-Polling:&#039;&#039;&#039; Detects if Ollama was started or stopped from a terminal and updates the panel icon automatically.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Install Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
You will need the Python bindings for GTK3 and AppIndicator to allow the script to integrate with the GNOME top panel.&lt;br /&gt;
&lt;br /&gt;
Open your terminal and run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install python3-gi python3-gi-cairo gir1.2-appindicator3-0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Create the Python Script ===&lt;br /&gt;
&lt;br /&gt;
Create a new Python file in a permanent location, such as your home directory or a dedicated scripts folder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano ~/ollama-panel.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following code into the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
import gi&lt;br /&gt;
import subprocess&lt;br /&gt;
import threading&lt;br /&gt;
&lt;br /&gt;
# Require the necessary GTK and AppIndicator versions&lt;br /&gt;
gi.require_version(&#039;Gtk&#039;, &#039;3.0&#039;)&lt;br /&gt;
gi.require_version(&#039;AppIndicator3&#039;, &#039;0.1&#039;)&lt;br /&gt;
from gi.repository import Gtk, AppIndicator3, GLib&lt;br /&gt;
&lt;br /&gt;
class OllamaIndicator:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        # Initialize with a placeholder icon; it will update immediately&lt;br /&gt;
        self.indicator = AppIndicator3.Indicator.new(&lt;br /&gt;
            &amp;quot;ollama_indicator&amp;quot;,&lt;br /&gt;
            &amp;quot;system-run&amp;quot;,&lt;br /&gt;
            AppIndicator3.IndicatorCategory.APPLICATION_STATUS&lt;br /&gt;
        )&lt;br /&gt;
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)&lt;br /&gt;
&lt;br /&gt;
        self.menu = Gtk.Menu()&lt;br /&gt;
&lt;br /&gt;
        # Start Button&lt;br /&gt;
        self.start_item = Gtk.MenuItem(label=&#039;▶ Start Ollama&#039;)&lt;br /&gt;
        self.start_item.connect(&#039;activate&#039;, lambda _: self.run_systemctl(&#039;start&#039;))&lt;br /&gt;
        self.menu.append(self.start_item)&lt;br /&gt;
&lt;br /&gt;
        # Stop Button&lt;br /&gt;
        self.stop_item = Gtk.MenuItem(label=&#039;⏹ Stop Ollama&#039;)&lt;br /&gt;
        self.stop_item.connect(&#039;activate&#039;, lambda _: self.run_systemctl(&#039;stop&#039;))&lt;br /&gt;
        self.menu.append(self.stop_item)&lt;br /&gt;
&lt;br /&gt;
        self.menu.append(Gtk.SeparatorMenuItem())&lt;br /&gt;
&lt;br /&gt;
        # Quit Button&lt;br /&gt;
        quit_item = Gtk.MenuItem(label=&#039;Quit Panel App&#039;)&lt;br /&gt;
        quit_item.connect(&#039;activate&#039;, Gtk.main_quit)&lt;br /&gt;
        self.menu.append(quit_item)&lt;br /&gt;
&lt;br /&gt;
        self.menu.show_all()&lt;br /&gt;
        self.indicator.set_menu(self.menu)&lt;br /&gt;
&lt;br /&gt;
        # Run an initial status check&lt;br /&gt;
        self.update_status()&lt;br /&gt;
&lt;br /&gt;
        # Poll systemctl every 3 seconds to catch external changes&lt;br /&gt;
        GLib.timeout_add_seconds(3, self.update_status)&lt;br /&gt;
&lt;br /&gt;
    def get_ollama_status(self):&lt;br /&gt;
        # Suppress errors/output so it fails gracefully if cancelled&lt;br /&gt;
        result = subprocess.run(&lt;br /&gt;
            [&amp;quot;systemctl&amp;quot;, &amp;quot;is-active&amp;quot;, &amp;quot;ollama&amp;quot;],&lt;br /&gt;
            capture_output=True, text=True&lt;br /&gt;
        )&lt;br /&gt;
        return result.stdout.strip() == &amp;quot;active&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def update_status(self):&lt;br /&gt;
        active = self.get_ollama_status()&lt;br /&gt;
&lt;br /&gt;
        if active:&lt;br /&gt;
            self.indicator.set_icon_full(&amp;quot;media-playback-start&amp;quot;, &amp;quot;Ollama is running&amp;quot;)&lt;br /&gt;
            self.start_item.set_sensitive(False)&lt;br /&gt;
            self.stop_item.set_sensitive(True)&lt;br /&gt;
        else:&lt;br /&gt;
            self.indicator.set_icon_full(&amp;quot;media-playback-pause&amp;quot;, &amp;quot;Ollama is stopped&amp;quot;)&lt;br /&gt;
            self.start_item.set_sensitive(True)&lt;br /&gt;
            self.stop_item.set_sensitive(False)&lt;br /&gt;
&lt;br /&gt;
        return True # Returning True keeps the GLib timer running&lt;br /&gt;
&lt;br /&gt;
    def run_systemctl(self, command):&lt;br /&gt;
        def execute():&lt;br /&gt;
            # Run the command and wait for it to finish (or be cancelled)&lt;br /&gt;
            subprocess.run([&amp;quot;pkexec&amp;quot;, &amp;quot;systemctl&amp;quot;, command, &amp;quot;ollama&amp;quot;])&lt;br /&gt;
            # Schedule a UI update on the main GTK thread once done&lt;br /&gt;
            GLib.idle_add(self.update_status)&lt;br /&gt;
&lt;br /&gt;
        # Fire in a background thread so the polkit prompt doesn&#039;t freeze the panel&lt;br /&gt;
        threading.Thread(target=execute, daemon=True).start()&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    app = OllamaIndicator()&lt;br /&gt;
    Gtk.main()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save the file and exit your text editor.&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Make the Script Executable ===&lt;br /&gt;
&lt;br /&gt;
Grant the script permission to run as an executable program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod +x ~/ollama-panel.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can test it immediately by running &amp;lt;code&amp;gt;python3 ~/ollama-panel.py&amp;lt;/code&amp;gt;. An icon should appear in your top-right system tray.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Optional: Configure Passwordless Toggling ==&lt;br /&gt;
&lt;br /&gt;
By default, clicking &amp;quot;Start&amp;quot; or &amp;quot;Stop&amp;quot; will bring up a graphical prompt asking for your sudo password. If you want to bypass this for convenience:&lt;br /&gt;
&lt;br /&gt;
# Open the sudoers editor safely:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo visudo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Add this line to the very bottom of the file (replace &amp;lt;code&amp;gt;your_username&amp;lt;/code&amp;gt; with your actual Ubuntu username):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
your_username ALL=(ALL) NOPASSWD: /bin/systemctl start ollama, /bin/systemctl stop ollama&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Save and exit.&lt;br /&gt;
# Open &amp;lt;code&amp;gt;~/ollama-panel.py&amp;lt;/code&amp;gt; and change the &amp;lt;code&amp;gt;subprocess.run&amp;lt;/code&amp;gt; line inside the &amp;lt;code&amp;gt;execute()&amp;lt;/code&amp;gt; function from &amp;lt;code&amp;gt;&amp;quot;pkexec&amp;quot;&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;&amp;quot;sudo&amp;quot;&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
subprocess.run([&amp;quot;sudo&amp;quot;, &amp;quot;systemctl&amp;quot;, command, &amp;quot;ollama&amp;quot;])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Setting Up Autostart (Run on Boot) ==&lt;br /&gt;
&lt;br /&gt;
To ensure the control panel is always available when you log in:&lt;br /&gt;
&lt;br /&gt;
# Open the &#039;&#039;&#039;Startup Applications&#039;&#039;&#039; tool from your Ubuntu application menu.&lt;br /&gt;
# Click &#039;&#039;&#039;Add&#039;&#039;&#039;.&lt;br /&gt;
# Fill in the fields:&lt;br /&gt;
#* &#039;&#039;&#039;Name:&#039;&#039;&#039; Ollama Control Panel&lt;br /&gt;
#* &#039;&#039;&#039;Command:&#039;&#039;&#039; &amp;lt;code&amp;gt;/usr/bin/python3 /home/YOUR_USERNAME/ollama-panel.py&amp;lt;/code&amp;gt; — ensure you use the absolute path to your script&lt;br /&gt;
#* &#039;&#039;&#039;Comment:&#039;&#039;&#039; System tray toggle for the Ollama service.&lt;br /&gt;
# Click &#039;&#039;&#039;Save&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Category:System Administration]]&lt;br /&gt;
[[Category:AI]]&lt;br /&gt;
[[Category:Ollama]]&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:GNOME]]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=210</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Main_Page&amp;diff=210"/>
		<updated>2026-03-31T16:38:11Z</updated>

		<summary type="html">&lt;p&gt;Justinaquino: &amp;quot;Add Ollama GNOME System Tray Panel guide&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f8f9fa; border:1px solid #ddd; border-radius:4px; padding:12px 16px; margin-bottom:20px;&amp;quot;&amp;gt;&lt;br /&gt;
Welcome to the &#039;&#039;&#039;Comfac IT Knowledge Base&#039;&#039;&#039;. Use the sections below to find guides, SOPs, and references organized by topic.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ERPNext / Frappe ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Frappe HRMS]] — &#039;&#039;&#039;HR &amp;amp; Payroll&#039;&#039;&#039; (with Philippine Localization)&lt;br /&gt;
* [[Frappe ERPNext/Webshop]] — &#039;&#039;&#039;E-Commerce Webshop&#039;&#039;&#039; (setup, architecture, chapters)&lt;br /&gt;
* [[Manufacturing v16 260125]]&lt;br /&gt;
* [[ERpnext Asset Management Procedure 260113]]&lt;br /&gt;
* [[ERPNext HR Module Outline]]&lt;br /&gt;
* [[ERPNEXT Payroll POC 251212]]&lt;br /&gt;
* [[Comfac ERPNext Strategy Canvas (Expanded)]]&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — PAD/AI-agentic implementation strategy for Frappe ERPNext&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — Local Docker setup for evaluation, testing, and student use&lt;br /&gt;
* [[Frappe Links and References]]&lt;br /&gt;
* [[Using Frappe Wiki]]&lt;br /&gt;
* [https://docs.frappe.io/cloud/guidelines-for-contributing-regional-compliance-app Guidelines for Contributing Regional Compliance App]&lt;br /&gt;
* [https://docs.frappe.io/cloud/what-are-benches-and-bench-groups What are Benches?]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Administration &amp;amp; Self-Hosting ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[pfSense Sales Training Material]]&lt;br /&gt;
* [[SOP: Network Troubleshooting &amp;amp; pfSense Monitoring 251130]]&lt;br /&gt;
* [[Modern Guide: pfSense Captive Portal with FreeRADIUS &amp;amp; ACME]]&lt;br /&gt;
* [[pfSense CE → pfSense Plus Upgrade Guide]]&lt;br /&gt;
* [[Tplink Mikrotik Equivalent]]&lt;br /&gt;
* [[Skills and Competencies for IT Staff Trained in pfSense]]&lt;br /&gt;
* [[System Hardening Strategy: Win2Lin Migration &amp;amp; Infrastructure 251129]]&lt;br /&gt;
* [[Controller Systems 251213-01]]&lt;br /&gt;
* [[Power Distribution Tree 251213]]&lt;br /&gt;
* [[Introduction: Why Self-Host Your Email?]]&lt;br /&gt;
* [[Mailcow + Thunderbird Setup Guide (Email + Calendar)]]&lt;br /&gt;
* [[Mailcow SOGo: Creating Filters for Events, Approvals, and Organizational Emails]]&lt;br /&gt;
* [[Spoof Timezone Extension – Setup Guide for Comfac Staff]]&lt;br /&gt;
* [[Viber Focus-Stealing]]&lt;br /&gt;
* [[🌐 WordPress Website — *You Own Everything, Learn Everything*]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Storage &amp;amp; Hardware ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[TrueNAS Configuration Options &amp;amp; Scale Options 251130]]&lt;br /&gt;
* [[TrueNAS Business Plan: Project 251212]]&lt;br /&gt;
* [[Comparison: TrueNAS Mini X+ vs Dell Precision 3680 Tower (2025)]]&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification]]&lt;br /&gt;
* [[Industrial Controllers and Water Utilities 251011]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== AI &amp;amp; Machine Learning ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[OpenWebUI - 251128-justin]]&lt;br /&gt;
* [[Comfac GPU Scaling and AI Research Goals]]&lt;br /&gt;
* [[🧠 Process: Selecting and Installing the Right Ollama Model for Your Hardware]]&lt;br /&gt;
* [[Ollama GNOME System Tray Panel 260401]] — GNOME system tray toggle to start/stop Ollama and reclaim VRAM&lt;br /&gt;
* [[Proceedural Agentic Development Methodology 260304]] — Methodology for systematic agent use&lt;br /&gt;
* [[Project OpenCoder: AI Independence Initiative]] — Strategic roadmap for manufacturing intelligence&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 Modelfile fix for tool calling in OpenCode; thinking mode suppression; HDD vs SSD findings&lt;br /&gt;
* [[PAD-Driven ERPNext Strategy 260303]] — Procedural Agentic Development for Frappe/ERPNext configuration and deployment&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job Descriptions ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Job Descriptions]] — Index of all official job descriptions (IT, Engineering, Sales)&lt;br /&gt;
* [[JD IT Project Staff]] — IT Project Staff&lt;br /&gt;
* [[JD Security Compliance Assistant 260224]] — Security and Compliance Assistant (SCA)&lt;br /&gt;
* [[JD Engineering Designer 260108]] — Engineering Designer&lt;br /&gt;
* [[JD Engineering Supervisor 260109]] — Engineering Supervisor&lt;br /&gt;
* [[JD Technical Sales 260112]] — Technical Sales Engineer&lt;br /&gt;
* [[JD Marketing Assistant 251119]] — Marketing Assistant&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IT Operations &amp;amp; SOPs ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[SCA Program Plan 260320]] — Security &amp;amp; Compliance Assistant Program Plan v3 (ISO 9001/27001, PDCA, distributed audit model)&lt;br /&gt;
* [[SOP: Inter-Company Ordering and Production Process 260203]] — Ordering and production workflow between Sister Companies and the Cabuyao Plant&lt;br /&gt;
* [[Memo: Team Roles &amp;amp; Reporting Process Clarification 260320]] — Role boundaries, data ownership, and the new ERPNext-driven reporting paradigm&lt;br /&gt;
* [[Standard Operating Procedure: Distributed Minute Taking &amp;amp; Task Ownership 251208]]&lt;br /&gt;
* [[Business Continuity]]&lt;br /&gt;
* [[Procedure: CC-Blast Data Breach Prevention]]&lt;br /&gt;
* [[8D (Eight Discipline) Problem Solving Procedure]]&lt;br /&gt;
* [[Offline Malware Remediation &amp;amp; Data Recovery]]&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [[Steps to Repair and OCR a Scanned or Corrupted PDF in Ubuntu]]&lt;br /&gt;
* [[IT IMPORTS PROCESSES]]&lt;br /&gt;
* [[IT Purchase Requests 241126]]&lt;br /&gt;
* [[IT REQUEST (OP-ERP-ITR) - EDITED 250801]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sales &amp;amp; Business ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Comfac Sales Knowledge Base]]&lt;br /&gt;
* [[Comfac CRM – Customer Qualification &amp;amp; Conversion Process]]&lt;br /&gt;
* [[Partner Reseller Pricing 251109]]&lt;br /&gt;
* [[Biz Analysis Methodology 251109]]&lt;br /&gt;
* [[2026 MIS IT KRA KPI Biz Plan]]&lt;br /&gt;
* [[SALES INVOICE TAX OUTPUT 250829]]&lt;br /&gt;
* [[Projects in Process Report 251023]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools &amp;amp; Productivity ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Excel Description Filler Tool 📝]]&lt;br /&gt;
* [https://github.com/Comfac-Global-Group/comfac-studies Comfac Studies - Spaced Repetiton Active Recall]&lt;br /&gt;
* [[LibreOffice / Nextcloud Office – &amp;quot;Due Tasks&amp;quot; Conditional Formatting]]&lt;br /&gt;
* [[Google Drive and Shared Drive Training]]&lt;br /&gt;
* [[260108 CGG- GitHub Administration Guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wiki &amp;amp; Documentation ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Mediawiki Setting Up Guide]]&lt;br /&gt;
* [[Contributing to Only Office 260307]]&lt;br /&gt;
* [[Mediawiki Additional Configuration]]&lt;br /&gt;
* [[Mediawiki Docker Migration Guide]]&lt;br /&gt;
* [[Home]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Claude Code Isolation and Burner Workflow 260211]] — Secure AI development environment setup&lt;br /&gt;
* [[Opencode isolation and burner workflow 260216]] — OpenCode CLI isolation procedures&lt;br /&gt;
* [[LibreOffice Calc NumToWords Extension Complete Guide]] — Extension development&lt;br /&gt;
* [[ERPNext v15 Docker Setup Guide]] — ERPNext v15 local Docker setup (students, evaluators, thin-client demos)&lt;br /&gt;
* [[Erpnextv15-SSH-setup-241111]] — ERPNext v15 SSH/Portainer production setup&lt;br /&gt;
* [[Git-Mediawiki Local Editing 260223]] — Wiki editing with Git&lt;br /&gt;
* [[Understanding &amp;amp; Fixing Kernel Panics 260212]] — System debugging&lt;br /&gt;
* [[OpenCode in Android Termux 260303]] — OpenCode in Android&lt;br /&gt;
* [[OpenCoder Qwen35 Agentic Setup 260330]] — Qwen3.5 agentic setup: Modelfile, tool calling fix, storage impact&lt;br /&gt;
* [[Lora Basics 260304]] — LORA research&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Research ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Ladybird Browser]] — Browser engine development&lt;br /&gt;
* [[Computing Architecture]] — System design principles&lt;br /&gt;
* [[Backblaze Drive Stats for Server and Storage Qualification 260219]] — Drive reliability analysis&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== For Users Only ==&lt;br /&gt;
* [[Private:Private Ngani]]&lt;br /&gt;
* [[Private:Private Nganipart2]]&lt;br /&gt;
&lt;br /&gt;
== CIT-OJT Project Documentations ==&lt;br /&gt;
* [[OJTDocs: For OJTs only]]&lt;br /&gt;
&lt;br /&gt;
== Need Help? ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;column-count:2; column-gap:2em;&amp;quot;&amp;gt;&lt;br /&gt;
* [[Troubleshooting: Access &amp;amp; Permission Issues]]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents MediaWiki User&#039;s Guide]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
</feed>