Securing the device itself: lines and password types, AAA with TACACS+ vs RADIUS, IPv4/IPv6 ACLs (standard, extended, named, time-based), uRPF strict and loose, Control Plane Policing (CoPP), and IPv6 First-Hop Security — RA Guard, DHCPv6 Guard, ND Inspection, Source Guard, binding table.

3.1  Securing device access — lines, passwords, SSH

The first hardening step is the management plane: who can log in and how. ENARSI assumes you know what to disable and how to enforce SSH-only access with strong password storage.

Lines & what they protect

Line Used for Hardening tip
console (con 0) Out-of-band serial Set login local, exec-timeout 5 0
aux 0 Modem/aux port Disable: no exec or transport input none
vty 0 4 (or 0 15) Inbound SSH/Telnet transport input ssh, ACL access-class, AAA login

Password storage types — pick the strongest

Type Algorithm Use it?
0 Plaintext Never — immediately auto-promoted with service password-encryption
7 Reversible Vigenère-style No — trivial to crack
5 MD5 hash Legacy; avoid for new accounts
8 PBKDF2 + SHA-256 Yes
9 scrypt Yes — strongest available on IOS
! Strong baseline
R1(config)# service password-encryption
R1(config)# username admin privilege 15 algorithm-type scrypt secret CiscoENARSI!
R1(config)# enable algorithm-type scrypt secret EnableSecret!

! SSH only on vty
R1(config)# ip domain name lab.local
R1(config)# crypto key generate rsa modulus 2048
R1(config)# ip ssh version 2
R1(config)# line vty 0 15
R1(config-line)# transport input ssh
R1(config-line)# login local
R1(config-line)# exec-timeout 5 0
R1(config-line)# access-class MGMT_VTY in

access-class on vty applies a numbered/named standard ACL to inbound SSH/Telnet only — far more efficient than putting an ACL on every interface.

3.2  AAA — TACACS+ vs RADIUS

What AAA stands for

  • AuthenticationWho are you? (verify identity)
  • AuthorizationWhat are you allowed to do? (commands, services)
  • AccountingWhat did you do? (audit logs)

TACACS+ vs RADIUS — the table you must memorize

Aspect TACACS+ RADIUS
Origin Cisco proprietary IETF (RFC 2865)
Transport / port TCP / 49 UDP / 1812 auth, UDP / 1813 accounting
Encryption Encrypts the entire payload Encrypts only the password field
AAA architecture Modular — A, A, A independent Combines authentication + authorization in the access-accept
Per-command authorization Yes — granular Limited (vendor-specific)
Best fit Device admin (network admin login) Network access (802.1X, dot1x, VPN)

SSH

Network Admin SSH user

Cisco Router AAA client aaa new-model

TACACS+ Server TCP / 49 full payload encrypted

RADIUS Server UDP / 1812 + 1813 password-only encryption

device admin login 802.1X / VPN access

AAA configuration template

R1(config)# aaa new-model
R1(config)# username fallback privilege 15 algorithm-type scrypt secret Backup!2026

! Define server groups
R1(config)# tacacs server TAC1
R1(config-server-tacacs)# address ipv4 10.0.0.10
R1(config-server-tacacs)# key 7 SuperSecretTAC

R1(config)# aaa group server tacacs+ TAC_GROUP
R1(config-sg-tacacs+)# server name TAC1

! Method lists
R1(config)# aaa authentication login default group TAC_GROUP local
R1(config)# aaa authentication enable default group TAC_GROUP enable
R1(config)# aaa authorization exec default group TAC_GROUP local if-authenticated
R1(config)# aaa authorization commands 15 default group TAC_GROUP local
R1(config)# aaa accounting exec default start-stop group TAC_GROUP
R1(config)# aaa accounting commands 15 default start-stop group TAC_GROUP

R1# test aaa group TAC_GROUP admin Cisco123! new-code

Always include the local fallback (local) as the last method. If TACACS+ is unreachable and the only method is group TAC_GROUP, you lock yourself out.

3.3  IPv4 & IPv6 access control lists

ACL types — what matches what

