The Cisco IOS commands worth having to hand — modes, a baseline config, VLANs and trunks, and the show commands you actually reach for on site. Pairs with the Cisco config generator on the Tools page, which will build a hardened baseline for you. Switch examples use Gi1/0/1-style interfaces; adjust to whatever your kit calls them.
Getting around: the modes
IOS is a set of nested rooms, and the prompt tells you which one you are standing in. You cannot configure anything from the front door.
| Mode | Prompt | How you get there |
|---|---|---|
| User EXEC | SW01> | Where you land on login. Look, barely touch. |
| Privileged EXEC | SW01# | enable |
| Global config | SW01(config)# | configure terminal (conf t) |
| Interface config | SW01(config-if)# | interface Gi1/0/1 |
| Line config | SW01(config-line)# | line vty 0 15 |
| Back one level | — | exit |
| Back to privileged EXEC | — | end or Ctrl+Z |
Tip
Tab completes a command and ? lists what is valid at that point — show ip ? is the fastest way out of “what was that command again”. Almost everything can be abbreviated (conf t, sh ip int br) as long as it is unambiguous. And do lets you run a privileged command without leaving config mode: do show ip int brief.
A sane baseline
| Task | Command |
|---|---|
| Name the device | hostname SW01 |
| Set the enable password (hashed) | enable secret <password> |
| Encrypt other plaintext passwords | service password-encryption |
| Create a local admin | username admin privilege 15 secret <password> |
| Login banner | banner motd #Authorised access only# |
| Management IP (switch SVI) | interface vlan 1 → ip address 10.0.0.2 255.255.255.0 → no shutdown |
| Default gateway (L2 switch) | ip default-gateway 10.0.0.1 |
Turning on SSH
| Step | Command |
|---|---|
| Domain name (needed for the key) | ip domain-name example.com |
| Generate the host key | crypto key generate rsa modulus 2048 |
| Force SSH v2 | ip ssh version 2 |
| Use local accounts on the VTY lines | line vty 0 15 → login local |
| SSH only, no telnet | transport input ssh |
| Stop console messages eating your typing | line con 0 → logging synchronous |
Interfaces
| Task | Command |
|---|---|
| Configure one port | interface Gi1/0/1 |
| Configure many at once | interface range Gi1/0/1-24 |
| Label it (do this — future you will thank you) | description Uplink to core |
| Bring it up | no shutdown |
| Take it down | shutdown |
| Give it an IP (router / L3) | ip address 192.168.1.1 255.255.255.0 |
| Access port in a VLAN | switchport mode access → switchport access vlan 10 |
| Skip the spanning-tree wait on an edge port | spanning-tree portfast |
| Shut the port if it sees a BPDU | spanning-tree bpduguard enable |
VLANs and trunks
| Task | Command |
|---|---|
| Create a VLAN | vlan 10 → name Staff |
| Put a port in it | switchport mode access → switchport access vlan 10 |
| Make a port a trunk | switchport mode trunk |
| Limit what crosses the trunk | switchport trunk allowed vlan 10,20,30 |
| Add one VLAN to an existing trunk | switchport trunk allowed vlan add 40 |
| Set the native VLAN | switchport trunk native vlan 99 |
| Route between VLANs (L3 switch) | ip routing + an interface vlan X per VLAN |
Warning
switchport trunk allowed vlan 10 replaces the allowed list with just VLAN 10 — it does not add to it. Use allowed vlan add 10 when you mean “and also”. Getting these two confused on a live uplink is one of the quicker ways to black out a floor.
Looking around: show commands
| Question | Command |
|---|---|
| What is the whole config? | show running-config (sh run) |
| What will it boot with? | show startup-config |
| Which interfaces are up, and their IPs? | show ip interface brief |
| Port status, speed, duplex, VLAN | show interfaces status |
| What VLANs exist and which ports are in them? | show vlan brief |
| Which trunks, carrying what? | show interfaces trunk |
| What MAC is on which port? | show mac address-table |
| What is plugged into me? | show cdp neighbors detail / show lldp neighbors |
| Spanning-tree state, who is root | show spanning-tree |
| Model, IOS version, uptime, serial | show version |
| One interface in detail (errors, drops) | show interfaces Gi1/0/1 |
| Filter any output | append | include VLAN0010 or | begin Gi1/0/5 |
Diagnostics
For when the problem is on the wire rather than in the config. Most of this is about reading counters honestly: a port can sit there reporting up/up and still be quietly mangling every third frame.
Testing the cable itself (TDR)
Most Catalyst switches have a Time Domain Reflectometer built into their copper ports. It fires a pulse down each pair, listens for the echo, and reports whether the pair is intact — and roughly how many metres away the fault is. It will not replace a Fluke, but it answers the question you actually have on site: do I go and look at the patch panel, or at the desk?
| Task | Command |
|---|---|
| Run the test | test cable-diagnostics tdr interface Gi1/0/1 |
| Read the result (give it a few seconds) | show cable-diagnostics tdr interface Gi1/0/1 |
| Pair result | What it means |
|---|---|
Normal | Pair is fine end to end. |
Open | Broken conductor, or nothing terminated at the far end. |
Short | Two conductors touching — usually a mangled crimp. |
Impedance Mismatch | A bad joint, a dodgy coupler, or mixed cable types along the run. |
Before you run TDR
It is copper only — no SFPs, no fibre — and on most platforms only the gigabit ports support it. More to the point, the test drops the link while it runs. Running it on the uplink you are managing the switch through is the same mistake as every other one on this page, just with a more interesting excuse. The distance figure is approximate too — expect a tolerance of a few metres — so treat it as “about that far along”, not a pinpoint.
What the error counters are telling you
| Counter climbing | Usually means |
|---|---|
| CRC / FCS errors | Bad cable or patch lead, electrical interference — or a duplex mismatch. |
| Late collisions | Duplex mismatch, or a run longer than 100 m. |
| Runts | Collisions, or again a duplex mismatch. |
| Giants | MTU / jumbo-frame mismatch between the two ends. |
| Input errors | An umbrella counter — read the specific ones underneath it. |
| Output drops | Egress congestion; classically a 1G port feeding a 100M one. |
| Interface resets | The link is flapping. Suspect the cable, then the far-end NIC. |
Duplex mismatch is the classic, because it presents as a slow and flaky link rather than a broken one, and people chase the application instead. The tell is asymmetric: late collisions on one side, CRC errors on the other. Both ends should be auto-negotiating, or both hard-set — never one of each.
| Task | Command |
|---|---|
| Errors on one port, in detail | show interfaces Gi1/0/1 |
| Error counters across every port | show interfaces counters errors |
| Reset counters for a clean baseline | clear counters Gi1/0/1 |
| Which ports are err-disabled, and why | show interfaces status err-disabled |
| What auto-recovers, and after how long | show errdisable recovery |
| Let a cause recover by itself | errdisable recovery cause psecure-violation + errdisable recovery interval 300 |
Finding things, and the rest
| Question | Command |
|---|---|
| Where is this MAC plugged in? | show mac address-table address 0011.2233.4455 |
| Which IP maps to which MAC? | show ip arp |
| Is the optic actually seeing light? | show interfaces transceiver (dBm per lane) |
| Is the switch delivering PoE? | show power inline |
| What has it been complaining about? | show logging |
| Is it CPU-bound? | show processes cpu sorted |
| Temperature, fans, power supplies | show environment |
| Can it reach that? | ping 10.0.0.1 / traceroute 10.0.0.1 |
If you reach for debug
debug output goes to the console by default, so over SSH you will see nothing until you run terminal monitor. Turn it off the moment you are done — undebug all. A chatty debug left running on a busy production switch can drive the CPU hard enough to take the thing off the network, which is a memorable way to turn a small fault into a large one.
Saving, and not locking yourself out
| Task | Command |
|---|---|
| Save the config | copy running-config startup-config — or write memory / wr |
| Safety net before a risky change | reload in 10 |
| Cancel it once you are happy | reload cancel |
| Throw away unsaved changes | reload and answer no to saving |
| Wipe a switch back to factory | erase startup-config + delete vlan.dat, then reload |
The reload-in trick
reload in 10 schedules a reboot in ten minutes before you make a change you are not sure about. If the change locks you out, the switch reboots into the last saved config and lets you back in. If it works, reload cancel and then save. It is the network engineer’s equivalent of keeping one hand on the door — and remember that on a switch, VLAN data lives in vlan.dat separately from the startup config, which is why a “factory reset” needs both.
Access lists, briefly
| Task | Command |
|---|---|
| Named extended ACL | ip access-list extended GUEST-IN |
| A permit rule | permit tcp 10.10.0.0 0.0.255.255 any eq 443 |
| A deny rule | deny ip 10.10.0.0 0.0.255.255 10.0.0.0 0.255.255.255 |
| Apply it to an interface | interface Vlan10 → ip access-group GUEST-IN in |
| See hit counts | show access-lists |
Note the wildcard masks — they are the inverse of a subnet mask (0.0.255.255 where a mask would read 255.255.0.0), and there is an invisible deny ip any any at the end of every ACL. The access list generator will write these for you, and the wildcard converter flips masks either way.
Hardening the switch
An access switch sitting in an unlocked comms cupboard is a row of live network sockets. These are the things worth doing beyond setting a password.
Port security
| Task | Command |
|---|---|
| Turn it on (access ports only) | switchport port-security |
| Limit how many MACs may appear | switchport port-security maximum 2 |
| Learn the MAC and keep it | switchport port-security mac-address sticky |
| What to do about a violation | switchport port-security violation restrict |
| Check it | show port-security interface Gi1/0/1 |
| Violation mode | Behaviour |
|---|---|
protect | Silently drops the offending traffic. |
restrict | Drops it, and logs and counts it. |
shutdown (default) | Err-disables the whole port. |
shutdown being the default catches people out: one unexpected MAC and the port is dead until somebody bounces it or errdisable recovery picks it up. On a desk port with a phone and a PC daisy-chained behind it, maximum 2 paired with restrict is usually the kinder arrangement.
The classic layer-2 attacks
| Threat | Defence |
|---|---|
| Someone plugs in a rogue DHCP server | ip dhcp snooping + ip dhcp snooping vlan 10,20, then ip dhcp snooping trust on the uplink only |
| ARP spoofing / poisoning | ip arp inspection vlan 10,20 + ip arp inspection trust on uplinks |
| A rogue switch grabbing the spanning-tree root | spanning-tree guard root on downstream ports |
| Any switch plugged into a desk port | spanning-tree bpduguard enable on edge ports |
| See what snooping has learned | show ip dhcp snooping binding |
Dynamic ARP Inspection leans on the DHCP snooping binding table, so snooping has to come first — DAI on its own has nothing to check against.
Trust the uplink, or break DHCP for everyone
Enabling DHCP snooping marks every port untrusted by default, and an untrusted port drops inbound DHCP offers. Turn it on without adding ip dhcp snooping trust to the uplink and you have just blocked the replies from your real DHCP server — the whole VLAN stops getting addresses as leases expire, on a delay long enough that nobody connects it to the change you made. Trust the uplink in the same maintenance window you enable snooping.
The management plane
| Task | Command |
|---|---|
| Restrict who may even reach VTY | line vty 0 15 → access-class MGMT-ONLY in |
| Slow down brute force | login block-for 120 attempts 3 within 60 |
| Time out idle sessions | exec-timeout 10 0 |
| Turn off the web server | no ip http server + no ip http secure-server |
| Stop advertising yourself to untrusted ports | no cdp enable (per interface) |
| SSH only on the VTY lines | transport input ssh |
secret, not password
Always enable secret, never enable password. The latter is stored with a type-7 cipher that is trivially reversible — there are decoders in the browser. And be clear about what service password-encryption buys you: it applies that same weak type-7 encoding to the remaining plaintext passwords in the config. It defeats shoulder-surfing, not anybody who walks away with a copy of the config file.
Unused ports and VLAN hygiene
| Practice | Why |
|---|---|
shutdown unused ports, and park them in an unused VLAN | An unpatched live port is a free network connection for anyone in the building. |
| Do not leave user ports in VLAN 1 | It is the default everywhere, which makes it everyone’s first guess. |
| Set the trunk native VLAN to something unused | Untagged traffic on a trunk lands in the native VLAN — reduces VLAN-hopping exposure. |
| Prune trunks to only the VLANs they carry | Smaller blast radius, and less flooding across the uplink. |
Mind the branch you are sitting on
The same rule as anywhere else: do not shutdown the port, VLAN or uplink you are managing the device through, and think hard before applying an ACL to the interface your session arrives on. On a switch in a comms room two hours away, that is the difference between a quick change and a long drive.
