If you have followed our journey through the Self-Managed Life series, you have achieved something most modern internet users consider impossible. You have built your own router (Post 3), established a VPN perimeter (Post 5), and deployed a fully functional Mailcow email server (Post 12). You are no longer a tenant in Google’s digital slum; you are the architect of your own castle.
But a castle with the drawbridge permanently down is not a fortress—it is a ruin waiting to happen.
In Post 13, we configured the software side of your email delivery, setting up SMTP relays and DNS records to ensure your emails hit inboxes instead of spam folders. Now, we must turn our attention to the hardware edge. We must configure pfSense to act as the ruthless gatekeeper for your mail server.
This is not simply about “opening ports.” If you blindly open ports 25, 80, and 443 to the entire world without restriction, you are inviting every botnet, script kiddie, and state-sponsored scanner to hammer your server.
In this guide, we will implement a Zero Trust architecture for your mail server. We will not just “allow” traffic; we will curate it. We will use pfSense Aliases to organize our rules, NAT Port Forwarding to precisely direct traffic, and GeoIP Blocking to silence the noise from countries where you have no contacts.
This is the definitive guide to hardening your self-hosted communications infrastructure.
The Philosophy of the “Bouncer”
Understanding the Attack Surface
Before we touch a single setting in the pfSense GUI, we must understand the threat model. A mail server is unique among self-hosted services because it must be publicly accessible to function.
- Plex can be hidden behind a VPN.
- Home Assistant can be restricted to your LAN.
- Email, by definition, requires that strangers (other mail servers) can talk to you.
This makes your mail server the most exposed component of your Sovereign Cloud. When you open Port 25 (SMTP) to receiving mail, you are essentially standing on a digital street corner and shouting, “I am here! Talk to me!”
Our goal in pfSense is to ensure that legitimate postmen can deliver mail, but thieves cannot enter the building to steal the furniture. We achieve this through three layers of defense, which we will configure in order:
- Aliases: The organizational layer that defines who and what is involved.
- NAT (Network Address Translation): The instructional layer that tells the router where to send incoming packets.
- Firewall Rules: The permission layer that decides if a packet is allowed to pass at all.
The Foundation – pfSense Aliases
The hallmark of an amateur network administrator is a firewall ruleset littered with raw IP addresses and port numbers. The hallmark of a professional is the use of Aliases.
Aliases allow you to group multiple ports, IPs, or networks into a single, named object. If you ever change your mail server’s internal IP address, you update the Alias once, and every NAT rule and firewall rule automatically updates.
Creating the Ports Alias
Your Mailcow server uses a symphony of ports to communicate. Instead of creating eight separate firewall rules, we will bundle them into a single Alias.
- Log in to your pfSense WebGUI.
- Navigate to Firewall > Aliases.
- Click the Ports tab.
- Click Add.
Configuration Values:
- Name:
Mail_Ports - Description: Ports required for Mailcow Public Access
- Type:
Port(s)
Now, add the following ports. It is important to understand why we are adding each one:
| Port | Service | Protocol | Why We Need It |
|---|---|---|---|
| 25 | SMTP | TCP | Mandatory. This is how other mail servers (Gmail, Yahoo) deliver mail to you. |
| 465 | SMTPS | TCP | Legacy/Implicit TLS. Used by some older clients to send mail securely. |
| 587 | Submission | TCP | Modern Standard. Used by your phone/laptop to send mail out via your server. |
| 143 | IMAP | TCP | Retrieval. Standard port for fetching emails (STARTTLS). |
| 993 | IMAPS | TCP | Secure Retrieval. SSL/TLS encrypted IMAP. The standard for mobile devices. |
| 110 | POP3 | TCP | Legacy Retrieval. Only needed if you use POP3 (downloads and deletes from server). |
| 995 | POP3S | TCP | Secure Legacy. SSL/TLS POP3. |
| 80 | HTTP | TCP | Certificate Validation. Required for Let’s Encrypt (ACME) to renew SSL certs. |
| 443 | HTTPS | TCP | Web Access. Required for SOGo Webmail, ActiveSync, and Mailcow UI. |
Web Access. Required for SOGo Webmail, ActiveSync, and Mailcow UI.
Self-Hoster Tip: If you never use POP3 (and you shouldn’t, IMAP is superior), do not include ports 110 and 995. Minimizing the attack surface is the first rule of security.
- Click Save.

