Skip to content

AyanAhmed2000/Automated-Router-Reset-for-cisco-ir809

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Automated Router Reset - Cisco IR809

Abstract

This project automates the factory reset process of Cisco IR809 routers using Python over a serial connection. Instead of manually resetting each router through terminal programs like picocom or screen, the scripts handle the entire process automatically, from login and configuration cleanup to reboot and ROMMON-2 handling.

Author: Ayan Ahmed
Publication Date: Spring 2026

Table of Contents

  1. Introduction
  2. Goals and Objectives
  3. Method
  4. Target Audience
  5. Document Status
  6. Disclaimer
  7. Scope and Limitations
  8. Environment
  9. Acknowledgments
  10. Implementaion
  11. Conclusion
  12. References

Introduction

Welcome! I'm Ayan Ahmed, an IT intern at The Swedish Meteorological and Hydrological Institute (SMHI) during spring 2026. I'm studying Networking, Infrastructure and Cybersecurity at Jönköping University a program that provides both theoretical and practical knowledge in network design, IT infrastructure and cybersecurity. This is my 9-week internship project, carried out within the IT-infrastructure department. The project focuses on automating the decommissioning process of older routers stored at SMHI's facilities. Previously, resetting each router required manual work for every single device. The goal was to build a scalable and reusable solution that can be applied to future decommissioning of other router models as well.

Goals and Objectives

The goal of this project is to develop an automated solution for factory resetting Cisco IR809 routers.
The solution should:

  • Handle the full reset process without manual intervention
  • Automatically identify the correct USB port and log in to the router
  • Clean all configuration files from flash and nvram
  • Handle the ROMMON-2 boot issue that arises after wiping the router
  • Support parallel handling of multiple routers simultaneously

Method

The project is divided into four sub-projects that together build a fully automated factory reset pipeline. Python was used together with the pyserial library for serial communication. Login credentials are stored securely in a .env file.Threading was used to enable parallel resets across multiple routers connected via a USB hub.

Target Audience

This repository is for anyone who needs to automate the factory reset of Cisco IR809 routers. It is also useful for anyone interested in Python-based serial communication and router automation in general.

Document Status

This repository is considered complete and officially published. Future improvements, refinements, or corrections may be introduced through controlled updates. Any changes will be versioned and documented in the commit history.

Disclaimer

Caution

The Scripts for this project are developed and tested against Cisco IR809 routers at SMHI facilities. It is not intended for production use without proper review and adaptation. Use at your own risk.

Scope and Limitations

The solution is developed and tested specifically for the Cisco IR809 router model.

  • The scripts communicate via a physical console cable over a serial connection.
  • The reset process requires the router to be powered on and physically connected via USB.
  • The solution does not support remote or network-based resets.
  • Instructions may become outdated as software updates; always verify with official documentation.

Environment

Asus PN64 ax210NGW:

  • Intel® Core™ i7-12700H
  • 1TB disk
  • 64 GB memory
  • Operating System: Linux (Ubuntu)

Router:

  • Cisco IR809G-LTE-GA-K9
  • IOS Version:15.6(3)M / 15.6(3)M1b

Python:

  • 3.x

Libraries:

External libraries:

  • pyserial
  • python-dotenv

Built-in Python modules:

  • time
  • os
  • glob
  • subprocess
  • re
  • threading
  • sys

Connection:

  • USB console cable, USB hub (for parallel handling)

Acknowledgments

I would like to thank my supervisors Robert Brokull and Rafael Urrutia Silva for their continuous support, guidance, and for providing access to the hardware needed for testing throughout this project. I would also like to thank Jonatan Högild for his support with brainstorming ideas and problem-solving during the whole process.

Implementation

Managing Login Credentials

To avoid storing sensitive information directly in the code, login credentials are saved in a .env file locally on the machine. The Python script reads them using environment variables via os.getenv(). The file is protected by .gitignore to ensure it is never uploaded to GitHub.

create the .env file

bash
touch .env
nano .env

.env file structure:

ROUTER_USERNAME=username
ROUTER_PASSWORD=password
ROUTER_ENABLE_PASSWORD=enable_password 

⚠️ The ROUTER_ prefix is used to avoid conflicts with Linux system variables, such as USERNAME which is already reserved by the system.

Save the file

Press CTRL + X, then Y, then ENTER to save and exit Nano.

create the .gitignore file

bash
touch .gitignore 
nano .gitignore 

Add this inside .gitignore

.env

Save the file

Press CTRL + X, then Y, then ENTER to save and exit Nano.

As an alternative, Ansible Vault was also explored, which encrypts credentials unlike the .env file which stores them in plaintext. However, the .env method was chosen for its simplicity and ability to fully automate the process without manual input. The key difference is that Ansible Vault is more secure since credentials are encrypted, but requires either manual input of the vault password each time, or storing it in a separate file, which in practice gives the same security level as the .env approach.

Connecting to the Router

The pyserial library was used to communicate with the router over a serial connection, replacing the manual work done in terminal programs like picocom and screen. The script automatically identifies the active USB port and logs in to the router, entering enable mode.

Installation:

bash
pip install pyserial python-dotenv 

or

bash
pip3 install pyserial python-dotenv

Step-by-step execution

  1. Create the connection script:
bash
touch connection.py
nano connection.py
  1. Add the following script to the file:

See Code/connection.py

  1. Save the file:

Press CTRL + X, then Y, then ENTER.

  1. Test the script:
bash
python3 connection.py

Prerequisites:

  • Physical console cable connected between the computer and the router
  • Router powered on
  • Console port identified via ls /dev/ttyUSB*

Issues encountered:

Issue Solution
pyserial didn't work properly Switched from pexpect, screen, and picocom to only using pyserial
Wrong USB port Checked the correct port with ls /dev/ttyUSB*
Device or resource busy error Closed active screen sessions with screen -X quit
Wrong variable names in .env Made sure the variable names matched in both files
Timeout issues Increased time.sleep() from 2 to 6 seconds

Result:

1: '\r\nrt-router-hostname>\r\nrt-router-hostname>' 
Logged in!
4: 'enable\r\nPassword: '
5: '\r\nrt-router-hostname#\r\nrt-router-hostname#'
Enable mode activated!

Resetting the Router Configuration

This is the core of the project. The work builds on the connection code from the previous sub-project and extends it with full configuration cleanup and reboot handling. The result is two scripts. reset.py Cleans the router configuration by:

  • Automatically identifying the USB port using a loop
  • Logging in with up to 10 attempts
  • Running write erase to clear startup-config
  • Automatically identifying and removing configuration files from flash and nvram via clean_flash() and clean_nvram()
  • Rebooting the router

fix_rommon.py Handles the ROMMON-2 issue that arises after the reset by:

  • Automatically detecting ROMMON-2
  • Looping until the IOS file is found in flash memory
  • Setting the boot variables BOOT and BOOT_IOS_SEQUENCE
  • Booting the router
  • Saving the boot variable permanently via write memory

Step-by-step execution

  1. Create the reset script:
touch reset.py
nano reset.py

The following script was added to the file:

See Code/reset.py

  1. Save the file:

Press CTRL + X, then Y, then ENTER.

  1. Create the ROMMON fix script:
touch fix_rommon.py
nano fix_rommon.py

The follwing script was added to the file:

See Code/fix_rommon.py

4.Save the file:

Press CTRL + X, then Y, then ENTER.

  1. Run the reset script:
python3 reset.py
  1. Wait a few seconds, then run the ROMMON fix script:
python3 fix_rommon.py

Or run both scripts together:

python3 reset.py && sleep 5 && python3 fix_rommon.py

Issues encountered

Issue Solution
Router entered ROMMON-2 after write erase Created fix_rommon.py
Boot variable was not saved after reboot Used no boot system, boot system flash:<file>, and write memory
BOOT_IOS_SEQUENCE=0 prevented automatic boot Set the value to 20
USB port was not found Added a loop that retries until the port is found
Enable mode was not reached Added a login loop with up to 10 attempts
Configuration dialog appeared after reboot Automatically answered no
Not all files were deleted Implemented clean_flash() and clean_nvram()
IOS file was not found on the first try Added a loop that retries until the file is found

Parallel Handling

To speed up the reset process when working with multiple routers, parallel_reset.py was developed. The script uses Python threading to reset several routers at the same time through a USB hub. This reduces the total time compared to resetting one router at a time.

Features

  • The number of routers is given as an argument when running the script
  • The script waits until the correct number of USB ports are found
  • One thread is started for each router
  • Each router is reset independently
  • The script prints how many routers have been completed

Step-by-step execution

  1. Create the parallel reset script:
touch parallel_reset.py
nano parallel_reset.py
  1. Add the following script to the file:

See Code/parallel_reset.py

  1. Save the file:

Press CTRL + X, then Y, then ENTER.

  1. Run the script:
python3 parallel_reset.py
  1. Run the script with a specific number of routers:
python3 parallel_reset.py 3

Issues encountered

Issue Solution
Threads interfered with each other Each thread got its own variables and serial port
Completed router count was incorrect Used threading.Lock() for safe counting
USB ports were not found immediately Added a loop that waits until the correct number of ports are found

Conclusion

The aim of this project was to automate the factory reset process of Cisco IR809 routers and build a reusable solution for future router decommissioning. I believe that this goal was successfully achieved.

This project was both interesting and challenging in several ways, especially when working with ROMMON-2 issues, boot variables, serial communication, and running resets in parallel. Many problems appeared during development, but solving them helped create a better understanding of how Cisco routers work internally.

The final solution supports fully automated factory resets of multiple routers at the same time, which is a clear improvement compared to the previous manual process. The result is a practical and flexible tool that can also be adapted for similar router models in future projects.

References

About

Automated factory reset solution for Cisco IR809 routers using Python and serial communication.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages