Set Up a Network Automation Lab

Automate Cisco routers in GNS3 using Python and SSH with Netmiko.

Introduction

30 Second Summary

Imagine you're responsible for 50 network routers. Every time a setting needs to change, you log into each one manually, type the same commands over and over, and hope you don't make a typo on router number 37.

In this project, you will build a network automation lab on your Windows machine using GNS3. You'll spin up three Cisco routers, configure them for SSH access, and write a Python script that connects to a live router, pulls its configuration, and saves it to a file.

What You'll Build

Picture running a script from your terminal and watching it SSH into a live Cisco router, print an interface status table, and save the entire running config to a backup file on your machine.

By the end of this project, you'll have:

  • Three routers running real Cisco IOS inside GNS3, all reachable from your Windows machine so your scripts can connect to any device in the lab.
  • SSH access on every router with proper credentials and encryption, ready for remote automation.
  • A Python script using Netmiko that SSHs into a live router, pulls its interface status, and saves the running config to a backup file.
  • Secret Mission: Write a multi-device script that loops through all 3 routers, backs up every config to individual files, and prints a summary report.

Are there any prerequisites?

This project assumes you have basic networking knowledge and Python installed on your Windows machine.

It's the first project in the Network Automation with Python and Ansible track.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters.

Install GNS3 and Set Up Your Environment

Your automation scripts need to talk to real Cisco IOS, not a simplified simulator that skips key behaviors. GNS3 is a network emulator that runs actual router firmware on your Windows machine, giving you a realistic lab without touching production hardware.

In this step, you will install GNS3 with its local server, create a virtual network adapter that bridges your PC to the emulated network, and install Netmiko, the Python library that handles SSH connections to network devices.

In this step, get ready to:
  • Install GNS3 2.2.x with Dynamips for local router emulation.
  • Set up a Microsoft Loopback Adapter to connect your PC to the GNS3 network.
  • Install Netmiko for Python-based SSH automation.
Download and install GNS3

GNS3 runs real Cisco IOS images using an engine called Dynamips. You need GNS3 version 2.2.x specifically, because GNS3 3.0+ requires a separate GNS3 VM or a Linux system, which would eat into your available RAM.

  • Open your browser and go to the GNS3 GitHub releases page.
  • Find the release titled Version 2.2.61 near the top of the list.
  • Under Assets, click GNS3-2.2.61-all-in-one.exe to download the Windows installer.
  • Once the download finishes, double-click the .exe file to launch the installer.
  • If a Windows UAC prompt appears, click Yes to allow the installation.

The installer asks you which components to include. Make sure the following are all checked:

  • Select GNS3 (the main application).
  • Select Dynamips (the IOS router emulation engine).
  • Select Npcap (the packet capture driver for Windows).
  • Select SolarPutty (a terminal client for console connections).
  • Click Next and follow the remaining prompts to complete the installation using the default settings.

What are these components?

Dynamips is the engine that actually runs Cisco IOS images on your CPU. Without it, GNS3 is just a drawing tool with no live devices.

Npcap lets GNS3 capture and inject network packets on your Windows machine. SolarPutty gives you a terminal window to type commands directly into each router's console.

After the installation finishes, GNS3 launches and the Setup Wizard appears. This is where you tell GNS3 how to run its server.

  • Select Run appliances on my local computer and click Next.
  • On the local server configuration screen, confirm the Host Binding is set to 127.0.0.1 and the Port is 3080.
  • Click Next through any remaining wizard screens to finish the setup.

Look at the bottom-right corner of the GNS3 window. You should see a green circle next to the server name, confirming the local server is running.

Why GNS3 instead of Packet Tracer?

Cisco Packet Tracer simulates network devices, but it does not support SSH connections from external tools like Netmiko. Your Python scripts cannot connect to Packet Tracer devices.

GNS3 with Dynamips runs real IOS firmware that accepts real SSH connections. The automation scripts you write here will work the same way against production routers.

GNS3 shows a red or orange server indicator?

Make sure you selected Run appliances on my local computer during the Setup Wizard. If you chose the GNS3 VM option instead, open Edit, then Preferences, then Server and switch to the local server with host binding 127.0.0.1.

Help me fix the GNS3 server connection issue

Install the Microsoft Loopback Adapter

