Book Image

JUNOS Automation Cookbook

By : Adam Chappell
Book Image

JUNOS Automation Cookbook

By: Adam Chappell

Overview of this book

The JUNOS Automation Cookbook is a companion guide for the complex field of automating tasks on JUNOS devices. With a foundation in industry-standrd XML, JUNOS provides an ideal environment for programmatic interation, allowing you to build upon the capabilities provided by Juniper, with your own original code. You will begin by learning about, and setting up, the industry-standard NETCONF remote procedure call mechanisms on your device. After initial setup, you'll walk through SLAX - Juniper's foundation scripting language - for manipulating XML representations of JUNOS concepts and elements. You'll learn how to write your own SLAX scripts to customise the operating environment, and also how to write proactive event handlers that deal with situations as they happen. You'll then delve into PyEZ - Juniper's bridging framework to make automation accessible to Python code - allowing you to build automation applications in the popular scripting language. You'll witness some examples of how to write applications that can monitor configuration changes, implement BGP security policies and implement ad-hoc routing protocols, for those really tricky situations. You'll also leaarn how asynchronous I/O frameworks like Node.js can be used to implement automation applications that present an acceptable web interface. Along with way, you'll explore how to make use of the latest RESTful APIs that JUNOS provides, how to visualize aspects of your JUNOS network, and how to integrate your automation capabilities with enterprise-wide orchestration systems like Ansible. By the end of the book, you'll be able to tackle JUNOS automation challenges with confidence and understanding, and without hassle.
Table of Contents (10 chapters)

JUNOS NETCONF over SSH setup

In this recipe, we'll prepare a JUNOS OS router for interaction using the NETCONF service. We can do this in one of two ways:

  • Using NETCONF-over-SSH on dedicated TCP port 830,
  • Using NETCONF inline with mainstream SSH communications, on TCP port 22.

We'll set up secure SSH keys and a dedicated username for an automation application. Then we'll configure the systems services hierarchy within the Junos OS for the specific method.

Getting ready

In order to complete this recipe, you need access to a JUNOS OS router, switch, or firewall, and a general-purpose Linux/UNIX management host from which to control it.

How to do it...

The steps to prepare a JUNOS OS router for interaction using NETCONF services are as follows:

  1. Verify that SSH is configured on your router by ensuring that you have the following configuration present:
      adamc@router> show configuration system services 
ssh;
  1. Generate SSH keys. Generate a public/private key pair using the SSH utility, ssh-keygen:
      unix$ ssh-keygen -C "JUNOS Automation" -f JUNOS_auto_id_rsa
Generating public/private rsa key pair.
Enter file in which to save the key (.ssh/id_rsa):
JUNOS_auto_id_rsa
Enter passphrase (empty for no passphrase): <type nothing here>
Enter same passphrase again: <again, nothing>
Your identification has been saved in JUNOS_auto_id_rsa.
Your public key has been saved in JUNOS_auto_id_rsa.pub.
  1. Once completed, verify that you have two new files in your working directory:
Filename Description
JUNOS_auto_id_rsa Private SSH key, reserved for use by your management automation application only
JUNOS_auto_id_rsa.pub Corresponding public SSH key (think of it as a certificate) is able to authenticate the private key.
  1. Configure a dedicated user profile to be used for NETCONF access that makes use of the previously generated key-pair. Apply the .pub file contents to the Junos configuration.
      adamc@router> show configuration system login user auto 
uid 2001;
class super-user;
authentication {
ssh-rsa "ssh-rsa [ actual key omitted] JUNOS Automation"; ##
SECRET-DATA
}
  1. Enable a dedicated NETCONF-over-SSH transport endpoint by configuring the following service:
      adamc@router> show configuration system services 
ssh;
netconf {
ssh;
}
  1. Connect to the NETCONF service to witness the protocol greeting and validate the correct operation:
   unix$ ssh -p 830 -i JUNOS_auto_id_rsa [email protected] -s   
