Posts Tagged ‘Cisco configuration’

Cisco 3750 Password Recovery

Monday, June 1st, 2009


This password recovery method also applies to at least the:
Cisco 2950, Cisco 2960, Cico 3550, Cisco 3560 and Cisco 3750 series.
The only difference will be for how long you will hold the mode button,
from my experience just try to hold it longer if it doesn’t work.
(It should be around 15 seconds for the 3750.)

Connect the PC to the console port
Settings:

  • 9600 bits
  • 8 data bits
  • ‘none’ parity
  • 1 stop bit

If the switch is powered on, power it off and press and hold the mode button while you power on the switch again. Hold it for about 15 seconds until the SYS led is solid green, then release it.

The switch should then give you this prompt

switch:

To initialize the flash file system, run the command

switch: flash_init

The switch will now print a bunch of messages about the flash memory, hopefully one of them will be ‘done initializing flash’.
The next command is load_helper to load any helper images required by boot.

You can now list the contents of your flash by running dir flash:
There should be a file named ‘config.text’, you can rename this file

switch: rename flash:config.text flash:oldconfig.backup

To further boot the switch run the boot command, this will start the boot you are used to. When the switch is booted up, you will realize that the configuration is gone.. But you are enabled on the switch now.

To recover the old configuration:

Switch#rename flash:oldconfig.backup flash:config.text

And now to replace the running configuration with the backup

Switch#copy flash:config.text running-config
Destination filename [running-config]?

Press enter, and you will have your old switch configuration back and you are enabled.
Just remember to change your password now! 😀

Manipulate Routed Traffic With A Route-map

Wednesday, May 6th, 2009

Sometimes.. when everything is failing, you’ll need to do some dirty hacks to get things the way you want. I’m going to show you how to modify the next-hop (where the packet is routed) with a route-map

Let’s say you want to redirect web-traffic to a local cache running for example squid, but let other traffic pass on to its intended destination. As usual I have created an imaginary scenario, but this time I have used my creative skills (yeah, right!) to draw a little network map in dia also.

squidroutemap

The idea is to let all TCP port 80 traffic from all the clients to be sent to the web cache server on 10.0.0.2
To achieve this, we need to create an access-list to match web traffic from the clients.

Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#ip access-list extended webtraffic
Router(config-ext-nacl)#deny tcp host 10.0.0.2 any eq www
Router(config-ext-nacl)#permit tcp 10.0.0.0 0.0.0.255 any eq www

To verify that this access-list now exists, run this command

Router#sh ip access-list webtraffic
Extended IP access list webtraffic
10 deny tcp host 10.0.0.2 any eq www
20 permit tcp 10.0.0.0 0.0.0.255 any eq www

As you can see, I have a deny on 10.0.0.2, this is because we can’t match traffic coming from the web caching server and redirect it to itself, that would create a loop.

The next thing we need to do is to create a route-map which uses the webtraffic access-list to match packets and do the intended modifications to it.

Router(config)#route-map webcache-redirect permit 10
Router(config-route-map)#match ip address webtraffic
Router(config-route-map)#set ip next-hop 10.0.0.2
Router(config-route-map)#route-map webcache-redirect permit 200

You can now verify this route-map by doing this

Router#sh route-map webcache-redirect
route-map webcache-redirect, permit, sequence 10
Match clauses:
ip address (access-lists): webtraffic
Set clauses:
ip next-hop 10.0.0.2
Policy routing matches: 0 packets, 0 bytes
route-map webcache-redirect, permit, sequence 200
Match clauses:
Set clauses:
Policy routing matches: 0 packets, 0 bytes

The last thing that needs to be done for this to have effect is to apply policy routing on the interface on which you receive the traffic from the clients (the interface which acts as a gateway for the clients, in this case the one with the IP address 10.0.0.1).

Router(config)#int vlan 1
Router(config-if)#ip policy route-map webtraffic-redirect

You can now use the sh route-map command again to see that your webtraffic now is being policy-routed.

Read about how to setup a squid as a transparent proxy here.

UPDATE: Eirik Hjelle poked me and told me that the squid tutorial that I am refering to is outdated, and it sure is!
The basics of the squid.conf should be (was not going to cover it here, since it’s a cisco blog, but since Eirik was a nice fellow and just gave me a paste of the required I’ll include it:

http_port 3128 transparent
acl internal_network src 10.0.0.0/24
http_access allow internal_network

The traffic will still be directed to port 80 so it might be needed to change the http_port to

http_port 10.0.0.2:80 transparent

Configuring errdisable behaviour

Thursday, February 19th, 2009

When was the first time you learned that errdisable exists? Here is a short introduction!

I learned this the hard way, I had a network setup in a lab when I had a port shutdown and never come up again… You can say I am glad I learned about it before that happened in the field, but do you know what it is and how you can configure it?

What is errdisable?
Errdisable is a mechanism in Cisco equipment that will for example shutdown or suspend network ports where traffic is looping, ports with unidirectional traffic and various other causes.  This renders the port useless and no traffic is passed over it, the LED on the switch or router turns orange.

To determine if a port is in errdisable state you can issue the command:

Switch#sh int gigabitEthernet 1/0/25 status
Port Name Status Vlan Duplex Speed Type
Gi1/0/25 mynetwork err-disabled 1 auto auto 1000BaseSX SFP

Additionally to see all errdisabled interfaces that will be enabled you can use

Switch# show errdisable recovery

This command will show all errdisable causes with enabled recovery and all interfaces that will be enabled on the next timeout.

Configuration
To configure errdisable recovery, you will use exactly that command

Switch#conf t
Switch(config)#errdisable recovery cause bpduguard
Switch(config)#

That command will enable recovery for the bpduguard (STP loop) cause.

errdisable recovery timer

Switch(config)#errdisable recovery interval 30

This will set a 30 second interval between timeouts, for every timeout cycle – all interfaces which are shutdown because of errdisable will be re-enabled.

If the reason for the errdisable status persists, the interface will then be shutdown and set to status errdisable again. If you set the timeout too low, you may use a lot of CPU because the interface will effectively be flapping.

How to setup a GRE tunnel on a Cisco Router

Tuesday, January 13th, 2009

Hey peeps, it has been a while now…
Sorry about that, I have had a lot of things on my mind lately.
Sometimes I also have issues figuring about a new subject to write about, but I will try to take on more advanced networking as someone requested it per email.  If you want me to write about something or need help with anything, don’t hesitate to contact me.

So, let’s warm up the new year with an easy tutorial on how to setup a GRE tunnel on a Cisco router.

Consider this scenario:
Router1 = 172.16.1.1
Router2 = 192.168.0.1

The routing between these routers are fixed so that they can reach each other, like on the internet.
Router2 will have the network 10.0.10.0/24 routed to it via a GRE tunnel.
The address on the tunnel interfaces will be 10.0.0.1 and 10.0.0.2 for Router1 and Router2 respectively.

Router1 configuration:

Router1(config)#interface Tunnel 0
Router1(config-if)#tunnel source 172.16.1.1
Router1(config-if)#tunnel destination 192.168.0.1
Router1(config-if)#tunnel mode gre ip
Router1(config-if)#ip address 10.0.0.1 255.255.255.252
Router1(config-if)#no shutdown
Router1(config-if)#exit
Router1(config)#ip route 10.0.10.0 255.255.255.0 10.0.0.2

Router1(config)#interface Tunnel 0
Router1(config-if)#tunnel source 192.168.0.1
Router1(config-if)#tunnel destination 172.16.1.1
Router1(config-if)#tunnel mode gre ip
Router1(config-if)#ip address 10.0.0.2 255.255.255.252
Router1(config-if)#no shutdown
Router1(config-if)#exit
Router1(config)#ip route 10.0.10.0 255.255.255.0 Null 0

You can now setup addresses within 10.0.10.0/24 on any interface you want and use them like as they were routed to your router directly.
The traceroute from Router2 to Router1 should look something like this:

Router2#traceroute 10.0.0.1

Type escape sequence to abort.
Tracing the route to 10.0.0.1

1 10.0.0.1 8 msec 8 msec 8 msec

Voila, we got routing over GRE!

Cisco IOS Dialin VPN Configuration With Radius Users in MySQL

Monday, November 24th, 2008

Sometimes it can be preferable to have client initiated dialin tunneling, here’s a flexible solution!

First off, the tunnel endpoint configuration (for example a 7200 router)

Router#conf t
Router(config)#aaa group server radius dialin
Router(config-sg-radius)#server-private 10.0.0.5 auth-port 1812 acct-port 1813 key MYSECRET
Router(config-sg-radius)#server 10.0.0.5 auth-port 1812 acct-port 1813
Router(config-sg-radius)#exit
Router(config)#aaa authentication ppp default group dialin
Router(config)#aaa authorization network default group dialin
Router(config)#aaa accounting network default start-stop group dialin
Router(config)#vpdn enable
Router(config)#vpdn authorize directed-request
Router(config)#vpdn-group dialingroup
Router(config-vpdn)#accept-dialin
Router(config-vpdn-acc-in)#protocol l2tp
Router(config-vpdn-acc-in)#virtual-template 1
Router(config-vpdn-acc-in)#exit
Router(config-vpdn)#source-ip 10.0.0.1
Router(config-vpdn)#local name vpnrouter
Router(config-vpdn)#lcp renegotiation always
Router(config-vpdn)#no l2tp tunnel authentication
Router(config-vpdn)#ip mtu adjust
Router(config-vpdn)#interface loopback 5
Router(config-if)#description Loopback for VPDN clients
Router(config-if)#ip address 10.0.1.1 255.255.255.0
Router(config-if)#interface virtual-template 1
Router(config-if)#ip unnumbered Loopback5
Router(config-if)#ip tcp adjust-mss 1420
Router(config-if)#ip policy route-map clear-df
Router(config-if)#peer default ip address pool dialinpool
Router(config-if)#no keepalive
Router(config-if)#ppp mru match
Router(config-if)#ppp authentication pap chap
Router(config-if)#exit
Router(config)#ip local pool dialinpool 10.0.1.2 10.0.1.254

Now, we need the radius server on 10.0.0.5 to work
I installed this on a debian system, the freeradius version used there was 1.1.7-1build4

Just run this command as root to install Freeradius and MySQL

apt-get install freeradius-mysql freeradius mysql-server-5.0

You may need to edit /etc/freeradius/radiusd.conf to have the modules pap and chap loaded if the part is commented out. (the # in the beginning of the lines (not comments) should be removed)

You may also need to remove the comment for

$INCLUDE ${confdir}/sql.conf

Example /etc/freeradius/sql.conf

sql {
driver = “rlm_sql_mysql”
server = “localhost”
login = “freeradius”
password = “mysqlpassword”
radius_db = “radius”
acct_table1 = “radacct”
acct_table2 = “radacct”
postauth_table = “radpostauth”
authcheck_table = “radcheck”
authreply_table = “radreply”
groupcheck_table = “radgroupcheck”
groupreply_table = “radgroupreply”
usergroup_table = “usergroup”
nas_table = “nas”
deletestalesessions = yes
sqltrace = yes
sqltracefile = ${logdir}/sqltrace.sql
num_sql_socks = 5
connect_failure_retry_delay = 60
sql_user_name = “%{Stripped-User-Name}”
# I know my blog design bugs here
authorize_group_check_query = “SELECT ${groupcheck_table}.id,${groupcheck_table}.GroupName,${groupcheck_table}.Attribute,${groupcheck_table}.Value,${groupcheck_table}.op FROM ${groupcheck_table},${usergroup_table} WHERE ${usergroup_table}.UserName = ‘%{SQL-User-Name}’ AND ${usergroup_table}.GroupName = ${groupcheck_table}.GroupName ORDER BY ${groupcheck_table}.id”
authorize_group_reply_query = “SELECT ${groupreply_table}.id,${groupreply_table}.GroupName,${groupreply_table}.Attribute,${groupreply_table}.Value,${groupreply_table}.op FROM ${groupreply_table},${usergroup_table} WHERE ${usergroup_table}.UserName = ‘%{SQL-User-Name}’ AND ${usergroup_table}.GroupName = ${groupreply_table}.GroupName ORDER BY ${groupreply_table}.id”
accounting_onoff_query = “UPDATE ${acct_table1} SET AcctStopTime=’%S’, AcctSessionTime=unix_timestamp(‘%S’) – unix_timestamp(AcctStartTime), AcctTerminateCause=’%{Acct-Terminate-Cause}’, AcctStopDelay = ‘%{Acct-Delay-Time}’ WHERE AcctSessionTime=0 AND AcctStopTime=0 AND NASIPAddress= ‘%{NAS-IP-Address}’ AND AcctStartTime <= '%S'" accounting_update_query = "UPDATE ${acct_table1} \ SET FramedIPAddress = '%{Framed-IP-Address}', \ AcctSessionTime = '%{Acct-Session-Time}', \ AcctInputOctets = '%{Acct-Input-Octets}', \ AcctOutputOctets = '%{Acct-Output-Octets}' \ WHERE AcctSessionId = '%{Acct-Session-Id}' \ AND UserName = '%{SQL-User-Name}' \ AND NASIPAddress= '%{NAS-IP-Address}'" accounting_update_query_alt = "INSERT into ${acct_table1} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', DATE_SUB('%S',INTERVAL (%{Acct-Session-Time:-0} + %{Acct-Delay-Time:-0}) SECOND), '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0')" accounting_start_query = "INSERT into ${acct_table1} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', '%S', '0', '0', '%{Acct-Authentic}', '%{Connect-Info}', '', '0', '0', '%{Called-Station-Id}', '%{Calling-Station-Id}', '', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '%{Acct-Delay-Time}', '0')" accounting_start_query_alt = "UPDATE ${acct_table1} SET AcctStartTime = '%S', AcctStartDelay = '%{Acct-Delay-Time}', ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}'" accounting_stop_query = "UPDATE ${acct_table2} SET AcctStopTime = '%S', AcctSessionTime = '%{Acct-Session-Time}', AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}', AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time}', ConnectInfo_stop = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}'" accounting_stop_query_alt = "INSERT into ${acct_table2} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', DATE_SUB('%S', INTERVAL (%{Acct-Session-Time:-0} + %{Acct-Delay-Time:-0}) SECOND), '%S', '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Connect-Info}', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0', '%{Acct-Delay-Time}')" simul_verify_query = "SELECT RadAcctId, AcctSessionId, UserName, NASIPAddress, NASPortId, FramedIPAddress, CallingStationId, FramedProtocol FROM ${acct_table1} WHERE UserName='%{SQL-User-Name}' AND AcctStopTime = 0" postauth_query = "INSERT into ${postauth_table} (id, user, pass, reply, date) values ('', '%{User-Name}', '%{User-Password:-Chap-Password}', '%{reply:Packet-Type}', NOW())" }

Also this is done in /etc/freeradius/proxy.conf

realm mydsl.com {
type = radius
authhost = LOCAL
accthost = LOCAL
}

Now get the SQL database up and running, login to the MySQL CLI as root and do:

mysql> CREATE DATABASE `radius`;
Query OK, 1 row affected (0.03 sec)
mysql> GRANT ALL PRIVILEGES ON `radius`.* to ‘radius’@’localhost’ IDENTIFIED BY ‘mysqlpassword’;
Query OK, 0 rows affected (0.03 sec)
mysql> USE radius;
Database changed

Then these tables needs to be created

CREATE TABLE `nas` (
`id` int(10) NOT NULL auto_increment,
`nasname` varchar(128) NOT NULL,
`shortname` varchar(32) default NULL,
`type` varchar(30) default ‘other’,
`ports` int(5) default NULL,
`secret` varchar(60) NOT NULL default ‘secret’,
`community` varchar(50) default NULL,
`description` varchar(200) default ‘RADIUS Client’,
PRIMARY KEY (`id`),
KEY `nasname` (`nasname`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `radacct` (
`RadAcctId` bigint(21) NOT NULL auto_increment,
`AcctSessionId` varchar(32) NOT NULL default ”,
`AcctUniqueId` varchar(32) NOT NULL default ”,
`UserName` varchar(64) NOT NULL default ”,
`Realm` varchar(64) default ”,
`NASIPAddress` varchar(15) NOT NULL default ”,
`NASPortId` varchar(15) default NULL,
`NASPortType` varchar(32) default NULL,
`AcctStartTime` datetime NOT NULL default ‘0000-00-00 00:00:00’,
`AcctStopTime` datetime NOT NULL default ‘0000-00-00 00:00:00’,
`AcctSessionTime` int(12) default NULL,
`AcctAuthentic` varchar(32) default NULL,
`ConnectInfo_start` varchar(50) default NULL,
`ConnectInfo_stop` varchar(50) default NULL,
`AcctInputOctets` bigint(20) default NULL,
`AcctOutputOctets` bigint(20) default NULL,
`CalledStationId` varchar(50) NOT NULL default ”,
`CallingStationId` varchar(50) NOT NULL default ”,
`AcctTerminateCause` varchar(32) NOT NULL default ”,
`ServiceType` varchar(32) default NULL,
`FramedProtocol` varchar(32) default NULL,
`FramedIPAddress` varchar(15) NOT NULL default ”,
`AcctStartDelay` int(12) default NULL,
`AcctStopDelay` int(12) default NULL,
`XAscendSessionSvrKey` varchar(10) default NULL,
PRIMARY KEY (`RadAcctId`),
KEY `UserName` (`UserName`),
KEY `FramedIPAddress` (`FramedIPAddress`),
KEY `AcctSessionId` (`AcctSessionId`),
KEY `AcctUniqueId` (`AcctUniqueId`),
KEY `AcctStartTime` (`AcctStartTime`),
KEY `AcctStopTime` (`AcctStopTime`),
KEY `NASIPAddress` (`NASIPAddress`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `radcheck` (
`id` int(11) unsigned NOT NULL auto_increment,
`UserName` varchar(64) NOT NULL default ”,
`Attribute` varchar(32) NOT NULL default ”,
`op` char(2) NOT NULL default ‘==’,
`Value` varchar(253) NOT NULL default ”,
PRIMARY KEY (`id`),
KEY `UserName` (`UserName`(32))
) ENGINE=MyISAM AUTO_INCREMENT=374 DEFAULT CHARSET=latin1;

CREATE TABLE `radgroupcheck` (
`id` int(11) unsigned NOT NULL auto_increment,
`GroupName` varchar(64) NOT NULL default ”,
`Attribute` varchar(32) NOT NULL default ”,
`op` char(2) NOT NULL default ‘==’,
`Value` varchar(253) NOT NULL default ”,
PRIMARY KEY (`id`),
KEY `GroupName` (`GroupName`(32))
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `radgroupreply` (
`id` int(11) unsigned NOT NULL auto_increment,
`GroupName` varchar(64) NOT NULL default ”,
`Attribute` varchar(32) NOT NULL default ”,
`op` char(2) NOT NULL default ‘=’,
`Value` varchar(253) NOT NULL default ”,
PRIMARY KEY (`id`),
KEY `GroupName` (`GroupName`(32))
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;

CREATE TABLE `radippool` (
`id` int(11) unsigned NOT NULL auto_increment,
`pool_name` varchar(30) NOT NULL,
`FramedIPAddress` varchar(15) NOT NULL default ”,
`NASIPAddress` varchar(15) NOT NULL default ”,
`CalledStationId` varchar(30) NOT NULL,
`CallingStationID` varchar(30) NOT NULL,
`expiry_time` datetime NOT NULL default ‘0000-00-00 00:00:00’,
`username` varchar(64) NOT NULL default ”,
`pool_key` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `radpostauth` (
`id` int(11) NOT NULL auto_increment,
`user` varchar(64) NOT NULL default ”,
`pass` varchar(64) NOT NULL default ”,
`reply` varchar(32) NOT NULL default ”,
`date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `radreply` (
`id` int(11) unsigned NOT NULL auto_increment,
`UserName` varchar(64) NOT NULL default ”,
`Attribute` varchar(32) NOT NULL default ”,
`op` char(2) NOT NULL default ‘=’,
`Value` varchar(253) NOT NULL default ”,
PRIMARY KEY (`id`),
KEY `UserName` (`UserName`(32))
) ENGINE=MyISAM AUTO_INCREMENT=1974 DEFAULT CHARSET=latin1;

CREATE TABLE `usergroup` (
`UserName` varchar(64) NOT NULL default ”,
`GroupName` varchar(64) NOT NULL default ”,
`priority` int(11) NOT NULL default ‘1’,
KEY `UserName` (`UserName`(32))
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

# This is the replies that every user that belongs to the group ‘clients‘ will receive
INSERT INTO `radgroupreply` VALUES (1,’clients’,’Service-Type’,’:=’,’Framed-User’)
INSERT INTO `radgroupreply` VALUES (2,’clients’,’Framed-Protocol’,’:=’,’PPP’)
INSERT INTO `radgroupreply` VALUES (3,’clients’,’Framed-Routing’,’:=’,’Broadcast-Listen’),
INSERT INTO `radgroupreply` VALUES (4,’clients,’Framed-MTU’,’:=’,’1420′)
INSERT INTO `radgroupreply` VALUES (5,’clients’,’Framed-Compression’,’:=’,’Van-Jacobsen-TCP-IP’);

# This creates a user with username ‘testuser’ and password ‘testpassword’
INSERT INTO `radcheck` VALUES (1,’testuser’,’User-Password’,’:=’,’testpassword’);

# This assigns 10.0.1.2 to the user ‘testuser’
INSERT INTO `radreply` VALUES (1,’testuser’,’Framed-IP-Address’,’:=’,’10.0.1.2′)

# This adds the user ‘testuser’ to the group ‘clients’, then it will receive all correct attributes from radgroupreply.
INSERT INTO `usergroup` VALUES (‘testuser’,’clients’,1);

Now just restart MySQL and Freeradius and the only thing left to do is to configure the VPDN client.

This is configured on a Cisco 850 series router with the WAN link on FastEthernet 4

Client#conf t
Client(config)#ip domain name mydsl.com
Client(config)#l2tp-class l2tpclass1
Client(config)#pseudowire-class pwclass1
Client(config-pw-class)#encapsulation l2tpv2
Client(config-pw-class)#protocol l2tpv2 l2tpclass1
Client(config-pw-class)#ip local interface FastEthernet4
Client(config-pw-class)#interface virtual-ppp 1
Client(config-if)#ip address negotiated
Client(config-if)#ip tcp adjust-mss 1420
Client(config-if)#ip policy route-map clear-df
Client(config-if)#ppp authentication pap chap callin
Client(config-if)#ppp chap hostname testuser@mydsl.com
Client(config-if)#ppp chap password testpassword
Client(config-if)#ppp pap sent-username testuser@mydsl.com password testpassword
Client(config-if)#ppp ipcp route default
Client(config-if)#pseudowire 10.0.0.1 10 pw-class pwclass1

That should be about it! Don’t be afraid of the comment box!

Log Commands on your Cisco Routers and Switches with Tacacs+ on Linux

Sunday, November 9th, 2008

I setup command logging with Tacacs+ on Linux this week. Let me show you how easy it is!

I am (as always) doing this with Ubuntu linux and so I just have to apt-get the packages I need.

espen@server:~$ sudo apt-get install tac-plus
Password:
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following NEW packages will be installed:
tac-plus
0 upgraded, 1 newly installed, 0 to remove and 104 not upgraded.
Need to get 105kB of archives.
After unpacking 324kB of additional disk space will be used.
Get:1 http://no.archive.ubuntu.com feisty/universe tac-plus 1:4.0.4.alpha-14 [105kB]
Fetched 105kB in 0s (331kB/s)
Selecting previously deselected package tac-plus.
(Reading database … 227388 files and directories currently installed.)
Unpacking tac-plus (from …/tac-plus_1%3a4.0.4.alpha-14_i386.deb) …
Adding system user `tacacs’ (UID 64005) …
Adding new group `tacacs’ (GID 64005) …
Adding new user `tacacs’ (UID 64005) with group `tacacs’ …
Not creating home directory `/home/tacacs’.
Setting up tac-plus (4.0.4.alpha-14) …
Starting Tacacs+ server: tac_plus.

Wow, that was quick… The tacacs+ server is already running!
But wait, we have to configure it just a bit.

For this article I will just focus on the logging part (accounting), but I will continue to write about authentication and authorization to fully comply fully with AAA.

Now, open up /etc/tac-plus/tacacs.conf in your favourite editor, mine is vim.
Be sure to uncomment and set the key, set the accounting file and you should be ready to roll.

key = tercesym
accounting file = /var/log/tac-plus/account

Just restart the tacacs daemon:

espen@server:/etc/tac-plus# sudo /etc/init.d/tac-plus restart
Restarting Tacacs+ server: tac_plus.
espen@server:/etc/tac-plus#

Now to configure this on your cisco equipment, please follow the steps in this article first.
Then to make sure the Cisco IOS Switch or Router will notify your tacacs deamon of accounting events, this is the configuration you need.

Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#aaa accounting delay-start
Router(config)#aaa accounting exec default start-stop group tacacs+
Router(config)#aaa accounting commands 15 default start-stop group tacacs+
Router(config)#tacacs-server host 10.0.0.50 key tercesym

! If you want the Router to source from a specific IP address
Router(config)#ip tacacs source-interface Loopback 1

Router(config)#end
Router#

Now you can verify accounting

Router#show accounting

Active Accounted actions on tty1, User admin Priv 1
Task ID 17, EXEC Accounting record, 00:16:58 Elapsed
task_id=17 start_time=1226261207 timezone=CET service=shell

There is one accounting session running, and you can also check the server to see if any accounting records are recorded.

espen@server:~# sudo tail /var/log/tac-plus/account
Sun Nov 9 21:26:58 2008 10.0.0.98 admin tty1 10.0.0.5 stop task_id=26 start_time=1226262225 timezone=CET service=shell priv-lvl=15 cmd=show accounting

Perfect, now there will be no doubt about who dropped that ‘no router bgp’ command on your Cisco Router!

IPv4 and IPv6 Access Control Lists In Cisco IOS

Wednesday, November 5th, 2008

Do you feel like you are comfortable with writing ACLs? This will be refreshing!

I’ll get to IPv6 in the bottom of this, it might prove extremely useful to understand the concept at first.

What are Access Control Lists?
ACLs are simple rulesets, they can be used to filter network traffic, routing updates, matching packets and a lot of different uses. The most common and basic usage must be to restrict network traffic to your router by applying it on the vty lines.

The access control lists have numbers and can also have text as identifiers, each number or string represents a specific access control list.

There are several “classes” of Access Control Lists, the most common ones are

  1. IP Standard Access List
    List numbers 1-99, can only define source or destination, not source and destination.
  2. IP Extended Access List
    List numbers 100-199, can define both source and destination as well as port and protocol numbers.

Okay, I understand…. but how do I configure it?

A IP standard access control list with two entries is configured like this

Router#conf t
Router(config)#ip access-list standard 5
Router(config-std-nacl)#5 permit 192.168.0.0 0.0.0.255
Router(config-std-nacl)#10 permit 192.168.1.0 0.0.0.255

To apply this inbound on an interface, just use

Router#conf t
Router(config)#int te 1/1
Router(config-if)#ip access-group 5 in

The alternative way to define an access list number 5 with two entries is

Router#conf t
Router(config)#access-list 5 permit 192.168.0.0 0.0.0.255
Router(config)#access-list 5 permit 192.168.1.0 0.0.0.255
Router(config)#

To apply this one inbound on a line interface

Router#conf t
Router(config)#line vty 1
Router(config-line)#access-class 5 in

Nice, now I have a lot of ACLs configured in my network for all the IPv4 traffic, mon ami! But IPv6 traffic still seems to keep flowing right through, thought you said you were supposed to make sense of all this in the end?

Yeah, I know I promised that and as long as you understand the IPv4 basics you will understand IPv6 pretty well. You will need to understand basic IPv6 subnetting theory to be able to filter subnets (obviously), if anyone wants me to write an article about it, just comment about it and I will get on to it ASAP. When you learn that, you will see that IPv6 access control lists are pretty much the same as for IPv4.

Anyways, I take for granted you understand IPv6 subnetting by now so I will just get right on to the configuration, an example for an IPv6 access list in Cisco IOS follows

Router#conf t
Router(config)#ipv6 access-list myfirewall
Router(config-ipv6-acl)#permit 3ffe:200::/32 any
Router(config-ipv6-acl)#permit 3ffe:100::/32 any

To verify the access-lists just look at this

Router#show access-lists myfirewall
IPv6 access list myfirewall
permit ipv6 3FFE:200::/32 any sequence 10
permit ipv6 3FFE:201::/32 any sequence 20
Router#

To apply this IPv6 Access Control List to an interface, just do as follows

Router#conf t
Router(config)#int te 1/1
Router(config-if)#ipv6 traffic-filter myfirewall in

To apply this IPv6 access control list to a line

Router#conf t
Router(config)#line vty 1
Router(config-line)#ipv6 access-class myfirewall in

Configuring IPv6 BGP Peering Sessions on Cisco IOS

Sunday, November 2nd, 2008

The future is closer than you think, are you ready?

Here is a little tutorial on configuring IPv6 BGP peering sessions on Cisco IOS.

First set the IP address on the interface, if this is a private peering session you can use a small network from your own PA block, on an exchange this IP address should be assigned by the exchange administrators.

Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#int fa 0/0
Router(config-if)#ipv6 address 3ffe:1234:1234::1/64

Then, it can be an idea to nullroute the prefix you are going to announce, I think it is good practice because it will also effectively blackhole traffic destined to unexisting networks. This will be announced into BGP with the redistribute static configuration item.

Router#conf t
Router(config)#ipv6 route 3ffe:2000::/32 null 0

Now we create a prefix list that permits only this network, this is very important to avoid leaks of prefixes to your peers. This prefix list is going to be applied outbound on to the BGP peering.

Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#ipv6 prefix-list announceAS65001-ipv6 seq 5 permit 3FFE:2000::/32
! better safe than sorry
Router(config)#ipv6 prefix-list announceAS65001-ipv6 seq 5000 deny ::/0 le 128

Now we are ready to configure the BGP peering session, this is just a simple example and most of these commands can be applied to peer groups, so that each configuration gets easier.

Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#router bgp 65001
Router(config-router)#redistribute static
Router(config-router)#neighbor 3ffe:1234:1234::2 remote-as 65002
Router(config-router)#address-family ipv6 unicast
Router(config-router-af)#neighbor 3ffe:1234:1234::2 activate
Router(config-router-af)#neighbor 3ffe:1234:1234::2 soft-reconfiguration inbound
Router(config-router-af)#redistribute static
Router(config-router-af)#neighbor 3ffe:1234:1234::2 prefix-list announceAS65001-ipv6 out

This will redistribute the static nullroute we made earlier to the peer at 3ffe:1234:1324::2, and the peering session should be up by now.

I can verify it on the other end:

Router2#sh ip bgp ipv6 unicast
BGP table version is 8, local router ID is 10.0.0.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
*> 3FFE:2000::/32 3FFE:1234:1234::1
0 0 65001 ?

As you can see, the network 3ffe:2000::/32 is now announced on this peering session, the route is sourced from AS65001. You can also get this on the summary:

Router2#sh ip bgp ipv6 unicast summary
BGP router identifier 10.0.0.1, local AS number 65002
BGP table version is 8, main routing table version 8
1 network entries using 152 bytes of memory
1 path entries using 76 bytes of memory
2/1 BGP path/bestpath attribute entries using 248 bytes of memory
1 BGP AS-PATH entries using 24 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 500 total bytes of memory
BGP activity 2/1 prefixes, 4/3 paths, scan interval 60 secs

Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
3FFE:1234:1234::1
4 65001 26 23 8 0 0 00:05:54 1

If you want to see the prefixes announced to a peer or received from a peer. (This requires soft reconfiguration inbound configured on the peering session, neighbor 3ffe:1234:1234::2 soft-reconfiguration inbound in configuration.

Router2#sh ip bgp ipv6 unicast neighbors 3ffe:1234:1234::1 received-routes
BGP table version is 8, local router ID is 10.0.0.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
*> 3FFE:2000::/32 3FFE:1234:1234::1
0 0 65001 ?

Total number of prefixes 1

The prefix 3ffe:2000::/32 is received from 3ffe:1234:1234::1.

Router#sh ip bgp ipv6 unicast neighbors 3ffe:1234:1234::2 advertised-routes
BGP table version is 3, local router ID is 10.0.0.2
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
*> 3FFE:2000::/32 :: 0 32768 ?

Total number of prefixes 1

Voila, a better understanding and some real life examples of IPv6 BGP peering in Cisco IOS.

Basic Cisco Configuration Steps for Absolute Beginners

Friday, October 24th, 2008

Thought I would write a post for those of you who are not yet evil Cisco Jedi masters with a black belt containing a network swizz army knife, with a sharp firewall slicer and a port opener.

Setting the hostname

Switch#configure terminal
Switch(config)#hostname SuperSwitch
SuperSwitch(config)#

As you can see, the hostname change happened immediately.

Configuring a VLAN with an IP on two ports
To get the list of interfaces on the Switch

Switch# show interfaces description

To create a new Layer 2 VLAN on the switch

! configure terminal enters configuration mode
Switch#configure terminal
! vlan 10 creates the layer 2 vlan on the switch, this is actually
! usually done by the switch when the first port is set to access vlan 10
Switch(config)#vlan 10
Switch(config-vlan)#exit
! Enter interface configuration
Switch(config)#interface GigabitEthernet1/0/1
! Sets the port to mode access
Switch(config-if)#switchport mode access
! Sets the port to access vlan 10
Switch(config-if)#switchport access vlan 10
! No shutdown turns on the port
Switch(config-if)#no shutdown
!
! Enter interface configuration of the second port and do all the same
! You can enter more interfaces at the time with the range command
! for example: interface range GigabitEthernet1/0/1 – 2
! In that way you wouldn’t have to do this twice.
Switch(config-if)#interface GigabitEthernet1/0/2
Switch(config-if)#switchport mode access
Switch(config-if)#switchport access vlan 10
Switch(config-if)#no shutdown
Switch(config-if)#exit
!
! Now create the layer 3 interface on vlan 10
!
Switch(config)#interface vlan 10
!
! Sets the IP address 10.0.0.1 and unshuts the interface
Switch(config-if)#ip address 10.0.0.1 255.255.255.0
Switch(config-if)#no shutdown
Switch(config-if)#end
Switch#

The computers on port GigabitEthernet 1/0/1 and 1/0/2 should now be able to ping 10.0.0.1 when they are configured with those IP settings.

Configuring a trunk port
A trunk port is a port that can carry several VLANs in one port, it is done with 802.1q or ISL, the first one is mostly prefered because it is not proprietary so several vendors supports it.

To configure a trunk port, you will have to issue this configuration on the trunk port on both switches:

Switch#configure terminal
Switch(config)#interface GigabitEthernet 1/0/10
Switch(config-if)#switchport trunk encapsulation dot1q
Switch(config-if)#switchport mode trunk
Switch(config-if)#no shut
Switch(config-if)#end
Switch#

This will create a trunk, per default it will accept any vlan tags, so if you do not want the network you connected to access any of your private vlans you will need an access list of which VLAN tags to accept on this port.

switchport trunk allowed vlan 10

By issuing this command on the port, you will only allow vlan 10 to flow through it.

If you now want to give for example port 9 on the second switch access to that 10.0.0.1

Switch#configure terminal
Switch(config)#interface GigabitEthernet 1/0/9
Switch(config-if)#switchport mode access
Switch(config-if)#switchport access vlan 10
Switch(config-if)#no shutdown
Switch(config-if)#end
Switch#

This is how to setup basic vlans and trunking on Cisco.
Read my other posts for more advanced configuration examples!

syslog-ng | Cisco: Setting Up Remote Syslog To MySQL in Linux

Thursday, October 16th, 2008

We are all in the need of a good method of keeping track of our log messages.

It’s a good feeling to know that all the syslog messages from all the equipment I manage are safely deposited into a MySQL database which is backed up daily by our backup software.

First, syslog-ng
I use Ubuntu, so I can also use their practical package manager and run

apt-get install syslog-ng

Then whip up /etc/syslog-ng/syslog-ng.conf in your favourite editor and add this to the configuration.

source s_net {
udp(ip(10.0.0.58) port(514));
tcp(ip(10.0.0.58) port(51400));
};

The 10.0.0.58 should be the IP address that you want syslog-ng to listen on, it has to be bound up to the server that runs syslog-ng.

Also add this to make syslog-ng write to a special pipe:

destination d_mysql {
pipe(“/tmp/mysql.pipe”
template(“INSERT INTO logs (host, facility, priority, level, tag, date,
time, program, msg) VALUES ( ‘$HOST’, ‘$FACILITY’, ‘$PRIORITY’, ‘$LEVEL’,’$TAG’,
‘$YEAR-$MONTH-$DAY’, ‘$HOUR:$MIN:$SEC’, ‘$PROGRAM’, ‘$MSG’ );\n”) template-escape(yes));
};

And to make things that comes from s_net go to d_mysql to make the
messages from the cisco device go to mysql instead:

log {
source(s_net);
destination(d_mysql);
};

Make a pipe that syslog-ng can write to with this command:

mkfifo /tmp/mysql.pipe

MySQL
Almost ready for the Cisco configuration, just get the database up first.
Setup the MySQL database like this:

CREATE DATABASE syslog
USE syslog

CREATE TABLE logs (
host varchar(32) default NULL,
facility varchar(10) default NULL,
priority varchar(10) default NULL,
level varchar(10) default NULL,
tag varchar(10) default NULL,
date date default NULL,
time time default NULL,
program varchar(15) default NULL,
msg text,
seq int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (seq),
KEY host (host),
KEY seq (seq),
KEY program (program),
KEY time (time),
KEY date (date),
KEY priority (priority),
KEY facility (facility)
) TYPE=MyISAM;

# Also create the user, replace username and password
GRANT ALL PRIVILEGES ON syslog.* TO syslogng@localhost IDENTIFIED BY ‘mypassword’;

Run this command to pipe the queries to MySQL, preferably in a screen or make a script that can run it in the background.

mysql -u syslogng –password=mypassword syslog < /tmp/mysql.pipe

Restart the syslog-ng process now:

/etc/init.d/syslog-ng stop
/etc/init.d/syslog-ng start

Cisco Syslog Configuration
Now all you have to do on the cisco router is one simple command to make it log to the syslog database.

Router(config)# logging 10.0.0.58

This will make the Cisco Router send all logging output to the syslog-ng process on 10.0.0.58

I have made a simple PHP page that makes the syslog output more viewable, it is not very pretty – but it works.
I am sure anyone of you can improve it, if you do please send me the change and if it is generally usefull I will update the package here with your improvement and leave a credit for you in it!

You can download the package syslog-ng PHP page