Your Windows machine and the GNS3 routers live in separate network worlds. A loopback adapter creates a virtual network interface on your PC that GNS3 can connect to, so your Python scripts can reach the routers directly.

  • Press the Windows key, type Device Manager, and press Enter.
  • Click on Action in the top menu bar.
  • Select Add legacy hardware.
  • Click Next on the welcome screen.
  • Select Install the hardware that I manually select from a list (Advanced) and click Next.
  • Select Network adapters and click Next.
  • In the Manufacturer list on the left, select Microsoft.
  • In the Model list on the right, select Microsoft KM-TEST Loopback Adapter.
  • Click Next to install the adapter.
  • Click Finish to close the wizard.

What is a loopback adapter?

A loopback adapter is a virtual network card that exists only in software. It gives your Windows PC an IP address on the same network as your GNS3 routers, so traffic can flow directly between your host machine and the emulated devices.

Without it, GNS3 routers would be isolated inside the emulator. Your Python scripts would have no way to reach them over SSH.

Now you need to assign a static IP address to the new adapter so it sits on the same subnet as your future routers.

  • Press the Windows key, type View network connections, and press Enter.
  • Find the adapter labeled Ethernet with Microsoft KM-TEST Loopback Adapter underneath it.
  • Right-click it and select Properties.
  • Select Internet Protocol Version 4 (TCP/IPv4) and click Properties.
  • Select Use the following IP address.
  • Enter 192.168.10.1 in the IP address field.
  • Enter 255.255.255.0 in the Subnet mask field.
  • Leave the Default gateway field blank and click OK to close both dialogs.
  • Press the Windows key, type cmd, and press Enter to open a Command Prompt.
  • Check the adapter's IP assignment by running:
ipconfig

Scroll through the output and find the section for the loopback adapter. You should see IPv4 Address showing 192.168.10.1 and Subnet Mask showing 255.255.255.0.

Don't see 192.168.10.1 in the output?

Make sure you selected Use the following IP address instead of Obtain an IP address automatically in the adapter properties. Go back to View network connections, right-click the loopback adapter, and re-enter the static IP settings.

Help me fix the loopback adapter IP configuration

Install Netmiko

Netmiko is a Python library that simplifies SSH connections to network devices. It knows how to handle the quirks of different vendor CLIs, so you can connect to a Cisco router, send commands, and read the output with just a few lines of Python.

Before installing Netmiko, confirm your Python version meets the requirement. Netmiko 4.7.0 requires Python 3.10 or higher.

  • In your Command Prompt, check your Python version by running:
python --version

✔️ I see version 3.10 or higher

Your Python version is compatible. Move on to install Netmiko below.

ⓧ I see a version lower than 3.10

Netmiko 4.7.0 will not work with your current Python version.

  • Download Python 3.10 or higher from the official Python downloads page.
  • Run the installer and check Add Python to PATH during installation.
  • Close and reopen Command Prompt.
  • Run python --version again to confirm the new version.

ⓧ Command not found

Python may not be on your system PATH.

  • Try running py --version instead. Windows sometimes uses the py launcher.
  • If that also fails, download and install Python 3.10+ from python.org.
  • Make sure to check Add Python to PATH during installation.
  • Close and reopen Command Prompt, then run python --version again.
  • Install Netmiko 4.7.0 by running:
pip install netmiko==4.7.0

Why pin a specific version?

Pinning Netmiko to 4.7.0 ensures everyone in this project is using the same code with the same behavior. Newer versions could rename functions or change defaults, which would break the instructions.

Before you run the next command, what do you expect to see if Netmiko installed correctly?

  • Verify the installation by running:
python -c "from netmiko import ConnectHandler; print('Netmiko ready')"

You should see Netmiko ready printed in your terminal. This confirms that Python can import Netmiko and its ConnectHandler class, which is the main function you will use to connect to routers.

Seeing a ModuleNotFoundError?

If Python cannot find Netmiko, the pip that installed the package may be linked to a different Python version than the python command you are using. Try running python -m pip install netmiko==4.7.0 to ensure the install targets the right interpreter.

Help me fix this pip and Python version mismatch

Your environment is ready. GNS3 is running locally, your loopback adapter bridges your PC to the emulated network, and Netmiko is standing by to automate SSH connections. Next up, you will build a router network inside GNS3 and bring it to life.

Build Your Router Network

Your environment is ready. GNS3 is installed, your Loopback Adapter is configured, and Netmiko is standing by.

Right now, GNS3 is an empty canvas with no devices. You need routers running real Cisco IOS to automate against. In this step, you'll import a router image, build a three-router topology, and give each router an IP address so your Windows PC can reach them.

In this step, get ready to:
  • Import a Cisco c3725 IOS image into GNS3 and configure Idle-PC.
  • Build a network topology with three routers, a switch, and a Cloud node.
  • Configure IP addresses on all routers and verify connectivity from your Windows PC.
