Port 25 works only on some IPs? Configure your VPS to send SMTP from all addresses

Applies to: LumaDock Cloud VPS • Linux (Ubuntu/Debian/RHEL/Alma/Rocky) • Postfix/Exim • IPv4/IPv6

LumaDock does not block port 25. If some of your IPs cannot send email, the cause is almost always local: missing IP bindings, reverse path filtering, firewall rules, or the mail server not binding to the intended source IP. Follow this guide to enable and verify port 25 on all assigned IPs without provider intervention.

Requirements

  • LumaDock VPS with multiple public IPs assigned
  • Root (or sudo) SSH access
  • Installed MTA (Postfix or Exim) if you plan to send mail directly
  • Basic DNS access to manage PTR (rDNS), SPF, DKIM, DMARC

Step 1 — Bring up all IPs on your network interface

Confirm the interface (e.g., eth0 or ens18) has all IPs configured:

ip addr show
ip route

Ubuntu/Debian (Netplan) — example

# /etc/netplan/01-netcfg.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    ETH0:
      dhcp4: no
      addresses:
        - YOUR_IP_1/24
        - YOUR_IP_2/24
        - YOUR_IP_3/24
        - YOUR_IP_4/24
        - YOUR_IP_5/24
      gateway4: YOUR_GW
      nameservers:
        addresses: [1.1.1.1, 8.8.8.8]
# Apply:
netplan apply

Debian (ifupdown) — example

# /etc/network/interfaces
auto ETH0
iface ETH0 inet static
    address YOUR_IP_1
    netmask 255.255.255.0
    gateway YOUR_GW
    dns-nameservers 1.1.1.1 8.8.8.8

# Additional IPs (same subnet)
iface ETH0 inet static
    address YOUR_IP_2
    netmask 255.255.255.0

iface ETH0 inet static
    address YOUR_IP_3
    netmask 255.255.255.0

# Restart:
systemctl restart networking

RHEL/CentOS/Alma/Rocky (network-scripts) — example

# /etc/sysconfig/network-scripts/ifcfg-ETH0
DEVICE=ETH0
ONBOOT=yes
BOOTPROTO=none
IPADDR=YOUR_IP_1
PREFIX=24
GATEWAY=YOUR_GW
DNS1=1.1.1.1
DNS2=8.8.8.8

# Additional IPs (aliases)
# /etc/sysconfig/network-scripts/ifcfg-ETH0:0
DEVICE=ETH0:0
ONBOOT=yes
BOOTPROTO=none
IPADDR=YOUR_IP_2
PREFIX=24

# /etc/sysconfig/network-scripts/ifcfg-ETH0:1
DEVICE=ETH0:1
ONBOOT=yes
BOOTPROTO=none
IPADDR=YOUR_IP_3
PREFIX=24

# Restart:
systemctl restart network

NetworkManager (nmcli) — quick add

nmcli con show
nmcli con mod "System ETH0" +ipv4.addresses YOUR_IP_2/24
nmcli con mod "System ETH0" +ipv4.addresses YOUR_IP_3/24
nmcli con up "System ETH0"

Step 2 — Set reverse path filtering (rp_filter) to loose

Strict rp_filter can silently drop packets when replying from “non-primary” IPs. Use mode 2 (loose):

# Temporary (until reboot)
sysctl -w net.ipv4.conf.all.rp_filter=2
sysctl -w net.ipv4.conf.default.rp_filter=2
sysctl -w net.ipv4.conf.ETH0.rp_filter=2

# Persist in /etc/sysctl.conf
net.ipv4.conf.all.rp_filter=2
net.ipv4.conf.default.rp_filter=2
net.ipv4.conf.ETH0.rp_filter=2

# Apply
sysctl -p

Step 3 — Test outbound port 25 from each IP

Install tools and test connectivity by binding the source IP:

apt-get update && apt-get install -y netcat-openbsd telnet swaks || \
yum install -y nc telnet swaks
# Netcat (choose source IP)
nc -zv -s YOUR_IP_2 smtp.gmail.com 25
nc -zv -s YOUR_IP_3 smtp.gmail.com 25