Creating the Host Alias
Next, we define where the mail server lives. In Post 11, you should have assigned your Ubuntu VM a static IP address (e.g., 192.168.1.50). We will reference this now.
- Click the IP tab (under Firewall > Aliases).
- Click Add.
- Name:
Mail_Server_IP - Description: Internal IP of Mailcow VM
- Type:
Host(s) - IP or FQDN: Enter your server’s static LAN IP (e.g.,
192.168.1.50). - Click Save and Apply Changes.
You have now created the vocabulary your firewall will use. Instead of saying “Allow TCP traffic on 25 to 192.168.1.50”, you can now say “Allow Mail_Ports to Mail_Server_IP.”

NAT Port Forwarding – Punching Holes in the Wall
NAT (Network Address Translation) is the process of taking traffic hitting your public WAN IP and rewriting it to go to an internal LAN IP. Without this, your router receives an email packet and drops it, having no idea which device inside your home is the mail server.
The “Fork in the Road”: Public Access vs. VPN Only
At this stage, you must make a critical architectural decision based on FUTO Guide Section 16.
Path A: The “Fortress” Mode (VPN Only)
- Who is this for? You only want to check email when you are at home, or you are willing to toggle your WireGuard/OpenVPN connection on your phone every time you want to check mail.
- The Configuration: You ONLY forward Port 25.
- Why? Port 25 is required for other servers to send you mail. But if you are the only human reading the mail, you can do that over your private VPN tunnel. This renders your webmail login page (SOGo) invisible to the internet.
Path B: The “Public Service” Mode (Standard)
- Who is this for? You want your phone to sync email automatically in the background without a VPN. You want to log into webmail from your work computer. You have family members using the server who are not technical.
- The Configuration: You forward All Ports in the
Mail_Portsalias. - Why? This offers the convenience of Gmail/iCloud but requires tighter security rules (GeoIP) which we will cover later.
For this guide, we will assume Path B (Standard), as it is what 99% of users require for a functional replacement of Big Tech services.
Creating the NAT Rule
- Navigate to Firewall > NAT.
- Select the Port Forward tab.
- Click Add (Up arrow).
The Rule Configuration:
- Interface:
WAN - Address Family:
IPv4 - Protocol:
TCP - Source:
Any(We will restrict this later in the Firewall rules, but for NAT, leave as Any). - Destination:
WAN Address - Destination Port Range:
- From:
Other-> enterMail_Ports(Type the first few letters and it will autocomplete in red). - To:
Other->Mail_Ports
- From:
- Redirect Target IP:
- Type:
Single host or Alias - Address:
Mail_Server_IP
- Type:
- Redirect Target Port:
Other->Mail_Ports
- NAT Reflection:
Enable (Pure NAT)- Critical Note: This setting allows you to access
mail.yourdomain.comfrom inside your house. Without it, you would have to use the internal IP when at home and the domain when away, which breaks phone sync.
- Critical Note: This setting allows you to access
- Filter Rule Association:
Add associated filter rule
- Click Save and Apply Changes.
You have now created the vocabulary your firewall will use. Instead of saying “Allow TCP traffic on 25 to 192.168.1.50”, you can now say “Allow Mail_Ports to Mail_Server_IP.”

NAT Port Forwarding – Punching Holes in the Wall
NAT (Network Address Translation) is the process of taking traffic hitting your public WAN IP and rewriting it to go to an internal LAN IP. Without this, your router receives an email packet and drops it, having no idea which device inside your home is the mail server.
The “Fork in the Road”: Public Access vs. VPN Only
At this stage, you must make a critical architectural decision based on FUTO Guide Section 16.
Path A: The “Fortress” Mode (VPN Only)
- Who is this for? You only want to check email when you are at home, or you are willing to toggle your WireGuard/OpenVPN connection on your phone every time you want to check mail.
- The Configuration: You ONLY forward Port 25.
- Why? Port 25 is required for other servers to send you mail. But if you are the only human reading the mail, you can do that over your private VPN tunnel. This renders your webmail login page (SOGo) invisible to the internet.
Path B: The “Public Service” Mode (Standard)
- Who is this for? You want your phone to sync email automatically in the background without a VPN. You want to log into webmail from your work computer. You have family members using the server who are not technical.
- The Configuration: You forward All Ports in the
Mail_Portsalias. - Why? This offers the convenience of Gmail/iCloud but requires tighter security rules (GeoIP) which we will cover later.
For this guide, we will assume Path B (Standard), as it is what 99% of users require for a functional replacement of Big Tech services.
Creating the NAT Rule
- Navigate to Firewall > NAT.
- Select the Port Forward tab.
- Click Add (Up arrow).
The Rule Configuration:
- Interface:
WAN - Address Family:
IPv4 - Protocol:
TCP - Source:
Any(We will restrict this later in the Firewall rules, but for NAT, leave as Any). - Destination:
WAN Address - Destination Port Range:
- From:
Other-> enterMail_Ports(Type the first few letters and it will autocomplete in red). - To:
Other->Mail_Ports
- From:
- Redirect Target IP:
- Type:
Single host or Alias - Address:
Mail_Server_IP
- Type:
- Redirect Target Port:
Other->Mail_Ports
- NAT Reflection:
Enable (Pure NAT)- Critical Note: This setting allows you to access
mail.yourdomain.comfrom inside your house. Without it, you would have to use the internal IP when at home and the domain when away, which breaks phone sync.
- Critical Note: This setting allows you to access
- Filter Rule Association:
Add associated filter rule
- Click Save and Apply Changes.

Firewall Rules – The Guards
When you created the NAT rule and selected “Add associated filter rule,” pfSense automatically created a rule on your WAN interface. However, this rule is likely too permissive. We need to audit and refine it.

The Danger of Auto-Generated Rules
Navigate to Firewall > Rules > WAN. You will see a new rule at the bottom allowing traffic to Mail_Server_IP.
The problem? It allows everything in the Mail_Ports alias from anywhere. While Any is necessary for Port 25 (SMTP) because we don’t know where email will come from, it is dangerous for Port 80 (Webmail) and Port 22 (SSH) if you included it.
Splitting the Rules (Advanced Security)
For true “Mastery,” we should split our access logic. We want the world to send us mail (Port 25), but we might only want our country to try and log in (Port 443/993).
Action Plan:
- Edit the auto-generated rule.
- Change the Destination Port Range from
Mail_Portsto just25(SMTP). - Save.
- Create a second rule for the “User Access” ports (443, 993, 587).
- For this second rule, we will apply GeoIP Blocking.
The Shield – Implementing GeoIP Blocking with pfBlockerNG
In Post 6, we installed pfBlockerNG. Now we will weaponize it to protect our mail server.
Most brute-force attacks on mail servers come from a handful of countries. If you live in the United States and have no business associates in Russia, China, or North Korea, there is zero reason for an IP address in those nations to attempt a login on your IMAP port.