Type Numbers Matches on
Standard 1-99, 1300-1999 Source IP only
Extended 100-199, 2000-2699 Source/dest IP, protocol, ports, TCP flags, ToS, ICMP type
Named ip access-list standard NAME / extended NAME Same as numbered, but editable per-line
Time-based Reference a time-range object Activates only during a configured window
Reflexive Created with reflect/evaluate Permits return traffic of sessions started inside
IPv6 ACL ipv6 access-list NAME Always named & extended-style

Wildcard mask — the inverse of a subnet mask

  • 0 in the wildcard = MUST match; 1 = don’t care.
  • 10.1.1.0 0.0.0.255 ↔ matches the entire 10.1.1.0/24.
  • host 10.1.1.5 shorthand for 10.1.1.5 0.0.0.0.
  • any shorthand for 0.0.0.0 255.255.255.255.

Reading rules

  1. Top-down, first match wins.
  2. Implicit deny any at the end of every ACL — nothing falls through to permit.
  3. Apply with ip access-group NAME { in | out } or ipv6 traffic-filter.
  4. Place extended ACLs near the source (drop traffic early); standard ACLs near the destination (so they don’t accidentally block legitimate traffic upstream).

Examples

! Named extended IPv4 ACL: allow only HR (10.10.0.0/16) to reach DB server
R1(config)# ip access-list extended FROM_HR
R1(config-ext-nacl)# permit tcp 10.10.0.0 0.0.255.255 host 10.20.0.5 eq 1433
R1(config-ext-nacl)# deny ip any host 10.20.0.5 log
R1(config-ext-nacl)# permit ip any any
R1(config)# interface Gi0/1
R1(config-if)# ip access-group FROM_HR in

! Time-based: SSH allowed only during business hours
R1(config)# time-range BIZ_HOURS
R1(config-time-range)# periodic weekdays 8:00 to 18:00
R1(config)# ip access-list extended VTY_IN
R1(config-ext-nacl)# permit tcp any any eq 22 time-range BIZ_HOURS

! IPv6 ACL: deny rogue prefix, permit ICMPv6 ND, permit established
R1(config)# ipv6 access-list V6_GUARD
R1(config-ipv6-acl)# deny ipv6 2001:DB8:DEAD::/48 any log
R1(config-ipv6-acl)# permit icmp any any nd-na
R1(config-ipv6-acl)# permit icmp any any nd-ns
R1(config-ipv6-acl)# permit tcp any any established
R1(config-ipv6-acl)# permit ipv6 any any
R1(config)# interface Gi0/0
R1(config-if)# ipv6 traffic-filter V6_GUARD in

IPv6 ACL gotcha: there is an implicit permit for ICMPv6 Neighbor Solicitation/Advertisement only with the built-in end of the list (permit icmp any any nd-na and nd-ns are appended automatically before the implicit deny). However, if you add an explicit deny before the end, you can break ND. Always permit ND messages explicitly when you write a tight v6 ACL.

3.4  Unicast Reverse Path Forwarding (uRPF)

uRPF mitigates spoofed source addresses. When a packet arrives, the router checks: does the FIB have a route to that source? If not, drop. uRPF requires CEF.

Strict vs Loose

Strict mode Loose mode
Test FIB has a route AND the route’s outgoing interface = the receiving interface FIB has a route to the source on ANY interface
When to use Symmetric routing (single-homed customer edge) Asymmetric routing (multihomed ISP edge)
Risk Drops legitimate asymmetric traffic Doesn’t catch spoofing within prefixes you actually have a route for
Command ip verify unicast source reachable-via rx ip verify unicast source reachable-via any

Attacker spoofs src 10.1.1.1

Router (uRPF) FIB lookup of src Strict: same iface? Mismatch → DROP

Internal Net 10.1.1.0/24 via Gi0/1

in Gi0/0 would have used Gi0/1
! Enable CEF (required) then turn on uRPF in strict mode on the user-facing interface
R1(config)# ip cef
R1(config)# interface Gi0/0
R1(config-if)# ip verify unicast source reachable-via rx allow-default

! Loose mode at an asymmetric ISP edge
R1(config-if)# ip verify unicast source reachable-via any

The allow-default keyword permits the source to match the default route 0.0.0.0/0 — useful so that legitimate Internet sources don’t get dropped on a stub router that has only a default route.

3.5  Control Plane Policing (CoPP)

The control plane is the route processor itself: BGP/OSPF/EIGRP packets, ARP, ICMP echo to the router, SSH/SNMP/NetFlow management, NTP, etc. A flood of these can melt the CPU even if the data plane is fine. CoPP applies a QoS policy to traffic destined for the route processor, classifying it and policing each class to a known rate.

The four CoPP class buckets

Class Examples Typical action
Critical Routing protocols (OSPF, EIGRP, BGP), HSRP/VRRP/GLBP High rate / no drop
Important SSH, SNMP, NTP, TACACS+/RADIUS Medium rate / police
Normal ICMP echo to the router, traceroute Low rate / police hard
Undesirable Telnet from outside, anything unauthorized Drop

Critical OSPF, BGP, HSRP

Important SSH, SNMP, NTP

Normal ICMP echo, trace

Undesirable Telnet from WAN

CoPP service-policy control-plane input

Route Processor protected CPU

CoPP configuration steps

  1. Define ACLs that match each class of traffic.
  2. Create class-maps that reference those ACLs.
  3. Build a policy-map binding each class to a policer.
  4. Apply the policy with control-planeservice-policy input NAME.
! Step 1 – ACLs
R1(config)# ip access-list extended COPP_CRITICAL
R1(config-ext-nacl)# permit ospf any any
R1(config-ext-nacl)# permit eigrp any any
R1(config-ext-nacl)# permit tcp any any eq bgp
R1(config-ext-nacl)# permit tcp any eq bgp any

R1(config)# ip access-list extended COPP_IMPORTANT
R1(config-ext-nacl)# permit tcp any any eq 22
R1(config-ext-nacl)# permit udp any any eq snmp
R1(config-ext-nacl)# permit udp any any eq ntp

R1(config)# ip access-list extended COPP_NORMAL
R1(config-ext-nacl)# permit icmp any any echo
R1(config-ext-nacl)# permit icmp any any echo-reply
R1(config-ext-nacl)# permit icmp any any ttl-exceeded

R1(config)# ip access-list extended COPP_UNDESIRABLE
R1(config-ext-nacl)# permit tcp any any eq telnet

! Step 2 – class-maps
R1(config)# class-map match-any CRITICAL
R1(config-cmap)# match access-group name COPP_CRITICAL
R1(config)# class-map match-any IMPORTANT
R1(config-cmap)# match access-group name COPP_IMPORTANT
R1(config)# class-map match-any NORMAL
R1(config-cmap)# match access-group name COPP_NORMAL
R1(config)# class-map match-any UNDESIRABLE
R1(config-cmap)# match access-group name COPP_UNDESIRABLE

! Step 3 – policy-map
R1(config)# policy-map COPP_POLICY
R1(config-pmap)# class CRITICAL
R1(config-pmap-c)# police 8000000 conform-action transmit exceed-action transmit
R1(config-pmap)# class IMPORTANT
R1(config-pmap-c)# police 1000000 conform-action transmit exceed-action drop
R1(config-pmap)# class NORMAL
R1(config-pmap-c)# police 100000 conform-action transmit exceed-action drop
R1(config-pmap)# class UNDESIRABLE
R1(config-pmap-c)# drop

! Step 4 – apply
R1(config)# control-plane
R1(config-cp)# service-policy input COPP_POLICY

R1# show policy-map control-plane

CoPP best practice: never put a class-default with drop at the end — if you forget to permit something legitimate (like your own SSH session) you’ll lock yourself out. Test with conform-action transmit exceed-action transmit first, monitor counters, then tighten.

3.6  IPv6 First-Hop Security (FHS)

IPv6 hosts auto-configure with SLAAC using router advertisements (RAs). That’s a juicy attack surface: any rogue device on a VLAN can advertise itself as the gateway. FHS is a family of L2 features that lock down the first hop.

The five FHS pillars

Feature What it stops Where applied
RA Guard Rogue Router Advertisements (fake gateway, MITM) L2 access ports facing hosts — block RAs
DHCPv6 Guard Rogue DHCPv6 server replies / advertisements L2 ports that are NOT trusted DHCPv6 servers
ND Inspection Spoofed Neighbor Solicitations / Advertisements (cache poisoning) VLAN-wide; needs IPv6 snooping policy
IPv6 Source Guard Hosts spoofing an IPv6 source address that isn’t theirs L2 access port; uses binding table
Binding Table Foundation for ND Inspection & Source Guard — the trusted IPv6/MAC/port database Switch global; populated by snooping

Real Router trusted RA source

Rogue Host sends fake RA

Access Switch RA Guard, DHCPv6 Guard, ND Inspection, Source Guard

Hosts SLAAC / DHCPv6 protected

RA permitted

RA blocked

Configuration template — modern (snooping policy) syntax

! Build a binding table for the VLAN
SW(config)# ipv6 neighbor binding vlan 10
SW(config)# ipv6 snooping policy SNOOP_HOST
SW(config-ipv6-snooping)# security-level guard
SW(config-ipv6-snooping)# device-role node
SW(config-ipv6-snooping)# protocol ndp
SW(config-ipv6-snooping)# protocol dhcp

! RA Guard policy — block RAs on host ports
SW(config)# ipv6 nd raguard policy RA_HOSTS
SW(config-nd-raguard)# device-role host

! DHCPv6 Guard policy — block server replies on host ports
SW(config)# ipv6 dhcp guard policy DHCPv6_HOSTS
SW(config-dhcp-guard)# device-role client

! Apply on a host-facing access port
SW(config)# interface Gi1/0/5
SW(config-if)# switchport mode access
SW(config-if)# switchport access vlan 10
SW(config-if)# ipv6 snooping attach-policy SNOOP_HOST
SW(config-if)# ipv6 nd raguard attach-policy RA_HOSTS
SW(config-if)# ipv6 dhcp guard attach-policy DHCPv6_HOSTS
SW(config-if)# ipv6 source-guard attach-policy

! Trusted uplink to real router
SW(config)# ipv6 nd raguard policy RA_TRUSTED
SW(config-nd-raguard)# device-role router
SW(config)# interface Gi1/0/24
SW(config-if)# ipv6 nd raguard attach-policy RA_TRUSTED

Verification

SW# show ipv6 neighbor binding
SW# show ipv6 snooping policies
SW# show ipv6 nd raguard policy RA_HOSTS
SW# show ipv6 dhcp guard policy DHCPv6_HOSTS
SW# show ipv6 source-guard policy

Hands-on labs (7)

Lab 1 — Harden device access (SSHv2 only, scrypt, vty ACL)
R1(config)# hostname R1
R1(config)# ip domain name lab.local
R1(config)# crypto key generate rsa modulus 2048

R1(config)# service password-encryption
R1(config)# username admin privilege 15 algorithm-type scrypt secret CiscoENARSI!
R1(config)# enable algorithm-type scrypt secret EnableSecret!

R1(config)# ip access-list standard MGMT_VTY
R1(config-std-nacl)# permit 10.10.0.0 0.0.255.255
R1(config-std-nacl)# deny any log

R1(config)# ip ssh version 2
R1(config)# ip ssh time-out 60
R1(config)# ip ssh authentication-retries 3

R1(config)# line con 0
R1(config-line)# login local
R1(config-line)# exec-timeout 5 0
R1(config)# line aux 0
R1(config-line)# no exec
R1(config)# line vty 0 15
R1(config-line)# transport input ssh
R1(config-line)# login local
R1(config-line)# access-class MGMT_VTY in
R1(config-line)# exec-timeout 5 0

R1# show ip ssh
R1# show running-config | section vty

Lab 2 — AAA with TACACS+ for device admin and local fallback
R1(config)# aaa new-model
R1(config)# username fallback privilege 15 algorithm-type scrypt secret Backup!2026

R1(config)# tacacs server TAC1
R1(config-server-tacacs)# address ipv4 10.0.0.10
R1(config-server-tacacs)# key Cisco-TAC-Secret
R1(config-server-tacacs)# single-connection

R1(config)# aaa group server tacacs+ TAC_GROUP
R1(config-sg-tacacs+)# server name TAC1

R1(config)# aaa authentication login VTY_AUTH group TAC_GROUP local
R1(config)# aaa authentication enable default group TAC_GROUP enable
R1(config)# aaa authorization exec VTY_EXEC group TAC_GROUP local if-authenticated
R1(config)# aaa authorization commands 15 VTY_CMD group TAC_GROUP local
R1(config)# aaa accounting commands 15 default start-stop group TAC_GROUP

R1(config)# line vty 0 15
R1(config-line)# login authentication VTY_AUTH
R1(config-line)# authorization exec VTY_EXEC
R1(config-line)# authorization commands 15 VTY_CMD

R1# test aaa group TAC_GROUP admin Cisco123! new-code
R1# debug aaa authentication
R1# debug tacacs

Lab 3 — Time-based extended IPv4 ACL on the WAN edge
R1(config)# time-range BIZ_HOURS
R1(config-time-range)# periodic weekdays 8:00 to 18:00

R1(config)# ip access-list extended WAN_IN
R1(config-ext-nacl)# remark RFC1918 anti-spoof
R1(config-ext-nacl)# deny ip 10.0.0.0 0.255.255.255 any
R1(config-ext-nacl)# deny ip 172.16.0.0 0.15.255.255 any
R1(config-ext-nacl)# deny ip 192.168.0.0 0.0.255.255 any
R1(config-ext-nacl)# permit tcp any host 198.51.100.10 eq 443
R1(config-ext-nacl)# permit tcp any host 198.51.100.20 eq 22 time-range BIZ_HOURS
R1(config-ext-nacl)# deny ip any any log

R1(config)# interface GigabitEthernet0/0
R1(config-if)# ip access-group WAN_IN in

R1# show ip access-lists WAN_IN
R1# show time-range

Lab 4 — uRPF strict at customer edge, loose at multihomed ISP edge
! Stub customer edge (single uplink) – strict mode
CE(config)# ip cef
CE(config)# interface GigabitEthernet0/1
CE(config-if)# description LAN
CE(config-if)# ip verify unicast source reachable-via rx allow-default

! Multihomed PE (asymmetric) – loose mode
PE(config)# ip cef
PE(config)# interface GigabitEthernet0/0
PE(config-if)# description To ISP-A
PE(config-if)# ip verify unicast source reachable-via any
PE(config)# interface GigabitEthernet0/1
PE(config-if)# description To ISP-B
PE(config-if)# ip verify unicast source reachable-via any

PE# show cef interface gig0/0 | include RPF
PE# show ip traffic | include RPF

Lab 5 — Full CoPP policy with four classes
R1(config)# ip access-list extended COPP_CRITICAL
R1(config-ext-nacl)# permit ospf any any
R1(config-ext-nacl)# permit eigrp any any
R1(config-ext-nacl)# permit tcp any any eq bgp
R1(config-ext-nacl)# permit tcp any eq bgp any
R1(config-ext-nacl)# permit udp any any eq 1985 ! HSRPv1

R1(config)# ip access-list extended COPP_IMPORTANT
R1(config-ext-nacl)# permit tcp 10.10.0.0 0.0.255.255 any eq 22
R1(config-ext-nacl)# permit udp host 10.10.10.10 any eq snmp
R1(config-ext-nacl)# permit udp any any eq ntp

R1(config)# ip access-list extended COPP_NORMAL
R1(config-ext-nacl)# permit icmp any any echo
R1(config-ext-nacl)# permit icmp any any echo-reply
R1(config-ext-nacl)# permit icmp any any ttl-exceeded

R1(config)# ip access-list extended COPP_BAD
R1(config-ext-nacl)# permit tcp any any eq telnet
R1(config-ext-nacl)# permit tcp any any eq 6667

R1(config)# class-map match-any CRITICAL
R1(config-cmap)# match access-group name COPP_CRITICAL
R1(config)# class-map match-any IMPORTANT
R1(config-cmap)# match access-group name COPP_IMPORTANT
R1(config)# class-map match-any NORMAL
R1(config-cmap)# match access-group name COPP_NORMAL
R1(config)# class-map match-any BAD
R1(config-cmap)# match access-group name COPP_BAD

R1(config)# policy-map COPP
R1(config-pmap)# class CRITICAL
R1(config-pmap-c)# police 8000000 conform-action transmit exceed-action transmit
R1(config-pmap)# class IMPORTANT
R1(config-pmap-c)# police 1000000 conform-action transmit exceed-action drop
R1(config-pmap)# class NORMAL
R1(config-pmap-c)# police 100000 conform-action transmit exceed-action drop
R1(config-pmap)# class BAD
R1(config-pmap-c)# drop

R1(config)# control-plane
R1(config-cp)# service-policy input COPP

