# Postfix w/ virtual domains & relay to ISP

## gmichels

I set up my mail using the excellent Virtual Mailhosting System with Postfix Guide, along with the Mail Filtering Guide, available at the Gentoo Docs, although I did a few modifications on the Mail Filtering part.

Currently I have two domains set: in one of them I am responsible for the MX record, so everything is done locally on my postfix install. The second domain is the troublesome one. I am not responsible for the MX record for this domain, so I use fetchmail to check for emails regularly on my ISP's pop3 server and have them delivered to my virtual mailboxes on my local postfix install.

My problem is on sending mail for the 2nd domain (everything is fine for the 1st one). On all the clients of the 2nd domain, I am using the ISP's SMTP server directly, but I would like to have them use my local postfix install, then have postfix to relay them to the ISP's SMTP server.

Searching a bit, I found two ways of doing it:

1) change the entry for the domain on the mysql transport table: currently, the entry for the 2nd domain is listed as maildrop:. I am using maildrop to filter mail server side (mainly moving spam to appropriate folders).

2) use relayhost setting on main.cf: according to the comments on main.cf, this entry will only be used if there are no matching entries on the transport table, which is not the case.

A more "visible" version of what I want. Here's the current scenario:

1st domain:

Client -> Postfix -> Internet

2nd domain:

Client -> ISP SMTP Server -> Internet

And here's what I need to do:

1st domain (doesn't change anything):

Client -> Postfix -> Internet

2nd domain:

Client -> Postfix -> ISP SMTP Server -> Internet

I am very new to postfix (first install), so I really don't know what to do to accomplish what I need. If anyone have any ideas, I would be happy to hear them. Also, I don't want to post unecessary lengthy config files, so if any configuration options are needed to help, please ask.

Thanks!

----------

## badchien

I use postfix, and I've come across this in the documentation:

http://www.postfix.org/postconf.5.html#sender_dependent_relayhost_maps

This sounds like the feature you are looking for, but I've never used it, so I can't offer much help with it. Hopefully you can research it and figure it out.

Good luck.

----------

## gmichels

Hi badchien,

Thanks for the suggestion, it does looks like what I need. However that feature is available only on postfix 2.3, which is still in experimental state and not yet on portage. I'll look into that in the future, if there are no other options.

----------

## badchien

I hadn't noticed that  :Sad:  Bad luck.

It looks like 2.3 has been in development for some time. Hopefully a release is near.

----------

## magic919

Set up a dedicated transport for the second domain and use the ISPs SMTP as the destination.

----------

## gmichels

 *magic919 wrote:*   

> Set up a dedicated transport for the second domain and use the ISPs SMTP as the destination.

 

Thanks for the reply, but won't I lose the maildrop filtering if I change the maildrop: entry on the transport table to smtp:smtp.myisp.com?

----------

## magic919

I was more thinking of you using the dedicated transport for the outgoing stuff.  I'd not do it in such a way that you lose your maildrop LDA.

----------

## gmichels

 *magic919 wrote:*   

> I was more thinking of you using the dedicated transport for the outgoing stuff.  I'd not do it in such a way that you lose your maildrop LDA.

 

I'm sorry, I'm really new to postfix and although I am searching for an hour, I can't find a way to use a dedicated transport for only the outgoing mail.

Currently, my setup includes using amavisd-new to scan for viruses and do spam filtering, so my main postfix instance listening on port 25 relays all mail to amavisd-new on port 10024 (thru content_filter), which then, after processing, injects the mail back to postfix at port 10025 (thru entry on master.cf), which then sends the mail to its appropriate destination, virtual mailbox (lookup domain at the transport table -> maildrop:) or internet, regardless it's an incoming or outgoing email.

How can I use a dedicated transport only for the outgoing messages?

----------

## magic919

No probs.

It comes down to where you want to do the work, really.  On the server side the simplest thing to implement is another Postfix instance listening on a fresh port.  You have one on 25 and one on 10025 now.  This instance would relay mail on to the ISP.  Clients would need to aim for this non-standard port.  You'd define this in master.cf, but leave off the content_filter as it's outgoing.  If you have the luxury of additional interfaces you could use the standard port 25 on another interface.

Another option is to using regex or PCRE filter to match against the outgoing email for that domain.  This would be inserted in main.cf  under smtpd_x_restrictions.  It would match the address and the result would be smtp:smtp.myisp.com .  This is 'filter actions in access tables'.

----------

## badchien

 *magic919 wrote:*   

> On the server side the simplest thing to implement is another Postfix instance ... If you have the luxury of additional interfaces you could use the standard port 25 on another interface

 Not a bad idea. Presumably you could make it even easier and just alias an additional IP to the existing NIC. 

I just set up two instances of postfix in this way on my gentoo server to see how it would work. (it works well!  :Smile: )

This is what I did: 

NOTE: I used the name "postfix2" for my 2nd instance of postfix, but in retrospect this may have been a bad choice because it looks like a version number, ala apache2. Using a name like "postfix-inst2" in place of "postfix2" might be less likely to cause problems or confusion in the future.

1 ) add ip alias to eth0 in /etc/conf.d/net and restart interface

```
alias_eth0="192.168.10.11"

/etc/init.d/net.eth0 restart
```

2 ) copy postfix config, init script, spool dir (might want to stop postfix first)

```
cp -a /etc/postfix /etc/postfix2

cp -a /etc/init.d/postfix /etc/init.d/postfix2

cp -a /var/spool/postfix /var/spool/postfix2
```

3 ) edit /etc/init.d/postfix2 init script as follows 

```
depend() {

  use logger dns ypbind amavisd mysql postgresql antivirus postfix_greylist net

  provide mta2

}

start() {

  ebegin "Starting postfix"

  /usr/sbin/postfix -c /etc/postfix2 start &>/dev/null

  eend $?

}

stop() {

  ebegin "Stopping postfix"

  /usr/sbin/postfix -c /etc/postfix2 stop &>/dev/null

  eend $?

}

reload() {

  ebegin "Reloading postfix"

  /usr/sbin/postfix -c /etc/postfix2 reload &>/dev/null

  eend $?

}
```

4 ) Edit /etc/postfix/main.cf inet_interfaces option:

```
inet_interfaces = $myhostname, localhost
```

5 ) Edit /etc/postfix2/main.cf inet_interfaces and queue dir options, etc:

```
inet_interfaces = example.virtual.domain.name

queue_directory = /var/spool/postfix2

myhostname = blah.blah

mydestination = $myhostname, localhost.$mydomain, $mydomain, virtual.domain.if.applicable

relayhost = different.from.primary.postfix.instance

```

6 ) Edit /etc/postfix/master.cf:

```
# ==========================================================================

# service type  private unpriv  chroot  wakeup  maxproc command + args

#               (yes)   (yes)   (yes)   (never) (100)

# ==========================================================================

192.168.10.10:smtp      inet  n       -       n       -       -       smtpd

```

7 ) Edit /etc/postfix2/master.cf:

```
# ==========================================================================

# service type  private unpriv  chroot  wakeup  maxproc command + args

#               (yes)   (yes)   (yes)   (never) (100)

# ==========================================================================

192.168.10.11:smtp      inet  n       -       n       -       -       smtpd
```

8 ) Stop primary postfix (if you haven't already) and start the two concurrent postfix instances.

```
/etc/init.d/postfix stop

etc/init.d/postfix start

etc/init.d/postfix2 start
```

9 ) If everything works, make postfix2 start at boot

```
rc-update add postfix2 default
```

----------

## magic919

You could slim that down and just add the 

```
# ==========================================================================

# service type  private unpriv  chroot  wakeup  maxproc command + args

#               (yes)   (yes)   (yes)   (never) (100)

# ==========================================================================

192.168.10.10:smtp      inet  n       -       n       -       -       smtpd 

192.168.10.11:smtp      inet  n       -       n       -       -       smtpd

```

second IP to master.cf and the main Postfix instance will run them both.

----------

## badchien

Could you explain that futher please?

I stopped both instances of postfix, edited /etc/postfix/master.cf as you suggested, and then started the primary instance of postfix. Now the primary postfix instance is listening on both IPs and the secondary instance and its configuration is essentially unused.

How does this allow incoming mail on the .11 address to be relayed through a different relayhost than that received on the .10 address?

----------

## magic919

Sure.  You can set up options on a per-listening-instance basis.  So if you wanted teh top one to do content filtering but not the bottom one you 'd make sure no content filter in main.cf and add

   -o content_filter

to top one.  You can set lots of options in this manner.

You can even override global options with

   -o global_option =

and leave it blank.

Hope this makes sense.

----------

## badchien

Ok, I understand that. I'm not as concerned with content filter as the OP. I was curious specifically about relayhost. As far as I can tell you cannot set different relayhost options per listening IP in master.cf. I tried it-- it doesn't work. Are you saying this should somehow work or are we misunderstanding eachother?

----------

## magic919

Okay.  Yes, I'm saying it should somehow work.

I'd opt for the easy route and drop in

  -o smtpd_recipient_restrictions = check_recipient_access pcre:/etc/postfix/use_isp_smtp

with the content of

/etc/postfix/use_isp_smtp

/./     smtp:smtp.example.com

The PCRE matches on anything and so all mail goes to the next hop you insert in use_isp_smtp file.

There may well be another way to do this, of course.  You could have defined it as the content_filter but that just seems plain nasty.

----------

## gmichels

Sorry for the late reply. I chose the pcre way of doing it, like this:

