Restructured Documentation
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 8s
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 8s
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
---
|
||||
tags:
|
||||
- Microsoft Exchange
|
||||
- Lets Encrypt
|
||||
- Email
|
||||
---
|
||||
|
||||
## Purpose
|
||||
If you want to set up automatic Let's Encrypt SSL certificates on a Microsoft Exchange server, you have to go through a few steps to install the WinACME bot, and configure it to automatically renew certificates.
|
||||
|
||||
!!! note "ACME Bot Provisioning Considerations"
|
||||
This document assumes you want a fully-automated one-liner command for configuring the ACME Bot, it is also completely valid to go step-by-step through the bot to configure the SSL certificate, the IIS server, etc, and it will automatically create a Scheduled Task to renew on its own. The whole process is very straight-forward with most answers being the default option.
|
||||
|
||||
### Download the Win-ACME Bot
|
||||
- Log into the on-premise Exchange Server via Datto RMM
|
||||
- Navigate to: [https://www.win-acme.com/](https://www.win-acme.com/)
|
||||
- On the top-right of the website, you will see a "**Download**" button with the most recent version of the Win-ACME bot
|
||||
- Extract the contents of the ZIP file to "**C:\\Program Files (x86)\\Lets Encrypt**"
|
||||
- Make the "**Lets Encrypt**" folder if it does not already exist
|
||||
|
||||
### Configure `settings_default.json`
|
||||
- The next step involves us making a modification to the configuration of the Win-ACME bot that allows us to export the necessary private key data for Exchange
|
||||
- Using a text editor, open the "**settings\_default.json**" file
|
||||
- Look for the setting called "**PrivateKeyExportable**" and change the value from "**false**" to "**true**"
|
||||
- Save and close the file
|
||||
|
||||
### Download and Install the SSL Certificate
|
||||
- Open an administrative Command Line (DO NOT USE POWERSHELL)
|
||||
- Navigate to the Let's Encrypt bot directory: `CD "C:\Program Files (x86)\Lets Encrypt"`
|
||||
- Invoke the bot to automatically download and install the certificate into the IIS Server that Exchange uses to host the Exchange Server
|
||||
- Be sure to change the placeholder subdomains to match the domain of the actual Exchange Server
|
||||
- (e.g. "**mail.example.org**" | "**autodiscover.example.org**")
|
||||
|
||||
```text
|
||||
wacs.exe --target manual --host mail.example.org,autodiscover.example.org --certificatestore My --acl-fullcontrol "network service,administrators" --installation iis,script --installationsiteid 1 --script "./Scripts/ImportExchange.ps1" --scriptparameters "'{CertThumbprint}' 'IIS,SMTP,IMAP' 1 '{CacheFile}' '{CachePassword}' '{CertFriendlyName}'" --verbose
|
||||
```
|
||||
|
||||
- When the command is running, it will ask for an email address for alerts and abuse notifications, just put "**infrastructure@bunny-lab.io**"
|
||||
- If you run into any unexpected errors that result in anything other than exiting with a status "0", consult with Nicole Rappe to proceed
|
||||
- Check that the domain of the Exchange Server is reachable on port 80 as Let's Encrypt uses this to build the cert.
|
||||
- Searching the external IP of the server on [Shodan](https://www.shodan.io/) will reveal all open ports.
|
||||
|
||||
### Troubleshooting
|
||||
If you find that any of the services such as [https://mail.example.org/ecp](https://mail.example.org/ecp), [https://autodiscover.example.org](https://autodiscover.example.org), or [https://mail.example.org/owa](https://mail.example.org/owa) do not let you log in, proceed with the steps below to correct the "Certificate Binding" in IIS Manager:
|
||||
|
||||
- Open "**Server Manager**" > Tools > "**Internet Information Services (IIS) Manager**"
|
||||
- Expand the "**Connections**" server tree on the left-hand side of the IIS Manager
|
||||
- Expand the "**Sites**" folder
|
||||
- Click on "**Default Web Site**"
|
||||
- On the right-hand Actions menu, click on "**Bindings...**"
|
||||
- A table will appear with different endpoints on the Exchange server > What you are looking for is an entry that looks like the following:
|
||||
- **Type**: https
|
||||
- **Host Name**: autodiscover.example.org
|
||||
- **Port**: 443
|
||||
- Double-click on the row, or click one then click the "**Edit**" button to open the settings for that endpoint
|
||||
- Under "**SSL Certificate**" > Make sure the certificate name matches the following format: "**\[Manual\] autodiscover.example.org @ YYYY/MM/DD**"
|
||||
- If it does not match the above, use the dropdown menu to correct it and click the "**OK**" button
|
||||
- **Type**: https
|
||||
- **Host Name**: mail.example.org
|
||||
- **Port**: 443
|
||||
- Repeat the steps seen above, except this time for "**mail.example.org**"
|
||||
- Click on "**Exchange Back End**"
|
||||
- On the right-hand Actions menu, click on "**Bindings...**"
|
||||
- A table will appear with different endpoints on the Exchange server > What you are looking for is an entry that looks like the following:
|
||||
- **Type**: https
|
||||
- **Host Name**: <blank>
|
||||
- **Port**: 444
|
||||
- Repeat the steps seen above, ensuring that the "**\[Manual\] autodiscover.example.org @ YYYY/MM/DD**" certificate is selected and applied
|
||||
- Click the "**OK**" button
|
||||
- On the left-hand menu under "**Connections**" in IIS Manager, click on the server name itself
|
||||
- (e.g. "**EXAMPLE-EXCHANGE (DOMAIN\\dptadmin**")
|
||||
- On the right-hand "**Actions**" menu > Under "Manage Server" > Select "Restart"
|
||||
- Wait for the IIS server to restart itself, then try accessing the webpages for Exchange that were exhibiting issues logging in
|
||||
|
||||
### Additional Documentation
|
||||
- [https://www.alitajran.com/install-free-lets-encrypt-certificate-in-exchange-server/](https://www.alitajran.com/install-free-lets-encrypt-certificate-in-exchange-server/)
|
||||
|
||||
## Related Documentation
|
||||
- [Related Email Documentation](<../../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
@@ -0,0 +1,802 @@
|
||||
---
|
||||
tags:
|
||||
- Proxmox Mail Gateway
|
||||
- PMG
|
||||
- Mailcow
|
||||
- Email
|
||||
- SMTP
|
||||
---
|
||||
|
||||
## Purpose
|
||||
This document defines the procedure for placing `Proxmox Mail Gateway` in front of an existing `Mailcow` server for inbound SMTP filtering.
|
||||
|
||||
PMG will handle inbound SMTP inspection before delivering accepted mail to Mailcow.
|
||||
|
||||
This document covers **inbound SMTP filtering only**.
|
||||
|
||||
It does not move:
|
||||
|
||||
- Outbound SMTP delivery
|
||||
- DKIM signing
|
||||
- SMTP submission
|
||||
- IMAP
|
||||
- POP3
|
||||
- ManageSieve
|
||||
- Mailcow certificates
|
||||
- Mailcow web access
|
||||
- Roundcube access
|
||||
|
||||
## Assumptions
|
||||
Mailcow is already deployed and functional.
|
||||
|
||||
Mailcow already handles:
|
||||
|
||||
- Mailbox hosting
|
||||
- User authentication
|
||||
- Webmail
|
||||
- Mailcow admin interface
|
||||
- IMAP
|
||||
- POP3
|
||||
- SMTP submission
|
||||
- Outbound delivery
|
||||
- DKIM signing
|
||||
- TLS certificates for `mail.bunny-lab.io`
|
||||
|
||||
Example environment:
|
||||
|
||||
```text
|
||||
Proxmox Mail Gateway: 192.168.3.15
|
||||
Mailcow Server: 192.168.3.61
|
||||
Mail Hostname: mail.bunny-lab.io
|
||||
Mail Domain: bunny-lab.io
|
||||
Firewall: pfSense
|
||||
Reverse Proxy: Traefik
|
||||
```
|
||||
|
||||
!!! warning "Inbound SMTP Only"
|
||||
Only move public inbound SMTP port `25` to PMG during this stage.
|
||||
|
||||
```text
|
||||
Do not move mail client ports, outbound relay behavior, DKIM signing, or Mailcow web access.
|
||||
```
|
||||
|
||||
## Architecture
|
||||
### Existing Mail Flow
|
||||
```text
|
||||
Internet
|
||||
|
|
||||
v
|
||||
pfSense WAN :25
|
||||
|
|
||||
v
|
||||
Mailcow 192.168.3.61:25
|
||||
```
|
||||
|
||||
### Target Mail Flow
|
||||
```text
|
||||
Internet
|
||||
|
|
||||
v
|
||||
pfSense WAN :25
|
||||
|
|
||||
v
|
||||
PMG 192.168.3.15:25
|
||||
|
|
||||
v
|
||||
Mailcow 192.168.3.61:25
|
||||
```
|
||||
|
||||
### Final Service Ownership
|
||||
```text
|
||||
PMG
|
||||
- Inbound SMTP on port 25
|
||||
- Spam filtering
|
||||
- Virus filtering
|
||||
- Tracking Center
|
||||
- Quarantine
|
||||
- Delivery of accepted inbound mail to Mailcow
|
||||
|
||||
Mailcow
|
||||
- Mailbox hosting
|
||||
- User authentication
|
||||
- Webmail
|
||||
- Mailcow admin interface
|
||||
- IMAP
|
||||
- POP3
|
||||
- SMTP submission
|
||||
- Outbound mail delivery
|
||||
- DKIM signing
|
||||
- TLS certificates for mail.bunny-lab.io
|
||||
|
||||
Traefik
|
||||
- Public HTTP
|
||||
- Public HTTPS
|
||||
- Mailcow / Roundcube frontend routing
|
||||
```
|
||||
|
||||
## DNS
|
||||
Public DNS remains unchanged.
|
||||
|
||||
```text
|
||||
bunny-lab.io MX 10 mail.bunny-lab.io
|
||||
mail.bunny-lab.io A <Public WAN IP>
|
||||
```
|
||||
|
||||
The public DNS records continue pointing to the WAN IP.
|
||||
|
||||
The firewall determines where inbound SMTP is delivered internally.
|
||||
|
||||
```text
|
||||
pfSense WAN :25 -> PMG 192.168.3.15:25
|
||||
```
|
||||
|
||||
!!! note "DNS Does Not Point to PMG Directly"
|
||||
The public MX and A records do not point to the internal PMG IP.
|
||||
|
||||
```text
|
||||
NAT controls the internal SMTP destination.
|
||||
```
|
||||
|
||||
## Firewall and NAT Design
|
||||
Only public inbound SMTP changes.
|
||||
|
||||
Change this:
|
||||
|
||||
```text
|
||||
WAN :25 -> Mailcow 192.168.3.61:25
|
||||
```
|
||||
|
||||
To this:
|
||||
|
||||
```text
|
||||
WAN :25 -> PMG 192.168.3.15:25
|
||||
```
|
||||
|
||||
Leave Mailcow client access ports pointed directly at Mailcow.
|
||||
|
||||
```text
|
||||
WAN :465 -> Mailcow 192.168.3.61:465
|
||||
WAN :587 -> Mailcow 192.168.3.61:587
|
||||
WAN :993 -> Mailcow 192.168.3.61:993
|
||||
WAN :995 -> Mailcow 192.168.3.61:995
|
||||
WAN :110 -> Mailcow 192.168.3.61:110
|
||||
WAN :143 -> Mailcow 192.168.3.61:143
|
||||
WAN :4190 -> Mailcow 192.168.3.61:4190
|
||||
```
|
||||
|
||||
Leave web traffic on the existing reverse proxy path.
|
||||
|
||||
```text
|
||||
WAN :80 -> Traefik :80
|
||||
WAN :443 -> Traefik :443
|
||||
```
|
||||
|
||||
!!! warning "Do Not Move Mail Client Ports to PMG"
|
||||
PMG is an SMTP gateway.
|
||||
|
||||
```text
|
||||
Do not forward IMAP, POP3, SMTPS, Submission, or ManageSieve ports to PMG.
|
||||
```
|
||||
|
||||
## Initial PMG Access
|
||||
Access the PMG management interface.
|
||||
|
||||
```text
|
||||
https://192.168.3.15:8006
|
||||
```
|
||||
|
||||
Use the `root` credentials configured during PMG installation.
|
||||
|
||||
!!! note "Certificate Warning"
|
||||
Browser certificate warnings are expected when accessing PMG by IP address unless a trusted certificate has already been configured for the management interface.
|
||||
|
||||
## Pre-Cutover Connectivity Checks
|
||||
Confirm PMG can reach Mailcow on SMTP port `25`.
|
||||
|
||||
Run from the PMG shell:
|
||||
|
||||
```sh
|
||||
# Confirm PMG can reach Mailcow SMTP
|
||||
nc -vz 192.168.3.61 25
|
||||
```
|
||||
|
||||
Expected result:
|
||||
|
||||
```text
|
||||
(UNKNOWN) [192.168.3.61] 25 (smtp) open
|
||||
```
|
||||
|
||||
Reverse DNS warnings are not automatically failures.
|
||||
|
||||
```text
|
||||
inverse host lookup failed: Unknown host
|
||||
```
|
||||
|
||||
If port `25` still reports as open, SMTP connectivity is working.
|
||||
|
||||
Confirm Mailcow presents an SMTP banner.
|
||||
|
||||
```sh
|
||||
# Connect from PMG directly to Mailcow SMTP
|
||||
nc 192.168.3.61 25
|
||||
```
|
||||
|
||||
Expected banner:
|
||||
|
||||
```text
|
||||
220-mail.bunny-lab.io ESMTP Postcow
|
||||
220 mail.bunny-lab.io ESMTP Postcow
|
||||
```
|
||||
|
||||
Exit the SMTP session.
|
||||
|
||||
```text
|
||||
quit
|
||||
```
|
||||
|
||||
!!! note "Mailcow SMTP Banner"
|
||||
Mailcow commonly identifies its SMTP service as `Postcow`.
|
||||
|
||||
```text
|
||||
That is expected.
|
||||
```
|
||||
|
||||
## PMG Mail Proxy Ports
|
||||
In PMG, navigate to:
|
||||
|
||||
```text
|
||||
Configuration > Mail Proxy > Ports
|
||||
```
|
||||
|
||||
Confirm:
|
||||
|
||||
```text
|
||||
External SMTP Port: 25
|
||||
```
|
||||
|
||||
No outbound filtering is configured during this stage.
|
||||
|
||||
!!! note "Internal SMTP Port"
|
||||
PMG also has an internal SMTP port used for outbound filtering from an internal mail server.
|
||||
|
||||
```text
|
||||
This deployment does not use outbound PMG filtering yet.
|
||||
```
|
||||
|
||||
## PMG Relay Domains
|
||||
In PMG, navigate to:
|
||||
|
||||
```text
|
||||
Configuration > Mail Proxy > Relay Domains
|
||||
```
|
||||
|
||||
Add the accepted mail domain.
|
||||
|
||||
```text
|
||||
bunny-lab.io
|
||||
```
|
||||
|
||||
This authorizes PMG to accept mail for the domain.
|
||||
|
||||
!!! warning "Relay Domains Are Required"
|
||||
If the domain is missing from Relay Domains, PMG may reject inbound mail because it is not configured as responsible for that domain.
|
||||
|
||||
## PMG Default Relay
|
||||
In PMG, navigate to:
|
||||
|
||||
```text
|
||||
Configuration > Mail Proxy > Relaying
|
||||
```
|
||||
|
||||
Configure Mailcow as the default relay.
|
||||
|
||||
```text
|
||||
Default Relay: 192.168.3.61
|
||||
Relay Port: 25
|
||||
Relay Protocol: smtp
|
||||
Disable MX Lookup: Yes
|
||||
Smarthost: none
|
||||
```
|
||||
|
||||
Target internal relay path:
|
||||
|
||||
```text
|
||||
PMG 192.168.3.15
|
||||
|
|
||||
v
|
||||
Mailcow 192.168.3.61:25
|
||||
```
|
||||
|
||||
!!! note "Disable MX Lookup"
|
||||
PMG should deliver accepted inbound mail directly to the internal Mailcow server.
|
||||
|
||||
```text
|
||||
It should not perform public MX lookup for the local mail domain.
|
||||
```
|
||||
|
||||
!!! note "No Smarthost"
|
||||
Leave `Smarthost` unset or set to `none` for inbound-only filtering.
|
||||
|
||||
```text
|
||||
Smarthost configuration is used for outbound relay behavior.
|
||||
```
|
||||
|
||||
## Mailcow Forwarding Host
|
||||
Configure Mailcow to trust PMG as a forwarding host.
|
||||
|
||||
In Mailcow, navigate to:
|
||||
|
||||
```text
|
||||
System > Configuration Dropdown > Options > Forwarding Hosts Dropdown
|
||||
```
|
||||
|
||||
Add the PMG IP address.
|
||||
|
||||
```text
|
||||
192.168.3.15
|
||||
```
|
||||
|
||||
Set the forwarding-host spam filter option to:
|
||||
|
||||
```text
|
||||
Inactive
|
||||
```
|
||||
|
||||
!!! note "Forwarding Host Behavior"
|
||||
After cutover, Mailcow sees PMG as the immediate SMTP source for inbound mail.
|
||||
|
||||
```text
|
||||
Trusting PMG allows Mailcow to interpret forwarded mail correctly.
|
||||
```
|
||||
|
||||
!!! note "Spam Filtering Placement"
|
||||
PMG is the primary inbound spam and virus filtering system.
|
||||
|
||||
```text
|
||||
Leave Mailcow forwarding-host spam filtering inactive to avoid double-filtering messages already inspected by PMG.
|
||||
```
|
||||
|
||||
## Outbound Mail
|
||||
Leave outbound mail unchanged.
|
||||
|
||||
```text
|
||||
Mailcow 192.168.3.61
|
||||
|
|
||||
v
|
||||
Internet
|
||||
```
|
||||
|
||||
Do not configure Mailcow to relay outbound mail through PMG during this stage.
|
||||
|
||||
Do not change:
|
||||
|
||||
```text
|
||||
Relayhost
|
||||
Outbound firewall rules
|
||||
DKIM signing
|
||||
SPF record
|
||||
DMARC record
|
||||
```
|
||||
|
||||
!!! warning "Do Not Move DKIM"
|
||||
DKIM signing applies to outbound mail.
|
||||
|
||||
```text
|
||||
This document only moves inbound SMTP filtering.
|
||||
```
|
||||
|
||||
## Filtering Policy
|
||||
Initial filtering ownership:
|
||||
|
||||
```text
|
||||
PMG = primary inbound SMTP filtering, tracking, quarantine
|
||||
Mailcow = mailbox hosting, authentication, webmail, mail client access
|
||||
```
|
||||
|
||||
Avoid configuring both PMG and Mailcow to aggressively quarantine the same inbound mail stream.
|
||||
|
||||
!!! note "Keep Filtering Boring"
|
||||
PMG should own edge filtering first.
|
||||
|
||||
```text
|
||||
Mailcow should continue owning mailbox and client access behavior.
|
||||
```
|
||||
|
||||
## SMTP NAT Cutover
|
||||
After PMG relay domains, PMG default relay, and Mailcow forwarding host settings are configured, update the pfSense NAT rule.
|
||||
|
||||
Change:
|
||||
|
||||
```text
|
||||
WAN :25 -> Mailcow 192.168.3.61:25
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```text
|
||||
WAN :25 -> PMG 192.168.3.15:25
|
||||
```
|
||||
|
||||
Do not change the remaining Mailcow port forwards.
|
||||
|
||||
```text
|
||||
465 -> 192.168.3.61
|
||||
587 -> 192.168.3.61
|
||||
993 -> 192.168.3.61
|
||||
995 -> 192.168.3.61
|
||||
143 -> 192.168.3.61
|
||||
110 -> 192.168.3.61
|
||||
4190 -> 192.168.3.61
|
||||
```
|
||||
|
||||
Do not change the Traefik web path.
|
||||
|
||||
```text
|
||||
80 -> Traefik
|
||||
443 -> Traefik
|
||||
```
|
||||
|
||||
!!! warning "Cutover Point"
|
||||
Changing `WAN :25` is the actual inbound mail cutover.
|
||||
|
||||
```text
|
||||
External SMTP servers will begin connecting to PMG instead of Mailcow directly.
|
||||
```
|
||||
|
||||
## Validation
|
||||
### External SMTP Reachability
|
||||
From an external system:
|
||||
|
||||
```sh
|
||||
# Confirm public SMTP is reachable
|
||||
nc -vz mail.bunny-lab.io 25
|
||||
```
|
||||
|
||||
Alternative:
|
||||
|
||||
```sh
|
||||
# Confirm public SMTP banner using telnet
|
||||
telnet mail.bunny-lab.io 25
|
||||
```
|
||||
|
||||
Expected result:
|
||||
|
||||
```text
|
||||
Port 25 open
|
||||
SMTP banner returned by gateway
|
||||
```
|
||||
|
||||
!!! note "Internal Testing Limitations"
|
||||
Internal tests may not represent public mail flow if NAT reflection or split-horizon DNS is involved.
|
||||
|
||||
```text
|
||||
Prefer external testing.
|
||||
```
|
||||
|
||||
If external port testing is unavailable, send real mail from an outside provider.
|
||||
|
||||
Usable external sources:
|
||||
|
||||
```text
|
||||
Gmail
|
||||
Outlook.com
|
||||
iCloud
|
||||
Proton Mail
|
||||
Work mailbox hosted outside Mailcow
|
||||
```
|
||||
|
||||
### Inbound Delivery
|
||||
Send an external message to a Mailcow-hosted mailbox.
|
||||
|
||||
Expected path:
|
||||
|
||||
```text
|
||||
External mailbox
|
||||
|
|
||||
v
|
||||
mail.bunny-lab.io
|
||||
|
|
||||
v
|
||||
pfSense WAN :25
|
||||
|
|
||||
v
|
||||
PMG 192.168.3.15
|
||||
|
|
||||
v
|
||||
Mailcow 192.168.3.61
|
||||
|
|
||||
v
|
||||
User mailbox
|
||||
```
|
||||
|
||||
Check PMG:
|
||||
|
||||
```text
|
||||
PMG > Tracking Center
|
||||
```
|
||||
|
||||
Expected PMG status:
|
||||
|
||||
```text
|
||||
Status: accepted/delivered
|
||||
Relay: 192.168.3.61[192.168.3.61]:25
|
||||
```
|
||||
|
||||
Check Mailcow:
|
||||
|
||||
```text
|
||||
System > Logs
|
||||
```
|
||||
|
||||
or review the relevant Mailcow Postfix and Dovecot logs.
|
||||
|
||||
### Mail Client Access
|
||||
Confirm normal mail client behavior remains unchanged.
|
||||
|
||||
Test:
|
||||
|
||||
```text
|
||||
IMAP receive
|
||||
SMTP submission send
|
||||
Mobile mail client access
|
||||
Desktop mail client access
|
||||
Webmail / Roundcube access
|
||||
Mailcow UI access
|
||||
```
|
||||
|
||||
Expected service paths:
|
||||
|
||||
```text
|
||||
IMAPS: 993 -> Mailcow
|
||||
Submission: 587 -> Mailcow
|
||||
SMTPS: 465 -> Mailcow
|
||||
Web: 443 -> Traefik -> Mailcow
|
||||
```
|
||||
|
||||
Confirm outbound mail still works by replying from a Mailcow-hosted mailbox to the external sender.
|
||||
|
||||
### PMG Queues
|
||||
Check PMG queues after test delivery.
|
||||
|
||||
```text
|
||||
PMG > Queues
|
||||
```
|
||||
|
||||
Expected state:
|
||||
|
||||
```text
|
||||
Queue empty or near-empty after delivery
|
||||
```
|
||||
|
||||
Queue status confirms PMG is not silently holding or deferring mail because of relay, DNS, or delivery errors.
|
||||
|
||||
## Validation Checklist
|
||||
- [ ] Public MX record points to `mail.bunny-lab.io`
|
||||
- [ ] `mail.bunny-lab.io` resolves to the correct public WAN IP
|
||||
- [ ] DNS records are unchanged
|
||||
- [ ] PMG can reach Mailcow on `192.168.3.61:25`
|
||||
- [ ] Mailcow SMTP banner is visible from PMG
|
||||
- [ ] PMG external SMTP port is `25`
|
||||
- [ ] PMG has `bunny-lab.io` configured as a relay domain
|
||||
- [ ] PMG default relay points to `192.168.3.61`
|
||||
- [ ] PMG relay port is `25`
|
||||
- [ ] PMG relay protocol is `smtp`
|
||||
- [ ] PMG internal delivery has MX lookup disabled
|
||||
- [ ] PMG smarthost is unset or `none`
|
||||
- [ ] Mailcow trusts `192.168.3.15` as a forwarding host
|
||||
- [ ] Mailcow forwarding-host spam filter is `Inactive`
|
||||
- [ ] Firewall forwards `WAN :25` to `192.168.3.15:25`
|
||||
- [ ] Firewall still forwards mail client ports directly to Mailcow
|
||||
- [ ] Traefik still handles Mailcow / Roundcube web traffic
|
||||
- [ ] Inbound test mail appears in PMG Tracking Center
|
||||
- [ ] PMG Tracking Center shows `accepted/delivered`
|
||||
- [ ] PMG log shows delivery to `192.168.3.61:25`
|
||||
- [ ] Inbound test mail is delivered to the Mailcow mailbox
|
||||
- [ ] PMG queue is empty after delivery
|
||||
- [ ] Mobile email client still works
|
||||
- [ ] Desktop email client still works
|
||||
- [ ] Webmail still works
|
||||
- [ ] Replying outbound from Mailcow still works
|
||||
- [ ] DKIM behavior is unchanged
|
||||
- [ ] SPF record is unchanged
|
||||
- [ ] DMARC record is unchanged
|
||||
- [ ] Outbound mail routing is unchanged
|
||||
|
||||
## Troubleshooting
|
||||
### Inbound Mail Never Reaches PMG
|
||||
Verify NAT.
|
||||
|
||||
```text
|
||||
WAN :25 -> 192.168.3.15:25
|
||||
```
|
||||
|
||||
Verify inbound port `25` is not blocked by the ISP.
|
||||
|
||||
From an external system:
|
||||
|
||||
```sh
|
||||
# Test public SMTP reachability
|
||||
nc -vz mail.bunny-lab.io 25
|
||||
```
|
||||
|
||||
If external testing is unavailable, send a real external test message and check:
|
||||
|
||||
```text
|
||||
PMG > Tracking Center
|
||||
```
|
||||
|
||||
### PMG Receives Mail but Does Not Deliver to Mailcow
|
||||
Verify PMG relay settings.
|
||||
|
||||
```text
|
||||
Default Relay: 192.168.3.61
|
||||
Relay Port: 25
|
||||
Relay Protocol: smtp
|
||||
Disable MX Lookup: Yes
|
||||
```
|
||||
|
||||
Verify Mailcow SMTP is reachable from PMG.
|
||||
|
||||
```sh
|
||||
# Test Mailcow SMTP from PMG
|
||||
nc -vz 192.168.3.61 25
|
||||
```
|
||||
|
||||
Confirm the Mailcow SMTP banner.
|
||||
|
||||
```sh
|
||||
# Inspect Mailcow SMTP banner from PMG
|
||||
nc 192.168.3.61 25
|
||||
```
|
||||
|
||||
Expected banner:
|
||||
|
||||
```text
|
||||
220-mail.bunny-lab.io ESMTP Postcow
|
||||
220 mail.bunny-lab.io ESMTP Postcow
|
||||
```
|
||||
|
||||
### PMG Shows Reverse DNS Warning for Mailcow
|
||||
A warning like this is not automatically a failure:
|
||||
|
||||
```text
|
||||
inverse host lookup failed: Unknown host
|
||||
```
|
||||
|
||||
If the connection still reports port `25` as open, SMTP connectivity is working.
|
||||
|
||||
### Mailcow Rejects Mail from PMG
|
||||
Verify Mailcow trusts PMG as a forwarding host.
|
||||
|
||||
```text
|
||||
192.168.3.15
|
||||
```
|
||||
|
||||
Verify the recipient domain exists in Mailcow.
|
||||
|
||||
```text
|
||||
bunny-lab.io
|
||||
```
|
||||
|
||||
Verify the recipient mailbox or alias exists in Mailcow.
|
||||
|
||||
### Mail Clients Stop Working
|
||||
Verify only inbound SMTP port `25` was moved to PMG.
|
||||
|
||||
These ports should still forward directly to Mailcow:
|
||||
|
||||
```text
|
||||
465
|
||||
587
|
||||
993
|
||||
995
|
||||
110
|
||||
143
|
||||
4190
|
||||
```
|
||||
|
||||
Expected service ownership:
|
||||
|
||||
```text
|
||||
PMG -> inbound SMTP gateway only
|
||||
Mailcow -> client access and mailbox services
|
||||
```
|
||||
|
||||
### Roundcube or Mailcow Web UI Stops Working
|
||||
Verify web traffic was not moved to PMG.
|
||||
|
||||
Expected path:
|
||||
|
||||
```text
|
||||
WAN :80 -> Traefik :80
|
||||
WAN :443 -> Traefik :443
|
||||
```
|
||||
|
||||
PMG should not replace Traefik for Mailcow or Roundcube web access.
|
||||
|
||||
### Outbound Mail Stops Working
|
||||
Outbound mail should not change during this deployment.
|
||||
|
||||
Verify no changes were made to:
|
||||
|
||||
```text
|
||||
Mailcow relayhost
|
||||
Outbound firewall behavior
|
||||
DKIM signing
|
||||
SPF record
|
||||
DMARC record
|
||||
Public DNS records
|
||||
```
|
||||
|
||||
### Spam Filtering Behavior Is Confusing
|
||||
Use one primary inbound filtering authority.
|
||||
|
||||
Recommended initial state:
|
||||
|
||||
```text
|
||||
PMG = primary inbound edge spam filter
|
||||
Mailcow = mailbox hosting and client access
|
||||
```
|
||||
|
||||
Avoid dual aggressive quarantine policies until basic mail flow is stable.
|
||||
|
||||
## Confirmed Final State
|
||||
After Stage 1, the environment should operate as follows:
|
||||
|
||||
```text
|
||||
Inbound SMTP:
|
||||
Internet -> pfSense WAN :25 -> PMG 192.168.3.15:25 -> Mailcow 192.168.3.61:25
|
||||
|
||||
Outbound SMTP:
|
||||
Mailcow -> Internet
|
||||
|
||||
Mail Client Access:
|
||||
Clients -> Mailcow
|
||||
|
||||
Webmail / Roundcube:
|
||||
Internet -> Traefik -> Mailcow
|
||||
```
|
||||
|
||||
The only public NAT behavior changed is:
|
||||
|
||||
```text
|
||||
WAN :25
|
||||
```
|
||||
|
||||
Unchanged components:
|
||||
|
||||
```text
|
||||
DNS records
|
||||
DKIM behavior
|
||||
SPF record
|
||||
DMARC record
|
||||
Outbound mail routing
|
||||
SMTP submission
|
||||
IMAP
|
||||
POP3
|
||||
ManageSieve
|
||||
Mailcow certificates
|
||||
Traefik web routing
|
||||
Mailcow / Roundcube web access
|
||||
```
|
||||
|
||||
## Deployment Status
|
||||
This document completes Stage 1 of the PMG deployment.
|
||||
|
||||
```text
|
||||
Stage 1: Inbound filtering only
|
||||
Stage 2: Optional outbound filtering
|
||||
```
|
||||
|
||||
At the end of Stage 1:
|
||||
|
||||
```text
|
||||
PMG = inbound SMTP filtering only
|
||||
Mailcow = mailboxes, webmail, authenticated submission, certificates, DKIM, outbound delivery, user-facing mail services
|
||||
```
|
||||
|
||||
## Maintain Mail Delivery
|
||||
For sender-validation and trusted-relay failures after integration, follow [Repair Trusted Mail Delivery Between PMG and Mailcow](<../../../../workflows/Applications/Email/Proxmox Mail Gateway/Repair Trusted Mail Delivery Between PMG and Mailcow.md>).
|
||||
|
||||
## Related Documentation
|
||||
- [Related Email Documentation](<../../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
tags:
|
||||
- cPanel
|
||||
- Email
|
||||
---
|
||||
|
||||
## Purpose
|
||||
This documentation helps you deploy an email server within a cPanel hosted environment.
|
||||
|
||||
!!! warning "Incomplete Procedure"
|
||||
The deployment steps remain a scaffold. No completed cPanel mail-server procedure is recorded here.
|
||||
|
||||
!!! note "Assumptions"
|
||||
It is assumed that the cPanel environment is set up (prior) to following this documentation, as deploying cPanel itself is not covered in this document.
|
||||
|
||||
## Related Documentation
|
||||
- [Related Email Documentation](<../../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
@@ -0,0 +1,285 @@
|
||||
---
|
||||
tags:
|
||||
- IredMail
|
||||
- Email
|
||||
---
|
||||
|
||||
## Purpose
|
||||
Self-Hosted Open-Source email server that can be setup in minutes, and is enterprise-grade if upgraded with an iRedAdmin-Pro license.
|
||||
|
||||
!!! note "Assumptions"
|
||||
It is assumed you are running at least Rocky Linux 9.3. While you can use CentOS Stream, Alma, Debian, Ubuntu, FreeBSD, and OpenBSD, the more enterprise-level sections of my homelab are built on Rocky Linux.
|
||||
|
||||
!!! warning "iRedMail / iRedAdmin-Pro Version Mismatching"
|
||||
This document assumes you are deploying iRedMail 1.6.8, which at the time of writing, coincided with iRedAdmin-Pro 5.5. If you are not careful, you may end up with mismatched versions down the road as iRedMail keeps getting updates. Due to how you have to pay for a license in order to get access to the original iRedAdmin-Pro-SQL repository data, if a newer version of iRedAdmin-Pro comes out after February 2025, this document may not account for that, leaving you on an older version of the software. This is unavoidable if you want to avoid paying $500/year for licensing this software.
|
||||
|
||||
## Overview
|
||||
The instructions below are specific to my homelab environment, but can be easily ported depending on your needs. This guide also assumes you want to operate a PostgreSQL-based iRedMail installation. You can follow along with the official documentation on [Installation](https://docs.iredmail.org/install.iredmail.on.rhel.html) as well as [DNS Record Configuration](https://docs.iredmail.org/setup.dns.html) if you want more detailed explanations throughout the installation process.
|
||||
|
||||
## Configure FQDN
|
||||
Ensure the FQDN of the server is correctly set in `/etc/hostname`. The `/etc/hosts` file will be automatically injected using the FQDN from `/etc/hostname` in a script further down, don't worry about editing it.
|
||||
|
||||
## Disable SELinux
|
||||
iRedMail doesn't work with SELinux, so please disable it by setting below value in its config file /etc/selinux/config. After server reboot, SELinux will be completely disabled.
|
||||
|
||||
```sh
|
||||
# Elevate to Root User
|
||||
sudo su
|
||||
|
||||
# Disable SELinux
|
||||
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config # (1)
|
||||
setenforce 0
|
||||
```
|
||||
|
||||
1. If you prefer to let SELinux prints warnings instead of enforcing, you can set this value instead: `SELINUX=permissive`
|
||||
|
||||
## iRedMail Installation
|
||||
### Set Domain and iRedMail Version
|
||||
Start by connecting to the server / VM via SSH, then set silent deployment variables below.
|
||||
|
||||
```sh
|
||||
# Define some deployment variables.
|
||||
VERSION="1.6.8" # (1)
|
||||
MAIL_DOMAIN="bunny-lab.io" # (2)
|
||||
```
|
||||
|
||||
1. This is the version of iRedMail you are deploying. You can find the newest version on the [iRedMail Download Page](https://www.iredmail.org/download.html).
|
||||
2. This is the domain suffix that appears after mailbox names. e.g. `first.last@bunny-lab.io` would use a domain value of `bunny-lab.io`.
|
||||
|
||||
You will then proceed to bootstrap a silent unattended installation of iRedMail. (I've automated as much as I can to make this as turn-key as possible). Just copy/paste this whole thing into your terminal and hit ENTER.
|
||||
|
||||
!!! danger "Storage Space Requirements"
|
||||
You absolutely need to ensure that `/var/vmail` has a lot of space. At least 16GB. This is where all of your emails / mailboxes / a lot of settings will be. If possible, create a second physical/virtual disk specifically for the `/var` partition, or specifically for `/var/vmail` at minimum, so you can expand it over time if necessary. LVM-based provisioning is recommended but not required.
|
||||
|
||||
### Install iRedMail
|
||||
```sh
|
||||
# Automatically configure the /etc/hosts file to point to the server listed in "/etc/hostname".
|
||||
sudo sed -i "1i 127.0.0.1 $(cat /etc/hostname) $(cut -d '.' -f 1 /etc/hostname) localhost localhost.localdomain localhost4 localhost4.localdomain4" /etc/hosts
|
||||
|
||||
# Check for Updates in the Package Manager
|
||||
yum update -y
|
||||
|
||||
# Install Extra Packages for Enterprise Linux
|
||||
dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
|
||||
|
||||
# Download the iRedMail binaries and extract them
|
||||
cd /root
|
||||
curl https://codeload.github.com/iredmail/iRedMail/tar.gz/refs/tags/$VERSION -o iRedMail-$VERSION.tar.gz
|
||||
tar zxf iRedMail-$VERSION.tar.gz
|
||||
|
||||
# Create the unattend config file for silent deployment. This will automatically generate random 32-character passwords for all of the databases.
|
||||
(echo "export STORAGE_BASE_DIR='/var/vmail'"; echo "export WEB_SERVER='NGINX'"; echo "export BACKEND_ORIG='PGSQL'"; echo "export BACKEND='PGSQL'"; for var in VMAIL_DB_BIND_PASSWD VMAIL_DB_ADMIN_PASSWD MLMMJADMIN_API_AUTH_TOKEN NETDATA_DB_PASSWD AMAVISD_DB_PASSWD IREDADMIN_DB_PASSWD RCM_DB_PASSWD SOGO_DB_PASSWD SOGO_SIEVE_MASTER_PASSWD IREDAPD_DB_PASSWD FAIL2BAN_DB_PASSWD PGSQL_ROOT_PASSWD DOMAIN_ADMIN_PASSWD_PLAIN; do echo "export $var='$(openssl rand -base64 48 | tr -d '+/=' | head -c 32)'"; done; echo "export FIRST_DOMAIN='$MAIL_DOMAIN'"; echo "export USE_IREDADMIN='YES'"; echo "export USE_SOGO='YES'"; echo "export USE_NETDATA='YES'"; echo "export USE_FAIL2BAN='YES'"; echo "#EOF") > /root/iRedMail-$VERSION/config
|
||||
|
||||
# Make Config Read-Only
|
||||
chmod 400 /root/iRedMail-$VERSION/config
|
||||
|
||||
# Set Environment Variables for Silent Deployment
|
||||
cd /root/iRedMail-$VERSION
|
||||
|
||||
# Deploy iRedMail via the Install Script
|
||||
AUTO_USE_EXISTING_CONFIG_FILE=y \
|
||||
AUTO_INSTALL_WITHOUT_CONFIRM=y \
|
||||
AUTO_CLEANUP_REMOVE_SENDMAIL=y \
|
||||
AUTO_CLEANUP_REPLACE_FIREWALL_RULES=y \
|
||||
AUTO_CLEANUP_RESTART_FIREWALL=n \
|
||||
AUTO_CLEANUP_REPLACE_MYSQL_CONFIG=y \
|
||||
bash iRedMail.sh
|
||||
```
|
||||
|
||||
When the installation is completed, take note of any output it gives you for future reference. Then reboot the server to finalize the server installation.
|
||||
|
||||
```text
|
||||
reboot
|
||||
```
|
||||
|
||||
!!! warning "Automatically-Generated Postmaster Password"
|
||||
When you deploy iRedMail, it will give you a username and password for the postmaster account. If you accidentally forget to document this, you can log back into the server via SSH and see the credentials at `/root/iRedMail-$VERSION/iRedMail.tips`. This file is critical and contains passwords and DNS information such as DKIM record information as well.
|
||||
|
||||
## Networking Configuration
|
||||
### Nested Reverse Proxy Configuration
|
||||
In my homelab environment, I run Traefik reverse proxy in front of everything, which includes the NGINX reverse proxy that iRedMail creates. In my scenario, I have to make some custom adjustments to the reverse proxy dynamic configuration data to ensure it will step aside and let the NGINX reverse proxy inside of iRedMail handle everything, including handling its own SSL termination with Let's Encrypt.
|
||||
|
||||
```sh
|
||||
tcp:
|
||||
routers:
|
||||
mail-tcp-router:
|
||||
rule: "HostSNI(`mail.bunny-lab.io`)"
|
||||
entryPoints: ["websecure"]
|
||||
service: mail-nginx-service
|
||||
tls:
|
||||
passthrough: true
|
||||
|
||||
services:
|
||||
mail-nginx-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- address: "192.168.3.13:443"
|
||||
```
|
||||
|
||||
### Let's Encrypt ACME Certbot
|
||||
At this point, we want to set up automatic Let's Encrypt SSL termination inside of iRedMail so we don't have to manually touch this in the future.
|
||||
|
||||
#### Generate SSL Certificate
|
||||
=== "Debian/Ubuntu"
|
||||
|
||||
```sh
|
||||
# Download the Certbot
|
||||
sudo apt update
|
||||
sudo apt install -y certbot
|
||||
sudo certbot certonly --webroot -w /var/www/html -d mail.bunny-lab.io
|
||||
|
||||
# Set up Symbolic Links (Where iRedMail Expects Them)
|
||||
sudo mv /etc/ssl/certs/iRedMail.crt{,.bak}
|
||||
sudo mv /etc/ssl/private/iRedMail.key{,.bak}
|
||||
sudo ln -s /etc/letsencrypt/live/mail.bunny-lab.io/fullchain.pem /etc/ssl/certs/iRedMail.crt
|
||||
sudo ln -s /etc/letsencrypt/live/mail.bunny-lab.io/privkey.pem /etc/ssl/private/iRedMail.key
|
||||
|
||||
# Restart iRedMail Services
|
||||
sudo systemctl restart postfix dovecot nginx
|
||||
```
|
||||
|
||||
=== "CentOS/Rocky/AlmaLinux"
|
||||
|
||||
```sh
|
||||
# Download the Certbot
|
||||
sudo yum install -y epel-release
|
||||
sudo yum install -y certbot
|
||||
sudo certbot certonly --webroot -w /var/www/html -d mail.bunny-lab.io
|
||||
|
||||
# Set up Symbolic Links (Where iRedMail Expects Them)
|
||||
sudo mv /etc/pki/tls/certs/iRedMail.crt{,.bak}
|
||||
sudo mv /etc/pki/tls/private/iRedMail.key{,.bak}
|
||||
sudo ln -s /etc/letsencrypt/live/mail.bunny-lab.io/fullchain.pem /etc/pki/tls/certs/iRedMail.crt
|
||||
sudo ln -s /etc/letsencrypt/live/mail.bunny-lab.io/privkey.pem /etc/pki/tls/private/iRedMail.key
|
||||
|
||||
# Restart iRedMail Services
|
||||
sudo systemctl restart postfix dovecot nginx
|
||||
```
|
||||
|
||||
#### Configure Automatic Renewal
|
||||
To automate the renewal process, set up a cron job that runs the certbot renew command regularly. This command will renew certificates that are due to expire within 30 days.
|
||||
|
||||
Open the crontab editor with the following command:
|
||||
|
||||
```sh
|
||||
sudo crontab -e
|
||||
```
|
||||
|
||||
Add the following line to run the renewal process daily at 3:01 AM:
|
||||
|
||||
```text
|
||||
1 3 * * * certbot renew --post-hook 'systemctl restart postfix dovecot nginx'
|
||||
```
|
||||
|
||||
### DNS Records
|
||||
Now you need to set up DNS records in Cloudflare (or the DNS Registrar you have configured) so that the mail server can be found and validated.
|
||||
|
||||
| **Type** | **Name** | **Content** | **Proxy Status** | **TTL** |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| MX | bunny-lab.io | mail.bunny-lab.io | DNS Only | Auto |
|
||||
| TXT | bunny-lab.io | "v=spf1 a:mail.bunny-lab.io ~all" | DNS Only | Auto |
|
||||
| TXT | dkim._domainkey | v=DKIM1; p=`IREDMAIL-DKIM-VALUE` | DNS Only | 1 Hour |
|
||||
| TXT | _dmarc | "v=DMARC1; p=reject; pct=100; rua=mailto:postmaster@bunny-lab.io; ruf=mailto:postmaster@bunny-lab.io" | DNS Only | Auto |
|
||||
|
||||
### Port Forwarding
|
||||
Lastly, we need to set up port forwarding to open the ports necessary for the server to send and receive email.
|
||||
|
||||
| **Protocol** | **Port** | **Destination Server** | **Description** |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| TCP | 995 | 192.168.3.13 | POP3 service: port 110 over STARTTLS |
|
||||
| TCP | 993 | 192.168.3.13 | IMAP service: port 143 over STARTTLS |
|
||||
| TCP | 587 | 192.168.3.13 | SMTP service: port 587 over STARTTLS |
|
||||
| TCP | 25 | 192.168.3.13 | SMTP (Email Server-to-Server Communication) |
|
||||
|
||||
## Install iRedAdmin-Pro
|
||||
When it comes to adding extra features, start by copying the data from this [Bunny Lab repository](https://git.bunny-lab.io/bunny-lab/iRedAdmin-Pro-SQL) to the following folder by running these commands first:
|
||||
|
||||
```sh
|
||||
# Stop the iRedMail Services
|
||||
sudo systemctl stop postfix dovecot nginx
|
||||
|
||||
# Grant Temporary Access to the iRedAdmin Files and Folders
|
||||
sudo chown nicole:nicole -R /opt/www/iRedAdmin-2.5
|
||||
|
||||
# Copy the data from the repository mentioned above into this folder, merging identical folders and files. Feel free to use your preferred file transfer tool tool / method (e.g. MobaXTerm / WinSCP).
|
||||
|
||||
# Change permissions back to normal
|
||||
sudo chown iredadmin:iredadmin -R /opt/www/iRedAdmin-2.5
|
||||
|
||||
# Reboot the Server
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
### Activate iRedAdmin-Pro
|
||||
At this point, if you want to use iRedAdmin-Pro, you either have a valid license key, or you adjust the python function responsible for checking license keys to bypass the check, effectively forcing iRedAdmin to be activated. In this instance, we will be forcing activation by adjusting this function, seen below.
|
||||
|
||||
There is someone else who outlined all of these changes, and additional (aesthetic) ones, like removing the renew license button from the license page, but the core functionality is seen below. If you want to see the original repository this was inspired from, it can be found [Here](https://github.com/marcus-alicia/iRedAdmin-Pro-SQL)
|
||||
|
||||
```sh
|
||||
# Take permission of the python script
|
||||
sudo chown nicole:nicole /opt/www/iRedAdmin-2.5/libs/sysinfo.py
|
||||
```
|
||||
|
||||
=== "Original Activation Function"
|
||||
|
||||
```python title="/opt/www/iRedAdmin-2.5/libs/sysinfo.py"
|
||||
def get_license_info():
|
||||
if len(__id__) != 32:
|
||||
web.conn_iredadmin.delete("updatelog")
|
||||
session.kill()
|
||||
raise web.seeother("/login?msg=INVALID_PRODUCT_ID")
|
||||
|
||||
params = {
|
||||
"v": __version__,
|
||||
"f": __id__,
|
||||
"lang": settings.default_language,
|
||||
"host": get_hostname(),
|
||||
"backend": settings.backend,
|
||||
"webmaster": settings.webmaster,
|
||||
"mac": ",".join(get_all_mac_addresses()),
|
||||
}
|
||||
|
||||
url = "https://lic.iredmail.org/check_version/licenseinfo/" + __id__ + ".json"
|
||||
url += "?" + urllib.parse.urlencode(params)
|
||||
|
||||
try:
|
||||
urlopen = __get_proxied_urlopen()
|
||||
_json = urlopen(url).read()
|
||||
lic_info = json.loads(_json)
|
||||
lic_info["id"] = __id__
|
||||
return True, lic_info
|
||||
except Exception as e:
|
||||
return False, web.urlquote(e)
|
||||
```
|
||||
|
||||
=== "Bypassed Activation Function"
|
||||
|
||||
```python title="/opt/www/iRedAdmin-2.5/libs/sysinfo.py"
|
||||
def get_license_info():
|
||||
return True, {
|
||||
"status": "active",
|
||||
"product": "iRedAdmin-Pro-SQL",
|
||||
"licensekey": "forcefully-open-source",
|
||||
"upgradetutorials": "https://docs.iredmail.org/iredadmin-pro.releases.html",
|
||||
"purchased": "Never",
|
||||
"contacts": "nicole.rappe@bunny-lab.io",
|
||||
"latestversion": "5.5",
|
||||
"expired": "Never",
|
||||
"releasenotes": "https://docs.iredmail.org/iredadmin-pro.releases.html",
|
||||
"id": __id__
|
||||
}
|
||||
```
|
||||
|
||||
```sh
|
||||
# Revert permission of the python script
|
||||
sudo chown iredadmin:iredadmin /opt/www/iRedAdmin-2.5/libs/sysinfo.py
|
||||
|
||||
# Reboot the Server (To be safe)
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
!!! success "Successful Activation"
|
||||
At this point, if you navigate to the [iRedAdmin-Pro License Page](https://mail.bunny-lab.io/iredadmin/system/license) you should see the server is activated successfully.
|
||||
|
||||
## Related Documentation
|
||||
- [Related Email Documentation](<../../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
@@ -0,0 +1,168 @@
|
||||
---
|
||||
tags:
|
||||
- Mailcow
|
||||
- Email
|
||||
- Docker
|
||||
---
|
||||
|
||||
## Purpose
|
||||
The purpose of this document is to illustrate how to deploy Mailcow in a dockerized format.
|
||||
|
||||
!!! note "Assumptions"
|
||||
It is assumed that you are deploying Mailcow into an existing Ubuntu Server environment. If you are using a different operating system, refer to the [official documentation](https://docs.mailcow.email/getstarted/install/).
|
||||
|
||||
### Setting Up Docker
|
||||
Go ahead and set up docker and docker-compose with the following commands:
|
||||
|
||||
```bash
|
||||
sudo su # (1)
|
||||
curl -sSL https://get.docker.com/ | CHANNEL=stable sh # (2)
|
||||
apt install docker-compose-plugin # (3)
|
||||
systemctl enable --now docker # (4)
|
||||
```
|
||||
|
||||
1. Make yourself root.
|
||||
2. Install `Docker`
|
||||
3. Install `Docker-Compose`
|
||||
4. Make docker run automatically when the server is booted.
|
||||
|
||||
### Download and Deploy Mailcow
|
||||
Run the following commands to pull down the mailcow deployment files and install them with docker. Go get a cup of coffee as the `docker compose pull` command may take a while to run.
|
||||
|
||||
!!! note "Potential `Docker Compose` Issues"
|
||||
If you run the `docker-compose pull` command and it fails for some reason, change the command to `docker compose pull` instead. This is just the difference between the plugin version of compose versus the standalone version. Both will have the same result.
|
||||
|
||||
```bash
|
||||
cd /opt
|
||||
git clone https://github.com/mailcow/mailcow-dockerized
|
||||
cd mailcow-dockerized
|
||||
./generate_config.sh # (1)
|
||||
docker-compose pull # (2)
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
1. Generate a configuration file. Use a FQDN (`host.domain.tld`) as hostname when asked.
|
||||
2. If you get an error about the ports of the `nginx-mailcow` service in the `docker-compose.yml` stack, change the ports for that service as follows:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
||||
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
|
||||
```
|
||||
|
||||
### Firewall / NAT Configuration
|
||||
Forward Mailcow service ports as follows:
|
||||
|
||||
```text
|
||||
WAN :80 -> Traefik :80
|
||||
WAN :443 -> Traefik :443
|
||||
|
||||
WAN :25 -> Mailcow :25
|
||||
WAN :465 -> Mailcow :465
|
||||
WAN :587 -> Mailcow :587
|
||||
WAN :993 -> Mailcow :993
|
||||
WAN :995 -> Mailcow :995
|
||||
WAN :110 -> Mailcow :110
|
||||
WAN :143 -> Mailcow :143
|
||||
WAN :4190 -> Mailcow :4190
|
||||
```
|
||||
|
||||
Mail protocol ports should be sent directly to the Mailcow server. Traefik should not terminate or proxy the SMTP, SMTPS, Submission, IMAP, IMAPS, POP3, POP3S, or ManageSieve ports.
|
||||
|
||||
### Reverse-Proxy Configuration
|
||||
For the purposes of this document, it will be assumed that you are deploying Mailcow behind Traefik for web traffic only. Traefik should pass HTTPS through transparently, allowing Mailcow to manage and serve its own certificates.
|
||||
|
||||
You can use the following dynamic configuration file to achieve this:
|
||||
|
||||
```yaml title="/srv/containers/traefik/config/dynamic/mail.bunny-lab.io.yml"
|
||||
# =====================================================================
|
||||
# Mailcow / Traefik Dynamic Configuration
|
||||
# Hostname: mail.bunny-lab.io
|
||||
#
|
||||
# Mailcow owns certificates.
|
||||
# Traefik forwards HTTP and passes HTTPS through.
|
||||
# Mail protocol ports are handled directly by pfSense -> Mailcow.
|
||||
# =====================================================================
|
||||
|
||||
http:
|
||||
routers:
|
||||
mailcow-http:
|
||||
entryPoints:
|
||||
- web
|
||||
rule: Host(`mail.bunny-lab.io`)
|
||||
service: mailcow-http
|
||||
priority: 100
|
||||
|
||||
services:
|
||||
mailcow-http:
|
||||
loadBalancer:
|
||||
passHostHeader: true
|
||||
servers:
|
||||
- url: "http://192.168.3.61:80"
|
||||
|
||||
tcp:
|
||||
routers:
|
||||
mailcow-https-passthrough:
|
||||
entryPoints:
|
||||
- websecure
|
||||
rule: HostSNI(`mail.bunny-lab.io`)
|
||||
service: mailcow-https
|
||||
tls:
|
||||
passthrough: true
|
||||
|
||||
services:
|
||||
mailcow-https:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- address: "192.168.3.61:443"
|
||||
```
|
||||
|
||||
### Traefik-Specific Configuration
|
||||
Traefik only needs the standard HTTP and HTTPS entrypoints for Mailcow web traffic. Mail protocol ports should not be exposed through Traefik if the firewall is forwarding those ports directly to Mailcow.
|
||||
|
||||
```yaml
|
||||
#Entrypoints
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
|
||||
#Ports
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
```
|
||||
|
||||
Do not add Mailcow mail protocol entrypoints or port bindings to Traefik unless you intentionally want Traefik to proxy those ports.
|
||||
|
||||
### Certificate Validation
|
||||
Mailcow should manage and serve the certificate for `mail.bunny-lab.io`.
|
||||
To verify the active Mailcow certificate on disk, run the following on the Mailcow server:
|
||||
|
||||
```bash
|
||||
cd /opt/mailcow-dockerized
|
||||
|
||||
openssl x509 \
|
||||
-in /opt/mailcow-dockerized/data/assets/ssl/cert.pem \
|
||||
-noout -subject -issuer -dates -serial -fingerprint -sha256
|
||||
```
|
||||
|
||||
If the certificate has renewed but services are still presenting an old certificate, restart the Mailcow services that serve TLS:
|
||||
|
||||
```bash
|
||||
cd /opt/mailcow-dockerized
|
||||
docker compose restart postfix-mailcow dovecot-mailcow nginx-mailcow
|
||||
```
|
||||
|
||||
### Login to Mailcow
|
||||
At this point, the Mailcow server has been deployed so you can log into it.
|
||||
|
||||
- **Administrators**: `https://${MAILCOW_HOSTNAME}/admin` (Username: `admin` | Password: `moohoo`)
|
||||
- **Regular Mailbox Users**: `https://${MAILCOW_HOSTNAME}` (*FQDN only*)
|
||||
|
||||
### Mail-Client Considerations
|
||||
You need to ensure that you generate an app password if you have MFA enabled within Mailcow. (MFA is non-functional in Roundcube/SoGo, you set it up via Mailcow itself). You can access it via the Mailcow configuration page: https://mail.bunny-lab.io/user, then look for the "**App Passwords**" tab.
|
||||
|
||||
### Running Updates
|
||||
If you want to run updates, just SSH into the server, and navigate to `/opt/mailcow-dockerized` and run `./update.sh`. I recommend avoiding the IPv6 implementation section. Be patient, and the upgrade will be fully-automated.
|
||||
|
||||
## Related Documentation
|
||||
- [Related Email Documentation](<../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
|
||||
Reference in New Issue
Block a user