Import a Cisco IOS image into GNS3

Before GNS3 can run any routers, it needs an IOS image file. This image is the actual operating system that runs on Cisco hardware.

Where do I get a Cisco IOS image?

Cisco IOS images are proprietary software. GNS3 and this project cannot provide download links.

You need a Dynamips-compatible c3725 IOS image file (.image or .bin format). Check your educational institution, Cisco learning platform, or lab resources for a c3725 image. Save the image file somewhere easy to find, like your Desktop.

  • Switch back to GNS3.
  • Click Edit in the top menu bar.
  • Click Preferences.
  • In the left sidebar, expand Dynamips and select IOS routers.
  • Click New in the right pane.
  • Select New Image, then click Browse and navigate to your c3725 IOS image file.
  • Click Next. The wizard auto-detects the c3725 platform. Confirm the platform is correct and click Next again.
  • Set the RAM to 128 MB and click Next.

What is Idle-PC?

Without a correct Idle-PC value, each Dynamips router consumes 100% of one CPU core even while doing nothing. The Idle-PC finder detects idle loops in the IOS code and tells Dynamips when to release the CPU.

With three routers running, skipping this step would pin three of your CPU cores at maximum. Setting Idle-PC keeps your system responsive.

  • On the Network adapters page, find the Slot 1 dropdown and select NM-1FE-TX.
  • Click Next to skip the WIC modules page.
  • On the Idle-PC page, click Idle-PC finder. GNS3 will boot the router temporarily and calculate a value. This can take 30-60 seconds.
  • Select the value marked with an asterisk (*). The asterisk indicates the most efficient value.
  • Click Finish, then click Apply and OK to close the Preferences window.

Why NM-1FE-TX in slot 1?

The c3725 has two built-in FastEthernet ports on its motherboard (slot 0). Adding a NM-1FE-TX module in slot 1 gives you a third FastEthernet interface called FastEthernet1/0. You will use this interface to connect each router to the shared network switch.

You should now see the c3725 router template listed in the Routers category in the left device toolbar.

Don't see the router in the device toolbar?

Make sure you clicked Apply before closing the Preferences window. If the router template was created but is not visible, click the router icon in the left device toolbar to expand the Routers category.

If the Idle-PC finder failed, reopen Edit > Preferences > Dynamips > IOS routers, select the router, click Edit, and try the Idle-PC finder again.

help me troubleshoot my GNS3 IOS router import

Build the network topology

With the router template ready, you can now place devices on the GNS3 canvas and cable them together into a working network.

  • From the Routers category in the left device toolbar, drag three c3725 routers onto the canvas.
  • GNS3 automatically names them R1, R2, and R3.
  • Click the Switches category in the left device toolbar and drag an Ethernet Switch onto the canvas.
  • Click the End devices category and drag a Cloud node onto the canvas.

What does the Cloud node do?

The Cloud node bridges your GNS3 virtual network to a real network interface on your Windows PC. By attaching it to the Loopback Adapter you configured in Step 1, your Windows machine becomes a device on the same network as your GNS3 routers. This is what lets Python scripts running on Windows reach the routers directly.

  • Right-click the Cloud node on the canvas.
  • Select Configure.
  • In the Ethernet tab, find the Microsoft KM-TEST Loopback Adapter in the dropdown.
  • Click Add, then click Apply and OK.
  • Click the Add a link button at the bottom of the left device toolbar (it looks like a network cable).
  • Click R1 on the canvas, then select FastEthernet1/0 from the interface list that appears.
  • Click the Ethernet Switch, then select any available port.
  • Repeat to cable R2 to the Ethernet Switch, selecting FastEthernet1/0 on R2.
  • Cable R3 to the Ethernet Switch the same way, selecting FastEthernet1/0 on R3.
  • Cable the Cloud node to the Ethernet Switch. Select the Loopback Adapter interface on the Cloud side and any available port on the switch.
  • Click the green Start all nodes button in the top toolbar to power on every device.

All connection lines on the canvas should turn green after a few seconds. This confirms every device is powered on and the links are active.

Seeing red link indicators?

Red links mean a device is not started or the interface is incorrect. Right-click each router and select Start individually if the toolbar button did not start all devices.

If a link stays red, right-click it and select Delete. Re-cable it, making sure you select FastEthernet1/0 on the router side (not FastEthernet0/0 or FastEthernet0/1).

help me troubleshoot my GNS3 topology links

Configure IP addresses on each router

