Network Security Hardening

25 min In Progress

Learning Objectives

  • Apply password policy commands that survive a config audit
  • Write and test an ACL rule — standard vs extended
  • Identify the minimum WiFi security standard and why WEP/TKIP fail

Password Policies on Cisco IOS

There are two critical differences most beginners miss: 1. enable secret vs enable password — secret uses MD5+ hashing; password is reversible with a simple Cisco tool. Always use secret. 2. service password-encryption only encrypts type-7 (weak, reversible). It hides passwords from shoulder-surfing, not from a real attacker. Pair it with proper secret commands, never rely on it alone. login block-for is the key lockout command — it rate-limits failed attempts before a brute-force can get anywhere.

This is Cisco IOS syntax shown as a Python string — study the commands, then practice them in Packet Tracer.
password_policy_config = '''
service password-encryption
enable secret MyStrongPass!2026

username admin privilege 15 secret AnotherStrong!2026

security passwords min-length 10
login block-for 120 attempts 3 within 60

line vty 0 4
 transport input ssh
 login local
'''

print('Password hardening config:')
for line in password_policy_config.strip().splitlines():
    print(f'  {line}')

ACLs — The Network Bouncer

Access Control Lists filter traffic on a router interface. Standard ACLs match on source IP only — blunt but fast. Extended ACLs match on source, destination, port, and protocol — more precise, preferred in real deployments. The most important rule: every ACL ends with an implicit deny any. If you don't explicitly permit traffic, it gets dropped silently. Always check hit counts with show access-lists.

# Practice: Python ACL rule engine (same logic as IOS ACL matching)

class acl_rule:
    def __init__(self, action, src_network, src_mask, dst_port=None):
        self.action = action
        self.src_prefix = src_network.rsplit('.', 1)[0]
        self.dst_port = dst_port

    def matches(self, src_ip, dst_port=None):
        src_match = src_ip.startswith(self.src_prefix)
        port_match = (self.dst_port is None) or (dst_port == self.dst_port)
        return src_match and port_match


class access_list:
    def __init__(self, name):
        self.name = name
        self.rules = []
        self.hit_counts = []

    def add_rule(self, action, src_network, src_mask, dst_port=None):
        self.rules.append(acl_rule(action, src_network, src_mask, dst_port))
        self.hit_counts.append(0)

    def check(self, src_ip, dst_port=None):
        for i, rule in enumerate(self.rules):
            if rule.matches(src_ip, dst_port):
                self.hit_counts[i] += 1
                return rule.action
        return 'deny'


# Extended ACL: only 192.168.1.x can reach port 443, block everything else
acl110 = access_list('BLOCK_EXTERNAL')
acl110.add_rule('permit', '192.168.1.0', '0.0.0.255', dst_port=443)
acl110.add_rule('deny',   '0.0.0.0',     '255.255.255.255')

test_traffic = [
    ('192.168.1.55', 443),
    ('192.168.1.55', 80),
    ('10.0.0.99',    443),
    ('172.16.0.1',   22),
]

for src, port in test_traffic:
    result = acl110.check(src, port)
    print(f'{result.upper():6} {src}:{port}')

WiFi Security Standards

WEP — broken. Cracked in minutes with aircrack-ng. Never use it. WPA-TKIP — deprecated. Shares WEP's RC4 cipher, still vulnerable. WPA2-AES — minimum acceptable. Strong encryption, widely supported. WPA3 — current standard. Protects against offline dictionary attacks with SAE (Simultaneous Authentication of Equals). WPS (Wi-Fi Protected Setup) looks convenient but its 8-digit PIN can be brute-forced in hours. Disable it. For enterprise: 802.1X + RADIUS server instead of a shared passphrase. Each user authenticates individually — one compromised password doesn't hand over the whole network.

wifi_standards = {
    'WEP':       {'status': 'BROKEN',     'note': 'cracked in minutes — never use'},
    'WPA-TKIP':  {'status': 'DEPRECATED', 'note': 'shares WEP vulnerabilities'},
    'WPA2-AES':  {'status': 'ACCEPTABLE', 'note': 'minimum for production'},
    'WPA3-SAE':  {'status': 'RECOMMENDED','note': 'current standard, offline attack resistant'},
    '802.1X':    {'status': 'ENTERPRISE',  'note': 'per-user auth via RADIUS'},
}

for standard, info in wifi_standards.items():
    print(f'{standard:10} [{info["status"]:11}] {info["note"]}')

📝 Exercise: Hardening Audit — ACL + Policy Check

Build a hardening_auditor class that takes a device's running_config list and checks: (1) 'enable secret' present, (2) 'transport input ssh' present, (3) 'login block-for' present, (4) 'service password-encryption' present. Run it against three devices and print PASS/FAIL per check.

code.py
Output

            
← Back to Chapter