# swaks (SMTP tester)
swaks --to test@example.com --server smtp.gmail.com --port 25 \
      --interface YOUR_IP_2 --quit-after DATA

If one IP works and another doesn’t: re-check Step 1 (IPs up) and Step 2 (rp_filter), and confirm no local firewall is blocking.

Step 4 — Make sure local firewalls aren’t blocking

  • UFW (Ubuntu)
    ufw status
    ufw allow 25/tcp
  • firewalld (RHEL family)
    firewall-cmd --permanent --add-service=smtp
    firewall-cmd --reload
    firewall-cmd --list-all
  • iptables/nftables — ensure no DROP/MASQUERADE rules interfere with chosen source IPs.

Note: On LumaDock, the provider firewall is off by default. This step is only about your OS firewall.

Step 5 — Bind your mail server (MTA) to specific IPs

By default, MTAs send from the main IP. Bind explicitly so each IP can send on port 25.

Postfix — global bind (simple)

# /etc/postfix/main.cf
smtp_bind_address = YOUR_IP_2
# For IPv6:
# smtp_bind_address6 = YOUR_IPV6_2

systemctl restart postfix

Postfix — per-domain/per-sender (multiple IPs)

# /etc/postfix/master.cf (add transports)
smtp-ip2   unix  -  -  n  -  -  smtp
  -o smtp_bind_address=YOUR_IP_2

smtp-ip3   unix  -  -  n  -  -  smtp
  -o smtp_bind_address=YOUR_IP_3
# /etc/postfix/transport (map domains to transports)
example.com       smtp-ip2:
anotherdomain.com smtp-ip3:

postmap /etc/postfix/transport
postconf -e 'transport_maps = hash:/etc/postfix/transport'
# (Optional) choose by sender instead of domain:
# postconf -e 'sender_dependent_default_transport_maps = hash:/etc/postfix/sender_transport'
systemctl reload postfix

Exim — bind interface(s)

# /etc/exim/exim.conf (transport)
remote_smtp:
  driver = smtp
  interface = YOUR_IP_2

# For multiple IPs, define additional transports (remote_smtp_ip3, etc.)
# and select via routers per domain/sender.
systemctl restart exim || systemctl restart exim4

Step 6 — (Optional) Receive mail on port 25 for all IPs

  • Postfix listen: inet_interfaces = all and inet_protocols = ipv4, ipv6 in /etc/postfix/main.cf
  • Open 25/tcp in your local firewall (see Step 4)
  • Create MX records pointing to hostnames that resolve to your receiving IPs
ss -lntp | grep :25

Step 7 — rDNS, SPF, DKIM, DMARC (deliverability)

  • PTR/rDNS: each sending IP should reverse to a matching hostname (request or set in your panel if available)
  • SPF: publish a TXT record including your sending IPs/hosts
  • DKIM: generate keys and publish TXT records; enable signing in your MTA
  • DMARC: start with p=none, then move to quarantine/reject

Troubleshooting (quick fixes)

  • Only main IP sends: MTA not bound → configure smtp_bind_address (Postfix) or interface (Exim)
  • nc -s IP2 works but emails go from IP1: Use Postfix transports / Exim routers to force source IP per domain/sender
  • “Connection refused” when testing inbound: Ensure MTA is listening on :25 and local firewall allows it
  • One IP fails, others OK: Re-apply Netplan/restart network, set rp_filter=2, check routes
  • SELinux (RHEL): Test with setenforce 0 (temporary) to rule out policy issues
  • IPv6 send: Set smtp_bind_address6 or Exim IPv6 interface and publish AAAA + PTR

Verification checklist

  • ip addr shows all IPs on your interface
  • rp_filter=2 (all/default/interface) in sysctl
  • nc -zv -s IPX smtp.gmail.com 25 succeeds for each IP
  • Postfix/Exim bound to desired IPs; service restarted
  • PTR, SPF, DKIM, DMARC set (and MX if receiving mail)
Was this answer helpful? 0 Users Found This Useful (0 Votes)