The routers are running, but they have no IP addresses yet. Each router needs an IP on its FastEthernet1/0 interface so it can communicate with the other routers and your Windows PC.

  • Right-click R1 on the canvas and select Console. A terminal window opens with the router's command line.
  • If you see ---More--- or a boot message, press Enter until you reach the Router> prompt.
  • Configure R1's IP address by entering these commands:
enable
configure terminal
! Select the interface from the NM-1FE-TX module
interface fastethernet 1/0
! Assign R1's IP address on the shared network
ip address 192.168.10.10 255.255.255.0
! Bring the interface online
no shutdown
! Return to privileged EXEC mode
end

What do these commands do?

  • enable enters privileged EXEC mode, which grants full access to the router's configuration.
  • configure terminal enters global configuration mode where you can change settings.
  • interface fastethernet 1/0 selects the FastEthernet port on the NM-1FE-TX module you added in slot 1.
  • ip address 192.168.10.10 255.255.255.0 assigns the IP 192.168.10.10 with a /24 subnet mask.
  • no shutdown activates the interface. Cisco interfaces are shut down by default.
  • Confirm R1's interface is up by running this command:
show ip interface brief

You should see FastEthernet1/0 listed with IP address 192.168.10.10 and a status of up.

Interface showing down/down?

Make sure you typed no shutdown on the interface. Also confirm the cable connects to FastEthernet1/0 (slot 1), not FastEthernet0/0 or FastEthernet0/1 (slot 0). Only the interface connected to the switch will show up.

help me troubleshoot my router interface status

  • Right-click R2 on the canvas and select Console.
  • Configure R2's IP address by entering these commands:
enable
configure terminal
interface fastethernet 1/0
ip address 192.168.10.20 255.255.255.0
no shutdown
end
  • Right-click R3 on the canvas and select Console.
  • Configure R3's IP address by entering these commands:
enable
configure terminal
interface fastethernet 1/0
ip address 192.168.10.30 255.255.255.0
no shutdown
end

What's the IP plan?

All three routers and your Windows Loopback Adapter share the 192.168.10.0/24 subnet. Your Windows PC is 192.168.10.1, R1 is 192.168.10.10, R2 is 192.168.10.20, and R3 is 192.168.10.30. Because they are all on the same subnet and connected through the Ethernet Switch, every device can reach every other device directly.

Before you test connectivity, what do you think will happen when your Windows PC tries to ping R1? Will the packets reach a GNS3 router from outside the emulator?

  • Open a Command Prompt on Windows by pressing the Windows key, typing cmd, and pressing Enter.
  • Test connectivity to R1 by running this command:
ping 192.168.10.10

You should see replies from 192.168.10.10. This proves your Windows PC can reach R1 through the Loopback Adapter and Cloud node.

  • Switch back to R1's console in GNS3 and test that R1 can reach R2 by running:
ping 192.168.10.20

You should see five exclamation marks (!!!!!), which is Cisco's way of showing five successful pings. Your three routers are alive, connected, and reachable from your Windows machine.

Not getting ping replies?

If pinging from Windows fails, check that your Loopback Adapter still has the IP 192.168.10.1 assigned. Open Control Panel > Network and Sharing Center > Change adapter settings and double-check the adapter's IPv4 properties.

If pinging between routers fails, verify that all routers are using FastEthernet1/0 (not FastEthernet0/0) and that every interface shows up/up in show ip interface brief.

Windows Firewall can also block ICMP ping packets. Try temporarily disabling it to test. If pings work with the firewall off, add an inbound rule to allow ICMPv4 traffic.

help me troubleshoot ping failures between my Windows PC and GNS3 routers

Your network is alive. Three routers are running real Cisco IOS, connected to each other and to your Windows PC. Next up, you'll write a Python script to automate one of these routers.

Write Your First Automation Script

Your three routers are alive and reachable from your Windows machine. You proved that with a successful ping in the last step.

Now it is time to put those routers to work with automation. You will write a Python script that uses Netmiko to connect to R1 over SSH and pull its interface data. But having IP connectivity does not automatically mean you can automate a device. You are about to find out why.

In this step, get ready to:
  • Create a Python script that connects to R1 using Netmiko.
  • Run the script and discover what happens when a router is not ready for SSH.
Set up your project folder

