Table of contents

Categories

Category cover

Automation
34 posts

Category cover

Notes
19 posts

Category cover

Security
19 posts

Category cover

Personal Security
14 posts

Category cover

Infrastructure
10 posts

Category cover

CISO
9 posts

Category cover

OT/ICS
5 posts

Category cover

UNetLab
3 posts

Category cover

Write-up
3 posts

Category cover

Books
2 posts

Category cover

OSInt
2 posts

Category cover

My life
1 posts

One-time commands on Cisco IOS with Ansible

Andrea Dainese
September 25, 2023
Post cover

In this article, we present an initial example of executing mass commands using Ansible on Cisco IOS devices. We will utilize the pre-configured “Cisco Legacy Core-Access topology” lab available in the repository DevNetOps course material:

Lab topology

Firstly, we need to create an inventario. At this stage, we won’t delve deeply into the topic, but simply create a file containing all the devices present in the lab and the necessary variables, such as:

  • ansible_host: the IP address of the device, as we don’t have a DNS system for automatic resolution;
  • ansible_user: the user (admin) to access the device;
  • ansible_ssh_pass: the password (cisco) to access the device;
  • ansible_connection: the connection mode Ansible should use to connect;
  • ansible_network_os: the type of device.

The inventory.yml file will look like this:

all:
  hosts:
    sw1.example.com:
    ansible_host: 169.254.1.101
    ansible_user: admin
    ansible_ssh_pass: cisco
    ansible_connection: ansible.netcommon.network_cli
    ansible_network_os: cisco.ios.ios

Since we are working with devices that only support outdated algorithms, we need to specifically enable them. We will do this by working on an SSH client config file named ansible_libssh.conf:

KexAlgorithms diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
HostKeyAlgorithms ssh-rsa,ssh-dss

Host *
    ServerAliveInterval 5
    ServerAliveCountMax 3

In theory, it would be sufficient to specify only the algorithms to add, prepending the symbol +. However, in my tests, this syntax might cause issues. Therefore, I suggest defining all the algorithms we will need in our tests.

The ansible_libssh.conf file will be referenced by the ansible.cfg file, which defines the settings of the libssh library:

[persistent_connection]
ssh_type = libssh

[libssh_connection]
host_key_checking = false
look_for_keys = false
config_file = ../ansible_libssh_conf

Next, we start the nodes and verify that they are reachable:

ansible all -i inventory.yml -m ping

The above command executes a so-called ad-hoc command. In other words, we ran the ping command on all devices configured in the inventory.

Similarly, we can decide to execute a command on all devices:

ansible all -i inventory.yml -m cisco.ios.ios_command -a "commands='show version'"

We can adjust the number of parallel processes running the playbook. This number depends on available resources, particularly the number of CPUs, but not limited to that. Running a playbook involves “idle times,” i.e., time when the Ansible machine is waiting for output from the device. For Cisco devices, consider the time elapsed from entering the show running-config command to actually seeing the output on the screen. Therefore, we can safely increase the number of forks to double the available processors without risking overloading the Ansible controller:

[defaults]
forks = 8