Archive
, Super Contributor
Archive
Junos NETCONF and SSH tunneling (Part 2)
11.04.13

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:

 

[jeremy@jeremy-pc.corp.net]$ ssh -s srx3600.jumpy netconf
Warning: Permanently added '[localhost]:8001' (RSA) to the list of known hosts. <!-- No zombies were killed during the creation of this user interface --> <!-- user jeremy, class j-super-user --> <hello> <capabilities> <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>22595</session-id> </hello> ]]>]]>

 

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 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/interface.

     

  2. Your network/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 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-tunnelled environment.  Let's say I simply want to connect to the Junos device, display the serial-number and version, and then close the connection.  It would look like the following:

 

from jnpr.junos import Device

dev = Device(host='srx3600.corp.net', user='jeremy', password='logmein')

dev.open()

print dev.facts['serialnumber']
print dev.facts['version']
dev.close()

 

The above example illustrates making a connection providing the user name 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:

 

from jnpr.junos import Device

# srx3600-1.jumpy uses port 8001 dev = Device(host='localhost', port=8001, user='jeremy') dev.open() print dev.facts['serialnumber'] print dev.facts['version'] 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 host name 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 host name defined in the config file, e.g. "srx3600-1.jumpy":

 

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

 

(UPDATED NOTE: 2014-Apr-15:  The above paramiko code is *not* required as of later version of the py-junos-eznc module.  This functionality was directly incorporated into the "Device" class.  So long as you have an SSH config file defined correctly and an active SSH tunnel, you will be able to connect through a jumphost when you invoke the Device.open() method).

 

JUNOS AUTOMATION WITH PYTHON

 

Writing Python scripts for Junos 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.

 

 

 

 

02.13.14
lukasb

Hi,

 

I'm getting hello message, but then I get stuck when trying directly ssh in on error below

 

Traceback (most recent call last):
  File "SRX_ssh_v2.py", line 7, in <module>
    dev.open()
  File "/usr/local/lib/python2.7/site-packages/jnpr/junos/device.py", line 236, in open
    hostkey_verify=False )
  File "/usr/local/lib/python2.7/site-packages/ncclient/manager.py", line 76, in connect_ssh
    session.connect(*args, **kwds)
  File "/usr/local/lib/python2.7/site-packages/ncclient/transport/ssh.py", line 181, in connect
    raise SSHError("Could not open socket to %s:%s" % (host, port))
ncclient.transport.errors.SSHError: Could not open socket to 10.2.77.31:830
[root@Linux-helper SRX]# 

 

02.13.14
lukasb

Sorry,  forgot to mention that it netconf appers to be configured correctly

 

root@fw201> show version               
Hostname: fw201
Model: srx240h
JUNOS Software Release [11.1R4.4]


root@fw201> show configuration | match netconf | display set
set system services netconf ssh

02.13.14

@lukasb,

 

For SRX devices, you will also need to enable the protocol on the zone/interface.  So if you are using ge-0/0/0 for your connectivity for NETCONF, find the zone that has ge-0/0/0.  Then on that interface check the host-inbound-services configuration to make sure that ssh/netconf is enabled.

 

Hope that helps!

 

02.25.14
jkloots

Hi,

 

I'm trying to run the sample test script on a T1600 box with netconf configured:

 

jac@re1-willem> show version
Hostname: re1-willem
Model: t1600
JUNOS Base OS boot [12.3R4.6]

 

$ ssh -s jac@willem.surf.net netconf
jac@willem.surf.net's password: 
<!-- No zombies were killed during the creation of this user interface -->
<!-- user noc, class j-super-user-local -->
<hello>
  <capabilities>
    <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>318</session-id>
</hello>
]]>]]>

 

Running the first sample script returns an error:

 

$ python test.py
No handlers could be found for logger "paramiko.hostkeys"
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    dev.open()
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/device.py", line 239, in open
    self.facts_refresh()
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/device.py", line 403, in facts_refresh
    gather(self, self._facts)
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/facts/personality.py", line 29, in personality
    raise RuntimeError("Unknown device persona: %s" % examine)
RuntimeError: Unknown device persona: T1600

Is T-series not supported?

 

 

02.26.14
jkloots

I Think I found the answer

 

https://github.com/Juniper/py-junos-eznc/blob/abba945af1e04abd56545fd83848d44f3d924a9b/lib/jnpr/juno...

 

No T-series defined in there, bummer Smiley Sad any change on getting this in there?

03.07.14

@jkloots,

 

The py-junos-eznc can add support (recognicition) for the T-series.  You could also "hack" the code if you'd like.  There is a simple regex match if/then/else block of code in the personality.py file.  You could add what you need there.

 

https://github.com/Juniper/py-junos-eznc/blob/master/lib/jnpr/junos/facts/personality.py

 

Maybe something like:

 

  elif examine.startswith("T"):
    persona = "T"

 

If you make the patch, and would like to upstream the fix to the code base, please do!  You can find steps on this process here:

 

http://lamejournal.com/2013/12/04/github-edit-juniper-ez-library/

 

03.07.14

Alternatively, please open an "issue" on the github repo here:

https://github.com/Juniper/py-junos-eznc/issues

 

And one of the engineering team guys will work on it.

 

Thank you again, and apologies for the delay responding.

03.27.14
Abdullah Aamer

I know this might be an off topic question, but I cant find support for this module anywhere else. I am having problem installing this module on python 3.4 win 7. I have ncclient, lxml, scp, pyyaml, and netaddr which was the requirement. I am getting error the following:

 

From CMD "python setup.py install

File "setup.py", line 24

print "Sorry, Python 3 is not supported (yet)"

SyntaxError: invalid syntax

03.28.14

@Abdullah,

 

You are trying to use Python version 3.4.  Only Python 2.7 is supported at this time.  You may have Python 2.7 installed on your system, but it might not be the default "python".  Please check for python2.7 executable.  If you do not have it, you will need to install it.

 

Hope this helps!

04.29.15
dalonso@adexus.cl

Hi 

 

Im trying to install the app in windows, my device accept the netconf connection but when i try to runn the scipt an error is returned

 

C:\Python27\scripts>xSet_Routing_Instance.py
Traceback (most recent call last):
File "C:\Python27\scripts\xSet_Routing_Instance.py", line 6, in <module>
dev.open()
File "C:\Python27\lib\site-packages\jnpr\junos\device.py", line 451, in open
raise cnx_err
jnpr.junos.exception.ConnectError: ConnectError(100.100.100.11)

 

Any advice

 

Thanks

 

C:\Python27\scripts>pip list
ecdsa (0.13)
Jinja2 (2.7.3)
junos-eznc (1.1.2)
lxml (3.4.4)
MarkupSafe (0.23)
ncclient (0.3.2)
netaddr (0.7.14)
paramiko (1.15.2)
pip (6.1.1)
pycrypto (2.6.1)
PyYAML (3.11)
scp (0.9.0)
setuptools (15.2)