Step 1: Configure GeoIP Aliases
- Navigate to Firewall > pfBlockerNG > IP > GeoIP.
- Ensure you have created an alias for Top Spammers or High Risk countries.
- Ensure you have an alias for your Home Country (e.g.,
North America).
Step 2: Apply to Firewall Rules
We will now modify the firewall rules to be “Allow” lists rather than “Block” lists.
The “User Access” Rule (Ports 443, 993, 587):
- Go back to Firewall > Rules > WAN.
- Create a new rule ABOVE the default deny rule.
- Action:
Pass - Source:
Single Host or Alias->pfB_NA_v4(This is the pfBlocker alias for North America. Adjust for your region). - Destination:
Mail_Server_IP - Destination Port: Create a new Alias called
Mail_Login_Ports(443, 993, 587) and use it here. - Description: “Allow Mail Login from Home Region Only”.
The “Server Talk” Rule (Port 25): Port 25 is trickier. Legitimate email can come from anywhere. However, 90% of spam comes from botnets in specific regions.
- Create a rule allowing Port 25 from
Any. - Crucial: Ensure your Block rules from pfBlockerNG (the general bad-guy lists) are processed BEFORE this pass rule.
- In pfSense, rules are processed top-down. The first match wins.
- Order should be:
- Block Malicious IPs (pfBlockerNG Auto-Rules).
- Block GeoIP Spammers (pfBlockerNG Auto-Rules).
- Pass Mail_Login_Ports (From Home Region).
- Pass Port 25 (From Any).
- Deny All.
Troubleshooting & The “Hairpin” Problem
You’ve set it all up. You disconnect your phone from Wi-Fi, and mail syncs perfectly. You walk back inside, connect to Wi-Fi, and suddenly… connection error.
This is the dreaded NAT Reflection (or Hairpin NAT) issue.
The Scenario
Your phone tries to connect to mail.example.com. DNS resolves this to your WAN IP (e.g., 203.0.113.5). Your phone sends a packet to 203.0.113.5. Your pfSense router sees a packet coming from the LAN destined for the WAN IP. Without Reflection, pfSense drops it or gets confused about where to send the reply.
The Fix: Split DNS (The Professional Way)
While we enabled “Pure NAT” earlier as a quick fix, the correct way to solve this in a sovereign cloud is Split DNS.
- Navigate to Services > DNS Resolver (Unbound).
- Scroll down to Host Overrides.
- Click Add.
- Host:
mail - Domain:
yourdomain.com - IP Address:
192.168.1.50(The LOCAL IP of the server). - Description: Split DNS for Mailcow.
What this does:
- When you are outside, Google DNS tells your phone the server is at
203.0.113.5. - When you are inside, pfSense tells your phone the server is at
192.168.1.50. - Your phone connects directly to the server over the LAN, bypassing the router’s NAT engine entirely. This is faster and cleaner.
Verification – Trust But Verify
Never assume your firewall is working. Test it.
Test 1: The Open Relay Test
Use a tool like MXToolbox to scan your domain.
- It should see Port 25 as Open.
- It should NOT see Port 80/443 as Open unless you specifically allowed them from the scanner’s IP (which you shouldn’t have restricted if you want public webmail).
- Run an SMTP Open Relay test. Your Mailcow configuration (Post 12) handles the relay security, but the firewall ensures only the mail container is hit.
Test 2: The GeoIP Test
- Use a VPN on your phone to tunnel to a blocked country (e.g., Russia or China).
- Try to load your Webmail URL (
https://mail.yourdomain.com). - Result: It should time out.
- Disconnect the VPN.
- Result: The login page should load immediately.
The Quiet Confidence of Security
You have now done what few sysadmins take the time to do properly. You haven’t just punched a hole in your firewall; you’ve installed a smart airlock. You’ve segregated traffic, optimized local routing with Split DNS, and erected geofences to keep out the noise.
Your mail server is now ready to face the hostile internet. But a secure server is only useful if it holds valuable data. In Module 3, Post 15, we will tackle the next giant of the Google ecosystem: Google Drive. We will begin building your own resilient, synchronized file cloud.
The next part is dropping soon.
Become a member to get early access.
Next Part of the Self Hosting Series Dropping Soon
Members get early access to every new part of the Self Hosting Series before it goes public — including guides, scripts, and in-depth walkthroughs.
Get Early Access NowThis post first appeared at - The CyberSec Guru