Scripting How-To: Junos NETCONF and SSH, Part 2

By Elevate posted 08-09-2015 08:23



NETCONF through a Firewall, Part 2.


Junos NETCONF and SSH Tunneling (Part 2)


Verify NETCONF Connectivity

Now that we've established SSH tunneling through the network, we can verify a NETCONF session directly.  When I use the ssh command, I specify the sub-command netconf using the -s parameter, as illustrated.  Note that the netconf sub-command is after the hostname:


01	[]$ ssh -s srx3600.jumpy netconf
03	Warning: Permanently added '[localhost]:8001' (RSA) to the list of known hosts.
04	<!-- No zombies were killed during the creation of this user interface -->
05	<!-- user jeremy, class j-super-user -->
06	<hello>
07	  <capabilities>
08	    <capability>urn:ietf:params:xml:ns:netconf:base:1.<wbr/>0</capability>
09	    <capability>urn:ietf:params:xml:ns:netconf:capabil<wbr/>ity:candidate:1.0</capability>
10	    <capability>urn:ietf:params:xml:ns:netconf:capabil<wbr/>ity:confirmed-commit:1.0</capability>
11	    <capability>urn:ietf:params:xml:ns:netconf:capabil<wbr/>ity:validate:1.0</capability>
12	    <capability>urn:ietf:params:xml:ns:netconf:capabil<wbr/>ity:url:1.0?protocol=http,ftp,file</capability>
13	    <capability></capabili<wbr/>ty>    <capability></capability>  </capabilities>
14	  <session-id>22595</session-id>
15	</hello>
16	]]>]]>

What you see here is the actual NETCONF "hello" message in response to the connection.  If you do not see this, then one of two things is not setup correctly:

  1. Your Junos OS device is not configured with NETCONF enabled.  You can verify this by checking the [edit system services] stanza.  If you are using an SRX, then you also need to enable NETCONF on the security-zone or interface.
  2. Your network or firewall is blocking TCP/830, which is the default port for NETCONF.

You can close the NETCONF session using <Ctrl-C>.

Sample Python Script

I am going to demonstrate a Python script using a module called jnpr.eznc.  This is an active open-source project that is relatively new.  I will write a more detailed blog on this module in the near term, but for now, if you'd like to get started using it, please see the github repo and README files located here.

Let's first take a look at a script that is *NOT* in an ssh-tunneled environment.  Let's say I simply want to connect to the Junos OS device, display the serial-number and version, and then close the connection.  It would look like the following:

01	from jnpr.junos import Device
03	dev = Device(host='', user='jeremy', password='logmein')
07	print dev.facts['serialnumber']
08	print dev.facts['version']
10	dev.close()

The above example illustrates making a connection providing the username and password.  If you are using ssh-keys, then you simply do not provide the password.

Now to do the tunneling use-case, we know that we are connecting through a local port forward.  We could do something like the following:


01	from jnpr.junos import Device
03	# srx3600-1.jumpy uses port 8001
04	dev = Device(host='localhost', port=8001, user='jeremy')
08	print dev.facts['serialnumber']
09	print dev.facts['version']
11	dev.close()

But now we've duplicated information between our script and the ssh config file.  What we really want to do is use the ssh config file to extract the port associated with srx3600-1.jumpy so we can connect by the hostname directly. 

I am using the Python paramiko module to illustrate the technique to load the ssh config file and extract the information based on the hostname defined in the config file, e.g., "srx3600-1.jumpy":


01	import paramiko
02	import os
04	from jnpr.junos import Device
06	# load the $HOME/.ssh/config file and do a lookup on the
07	# host name "srx3600-1.jumpy"
09	config_file = os.path.join(os.getenv('HOME'),'.ssh/config')
10	ssh_config = paramiko.SSHConfig()
11	ssh_config.parse(open(config_file,'r'))
12	got_lkup = ssh_config.lookup( "srx3600-1.jumpy" )
14	# now open the NETCONF connection using the information
15	# we retreived from the ssh config file
17	dev = Device(user='jeremy', host=got_lkup['hostname'], port=got_lkup['port'])
21	print dev.facts['serialnumber']
22	print dev.facts['version']
24	dev.close()

Junos OS Automation with Python

Writing Python scripts for Junos OS automation tasks can be easy (and fun!).  With a little bit of practice and the right set of modules (like jnpr.junos), you can quickly create very powerful automation tools with a high degree of confidence.


Network Automatic Blog - Jeremy Schulman - Nov. 4, 2013.

Reposted with permission to TechWiki.