Protecting against RADIUS vulnerabilities

(Using built-in kernel firewall rulesets)

DISCLAIMER

  I take NO responsibility for anything that you break on your
  system!  You may use this information fully at your own risk.  If
  the idea of modifying kernel IP rulesets rightfully scares the life
  out of you, then you might consider bailing at this point.  I have
  purposely used permit-all (rather than implicit deny) filters so 
  that the likelihood of locking oneself out of a machine is minimal,
  but if it happens due to error on your part, don't say I didn't warn 
  you.

SYNOPSIS

  Recent vulnerabilities in the RADIUS protocol have left many people 
  scrambling for patches and fixes.  The simple fact is that this is a
  difficult vulnerability to exploit, and quite easy to diffuse using
  pretty ordinary network security.  The methods described here to 
  protect your RADIUS daemon will hopefully lead you into the natural
  progression of securing your other network services, particularly
  sshd and your RPC services.

  These instructions are NOT all-encompassing, and will assume that 
  you are somewhat of an astute admin already, and know your way around
  your OS, how to install software, build a kernel, etc.  I simply don't
  have enough hours in my day to elaborate on every detail, so unless
  you have a problem explicitly related to the information contained on
  this page, I'm probably not going to be able to help you out via email.

REQUIRED PACKAGES

  Solaris 2.8 (64bit):
- ipfilter (ipf-3.4.20-Sol8-sparc-64bit.pkg.gz)
- If you are running 32-bit or an earlier version of Solaris, you should
  go here and get the source or here for some binary packages.

  Linux:
- iptables|ipchains|ipfwadm (included with OS)

  FreeBSD:
- ipfilter (included with OS)
- ipfw (included with OS)

PREPARATION

  Solaris (binary package):
  - Install ipf ('pkgadd -d ipf-3.4.20-Sol8-sparc-64bit.pkg')
  - There are 2 packages - install the 2nd listed one first
  - The package installation will automatically enable ipfilter but
    you may need to start up the monitor manually ('ipmon -Ds')
  - The installation will automatically add ipf to system startup scripts

  FreeBSD:
  - NOTE:  These directions (added 06/20/02) have been contributed by Ted 
    Mittelstaedt and should be considered preferable to the ipf directions 
    below unless you are already using ipf!

  - Edit /etc/rc.conf and put in
 
    firewall_enable="YES"
    firewall_type="open"

  - Edit /etc/rc.firewall and right under the section labeled

    ${fwcmd} add 100 pass all from any to any via lo0
    ${fwcmd} add 200 deny all from any to 127.0.0.0/8
    ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any

  Put in the following rules:

    ${fwcmd} add 401 allow udp from 192.168.1.1 radius to any
    ${fwcmd} add 402 allow udp from 192.168.1.1 radacct to any
    ${fwcmd} add 403 allow udp from 192.168.1.2 radius to any
    ${fwcmd} add 404 allow udp from 192.168.1.2 radacct to any
    ${fwcmd} add 405 deny log udp from any radius to any
    ${fwcmd} add 406 deny log udp from any radacct to any

  If you want a record of logged packets then issue the command:

    [root@spork tmp]# sysctl net.inet.ip.fw.verbose=1
  
   If you get the error "sysctl: unknown oid 'net.inet.ip.fw.verbose'"
   then you have not yet booted after enabling firewall support.

   Note this needs to go in the local startup script for logging to 
   be permanent.


  With ipf:
  - Test for kernel support by enabling ipf:

    [root@spork tmp]# ipf -E
    open device: Device not configured
    ioctl(SIOCIPFFL): Bad file descriptor

  - If this command returns nothing, or IP FIlter: already initialized 
    skip down to CONFIGURING & RUNNING section

  - Enable the following in your kernel config file:

    options         IPFILTER                #ipfilter support
    options         IPFILTER_LOG            #ipfilter logging

  - Compile/Install your new kernel (some directions for doing so can
    be found here)

  - Set the following in /etc/rc.conf:

    ipfilter_enable="YES"
    ipfilter_program="/sbin/ipf -Fa -f"
    ipfilter_rules="/etc/ipf.conf"
    ipfilter_flags=""
    ipmon_enable="YES"

  - Boot up your new kernel and check syslog for the following:

    IP Filter: v3.4.20 initialized.  Default = pass all, Logging = enabled

  - NOTE:  ipf may exist on your system already as a module and can likely
    be loaded as one without a new kernel.  I have always done it as described
    above.  If you send me the steps for enabling it as a module, I will add
    them to this document.

