Postfix: As a smarthost, how can I limit incoming mail to sender domain and sender IP?

I'm running a Postfix+Dovecot service on Centos 7 with a few unrelated virtual domains. This same Postfix server is also set as a smarthost (relay) for IP 192.0.2.2 and 203.0.113.2. Right now, whatever mail IP 192.0.2.2 sends, my Postfix relays forward onto the Internet, as it should. All sender addresses from 192.0.2.2 come from @example.com domain. However, sometimes IP 192.0.2.2 will send spam originating from random sender domains, which my Postfix will relay onto the Internet, blacklisting my IP.

I'd like to configure a restriction on my Postfix so when IP 192.0.2.2 tries to relay mail, the sender domain must be example.com, otherwise my Postfix must reject the mail.

I have identical problem with IP 203.0.113.2 sending from @example.net domain.

I have no control over 192.0.2.2 or 203.0.113.2, so the problem must be solved using my Postfix only.

This is in my main.cf file right now to enable smarthost functionality:

mynetworks = 127.0.0.0/8, 192.0.2.2/32, 203.0.113.2/32

Edit:

Below was anonymized postconf -n output: "inet:127.0.0.1:8891" is OpenDKIM that I use to sign outgoing email from example.org

alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
broken_sasl_auth_clients = yes
command_directory = /usr/sbin
config_directory = /etc/postfix
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
debug_peer_level = 2
debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5
dovecot_destination_recipient_limit = 1
html_directory = no
inet_interfaces = all
inet_protocols = all
mail_owner = postfix
mailbox_size_limit = 51200000
mailq_path = /usr/bin/mailq.postfix
manpage_directory = /usr/share/man
message_size_limit = 51200000
milter_default_action = accept
milter_protocol = 6
mydestination = $myhostname, localhost.$mydomain, localhost
mydomain = example.org
myhostname = mail.example.org
mynetworks = 127.0.0.0/8, 192.0.2.2/32, 203.0.113.2/32
myorigin = $mydomain
newaliases_path = /usr/bin/newaliases.postfix
non_smtpd_milters = inet:127.0.0.1:8891
queue_directory = /var/spool/postfix
readme_directory = /usr/share/doc/postfix-2.10.1/README_FILES
relay_domains = $mydestination, example.com
sample_directory = /usr/share/doc/postfix-2.10.1/samples
sendmail_path = /usr/sbin/sendmail.postfix
setgid_group = postdrop
smtpd_milters = inet:127.0.0.1:8891, unix:/run/spamass-milter/postfix/sock
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/pki/tls/mail.example.org.public.pem
smtpd_tls_key_file = /etc/pki/tls/mail.example.org.private.pem
smtpd_tls_loglevel = 1
smtpd_tls_mandatory_protocols = $smtpd_tls_protocols
smtpd_tls_protocols = !SSLv2, !SSLv3
smtpd_tls_received_header = yes
smtpd_tls_security_level = may
smtpd_tls_session_cache_timeout = 3600s
smtpd_use_tls = yes
tls_random_source = dev:/dev/urandom
transport_maps = hash:/etc/postfix/transport
unknown_local_recipient_reject_code = 550
virtual_alias_maps = hash:/etc/postfix/vmail_aliases
virtual_gid_maps = static:800
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_domains = hash:/etc/postfix/vmail_domains
virtual_mailbox_maps = hash:/etc/postfix/vmail_mailboxes
virtual_minimum_uid = 800
virtual_transport = dovecot
virtual_uid_maps = static:800

Solution 1:

This solution was variant from this solution. But first, we will adjust some configuration.

First: Of course you can use combination of mynetworks and permit_mynetworks to allow client relay. The alternative is using check_client_access parameter. So, please remove both IP addresses (192.0.2.2/32, 203.0.113.2/32) from mynetworks.

Second: We will apply restriction one by one. For initial step, we only limit domain and IP address from IP address 192.0.2.2. We can apply restriction class solution here

main.cf

smtpd_restriction_classes =
   firstclient

firstclient =
  check_sender_access hash:/etc/postfix/firstsender
  reject

smtpd_recipient_restrictions =
   permit_sasl_authenticated
   permit_mynetworks
   check_client_access hash:/etc/postfix/myclient
   reject_unauth_destination

/etc/postfix/myclient

192.0.2.2               firstclient

/etc/postfix/firstsender

example.com     OK

Third: apply the similiar solution for second client, so the setup become

main.cf

smtpd_restriction_classes =
   firstclient, secondclient

firstclient =
  check_sender_access hash:/etc/postfix/firstsender
  reject

secondclient = 
  check_sender_access hash:/etc/postfix/secondsender
  reject

smtpd_recipient_restrictions =
   permit_sasl_authenticated
   permit_mynetworks
   check_client_access hash:/etc/postfix/myclient
   reject_unauth_destination

/etc/postfix/myclient

192.0.2.2               firstclient
203.0.113.2             secondclient 

/etc/postfix/firstsender

example.com     OK

/etc/postfix/secondsender

example.net     OK

FAQ:

Could you explain how above setup works?

The explanation how it works: Postfix restriction classes official docs

This isn't looks scalable. Can you provide me another solution?

Yes, you can use Postfix SMTP Access Policy Delegation

Hmm, postfix policy server looks good to me. But do I have to implement my own script?

You can use any policy server addon like policyd, postfwd and others.