Archive
, Super Contributor
Archive
Junos NETCONF and SSH tunneling (Part 1)
Nov 1, 2013

Let's say you have a network of devices that are sitting behind a firewall and you can only access them through a jump-host.  This means you need to first login to the jump-host, and from there you can access the devices. 

 

Take for example the following setup: I have a laptop called jeremy-pc.corp.net and a jump-host called jumpy.corp.net.   Behind "jumpy" I've got a few hundred EX switches, a few SRX firewalls, and a few MX routers:  All of the network devices are in the private 10.1.0.0/16 network.  A simplified view:

 

pic2.png

 

In order for my Python programs to connect from jeremy-pc to the SRX and MXs, I need to go through jumpy, I cannot ssh directly to they (which means I cannot open a NETCONF session directly either).

 

In order to make all this work, I need to do the following:

 

  1. Create an ssh-key
  2. Install the public ssh-key on the Junos devices, srx3600-1, mx960-1, and mx960-2
  3. Setup my user account on jumpy.corp.net to allow ssh forwarding
  4. Setup my user account on jeremy-pc.corp.net to ssh-port tunnel
  5. Activate SSH tunnel and ssh-key from jeremy-pc.corp.net, then connect!

Let's go through each of these steps.

 

CREATE SSH-KEY

 
If you are not familiar with the process of generating ssh-keys, it is fairly straight forward, providing you have the ssh utilities installed.  Use the ssh-keygen command to create the public and private keys.  Here I am creating a pair called "jeremykey" (private key) and "jeremykey.pub" (public key).  You will be prompted to enter a passphrase, which I recommend you use.

 

[jeremy@jeremy-pc.corp.net] ssh-keygen -f jeremykey

Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in jeremykey.
Your public key has been saved in jeremykey.pub.

 

INSTALL PUBLIC SSH-KEY ONTO JUNOS DEVICES

 

Now copy your public key file to each of the Junos devices.  You will need to first copy them to your jump-host, and then from there scp them to each Junos device.  Assuming that I've copied the file jeremykey.pub to each Junos device, I can install the key from the Junos CLI, for example on the SRX3600-1 device:

 

jeremy@srx3600-1> configure 
Entering configuration mode

[edit]
jeremy@srx3600-1# set system login user jeremy authentication load-key-file jeremykey.pub 

[edit]
jeremy@srx1400-1# commit and-quit

 

SETUP "JUMPY" FOR SSH AGENT FORWARDING

 

I now need to setup my user account on jumpy.corp.net so that it will forward my SSH connections when I originate them from my laptop, jeremy-pc.corp.net.  To do this, I need to edit the ssh config file in $HOME/.ssh/config so that it looks like this:

 

Host *
  ForwardX11Trusted yes
  ForwardAgent yes
  Protocol 2

 

For more details on the ssh config file, you can do a "man ssh_config".  The above example is considered very open since it applied to all hosts.  You can get very specific on configs, but for the sake of this blog simplicity, we'll leave it like this.

 

Now on to the tricky part, setting up ssh port forwarding ...

 

SETUP "JEREMY-PC" FOR SSH PORT FORWRDING

 

The technique for ssh-port forwarding is to designate ports on jeremy-pc.corp.net that get mapped to specific hosts reachable from jumpy.corp.net.  I can pick any ports that I want, but generally in the range above the range 1024.  I use ports >= 8000.  The following illustrates the mapping I want to create:

pci3.png

On jeremy-pc.corp.net, I create an ssh config file in $HOME/.ssh/config that looks like the following.

 

Host jumpy-tunnel
   Hostname jumpy.corp.net
   ForwardX11Trusted yes
   LocalForward 8001 10.1.0.12:22
   LocalForward 8002 10.1.0.21:22
   LocalForward 8003 10.1.0.22:22
   ControlPath ~/.ssh/master-%l-%r@jumpy:%p
   ControlMaster auto

Host srx3600-1.jumpy
   User jeremy
   Hostname localhost
   Port 8001

Host mx960-1.jumpy
   User jeremy
   Hostname localhost
   Port 8002

Host mx960-2.jumpy
   User jeremy
   Hostname localhost
   Port 8003

Host *
   ForwardAgent yes
   Protocol 2
   StrictHostKeyChecking no
   UserKnownHostsFile=/dev/null

 

There is a lot to dissect in this config file, but the main technique here is that the host jumpy-tunnel is what will be used to setup the port forwarding, then each unique host, e.g. srx3600-1.jumpy, is used to associate a name so we don't need to remember all the port mappings.

 

ACTIVATE SSH-KEY ON "JEREMY-PC"

 

In order for ssh-keys to work, you need to have an "ssh-agent" running and then add your keys to the agent.  Depending on your system, the ssh-agent may be running already.  Here is the process to startup the ssh-agent manually and add your ssh-key:

 

[jeremy@jeremy-pc.corp.net] eval `ssh-agent`
[jeremy@jeremy-pc.corp.net] ssh-add jeremykey

 

The first command starts the ssh-agent process.  The use of eval is needed to capture the ENVIRONMENT variables that are returned by ssh-agent.  The second command loads the ssh-key.  You will be prompted for the passphrase at this point (not shown).

 

The next step is to create the port mapping tunnel to jumpy.  The following command opens an ssh tunnel and puts the process in the background.  Note here that the ssh target is jumpy-tunnel, which was the Host in the ssh config that defined all of the LocalForward definitions.

 

[jeremy@jeremy-pc.corp.net]$ ssh -f -N jumpy-tunnel

 

Now that the tunnel is active, and the ssh-key is active, you can directly ssh to the remote Junos device by referring to the host name defined in the ssh config file.  For example, to ssh directly to the SRX3600-1 device, use the name srx3600-1.jumpy:

 

[jeremy@jeremy-pc.corp.net]$ ssh srx3600-1.jumpy
Warning: Permanently added '[localhost]:8001' (RSA) to the list of known hosts.
--- JUNOS 12.1X44-D20.3 built 2013-07-19 04:28:29 UTC
jeremy@SRX3600-1> 

 

... NEXT IN PART 2

 

In Part 2 of this blog, I will illustrate a Python script that makes a NETCONF connection and performs a basic "hello, world" with the remote device. 

 

Continue reading ...

Part 2

 

Nov 1, 2013
Recognized Expert Recognized Expert
Just when I think I know something back and forward, you come along with something. ;-) Been using this technique for *years*, but only now learned about the "ControlPath" and "ControlMaster" ssh config knobs. Very nice. Thanks! /doug
Nov 8, 2013

Awesome article, Jeremy! Thanks for this!

Dec 4, 2013
tdnguyen

I think it is also working with the ProxyCommand :

 

in the .ssh/config

Host *.lab
    ProxyCommand ssh jumpy.corp.net"nc -q 0 $(basename %h .lab) %p"
    Compression no
    ControlMaster auto
    ControlPath /tmp/ssh_%h_%r

But in this configuration, you need to configure the hosts on jumpy.

Apr 14, 2017
njayarama

I have similar setup, but have limitations to install public ssh-key onto JUNOS devices.

 

what is an alternative way to login to devices from remote PC and use Python script to automate.

Thanks for detailed article.

Apr 9, 2018
JoseIbanez

Hi all,

 

What about "ProxyJump" or "ProxyCommand" settings in .ssh/config file? As far I tested they are ignored.

 

Host vSRX-sgn1
  Hostname 100.77.88.20
  User csp
  IdentityFile ~/.ssh/sgn.pem
  ProxyJump jms-p-js
  
Host vSRX-leeds3
  Hostname 100.77.88.44
  User csp
  IdentityFile ~/.ssh/leeds.pem
  ProxyCommand ncat --proxy 127.0.0.1:8888 --proxy-type socks4 %h %p

Any idea howto use dinamic proxy with netconf ?

 

Thanks in advance, great post.

Jose I. 

Top Kudoed Members