Settings of the Proxmox Mail Gateway as SMTP server with SMTP authenication

testOA

New Member
Aug 25, 2025
1
0
1
Hi everyone, I am trying to build a Proxmox Mail Gateway as SMTP server to send notification for external person.
By default, it delivers by 25 and 26 ports. And sometimes reponsed that the emails become spam mail that without SMTP auth.
So I trying to enable the SMTP authenication.

I had read some instruction to do the configuration in the main.cf file of Postfix , creating SASL for SMTP authenication.
Mostly the instruction describe to use the gmail SMTP as the relayhost.
However, I don't want to use the external SMTP server and the gmail accounts.

For example, I created the VM , installed Proxmox Mail Gateway 7.0.6 , running as Debian OS in default.
I assigned the DNS name "pmg.mydomain.com" to it.
And I also allowed all ports for SMTP required.
Is it possible to set the server itself as the SMTP server with the SMTP authenication?


In main.cf:
Code:
relayhost = [pmg.mydomain.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

In sasl_passwd
Code:
[pmg.mydomain.com]:587    SMTP_username:SMTP_password
 
So i also had a strong use case to have the gateway support auth email.

I wanted it so not run on the config of Proxmox Mail Gateway to minimize problems interference ect. so i run the auth option on port 587

This is the changed you need to do for PMG 9.0-1 Install:
/var/lib/pmg/templates/master.cf.in
#----------------------------------------------------------
# Custom Code: Submission Port 587 for SMTP AUTH
#----------------------------------------------------------
587 inet n - - - - smtpd
-o smtpd_tls_cert_file=/etc/pmg/pmg-tls.pem
-o smtpd_tls_key_file=/etc/pmg/pmg-tls.pem
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_auth_only=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=cyrus
-o smtpd_sasl_path=smtpd
-o smtpd_sasl_security_options=noanonymous
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
#----------------------------------------------------------
cat > /etc/sasl2/smtpd.conf <<'EOF'
pwcheck_method: auxprop
auxprop_plugin: sasldb
mech_list: PLAIN LOGIN
sasldb_path: /etc/sasldb2
EOF
#----------------------------------------------------------

#----------------------------------------------------------
apt install sasl2-bin libsasl2-modules
#----------------------------------------------------------
pmgconfig sync --restart 1
systemctl restart postfix
#----------------------------------------------------------

#----------------------------------------------------------
Create Users for Auth.
#----------------------------------------------------------
saslpasswd2 -c -u DOMAIN USERNAME -> this will create a user USERNAME@DOMAIN
Password need to be input here
#----------------------------------------------------------

#----------------------------------------------------------
List Users for Auth.
#----------------------------------------------------------
sasldblistusers2
#----------------------------------------------------------

#----------------------------------------------------------
Remove Users for Auth.
#----------------------------------------------------------
saslpasswd2 -d -u DOMAIN USERNAME
#----------------------------------------------------------
Hope this help anyone took me hours to figure this one out and get it to work.

Pros with this is you can keep config for ports 25 and 26 as is and have a seperate smarthost firewall rule for port 587.

Working nicely for me.
 
Last edited:
  • Like
Reactions: AlexHK
We also implemented Nginx and Fail2ban now for extra security and able to use the portal for when 8006 in not allowed: these are our notes of it:

We run the let encypt option in pmg and use those in the config.

#----------------------------------------------------------
Nginx Website Port 443: (8006):
#----------------------------------------------------------
apt update
apt install nginx
#----------------------------------------------------------
/etc/nginx/sites-available/pmg-quarantine

server {
listen 443 ssl;
server_name _;

# Enable HTTP/2
http2 on;

# Dedicated access log
access_log /var/log/nginx/pmg-access.log;

# PMG certificate (combined cert + key)
ssl_certificate /etc/pmg/pmg-api.pem;
ssl_certificate_key /etc/pmg/pmg-api.pem;
proxy_redirect off;

#######################################
# TLS
#######################################
ssl_protocols TLSv1.2 TLSv1.3;

# TLS 1.2 explicit ciphers
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers on;

# Recommended ECDH curves
ssl_ecdh_curve X25519:secp521r1:secp384r1:secp256r1;

# Session cache
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1h;
ssl_session_tickets off;

# HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# Security headers
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy no-referrer always;

# Allow embedding in iframes from same origin
add_header X-Frame-Options "SAMEORIGIN" always;

proxy_set_header Host $host;
proxy_set_header PVEClientIP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;

# WebSocket support for PMG UI
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

proxy_buffering off;
client_max_body_size 0;
proxy_connect_timeout 3600s;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
send_timeout 3600s;

#######################################
# REVERSE PROXY TO PMG Static Components
#######################################
location ~ /proxmoxlib.js$|/favicon.ico$|/pve2/|/fontawesome/|/framework7|/pwt|/mobile {
proxy_pass https://localhost:8006
}

#######################################
# REVERSE PROXY TO PMG Quarantine
#######################################
location /quarantine {
proxy_pass https://localhost:8006
}

#######################################
# REVERSE PROXY TO PMG API2
#######################################
location /api2 {
location ~ /api2/(extjs|json|htmlmail)/(access/ticket$|version$) {
proxy_pass https://localhost:8006
}
location ~ /api2/(extjs|json|htmlmail)/nodes/.+/subscription$ {
proxy_pass https://localhost:8006
}
location ~ /api2/(extjs|json|htmlmail)/quarantine {
proxy_pass https://localhost:8006
}
return 444;
}

# Block everything else
location / {
return 444;
}
}


#----------------------------------------------------------
rm /etc/nginx/sites-enabled/default
ln -s /etc/nginx/sites-available/pmg /etc/nginx/sites-enabled/

nginx -t
systemctl restart nginx
systemctl reload nginx



#----------------------------------------------------------
Fail2Ban:
#----------------------------------------------------------
apt install fail2ban

systemctl enable fail2ban
systemctl start fail2ban
systemctl status fail2ban

#----------------------------------------------------------
/etc/fail2ban/filter.d/pmg-login.conf
[Definition]
# Match failed login requests to PMG webgui (ticket API)
failregex = ^<HOST> - - \[.*\] "(POST|GET) /api2/(json|extjs)/access/ticket HTTP/[\d.]+" 200 ([5-9][0-9]|100) .*
ignoreregex =

/etc/fail2ban/jail.d/pmg-login.local
[pmg-login]
enabled = true
filter = pmg-login
action = nftables-multiport[name=PMGLogin, port=443, protocol=tcp]
logpath = /var/log/nginx/pmg-access.log
maxretry = 5
findtime = 600
bantime = 3600

/etc/fail2ban/jail.d/postfix-submission.local
[postfix-submission-auth]
enabled = true
filter = postfix[mode=auth]
action = nftables-multiport[name=PostfixSubmissionAuth, port="587", protocol=tcp]
logpath = /var/log/mail.log
maxretry = 5
findtime = 600 ; 10 minutes
bantime = 3600 ; 1 hour

/etc/fail2ban/jail.d/recidive.local
[DEFAULT]
ignoreip = 127.0.0.1/8 10.0.0.0/8
bantime = 3600
findtime = 600
maxretry = 5
backend = auto
 
Last edited: