# MailServer: Postfix + Amavis und Spamassassin nur ausgehende E-Mails prüfen



## eperdemer (11. November 2010)

Moin,

ich habe einen Mailserver mit Postfix ausgesetzte der zur Filterung Amavis und Spamassassin verwendet als POP/IMAP wird Dovecot verwendet, so wie auch zur Mail verteilung von Postfix und zur SASL Authentifizierung.


Jetzt habe ich folgendes Problem, es werden auch E-Mails die über SMTP zum versenden von den Benutzern eingeliefert werden auf Spam und Viren geprüft, was ja unnötig ist und nur Performance verschlingt.

Ich habe im Internet schon etwas recherchiert und einige "Lösungen" gefunden
- http://www.postfix.org/FILTER_README.html#remote_only
- in verbidung mit remote_only den Port 587 verwenden.

Nur hat das ganze ne schwachstelle, wenn ich vorgehe wie bei postfix.org beschrieben, werden ja nur die E-Mails vom Filter ausgenommen die direkt vom Server versendet werden, bzw. aus dem Netztwerk versendet werden und alle anderren werden geprüft. oder verstehe ich das falsch, beim Testen war das Resultat das die E-Mails die über SMTP eingelifert wurden auch gescannt wurden bzw. nicht angenommen wurden wegen dem "smtpd_client_restrictions=permit_mynetworks,reject"

Der Mailserver steht aber im Internet und der zugriff erfolgt von verschiedenen Netzwerken.

Alternativ habe ich den Port 587 für die Maileinlieferung vom E-Mail Programm verwendet, was auch ganz gut geklappt hat, die Mails wurden nicht gescannt und alle anderren E-Mail die von anderren Servern versendet wurden, wurden durch die Filter geschickt.

Der nachteil ist das alle Benutzer den Port ändern müssen (sind nur rund 200 Stück)
Und theoretisch könnte man doch mit einem Portscanner den Port finden und als Spamversender seine Mails dort einspeisen?

Kennt vielleicht jemand eine Lösung wie man das Filtern der Ausgehenden E-Mails bei Postfix verhindert so das die E-Mails von Clients pber SMTP aus anderren Netzwerken eingelifert werden können, und die Mails die von anderen Servern versendet werden gefiltert werden?

MfG


----------



## Bratkartoffel (11. November 2010)

Hallo,

EMails werden (egal ob von Client oder anderem Mailserver) über den Port 25 versendet, da gibt es keinen Unterschied.
Eine Möglichkeit wäre, hier je nach dem verwendeten Interface zu reagieren.
Beispiel:

```
Internet   <------> (eth0) Mailserver (eth1) <-------> LAN
```

Alles was bei eth0 über den Port 25 reinkommt wird gefiltert, alles über eth1 und Port 25 geht direkt durch.

Eine andere Möglichkeit die ich mir vorstellen könnte, wäre ein Filter über die Quell-EMail-Adresse. Stammt die Email aus dem Netzwerk selber (Domain checken) dann wird sie nicht überprüft.

Gruß
BK


----------



## eperdemer (11. November 2010)

Moin Bratkartoffel,

erstmal danke für deine antwort, vom prinzib her ist das wie mit den mehreren IP Adressen wie es bei Postfix.org beschrieben ist.

http://www.postfix.org/FILTER_README.html#remote_only


> Filtering mail from outside users only
> 
> The easiest approach is to configure ONE Postfix instance with multiple SMTP server IP addresses in master.cf:
> 
> ...



Es werden aber keine E-Mails vom Lan aus versendet, da der Server in einem Rechenzentrum steht, wird nur vom Internet drauf zugegriffen und versendet.


----------



## Bratkartoffel (11. November 2010)

Hi,

du könntest auch ein Script als Filter erstellen. Dieses überprüft die Absenderadresse der Mail wie oben als zweite Möglichkeit beschrieben.
So etwas ähnlich hab ich schon einrichten müssen, nur dass bei uns entschieden wurde ob die EMail eine Ticket-ID bekommt oder nicht. Bei dir wird halt entschieden, ob die Mail durch den Virenscanner soll, oder nicht.

Gruß
BK


----------



## eperdemer (11. November 2010)

Moin,

das wäre ne Idee, nur hat das ganze einen Haken, Spamversenden fälschen gerne mal die Absender, so wird der Empfänger zum Absender und schon würde man eine Tor für solche Spams öffnen.

