LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   *BSD (https://www.linuxquestions.org/questions/%2Absd-17/)
-   -   How to block all outgoing port 25 except internal mail server. (https://www.linuxquestions.org/questions/%2Absd-17/how-to-block-all-outgoing-port-25-except-internal-mail-server-874850/)

sattech2000 04-13-2011 03:55 PM

How to block all outgoing port 25 except internal mail server.
 
Our ISP setup and installed an OpenBSD Firewall at the border doing NAT translation. I知 running a linux mailserver internally. It seems about every six months someone brings an infected laptop into the building that starts sending out spam and gets us blacklisted. I知 looking for something that will block all outgoing port 25 except for the mail server. Notification (email or ?) would be a big bonus.

I have been playing around with
pass out quick on $ext_if proto tcp from $emailserver to any port 25 flags S/SA synproxy state
block out on $ext_if proto tcp from any to any port 25
however everytime I run that rule the email server returns "no route to host" when I try to ping outside servers.

I知 fairly new to the OpenBsd world so any suggestions on an overall monitoring or logging that could be setup on the firewall would be great also.
Thank you
Randy


Something like this from the cisco world.
access-list acl_out permit tcp host X.X.X.X any eq 25
access-list acl_out deny tcp any any eq 25
access-list acl_out permit ip any any

tizzef 04-14-2011 08:58 AM

something like
Quote:

iptables -A output-o eth0 sport 25 -j DROP
will certainly do the job

sattech2000 04-14-2011 10:26 AM

Could you give me an explanation of that command? I am fairly new to OpenBSD and Linux/UNIX in general. From my research I have found iptables apply to linux. I am using OpenBSD and not sure where that is implemented.

Thank you
Randy

Gerard Lally 04-14-2011 10:56 AM

Quote:

Originally Posted by sattech2000 (Post 4323769)
Our ISP setup and installed an OpenBSD Firewall at the border doing NAT translation. I’m running a linux mailserver internally. It seems about every six months someone brings an infected laptop into the building that starts sending out spam and gets us blacklisted. I’m looking for something that will block all outgoing port 25 except for the mail server. Notification (email or ?) would be a big bonus.

I have been playing around with
pass out quick on $ext_if proto tcp from $emailserver to any port 25 flags S/SA synproxy state
block out on $ext_if proto tcp from any to any port 25
however everytime I run that rule the email server returns "no route to host" when I try to ping outside servers.

What I would do is block on the internal interface, as follows:
Code:

## macros
int_if = "192.168.1.100/32"
lan = "192.168.1.0/24"
mail_ports = { 25 465 587 }
mail_server = "192.168.1.50/32"

## filtering - block traffic on all interfaces
block log all

## let traffic out on all interfaces
pass out keep state

## block in all traffic on internal interface
## destined for mail ports
block in on $int_if from $lan to any port $mail_ports

## pass in traffic on internal interface from mail server
## destined for mail ports
pass in on $int_if from $mail_server to any port $mail_ports

## pass all other traffic coming in on
## internal interface
pass in on $int_if from $lan to any


sattech2000 04-14-2011 01:31 PM

For some reason I cannot even get the block to work on the $int_if. I can get it to work on the $ext_if I'm just beating my head going in circles trying to figure this out. Attached is my pf.conf
Have any recommendations?



# $OpenBSD: pf.conf,v 1.34 2007/02/24 19:30:59 millert Exp $
#
# See pf.conf(5) and /usr/share/pf for syntax and examples.
# Remember to set net.inet.ip.forwarding=1 and/or net.inet6.ip6.forwarding=1
# in /etc/sysctl.conf if packets are to be forwarded between interfaces.

ext_if="xl0"
int_if="xl1"
emailserver = "x.x.11.1"
spamfirewall = "x.x.11.2"
remoteaccess = "x.x.11.13"
automation = "x.x.11.21"
ftpserver = "x.x.11.29"

email = "{ pop3, imap, imap3, imaps, pop3s }"


#table <spamd-white> persist

set skip on { lo enc0 $int_if }

scrub in

nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
nat on $ext_if from !($ext_if) -> ($ext_if:0)
#rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
rdr pass on $int_if proto tcp from $int_if:network to any port 21 -> \
127.0.0.1 port 8021

#no rdr on $ext_if proto tcp from <spamd-white> to any port smtp
#rdr pass on $ext_if proto tcp from any to any port smtp \
# -> 127.0.0.1 port spamd

rdr on $ext_if proto tcp from any to $ext_if port \
$email -> $emailserver
rdr on $ext_if proto tcp from any to $ext_if port \
587 -> $emailserver port smtp

rdr on $ext_if proto tcp from any to $ext_if port \
smtp -> $spamfirewall
rdr on $ext_if proto tcp from any to $ext_if port \
8080 -> $spamfirewall port 80

rdr on $ext_if proto udp from any to $ext_if port \
500 -> $automation
rdr on $ext_if proto tcp from any to $ext_if port \
1723 -> $remoteaccess
rdr on $ext_if proto tcp from any to $ext_if port \
1792 -> $remoteaccess
rdr on $ext_if proto udp from any to $ext_if port \
1701 -> $remoteaccess

rdr on $ext_if proto udp from any to $ext_if port \
6502 -> $automation

rdr on $ext_if proto tcp from any to $ext_if port \
ftp -> $ftpserver

anchor "ftp-proxy/*"
block in
pass out

pass quick on $int_if no state
antispoof quick for { lo $int_if }

pass in quick inet proto icmp from any to any keep state queue icmp
pass out inet proto icmp from any to any keep state queue icmp

pass in quick on $ext_if inet proto esp from any to $ext_if:0 keep state
pass out quick on $ext_if inet proto esp from $ext_if:0 to any keep state

pass in on $ext_if proto tcp to ($ext_if) port ssh

pass in quick on $ext_if proto udp from any to $ext_if:0 port isakmp
pass out quick on $ext_if proto udp from $ext_if:0 to any port isakmp

pass in on $ext_if proto tcp from any to $emailserver port $email \
flags S/SA synproxy state
pass in on $ext_if proto tcp from any to $emailserver port 587 \
flags S/SA synproxy state
pass in on $ext_if proto tcp from any to $emailserver port smtp \
flags S/SA synproxy state

pass in on $ext_if proto tcp from any to $spamfirewall port smtp \
flags S/SA synproxy state
pass in on $ext_if proto tcp from any to $spamfirewall port http \
flags S/SA synproxy state

pass in on $ext_if proto tcp from any to $remoteaccess port 1723 \
flags S/SA synproxy state
pass in on $ext_if proto udp from any to $remoteaccess port 1701 \
keep state
pass in on $ext_if proto tcp from any to $remoteaccess port 1792 \
flags S/SA synproxy state

# VPN GRE PROTOCALL
pass in proto gre all keep state
pass out proto gre all keep state
#
pass in on $ext_if proto udp from any to $remoteaccess port 500 \
keep state

pass in on $ext_if proto udp from any to $automation port 6502 \
keep state

pass in on $ext_if proto tcp from any to $ftpserver port ftp \
flags S/SA synproxy state

Gerard Lally 04-14-2011 03:41 PM

Quote:

Originally Posted by sattech2000 (Post 4324781)
For some reason I cannot even get the block to work on the $int_if. I can get it to work on the $ext_if I'm just beating my head going in circles trying to figure this out. Attached is my pf.conf
Have any recommendations?



# $OpenBSD: pf.conf,v 1.34 2007/02/24 19:30:59 millert Exp $
#
# See pf.conf(5) and /usr/share/pf for syntax and examples.
# Remember to set net.inet.ip.forwarding=1 and/or net.inet6.ip6.forwarding=1
# in /etc/sysctl.conf if packets are to be forwarded between interfaces.

ext_if="xl0"
int_if="xl1"
emailserver = "x.x.11.1"
spamfirewall = "x.x.11.2"
remoteaccess = "x.x.11.13"
automation = "x.x.11.21"
ftpserver = "x.x.11.29"

email = "{ pop3, imap, imap3, imaps, pop3s }"


#table <spamd-white> persist

set skip on { lo enc0 $int_if }

scrub in

nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
nat on $ext_if from !($ext_if) -> ($ext_if:0)
#rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
rdr pass on $int_if proto tcp from $int_if:network to any port 21 -> \
127.0.0.1 port 8021

#no rdr on $ext_if proto tcp from <spamd-white> to any port smtp
#rdr pass on $ext_if proto tcp from any to any port smtp \
# -> 127.0.0.1 port spamd

rdr on $ext_if proto tcp from any to $ext_if port \
$email -> $emailserver
rdr on $ext_if proto tcp from any to $ext_if port \
587 -> $emailserver port smtp

rdr on $ext_if proto tcp from any to $ext_if port \
smtp -> $spamfirewall
rdr on $ext_if proto tcp from any to $ext_if port \
8080 -> $spamfirewall port 80

rdr on $ext_if proto udp from any to $ext_if port \
500 -> $automation
rdr on $ext_if proto tcp from any to $ext_if port \
1723 -> $remoteaccess
rdr on $ext_if proto tcp from any to $ext_if port \
1792 -> $remoteaccess
rdr on $ext_if proto udp from any to $ext_if port \
1701 -> $remoteaccess

rdr on $ext_if proto udp from any to $ext_if port \
6502 -> $automation

rdr on $ext_if proto tcp from any to $ext_if port \
ftp -> $ftpserver

anchor "ftp-proxy/*"
block in
pass out

pass quick on $int_if no state
antispoof quick for { lo $int_if }

pass in quick inet proto icmp from any to any keep state queue icmp
pass out inet proto icmp from any to any keep state queue icmp

pass in quick on $ext_if inet proto esp from any to $ext_if:0 keep state
pass out quick on $ext_if inet proto esp from $ext_if:0 to any keep state

pass in on $ext_if proto tcp to ($ext_if) port ssh

pass in quick on $ext_if proto udp from any to $ext_if:0 port isakmp
pass out quick on $ext_if proto udp from $ext_if:0 to any port isakmp

pass in on $ext_if proto tcp from any to $emailserver port $email \
flags S/SA synproxy state
pass in on $ext_if proto tcp from any to $emailserver port 587 \
flags S/SA synproxy state
pass in on $ext_if proto tcp from any to $emailserver port smtp \
flags S/SA synproxy state

pass in on $ext_if proto tcp from any to $spamfirewall port smtp \
flags S/SA synproxy state
pass in on $ext_if proto tcp from any to $spamfirewall port http \
flags S/SA synproxy state

pass in on $ext_if proto tcp from any to $remoteaccess port 1723 \
flags S/SA synproxy state
pass in on $ext_if proto udp from any to $remoteaccess port 1701 \
keep state
pass in on $ext_if proto tcp from any to $remoteaccess port 1792 \
flags S/SA synproxy state

# VPN GRE PROTOCALL
pass in proto gre all keep state
pass out proto gre all keep state
#
pass in on $ext_if proto udp from any to $remoteaccess port 500 \
keep state

pass in on $ext_if proto udp from any to $automation port 6502 \
keep state

pass in on $ext_if proto tcp from any to $ftpserver port ftp \
flags S/SA synproxy state

You can't get block to work on $int_if because you're using a "pass quick" rule which means none of the rules following the "pass quick" rule are applied:

Code:

pass quick on $int_if no state
Rules relating to $int_if after this simply aren't processed.

My advice is remove all "quick" keywords and let pf process your rules top to bottom, last matching rule wins. If I get a chance I'll tidy your ruleset although I'm by no means an expert at this either but it's better for you to go through it yourself first.

sattech2000 04-15-2011 11:16 AM

This is AWSOME! :) Thank you very much. This is exactly how I learn the best. The config I listed is how my ISP set it up. This will be my first change that I’m making to it and I appreciate all your input. I have removed all the quicks for testing and still cannot get the block to work on the int_if I’m scratching my head at the moment.

I should note this firewall is also doing a branch office vpn connection to another office of ours.

Gerard Lally 04-15-2011 03:04 PM

Quote:

Originally Posted by sattech2000 (Post 4325612)
This is AWSOME! :) Thank you very much. This is exactly how I learn the best. The config I listed is how my ISP set it up. This will be my first change that I知 making to it and I appreciate all your input. I have removed all the quicks for testing and still cannot get the block to work on the int_if I知 scratching my head at the moment.

I should note this firewall is also doing a branch office vpn connection to another office of ours.

I've just spotted the reason blocking on $int_if doesn't work: your ISP in their wisdom set up your pf ruleset to skip the internal interface, and enc0 as well, which I suspect is the VPN interface. Skipping on enc0 should be fine (it is a trusted VPN after all) but not on $int_if.

Remove $int_if from your "set skip on ... " rule. Flush your ruleset and restart firewall:

Code:

pfctl -F rules
pfctl -d
pfctl -e

Then your firewall will process rules on the internal interface.

sattech2000 04-15-2011 04:34 PM

Thank you VERY MUCH! I started going through the rules one by one so I had a full understanding of what was going on and caught that. Just wasn't sure how it should be handled. More playing I have to do :)

archtoad6 04-25-2011 09:23 AM

sattech2000,

Welcome to LQ. Hope your time here helps you as much as mine has helped me.

Please put code, command line output, config files, etc. inside [CODE] tags, aka "Code:" blocks.

It will make your posts easier to read, & that will get you more, faster, better answers. -- Help us help you.
BTW, You can edit your post(s) to do this retroactively.

Thank you, & again, welcome.


All times are GMT -5. The time now is 09:59 AM.