From owner-freebsd-security@FreeBSD.ORG Sat Mar 15 22:34:38 2014 Return-Path: Delivered-To: freebsd-security@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C40F6C9E for ; Sat, 15 Mar 2014 22:34:38 +0000 (UTC) Received: from vps1.elischer.org (vps1.elischer.org [204.109.63.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 8F628CB7 for ; Sat, 15 Mar 2014 22:34:38 +0000 (UTC) Received: from Julian-MBP3.local ([12.157.112.67]) (authenticated bits=0) by vps1.elischer.org (8.14.8/8.14.8) with ESMTP id s2F30PRD073448 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Fri, 14 Mar 2014 20:00:26 -0700 (PDT) (envelope-from julian@freebsd.org) Message-ID: <5323C244.8050101@freebsd.org> Date: Fri, 14 Mar 2014 20:00:20 -0700 From: Julian Elischer User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: Brett Glass , Fabian Wenk , freebsd-security@freebsd.org Subject: Re: NTP security hole CVE-2013-5211? References: <52CEAD69.6090000@grosbein.net> <81785015-5083-451C-AC0B-4333CE766618@FreeBSD.org> <52CF82C0.9040708@delphij.net> <86d2jud85v.fsf@nine.des.no> <52D7A944.70604@wenks.ch> <201403141700.LAA21140@mail.lariat.net> In-Reply-To: <201403141700.LAA21140@mail.lariat.net> Content-Type: multipart/mixed; boundary="------------010709070803080609010703" X-BeenThere: freebsd-security@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "Security issues \[members-only posting\]" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Mar 2014 22:34:38 -0000 This is a multi-part message in MIME format. --------------010709070803080609010703 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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-unsubscribe@freebsd.org" > --------------010709070803080609010703 Content-Type: text/plain; charset=UTF-8; x-mac-type="0"; x-mac-creator="0"; name="rc.firewall.jre" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="rc.firewall.jre" #!/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 ---- --------------010709070803080609010703--