netconf
<!-- No zombies were killed during the creation of this user
interface -->
<!-- user auto, class j-super-user -->
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<capabilities>
<capability>urn:ietf:params:netconf:base:1.0</capability>
<capability>urn:ietf:params:netconf:capability:candidate:1.0
</capability>
<capability>urn:ietf:params:netconf:capability:confirmed-
commit:1.0</capability>
<capability>urn:ietf:params:netconf:capability:validate:1.0
</capability>
<capability>urn:ietf:params:netconf:capability:url:1.0?
scheme=http,ftp,file</capability>
<capability>urn:ietf:params:xml:ns:netconf:base:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:
candidate:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:confirmed-
commit:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:
validate:1.0
</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:url:1.0?
protocol=http,ftp,file</capability>
<capability>http://xml.juniper.net/netconf/JUNOS/1.0</capability>
<capability>http://xml.juniper.net/dmi/system/1.0</capability>
</capabilities>
<session-id>35980</session-id>
</hello>
]]>]]>
  1. On the same SSH session, issue a test RPC to prove that things are working normally. Enter the highlighted first line of the following text exactly as it is and observe the response:
      <rpc><get-software-information/></rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS">
<software-information>
<host-name>router</host-name>
<product-model>olive</product-model>
<product-name>olive</product-name>
<JUNOS-version>15.1F6-S5.6</JUNOS-version>
<package-information>
<name>os-kernel</name>
<comment>JUNOS OS Kernel 64-bit [
20161130.340898_builder_stable_10]</comment>
</package-information>
<package-information>
<name>os-libs</name>
<comment>JUNOS OS libs [20161130.340898_builder_stable_10]
</comment>
</package-information>
<package-information>
<name>os-runtime</name>
<comment>JUNOS OS runtime [20161130.340898_builder_stable_10]
</comment>
</package-information>
[…]

How it works...

In step 1, we verified that the SSH protocol was configured and available in order to access the JUNOS device.

In step 2, we created an SSH public/private key-pair in order to allow any applications that we create to be able to login and authenticate with the JUNOS device in the same way that an ordinary user does. Key-based authentication is preferred over conventional password authentication for this, because it removes the authentication step from the interactive dialog under development.

In step 3, we created a dedicated user profile on the JUNOS device for automation applications and associated it with the public key that we created. Any automation application that makes use of the corresponding private key can be authenticated on the JUNOS OS platform with the public key.

With step 4, we created a NETCONF-over-SSH service endpoint. This isn't technically required, but it can be useful if you would like to treat ordinary user management traffic independently from machine-to-machine programmatic access, and want to enforce such policies via a firewall or similar.

In step 5, we connected to the NETCONF-over-SSH service on port 830 and observed its welcome greeting. We used the -i switch in order to specify the private key that we generated in step 2.

NETCONF-over-SSH runs on a separate TCP port to the conventional SSH transport. The default, Internet Assigned numbers Authority (IANA) is 830, but JUNOS OS allows you to select any arbitrary number. When NETCONF-over-SSH is used in this manner, the SSH server makes use of a protocol feature called subsystems. This allows the SSH server to directly connect to another internal component without consideration for details such as pseudo-terminal or user shell.

For this reason though, when we connect from an ordinary SSH client, we need to use the -s switch in order to specify that we want the NETCONF subsystem.

Alternatively, it is possible to connect to the NETCONF service using the convention SSH management interface in the following manner:

unix$ ssh -i JUNOS_auto_id_rsa [email protected] netconf

Finally, in step 6, we issued a very basic RPC request to ask the JUNOS OS device for information about its system software. We can see the regularity in the structure of communications between client and NETCONF server. The client's communications consists of a remote procedure call request, enclosed in <rpc></rpc> tags. And the server responds with a document structure enclosed within <rpc-reply></rpc-reply> tags. The actual internal structure of the response depends on the exact RPC called, but the XML format is easier to machine-read than a free-form text interface designed to please a human.

There's more...

In step 5 and step 6, we saw the guts of the NETCONF protocol dialog occurring. The server said hello to us, and we issued a procedure call which the server duly answered. In actual fact, we were being a little lax in our use of the NETCONF protocol standard there. If you want to speak RFC-compliant NETCONF, it is customary for both the client and the server to issue hello messages that describe their capabilities. The capabilities announced describe concepts over and above some of the base NETCONF principles that are supported by the element, and the manager. In this case, the JUNOS OS server has likely little concern for our client capabilities and takes the IETF mantra of being liberal in acceptance, conservative in communication, to heart.

The other significant point to note is the special sequence of characters used to delimit successive XML messages. We see it at the end of a hello message, and at the end of every RPC response the server answers:

  ]]>]]>

Technically, this framing sequence is actually deprecated within the latest specification of the NETCONF-over-SSH standard, because it was discovered that it can legitimately appear within the XML payload. The JUNOS OS implementation currently makes use of the framing sequence to flag the end of its responses, but if you write software -- as we will -- to read the NETCONF XML stream directly, then it is wise to be aware that this behavior could change in the future.