In main.cf, I added smtpd_sender_restrictions = check_sender_access pcre:/etc/postfix/use_isp_smtp. The content of use_isp_smtp is /^From: .*@domain2.com/  smtp:smtp.isp.com. Now everything is as I asked, thanks a lot for your help!

However, I have one extra request. With the above solution, every email sent from and to *@domain2.com is unnecessarily relayed thru the isp smtp server, while it could be simply delivered locally. I tried using if conditions on the pcre tables, like this:

```
if /^From: .*@domain2.com/

if /^To: .*@domain2.com/

/./ smtp:smtp.isp.com

endif

endif
```

But I found out I can't check two different headers at the same time while using if conditions, and this won't work. Is there any way to accomplish this?

----------

## magic919

Generally I have an allow above for the 'local' stuff.  permit_mynetworks is enough on most of mine.  If this doesn't work for you then stack the PCREs.

----------

## gmichels

Hi

First I'd like to thank you for your patience, I am learning a lot from this topic.

To be honest, I didn't understand what you meant on your last post, but I thought of another solution for my situation, which would combine the two suggestions you made previously. I was thinking of creating that outgoing-only postfix instance, then use pcre on the To: field to change the transport method. As everyone on the From: field for this postfix instance would be from my domain, this check on the To: field would be enough.

However I am having troubles trying to make this outgoing-only postfix instance relay mail to the ISP smtp server. Maybe it will be easier if I post my setup:

```
# postconf -n

alias_maps = mysql:/etc/postfix/mysql-aliases.cf

biff = no

broken_sasl_auth_clients = yes

command_directory = /usr/sbin

config_directory = /etc/postfix

content_filter = smtp-amavis:[127.0.0.1]:10024

daemon_directory = /usr/lib/postfix

debug_peer_level = 2

default_destination_concurrency_limit = 10

disable_vrfy_command = yes

empty_address_recipient = MAILER-DAEMON

home_mailbox = .maildir/

html_directory = /usr/share/doc/postfix-2.2.5/html

inet_interfaces = all

local_destination_concurrency_limit = 2

local_recipient_maps = $alias_maps $virtual_mailbox_maps unix:passwd.byname

local_transport = local

mail_owner = postfix

mailq_path = /usr/bin/mailq

manpage_directory = /usr/share/man

mydestination = $myhostname

myhostname = mail.domain

mynetworks = 192.168.0.0/24 127.0.0.0/8

newaliases_path = /usr/bin/newaliases

queue_directory = /var/spool/postfix

queue_minfree = 120000000

readme_directory = /usr/share/doc/postfix-2.2.5/readme

relocated_maps = mysql:/etc/postfix/mysql-relocated.cf

sample_directory = /etc/postfix

sendmail_path = /usr/sbin/sendmail

setgid_group = postdrop

smtp_tls_note_starttls_offer = yes

smtpd_data_restrictions = reject_unauth_pipelining

smtpd_etrn_restrictions = reject

smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination

smtpd_sasl_auth_enable = yes

smtpd_sasl_local_domain = $myhostname

smtpd_sasl_security_options = noanonymous

smtpd_tls_CAfile = /etc/postfix/cacert.pem

smtpd_tls_cert_file = /etc/postfix/newcert.pem

smtpd_tls_key_file = /etc/postfix/newreq.pem

smtpd_tls_loglevel = 3

smtpd_tls_received_header = yes

smtpd_tls_session_cache_timeout = 3600s

smtpd_use_tls = yes

tls_random_source = dev:/dev/urandom

transport_maps = mysql:/etc/postfix/mysql-transport.cf

unknown_local_recipient_reject_code = 550

virtual_alias_maps = mysql:/etc/postfix/mysql-virtual.cf

virtual_gid_maps = static:1006

virtual_mailbox_base = /

virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-domains.cf

virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-maps.cf

virtual_minimum_uid = 1000

virtual_transport = $transport_maps

virtual_uid_maps = static:1006
```

Now the relevant part of master.cf:

```
2025      inet  n       -       n       -       -       smtpd

        -o content_filter=

        -o default_transport=smtp:smtp.isp.com

        -o smtp_sasl_auth_enable=yes

        -o smtp_sasl_password_maps=hash:/etc/postfix/saslpass

        -o smtp_sasl_security_options=noanonymous
```

And it won't work, any email I sent on this postfix instance is delivered directly to the destination, as if the nexthop was empty. I also tried the options:

- virtual_transport=smtp:smtp.isp.com

- transport_maps=mysql:/etc/postfix/mysql-transport-relay.cf (on this mysql table, I have setup the correlation domain2.com -> smtp:smtp.isp.com)

None of them worked and now I don't know where the problem could be. If you have any ideas, I would be glad to hear them.

Thanks!

----------

