Ansible Project: Network Security Audit 3 – ios_acl Module

As I have been going through my list of configuration items for the security audit, I have only used Ansible to send commands. I haven’t used the ios_config module for any of its other abilities like interface configuration, gathering facts or ACL configuration.
This post will cover 2/3 of those. Gathering facts, specifically ACL facts and ACL configuration.

A great resource I used for this post can be found on the Ansible website blog. It covers more of the ACL configuration differences that can be performed. I did run into a couple of issues, so I’ll note them down.

The playbooks I will use here can be found on my GitHub.

Gathering ACL Configuration and Creating ACL Host Vars

The gathering of the current ACLs and saving them as host_vars is important. The ios_acls module creates the ACLs in a specific format that would be time-consuming and frustrating to manually create.

Current ACL. Very basic standard ACL.

Ansible will need a variable that looks like the below. This is readable, if you compare to the Cisco config above. It’s very long and not easily readable. Nobody wants to manually create this.

To avoid manually creating the ios_acl module can do it and save it in the correct location for host_vars. Although I am going to use this as a group_var, so I will just manually copy the yaml over.

I did have an issue with the resulting host_var files. The last line of my ACL is a deny any.

The deny any line on 210 is similar to the host line on 10. The ios_acl has interpreted the “any” as a hostname. This causes an error when the ACL is run as the command “210 deny host any” is sent to the device, resulting in an error.

To fix this I simply opened the yaml file where the ACL variable is and changed the key of “host” for “address”. This worked, and the ACL can be applied successfully.

This does cause problems with the ability for Ansible to compare the ACL that is gathered from the device and to what the group_var has. They will always be different due to ios_acl incorrectly assuming that “any” is a host.
The only solution to this is to remove the explicit deny statement from the ACL.

Configuring Devices With ACLs

Now that the ACL in yaml format has been added to the group_vars file (below). The next step is to create a playbook that can use this to make changes.

The ACL configuration playbook will utilise the ios_acl module, and therefore it’s very easy to configure as the complex checking is handled by the module.
For this configuration, I have chosen to use the “replaced” state for the ACL configuration.
This means that the ios_acl will remove the ACLs referenced in the group_vars file before applying the correct ACLs.

In my example case, there is only a single ACL in the group_vars, ACL 99. So if there were another ACL, say ACL 10 on the device, this one would not be touched, it will remain as last configured.

The below playbook will simply remove entries in ACL 99 and then apply the entries from the group_vars file. This task will always show as changing the configuration. There is no comparison taking place to check if it is required.

The output of this playbook.

The ACL 10 is still present after the change. As this is not in the group_vars file, it is not modified by Ansible.

Configuring ACL 99 on VTY Lines

I have left the configuration of the VTY lines to the very last step. I had hoped to perform a comparison of the ACL 99 applied on the device with what is in the group_var. However, they do not match, due to my workaround and also because they are named differently. A comparison using “show run” commands is probably easier.

Leave a Comment

Your email address will not be published. Required fields are marked *