0. Exam strategy
Format: MCQ and Multi-Select, 1% per question (about 17–18 questions), with partial marks for Multi-Select. Questions are scenario based: “A student set up the above network topology in the lab…”, followed by a topology drawing, a CLI configuration, and a question asking what works, what is logged, how many, or which commands are (NOT) needed. Almost every question is a lab situation, so know the labs’ topologies, addresses and expected results.
How Multi-Select is marked
So: treat each option as a separate True/False statement. Tick it only if you believe it is more likely true than false. A wrong tick costs only 1/n of the mark.
A method for “will this ping or connection work?” questions
- Write down the real source and destination IP. A router or switch pinging without
sourceuses its exit interface IP, not its loopback or VLAN IP. - Walk hop by hop. At every interface ask: is there an inbound ACL where the packet enters, and an outbound ACL where it leaves?
- In each ACL: go top-down, first match wins, then implicit deny. Check protocol, source, destination and which side the port operator is on.
- Repeat for the reply. Routers are stateless: a ping fails if either the request or the reply is dropped.
- Router-originated packets skip that router’s own outbound ACL. Inbound ACLs also filter packets to the router (pings to it, OSPF hellos, SSH).
- On Firepower/ASA: which interface does the packet enter, and what are the security levels? Is there an ACL on the ingress interface? Is the packet a reply to an existing connection (stateful)? Is it ICMP, which is not inspected by default?
- VRF: which routing table does the packet use? AAA: is the server unreachable (ERROR) or did it reject (FAIL)?
1. Access Control Lists (Lab 2.1a, 2.1b, notes 2.1)
An ACL is a sequential list of ACEs (access control entries). Each ACE has an action (permit or deny) and a test condition:
- Standard: matches the source IP only (Layer 3).
- Extended: matches protocol, source IP, destination IP, and source/destination port (L3 + L4), plus ICMP type.
| Type | Numbers | Named | Place it… | Why |
|---|---|---|---|---|
| Standard | 1–99, 1300–1999 | ip access-list standard NAME | near the destination | It only knows the source. Near the source it blocks that source from everything (over-filtering). |
| Extended | 100–199, 2000–2699 | ip access-list extended NAME | near the source | It can match the destination, so drop early and don’t waste bandwidth. |
Processing rules and direction
- ACEs are processed top to bottom. The first match wins and later ACEs are not checked. The order matters, so put more specific ACEs first.
- Implicit
deny anyat the end. It is not shown and not counted inshow access-lists; add an explicitdeny anyto see a match counter. - An ACL with only deny statements blocks everything, so add
permit any/permit ip any anyto allow the rest. - One ACL per interface, per direction, per protocol (IPv4/IPv6). A second
ip access-group … inreplaces the first.
2. An outbound ACL does not filter packets originated by the router itself (its own pings, OSPF hellos, syslog, NTP).
deny ip any any out still lets the router ping out, but forwarded traffic is dropped.Wildcard masks
0 bit = must match, 1 bit = ignore. For a subnet: wildcard = 255.255.255.255 − subnet mask.
| Need | Address + wildcard | Shortcut |
|---|---|---|
| one host 192.168.20.3 | 192.168.20.3 0.0.0.0 | host 192.168.20.3 (newer IOS: just the IP) |
| everything | 0.0.0.0 255.255.255.255 | any |
| /24 192.168.10.0 | 0.0.0.255 | |
| /27 209.165.200.224 (.224–.255) | 0.0.0.31 | |
| /30 10.1.1.0 | 0.0.0.3 | |
| /28 10.0.0.16 (.16–.31) | 0.0.0.15 | |
| /29 10.0.0.0 (.0–.7) | 0.0.0.7 | |
| 172.16.0.0/16 even addresses only | 172.16.0.0 0.0.255.254 | last bit must be 0 (notes p.13) |
255.255.255.0) matches something completely different. 0.0.0.32 ignores only a single bit, so it matches 2 addresses, not a /27. On the Firepower/ASA it is the opposite: ACLs use normal subnet masks (192.168.2.0 255.255.255.0).Syntax
Standard (numbered and named)
R1(config)# access-list 1 remark Allow DSW1 LANs ! optional comment R1(config)# access-list 1 permit 192.168.10.0 0.0.0.255 [log] R1(config)# interface g1/0/24 R1(config-if)# ip access-group 1 in ! in | out R1(config)# ip access-list standard BRANCH-OFFICE-POLICY R1(config-std-nacl)# permit host 192.168.20.3 R1(config-std-nacl)# permit 192.168.40.0 0.0.0.255
Extended
R1(config)# access-list 100 permit protocol src src-wild [op port] dst dst-wild [op port] [icmp-type] [log] [time-range name] DSW1(config)# access-list 100 permit tcp host 192.168.10.3 host 10.2.2.1 eq 22 log DSW1(config)# access-list 100 permit tcp 192.168.10.0 0.0.0.255 any eq 443 log R1(config)# access-list 110 permit icmp any 192.168.1.0 0.0.0.255 echo-reply ! no 'eq' for ICMP
- At minimum, an extended ACE needs protocol, source and destination. Protocols:
ip(all),tcp,udp,icmp,ospf, … - Port operators:
eq,neq,lt,gt,range a b. The operator belongs to the address it follows.tcp 10.1.1.0 0.0.0.255 eq www anymatches source port 80, which is wrong for browsing. - Port names:
www80,ftp21,telnet23,smtp25,domain53,tftp69 (UDP),ntp123 (UDP),snmp161 (UDP). Use numbers for the others (22, 443, …). - ICMP keywords:
echo(type 8),echo-reply(0),unreachable(3),time-exceeded(11). There is noeq. logproduces%SEC-6-IPACCESSLOGPmessages, which are severity 6. They won’t reach a syslog server set tologging trap 4.
Named ACLs, sequence numbers and editing
R1# show access-lists Extended IP access list WEB-POLICY 10 permit tcp 192.168.20.0 0.0.0.255 host 10.1.1.1 eq 443 (15 matches) 20 permit tcp 192.168.20.0 0.0.0.255 209.165.200.224 0.0.0.31 eq 443 R1(config)# ip access-list extended WEB-POLICY R1(config-ext-nacl)# no 20 ! delete one line R1(config-ext-nacl)# 15 permit icmp any any echo ! insert between 10 and 20 R1(config-ext-nacl)# deny ip any any ! no number → appended (last +10) R1(config)# ip access-list resequence WEB-POLICY 100 5 ! start 100, step 5 R1# clear access-list counters
- Newer IOS lets numbered ACLs be edited the same way (
ip access-list extended 100), and sequence numbers are inserted automatically (10, 20, 30…). - Trap:
no access-list 101 …in global mode deletes the entire numbered ACL. If an interface still references a deleted ACL, then depending on the IOS either everything passes or filtering continues. - Edits take effect immediately. You never need to re-apply
ip access-group. - Verify with
show access-lists [n|name](ACEs and match counts) andshow ip interface g1/0/24(“Inbound access list is 1”, “Outgoing access list is not set”).
Time-based and object group-based ACLs
R1(config)# time-range OFFICE R1(config-time-range)# periodic weekdays 8:00 to 18:00 ! or absolute start … end … R1(config)# access-list 101 permit tcp any host 192.168.1.10 eq www time-range OFFICE
show clock shows a leading * (not authoritative or not synced) or the wrong timezone, the ACE is active at the wrong times. Fix it with NTP plus clock timezone SGT 8. Outside the range the ACE is skipped, as if absent, and processing continues to the next ACE.router(config)# object-group network Inside_Eng router(config-network-group)# 10.0.0.0 /24 router(config)# object-group network Inside_Mktg router(config-network-group)# host 10.0.1.1 router(config)# object-group network Inside_Networks router(config-network-group)# group-object Inside_Eng ! nesting router(config-network-group)# group-object Inside_Mktg router(config)# object-group service Host_Services router(config-service-group)# tcp www router(config-service-group)# tcp 443 router(config)# access-list 100 permit object-group Host_Services object-group Inside_Networks any
Format: permit object-group SERVICE object-group SRC DST. The protocol comes from the service group. User, ICMP-type and Security object groups exist only on ASA firewalls.
Lab 2.1a / 2.1b walkthrough (memorise the expected results)
| Lab | ACL | Where | Expected results |
|---|---|---|---|
| 2.1a P3 | access-list 1 permit 192.168.10.0 0.0.0.255access-list 1 permit 192.168.30.0 0.0.0.255 | DSW2 G1/0/24 in (near destination) | PC-A→PC-B ✔; DSW1 extended ping src 192.168.30.1 ✔; DSW1 plain ping (src 10.1.1.1) ✘ |
| 2.1a P3 | BRANCH-OFFICE-POLICY: permit host 192.168.20.3, permit 192.168.40.0 0.0.0.255 | DSW1 VLAN 1 out | PC-B→PC-A ✔; DSW2 src VLAN1 192.168.20.1 ✘; DSW2 src Lo0 192.168.40.1 ✔ |
| 2.1a P4 | add 30 permit 209.165.200.224 0.0.0.31, 40 deny any | same, no re-apply needed | R1 extended ping src Lo0 → PC-A ✔ |
| 2.1b P3 | ACL 100: permit tcp host 192.168.10.3 host 10.2.2.1 eq 22 log, permit tcp 192.168.10.0 0.0.0.255 any eq 443 log | DSW1 VLAN 1 in (near source) | PC-A https R1 ✔; PC-A SSH 10.2.2.1 ✔; PC-A ping 10.2.2.1 ✘ (implicit deny) |
| 2.1b P3 | WEB-POLICY: 443 to host 10.1.1.1 and to 209.165.200.224 0.0.0.31 | DSW2 VLAN 1 in | PC-B https 209.165.200.225 ✔; https 10.1.1.1 ✔; https 209.165.201.1 ✘; ping PC-A ✘ |
| 2.1b P4 | 30 permit ip 192.168.10.0 0.0.0.255 192.168.20.0 0.0.0.255 (and the reverse on DSW2) | appended as line 30 | PC-A ↔ PC-B pings ✔ both ways |
The 2.1b servers are enabled with ip http server, ip http authentication local, username admin privilege 15 secret class, and SSH on DSW2 (ip domain name, crypto key generate rsa modulus 2048, line vty 0 4, login local, transport input ssh).
2. Cisco Firepower / ASA firewall (Lab 2.2)
Security levels and default policy
ciscoasa(config)# interface ethernet1/1 ciscoasa(config-if)# nameif outside ! level auto 0 ciscoasa(config-if)# security-level 0 ciscoasa(config-if)# ip address 23.1.2.3 255.255.255.0 ciscoasa(config)# interface ethernet1/3 ciscoasa(config-if)# nameif dmz ciscoasa(config-if)# security-level 50 ! MUST set — otherwise 0 ciscoasa(config-if)# ip address 192.168.2.254 255.255.255.0 ciscoasa(config)# interface vlan 1 ciscoasa(config-if)# no nameif inside ! names must be unique; 'inside' pre-used by VLAN 1 ciscoasa(config)# object network obj_any ciscoasa(config-network-object)# no nat (any,outside) dynamic interface ! remove default PAT
- Security levels run from 0 to 100.
nameif insidedefaults to 100; any other name defaults to 0. - Higher → lower: allowed by default, and return traffic is allowed statefully (the connection table,
show conn). - Lower → higher: denied unless an ACL on the ingress interface permits it.
- Same level: denied by default (needs
same-security-traffic permit inter-interface). - The firewall is stateful. Packets of an existing connection are not re-checked against interface ACLs.
- The default dynamic PAT on outside (
nat (any,outside) dynamic interface) makes inside hosts appear as 23.1.2.3. The lab removes it. - On the Firepower 1010 factory config, E1/1 is outside and the other ports belong to VLAN 1 “inside”. That is why “inside” must first be removed from
int vlan 1.
ciscoasa# show conn TCP outside 23.1.2.10:51544 dmz 192.168.2.100:80, idle 0:00:02, bytes 3150, flags UIO TCP inside 10.0.0.25:50112 dmz 192.168.2.100:80, idle 0:00:05, bytes 1830, flags UIO ! U = up, I = inbound data, O = outbound data. Only permitted traffic creates entries.
ASA ACLs (overriding the security levels)
ciscoasa(config)# access-list OUTSIDE_DMZ extended permit tcp any host 192.168.2.100 eq www ciscoasa(config)# access-group OUTSIDE_DMZ in interface outside
| IOS router ACL | Firepower/ASA ACL |
|---|---|
| wildcard mask (0.0.0.255) | subnet mask (255.255.255.0) |
ip access-group NAME in under the interface | global access-group NAME in interface IFNAME |
| stateless: return traffic needs its own permit | stateful: return traffic allowed automatically |
| no ACL = permit all | no ACL = security levels decide |
• An inbound ACL replaces the default “permit to lower levels” for that interface. Putting
permit … eq www inbound on inside stops inside users using SSH, HTTPS and DNS. Putting an ACL inbound on dmz stops the DMZ server from starting connections out.•
access-list … permit icmp any any inbound on outside, with no NAT, lets the Internet ping your inside hosts.ICMP and MPF inspection
ICMP is not inspected by default. An inside → outside ping sends the echo request out (higher → lower), but the echo-reply arrives on a lower-level interface with no matching state and is dropped. Browsing works because TCP/UDP is stateful by default. Two fixes:
! Fix 1 (lab Part 4): make ICMP stateful via the default MPF policy ciscoasa(config)# policy-map global_policy ciscoasa(config-pmap)# class inspection_default ciscoasa(config-pmap-c)# inspect icmp ! global_policy is already applied by default: service-policy global_policy global ! Fix 2: stateless ACL letting the replies back in ciscoasa(config)# access-list OUTSIDE extended permit icmp any any echo-reply ciscoasa(config)# access-group OUTSIDE in interface outside
icmp permit any outside controls ICMP to the firewall’s own interface, not through it. Inspection does not override security levels for new traffic: outside → DMZ pings still need an ACL.
Modular Policy Framework (MPF)
| Part | Purpose | Example |
|---|---|---|
| class-map | identify traffic | class-map WEB → match access-list WEB_ACL |
| policy-map | actions per class | policy-map P → class WEB → set connection … / inspect … |
| service-policy | activate it on an interface or globally | service-policy P interface outside / service-policy global_policy global |
An ACL used in match access-list only classifies; it doesn’t permit or deny. A service-policy has no in/out keyword, and an interface policy only affects traffic through that interface. There is only one global policy.
Reset
ciscoasa(config)# configure factory-default ! or ciscoasa# write erase ciscoasa# reload System config has been modified. Save? [Y]es / [N]o: N ! Y would save the running config back!
Traffic matrices (inside 100, dmz 50, outside 0, NAT removed)
| Traffic | No ACL, default | + inspect icmp | Outside ACL permit icmp any any (no inspect) |
|---|---|---|---|
| Inside → DMZ HTTP | ✔ | ✔ | ✔ |
| Inside → Internet HTTP | ✔ | ✔ | ✔ |
| Outside → DMZ HTTP | ✘ | ✘ | ✘ (ACL only permits ICMP) |
| Inside ping Internet | ✘ reply dropped | ✔ | ✔ reply permitted by ACL |
| Inside ping DMZ | ✘ | ✔ | ✘ reply enters dmz, no state |
| DMZ ping Internet | ✘ | ✔ | ✔ |
| Internet ping DMZ | ✘ | ✘ | ✔ |
| Internet ping Inside | ✘ | ✘ | ✔ (security hole!) |
| DMZ → Inside (any) | ✘ | ✘ | ✘ |
3. DoS overview (Topic 2)
| Attack | Type | What it exploits | Lab defence | Why an ACL fails |
|---|---|---|---|---|
| Smurf | volumetric (amplified) | ICMP echo to directed broadcast with spoofed victim source; replies flood the victim | no ip directed-broadcast, ACLs, hosts not replying to broadcast pings | (covered in Quiz 1) |
| TCP SYN flood | volumetric | TCP handshake: half-open (embryonic) connections fill the server backlog | MPF set connection embryonic-conn-max → TCP Intercept; server SYN cookies | it must permit TCP 80 from any; spoofed SYNs look legitimate |
| Slowloris | low-rate (one PC is enough) | HTTP needs the full request header; slow partial headers keep connections reserved | MPF set connection per-client-max (+ conn-max/timeouts) | the server must be reachable from the Internet |
4. TCP SYN flooding attack and defence (Lab 2.5)
- Normal handshake: SYN → SYN-ACK → ACK. After SYN-ACK the server holds a half-open / embryonic connection in the SYN-RECV state.
- The attacker (a scapy script,
sudo python tcpsynflood target-ip target-port) sends SYNs from spoofed sources and never ACKs. The backlog fills (the 512 default in the lab) and PC-A can’t connect. - If a spoofed IP is a live host, it replies RST and frees the slot, so attackers spoof unused addresses.
- Lab setup:
sudo systemctl start apache2andsudo sysctl -w net.ipv4.tcp_syncookies=0. Disabling SYN cookies makes the server vulnerable for the demo; with cookies the server keeps no state until the ACK. - Monitor with
ss -t -r state syn-recv | wc -l, which counts half-open connections.
ciscoasa(config)# access-list WEB extended permit tcp any host 192.168.2.100 eq www ciscoasa(config)# class-map WEB-CLASS ciscoasa(config-cmap)# match access-list WEB ciscoasa(config)# policy-map WEB-POLICY ciscoasa(config-pmap)# class WEB-CLASS ciscoasa(config-pmap-c)# set connection embryonic-conn-max 50 per-client-embryonic-max 5 ciscoasa(config-pmap-c)# set connection timeout embryonic 0:00:10 ! optional: free half-open faster (default 30 s) ciscoasa(config)# service-policy WEB-POLICY interface outside ciscoasa# show service-policy interface outside
per-client-embryonic-max alone is useless against random spoofed sources, because every packet is a “new client”. The policy must be on an interface the attack actually crosses: outside, dmz, or global, not inside. Embryonic limits do nothing against Slowloris.5. Slowloris attack and defence (Lab 2.6)
- Low-rate DoS: a small amount of crafted traffic from a single PC can bring the server down.
- It exploits HTTP: the server must receive the complete request header (ending in a blank line,
\r\n\r\n) before responding, and the connection stays reserved meanwhile. Slowloris opens many connections and sends partial headers very slowly. - Its connections are established (the handshake completes), not embryonic, and they are not idle (a header line every ~10 s).
- Tool:
slowhttptest -c <connections> -u http://x.x.x.x(install via ICT-WIFI, then disable Wi-Fi!).
set connection … | Meaning | Against Slowloris (one attacker) |
|---|---|---|
| per-client-max N | max simultaneous connections per source IP | Best: the attacker is capped, others unaffected |
| conn-max N | max total connections for the class | Protects the server, but the attacker fills all N, so legitimate users are still denied |
| embryonic-conn-max N | max half-open connections (then TCP Intercept) | No effect: connections are established |
| per-client-embryonic-max N | half-open per client | No effect |
| timeout idle hh:mm:ss | close idle connections | Usually ineffective: Slowloris keeps sending |
| random-sequence-number | randomises TCP ISNs | Unrelated |
per-client-max, slowhttptest’s own availability probe comes from the same attacker IP, which is already at its limit, so it is refused and reports service available: NO. Meanwhile PC-A browses normally. A distributed Slowloris (many bots, each under the per-client limit) would still need conn-max, timeouts or upstream protection.6. Out-of-Band management, VRF, jump host and SSH (Lab 3.1)
- In-band: management traffic flows over the same production LAN as user traffic. Convenient, but exposed to malicious users.
- Out-of-band (OoB): a separate, dedicated management network with no user traffic, only reachable by network engineers and administrators.
- Devices provide management ports next to the console port: Catalyst 9200L, 9300L and Firepower 1010 have one (Gi0/0 / Management1/1). The Catalyst 8200L has none, so it uses VRF (a management VRF).
- Other OoB devices: a serial console server (remote access to console ports), KVM over IP (servers), and server BMC/IPMI.
Virtual Routing and Forwarding (VRF)
A VRF creates separate routing tables, so traffic in one table never crosses into another. It logically divides one router into several. Interfaces not in a VRF stay in the global table.
R1(config)# vrf definition OOB R1(config-vrf)# address-family ipv4 R1(config)# interface g0/1/1 R1(config-if)# vrf forwarding OOB ! FIRST — this REMOVES any existing IP address R1(config-if)# ip address 172.16.99.1 255.255.255.0 R1# show ip route ! global table only — no OOB routes R1# show ip route vrf OOB ! OOB table R1# ping vrf OOB 172.16.99.10 ! plain ping uses global table → fails
vrf forwarding after the IP address wipes the IP (“IPv4 disabled and address(es) removed”). A host on the production side cannot ping the VRF interface; that is the whole point (lab step 2.2). There is no routing between VRFs unless route leaking is configured.Jump host (jump server / jump box)
- An intermediary that is the entry point from a less-secure zone to a more-secure zone (the OoB LAN).
- Pros: the attack surface shrinks to a single point of entry, which is easier to log, monitor and audit.
- Cons: it is an attractive target and a single point of failure, so it must be securely hardened.
- Typical design: a hardened Linux machine with SSH, in the DMZ, permitted to access the OoB LAN. It must not route between its two interfaces.
- OpenSSH shortcut:
ssh -J user@jumphost admin@device(ProxyJump).
Lab 3.1 setup and expected results
| Step | Test | Result |
|---|---|---|
| 1.5 / 1.7 | Laptop pings R1 G0/0/0, G0/0/1, and the jump VM’s 1st interface (LAN 2) | ✔ |
| 2.2 | Laptop pings R1 G0/1/1 (VRF) | ✘ not in the global table |
| 2.4 | R1# ping vrf OOB <VM 2nd int> | ✔ |
| 3.4 | Laptop SSH directly to R1 | ✘ the ACL allows only the OOB subnet |
| 3.5–3.7 | Laptop SSH to the jump server, then ping or SSH to R1 G0/1/1 from it | ✔ |
SSH configuration
Router(config)# hostname R1 ! required (key name = hostname.domain) R1(config)# ip domain-name netsec.lab ! required R1(config)# crypto key generate rsa modulus 2048 ! 2048/4096; ≥768 needed for SSHv2 R1(config)# ip ssh version 2 R1(config)# ip ssh authentication-retries 2 ! optional R1(config)# ip ssh time-out 60 ! optional R1(config)# username netadmin secret Adm1n#2217 R1(config)# ip access-list standard OOB-ONLY R1(config-std-nacl)# permit 172.16.99.0 0.0.0.255 R1(config)# line vty 0 15 R1(config-line)# login local R1(config-line)# transport input ssh ! Telnet refused R1(config-line)# access-class OOB-ONLY in vrf-also ! vrf-also: accept sessions arriving on VRF interfaces R1# show ip ssh ! version/settings R1# show ssh ! active sessions
- Without a non-default hostname: “% Please define a hostname other than Router.”
access-classfilters who may connect to the VTY lines. Withoutvrf-also, sessions arriving through a VRF interface are rejected.- Telnet sends usernames and passwords in clear text, so don’t use it.
7. Supermicro server, IPMI/BMC and Proxmox (Lab 3.1 Appendices A–C)
| What | Port | Address | Login |
|---|---|---|---|
| BMC / IPMI (OoB): power on/off, HTML5 remote console | IPMI port | http://10.0.0.1 (/24) | sitstudent / whiteboard |
| Proxmox VE web UI | LAN 1 (eno1 → vmbr0) | https://10.0.0.10:8006 | root / whiteboard |
| Laptop | — | any other 10.0.0.x/24, e.g. 10.0.0.100 (not .1 or .10) |
| Name | Physical port |
|---|---|
| eno1 | LAN 1 (vmbr0, 10.0.0.10 for Proxmox) |
| eno2 | LAN 2 |
| eno3np0 / eno4np2 | SFP 1 / SFP 2 |
| eno5 | LAN 3 |
| eno6 | LAN 4 |
| enxbe3af2b6059f | IPMI |
- A VM can only connect through a Linux bridge: pve → System → Network → Create → Linux Bridge, name (vmbr1) plus bridge port (eno2). Don’t enter IP addresses there. Click Apply Configuration, otherwise it stays pending.
- Attach it to the VM: VM → Hardware → Network Device → Edit → Bridge. In the lab: ens18 → vmbr1 → eno2 (LAN 2) and ens19 → vmbr2 → eno5 (LAN 3).
- VM IP addresses go in
/etc/netplan/50-cloud-init.yaml(create it withsudo netplan generateif missing), applied withsudo netplan apply. - Pre-configured VMs (gateway 10.0.0.254, DNS 8.8.8.8, user ubuntu): 100 Apache web server .11, 101 Bind9 DNS .12, 102 FreeRADIUS + TACACS (AAA) .13, 104 FTP+SMB file server .14.
- Storage: local (pve) holds ISO images and backups; local-lvm (pve) holds VM disks and CT volumes.
- VM power: Shutdown/Reboot = graceful (best practice). Pause keeps the RAM; Hibernate saves the RAM to disk; Stop and Reset are forced (not recommended). A broken VM is rolled back with Snapshots → Original-Image → Rollback.
- Shut down in this order: the VMs, then the Proxmox host (pve → Shutdown), or use BMC → Power → Graceful Shutdown.
8. AAA overview
| Question answered | Lab | |
|---|---|---|
| Authentication | Who are you? | 3.2: local, TACACS+, RADIUS |
| Authorization | What may you do? | 3.3: privilege levels, CLI views |
| Accounting | What did you do? | 3.4: exec and command logs |
9. AAA Part 1: Authentication (Lab 3.2)
Local passwords and login hardening
! Simple password, no username: everyone shares it, and it can't be used with SSH switch(config)# line vty 0 15 switch(config-line)# password love switch(config-line)# login ! Better: unique local users (required for SSH) switch(config)# username wendell secret odom switch(config-line)# login local
| Type | Created by | Strength |
|---|---|---|
| 0 | password x (clear text) | none |
| 7 | service password-encryption | weak, reversible, easily decoded |
| 5 | secret x (MD5, the default per the notes) | one-way hash |
| 8 | algorithm-type sha256 secret x | stronger (recommended) |
| 9 | algorithm-type scrypt secret x | stronger (recommended) |
R1(config)# login delay 3 ! slow brute force R1(config)# login block-for 120 attempts 3 within 60 ! 3 fails in 60 s → quiet mode 120 s (ALL remote logins blocked) R1(config)# ip access-list standard PERMIT-ADMIN R1(config-std-nacl)# permit 192.168.10.10 R1(config)# login quiet-mode access-class PERMIT-ADMIN ! hosts STILL ALLOWED during quiet mode R1(config)# login on-success log R1(config)# login on-failure log ! %SEC_LOGIN-4-LOGIN_FAILED (severity 4) R1# show login failures
Server-based AAA (TACACS+ / RADIUS)
Benefits: scalability and manageability (users are configured centrally, once) and fault tolerance (several servers). Still keep a local fallback.
R1(config)# aaa new-model ! 1. enable AAA R1(config)# tacacs server TACACSERVER ! 2. servers R1(config-server-tacacs)# address ipv4 192.168.1.11 R1(config-server-tacacs)# key TACACS-pa55w0rd ! must match the server's shared secret R1(config)# radius server RADIUSERVER R1(config-radius-server)# address ipv4 192.168.1.12 auth-port 1812 acct-port 1813 R1(config-radius-server)# key RADIUS-pa55w0rd R1(config)# username ADMIN secret Str0ngPa55w0rd ! local fallback R1(config)# aaa authentication login default group tacacs+ group radius local ! 3. method list ! custom list — must be APPLIED to a line to take effect R1(config)# aaa authentication login MY-LIST group tacacs+ local R1(config)# line vty 0 15 R1(config-line)# login authentication MY-LIST
| Method | Meaning |
|---|---|
local / local-case | local username DB (local-case = case-sensitive username) |
enable | enable password |
none | no authentication |
group radius / group tacacs+ | all configured RADIUS / TACACS+ servers |
group NAME | servers in aaa group server radius|tacacs+ NAME |
Default list: applied automatically to the console and VTY lines (unless a line uses a custom list). Custom list: only active where applied with login authentication NAME.
ERROR vs FAIL: the key to every fallback question
default group tacacs+ group radius local | TACACS+ user | RADIUS user | local user |
|---|---|---|---|
| Both servers up | ✔ | ✘ (TACACS+ FAIL) | ✘ |
| TACACS+ down, RADIUS up | ✘ | ✔ | ✘ (RADIUS FAIL) |
| Both down | ✘ | ✘ | ✔ |
List without local, both down | Nobody can log in, including on the console (locked out) | ||
Server setup
- TACACS.net (Windows,
C:\ProgramData\TACACS.net\config):tacplus.xml(listening IP, default 127.0.0.1, change it to the PC’s IP; port 49),clients.xml(authorized NAS IPs and shared secret),authentication.xml(users),authorization.xml(privilege level or view). Restart withsc stop TACACS.net/sc start TACACS.netand verify withnetstat -an. Logs are inC:\ProgramData\TACACS.net\Logs. - FreeRADIUS (Kali,
/etc/freeradius/3.0, aftersudo chmod o+rx /etc/freeradius):clients.conf(switch IP or block and secret),users(wendell Cleartext-Password := "odom"). Runsudo freeradius -X(debug) and test locally withradtest. Logs are under/var/log/freeradius. - Troubleshoot with Wireshark on the server: are the requests arriving, and are replies sent?
TACACS+ vs RADIUS
| TACACS+ | RADIUS | |
|---|---|---|
| Functionality | separates authentication, authorization and accounting (modular) | combines authentication and authorization; accounting separate |
| Standard | mostly Cisco | open / RFC |
| Transport | TCP 49 | UDP 1812 (auth), 1813 (acct) [legacy 1645/1646] |
| Security | entire packet body encrypted | only the password encrypted (username visible) |
| Command authorization | yes, per user or group | no |
| Command accounting | yes | no |
| Primary use | device administration | network access |
10. AAA Part 2: Authorization (Lab 3.3)
After authentication, give users no more access than necessary. Two models: rights assigned directly to users (privilege levels), or rights assigned to roles that users get (RBAC with CLI views).
Privilege levels
| Level | Meaning |
|---|---|
| 0 | only disable, enable, exit, help, logout |
| 1 | user EXEC (R1>), the default after login; limited, read-only commands such as show |
| 2–14 | custom: move commands into them |
| 15 | privileged EXEC (R1#, “enable mode”), full access |
R1(config)# privilege exec level 5 ping ! ping now needs level ≥5 (level-1 users LOSE it) R1(config)# enable secret level 5 cisco5 ! password to 'enable 5' R1(config)# privilege exec level 10 reload R1(config)# privilege exec reset ping ! back to default level R1(config)# username SUPPORT privilege 5 secret cisco5 ! land at level 5 after login R1> enable 5 R1# show privilege ! Current privilege level is 5
- A user can run commands at their level or lower. Lower-level commands are always available, which is the weakness that views solve.
- With AAA:
aaa authorization exec default group tacacs+ group radius localis required for the device to apply the privilege level or view returned by the server. Authorization only works when authentication is configured too. - FreeRADIUS AV-pair:
cisco-avpair = "shell:priv-lvl=5". TACACS.net:authorization.xml. - FYI: authorization on the console line also needs
aaa authorization console.
Role-based CLI views
- Root view creates views and superviews (like level 15):
enable viewplus the enable secret. - CLI view: a defined set of commands. Superview: a group of CLI views, not commands. A view can belong to several superviews.
- Requires
aaa new-model. At most 15 views. - Always available in any view:
enable,exit,show parser.
R1(config)# aaa new-model R1# enable view ! root view (enable secret) R1(config)# parser view SHOWVIEW R1(config-view)# secret cisco R1(config-view)# commands exec include show version R1(config)# parser view CONFIGVIEW R1(config-view)# secret cisco10 R1(config-view)# commands exec include configure terminal R1(config-view)# commands configure include interface R1(config)# parser view ADMIN superview R1(config-view)# secret cisco2 R1(config-view)# view SHOWVIEW R1(config-view)# view CONFIGVIEW R1(config)# username Wendell view ADMIN secret odom ! land in ADMIN at login R1> enable view SHOWVIEW R1# show parser view ! Current view is 'SHOWVIEW' R1# show parser view all ! (root) lists views; * = superview
| Keyword | Effect |
|---|---|
include | add the command; other views may also include it |
include-exclusive | add it here and prevent any other view from including it |
exclude | users of this view cannot use it |
all | wildcard: every command starting with the keyword (e.g. include all show) |
RADIUS view assignment: Service-Type = NAS-Prompt-User, cisco-avpair = "shell:cli-view-name=ADMIN". TACACS+ authorization is a separate REQUEST/RESPONSE pair after authentication; RADIUS includes it in the Access-Accept.
11. AAA Part 3: Accounting (Lab 3.4)
R1(config)# aaa accounting exec default start-stop group tacacs+ group radius R1(config)# aaa accounting commands 15 default stop-only group tacacs+
- exec accounting records the user’s EXEC session: a Start when it begins and a Stop when it ends (start-stop). stop-only sends only the Stop.
- commands 15 records each command of privilege level 15 (stop-only: sent when the command runs). This is TACACS+ only; RADIUS can’t do it. Level-1 commands need
commands 1. - Fallback works like authentication: with TACACS+ down, exec records go to RADIUS (lab steps 1.9–1.12), but command records are lost unless there is another TACACS+ server.
- RADIUS accounting uses separate Accounting-Request/Response messages on UDP 1813, after authentication and authorization.
<102> 2017-11-09 03:57:41 [192.168.1.200:43972] NAS_IP=192.168.1.200 Port=tty1 rem_addr=192.168.1.3
User=wendell Flags=Start task_id=25 timezone=UTC service=shell
<102> 2017-11-09 03:57:47 … User=wendell Flags=Stop task_id=25 service=shell priv-lvl=15 cmd=show running-config <cr>
<102> 2017-11-09 03:58:04 … User=wendell Flags=Stop task_id=25 service=shell disc-cause=1 elapsed_time=22
| Field | Meaning |
|---|---|
| NAS_IP | the network device (AAA client) that sent the record |
| rem_addr | the remote user’s IP (where they logged in from) |
| Port=tty1 | the line used (a VTY session) |
| task_id | the same value for every record of one session |
| Flags=Start/Stop | session start/stop, or a command record (Stop with cmd=) |
| elapsed_time | session length in seconds |
12. NTP (Lab 3.5)
Synchronised time is essential for correlating logs across devices and for time-based ACLs. NTP is defined in RFC 5905, runs over UDP 123, and has three modes: client/server, peer (symmetric) and broadcast.
Round-trip delay δ = (T4 − T1) − (T3 − T2), i.e. total time minus the server’s processing time.
2. T1 10:00:00.000, T2 10:00:05.300, T3 10:00:05.400, T4 10:00:00.500 → θ = (5.3 + 4.9)/2 = +5.1 s; δ = 0.5 − 0.1 = 0.4 s.
3. T1 11:00:00.100, T2 .180, T3 .200, T4 .300 → θ = (0.08 − 0.10)/2 = −10 ms (client ahead); δ = 0.2 − 0.02 = 180 ms.
| Timestamp field | NTP request | NTP reply |
|---|---|---|
| Origin | ignore | T1 |
| Receive | ignore | T2 |
| Transmit | T1 | T3 |
| Reference | when the sender’s system clock was last updated (T4 is recorded locally by the client) | |
Stratum
- Stratum = how many NTP hops from the authoritative source (stratum 0: atomic or GPS clock). Higher stratum means lower accuracy.
- A device synchronised to stratum n becomes stratum n+1, and automatically acts as an NTP server for others. Stratum 16 means unsynchronised.
ntp master 5: the router uses its own clock as an authoritative source at stratum 5 (the default when no number is given is 8). Use it only if no reliable external source is reachable. Its clients become stratum 6.- NTP pool (e.g.
0.sg.pool.ntp.org) needs DNS:ip name-server 8.8.8.8. Enterprises sync hierarchically: edge router ← pool, then switches ← edge router.
Configuration and verification
R1# clock set 9:39:00 05 july 2013 ! privileged EXEC R1(config)# clock timezone SGT 8 R1(config)# ntp master 5 ! server using own clock R2(config)# ntp server 10.1.1.1 [prefer] ! client S1(config)# ntp peer 172.16.0.2 ! symmetric R1(config-if)# ntp broadcast / S1(config-if)# ntp broadcast client ! interface mode R2# show ntp associations address ref clock st when poll reach delay offset disp *~10.1.1.1 127.127.1.1 5 11 64 177 1.312 -0.018 4.298 * sys.peer, # selected, + candidate, - outlyer, x falseticker, ~ configured R2# show ntp status ! Clock is synchronized, stratum 6, reference is 10.1.1.1
st is the server’s stratum; 127.127.1.1 as the reference clock means the server uses its own clock (ntp master). * means this is the peer we are synchronised to.
Securing NTP
! server R1(config)# ntp authentication-key 1 md5 NTP-pa55w0rd R1(config)# ntp trusted-key 1 ! client S1(config)# ntp authentication-key 1 md5 NTP-pa55w0rd ! same key (case-sensitive!) S1(config)# ntp authenticate ! enforce authentication S1(config)# ntp trusted-key 1 S1(config)# ntp server 10.0.0.1 key 1
The server attaches an MD5 digest computed with the pre-shared key; the client recomputes it and accepts the message only if they match. This protects against an attacker injecting false NTP replies.
ntp access-group … | Allows the listed hosts to… |
|---|---|
| peer | sync this device and be served (accept replies and respond) |
| serve | be served, plus NTP control queries |
| serve-only | only be served (respond to their requests) |
| query-only | only control queries |
Also: ntp logging. Over OoB: ntp server vrf Mgmt-vrf 10.0.0.1 (router/switch) or ntp server 10.0.0.1 source management (firewall).
13. Syslog (Lab 3.5)
- Syslog: RFC 5424. Transport: UDP 514 by default (RFC 5426), or securely TLS over TCP 6514 (RFC 5425, may not be supported by Cisco).
- Logs can go to syslog, SNMP or NetFlow collectors, or to a SIEM for central correlation and alerting.
| # | Keyword | Meaning | Group |
|---|---|---|---|
| 0 | emergencies | system unusable | Severe |
| 1 | alerts | immediate action needed | |
| 2 | critical | critical conditions | Impactful |
| 3 | errors | error conditions | |
| 4 | warnings | warning conditions | |
| 5 | notifications | normal but significant | Normal |
| 6 | informational | informational | |
| 7 | debugging | debug messages | Debug |
logging trap N sends levels 0 to N, i.e. that level and everything more severe.R2(config)# logging host 172.16.2.3 ! or: logging 172.16.2.3 R2(config)# logging trap warnings ! = logging trap 4 (default trap level: informational/6) R2(config)# logging buffered ! store in RAM → show logging R2(config)# no logging console ! console only R2(config)# logging monitor ! VTY sessions … R2# terminal monitor ! … each SSH session must also enter this R2(config-line)# logging synchronous ! don't interrupt typing R2(config)# service timestamps log datetime msec ! per-destination levels: logging console|monitor|buffered|trap <level>
Message anatomy
*Dec 18 17:10:15.079: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/0, changed state to down └ timestamp └ facility └ severity └ mnemonic └ description
A leading * means the clock is not authoritative (not NTP-synchronised). In the lab, after NTP sync the messages show Jul 5 09:57:47.162 with no asterisk.
%LINK-3-UPDOWN (3), %LINEPROTO-5-UPDOWN (5), %LINK-5-CHANGED (5) and %LINEPROTO-5-UPDOWN (5).trap 4 (warnings) → 1 message · trap 5 (notifications) → 4 · trap 6 (informational) → 4 · trap 2 → 0.
Other useful severities:
%SEC_LOGIN-4-LOGIN_FAILED (4), %SEC_LOGIN-5-LOGIN_SUCCESS (5), %SEC-6-IPACCESSLOGP (6, ACL log), %SYS-5-CONFIG_I (5).R2# show logging
Console logging: level debugging, 47 messages logged
Monitor logging: level debugging, 0 messages logged
Buffer logging: level debugging, 47 messages logged
Trap logging: level informational, 49 message lines logged
Logging to 172.16.2.3 (udp port 514, audit disabled, link up), 6 message lines logged
Setting the level too severe (e.g. 0–1) misses important events. Setting it too verbose (7) floods the server, network and storage and buries real alerts. Servers: Tftpd64, Kiwi Syslog (free for 5 clients).
14. Cisco Flexible NetFlow (Lab 3.6)
- NetFlow keeps statistics about IP packets passing through a device in a NetFlow cache and exports them to a collector (e.g. ManageEngine NetFlow Analyzer). It exports no payload.
- A flow is a unidirectional sequence of packets sharing the same key fields. Classic key fields (7): source IP, destination IP, source port, destination port, L3 protocol, ToS byte (DSCP), input interface.
- Variants: Flexible NetFlow / v9 (RFC 3954), IPFIX (RFC 7011), the IETF standard based on v9, sFlow (RFC 3176) (sampling), and JFlow (Juniper).
The four configuration steps
! 1. flow record — match = KEY fields, collect = non-key statistics (or use predefined: netflow ipv4 original-input) R1(config)# flow record my-record R1(config-flow-record)# match ipv4 source address R1(config-flow-record)# match ipv4 destination address R1(config-flow-record)# match transport source-port R1(config-flow-record)# match transport destination-port R1(config-flow-record)# match ipv4 protocol R1(config-flow-record)# match ipv4 tos R1(config-flow-record)# match interface input R1(config-flow-record)# collect counter bytes R1(config-flow-record)# collect counter packets ! 2. flow exporter — where to send R1(config)# flow exporter my-exporter R1(config-flow-exporter)# destination 192.168.1.50 R1(config-flow-exporter)# transport udp 9999 ! must match the collector's port R1(config-flow-exporter)# source lo0 ! optional; default = exit interface IP R1(config-flow-exporter)# export-protocol netflow-v9 ! 3. flow monitor — record + exporter + cache R1(config)# flow monitor my-monitor R1(config-flow-monitor)# record my-record R1(config-flow-monitor)# exporter my-exporter R1(config-flow-monitor)# cache timeout active 30 ! 4. apply to the interface R1(config)# interface g0/0/1 R1(config-if)# ip flow monitor my-monitor input ! and/or output
- Verify with
show flow record NAME,show flow exporter NAME,show flow monitor [NAME] [cache|statistics]. - Active timeout exports long-lived flows periodically (default 1800 s; 30 s in the lab). Inactive timeout exports a flow once it has been idle for that time (15 s). The cache in the lab held 200,000 entries.
- Wireshark on the collector:
ip.src == 192.168.1.1 && udp.dstport == 9999 && !icmp. Withsource lo0, the source becomes 10.0.0.1.
Reading the cache
IPV4 SOURCE ADDRESS: 192.168.1.75 IPV4 DESTINATION ADDRESS: 10.0.0.1 TRNS SOURCE PORT: 0 TRNS DESTINATION PORT: 2048 INTERFACE INPUT: Gi0/0/1 IP PROTOCOL: 1 counter bytes: 12024 counter packets: 8
- Protocol 1 = ICMP, 6 = TCP, 17 = UDP.
- For ICMP the “destination port” holds type × 256 + code: echo request (8,0) = 2048, echo-reply (0,0) = 0.
- 12024 / 8 = 1503 bytes per packet = 1475 (ping -l) + 8 (ICMP) + 20 (IP).
Security use: a SYN flood shows as huge numbers of tiny 1–2 packet flows to :80 from many sources. Slowloris shows as many long-lived, low-byte flows from one source. Smurf shows as an echo-reply flood toward the victim. Combine with syslog in a SIEM for correlation.
15. Cheat sheet
Numbers to know
| Item | Value |
|---|---|
| Standard / extended ACL numbers | 1–99, 1300–1999 / 100–199, 2000–2699 |
| TACACS+ | TCP 49 |
| RADIUS auth / acct | UDP 1812 / 1813 |
| NTP | UDP 123 |
| Syslog / secure syslog | UDP 514 / TLS-TCP 6514 |
| SSH / Telnet / HTTP / HTTPS / DNS / TFTP | TCP 22 / TCP 23 / TCP 80 / TCP 443 / 53 / UDP 69 |
| IP protocol numbers | ICMP 1, TCP 6, UDP 17, OSPF 89 |
| ICMP types | echo-reply 0, unreachable 3, echo 8, time-exceeded 11 |
| ASA default levels | inside 100, other names 0 (DMZ set to 50 in the lab) |
| SYN backlog in the lab | 512 SYN-RECV |
| Supermicro | BMC 10.0.0.1 (IPMI port) · Proxmox https://10.0.0.10:8006 (LAN 1) |
| Privilege levels | 0 (5 cmds), 1 user, 2–14 custom, 15 privileged |
| Max CLI views | 15 |
| NetFlow ICMP echo “port” | 2048 (8×256+0) |
Top exam traps (read before the quiz)
- A standard ACL near the source over-filters. Place standard ACLs near the destination and extended ACLs near the source.
- The implicit deny is not counted. Add an explicit
deny anyto see matches. - A router pinging without
sourceuses its exit interface IP. - An outbound ACL doesn’t filter router-originated traffic. An inbound ACL does filter traffic to the router, including OSPF hellos.
- A ping fails if the reply is blocked. Routers are stateless.
eq portafter the source means the source port.- There is no
eqfor ICMP types. no access-list N …deletes the whole numbered ACL. Useip access-list … / no 20.- A second
ip access-group … inreplaces the first. - Edits to an applied ACL take effect immediately.
- Time-based ACLs use the router clock, so you need NTP and the timezone.
- ASA ACLs use subnet masks and
access-group NAME in interface IF. - ASA: no ACL means security levels decide; an inbound ACL replaces “permit to lower” on that interface.
- ASA: ICMP is not inspected by default. Add
inspect icmpin global_policy/inspection_default, or an echo-reply ACL. - ASA:
nameifother than “inside” means security level 0. Equal levels can’t talk by default. - ASA: stateful, so return traffic of allowed connections is never checked against interface ACLs.
write erasethenreload: answer N to “Save?”.- An ACL can’t stop a SYN flood or Slowloris aimed at a public server.
- SYN flood →
embryonic-conn-max(TCP Intercept). Slowloris →per-client-max. per-client-embryonic-maxdoesn’t help against random spoofed sources.conn-maxalone lets one attacker hog all slots.- The service-policy must be on an interface the attack crosses. A class-map ACL only classifies.
- slowhttptest says “unavailable” because its own probe is limited, while PC-A works.
vrf forwardingremoves the IP address. Useping vrf/show ip route vrf.access-class … inwithoutvrf-alsorejects VTY sessions from VRF interfaces.- SSH needs a hostname plus a domain-name, RSA ≥ 768 bits (2048 recommended),
login localandtransport input ssh. - Jump host: single entry point and easy auditing, but an attractive target and single point of failure. It must be hardened and must not route.
- BMC on the IPMI port at 10.0.0.1. Proxmox on LAN 1 at 10.0.0.10:8006. LAN 3 = eno5.
- Linux bridge: no IPs in the dialog; click Apply Configuration. Use
netplan applyin the VM. - AAA falls back on ERROR only, never on FAIL. Always end the list with
local. - The default method list covers console and VTY. A custom list must be applied with
login authentication. - TACACS.net listens on 127.0.0.1 by default. Fix it in tacplus.xml; clients go in clients.xml.
- FreeRADIUS silently ignores unknown clients (which counts as an ERROR, so fallback happens).
- Type 7 passwords are reversible.
secret= MD5 (5); sha256 = 8; scrypt = 9. - Quiet mode blocks all remote logins. The quiet-mode ACL lists the hosts that are still allowed.
- Moving a command up a privilege level removes it from the lower levels.
- Exec authorization (
aaa authorization exec) is needed for server-assigned privilege levels or views. - Views: always
enable,exit,show parser. Superviews hold views, not commands. include-exclusive blocks other views. - Command accounting is TACACS+ only.
commands 15logs only level-15 commands. - NTP: θ = ((T2−T1)+(T3−T4))/2 and δ = (T4−T1)−(T3−T2). The client is one stratum above its server.
- NTP auth keys are case-sensitive. The client needs
ntp authenticate+ trusted-key +server … key n. logging trap Nsends 0..N. The SSH session needsterminal monitor.*on a timestamp means not synced.- NetFlow flows are unidirectional and counted by key fields. ICMP echo = 2048. The exporter port must match the collector.