Posts tagged ‘security’

You know you’re a computer security guy when…

No idea where this originated, but I received it several months ago via e-mail. For your enjoyment…

You know you’re a computer security guy (or girl) when…

  • You not only lock your laptop with a physical cable leash, but you change the combination of the lock when it’s not in use so that it can’t be “compromised”.
  • Although you have no ill intent, you spend no small amount of your downtime in airports thinking of ways to circumvent TSA security — and you’ve come up with several can’t-miss terrorist ideas that even Jack Bauer couldn’t stop.
  • You lock your screensaver with twice as much insistence when security friends are around than when strangers are, because you’re not nearly as worried about a stranger’s intentions.
  • You’re immediately discontent with all newly announced security solutions, even before you know anything beyond the name.
  • Having extralong passwords that you must type over and over again to get correct is not a bother.
  • You have a database program to store all your passwords, but even it doesn’t contain a single, decoded password.
  • When you read industry-mandated security guidelines, you chuckle at all the newbie mistakes.
  • You secretly hope you don’t miss a big virus outbreak while you are out on vacation.
  • Any security book you read is covered in pen from the technical corrections you’ve made.
  • Your Internet browser home page is a computer security news bundling Web site.
  • You’ve so fine-tuned your personal computer’s host-based firewall that you are sure it is causing problems with legitimate programs, but you really don’t care.
  • You fantasize about a job where you could bust into the house of unsuspecting malicious hackers and take them away to jail.
  • You’ve got a new car with a built-in GPS and computer, but you are constantly worried about how easy it would be to hack.
  • You suspect that every banner and Flash ad on every Web site is hosting malicious JavaScript.
  • You loath government interference with the Internet because you know they will only mess it up more and not fix the problem (see CAN-SPAM Act).
  • When you hear that we’ve arrested some big spammer, you have the same nonreaction as when you hear we’ve arrested Al-Qaeda’s No. 2 person … again.
  • You resist every new application install because of the new attack vector opportunities it will bring.
  • You know that mobile small-form-factor computers have almost no security.
  • Your cell phone is password-protected.
  • You resent having to give out your Social Security number to any person or company, especially because you have never given it when dealing with the Social Security administration.
  • You already own or covet one of those special screen covers that prevent people on either side of you of from reading your screen.
  • You can’t prevent yourself from laughing out loud when someone announces they think that computer viruses, buffer overflows, or whatever will be solved in five years.
  • You hate upgrading your computer because it means spending days trying to copy and convert all your cool hacker and anti-hacker tools to the new system.
  • You have solid friends on computer security discussion lists, whom you know would be there for you in a life-crisis pinch but that you’ve never met in person or talked to on the phone.
  • Although you never try to shoulder surf other people’s passwords, you can always tell by sound alone when they haven’t typed one that is eight characters or more, and you chuckle inside.
  • When someone hands you their USB key to copy something, you always decline, and instead offer your known, clean USB key. You would also prefer one-time, disposable, Tupperware-like memory drives if they existed.
  • You always slow down when reading security guidance looking for the words “should,” “must,” “never,” and “always” — and you understand their importance.
  • By the time you read a CERT security bulletin, you’ve known about the issue for several days.
  • You always investigate SSL certificate errors when they come up in your browser.
  • Finally, you know you’re a computer security person when you have so frequently spoken passionately to complete strangers about computer security and the frustration it entails that you know what it’s like to be covered in sweat — and the listening partyto have a look on their face that says they didn’t know what they were in for.

Are there others? Post them in the comments below!

The Most Dangerous Person in the World?

Executive Summary of John Goekler’s “The Most Dangerous Person in the World?”

“The things we fear most may be least likely to occur, which means the time, trauma and treasure we invest in them is a complete waste.

Security itself is an illusion. It is a perception that exists only between our ears. No army, insurance policy, hazmat team, video surveillance or explosive sniffer can protect us from our own immune system, a well-intentioned but clumsy surgeon, failing to look before crossing the street, an asteroid randomly hurtling through space or someone willing to die in order to do others harm.

In this sense, the only things that can truly make us more “secure” are not things. They are the courage to face whatever comes with dignity and intention, and the strong relationships that assure we will face the future together, and find comfort and meaning in doing so.

Imagine, then, what might happen if we simply quit listening to the scaremongers and those who profit from our paranoia. Imagine what the world could look like if we made a conscious choice to live out whatever time we have with courage, compassion, service and joy.

Terrorism is an act of the weak. But so is walking through the airport in our socks.

We can make better choices.”

[ Read More ]

Judge orders defendant to decrypt PGP-protected laptop

I believe in security and privacy on the intarwebz. I also use PGP for e-mail and whole disk encryption (more to protect data in the event my devices are lost or stolen than to “hide” anything). Because of that, this is kinda scary:

A federal judge has ordered a criminal defendant to decrypt his hard drive by typing in his PGP passphrase so prosecutors can view the unencrypted files, a ruling that raises serious concerns about self-incrimination in an electronic age. In an abrupt reversal, U.S. District Judge William Sessions in Vermont ruled that Sebastien Boucher, who a border guard claims had child porn on his Alienware laptop, does not have a Fifth Amendment right to keep the files encrypted. “Boucher is directed to provide an unencrypted version of the Z drive viewed by the ICE agent,” Sessions wrote in an opinion last week, referring to Homeland Security’s Immigration and Customs Enforcement bureau. Police claim to have viewed illegal images on the laptop at the border, but say they couldn’t access the Z: drive when they tried again nine days after Boucher was arrested.

There is, of course, the alternative: =)

BPDU Protection on HP ProCurve Switches

From HP’s Advanced Traffic Management Guide:

“BPDU protection is a security feature designed to protect the active STP topology by preventing spoofed BPDU packets from entering the STP domain. In a typical implementation, BPDU protection would be applied to edge ports connected to end user devices that do not run STP. If STP BPDU packets are received on a protected port, the feature will disable that port and alert the network manager …”

In short, we want to enable BPDU protection on any “edge ports”, or ports that are connected to end user devices (PCs, printers, etc.) — any device that should not be sending out STP BPDU’s. Without BPDU protection, a malicious (or ignorant) user could plug a switch into our network and alter the spanning tree topology. That’s a bad thing.

With BPDU protection, we can a port automatically disabled if it receives an STP BPDU. Under normal circumstances, this should never happen. Enabling this feature does two things:

  • helps protect your network, and
  • keeps you, the network guy (or gal), informed about what is happening.

Let’s assume a user brings in their own switch from home. They unplug their PC from the wall, plug into their own switch, then plug their switch into the data jack in the wall. As soon as their switch sends out a BPDU, our switch will receive it and immediately disable the port. If you do not configure your switch to automatically re-enable the port after a specified period of time (I don’t), their data jack is effectively dead. It cannot be used again without the intervention of the network guy. When they can no longer work and must come to you for assistance, you’ll have a good idea of what they did and can promptly break their fingers educate them on why they should never do that.

On HP ProCurve switches, we enable BPDU protection with the “spanning-tree <port> bpdu-protection” command. You can do this individually per port (you can specify ranges) or do it like I do:

SWITCH(config)# spanning-tree all bpdu-protection

This, in my opinion, is the best way. This will enable BPDU protection on EVERY port. Then, you selectively disable it on your uplink ports:

SWITCH(config)# no spanning-tree a24 bpdu-protection

The default BPDU protection timeout is set to 0. This is the amount of time, in seconds, after which the switch will re-enable a port that has been disabled due to receiving an “illegal” BPDU. A value of 0 means “never”, and is the value that I prefer. This ensures that “network guy intervention” is required to break the user’s fingers re-enable the port.

Let’s take a look at what happens. In this example, I have BPDU protection enabled on port A2 (all ports except for A24, actually), as can be verified here:

SWITCH# sh spanning-tree bpdu-protection

 Status and Counters - STP Port(s) BPDU Protection Information

 BPDU Protection Timeout (sec) : 0                     
 BPDU Protected Ports : A1-A23,B1-B24,C1-C24,D1-D24,E1-E24,F1-F24,G1-G24,H1-H2...

So, having verified that BPDU protection is enabled on port A2, what happens when we plug another switch into that port? You obviously can’t see me plug in the cable, but here’s what we get in our logs:

SWITCH# sh logging
 Keys:   W=Warning   I=Information
         M=Major     D=Debug E=Error
----  Event Log listing: Events Since Boot  ----
I 03/12/09 00:02:41 00435 ports: port A2 is Blocked by STP
I 03/12/09 00:02:41 00840 stp: port A2 disabled - BPDU received on protected
            port.
I 03/12/09 00:02:41 00898 ports: BPDU protect(5) has disabled port A2 for 0
            seconds
I 03/12/09 00:02:41 00077 ports: port A2 is now off-line
----  Bottom of Log : Events Listed = 99  ----

Our switch will, when the port comes “up”, wait briefly and just listen. It will wait to see if it receives a BPDU (”Blocked by STP”) and, as soon as it does, notes this in the system log and immediately disables the port.

SWITCH# sh spanning-tree bpdu-protection a2

 Status and Counters - STP BPDU Protection Information

 BPDU Protection Timeout (sec) : 0                     
 BPDU Protected Ports : A1-A23,B1-B24,C1-C24,D1-D24,E1-E24,F1-F24,G1-G24,H1-H2..
.

  Port  Type      Protection State      Errant BPDUs
  ----- --------- ---------- ---------- ------------
  A2    100/1000T Yes        BpduError  1

The “sh spanning-tree bpdu-protection a2″ command shows us that port A2 is in “BpduError” state and has received a total of one “errant BPDUs”. Now, let’s assume we’ve unplugged the switch and plugged a PC back in. How do we get the port functional again? Easy:

SWITCH# conf
SWITCH(config)# interface a2
SWITCH(eth-A2)# enable
SWITCH(eth-A2)# end

That’s all there is to it! BPDU protection is simple to implement (assuming you know what connects where) and can add a bit of protection to your network. Turn it on!

‘Twas the night before Christmas, when all through the LAN…

I’d love to give credit for this because it’s awesome, but I have no idea where it originated.