CONFIGURATION

  Solaris
  - Add the following lines to /etc/opt/ipf/ipf.conf:

    pass in quick on lo0
    pass in quick on hme0 proto udp from 192.168.1.1 to any port = 1812
    pass in quick on hme0 proto udp from 192.168.1.2 to any port = 1812
    block return-rst in log level auth.notice quick on hme0 proto udp from any to any port = 1812
    pass in quick on hme0 proto udp from 192.168.1.1 to any port = 1813
    pass in quick on hme0 proto udp from 192.168.1.2 to any port = 1813
    block return-rst in log level auth.notice quick on hme0 proto udp from any to any port = 1813
    pass in all

  - NOTE:  Replace 'hme0' with whatever the primary ethernet interface is on
    your system (see 'ifconfig -a')  Some older Suns may use 'le0'
  - Start filtering ('ipf -Fa -f /etc/opt/ipf/ipf.conf')
  - Test filtering by probing port from non-permitted host (you can use nc to
    do this) - you should see denials in /var/adm/messages if ipmon is running.

  Linux
  
  - First determine which IP filtering method is supported by your kernel.
    
    [root@mx log]# iptables -L
    iptables v1.1.1: can't initialize iptables table `filter': iptables who? (do you need to insmod?)
    Perhaps iptables or your kernel needs to be upgraded.
 
    [bofh@home bofh]$ ipchains -L
    ipchains: Incompatible with this kernel

  - Either of the above indicates that you naturally cannot use that 
    filtering method with your existing kernel.  Try the other.  At 
    least one should work on virtually any Linux.

  iptables
  - Run the following (or preferably create a script for future use):

    iptables -F
    iptables -X FIREWALL
    iptables -P FORWARD ACCEPT
    iptables -N FIREWALL
    iptables -A FIREWALL -j LOG --log-level info
    iptables -A FIREWALL -j REJECT --reject-with icmp-port-unreachable
    iptables -A INPUT -i lo -s 0/0 -d 0/0 -j ACCEPT
    iptables -A INPUT -i eth0 -s 192.168.1.1 -d 0/0 -p udp --dport 1812 -j ACCEPT
    iptables -A INPUT -i eth0 -s 192.168.1.2 -d 0/0 -p udp --dport 1812 -j ACCEPT
    iptables -A INPUT -i eth0 -s 192.168.1.1 -d 0/0 -p udp --dport 1813 -j ACCEPT
    iptables -A INPUT -i eth0 -s 192.168.1.2 -d 0/0 -p udp --dport 1813 -j ACCEPT
    iptables -A INPUT -p udp --dport 1812:1813 -j REJECT

  ipchains
  - Add the following lines to your firewall config (/etc/sysconfig/ipchains
    in RedHat Linux) or just prepend 'ipchains' to each line not beginning 
    with a colon, and create a script:
   
    :input ACCEPT
    :forward ACCEPT
    :output ACCEPT
    -A input -s 0/0 -d 0/0 -i lo -j ACCEPT
    -A input -s 192.168.1.1 -d 0/0 1812 -p udp -j ACCEPT
    -A input -s 192.168.1.2 -d 0/0 1812 -p udp -j ACCEPT
    -A input -s 0/0 -d 0/0 1812 -p udp -j DENY
    -A input -s 192.168.1.1 -d 0/0 1813 -p udp -j ACCEPT
    -A input -s 192.168.1.2 -d 0/0 1813 -p udp -j ACCEPT
    -A input -s 0/0 -d 0/0 1813 -p udp -j DENY
    

  - If you added the above lines to /etc/sysconfig/ipchains (RedHat and
    derivatives) then start filtering with '/etc/init.d/ipchains restart'

  - If you manually entered the firewall, then check if your system has
    'ipchains-save'.  If so, run 'ipchains-save >/etc/sysconfig/ipchains'
    to save your rules for subsequent boots (RedHat and clone distributions
    will utilize this method)

  ipfwadm
  - PLEASE upgrade your system.  ipfwadm is ancient :)  Sorry, but
    I'm not even going to touch this fossil here...

  FreeBSD
- SKIP THIS STEP IF YOU ARE USING IPFW
- Use the same config as Solaris above, but replace 'hme0' with the name of
  your ethernet interface.  This will differ depending on the brand.  Check
  the output of 'ifconfig -a' for what yours is called.  Also, instead of
  the /etc/opt/ipf path, use '/etc/ipf.conf'.
- Start filtering ('ipf -Fa -f /etc/ipf.conf')
- Check /var/log/messages for deny messages which you can generate from
  non-permitted hosts using netcat or similar tools

OTHER LINKS

- IP Filter FAQ
- IPFilter and PF resources

NOTES

- These instructions should be relatively easy, however if there are
  any suggestions or noted ommissions/errors, etc. feel free to drop
  me a note at bofh at ls dash l dot net
  

Colin Bloch [03/12/2002]