MfG


----------



## olqs (11. November 2010)

Also ich habs so implementiert:

- Mail Receiver lauscht auf offizieller IP:25. Nimmt von anderen Servern Mails entgegen und leitet die internen Domains mittels virtual_transport an Amavis weiter. smtpd_recipient_restrictions filtern sachen aus wie:
kommt mit "interner domain als absender" und ist nicht authentifiziert
- Amavis läuft auf localhost:10025 checkt auf Viren und Spam und schickt die Mail an den lokalen Postfix weiter
- lokaler SMTP nimmt Mails entgegen und liefert bei interner Maildomain aus
- Wenn lokal weggesendet wird, dann wird per sender_based_routing entschieden über welche Frontend Instanz rausgesendet wird und amavis nicht durchlaufen.

- Wenn man remote über einen externen Absenden will, dann geht das auch nicht über Amavis, da nur die virtual domains zu amavis geschickt werden.
- Lokalen Versand hast du mein nem Server im RZ z.B. wenn du ein Webmail Interface zur Verfügung stellst.

@eperdemer Das lässt sich alles schön abfangen:

```
smtpd_recipient_restrictions =
  # Lokale Netze dürfen 
  permit_mynetworks,
  # Authentifizierte Clients dürfen
  permit_sasl_authenticated,
  # Keine gültige Absender Domain, kein Emailversand
  reject_unknown_sender_domain,
  # Keine vollqualifizierte Absenderadresse 
  reject_non_fqdn_sender,
  # Keine vollqualifizierte Empfängeradresse 
  reject_non_fqdn_recipient,
  # So jetzt mal an den Greylisting Dienst schicken
  check_policy_service inet:127.0.0.1:10030,
  # Absender ist eine "lokale" Mailadresse, dann verweigern
  check_sender_access mysql:/etc/postfix/sql/sender_access.cf,
  # Empfänger ist lokale Email Adresse, dann erlauben
  check_recipient_access mysql:/etc/postfix/sql/recipient_access.cf,
  # Email von unauthentifizieren Clients mit fremder Absender und Empfängeradresse blocken
  reject
```

Gruss
Alex


----------



## eperdemer (11. November 2010)

Moin Alex,

erstmal Danke, funktioniert das ganze auch mit Virtuellen Mailboxen? Die Benutzer existieren nur in den MySQL Datenbanken und haben halt ein Maildir auf der Festplatte.


Bei mir schaut das ganze so aus:

Postfix laucht auf Port 25 übergibt die mail mit "smtpd_proxy_filter = 127.0.0.1:10026" an postprox wo die Spamassassin geladen wird und evtl. die Mail abgewiesen wird, danach geht das ganze zurück an amavis und wieder nach Postfix. Postfix hat als local und virtual_transport = dovecot.

main.cf

```
# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.                                            
#myorigin = /etc/mailname                                      

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no                                               

disable_vrfy_command = yes

# appending .domain is the MUA's job.
append_dot_mydomain = no             

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h                                     

readme_directory = no



# tls config
smtpd_use_tls = yes
#smtp_tls_loglevel = 1
smtp_tls_note_starttls_offer = yes
smtpd_tls_key_file = /etc/postfix/ssl/key
smtpd_tls_cert_file = /etc/postfix/ssl/cert
smtpd_tls_CAfile = /etc/postfix/ssl/ca.crt              
smtpd_tls_session_cache_database = btree:${queue_directory}/smtpd_scache
#smtpd_tls_loglevel = 10                                                
smtpd_tls_received_header = yes                                         
smtpd_tls_session_cache_timeout = 3600s                                 
tls_random_source = dev:/dev/urandom                                    
tls_random_prng_update_period = 3600s                                   

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.                        

myhostname = smtp.***.de
alias_maps = hash:/etc/aliases
#alias_database = hash:/etc/aliases
myorigin = /etc/mailname           
mydestination = smtp.***.de, localhost
relayhost =                           
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
#mailbox_size_limit = 0                                  
recipient_delimiter = +                                  
inet_interfaces = all                                    

#header_checks = regexp:/etc/postfix/header_checks.cf

virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf
virtual_mailbox_base = /var/vmail/                                         
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf 

virtual_create_maildirsize = yes
virtual_mailbox_extended = yes  

virtual_mailbox_limit_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes                                                     
virtual_maildir_limit_message = "The user you are trying to reach is over quota."        
virtual_overquota_bounce = yes                                                           

home_mailbox = /var/vmail/
local_transport = dovecot 
mailbox_command = /usr/lib/dovecot/deliver

virtual_minimum_uid = 104
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_transport = dovecot   
dovecot_destination_recipient_limit = 1

smtpd_sasl_type=dovecot
smtpd_sasl_path=private/auth_dovecot
smtpd_sasl_auth_enable = yes        
#smtpd_sasl_authenticated_header = yes
broken_sasl_auth_clients = yes        
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =                

smtpd_recipient_restrictions = reject_invalid_hostname, reject_unknown_recipient_domain, reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_unlisted_recipient, reject_unknown_sender_domain, reject_unauth_destination, reject_rbl_client multi.uribl.com, reject_rbl_client dsn.rfc-ignorant.org, reject_rbl_client dul.dnsbl.sorbs.net, reject_rbl_client zen.spamhaus.org, reject_rbl_client bl.spamcop.net, reject_rbl_client dnsbl.sorbs.net, reject_rbl_client cbl.abuseat.org, reject_rbl_client ix.dnsbl.manitu.net, reject_rbl_client combined.rbl.msrbl.net, reject_rbl_client rabl.nuclearelephant.com, permit                                                                                                                                         

smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_hostname,  reject_unknown_client, reject_rbl_client zen.spamhaus.org, reject_rbl_client dnsbl.sorbs.net
smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch, permit_sasl_authenticated, reject_unauth_destination, reject_unknown_sender_domain, permit_mynetworks, reject_unknown_address, reject_unknown_sender_domain, reject_non_fqdn_sender
smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_hostname, reject_invalid_hostname, permit
smtpd_data_restrictions = reject_unauth_pipelining

#smtpd_sender_restrictions = reject_sender_login_mismatch
#, reject_unknown_sender_domain
#, reject_non_fqdn_sender

smtpd_recipient_limit = 250

smtpd_delay_reject = yes
smtpd_helo_required = yes
disable_vrfy_command = yes
strict_rfc821_envelopes = yes
invalid_hostname_reject_code = 554
multi_recipient_bounce_reject_code = 554
non_fqdn_reject_code = 554
relay_domains_reject_code = 554
unknown_address_reject_code = 554
unknown_client_reject_code = 554
unknown_hostname_reject_code = 554
unknown_local_recipient_reject_code = 554
unknown_relay_recipient_reject_code = 554
unknown_sender_reject_code = 554
unknown_virtual_alias_reject_code = 554
unknown_virtual_mailbox_reject_code = 554
unverified_recipient_reject_code = 554
unverified_sender_reject_code = 554

virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf

transport_maps = proxy:mysql:/etc/postfix/mysql-virtual_transports.cf

smtpd_sender_login_maps = proxy:mysql:/etc/postfix/mysql-virtual_login.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf

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 $virtual_mailbox_limit_maps $smtpd_sender_login_maps $check_sender_access $check_recipient_access $smtpd_recipient_restrictions

content_filter = amavis:[127.0.0.1]:10024
smtpd_proxy_filter = 127.0.0.1:10026
```

master.cf

```
smtp      inet  n       -       -       -       -       smtpd

dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}

amavis  unix    -       -       -       -       2       smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes

127.0.0.1:10026 inet    n       n       n       -       20      spawn
        user=spamd argv=/usr/local/sbin/postprox -v -c /usr/bin/postprox_spamc_wrapper 127.0.0.1:10027

127.0.0.1:10025 inet    n       -       -       -       -       smtpd
        -o smtpd_authorized_xforward_hosts=127.0.0.0/8
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_client_restrictions=
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o smtpd_data_restrictions=
        -o smtpd_junk_command_limit=100000
        -o smtpd_soft_error_limit=10000
        -o smtpd_error_sleep_time=0
        -o smtpd_proxy_filter=
        -o mynetworks=127.0.0.0/8
        -o strict_rfc821_envelopes=yes
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
        -o smtpd_bind_address=127.0.0.1

127.0.0.1:10027 inet    n       -       -       -       -       smtpd
        -o smtpd_authorized_xforward_hosts=127.0.0.0/8
        -o content_filter=amavis:[127.0.0.1]:10024
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_client_restrictions=
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o smtpd_data_restrictions=
        -o smtpd_junk_command_limit=100000
        -o smtpd_soft_error_limit=10000
        -o smtpd_error_sleep_time=0
        -o smtpd_proxy_filter=
        -o mynetworks=127.0.0.0/8
        -o strict_rfc821_envelopes=yes
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
        -o smtpd_bind_address=127.0.0.1
```

MfG


----------



## olqs (11. November 2010)

Ok dein smtpd_proxy_filter wir in dem Setup immer ziehen, egal ob du von einer internen oder externen Mailaddresse sendest.

Dieser Filter wird grunsätzlich mal ausgeführt bevor der in einer Postfix Queue landet. Also so gibts hier keine Möglichkeit den unter bestimmten Bedingungen zu umgehen.

Dein Content Filter wird selbst auch immer angesprochen. Das liegt einfach an der Art der Konfiguration und ohne ein "bisschen" umbauen der Struktur wirst das nicht schaffen.
EDIT: Du hast nur einen möglichen Weg der Mails durch deinen Server und keine Entscheidung wann wohin.

Ich post dir dafür mal meine Postfix Konfig:
Ich nutze Postfix 2.6 und das multi instance Feature um die Konfigs lesbar zu halten
Die master.cf Konfigs wurden nur ein wenig bereinigt, aber es gibt keine zusätzlichen Einträge da drin darum lass ich die weg.

Mailweg geht von aussen an ne interne Domain:
x.x.x.86:25 -> amavis (127.0.0.1:10024) -> localhost:25 -> cyrus:lmtp

von aussen an ne externe Domain:
x.x.x.86:25 -> ext-domain:25

von localhost an extern, hab grad gemerkt, dass ich sender_based_routing noch nicht aktiviert hab, aber das ist ja nicht so schlimm:
127.0.0.1:25 -> ext-domain:25

von localhost an intern
127.0.0.1:25 -> cyrus:lmtp

/etc/postfix-blubb.net/main.cf von der externen Postfix Instanz:
TLS ist hier nicht aktiviert, aber ist natürlich möglich.

```
# Postfix Config fuer die externe blubb.net Postfix Instanz

myhostname = mail.blubb.net

mynetworks = 127.0.0.0/8,
             192.168.0.0/16,
             x.x.x.86,
             x.x.x.117,
             x.x.x.118,
             x.x.x.119,

inet_interfaces = x.x.x.86

broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes

smtpd_recipient_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unknown_sender_domain,
  reject_non_fqdn_sender,
  reject_non_fqdn_recipient,
  check_policy_service inet:127.0.0.1:10030,
  check_sender_access mysql:/etc/postfix/sql/sender_access.cf,
  check_recipient_access mysql:/etc/postfix/sql/recipient_access.cf,
  reject

virtual_mailbox_domains = mysql:/etc/postfix/sql/mailbox_domains.cf
virtual_transport = smtp:[127.0.0.1]:10024

alias_database =
alias_maps =

queue_directory = /var/spool/postfix-blubb.net
data_directory = /var/lib/postfix-blubb.net
unknown_local_recipient_reject_code = 550
multi_instance_group = external
multi_instance_name = postfix-blubb.net
multi_instance_enable = yes
```


/etc/postfix/main.cf des internen Servers auf localhost:25

```
# Postfix Config für lokale Pickup und Mail Auslieferung

myhostname = localmail.blubb.net

mynetworks = 127.0.0.0/8,
             192.168.0.0/16,
       x.x.x.86,
       x.x.x.117,
       x.x.x.118,
       x.x.x.119

mydestination = $myhostname
myorigin = blubb.net

virtual_alias_maps = mysql:/etc/postfix/sql/forwardings.cf, mysql:/etc/postfix/sql/alias_maps.cf
virtual_mailbox_domains = localhost, mysql:/etc/postfix/sql/mailbox_domains.cf
virtual_transport = lmtp:unix:/var/imap/socket/lmtp

inet_interfaces = localhost
smtpd_banner = $myhostname ESMTP

soft_bounce = yes

alias_database =
alias_maps =

multi_instance_wrapper = ${command_directory}/postmulti -p --
multi_instance_enable = yes
multi_instance_directories = /etc/postfix-blubb.net /etc/postfix-bla.de /etc/postfix-foo.at /etc/postfix-bar.de
readme_directory = /usr/share/doc/postfix-2.6.6/readme
sample_directory = /etc/postfix
sendmail_path = /usr/sbin/sendmail
html_directory = /usr/share/doc/postfix-2.6.6/html
setgid_group = postdrop
command_directory = /usr/sbin
manpage_directory = /usr/share/man
daemon_directory = //usr/lib64/postfix
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
queue_directory = /var/spool/postfix
mail_owner = postfix
data_directory = /var/lib/postfix
```

Die User liegen bei mir auch in ner Mysql Datenbank, nur nutz ich halt cyrus statt dovecot als imap Server.



Gruss
olqs


----------



## eperdemer (11. November 2010)

Wenn ich bei mir in der config den smtpd_proxy_filter und den content_filter rausnehme und virtual_transport = amavis:[127.0.0.1]:10024 (wo amavis sitzt) oder smtp:[127.0.0.1]:10026 (wo postproxy sitzt) eintrage, werden die Emails zwar zugestellt aber es findet kein viren bzw. Spam prüfung statt.

Darf man mal fragen wie deine sender_access.cf und recipient_access.cf aussehen bzw. wie der rückgabe wert aussehen muss? Habe die smtpd_recipient_restrictions von dir übernommen bis auf die check_policy_service.

Bei bei beiden eine Abfrage drinne die prüft ob die die E-Mails Addresse lokal existiert und den ne 1 zurückgibt.

EDIT:
So ich habe mal etwas rum experimentiert wenn ich virtual_trasport änder oder auskommentiere hat das keinen einfluss, wenn ich aber local_transport änder den kommt eine Fehlermeldung bzw. er dreht sich im Kreis mit amavis und endent mit "host 127.0.0.1[127.0.0.1] said: 554 5.4.0 Failed"

EDIT2:
Habe erstmal eine Temporäre lösung gefunden, und zwar ne lösung mit zwei IP Adressen

Eine IP dienst als Externen Maileingang mit Spamfilter und Amavis inkl Auth Schutz usw.
Die Zweite IP dient als Maileingang für die Clients ohne Spamfilter und Amavis aber mit Auth Shutz usw.

Bin damit zwar nicht ganz glücklich aber wer eine besser lösung hat, immer her damit.
Der ansatz von olqs gefällt mir sehr gut nur scheint es nicht mit meinem Postfix zu laufen, oder es hengt an der umsetzung bei mir.

Es läuft ein Postfix 2.5.5 auf nem Debian lenny

MfG


----------



## olqs (12. November 2010)

Hi,

erstmal meine sender_access.cf

```
hosts = 127.0.0.1
user = xxx
password = xxx
dbname = postfixdb
query = select "REJECT"
        from domains d
        where d.name = "%s"
```

Die überprüft die Absenderadresse und liefert REJECT zurück wenn die Absenderdomain in der Liste der internen Domains ist, ansonsten wird nichts zurückgegeben.

Die recipient_access.cf ist ein bisschen umfangreicher:

```
hosts = 127.0.0.1
user = xxx
password = xxx
dbname = postfixdb
query = select "OK"
        from users u
        join addresses a on u.user_id = a.user_id
        join domains d on a.domain_id = d.domain_id
        join aliases al on al.user_id = u.user_id
        join domains dal on al.domain_id = dal.domain_id
        where concat(al.local_part,"@",dal.name) = "%s" or
          ( dal.name = "%d" and al.local_part = "" )
          and a.main = 1
        UNION
        select "OK"
        from forwardings f
        join domains d on f.domain_id = d.domain_id
        where concat(local_part,"@",d.name) = "%s" or
          ( d.name = "%d" and f.local_part = "" )
        UNION
        select "OK"
        from users u
        join addresses a on u.user_id = a.user_id
        join domains d on a.domain_id = d.domain_id
        where concat(u.name,"@",d.name) = "%s"
           and a.main = 1
```
Grundsätzlich wird überprüft, ob der Server für die Empfängeradresse zuständig ist und wenn ja gibt ein OK zurück. Liegt an meinem etwas modularen Datenbankaufbau das das ein bisschen komplizierter ist.

Zum Edit:
wenn du local_transport auskommentierst, dann weiß postfix ja nicht mehr wohin mit den Mail für die Postfächer. Irgendwo muss man ja festlegen wer die bekommt. Bei dir zu dovecot, bei mir per lmtp zu cyrus.

Ich schau mir deine config Mal am Wochenende in Ruhe an und überleg mal.

Zum Edit2:
die multi_instance Parameter und die dazugehörigen Kommandos (postmulti z.b.) gibts erst ab Postfix 2.6


----------