'Twas the night before Christmas, when all through the LAN
No malware was stirring, not even LoveSan;
The firewalls were racked by the router with care,
In hopes that no hacker soon would be there;

The users were nestled all snug in their beds,
While visions of emails danced in their heads;
And me with my MacBook, and fresh packet cap,
Had just settled down for a long winter's nap,

When out from the pager there arose such a clatter,
I sprang to my desk to see what was the matter.
Away to the browser I flew like a flash,
Came through the VPN and refreshed the cache.

The sign on the certificate gave me to know
The session was safe, so I opened it - Lo!
When, what to my wondering eyes should appear,
But a miniature email, and in text that was clear,

With a new device driver, with a quick "ho ho ho",
I knew in a moment it was our CSO.
More rapid than eagles his memos they came,
And he whistled, and shouted, and called them by name;

"Now, firewall! now, filter! now, intrusion detection!
On, event correlation! deep packet inspection!
Build layered defense! to the top of the wall!
Now block away! block away! block away all!"

As alarms that before the wild network worm fly,
When they meet with my console, mount up to the sky,
So up to the network the sensors they flew,
With the rack full of gear, and the CSO too.

And then, with a twinkling, I heard on my cell
The custom ring-tone - the network was well.
As I drew in my hand, and was turning around,
Down to my inbox he came with a bound.

His message was brief, what was afoot?
Were servers and systems safe at the root?
A bundle of appliances stacked on his rack,
And he looked like a peddler just opening his pack.

Their lights -- how they twinkled! Their vendors - how merry!
They stopped all attacks, they paged my BlackBerry!
The poor little hackers were drawn up like a bow,
And tied up in knots in the honeypot below;

The stump of net packets held tight in our teeth,
With logs all analyzed, traceroutes were a breeze;
Our policies sound, vulnerabilities patched,
Our security systems just could not be matched.

He was chubby and plump, a right jolly old elf,
And I laughed when I saw him, in spite of myself;
A wink of his eye and a twist of his head,
Soon gave me to know I had nothing to dread;

He spoke not a word, but went straight to his audit,
tested the firewalls; then turned to report it,
And laying his finger aside of his nose,
And giving a nod, up our T3 he rose;

He sprang to his limo, gave his consultants a whistle,
And away they all flew like the down of a thistle.
But I heard him exclaim, ere he drove out of sight,
"HAPPY CHRISTMAS TO ALL, AND TO ALL A GOOD-NIGHT!"

To whomever wrote this, thank you. Excellent piece.

SNMPv3 Configuration for ProCurve 5400s

I found myself recently setting up new HP ProCurve 5400 switches in production. Because I’m a network guy, I like to keep an eye on them (interface counters, traps, etc.), thus setting up SNMPv3 was necessary. In addition, these devices come (”out of the box”) with a default read-write community string set to — you guessed it — “public”, open to anywhere. That had to be taken care of first.

Setting up SNMPv3:

First, let’s set some basic information so we can track this device amongst all the others:

SWITCH1# conf
SWITCH1(config)# snmp-server location S123
SWITCH1(config)# snmp-server contact jlgaddis

Next, we’ll enable SNMPv3 which, on these 5400s, also has the effect of creating an “initial” user:

SWITCH1(config)# snmpv3 enable
SNMPv3 Initialization process.
Creating user 'initial'
Authentication Protocol: MD5
Enter authentication password: ******
Privacy protocol is DES
Enter privacy password: ******

User 'initial' is created
Would you like to create a user that uses SHA? n

User creation is done.  SNMPv3 is now functional.
Would you like to restrict SNMPv1 and SNMPv2c messages to have read only
access (you can set this later by the command 'snmp restrict-access'): y

What happened here is that an SNMPv3 user (with username “initial”) was automatically created for us. We were prompted for the authentication password and privacy password (note that the protocols were automatically chosen). At this point, I just entered “123456″ as I have plans to delete that user anyway. I went ahead and answered “y” to the last question, but I’ll be turning off SNMPv1 and SNMPv2 in a bit moment regardless.

Let’s configure our switch to only run SNMPv3 and go ahead a create a new SNMPv3 user as well:

SWITCH1(config)# snmpv3 only
SWITCH1(config)# snmpv3 restricted-access
SWITCH1(config)# snmpv3 user cacti auth sha AUTHPASS priv aes PRIVPASS

Here I was setting up a user so that my “graphing application” of choice, cacti, can communicate with the switch to retrieve interface statistics. Substitute your own authentication password and privacy passwords above (”AUTHPASS” and “PRIVPASS”). You can change the protocols as well, if you’d like, to MD5 and DES, respectively. I prefer to go the “high security” route whenever possible, however, so that’s what I opted for here. Be sure your management software is compatible with these settings!

Now, we need to assign our “cacti” user to a group that’s appropriate for the level of access we want it to have. I won’t describe all of the ones available (see Chapter 14 of the Management and Configuration Guide for that), but the one I want (in this case) is “operatorauth”. This group provides for “operator” level access (a.k.a. “unprivileged”) and requires authentication. We’ll also specify “sec-model ver3″ as an SNMPv3 access group should only use the ver3 security model:

SWITCH1(config)# snmpv3 group operator auth user cacti sec-model ver3

Okay, almost there! Now we just need to allow SNMP access to the switch from the host that cacti is running on. In my case, it’s 172.30.144.17:

SWITCH1(config)# ip authorized-managers 172.30.144.17 255.255.255.255 access operator access-method snmp

You can change that, of course, to your own IP address (or whole networks — be sure to change the netmask, however).

At this point, we should be good to go. We could add the device into cacti’s web interface and within a few polling cycles we’ll start to see interface traffic statistics, such as this (from another device):

Finally, there’s one more step that might be necessary, depending upon your switch’s configuration. Because my switch has a loopback address assigned to it, that’s the IP address I want to tell cacti to poll. This method will still allow the switch to be reachable if one (or more) of it’s interfaces go down (there are multiple routes to it). By default, the ProCurve 5400 will respond to SNMP requests with a source IP address of the interface that the requests were received on, and NOT a source IP matching the original destination of the requests:

SWITCH1(config)# snmp-server response-source dst-ip-of-request

…and that’s it! We can now “speak” SNMPv3 (and ONLY SNMPv3) to our switch. In addition, only the “cacti” user can access it, and only from 172.30.144.17.

That’s a helluva lot better than the default read-write “public” community string that’s accessible from anywhere, huh!?

UPDATE: I forgot the part where I deleted the “initial” user that was created automatically for us. Here’s how that’s done:

SWITCH1(config)# no snmpv3 user initial

Easy enough!

Cisco BGP bug crashes 12.4(23)

Two 7200s connected back to back via their serial 2/0 ports. Bring up a link, establish a BGP neighbor relationship between them and then kill your router. The cool thing is, you can even do it from unprivileged mode:

c7200-b# conf t
c7200-b(config)# int loopback 0
*Dec  6 19:36:57.871: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback0, changed state to up
c7200-b(config-if)# ip address 192.168.1.1 255.255.255.0
c7200-b(config-if)# interface serial 2/0
c7200-b(config-if)# ip address 10.0.0.2 255.255.255.252
c7200-b(config-if)# no shutdown
c7200-b(config-if)#
*Dec  6 19:37:13.875: %LINK-3-UPDOWN: Interface Serial2/0, changed state to up
c7200-b(config-if)#
*Dec  6 19:37:13.879: %ENTITY_ALARM-6-INFO: CLEAR INFO Se2/0 Physical Port Administrative State Down 
c7200-b(config-if)#
*Dec  6 19:37:14.883: %LINEPROTO-5-UPDOWN: Line protocol on Interface Serial2/0, changed state to up
c7200-b(config-if)# do ping 10.0.0.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.0.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/13/24 ms
c7200-b(config-if)# router bgp 65001
c7200-b(config-router)# neighbor 10.0.0.1 remote-as 65000
c7200-b(config-router)# network 192.168.1.0 mask 255.255.255.0
c7200-b(config-router)# end
c7200-b#
*Dec  6 19:37:36.911: %SYS-5-CONFIG_I: Configured from console by console
c7200-b#
*Dec  6 19:37:40.919: %BGP-5-ADJCHANGE: neighbor 10.0.0.1 Up 
c7200-b# show ip bgp
BGP table version is 3, local router ID is 192.168.1.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 192.168.0.0      10.0.0.1                 0             0 65000 i
*> 192.168.1.0      0.0.0.0                  0         32768 i
c7200-b# exit

Then, while in unprivileged mode…

c7200-b> show ip bgp version 3

…and that’s it. From the other router, we see that it’s down:

c7200-a> ping 10.0.0.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.0.2, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
c7200-a>

And a moment later we’ll see the BGP adjacency go down:

*Dec  6 19:42:59.419: %BGP-5-ADJCHANGE: neighbor 10.0.0.2 Down Interface flap
c7200-a>

Configuring OSPF Authentication (Dynamips)

Let’s continue on from yesterday’s lab, “Configuring Basic OSPF“. We’ve had a new requirement added to our original design: authenticated OSPF.

Our security team has decided that it is a potential security risk to run unauthenticated OSPF across our network backbone and have asked us to implement a secure method of sending OSPF updates.

OSPF authentication comes in two forms: plain-text and MD5. Because a “secure method” was specified, we have to use MD5 authentication in our environment (plain-text is not “secure”).

Using “pwgen” on an Ubuntu Linux box (”sudo apt-get install pwgen”), I came up with a random key of “xooph8MuBaeph5ee”. This is the authentication key I’ll use for OSPF. You are, of course, free to use something else (and encouraged to do so!).

Since we already have an environment up and running (see the “Configuring Basic OSPF” lab), we just need to add OSPF authentication to our configs and then verify proper operation. Let’s get started.

The actual configuration to enable OSPF authentication is pretty simple. There’s a quick two-part process: 1) create our authentication key (per interface) and 2) tell OSPF to use this authentication key. We’ll knock them both out at once on each router:

ISP# configure terminal
ISP(config)# interface fastethernet 0/0
ISP(config-if)# ip ospf message-digest-key 1 md5 xooph8MuBaeph5ee
ISP(config-if)# router ospf 1
ISP(config-router)# area 0 authentication message-digest 
ISP(config-router)# end
ISP#

Shortly after entering the above configuration, you should have noticed that both of your adjacencies (to Remote1 and Remote2) went from “FULL” to “DOWN”. This is because the ISP router is now sending authenticated OSPF updates and is expecting to receive them as well. Let’s configure the Remote1 router:

REMOTE1# configure terminal
REMOTE1(config)# interface fastethernet 0/0
REMOTE1(config-if)# ip ospf message-digest-key 1 md5 xooph8MuBaeph5ee
REMOTE1(config-if)# router ospf 1
REMOTE1(config-router)# area 0 authentication message-digest 
REMOTE1(config-router)# end
REMOTE1#

What we see on Remote1 is a bit different. After entering the configuration, we should notice two things. First, the adjacency with Remote2 will go down (for the same reasons as with ISP router above). In addition, we should see the adjacency with the ISP router come back up as both are now sending (and expecting to receive) authenticated updates.

If we run “show ip ospf neighbor” on each router, we should see that ISP and Remote1 have an adjacency formed but that Remote2 does not have any adjacencies. Let’s verify this:

ISP# show ip ospf neighbor

Neighbor ID     Pri   State           Dead Time   Address         Interface
10.10.10.3      254   FULL/BDR        00:00:36    10.10.10.3      FastEthernet0/0
ISP#
REMOTE1# show ip ospf neighbor

Neighbor ID     Pri   State           Dead Time   Address         Interface
10.10.10.1      255   FULL/DR         00:00:32    10.10.10.1      FastEthernet0/0
REMOTE1#
REMOTE2# show ip ospf neighbor

REMOTE2#

All we need to do to get all of our adjacencies back up is to configure OSPF authentication on Remote2 just like we did the other two routers. We should then see our adjacencies form again:

REMOTE2# configure terminal
REMOTE2(config)# interface fastethernet 0/0
REMOTE2(config-if)# ip ospf message-digest-key 1 md5 xooph8MuBaeph5ee
REMOTE2(config-if)# router ospf 1
REMOTE2(config-router)# area 0 authentication message-digest
REMOTE2(config-router)# end
REMOTE2#

And, indeed, we’ll see the adjacencies form. By looking at the output of “show ip route” we can verify convergence, but how can be know that authentication is actually being used?

Let’s run a “debug ip ospf adj” on ISP router and take a look at the output:

ISP# debug ip ospf adj
OSPF adjacency events debugging is on
ISP#
*Mar  1 00:28:18.055: OSPF: Send with youngest Key 1
ISP#
*Mar  1 00:28:28.055: OSPF: Send with youngest Key 1
ISP#
*Mar  1 00:28:38.055: OSPF: Send with youngest Key 1
ISP#
*Mar  1 00:28:48.055: OSPF: Send with youngest Key 1
ISP#undebug all
All possible debugging has been turned off
ISP#

Success! We’ve now added authentication to our OSPF updates which will make our security team happy — and now they owe us a beer!

Basic NTP Configuration for Cisco Routers

What is NTP?

  • “The Network Time Protocol (NTP) is a protocol for distributing the Coordinated Universal Time (UTC) by means of synchronizing the clocks of computer systems over packet-switched, variable-latency data networks.”Wikipedia

Why is NTP important?

  • “Time is inherently important to the function of routers and networks. It provides the only frame of reference between all devices on the network. This makes synchronized time extremely important. Without synchronized time, accurately correlating information between devices becomes difficult, if not impossible. When it comes to security, if you cannot successfully compare logs between each of your routers and all your network servers, you will find it very hard to develop a reliable picture of an incident. Finally, even if you are able to put the pieces together, unsynchronized times, especially between log files, may give an attacker with a good attorney enough wiggle room to escape prosecution.”Thomas Akin, in Hardening Cisco Routers.

NTP provides us (the network, systems, and security guys) with an easy way to ensure that all of our network devices have the same time. In smaller networks, this is desirable; in large networks, it is a must. In this lab, we’ll configure one Cisco router as both a client (synchronizing time from hosts on the Internet) and server (providing time synchronization to other internal devices).

Topology

Our physical topology looks like this:

Specifications

For our demonstration, R1 will be both an NTP client and NTP server while R2 will only be an NTP client. Because we will be synchronizing R1’s time with a host on the Internet, R1 will need connectivity to the Internet for this demonstration; R2 will not. R1’s actual connectivity to the Internet is irrelevant and out of the scope of this demonstration.

  • R1 will synchronize time against nist.netservicesgroup.com (64.113.32.5).
  • R2 will synchronize time against R1 (172.16.12.1).
  • NTP synchronization between R1 and R2 will be authenticated, using a key of “ThereIsTimeForEverything“.

Configuring R1 as an NTP client

Before we get started, I first want to show that we currently have an unsynchronized clock:

R1# show clock detail
*00:01:19.099 UTC Fri Mar 1 2002
No time source
R1#