Your automation scripts need a home on your machine. You will create a project folder on your Desktop so you can find your files easily.

  • In VS Code, open the built-in terminal by pressing Ctrl+` (backtick key, usually above the Tab key).
  • Navigate to your Desktop and create a project folder by running these commands:
cd %USERPROFILE%\Desktop
mkdir network-automation
cd network-automation
  • Confirm the folder was created by running:
dir

You should see an empty directory listing inside network-automation.

Seeing an error with the cd command?

Make sure you are using the Command Prompt or PowerShell terminal in VS Code, not a bash shell. If VS Code opened a different shell, click the dropdown arrow next to the + icon in the terminal panel and select Command Prompt or PowerShell.

help me fix the terminal type in VS Code

  • Open this folder in VS Code by clicking File in the top menu bar.
  • Click Open Folder.
  • Navigate to your Desktop, select the network-automation folder, and click Select Folder.

Why open the folder in VS Code?

Opening a folder sets it as VS Code's workspace. When you open a terminal inside VS Code, it automatically starts in this folder. That means your python commands will find your script files without needing to navigate anywhere.

Write the connection script

Netmiko handles the complexity of SSH connections to network devices. You give it a dictionary of connection details, and it manages the session for you.

  • Create a new file by pressing Ctrl+N.
  • Save it immediately by pressing Ctrl+S and naming it connect_router.py.
  • Add the import and device dictionary by pasting this code into the file:
from netmiko import ConnectHandler

# Define the target router's connection details
device = {
    "device_type": "cisco_ios",
    "host": "192.168.10.10",
    "username": "admin",
    "password": "cisco123",
    "secret": "cisco123",
}

What does this code do?

  • from netmiko import ConnectHandler imports the class that opens SSH sessions to network devices.
  • device_type tells Netmiko this is a Cisco IOS device, so it knows which CLI prompts and commands to expect.
  • host is R1's IP address that you configured in the previous step.
  • username and password are the SSH login credentials the script will use.
  • secret is the enable password for entering privileged EXEC mode on the router.
  • Below the device dictionary, add the connection and command logic:
# Connect to the router via SSH
net_connect = ConnectHandler(**device)

# Run a show command and print the output
output = net_connect.send_command("show ip interface brief")
print("=== Interface Status ===")
print(output)

What does this code do?

  • ConnectHandler(**device) unpacks your device dictionary and opens an SSH session to R1 using those credentials.
  • send_command("show ip interface brief") runs a Cisco IOS command on the remote router and captures the output as a string.
  • The two print() lines display a header and the command output in your terminal.
  • Save connect_router.py by pressing Ctrl+S.

✔️ Awesome, I've got everything!

Great. Double check you have saved connect_router.py before moving on.

ⓧ I'd like to double check the full code

Here is the complete connect_router.py file so far. Compare it against what you have:

from netmiko import ConnectHandler

# Define the target router's connection details
device = {
    "device_type": "cisco_ios",
    "host": "192.168.10.10",
    "username": "admin",
    "password": "cisco123",
    "secret": "cisco123",
}

# Connect to the router via SSH
net_connect = ConnectHandler(**device)

# Run a show command and print the output
output = net_connect.send_command("show ip interface brief")
print("=== Interface Status ===")
print(output)
Run the script and observe the result

Your script is ready. It should connect to R1 at 192.168.10.10, log in, and pull the interface table.

Before you run this, think about it: you can ping R1 successfully, and the script has the right IP address. Do you think the script will connect and print the interface data?

  • Open a terminal in VS Code by pressing Ctrl+` (if one is not already open).
  • Run the script:
python connect_router.py

The script will pause for several seconds while it tries to connect. Then it will fail with a NetMikoTimeoutException error.

This is exactly what should happen. Your script has no bugs.

Why did the script fail?

IP connectivity and SSH connectivity are two different things. Pinging a router proves you can reach it over the network, but SSH is a separate service that must be explicitly configured on the device.

Right now, R1 has no SSH service running, no user accounts, and no encryption keys. Network devices do not accept SSH by default. Netmiko tried to open an SSH session on port 22, and the router simply did not respond.

Seeing a different error?

If you see a ModuleNotFoundError, Netmiko is not installed in the Python environment your terminal is using. Run pip install netmiko==4.7.0 and try again.

If you see a SyntaxError, double check your code against the full file in the tab above. Make sure all quotes and brackets match.

help me fix my connect_router.py errors

Your script is correct, but the router is not ready for automation. In the next step, you will configure SSH on all three routers so they accept incoming connections.

Enable SSH on Your Routers

In Step 3, your Python script tried to reach R1 over SSH and hit a NetMikoTimeoutException. The router rejected the connection because Cisco devices do not accept SSH by default.

To accept SSH connections, each router needs an identity (hostname and domain name), encryption (RSA keys), authentication (a local user account), and an access policy (VTY lines configured for SSH). In this step, you will configure all of these on every router and prove it works with a manual SSH test.

In this step, get ready to:
  • Configure hostname, domain name, RSA keys, and credentials on R1.
  • Set up VTY lines for SSH access and repeat the full configuration on R2 and R3.
  • Test SSH connectivity manually from Windows Command Prompt.
Configure SSH identity and credentials on R1

SSH requires the router to have a unique identity before it can generate encryption keys. The hostname and domain name combine to form this identity, and RSA keys cannot be generated without a domain name set first.

  • Right-click R1 in GNS3 and select Console to open the router CLI.
  • If you see the Router> prompt, type enable to enter privileged exec mode.
  • Set R1's identity and generate encryption keys by entering these commands:
configure terminal
hostname R1
ip domain-name automation.lab
crypto key generate rsa

What does crypto key generate rsa do?

This command generates the RSA encryption keys that SSH uses to secure the connection. The router will prompt you for the key modulus size, which determines the strength of the encryption.

  • When the router asks for the modulus size, type 1024 and press Enter.

You will see output showing the RSA key fingerprint. This confirms the encryption keys are ready.

  • Create a local user account and set the enable password by entering these commands:
username admin privilege 15 secret cisco123
enable secret cisco123

What do these commands do?

Each command in this sequence sets up a piece of the SSH puzzle:

  • hostname R1 and ip domain-name automation.lab give the router the identity it needs before RSA keys can be generated.
  • crypto key generate rsa creates the 1024-bit RSA key pair used to encrypt SSH sessions.
  • username admin privilege 15 secret cisco123 creates a local account named admin with full privileges. This is the account your Python script will log in with.
  • enable secret cisco123 sets the password required to enter privileged exec mode on the router.

Why must hostname and domain come first?

Cisco IOS uses the hostname and domain name to build the key label for RSA generation. If you try to run crypto key generate rsa without setting a domain name, the router will reject the command.

Set up VTY lines and repeat on R2 and R3

R1 now has encryption and credentials, but it still has no policy telling it to accept SSH connections on its management lines. VTY (Virtual Teletype) lines are the router's remote access ports.

  • Still in R1's configuration mode, configure the VTY lines and enable SSHv2 by entering these commands:
line vty 0 4
login local
transport input ssh
exit
ip ssh version 2
end

What does this configure?

  • line vty 0 4 selects the five virtual terminal lines that handle remote connections.
  • login local tells the router to authenticate users against its local user database (the admin account you just created).
  • transport input ssh restricts the VTY lines to SSH only. Telnet connections will be refused.
  • ip ssh version 2 enforces the more secure SSHv2 protocol instead of the older SSHv1.
  • Verify that SSH is active on R1 by running this command:
show ip ssh

You should see output showing SSH Enabled - version 2.0. This confirms R1 is ready to accept SSH connections.

Seeing SSH disabled or version 1.99?

  • Make sure you ran ip ssh version 2 from global configuration mode, not from inside the line vty block.
  • Confirm that crypto key generate rsa completed successfully. If the domain name was missing, re-enter ip domain-name automation.lab first, then regenerate the keys.

Help me troubleshoot my SSH configuration on R1.

Now you need to repeat the full SSH configuration on R2 and R3. The commands are identical except for the hostname.

  • Right-click R2 in GNS3 and select Console.
  • If you see the Router> prompt, type enable to enter privileged exec mode.
  • Set R2's identity and generate its RSA keys by entering these commands:
configure terminal
hostname R2
ip domain-name automation.lab
crypto key generate rsa
  • Type 1024 when prompted for the modulus size, then configure credentials and VTY lines by entering:
username admin privilege 15 secret cisco123
enable secret cisco123
line vty 0 4
login local
transport input ssh
exit
ip ssh version 2
end
  • Verify SSH is active on R2 by running:
show ip ssh

You should see SSH Enabled - version 2.0 again.

  • Right-click R3 in GNS3 and select Console.
  • If you see the Router> prompt, type enable.
  • Enter the same sequence of commands you used for R2, but change the hostname to R3:
configure terminal
hostname R3
ip domain-name automation.lab
crypto key generate rsa
  • Type 1024 when prompted, then enter the remaining commands:
username admin privilege 15 secret cisco123
enable secret cisco123
line vty 0 4
login local
transport input ssh
exit
ip ssh version 2
end
  • Run this on R3 to confirm SSH is active:
show ip ssh

All three routers should now show SSH Enabled - version 2.0.

Test SSH from Windows Command Prompt