R1# show policy-map control-plane
R1# show policy-map control-plane input class CRITICAL

Lab 6 — IPv6 First-Hop Security on a host VLAN
SW(config)# ipv6 unicast-routing

SW(config)# ipv6 neighbor binding vlan 10
SW(config)# ipv6 snooping policy SNOOP_HOST
SW(config-ipv6-snooping)# security-level guard
SW(config-ipv6-snooping)# device-role node
SW(config-ipv6-snooping)# protocol ndp
SW(config-ipv6-snooping)# protocol dhcp

SW(config)# ipv6 nd raguard policy RA_HOSTS
SW(config-nd-raguard)# device-role host
SW(config)# ipv6 nd raguard policy RA_TRUSTED
SW(config-nd-raguard)# device-role router

SW(config)# ipv6 dhcp guard policy DHCPv6_HOSTS
SW(config-dhcp-guard)# device-role client

SW(config)# interface range Gi1/0/1 – 23
SW(config-if-range)# switchport mode access
SW(config-if-range)# switchport access vlan 10
SW(config-if-range)# ipv6 snooping attach-policy SNOOP_HOST
SW(config-if-range)# ipv6 nd raguard attach-policy RA_HOSTS
SW(config-if-range)# ipv6 dhcp guard attach-policy DHCPv6_HOSTS
SW(config-if-range)# ipv6 source-guard attach-policy

SW(config)# interface Gi1/0/24
SW(config-if)# description Uplink to L3 router
SW(config-if)# ipv6 nd raguard attach-policy RA_TRUSTED

SW# show ipv6 neighbor binding
SW# show ipv6 snooping counters interface Gi1/0/5

Lab 7 — IPv6 ACL with explicit Neighbor Discovery permit
R1(config)# ipv6 access-list V6_GUARD
R1(config-ipv6-acl)# remark Permit ND so SLAAC keeps working
R1(config-ipv6-acl)# permit icmp any any nd-na
R1(config-ipv6-acl)# permit icmp any any nd-ns
R1(config-ipv6-acl)# permit icmp any any router-advertisement
R1(config-ipv6-acl)# permit icmp any any router-solicitation
R1(config-ipv6-acl)# remark Block known-bad prefix
R1(config-ipv6-acl)# deny ipv6 2001:DB8:DEAD::/48 any log
R1(config-ipv6-acl)# remark Permit established TCP
R1(config-ipv6-acl)# permit tcp any any established
R1(config-ipv6-acl)# permit ipv6 any any

R1(config)# interface GigabitEthernet0/0
R1(config-if)# ipv6 traffic-filter V6_GUARD in

R1# show ipv6 access-list V6_GUARD
R1# show ipv6 interface Gi0/0 | include filter

Check Your Understanding

Twenty-five questions on this section. Each answer is explained as you go.

1. 

Which password algorithm-type produces the strongest hash on Cisco IOS?

2. 

To restrict SSH to a specific subnet, you should apply…

3. 

TACACS+ uses which transport and port?

4. 

RADIUS authentication and accounting use which UDP ports?

5. 

Which is true about TACACS+ vs RADIUS?

6. 

To avoid being locked out when AAA servers are unreachable, the AAA method list should…

7. 

Which AAA component answers “What did the user do?”

8. 

Standard IPv4 ACLs match on…

9. 

The wildcard 10.1.1.0 0.0.0.255 matches…

10. 

ACL placement guidance — standard ACLs should be placed…

11. 

Every ACL ends with…

12. 

To attach an IPv6 ACL to an interface you use…

13. 

uRPF requires which feature to be enabled?

14. 

uRPF strict mode drops a packet when…

15. 

uRPF loose mode is the right choice for…

16. 

Where do you apply a CoPP service-policy?

17. 

Which class typically holds OSPF, BGP, EIGRP, HSRP, and VRRP traffic in a CoPP design?

18. 

A safe first iteration of CoPP uses…

19. 

RA Guard's primary job is to…

20. 

DHCPv6 Guard policy with device-role client is applied to…

21. 

The IPv6 binding table records…

22. 

IPv6 Source Guard validates traffic against…

23. 

When writing a tight IPv6 ACL, you must EXPLICITLY permit…

24. 

Which command best validates that AAA is reaching a TACACS+ server?

25. 

The strict mode uRPF command is…

1 out of 1