On 3/14/14, 8:38 AM, Brett Glass wrote:
Everyone:
Two months after this vulnerability was announced, we're still
seeing attempts to use the NTP "monitor" query to execute and
amplify DDoS attacks. Unfortunately, FreeBSD, in its default
configuration, will amplify the attacks if not patched and will
still relay them (by sending "rejection" packets), obfuscating the
source of the attack, if the system is patched using freebsd-update
but the default ntp.conf file is not changed.
To avoid this, it's necessary to change /etc/ntp.conf to include the
following lines:
# Stop amplification attacks via NTP servers
disable monitor
restrict default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict 127.127.1.0
# Note: Comment out these lines on machines without IPv6
restrict -6 default kod nomodify notrap nopeer noquery
restrict -6 ::1
We've tested this configuration on our servers and it successfully
prevents the latest patches of FreeBSD 9.x and 10.0 from
participating in a DDoS attack, either as a relay or as an amplifier.
the best solution is to add a firewall stateful rule so that the ONLY
port 123 udp packet that gets in is one that is a response to one you
sent out first.
I include for fun my ipfw script. (slightly anonimised.. hope I
didn't break it doing so,
last i checked the average packet only hit about 6 rules in this
set. and interface and local address are only checked once.
it's about as efficient as one can get on an ipfw firewall. beware the
script puts the rules in out of order..
Some of our own systems which were probed prior to the time we
secured them are still receiving a large stream of attack packets,
apparently from a botnet.
yeah me too.. 500 pps up until a few ours ago.. then it stopped
I'd recommend that the lines above be included in the default
/etc/ntp.conf in all future releases, and that all systems that use
the default ntp.conf without modification be patched automatically
via freebsd-update.
it already is.
--Brett Glass
_______________________________________________
freebsd-security@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-security
To unsubscribe, send any mail to
"freebsd-security-unsubscr...@freebsd.org"
#!/bin/sh
IPFW=/sbin/ipfw
SYSCTL=/sbin/sysctl
set -x
#Here is a revised version fo hte firewall rules.
# includes the fib fix and the NAT rules integrated.
# ipfw and sysctl defiend tp "echo" so that the script does nothing.
# run as "sh firewall3.sh |sort -n -k 4 >/tmp/xx" to see the output as
injected.
# rules are not injected in order so for debug output
# the sort is needed to see output in final form.
# Suck in the configuration variables.
if [ -z "${source_rc_confs_defined}" ]; then
if [ -r /etc/defaults/rc.conf ]; then
. /etc/defaults/rc.conf
source_rc_confs
elif [ -r /etc/rc.conf ]; then
. /etc/rc.conf
fi
fi
INCLUDE_COMMENTS="YES"
HAVE_TUNNEL="NO"
# nets of form a.b.c.d/xx from rc.conf
iif=${firewall_simple_iif}
iip=${firewall_simple_inet%%/[0-9]*}
oif=${firewall_simple_oif}
oip=${firewall_simple_onet%%/[0-9]*}
DEFAULT_SET=0
APP_SET=1
APP_BLOCK_SET=2
NAT_SET=3
${IPFW} disable firewall
sleep 1
${IPFW} -q -f flush
# For each interface set up 4 sets of rules
#
# rules incoming to that interface to us
# rules incoming to that interface not for us (for routing)
# rules outgoing on that interface from us
# rules outgoing on that interface not from us
#
# Allow 200 numbers for each rule set and 1000 for each interface
OUR_INCOMING=0
OUR_OUTGOING=0
OTHER_INCOMING=0
OTHER_OUTGOING=0
NEXTRULE=0
#decide how many number between rules and keep the kernel in sync with this
RULESKIP=2
${SYSCTL} net.inet.ip.fw.autoinc_step=$RULESKIP
# Make sure that pipes and NAT return to processing at the next rule number
${SYSCTL} net.inet.ip.fw.one_pass=0
#################################################################
#################################################################
# special values to set up pre-processing for a NAT'd tunnel
# e.g. from home to office. not fully set up yet... ignore
#################################################################
#################################################################
TUN_REMOTE=10.0.1.2
VPN_SRC=18.0.0.1
VPN_NET=18.0.0.0/24
TUN=tun0
##############################################################
# N.B. port lists must contain 30 elements or less.
# These are for SESSIONS. stateful behaviour is expected
# to keep these sessions alive.
# We may have to tune dynamic timeouts
##############################################################
# Expected services handled, (inwards): #
# == udp ==
UDP_INPORTS_SYS=53 # We will serve dns so we need this
# === tcp ===
# TCP ports we enable as soon as possible
#-----------------------------------------------------
TCP_INPORTS_SYS=1234 # admin ssh
$IPFW table add 2 $SECONDARY1 # dns secondary
$IPFW table add 2 $SECONDARY2
${IPFW} table add 13 10.0.0.0/8
${IPFW} table add 13 172.16.0.0/12j
${IPFW} table add 13 192.168.0.0/16
${IPFW} table add 13 0.0.0.0/8
${IPFW} table add 13 169.254.0.0/16
${IPFW} table add 13 192.0.2.0/24
${IPFW} table add 13 224.0.0.0/4
${IPFW} table add 13 240.0.0.0/4
TCP_DNS_ZONE=53 # DNS ZONES to secondaries
# TCP ports we only enable when we turn on client services
#-----------------------------------------------------
TCP_INPORTS_APP=25 # Mail inwards
TCP_INPORTS_APP=$TCP_INPORTS_APP,993
TCP_INPORTS_APP=$TCP_INPORTS_APP,995
TCP_INPORTS_APP=$TCP_INPORTS_APP,597
TCP_INPORTS_APP=$TCP_INPORTS_APP,514
TCP_INPORTS_APP=$TCP_INPORTS_APP,80
TCP_INPORTS_APP=$TCP_INPORTS_APP,443
##############################################################
# Known remote services we use are:
# We initiate these sessions..
# ======= udp =======
UDP_REMPORTS_SYS=53 # DNS 53
UDP_REMPORTS_SYS=$UDP_REMPORTS_SYS,67 # DHCP 67
UDP_REMPORTS_SYS=$UDP_REMPORTS_SYS,123 # NTP 123
# ======= tcp =======
TCP_REMPORTS_SYS=53 # DNS 53 .. actually I probably don't need this
#-------------------------------------------------------
TCP_REMPORTS_BACKUP=22 # ports used out the internal interface.
# Machine does not route. just has 2 interfaces.
# ===== ICMP =======
##############################################################
# add $NEXTRULE set {setnumber} {rule}
writerule () {
SET=$1
shift
${IPFW} -q add $NEXTRULE set $SET $@
NEXTRULE=$(($NEXTRULE + $RULESKIP))
}
# skipto {setnumber} {rules-to-skip} rulebody
skipcount () {
SET=$1
shift
SKIPDIST=$(($RULESKIP * $1))
shift
${IPFW} -q add $NEXTRULE set $SET skipto $(($NEXTRULE + $SKIPDIST )) $@
NEXTRULE=$(($NEXTRULE + $RULESKIP))
}
if [ "$INCLUDE_COMMENTS" = "YES" ]
then
# set {setnumber} // {commnet}
writecomment () {
SET=$1
shift
${IPFW} -q add $NEXTRULE set $SET "//" $@
NEXTRULE=$(($NEXTRULE + $RULESKIP))
}
else
writecomment() {
}
fi
# writefilter baserule ifname
# sets up a filter set as:
# YY00 skipto X000 inward
# YY10 skipto X500 outward
#
# and then adds the base filter sections further down.
# you should set up one of these per interface.
#
# [...]
# X000 skipto X200 to us
# [...] # routed packet rules go here
# X200
# [...] # rules for our packets go here
# X500 skipto X700 from us
# [...] # routed packet rules go here
# X700
# [...] # rules for our packets go here
#
# Leaves OUR_INCOMING OUR_OUTGOING OTHER_INCOMING OTHER_OUTGOING
# set up to where more rules should go to
writefilter () {
# rule number, interface name, interface address
# Write an interface filter in the filters section
# splitting into two sectins (in and out)
local TARGET_RULE=$1
local IFACE=$2
local IPADDR=$3
local INCOMING=${TARGET_RULE}
local OUTGOING=$(( ${TARGET_RULE} + 500 ))
if [ ${IFACE} = "lo0" ] # Optimise for lo0
then
writecomment ${DEFAULT_SET} "filter out packets on ${IFACE}"
writerule ${DEFAULT_SET} skipto ${INCOMING} ip from any to any in recv
${IFACE}
writerule ${DEFAULT_SET} skipto ${OUTGOING} ip from any to any out xmit
${IFACE}
#just have two simple sections this is already probably too much
OUR_INCOMING=${INCOMING}
OUR_OUTGOING=${OUTGOING}
else
NEXTRULE=${NEXTFILTER}
writecomment ${DEFAULT_SET} "filter out packets on ${IFACE}"
writerule ${DEFAULT_SET} skipto ${INCOMING} ip from any to any in recv
${IFACE}
writerule ${DEFAULT_SET} skipto ${OUTGOING} ip from any to any out xmit
${IFACE}
NEXTFILTER=${NEXTRULE}
# then further split those sections into "ours and other"
NEXTRULE=${INCOMING}
OUR_INCOMING=$(( ${INCOMING} + 200 ))
writerule ${DEFAULT_SET} skipto $OUR_INCOMING ip from any to ${IPADDR}
writecomment ${DEFAULT_SET} "packets not addressed to us coming in on
${IFACE}"
OTHER_INCOMING=$NEXTRULE
NEXTRULE=${OUR_INCOMING}
writecomment ${DEFAULT_SET} "packets addressed to US comin in on ${IFACE}"
OUR_INCOMING=$NEXTRULE
NEXTRULE=${OUTGOING}
OUR_OUTGOING=$(( ${OUTGOING} + 200 ))
writerule ${DEFAULT_SET} skipto ${OUR_OUTGOING} ip from ${IPADDR} to any
writecomment ${DEFAULT_SET} "Packets NOT from us, going out on ${IFACE}"
OTHER_OUTGOING=$NEXTRULE
NEXTRULE=$OUR_OUTGOING
writecomment ${DEFAULT_SET} "packets from us, going out ${IFACE}"
OUR_OUTGOING=$NEXTRULE
fi
}
if [ ${HAVE_TUNNEL} = "YES" ]
then
if ${IPFW} nat 123 config if ${iif} log reset same_ports
then
NAT_OP="nat 123"
else
NAT_OP="count" # for testing when we don't have NAT loaded
echo "Need to load NAT kernel module"
echo "adding dummy rules for NAT"
fi
fi
##############################################################
##############################################################
# Special initial rules #
# Leave space at front for manually debugging etc. #
##############################################################
##############################################################
NEXTRULE=400
# should put standard non spoofing rules from rc.firewal here (except better
ones)
NEXTFILTER=1000
##############################################################
##############################################################
# loopback #
# This is optimised a bit. (see above) #
##############################################################
##############################################################
# First for efficiency put Loopback spoofing test in right
# after the lo0 filter. Packets to or from 127.0.0.1 die right here
# if they didn't get sent to lo0 procesing
writefilter 2000 "lo0" "127.0.0.1"
NEXTRULE=${NEXTFILTER}
writerule ${DEFAULT_SET} deny all from 127.0.0.1 to any
writerule ${DEFAULT_SET} deny all from any to 127.0.0.1
NEXTFILTER=$NEXTRULE
NEXTRULE=$OUR_INCOMING
writerule ${DEFAULT_SET} allow all from any to any
NEXTRULE=$OUR_OUTGOING
writerule ${DEFAULT_SET} allow all from any to any
##############################################################
##############################################################
# Interface 0 #
##############################################################
##############################################################
writefilter 3000 ${oif} ${oip}
##############################################################
# INCOMING packets ADDRESSED TO US #
# We should only accept them if we export a known service #
# or they are a response to an outgoing packet of our own. #
##############################################################
NEXTRULE=$OUR_INCOMING
# we will only have dynamic rules for locally connected sessions
# that do not do rate control or NAT, so we can skip these expensive
# operations by utilising this fact.
writerule ${DEFAULT_SET} check-state
writerule ${DEFAULT_SET} reject ip from table\(13\) to any
writerule ${DEFAULT_SET} reject ip from any to table\(13\)
if [ ${HAVE_TUNNEL} = "YES" ]
then
# check incoming packets against known NAT sessions
writecomment ${NAT_SET} "check incoming packets against known NAT sessions
and dispatch them."
writerule ${NAT_SET} ${NAT_OP} ip from any to ${VPN_SRC}
# A NAT'd packet will now look like this: accept it. We're done.
writerule ${NAT_SET} accept ip from any to ${TUN_REMOTE}
# Because we set one_pass to 0, packets that are NOT NAT'd
# will be left untouched and will be for us.
# We need to handle these when they return to us
# along with any that were not sent for NATing.
fi
#================================================================
# set keep-state for these to skip future NAT and pipe calls.
writerule ${DEFAULT_SET} allow tcp from any to any ${TCP_INPORTS_SYS} setup
keep-state
writerule ${DEFAULT_SET} allow udp from any to any ${UDP_INPORTS_SYS} keep-state
writerule ${DEFAULT_SET} allow tcp from table\(2\) to any ${TCP_DNS_ZONE}
keep_state
writerule ${APP_SET} allow tcp from any to any ${TCP_INPORTS_APP} setup
keep-state
writerule ${APP_SET} allow udp from any to any ${UDP_INPORTS_APP} keep-state
# IP fragments for UDP NFS # check the safety of this
writerule ${DEFAULT_SET} allow udp from any to any frag
# ICMP
# there are some one might want to stop
writerule ${DEFAULT_SET} allow icmp from any to any keep-state
# an alternative... (thought we probably want more)
# writerule ${DEFAULT_SET} allow icmp from any to any icmptype 0,8 keep-state
writerule ${DEFAULT_SET} drop ip from any to any
#################################################################
# Incoming packets not for us. #
# There is just no excuse for any incoming packet not for us. #
# Throw it away. hmm only exception.. dhcp broadcast? #
#################################################################
NEXTRULE=$OTHER_INCOMING
writerule ${DEFAULT_SET} drop ip from any to any
#################################################################
# OUTGOING packets FROM US #
# these should either be reponses to incoming service requests #
# or our own service requests going out. Either way, we should #
# let them go and make a rule for the return packet. #
#################################################################
NEXTRULE=$OUR_OUTGOING
writecomment ${DEFAULT_SET} "outgoing packets from sesions we have already
aproved are ok"
writerule ${DEFAULT_SET} check-state
# writecomment ${DEFAULT_SET} "remember any outgoing session we initiate"
# writerule ${DEFAULT_SET} allow tcp from any to any setup keep-state
# This is redundant if we allow the above rule.
writecomment ${DEFAULT_SET} "remeber any outgoing session we allow"
writerule ${DEFAULT_SET} allow tcp from any to any ${TCP_REMPORTS_SYS} setup
keep-state
writerule ${DEFAULT_SET} allow udp from any to any ${UDP_REMPORTS_SYS}
keep-state
# when we turn on, allow already running sessiosn to continue if we know about
them (and send a packet).
writerule ${DEFAULT_SET} allow tcp from any to any established keep-state
writerule ${DEFAULT_SET} allow icmp from any to any keep-state
writerule ${DEFAULT_SET} drop ip from any to any
#################################################################
# Outgoing packets not from us. #
# If it's not from us it must be from the tunnel in which case #
# it is a NAT candidate. If not then throw it away. #
#################################################################
NEXTRULE=$OTHER_OUTGOING
if [ ${HAVE_TUNNEL} = "YES" ]
then
# only NAT packets we need to. Why waste time with others?
writerule ${NAT_SET} ${NAT_OP} all from ${TUN_REMOTE} to any recv ${TUN}
# successfully NAT'd packets will look like this.
writerule ${NAT_SET} accept all from ${VPN_SRC} to any
fi
writerule ${DEFAULT_SET} drop ip from any to any
if [ "$iif" != "$oif" ]
then
##############################################################
##############################################################
# Interface 1 In INLINE mode this goes to the cloud #
##############################################################
##############################################################
writefilter 4000 ${iif} ${iip}
NEXTRULE=$OUR_INCOMING
writerule ${DEFAULT_SET} check-state # Only allow incoming packets on
sessions we initiated.
writerule ${DEFAULT_SET} allow icmp from any to any icmptype 0,3,8 keep-state
writerule ${DEFAULT_SET} deny log ip from any to any
# Packets coming in here that are not for us? drop them.
NEXTRULE=$OTHER_INCOMING
writerule ${DEFAULT_SET} deny log ip from any to any
# packets FROM US going out this interface
NEXTRULE=$OUR_OUTGOING
writerule ${DEFAULT_SET} check-state # may be redundant due to the
"keep-state" in the next rule
writerule ${DEFAULT_SET} allow tcp from any to any ${TCP_REMPORTS_BACKUP}
setup keep-state
writerule ${DEFAULT_SET} deny ip from any to any
# packets NOT FROM US going out this interface,.. there shoudn't be any.
NEXTRULE=$OTHER_OUTGOING
writerule ${DEFAULT_SET} deny log ip from any to any
fi
##############################################################
##############################################################
# Tunnel interface #
##############################################################
##############################################################
if [ ${HAVE_TUNNEL} = "YES" ]
then
writefilter 5000 tun0 me # punt on addr.. we have no idea
NEXTRULE=$OUR_INCOMING
writerule ${DEFAULT_SET} allow ip from any to any
NEXTRULE=$OTHER_INCOMING
writerule ${DEFAULT_SET} allow ip from any to any
NEXTRULE=$OUR_OUTGOING
writerule ${DEFAULT_SET} allow ip from any to any
NEXTRULE=$OTHER_OUTGOING
writerule ${DEFAULT_SET} allow ip from any to any
fi
##############################################################
##############################################################
# Any other interfaces not mentioned #
##############################################################
##############################################################
NEXTRULE=${NEXTFILTER}
writecomment ${DEFAULT_SET} "handle other intefaces"
writerule ${DEFAULT_SET} deny ip from any to any
# post rule stuff
${IPFW} set enable $DEFAULT_SET
${IPFW} set disable $APP_SET
${IPFW} set disable $APP_BLOCK_SET # not written yet
${IPFW} set disable $NAT_SET # nat rules disabled if written. not ready..
${IPFW} enable firewall
# ---- EOF ----
_______________________________________________
freebsd-security@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-security
To unsubscribe, send any mail to "freebsd-security-unsubscr...@freebsd.org"