The routers are configured, but you have not yet proven that a remote connection actually works. A manual SSH test from your Windows machine confirms that everything is wired up correctly before you hand it off to your Python script.

  • Press the Windows key to open the search bar.
  • Type cmd and press Enter to open Command Prompt.

Before you run the next command, take a moment to predict what will happen. Do you think the SSH connection will succeed this time, or will it fail like the Python script did in Step 3?

  • Connect to R1 over SSH by running this command:
ssh -l admin 192.168.10.10

First-time connection prompt

The first time you SSH to a new host, you will see a message asking you to verify the host's authenticity. Type yes and press Enter to continue.

  • When prompted for the password, type cisco123 and press Enter. The password will not appear on screen as you type.

You should land on the R1# prompt. This confirms that your Windows machine can reach R1 over SSH with the credentials you configured. Type exit to disconnect.

Connection timed out or refused?

  • Make sure all three routers are still running in GNS3. Check for green play icons on each device.
  • Verify your Loopback Adapter still has the IP address 192.168.10.1. Open the adapter's IPv4 properties and confirm the static IP is set.
  • Try pinging R1 first with ping 192.168.10.10. If pings fail, the connectivity issue is at the network level, not SSH.
  • Console into R1 in GNS3 and run show ip ssh to confirm SSH is enabled. If it shows disabled, re-enter the configuration commands from earlier in this step.

Help me troubleshoot my SSH connection from Windows to a GNS3 router.

All three routers are now SSH-ready, and you have proof that a remote connection works. Next up, you will re-run the Python script that failed in Step 3 and watch it succeed.

Run Your First Automation Script

In the last step, you configured SSH on all three routers with hostnames, RSA keys, user accounts, and VTY lines.

The script that failed with a NetMikoTimeoutException in Step 3 is still sitting in your project folder, unchanged. Let's find out if your SSH configuration was enough to make it work.

In this step, get ready to:
  • Re-run your automation script and watch it successfully connect to R1 via SSH.
  • Add a config backup feature that saves R1's running configuration to a file.
Re-run your automation script

Before you run the script, think back to Step 3. The script tried to SSH into R1 and was rejected. You have since configured SSH on every router. What do you expect to see this time?

  • Run the script again in your VS Code terminal:
python connect_router.py

This time, the script connects to R1 over SSH and prints R1's interface table. You should see a list of interfaces including FastEthernet1/0 with the IP address 192.168.10.10.

What just happened?

In Step 3, this exact script failed with a NetMikoTimeoutException because R1 had no SSH service, no user accounts, and no encryption keys.

After configuring all of that in Step 4, the router now accepts the SSH connection. Netmiko logs in with the admin credentials, runs show ip interface brief on the router, and prints the output back to your terminal.

Still seeing a timeout error?

  • Make sure all three routers are running in GNS3. Check for green play icons on each router in the canvas.
  • Console into R1 and run show ip interface brief. The fa1/0 interface should show 192.168.10.10 with status up.
  • Try pinging R1 from a separate Command Prompt with ping 192.168.10.10. If the ping fails, check that your Loopback Adapter's IP is 192.168.10.1 and that the Cloud node is connected to the Ethernet Switch.
  • Help me troubleshoot my Netmiko connection timeout
Add a config backup to the script

Printing interface status is useful, but the real power of automation is doing something you would otherwise have to do manually on every router. Saving a router's running configuration to a backup file is one of the most common automation tasks in network engineering.

  • In VS Code, open connect_router.py.
  • Find the last line of your script, which reads print(output).
  • Add the following code below that line:
# Pull the full running config from the router
config = net_connect.send_command("show running-config")

# Save the config to a backup file
with open("R1-backup.cfg", "w") as f:
    f.write(config)
print("\nConfig backed up to R1-backup.cfg")

# Close the SSH connection cleanly
net_connect.disconnect()

What does this code do?

  • send_command("show running-config") retrieves the entire running configuration from R1. This is the same output you would see if you typed the command in the router's CLI.
  • open("R1-backup.cfg", "w") creates a new file called R1-backup.cfg in your project folder and writes the full config into it.
  • net_connect.disconnect() closes the SSH session so you do not leave a connection hanging on the router.
  • Save connect_router.py.

Before you run the updated script, what do you expect to see in the terminal this time?

  • Run the updated script:
python connect_router.py

The terminal prints the interface table, followed by a confirmation line: Config backed up to R1-backup.cfg.

  • Confirm the backup file was created by running:
dir

You should see R1-backup.cfg listed alongside connect_router.py.

  • Open R1-backup.cfg in VS Code by clicking on it in the Explorer sidebar.

