Radius/Tacacs Configuration for Network Devices

Most network devices support external authentications via the radius protocol and/or TACACS. The two protocols have some differences but the concepts are the same, so for the rest of article I will focus mainly on using radius.
This configuration is extremely useful to centralize all your users in a common directory system (ldap, active directory, etc…). You usually do not want to change your passwords in hundredth of cisco switches because one of your employees leaves…
The standard solution for Cisco Devices is Cisco ACS, but to make things more interesting (and cheaper!), I will describe how to implement radius authentication using a Radius Server under Linux.
What you need:

  • a Linux server (a low resource VPS is enough)
  • Radiator Radius server
  • an OpenLDAP server

The installation of radiator is very easy:

1
2
tar xzvf Radiator-LASTVERSION.tgz && cd Radiator-LASTVERSION
perl Makefile.PL && make && make test && sudo make install

Now let’s have a look at the radius.cfg file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# All the devices have the same password
<Client DEFAULT>
Secret YOURSECRET
TACACSPLUSKey YOURSECRET
</Client>
<ServerTACACSPLUS>
Key YOURSECRET
</ServerTACACSPLUS>
<Realm /ldap/>
RejectHasReason
PostAuthHook file:"postauthhook.pl"
<AuthBy INTERNAL>
AcctHook file:"accthook.pl"
</AuthBy>
<AuthBy LDAP2>
ServerChecksPassword
Host YOURLDAPSERVER
BaseDN o=YOURBASEDN
UsernameAttr uid
PasswordAttr userPassword
SearchFilter (&(|(privilegedUser=*))(%0=%1))
PostSearchHook file:"postsearchhook.pl"
HoldServerConnection
</AuthBy>
</Realm>

Let’s analyze the configuration in detail:

  • we use the secret key YOURSECRET. You will need to configure the same key in all your network devices. For additional security, you could change the secret key per device and add a certain number of Client clause to map IPs to secret keys (eventually it is possible to store these values as well in a database…)
  • we will accept both Radius and Tacacs+ connections (remember to open your firewall!)
  • the realm is ldap so if your login is USERNAME, you will have to enter it like USERNAME@ldap
  • the AuthBy LDAP clause contains all the informations needed for authenticating against the ldap server. You will have to fill them based on your ldap schema.

What about the perl script that are executed in the different hooks?

  • postauth.pl: this hook is executed after the authentication is validated. This could be useful to add logging about what has happened during the authentication (e.g: which user has authenticated, their IP address etc…)
  • accthook.pl: this hook is useful for devices that support logging of executed commands via accounting packets. You can then logs in your favorite way (file, syslog server, database) all the commands executed (and by whom)
  • postsearchhook.pl: this is the main script for managing authorization. After we have validated username and password, we could still need to validate additional authorizations like:
    does the user have access to this particular device?
    does the user have administrative access to the device? (in Cisco terms, can it execute the “enable” command)
    For example, the code to make the user escalate to level 15 in a Cisco router could be the following:
1
2
3
4
if ($isUserAdmin) {
$_[3]->get_reply->add_attr('cisco-avpair', "shell:priv-lvl=15");
$_[3]->get_reply->add_attr('Service-Type', 'Administrative-User');
}

Radius support is quite wide-spread in network devices, but sometimes it can be buggy or non-standard. A good documentation covering which attributes need to be sent to different devices can be found at the FreeRadius Wiki (hp, cisco)
Which radius server and authentication mechanism do you use in production?

Blocking DNS Amplification attacks

You wake up one normal day and your monitoring system shows a graph like this for the number of queries answered by your DNS server:

Your DNS is usually used only by a couple of machines. What is happening?

The best way to start troubleshooting is using the command dnstop.

1
dnstop -4 eth0

You will see immediately a list of the source IP that are doing the most queries to your DNS.

But what are they requesting? Just press ‘2’ and find out. You will see the domain names and the number of hits.

You have good chances that you will see one of the following domain names:

  • isc.org
  • ripe.net

Congratulations! You are victim of a DNS amplification attack.

In a few words, the bad guys spoof their IP addresses to the one of the victim they want to attack and then they use your recursive DNS server to query domain names.

The result is that (thanks UDP!) the attackers is sending small UDP packets with the request and your DNS server is answering with DNS replies that can be many times bigger than the original packet. This replies are sent back to the spoofed IP address and your DNS is now part of a army of DOSsers to the victim.

What can you to do to avoid this problem?

You have different possibilities:

Stop running a open recursive DNS server on Internet. There are very few reasons for having an open recursive DNS (normally only your authoritative DNS server should be available for the whole internet)

Use the string module of iptables to block all packets that contain isc.org and ripe.

1
iptables -A INPUT -p udp -m string —hex-string “|03697363036f726700|” —algo bm —to 65535 -j DROP

The command will check the content of udp packets for the hex-string that represents isc.org

you can create some tricks on your dns server to avoid answering specific domain names. For example on dnsmasq (typical in many home routers), you could configure it with the following:

1
server=/isc.org/10.0.0.1

where 10.0.0.1 is an IP that is not part of your network and does not run a dns server.

To be extra sure also null-route the IP address:

1
route add 10.0.0.1 gw 127.0.0.1 lo

The result is that all requests for the domain name isc.org will be forwarded to a non-existent address and the attacker will never receive a reply.

finally, you could also configure fail2ban to block IPs that produce a high number of DNS requests (be careful not to block valid traffic!). To do this, you can create a log message when the amounts of dns requests are higher than a certain threshold:

1
iptables -A INPUT -p udp -m udp --dport 53 -m limit --limit 5/sec -j LOG --log-prefix "fw-dns " --log-level 7

This generates a log message like the following:

1
Aug 24 06:34:02 aragorn kernel: [2582889.374570] fw-dns IN=venet0 OUT= MAC= SRC=attacker.ip DST=your.ip LEN=64 TOS=0x00 PREC=0x00 TTL=110 ID=49937 PROTO=UDP SPT=43523 DPT=53 LEN=44

Create the file /etc/fail2ban/filter.d/iptables-dns.conf:

1
2
3
[Definition]
failregex = fw-dns.*SRC= DST

and add the following to jail.conf to ban the IP for 1 day.

1
2
[iptables-dns] enabled = true ignoreip = 127.0.0.1 filter = iptables-dns action = iptables-multiport[name=iptables-dns, port="53", protocol=udp] logpath = /var/log/iptables/dns_reqs.log bantime = 86400 findtime = 120 maxretry = 1

Do you have other suggestions to block dns amplification attacks? Alas compared to an open mail relay, sometimes there are reasons to have an open dns resolver on Internet so we will have to deal with this problem for a while.