mirror of
https://github.com/ION606/learn.git
synced 2026-05-14 21:06:56 +00:00
Create mail-server-setup.md
This commit is contained in:
@@ -0,0 +1,415 @@
|
|||||||
|
# **Mail Server with WireGuard and Linode Proxy**
|
||||||
|
|
||||||
|
This guide will set up a mail server on a local machine (Fedora) behind a restricted network. A **Linode VPS** (Ubuntu) will act as a proxy to forward traffic using **WireGuard** and **rinetd**. The webmail interface will be provided via **RainLoop** running in a Docker container.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Prerequisites**
|
||||||
|
|
||||||
|
- **Linode VPS** with a public IP: `<LINODE_PUBLIC_IP>`
|
||||||
|
- **Local Fedora Server** (mail server) without direct internet access.
|
||||||
|
- **Domain**: `<your-domain.com>` (e.g., `ion606.com`)
|
||||||
|
- Tools installed:
|
||||||
|
- **Docker** and **Docker Compose**
|
||||||
|
- **WireGuard**
|
||||||
|
- **Postfix** and **Dovecot**
|
||||||
|
- **Nginx**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **1. Set Up WireGuard VPN**
|
||||||
|
|
||||||
|
WireGuard will create a private VPN tunnel between your Linode VPS and your local Fedora server.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **1.1 Generate WireGuard Keys**
|
||||||
|
|
||||||
|
### On the **Linode VPS**:
|
||||||
|
```bash
|
||||||
|
wg genkey | tee linode-private.key | wg pubkey > linode-public.key
|
||||||
|
cat linode-private.key # Save this for later
|
||||||
|
cat linode-public.key # Save this for later
|
||||||
|
```
|
||||||
|
|
||||||
|
### On the **Local Server**:
|
||||||
|
```bash
|
||||||
|
wg genkey | tee local-private.key | wg pubkey > local-public.key
|
||||||
|
cat local-private.key # Save this for later
|
||||||
|
cat local-public.key # Save this for later
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **1.2 Configure WireGuard**
|
||||||
|
|
||||||
|
### On the **Linode VPS** (`/etc/wireguard/wg0.conf`):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = <LINODE_PRIVATE_KEY>
|
||||||
|
Address = 10.0.0.1/24
|
||||||
|
ListenPort = 51820
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = <LOCAL_PUBLIC_KEY>
|
||||||
|
AllowedIPs = 10.0.0.2/32
|
||||||
|
PersistentKeepalive = 25
|
||||||
|
```
|
||||||
|
|
||||||
|
### On the **Local Server** (`/etc/wireguard/wg0.conf`):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = <LOCAL_PRIVATE_KEY>
|
||||||
|
Address = 10.0.0.2/24
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = <LINODE_PUBLIC_KEY>
|
||||||
|
AllowedIPs = 10.0.0.1/32
|
||||||
|
Endpoint = <LINODE_PUBLIC_IP>:51820
|
||||||
|
PersistentKeepalive = 25
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **1.3 Start WireGuard**
|
||||||
|
|
||||||
|
### Enable and Start WireGuard on Both Servers:
|
||||||
|
```bash
|
||||||
|
sudo systemctl enable wg-quick@wg0
|
||||||
|
sudo systemctl start wg-quick@wg0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify the Tunnel:
|
||||||
|
```bash
|
||||||
|
ping 10.0.0.1 # From local server
|
||||||
|
ping 10.0.0.2 # From Linode VPS
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **2. Forward Mail Traffic Using rinetd**
|
||||||
|
|
||||||
|
Install and configure `rinetd` on the Linode VPS to forward mail traffic to your local server.
|
||||||
|
|
||||||
|
### **Install rinetd**:
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install rinetd -y
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Configure rinetd**:
|
||||||
|
Edit `/etc/rinetd.conf`:
|
||||||
|
```plaintext
|
||||||
|
0.0.0.0 587 10.0.0.2 587
|
||||||
|
0.0.0.0 993 10.0.0.2 993
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart `rinetd`:
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart rinetd
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **3. Install and Configure Mail Server (Postfix + Dovecot)**
|
||||||
|
|
||||||
|
## **3.1 Install Postfix and Dovecot**
|
||||||
|
|
||||||
|
On the **local Fedora server**:
|
||||||
|
```bash
|
||||||
|
sudo dnf install postfix dovecot -y
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **3.2 Configure Postfix**
|
||||||
|
|
||||||
|
Edit `/etc/postfix/main.cf`:
|
||||||
|
```ini
|
||||||
|
inet_interfaces = 10.0.0.2
|
||||||
|
myhostname = mail.<your-domain.com>
|
||||||
|
mydomain = <your-domain.com>
|
||||||
|
myorigin = $mydomain
|
||||||
|
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
|
||||||
|
relay_domains = $mydestination
|
||||||
|
mynetworks = 127.0.0.0/8, 10.0.0.1/32
|
||||||
|
smtp_use_tls = yes
|
||||||
|
smtpd_use_tls = yes
|
||||||
|
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||||
|
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart Postfix:
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart postfix
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **3.3 Configure Dovecot**
|
||||||
|
|
||||||
|
Edit `/etc/dovecot/conf.d/10-mail.conf`:
|
||||||
|
```ini
|
||||||
|
mail_location = mbox:~/mail:INBOX=/var/mail/%u
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `/etc/dovecot/conf.d/10-ssl.conf`:
|
||||||
|
```ini
|
||||||
|
ssl = yes
|
||||||
|
ssl_cert = </etc/ssl/certs/dovecot-selfsigned.pem
|
||||||
|
ssl_key = </etc/ssl/private/dovecot-selfsigned.key
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart Dovecot:
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart dovecot
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **4. Set Up RainLoop Webmail in Docker**
|
||||||
|
|
||||||
|
## **4.1 Create Docker Compose File**
|
||||||
|
|
||||||
|
Create the following structure:
|
||||||
|
```plaintext
|
||||||
|
~/docker/rainloop/
|
||||||
|
└── docker-compose.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
**`docker-compose.yml`**:
|
||||||
|
```yaml
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
rainloop:
|
||||||
|
container_name: rainloop
|
||||||
|
image: hardware/rainloop
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./data:/rainloop/data:z
|
||||||
|
ports:
|
||||||
|
- "8888:8888"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **4.2 Start RainLoop**
|
||||||
|
|
||||||
|
From the `~/docker/rainloop/` directory, run:
|
||||||
|
```bash
|
||||||
|
sudo docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **4.3 Access RainLoop Admin Panel**
|
||||||
|
|
||||||
|
1. Open a browser and visit:
|
||||||
|
```
|
||||||
|
https://mail.<your-domain.com>:8888/?admin
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Log in with:
|
||||||
|
- **Username**: `admin`
|
||||||
|
- **Password**: `12345` (default).
|
||||||
|
|
||||||
|
3. Add your domain configuration:
|
||||||
|
- **IMAP**: `mail.<your-domain.com>` (Port 993, SSL)
|
||||||
|
- **SMTP**: `mail.<your-domain.com>` (Port 587, STARTTLS)
|
||||||
|
|
||||||
|
Test the configuration and save.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **5. Update DNS Records**
|
||||||
|
|
||||||
|
Set the following DNS records in your provider (e.g., Cloudflare):
|
||||||
|
|
||||||
|
- **MX Record**:
|
||||||
|
- Name: `@`
|
||||||
|
- Content: `mail.<your-domain.com>`
|
||||||
|
- Priority: `10`
|
||||||
|
|
||||||
|
- **A Record**:
|
||||||
|
- Name: `mail`
|
||||||
|
- Content: `<LINODE_PUBLIC_IP>`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **6. Test the Mail Server**
|
||||||
|
|
||||||
|
1. **Send a test email** to `user@<your-domain.com>` from an external account (e.g., Gmail).
|
||||||
|
|
||||||
|
2. Log in to RainLoop:
|
||||||
|
- Visit: `https://mail.<your-domain.com>:8888`
|
||||||
|
- Log in with your email account credentials.
|
||||||
|
|
||||||
|
3. Check for incoming emails.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# **7. Errors and Troubleshooting**
|
||||||
|
|
||||||
|
_Sidenote: Here are the commands to view the logs from the above programs_
|
||||||
|
- **Postfix Logs**:
|
||||||
|
```bash
|
||||||
|
sudo tail -f /var/log/maillog
|
||||||
|
```
|
||||||
|
- **Dovecot Logs**:
|
||||||
|
```bash
|
||||||
|
sudo tail -f /var/log/dovecot.log
|
||||||
|
```
|
||||||
|
- **RainLoop Errors**:
|
||||||
|
Check `~/docker/rainloop/data/_data_/logs/`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **1. WireGuard: "Required key not available"**
|
||||||
|
|
||||||
|
### **Cause**:
|
||||||
|
- Missing or mismatched WireGuard keys.
|
||||||
|
- Configuration errors in the `AllowedIPs` or `Endpoint`.
|
||||||
|
|
||||||
|
### **Solution**:
|
||||||
|
- Regenerate and verify keys on both servers:
|
||||||
|
```bash
|
||||||
|
wg genkey | tee private.key | wg pubkey > public.key
|
||||||
|
```
|
||||||
|
- Replace keys in `/etc/wireguard/wg0.conf` and restart WireGuard:
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart wg-quick@wg0
|
||||||
|
```
|
||||||
|
- Verify the tunnel with `wg show` and ping test (`ping 10.0.0.1` and `ping 10.0.0.2`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **2. Postfix: "inet_interfaces: no local interface found"**
|
||||||
|
|
||||||
|
### **Cause**:
|
||||||
|
- Postfix is configured to bind to `10.0.0.2` before WireGuard is active.
|
||||||
|
|
||||||
|
### **Solution**:
|
||||||
|
- Temporarily set Postfix to listen on all interfaces:
|
||||||
|
```ini
|
||||||
|
inet_interfaces = all
|
||||||
|
```
|
||||||
|
- Use systemd overrides to start Postfix after WireGuard:
|
||||||
|
```bash
|
||||||
|
sudo systemctl edit postfix
|
||||||
|
```
|
||||||
|
Add:
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
After=network.target wg-quick@wg0.service
|
||||||
|
Wants=wg-quick@wg0.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart Postfix:
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart postfix
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **3. RainLoop: "Data folder permissions error [is_readable]"**
|
||||||
|
|
||||||
|
### **Cause**:
|
||||||
|
- RainLoop container cannot access the host `data` directory due to file ownership or SELinux restrictions.
|
||||||
|
|
||||||
|
### **Solution**:
|
||||||
|
1. Fix directory ownership for RainLoop's user (`UID 33`):
|
||||||
|
```bash
|
||||||
|
sudo chown -R 33:33 ~/docker/rainloop/data
|
||||||
|
sudo chmod -R 755 ~/docker/rainloop/data
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Adjust SELinux labels (Fedora specific):
|
||||||
|
```bash
|
||||||
|
sudo chcon -R -t container_file_t ~/docker/rainloop/data
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Update `docker-compose.yml` to add `:z` for SELinux compatibility:
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
- ./data:/rainloop/data:z
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart RainLoop:
|
||||||
|
```bash
|
||||||
|
sudo docker-compose down
|
||||||
|
sudo docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **4. Dovecot: "ssl_cert: Can't open file"**
|
||||||
|
|
||||||
|
### **Cause**:
|
||||||
|
- The SSL certificate file is missing or incorrectly referenced.
|
||||||
|
|
||||||
|
### **Solution**:
|
||||||
|
1. Generate a self-signed SSL certificate:
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /etc/ssl/certs /etc/ssl/private
|
||||||
|
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
||||||
|
-keyout /etc/ssl/private/dovecot-selfsigned.key \
|
||||||
|
-out /etc/ssl/certs/dovecot-selfsigned.pem \
|
||||||
|
-subj "/C=US/ST=State/L=City/O=Organization/OU=IT/CN=mail.<your-domain.com>"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Update Dovecot's configuration in `/etc/dovecot/conf.d/10-ssl.conf`:
|
||||||
|
```ini
|
||||||
|
ssl = yes
|
||||||
|
ssl_cert = </etc/ssl/certs/dovecot-selfsigned.pem
|
||||||
|
ssl_key = </etc/ssl/private/dovecot-selfsigned.key
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Restart Dovecot:
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart dovecot
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **5. rinetd Errors: Permission Denied**
|
||||||
|
|
||||||
|
### **Cause**:
|
||||||
|
- `rinetd` may not have permissions to forward traffic.
|
||||||
|
|
||||||
|
### **Solution**:
|
||||||
|
1. Ensure `rinetd.conf` is properly configured:
|
||||||
|
```plaintext
|
||||||
|
0.0.0.0 587 10.0.0.2 587
|
||||||
|
0.0.0.0 993 10.0.0.2 993
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Restart `rinetd`:
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart rinetd
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Check for SELinux interference:
|
||||||
|
```bash
|
||||||
|
sudo setenforce 0 # Temporarily disable SELinux for testing
|
||||||
|
```
|
||||||
|
|
||||||
|
If this resolves the issue, fix SELinux permanently:
|
||||||
|
```bash
|
||||||
|
sudo chcon -R -t container_file_t /etc/rinetd.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Summary of Error Handling**
|
||||||
|
|
||||||
|
| **Error** | **Cause** | **Solution** |
|
||||||
|
|-----------------------------------------|---------------------------------|-----------------------------------------------|
|
||||||
|
| Required key not available (WireGuard) | Missing/mismatched keys | Regenerate keys and verify configuration. |
|
||||||
|
| inet_interfaces error (Postfix) | WireGuard interface not active | Delay Postfix startup using systemd overrides.|
|
||||||
|
| Data folder permissions error (RainLoop)| Ownership or SELinux restriction| Fix ownership (`chown`) and SELinux labels. |
|
||||||
|
| ssl_cert error (Dovecot) | Missing SSL certificate | Generate a self-signed SSL certificate. |
|
||||||
|
| rinetd permission denied | SELinux or misconfigurations | Fix permissions and test SELinux compatibility.|
|
||||||
|
|
||||||
Reference in New Issue
Block a user