The file contains R1's full running configuration, including the hostname, interface IP addresses, SSH settings, and user accounts you configured in previous steps.

Not seeing the backup file?

  • Make sure you saved connect_router.py before running it. Unsaved changes in VS Code show a dot next to the filename in the tab bar.
  • Check that you added the new code below the existing print(output) line, not inside or above it.
  • Help me figure out why my backup file was not created

✔️ Awesome, I've got everything!

Great. Double check you have saved connect_router.py.

ⓧ I'd like to double check the full code

Here is the complete connect_router.py file. Compare it against yours line by line.

from netmiko import ConnectHandler

device = {
    "device_type": "cisco_ios",
    "host": "192.168.10.10",
    "username": "admin",
    "password": "cisco123",
    "secret": "cisco123",
}

net_connect = ConnectHandler(**device)

output = net_connect.send_command("show ip interface brief")
print("=== Interface Status ===")
print(output)

config = net_connect.send_command("show running-config")
with open("R1-backup.cfg", "w") as f:
    f.write(config)
print("\nConfig backed up to R1-backup.cfg")

net_connect.disconnect()

Secret mission

Multi-Device Backup Script

Your current script automates one router. Your manager has 50. Can you extend your Python skills to loop through all three routers in your lab, back up every config to its own file, and handle failures gracefully so one downed router does not crash the whole job?

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely on your local Windows machine, so there are no ongoing costs.

Resources you used:

  • GNS3 2.2.x application (includes Dynamips, Npcap, and SolarPutty).
  • GNS3 project with three routers (R1, R2, R3), an Ethernet Switch, and a Cloud node.
  • Microsoft KM-TEST Loopback Adapter with static IP 192.168.10.1.
  • Netmiko 4.7.0 Python package.
  • Project files: connect_router.py, backup_all.py, and backup config files (R1-backup.cfg, R2-backup.cfg, R3-backup.cfg).

Keep everything running

No action needed. Choose this if you are still actively building or planning to continue with the next project in this track.

  • Your GNS3 project, routers, Loopback Adapter, and scripts all remain in place.
  • Since everything runs locally, there are no costs while the lab is idle.
  • Netmiko stays installed in your Python environment, ready for future scripts.

Pause - I'll come back to this later

Shut down the running routers to free up CPU and memory while keeping all your files and configuration intact.

  • In GNS3, click the red square Stop All button in the toolbar to stop all routers.
  • Save your project by clicking File > Save Project.
  • Close GNS3. When you reopen the project later, start all devices again and your lab will be exactly as you left it.

Delete - I don't want to use this again

Remove all project resources and start fresh. Follow each step below.

Note your GNS3 data directories:

  • Before closing GNS3, go to Edit > Preferences > General.
  • Write down the paths shown for your projects directory and images directory. You will delete these folders after uninstalling GNS3.

Uninstall GNS3 and Npcap:

  • Press the Windows key and type Add or remove programs. Press Enter.
  • Search for GNS3. Click it and select Uninstall.
  • Search for Npcap. Click it and select Uninstall.
  • Open File Explorer and navigate to the projects directory and images directory paths you noted earlier. Delete both folders.

Remove the Loopback Adapter:

  • Press the Windows key and type Device Manager. Press Enter.
  • Expand Network adapters.
  • Right-click Microsoft KM-TEST Loopback Adapter and select Uninstall device.
  • Confirm the removal when prompted.

Uninstall Netmiko:

  • Open a Command Prompt and run:
pip uninstall netmiko
  • Type y and press Enter when prompted to confirm.

Delete project files:

  • In File Explorer, navigate to the folder where you saved your Python scripts.
  • Delete connect_router.py, backup_all.py, R1-backup.cfg, R2-backup.cfg, and R3-backup.cfg.

Nice Work!

Nice Work!

You just built a fully operational network automation lab from scratch. Three Cisco routers are running real IOS inside GNS3, your Windows PC can reach every one of them over SSH, and a Python script pulls live configuration data without you ever touching the router CLI.

You've learned how to:

  • Build a GNS3 network lab with three Cisco routers running real IOS on your Windows machine, connected to your host PC through a loopback adapter for direct communication.
  • Configure SSH from scratch on Cisco routers, including RSA key generation, local user accounts, and VTY line configuration for remote access.
  • Write a Python script using Netmiko that connects to a live router over SSH, pulls interface data, and saves the running configuration to a backup file.
  • Secret Mission: Built a multi-device backup script that loops through all routers, saves individual configs, handles connection failures gracefully, and reports results.

Ready to quiz yourself?