Saturday, June 30, 2018

Ansible REST API - Interacting with Cisco FirePower Management Center (FMC) - 02 - Flow Charts of the scripts

This post belongs to my "Ansible REST API - Interacting with Cisco FMC" series. The following is the table of content of this series: 

  1. Introduction and Ansible playbook download
  2. Script flow charts
  3. Introduction of REST API and Cisco FMC API Explorer
  4. Script prerequisites
  5. Request Access Token 
  6. Get policy content, modify content and "PUT' in FMC - Part 1
  7. Get policy content, modify content and "PUT' in FMC - Part 2 
  8. Get deployable devices and deploy policy
First, let me show you how the work flows look like with the scripts:

Here is the flow chart which shows how to disable the specified policy rule:

click the image to expand
And the following is the flow chart which shows how to enable the specified policy rule. You can see they are pretty much the same as the above script:
click the image to expand
In the next post, I will talk about the "REST API basic and the Cisco FMC API Explorer". 

Sunday, June 17, 2018

LInux 101 - Enable SSH key based authentication

SSH Key based authentication allows a user to login to the remote Linux server without providing the username/password. Key based authentication works with a pair of public/private keys. The public key of the client is stored in ~/.ssh/authorized_keys on the server. The private key is kept in the client machine.

The following are the steps of authentication process:

a. User starts the SSH process by specifying key pair to be used. Then the client machine sends the SSH connection request to the server with the Key ID.

b. The server checks its ~/.ssh/authorized_keys and try to find the public key with the Key ID. Once the Key is found, the server will generate a random number and encrypts this number with the found public key.

c. The client machine decrypts the message sent by the server with its private key and obtain the random number.

d. The client machine will calculate a MD5 hash value with the "obtained random number + the session key" and send this MD5 value back to server.

(Noted: this "obtained random number + the session key" value will also be used to encrypt the communication messages between client and server later on.)

e. The server will calculate the MD5 value of "obtained random number + the session key" and compare it with the one received from the client. If they are matching, the SSH request is granted.

The follow will describe the steps of configuring the SSH key based authentication:

Step 1: Create SSH keys on the client machine

#mkdir -p $HOME/.ssh
#chmod 0700 $HOME/.ssh
#cd ~/.ssh

# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/
The key fingerprint is:
b3:7b:be:1a:7f:66:c9:01:ea:28:f4:36:09:ec:6e:3e root@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|                 |
|          .      |
|   .    S. .     |
|    +   .o  .    |
|   o o +o  . o   |
|    E * .+. *    |
|   +o+ .o++=     |

After this step, we will have the private key and public key:

$HOME/.ssh/id_rsa– private key.

$HOME/.ssh/ – public key.

Step 2: Copy the public key to your remote SSH server

[root@localhost ~]# ssh-copy-id root@
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@'s password: (here is the remote SSH server login password)

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@'"
and check to make sure that only the key(s) you wanted were added.

Step 3: Initial the SSH session from the client machine by specifying the key to be used

specifc the prviate key (~/.ssh/id_rsa) to be used:

ssh -i ~/.ssh/id_rsa root@ 

SSH key based authentication is widely used. In my previous post "
Network Automation 02 - Ansible Play book for FTP server file synchronisation
", we use key based authentication for the "rsync".

Linux 101 - Setup FTP/SFTP server in Centos

1. Install vsftpd and enable the service, open the firewall port    

# yum install vsftpd

# systemctl start vsftpd
# systemctl enable vsftpd

# firewall-cmd --zone=public --permanent --add-port=21/tcp
# firewall-cmd --zone=public --permanent --add-service=ftp
# firewall-cmd --reload

2. Configure the FTP server:

# cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.orig

vi vsftpd.conf


# the above folder needs to be existed

3. Fix the SELinux for vsftpd

# setsebool -P allow_ftpd_full_access 1

4. Create user for FTP access

# useradd -m -c “dennis” -s /bin/bash dennis
# passwd dennis

Changing password for user dennis.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

# echo "dennis" | tee -a /etc/vsftpd.userlist
# cat /etc/vsftpd.userlist

5. Create Secure FTP

# mkdir /etc/ssl/private

# openssl req -x509 -nodes -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem -days 365 -newkey rsa:2048

Country Name (2 letter code) [XX]:IN
State or Province Name (full name) []:Lower Parel
Locality Name (eg, city) [Default City]:Mumbai
Organization Name (eg, company) [Default Company Ltd]
Organizational Unit Name (eg, section) []:Linux and Open Source
Common Name (eg, your name or your server's hostname) []:tecmint
Email Address []

# firewall-cmd --zone=public --permanent --add-port=990/tcp
# firewall-cmd --zone=public --permanent --add-port=40000-50000/tcp
# firewall-cmd --reload

# vi /etc/vsftpd/vsftpd.conf








# systemctl restart vsftpd

Saturday, June 16, 2018

Network Automation 02 - Ansible Play book for FTP server file synchronisation

In the last post, I introduced a Ansible playbook which can collect the updated router/ switch configuration files at regular intervals. However, saving the configuration files in the Ansible server is not a particular way to store those files. Because, in this way, you will have to allow the other users to login into this Ansible server and fetch the required configuration files. This may cause performance and security issues of this Ansible server. So, in our design, we build a central FTP/Web server. And the remote Ansible Servers collect the configuration files and synchronise those files with the central server.

The topology is shown as the follow diagram:


There are a couple of prerequisite steps we need to completed before writing our Ansible Run book.

1. Install rsync on the every server including the remote Ansible Servers and the Central Server.

yum install rsync

2. Generate the Vault File

If the Vault file has been build in the previous config collection post, then ignore this step.

3. Install the FTP server in the central server

Please check my post to describe about how to setup FTP/SFTP server.

Step 1: Configure the host file



Step 2: Configure the host var login file


ansible-vault create ftp

  ansible_ssh_pass: 123456
  ansible_ssh_user: root

Step 3: Create the Site YML file


  - hosts: ftp
    gather_facts: no
    become: no
      - ftp-sync

Step 4: Initial the Ansible role "ftp-sync"


ansible-galaxy init ftp-sync

Step 5: Configure the tasks in "ftp-sync" role

This task will login to the central FTP server and synchronise the files from the local folder "/etc/ansible/backup" to the central server.

cd /etc/ansible/roles/ftp-sync/tasks/
vi main.yml

  - name: syn files
      src: /etc/ansible/backup
      dest: /var/ftp/ansible/backup set_remote_user=no

Step 6: Enable SSH key based authentication on the Ansible server to bypass the password prompt in "rsync"

Ansible will utilize "rsync" to synchronise the files between the source and destination folders.

Although Ansible has the username/password to login to the Central server, the "rsync" doesn't have those details. So in order to avoid the "password prompt" pop up, we can enable SSH key based authentication for the Ansible Server on the Central server.

Please check my other post which describe how to enable SSH key based authentication for Linux.

Step 7: Setup CRON

# crontab /etc/crontab

# vi /etc/crontab

*/5 * * * * ansible-playbook /etc/ansible/ftp.yml
# every 5 minutes


This Ansible playbook achieve our gold to synchronise the configuration files collected by the remote Ansible server to the central storage server. The the users can fetch the configuration files from the central server via FTP, SFTP or HTTP.

Wednesday, June 13, 2018

Network Automation 01 - Ansible Play book for Cisco configuration backup

In this blog, I would like to introduce one of my Ansible playbooks. The function of this playbook is to collect the updated Cisco IOS device configurations in a defined interval. Only the updated configuration file will be kept.

1. Create a vault password file

echo "myvault" > ~/.vault_pass.txt
chomd 0600 ~/.vault_pass.txt

So this "vault_pass.txt" file has the "0600" privilege for the current user. And the "myvault" is the encryption key to encrypt other device login details which we will use later on.

2. Put the file path in the “ansible.cfg”

vault_password_file = ~/vault_pass.txt

Step 1: Configure the hosts file:

A-RTR01 ansible_host= ansible_hostname=A-RTR01

A-SWT01 ansible_host= ansible_hostname=A-SWT01


B-SWT01 ansible_host= ansible_hostname=B-SWT01
B-SWT02 ansible_host= ansible_hostname=B-SWT02
B-SWT03 ansible_host= ansible_hostname=B-SWT03


Step 2: Create the login detail file which encryption

cd /etc/ansible/group_vars/all/
ansible-vault create vault

******* the following is the content of the vault file *******

  customerA_ssh_username: cisco
  customerA_ssh_pass: ciscoA
  customerA_enable_pass: ciscoA

  customerB_ssh_username: cisco
  customerB_ssh_pass: cisco
  customerB_enable_pass: cisco

Step 3: Create the Group Var files

Ansible will try to find the Group Vars for the groups in the Inventory file under the “/group_vars” folder. In this example, we have “customerA” & “customerB” groups in the hosts file. So we can setup two vars files with the same name under the “/etc/ansible/group_vars/”.

cd /etc/ansible/group_vars/
vi customerA

    host: "{{ ansible_host }}"
    username: "{{ customerA_ssh_username }}"
    password: "{{ customerA_ssh_pass }}"
    auth_pass: "{{ customerA_enable_pass }}"
    transport: cli

cd /etc/ansible/group_vars/
vi customerB

    host: "{{ ansible_host }}"
    username: "{{ customerB_ssh_username }}"
    password: "{{ customerB_ssh_pass }}"
    auth_pass: "{{ customerB_enable_pass }}"
    transport: cli

Step 4: Create a site yml file
You can execute the role by:

ansible-playbook sc.yml

vi sc.yml

  - hosts: customerA
    gather_facts: no
    connection: local
      - saveconfig

  - hosts: customerB
    gather_facts: no
    connection: local
      - saveconfig

Step 5: Initial the Ansible Role

ansible-galaxy init saveconfig

Step 6: Setup the default variable in the "saveconfig" role

The default variable we would like to setup is the backup folder on the local server.

vi main.yml

  backupdir: /etc/ansible/backup

Step 7: Tasks in the roles (save configuration on the local Ansible server)

vi main.yml

# tasks file for saveconfig

# get the time for the current save file
  - name: get time
    local_action: command date +%Y%m%d%H%M%S
    register: time

# get the current running config form the destination device
  - name: run 'show run'
      provider: "{{provider}}"
      authorize: yes
        - show run
    register: config

# if there is not an existing folder for the destination device, create one
  - name: ensure the directory exists
      path: "{{backupdir}}/{{inventory_hostname}}"
      recurse: yes
      state: directory

# get the file list from the destination device folder
  - name: Get files in a folder
      paths: "{{backupdir}}/{{inventory_hostname}}"
    register: found_files

# get the latest file attributes if the folder is not empty
  - name: get the latest old file
      latest_file: "{{ found_files.files | sort(attribute='mtime',reverse=true) | first }}"
    when: found_files.matched != 0

# get the stat of the latest old config
  - name: get the stat of the old config
      path: "{{latest_file.path}}"
    register: oldconfig_stat
    when: found_files.matched != 0

# save the new config file to folder
  - name: save output to {{backupdir}}
      content: "{{config.stdout[0]}}"
      dest: "{{backupdir}}/{{inventory_hostname}}/config_{{inventory_hostname}}_{{time.stdout}}.txt"

# get the stat of the new config
  - name: get the stat of the new config
      path: "{{backupdir}}/{{inventory_hostname}}/config_{{inventory_hostname}}_{{time.stdout}}.txt"
    register: newconfig_stat
    when: found_files.matched != 0

# if the new config is the same as the latest old config, delete the new config file, delete the new file if it's the same
  - name: compare the new config and the latest old config
      state: absent
      path: "{{backupdir}}/{{inventory_hostname}}/config_{{inventory_hostname}}_{{time.stdout}}.txt"
      - found_files.matched != 0
      - newconfig_stat.stat.checksum == oldconfig_stat.stat.checksum

# if the new config is different than the latest old config, do nothing

Step 8: Setup the CRON

crontab /etc/crontab

 vi /etc/crontab

*/15 * * * * ansible-playbook /etc/ansible/sc.yml
# every 15 minutes


In this playbook, we achieve the gold to save the updated configuration in every 15 mins. But this playbook is not perfect as users have to login to the local Ansible server to get the configuration files. In the next post, I will introduce another play book to synchronise the configuration files to the central file server. So users only have to access the central file server.

NSX Load Balancer "Application Rules" Examples:

Load Balancing is one of the features provided by the NSX Edge Services Gateway (ESG). It can provide L7 Load Balancing by utilizing the HA...