haproxy in HTTP mode can add the necessary X-Forwarded-For header and backends like Apache can use the mod_remoteip.so module with the RemoteIPHeader parameter to handle the new header.
haproxy in TCP mode can't do that[1], thus haproxy has written a "proxy protocol v2"[2] that does that, but requires a custom implementation for the backend[3]. I believe postfix supports this since 2.10 ! (but I've never used it) postscreen_upstream_proxy_protocol = haproxy [1] https://www.haproxy.com/documentation/hapee/latest/load-balancing/client-ip-preservation/enable-proxy-protocol/ [2] https://www.haproxy.com/blog/using-haproxy-with-the-proxy-protocol-to-better-secure-your-database/ [3] https://www.haproxy.com/blog/efficient-smtp-relay-infrastructure-with-postfix-and-load-balancers/ On Wed, 21 Dec 2022 12:39:30 +0400 Samer Afach <samer.af...@msn.com> wrote: > Thank you. You and Pat actually may be onto something. I grepped the whole > logs for "connect from", and all the "connect from" and "disconnect from" > statements seem to be coming from 172.30.0.1, which, if I understand > correctly, is the NAT bridge address of docker, i.e., the subnet router > address. > > > What is the correct solution in this case, based on my configuration? Please > advise. I understand I have to make "mynetworks" just localhost, but specific > recommendation based on my configuration would be highly appreciated. > > > Best regards, > > Sam > > > > On 21/12/2022 11:51 AM, mailm...@ionos.gr wrote: > > > The most common issue when using a proxy/load balancer like haproxy, is > > that the remote/foreign connections are being forwarded with the IP address > > of the haproxy machine. Thus, they all appear as "local", which makes > > postfix think they are "mynetworks" and as a result, postfix becomes a open > > relay. > > > > So check your logs, to make sure remote/foreign connections don't appear as > > 172.30.0.0/16 in postfix. If they do, then that is the problem. > > > > > > > > On Wed, 21 Dec 2022 11:35:13 +0400 Samer Afach <samer.af...@msn.com> wrote: > > > > Dear Pat: > >> > >> Thank you for throwing this idea, because I really thought it wasn't > >> possible to retrieve docker logs without setup, but I dug and found the > >> logs. I have them all. Unfortunately, I can't share them all because > >> they're like GBs in size. Just the grep on that email address is like > >> 750 MB in size. > >> > >> I cut a snippet of the relevant part (where I see the spam address), and > >> put it in pastebin. I hope that's allowed in the rules of the list. > >> > >> https://pastebin.com/PEir7mDc > >> > >> (all from postfix, nothing from dovecot, btw). > >> > >> I minimally redacted the logs: > >> > >> - The domains example.com and example.org belong to me, seems like both > >> were involved in this attack. > >> - My public IP address was replaced with 123.456.789.123 > >> > >> Please note that 172.30.0.0/16 is the docker-compose subnet for all > >> dockerized email applications. It was created automatically by > >> docker-compose. > >> > >> If you need any additional information or additional logs, please let me > >> know. > >> > >> Best regards, > >> Sam > >> > >> > >> On 21/12/2022 10:31 AM, Patrick Proniewski wrote: > >> Hello, > >>> > >>> Do you have the logs (postfix and maybe dovecot) showing the spammer > >>> interaction with the server? > >>> > >>> pat > >>> > >>> On 21 Dec 2022, at 05:45, Samer Afach <samer.af...@msn.com> wrote: > >>>> > >>>> Thank you, Phil. Here we go. Here's postconf -n: > >>>> > >>>> > >>>> I hope this helps in better identifying how the spammer was able to use > >>>> my server to send a spam email. > >>>> > >>>> > >>>> ``` > >>>> > >>>> alias_database = hash:/etc/aliases > >>>> alias_maps = hash:/etc/aliases > >>>> append_dot_mydomain = no > >>>> biff = no > >>>> broken_sasl_auth_clients = yes > >>>> debug_peer_level = 6 > >>>> debug_peer_list = 0.0.0.0/0 > >>>> disable_vrfy_command = yes > >>>> inet_interfaces = all > >>>> inet_protocols = ipv4 > >>>> mailbox_size_limit = 0 > >>>> maillog_file = /dev/stdout > >>>> message_size_limit = 0 > >>>> milter_default_action = accept > >>>> milter_protocol = 2 > >>>> mydestination = hostname.hosting-service.com, > >>>> localhost.hosting-service.com, localhost > >>>> myhostname = localhost > >>>> mynetworks_style = subnet > >>>> myorigin = localhost > >>>> non_smtpd_milters = inet:docker-email-opendkim:12301 > >>>> proxy_read_maps = $local_recipient_maps $mydestination > >>>> $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps > >>>> $virtual_mailbox_domains $relay_recipient_maps $relay_domains > >>>> $canonical_maps $sender_canonical_maps $recipient_canonical_maps > >>>> $relocated_maps $transport_maps $mynetworks $smtpd_sender_login_maps > >>>> readme_directory = no > >>>> recipient_delimiter = + > >>>> relay_domains = > >>>> relayhost = > >>>> smtp_tls_cert_file = /shared-keys/example.com/fullchain.pem > >>>> smtp_tls_key_file = /shared-keys/example.com/privkey.pem > >>>> smtp_tls_loglevel = 1 > >>>> smtp_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1 > >>>> smtp_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1 > >>>> smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache > >>>> smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) > >>>> smtpd_client_restrictions = permit_mynetworks > >>>> smtpd_helo_restrictions = reject_invalid_helo_hostname, > >>>> smtpd_milters = inet:docker-email-opendkim:12301 > >>>> smtpd_recipient_restrictions = check_sender_access > >>>> hash:/etc/postfix/sender_access, permit_sasl_authenticated, > >>>> permit_mynetworks, reject_unauth_destination, reject_invalid_hostname, > >>>> reject_unknown_recipient_domain, reject_unauth_destination, > >>>> reject_rbl_client sbl.spamhaus.org, reject_rbl_client > >>>> b.barracudacentral.org, reject_rbl_client zen.spamhaus.org, > >>>> reject_rbl_client truncate.gbudb.net, reject_rbl_client bl.spamcop.net, > >>>> reject_rbl_client cbl.abuseat.org, > >>>> smtpd_relay_restrictions = permit_sasl_authenticated permit_mynetworks > >>>> reject_unauth_destination > >>>> smtpd_sasl_auth_enable = yes > >>>> smtpd_sasl_authenticated_header = yes > >>>> smtpd_sasl_path = /shared-socks/auth_dovecot > >>>> smtpd_sasl_type = dovecot > >>>> smtpd_sender_login_maps = > >>>> proxy:mysql:/etc/postfix/mysql_sender_login_maps.cf > >>>> smtpd_tls_auth_only = yes > >>>> smtpd_tls_cert_file = /shared-keys/example.com/fullchain.pem > >>>> smtpd_tls_ciphers = high > >>>> smtpd_tls_key_file = /shared-keys/example.com/privkey.pem > >>>> smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1 > >>>> smtpd_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1 > >>>> smtpd_tls_security_level = may > >>>> smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache > >>>> smtpd_use_tls = yes > >>>> virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf > >>>> virtual_gid_maps = static:5000 > >>>> virtual_mailbox_base = /var/vmail/ > >>>> virtual_mailbox_domains = > >>>> proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf > >>>> virtual_mailbox_limit = 0 > >>>> virtual_mailbox_maps = > >>>> proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf > >>>> virtual_minimum_uid = 104 > >>>> virtual_transport = lmtp:inet:docker-email-dovecot:10024 > >>>> virtual_uid_maps = static:5000 > >>>> > >>>> ``` > >>>> > >>>> > >>>> Best regards, > >>>> > >>>> Sam > >>>> > >>>> > >>>> On 21/12/2022 8:35 AM, Phil Stracchino wrote: > >>>> On 12/20/22 21:39, Samer Afach wrote: > >>>>> I could share postconf too, but it's huge and I don't want to make this > >>>>>> a huge burden unless necessary. > >>>>>> 'postconf -n' is much more concise. Try it. > >>>>> > >>>>> > >>>>>