Configuring a Cisco router to act as an NTP client is extremely simple. We’ll use the “ntp server” command, followed by the IP address of the NTP server:

R1# configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
R1(config)# ntp server nist.netservicesgroup.com
Translating "nist.netservicesgroup.com"...domain server (192.168.1.12) [OK]

R1(config)#

That’s about all there is to it, from the client side. Note that if you do not have DNS configured on your devices, you’ll need to use IP addresses instead of fully qualified domain names (above). If we take a look at our clock, we’ll see that the time has been updated from NTP:

R1# show clock detail
03:15:52.593 UTC Sun Nov 23 2008
Time source is NTP

Let’s verify our NTP associations and status:

R1# show ntp associations

      address         ref clock     st  when  poll reach  delay  offset    disp
*~64.113.32.5      .ACTS.            1    45    64   17    36.2   -2.90  1901.2
 * master (synced), # master (unsynced), + selected, - candidate, ~ configured
R1# show ntp status
Clock is synchronized, stratum 2, reference is 64.113.32.5
nominal freq is 250.0000 Hz, actual freq is 250.0000 Hz, precision is 2**18
reference time is CCD34DAA.B4D97B06 (03:34:02.706 UTC Sun Nov 23 2008)
clock offset is -2.8967 msec, root delay is 36.16 msec
root dispersion is 909.03 msec, peer dispersion is 906.13 msec

Note that the synchronization process could take up to five minutes. If you see “Clock is unsynchronized” in the output of “show ntp status”, wait a moment and run the command again. If you so desired, you could use “debug ntp events” to watch the communications and see what is happening. Make sure that R1 becomes synchronized before beginning to configure R2 — a device providing NTP services will not do so until the device itself is fully synchronized.

Configuring R1 as an NTP server

Configuring R1 to act as an NTP server is easy enough — it’s already done! As soon as R1 becomes synchronized, it will automatically begin answering NTP requests from other hosts. This is why access lists are important; we’ll cover those in a later lab.

Configuring R2 as an NTP client

Now we’ll configure R2 as an NTP client, just as we did with R1. Let’s first show that our clock is unsynchronized, then configure R2 to synchronize with R1:

R2# show clock detail
*02:16:24.771 UTC Fri Mar 1 2002
No time source
R2# configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
R2(config)# ntp server 172.16.12.1

After a moment, we should see that R2 is now successfully synchronizing time with R1:

R2# show clock detail
04:17:06.271 UTC Sun Nov 23 2008
Time source is NTP
R2# show ntp associations

      address         ref clock     st  when  poll reach  delay  offset    disp
*~172.16.12.1      64.113.32.5       2    17    64  377    35.9    2.41     7.8
 * master (synced), # master (unsynced), + selected, - candidate, ~ configured
R2# show ntp status
Clock is synchronized, stratum 3, reference is 172.16.12.1
nominal freq is 250.0000 Hz, actual freq is 250.0001 Hz, precision is 2**18
reference time is CCD357B6.5807B0D4 (04:16:54.343 UTC Sun Nov 23 2008)
clock offset is 2.4103 msec, root delay is 55.85 msec
root dispersion is 261.81 msec, peer dispersion is 7.80 msec

Configuring NTP Authentication

As of now, we have time synchronization working between R1 and an external NTP server and between R1 and R2. Our security policy, however, dictates (hypothetically, of course) that NTP traffic between hosts inside our network must be authenticated. (For additional security, we would use authentication for requests between R1 and the external NTP server as well.)

It is important to note that configuring authentication doesn’t require clients to use authentication — it merely enables them to do so. Our NTP servers will still answer requests that are not authenticated, so we’ll want to use access lists to control access as well (coming in the next lab).

Our first step in turning on authentication is to enable it on R1. Recall from above that we’re going to use the key “ThereIsTimeForEverything” (bonus points for the first person to leave a comment below telling me who that quote is from!):

R1# configure terminal
R1(config)# ntp authenticate
R1(config)# ntp authentication-key 10 md5 ThereIsTimeForEverything
R1(config)# ntp trusted-key 10

Likewise, we must configure the same authentication key on R2 and instruct it to use that key when “speaking” NTP to R1:

R2# configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
R2(config)# ntp authenticate
R2(config)# ntp authentication-key 10 md5 ThereIsTimeForEverything
R2(config)# ntp trusted-key 10
R2(config)# ntp server 172.16.12.1 key 10

Shortly thereafter, we can check our NTP associations on R2 and we should see that the NTP exchanges between it and R1 are authenticated:

R2# show ntp associations detail 
172.16.12.1 configured, authenticated, our_master, sane, valid, stratum 2
ref ID 64.113.32.5, time CCD37909.8B261140 (06:39:05.543 UTC Sun Nov 23 2008)
our mode client, peer mode server, our poll intvl 128, peer poll intvl 128
root delay 20.14 msec, root disp 65.69, reach 377, sync dist 116.699
delay 7.81 msec, offset 116.2200 msec, dispersion 37.03
precision 2**18, version 3
org time CCD37929.2A38A6CA (06:39:37.164 UTC Sun Nov 23 2008)
rcv time CCD37929.17DC107A (06:39:37.093 UTC Sun Nov 23 2008)
xmt time CCD37929.07835CB1 (06:39:37.029 UTC Sun Nov 23 2008)
filtdelay =    63.72    7.81   55.88   48.10   48.02   48.02   36.01   55.95
filtoffset =  103.59  116.22  118.39   92.51   79.64   51.89   70.94   43.87
filterror =     0.02    0.99    1.60    3.56    5.51    7.46    8.44    8.97

Did you see it? Let’s filter out some of the output and look only at the line we’re concerned with:

R2# show ntp associations detail | include 172.16.12.1  
172.16.12.1 configured, authenticated, our_master, sane, valid, stratum 2

There it is: “authenticated“.

Okay, now what!?

Excellent, we’ve managed to configure R1 as an NTP client synchronizing against a public NTP server on the Internet as well as providing NTP services to internal hosts. We even enabled the ability of R1’s NTP clients to authenticate the responses they’re receiving from R1 (security of NTP is important).

Later, we’ll extend this lab to provide redundancy as well as implement access lists to increase the security of our NTP “infrastructure”.

Configuring FreeRADIUS to support Cisco AAA Clients

In this demonstration, we’re going to install FreeRADIUS onto a CentOS 5.2 server and configure it to support AAA on Cisco devices.

“FreeRADIUS is the most widely deployed RADIUS server in the world. It is the basis for multiple commercial offerings. It supplies the AAA needs of many Fortune-500 companies and Tier 1 ISPs. It is also widely used in the academic community, including eduroam. The server is fast, feature-rich, modular, and scalable.” –FreeRADIUS home page

I’ve been using FreeRADIUS in production for a few years now, mostly to support wireless users. One of the benefits of FreeRADIUS — besides being open source, of course — is the numbers of backends one can use for authentication:

“If a password is not available locally for some reason, the server can pass the authentication to another system such as LDAP, PAM, Unix (/etc/passwd), Kerberos, Active Directory, or RADIUS server via RADIUS proxying. Local programs (e.g. CGI scripts) can also be used to authenticate users via shell scripts or any other method. Perl or Python scripts can be pre-loaded into the server, which significantly lowers the cost of running such programs.”

Powerful, huh? Indeed.

For this demonstration, I’m installing a new CentOS 5.2 virtual machine on my MacBook under VMware Fusion. Installing the operating system, however, is beyond the scope of this document. Also, we’ll just be using the local system database for now — we’ll save SQL and LDAP (perhaps even Active Directory) authentication for later. After we get FreeRADIUS up and running, we’ll set up a user account and then configure a Cisco router to use RADIUS for authentication.

Let’s begin with installing FreeRADIUS by running (as root) the following command:

[root@bertram ~]# yum -y install freeradius

“yum” should have went out, grabbed the appropriates packages and dependencies, and installed them. If the end of your output looks like this, you’re all set:

Complete!
[root@bertram ~]#

Because FreeRADIUS will need to use the local system database for authentication, we need to set ‘user = root’ and ‘group = root’ in radiusd.conf. This is easy enough, just open up /etc/raddb/radiusd.conf, and change the lines that reads “user = radiusd” and “group = radiusd” to “user = root” and “group = root”, respectively. Note that this (running our daemons as root) is almost always something we want to avoid. Using other authentication backends, such as SQL or LDAP, would not require this change and would allow the FreeRADIUS service to run under the default “radiusd” unprivileged account.

Next, we need to let FreeRADIUS know about our NAS — in this case, our Cisco router. For the sake of this demonstration, our router (R1) will have IP address 192.168.1.201. We’ll also need a shared secret that the router and RADIUS server use. Let’s use the ever popular “SECRET_KEY”. Add the following to the end of /etc/raddb/clients.conf:

client 192.168.1.201 {
        secret = SECRET_KEY
        shortname = R1
        nastype = cisco
}

Then, on the FreeRADIUS side, we need to create a user account in the local user database that we’ll use for actually authenticating to R1. Nothing special here, just creating a new user account and setting the password. I’ve passed the plain-text password into “passwd” via stdin so that you can see it. Normally, we wouldn’t do that — just run “passwd cisco” and enter the password when prompted:

[root@bertram ~]# /usr/sbin/useradd cisco
[root@bertram ~]# echo secret | passwd --stdin cisco
Changing password for user cisco.
passwd: all authentication tokens updated successfully.
[root@bertram ~]#

We now have a local user named “cisco” with a password of “secret” that we’ll use when it comes time to authenticate to R1. Before we can do that, however, we must let FreeRADIUS know about the user. Append the following to /etc/raddb/users:

cisco   Auth-Type := System
        Service-Type = NAS-Prompt-User,
        cisco-avpair = "shell:priv-lvl=15"

This notifies FreeRADIUS of a local user account named “cisco”. Using the “cisco-avpair” attribute in this manner allows us to automatically assign privilege level 15 to the user, removing the requirement for the user to issue “enable” (and the enable secret) in order to gain elevated access.

Let’s get started configuring R1. I’m going to assume that you’re starting from a default configuration. The first thing we want to do is create a “fallback” user account (on the router itself) that we can use to authenticate if, for some reason, connectivity to the RADIUS server is lost. Let’s create a user named “admin” with a password of “letmein”:

R1(config)#username admin privilege 15 secret letmein

Under normal circumstances, we’ll never use this local account — only when the RADIUS server is unavailable.

The first thing I need to do is configure my interface on R1 and verify we can ping the RADIUS server. Assuming you already have your router up and running, you can likely skip this step:

R1(config)#interface fastethernet 3/0
R1(config-if)#ip address 192.168.1.201 255.255.255.0
R1(config-if)#no shutdown
R1(config-if)#
*Mar  1 00:10:14.635: %LINK-3-UPDOWN: Interface FastEthernet3/0, changed state to up
*Mar  1 00:10:15.635: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet3/0, changed state to up
R1(config-if)#do ping 192.168.1.51

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.1.51, timeout is 2 seconds:
.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 4/11/24 ms
R1(config-if)#

Excellent, all set! Let’s start configuring R1 for AAA:

R1(config)#aaa new-model
R1(config)#radius-server host 192.168.1.51 auth-port 1812 acct-port 1813 key SECRET_KEY

AAA should now be enabled on R1. Note that we provided the IP address of the RADIUS server as well as the shared secret we configured in FreeRADIUS earlier. In addition, we must specify the “auth-port” and “acct-port” used by FreeRADIUS, as these are different from Cisco’s defaults (1645 and 1646). Let’s configure authentication:

R1(config)#aaa authentication login default group radius local
R1(config)#line vty 0 4
R1(config-line)#login authentication default
R1(config-line)#line con 0
R1(config-line)#login authentication default

Here, we’ve told R1 to use RADIUS for authentication and to fall back to the local user database if the RADIUS server is not available. We don’t want to DoS ourselves!

The following command will allow the user to run an “exec” shell when logging into the router:

R1(config)#aaa authorization exec default group radius if-authenticated 

Last, but not least, we want accounting (the final “A” in “AAA”):

R1(config)#aaa accounting exec default start-stop group radius
R1(config)#aaa accounting system default start-stop group radius

That should be enough to allow us to login with our local (Linux) system account “cisco” that we created earlier. Let’s give it a shot:

macbook:~ jlgaddis$ telnet 192.168.1.201
Trying 192.168.1.201...
Connected to 192.168.1.201.
Escape character is '^]'.


User Access Verification

Username: cisco
Password:

R1#show ip interface brief
Interface                  IP-Address      OK? Method Status                Protocol
Ethernet0/0                unassigned      YES unset  administratively down down
Ethernet0/1                unassigned      YES unset  administratively down down
Ethernet0/2                unassigned      YES unset  administratively down down
Ethernet0/3                unassigned      YES unset  administratively down down
Serial1/0                  unassigned      YES unset  administratively down down
Serial1/1                  unassigned      YES unset  administratively down down
Serial1/2                  unassigned      YES unset  administratively down down
Serial1/3                  unassigned      YES unset  administratively down down
FastEthernet3/0            192.168.1.201   YES manual up                    up
R1#exit
Connection closed by foreign host.
macbook:~ jlgaddis$

Success! We’ve installed FreeRADIUS, added a local user account, set up the NAS client (R1) and configured it to authenticate against the RADIUS server. Let’s take a look at what was logged by FreeRADIUS:

[root@bertram ~]# cat /var/log/radius/radacct/192.168.1.201/detail-20081119
Wed Nov 19 00:24:47 2008
        Acct-Session-Id = "00000005"
        User-Name = "cisco"
        Acct-Authentic = RADIUS
        Acct-Status-Type = Start
        NAS-Port = 130
        NAS-Port-Id = "tty130"
        NAS-Port-Type = Virtual
        Calling-Station-Id = "192.168.1.49"
        Service-Type = NAS-Prompt-User
        NAS-IP-Address = 192.168.1.201
        Acct-Delay-Time = 0
        Client-IP-Address = 192.168.1.201
        Acct-Unique-Session-Id = "31b757fca2145e79"
        Timestamp = 1227072287

Wed Nov 19 00:25:14 2008
        Acct-Session-Id = "00000005"
        User-Name = "cisco"
        Acct-Authentic = RADIUS
        Acct-Terminate-Cause = User-Request
        Acct-Session-Time = 27
        Acct-Status-Type = Stop
        NAS-Port = 130
        NAS-Port-Id = "tty130"
        NAS-Port-Type = Virtual
        Calling-Station-Id = "192.168.1.49"
        Service-Type = NAS-Prompt-User
        NAS-IP-Address = 192.168.1.201
        Acct-Delay-Time = 0
        Client-IP-Address = 192.168.1.201
        Acct-Unique-Session-Id = "31b757fca2145e79"
        Timestamp = 1227072314

[root@bertram ~]#

If there’s interest, I may expand on this later to include huntgroups, multiple RADIUS servers, using MySQL for accounting, or even through some LDAP and/or Active Directory authentication into the mix. If you’re interested, please leave a comment below!