Category Archives: Security

Leaking Routes into a Routing-Instance

In a previous post I wrote about how I went about configuring a NTP server and setting NTP clients. A few days later, when speaking with my senior, the plan changed slightly and we weren’t configuring our own NTP server using Linux based OS, but get satellite feeds running our own LANTIME Stratum 1 Server o_O! In other words that previous post is now invalid haha!

For now I don’t know if I’ll be involved in that side of the project, I hope I am, but that’s for another day! Back to my actual point, because of the environment we run in our datacentres, our firewalls run with Virtual-Router Routing-Instances. A Virtual Router is similar than Cisco’s VRF concept however, with Juniper’s a Virtual Router is used for non-VPN related applications. So, I was asked to investigate if it was possible for our firewalls to be NTP clients to a NTP server via the master instance and also be able to act as a NTP server to attached clients within a routing-instance.

You can get more detail about Juniper’s Routing-Instance Types on their TechLibrary Routing Instances Overview

Although it sounds a bit of a mouthful, the topology itself is quite straightforward. The diagram below shows the topology I’ll be testing with:


As the diagram shows, I’ll be using a standalone Juniper SRX220h and two ESXi Ubuntu 14.04LTS servers. The SRX will be a NTP client of the NTP server (km-vm4) via the master inet.0 table. The second client km-vm1 will be located within the Routing-Instance “test” and will be using the SRX220 as its NTP server. Security policies will need to be defined, as the stateful functionalities of the SRX will still be in use. Without creating security between the zones all traffic will be dropped.

The Base configuration used in this topology is below. (I using this SRX for IPv6 testing as well, so ignore the vlan name lol)
Base Config
set interfaces ge-0/0/0 enable
set interfaces ge-0/0/0 unit 0 family ethernet-switching port-mode access
set interfaces ge-0/0/0 unit 0 family ethernet-switching vlan members internal-v6
set interfaces ge-0/0/1 enable
set interfaces ge-0/0/1 unit 0 family ethernet-switching port-mode access
set interfaces ge-0/0/1 unit 0 family ethernet-switching vlan members ntp-server
set interfaces vlan unit 100 family inet address
set interfaces vlan unit 101 family inet address

set security policies from-zone vlan100 to-zone vlan101 policy allow-ntp match source-address any
set security policies from-zone vlan100 to-zone vlan101 policy allow-ntp match destination-address any
set security policies from-zone vlan100 to-zone vlan101 policy allow-ntp match application junos-ntp
set security policies from-zone vlan100 to-zone vlan101 policy allow-ntp then permit

set security policies from-zone vlan101 to-zone vlan100 policy allow-ntp match source-address any
set security policies from-zone vlan101 to-zone vlan100 policy allow-ntp match destination-address any
set security policies from-zone vlan101 to-zone vlan100 policy allow-ntp match application junos-ntp
set security policies from-zone vlan101 to-zone vlan100 policy allow-ntp then permit

set security zones security-zone vlan100 interfaces vlan.100 host-inbound-traffic system-services any-service
set security zones security-zone vlan101 interfaces vlan.101 host-inbound-traffic system-services any-service

set routing-instances test instance-type virtual-router
set routing-instances test interface vlan.100

set vlans internal-v6 vlan-id 100
set vlans internal-v6 l3-interface vlan.100
set vlans ntp-server vlan-id 101
set vlans ntp-server l3-interface vlan.101

With this setup, the overall goal of this testing is to see if it’s possible to advertise specific routes from the inet.0 table to another routing table, to allow end to end connectivity between routing instances.

This post will not show/explain how the stateful functionalities of the SRX series firewall works. That will be in another post :p

With all that talk and background out of the way… Let’s get cracking 🙂

With the NTP server already configured, the SRX need to set as an NTP client. This configuration is done under system ntp stanza. We set the remote server, ntp version and preference. In addition, I set two other statements; one is optional and the other had to be set. The statements, boot-server and source-address, Juniper defines these statements as:

  • boot-server: When the router or switch boots, it immediately synchronizes with the boot server even if the NTP process is explicitly disabled or if the time difference between the client and the boot server exceeds the threshold value of 1000 seconds.
  • source-address: This is statement useful for controlling which source address NTP will use to access your network when it is either responding to an NTP client request from your network or when it itself is sending NTP requests to your network.

As described above, and in a nutshell, by adding the source-address this will allow other clients/devices to set an IP address that’s located on the SRX as their remote NTP server. Thus providing a /32 address that can be advertised. For my example the address, the gateway address for the ntp server, will be the address used as the source address.

[email protected]# show system ntp 
server version 4 prefer;

We can verify the NTP association by using the command show ntp assocication.

[email protected]# run show ntp associations                      
     remote           refid      st t when poll reach   delay   offset  jitter
*    3 -  148  256  377    2.313    0.748   0.063

With NTP verified on the SRX, we have to leak the NTP source address for the SRX from the inet.0 table to the test.inet.0 table. As we can see, when we look at the routing instance’s routing table, we don’t have the route installed into the table:

[email protected]# run show route table test.inet.0      

test.inet.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both     *[Direct/0] 04:02:28
                    > via vlan.100     *[Local/0] 06:31:31
                      Local via vlan.100

To get the route installed into the test.inet.0 table, we’ll need to leak the route into the test.inet.0 table, and we’ll do this by creating two policy statements. For my example I’ve named them master and instance just for ease!

  • Master: This statement allows all routes from routing instance test to be accepted into the master routing table.
  • Instance: This statement has two terms. Term 1 only allows the exact route from the master instance to be accepted. Term 2 denies all other routes from master instance.
[email protected]# show policy-options 
policy-statement master {
    from instance test;
    then accept;
policy-statement instance {
    term 1 {
        from {
            instance master;
            route-filter exact;
        then accept;
    term 2 {
        then reject;

Now we’ll need to import the relevant policy into each instance, under the routing-options stanza for the inet.0 table and routing-instance test routing-options for the test.inet.0 table.

Master Instance Routing-OptionsRouting-Instance Routing-Options
[email protected]# show routing-options 
static {
    route {
instance-import master;
[email protected]# show routing-instances test routing-options 
instance-import instance;

Having committed the policy statements, when we check both routing tables we can see the route have been leaked into the inet.0 table, and that only the route has been installed into the test.inet.0 table. All other routes have not been leaked.

inet.0 tabletest.inet.0 table
[email protected]> show route table inet.0 

inet.0: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both          *[Static/5] 1w2d 09:40:34
                    > to via ge-0/0/7.0        *[Direct/0] 1w2d 09:40:34
                    > via ge-0/0/7.0      *[Local/0] 1w2d 09:40:39
                      Local via ge-0/0/7.0     *[Direct/0] 2d 04:15:32
                    > via vlan.100     *[Local/0] 2d 04:15:32
                      Local via vlan.100     *[Direct/0] 2d 07:20:32
                    > via vlan.101     *[Local/0] 3d 08:44:24
                      Local via vlan.101
[email protected]> show route table test.inet.0   

test.inet.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both     *[Direct/0] 09:32:22
                    > via vlan.100     *[Local/0] 12:01:25
                      Local via vlan.100     *[Local/0] 05:28:32
                      Local via vlan.101

Finally, on the client we’ll need to set a static route so that the host knows if it wants to get the subnet it will need to use the gateway via eth1

[email protected]:~$ sudo route add -net gw dev eth1
[email protected]:~$ ip route
default via dev eth0 dev eth0  proto kernel  scope link  src dev eth1  proto kernel  scope link  src via dev eth1

Once that route has been installed we can see that the host has now become a NTP client to the SRX by running the command ntpq -p. In addition on the SRX, we can see the flow session between inet.0 and test.inet.0 routing tables.

NTP AssociationSRX flow Session
[email protected]:~$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
*    4 u   15   64    3    2.086   -0.094   0.109
[email protected]> show security flow session destination-prefix 
Session ID: 21218, Policy name: allow-ntp/4, Timeout: 40, Valid
  In: -->;udp, If: vlan.100, Pkts: 7, Bytes: 532
  Out: -->;udp, If: .local..5, Pkts: 7, Bytes: 532
Total sessions: 1

And with that we’ve been able to route between routing instances! The most important thing that I found whilst do this testing is that you need to remember to add the static route on the host or device that is directly connected to router with the routing-instance. This same setup would work with a switch in between the SRX and end host, just have the static route and you’ll be sorted. In addition to having the right security policies, as they’ll bite you in the bum as well :p

I’ve included the set commands that I used in my example below, if you wanted to give it a try for yourself 🙂

Set Commands
set system ntp boot-server
set system ntp server version 4
set system ntp server prefer
set system ntp source-address

set routing-options instance-import p1

set policy-options policy-statement p1 from instance test
set policy-options policy-statement p1 then accept

set policy-options policy-statement p2 term 1 from instance master
set policy-options policy-statement p2 term 1 from route-filter exact
set policy-options policy-statement p2 term 1 then accept
set policy-options policy-statement p2 term 2 then reject

set routing-instances test routing-options instance-import p2


Juniper Knowledge Base: NTP over routing-instance on EX-series switches
Juniper TechLibrary: NTP Configuring

Share this:

IPv6 and Junos – Firewall Filter (ACLs)

For IPv6 testing I’ve been asked to do one of the more noddy things to test Firewall Filters; these are Stateless Firewall Filters and are what Cisco call Access Control Lists (ACL). Unlike Stateful Firewall Filters, Stateless Filters do not inspect traffic flows, pattern or keep a record of network connections, as such TCP streams and/or UDP communication. Instead, these filters evaluate packet contents statically against a set of packet-matching rules that either permit or deny packets transiting the switch.

Firewall Filter (ACL) is an important feature for a switch to have as it provides some (although limited) protection for devices and host directly connected. I said that this was one of the more noddy things as there’s only one difference between creating a Firewall Filter for IPv4 and IPv6. However, as they say, better to be safe than sorry! With all that said and done, this post will be to show how you’d configure and implement a Stateless Firewall Filter within Junos.

Let’s get cracking 🙂

I had a pretty simple topology, using a Juniper EX Series 4200 switch configured with two Layer-3 vlans, and I’ve set up two Ubuntu 14.04LTS ESXi host; 1 of the host will be configured as a webserver (km-vm1) and the other as a client trying to access the server (km-vm3)

Firewall Filter Topology

Firstly, I created all of the physical and logical connections were expected, by running show ipv6 neighbors and show lldp neighbors

IPv6 SubnetsServers
[email protected]> show ipv6 neighbors 
IPv6 Address                 Linklayer Address  State       Exp Rtr Secure Interface
2001:123:212:1::2            00:0c:29:fc:d5:de  stale       202 no  no      vlan.300       
2001:192:168:2::2            00:0c:29:4f:26:c5  stale       1197 no no      vlan.200
[email protected]> show lldp neighbors 
Local Interface    Parent Interface    Chassis Id          Port info          System Name
ge-0/0/0.0         -                   00:0c:29:4f:26:bb   eth1               km-vm1                          
xe-0/1/0.0         -                   00:0c:29:fc:d5:d4   eth1               km-vm3

The goal of this test is ensure that KM-VM3 can ONLY access KM-VM1 on TCP ports 80 and 443, as these are well-known and IANA defined ports for unsecured (HTTP) and secured (HTTPS) web traffic, and ICMP traffic (ie. ping and traceroute).

Before configuring the Firewall Filter I wanted to see what was accessible for KM-VM3, so I ran a very useful open source utility for network discovery and a security auditing tool called nmap , to produce a port scan of the webserver. From the output we can see that not only are HTTP and HTTPS accessible, but the Port 22 Secure Shell (SSH) is open. As KM-VM1 doesn’t have any firewalling configured on the server level via iptables, KM-VM3 could be used to try and hack KM-VM1 by attacking the SSH port to gain access to the server, which is never good!

Port ScanSSH access
[email protected]:~$ nmap -6 2001:192:168:2::2

Starting Nmap 6.40 ( ) at 2015-11-11 14:17 GMT
Nmap scan report for 2001:192:168:2::2
Host is up (0.0017s latency).
Not shown: 997 closed ports
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https
[email protected]:~$ ssh 2001:192:168:2::2
The authenticity of host '2001:192:168:2::2 (2001:192:168:2::2)' can't be established.
ECDSA key fingerprint is e3:e3:f7:91:c0:30:a3:02:f9:1f:fd:aa:b7:0d:9c:9d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '2001:192:168:2::2' (ECDSA) to the list of known hosts.
[email protected]:192:168:2::2's password:

With that security risk in mind, lets add a Firewall Filter that will only allow access to ports 80, 443 and ICMP traffic. I created a prefix-list, webservers, that would list all the prefixes (IP addresses) for the webservers. Although in this example I’ll only have the one prefix, I was always taught to use prefix-lists for ease of configuration. This was configured under edit policy-options prefix-list stanza:

[email protected]# show policy-options       
prefix-list webservers {

Now, for the Filter you’ll need to be under firewall family inet6 filter stanza, (for an IPv4 filter; firewall family inet filter). You can name your filter anything however, it can’t be more than 64 characters and if you have any spaces you’ll need to use ” ” marks. The same goes with naming your rules, which Junos calls terms. The Filter must have at least one term and the term(s) must have from or then statement. The from and then statements provide the actions of the term.

As you can see below, the Firewall Filter is named ALLOW-HTTP/HTTPS and has 3 terms:

{master:0}[edit firewall family inet6 filter ALLOW-HTTP/HTTPS]
[email protected]# show 
term allow-http/https {
    from {
        source-address {
        destination-prefix-list {
        destination-port [ 80 443 ];
    then accept;
term allow-icmp {
    from {
        icmp-type [ echo-reply echo-request neighbor-advertisement packet-too-big destination-unreachable neighbor-solicit ];
    then accept;
term deny-all {
    then {
        count deny-all;

Lets break down each aspect of this Firewall Filter:

  • The first term allow-http/https states from source-address ::/0, for IPv6 is any address to the destination of the webservers, which has been defined in the prefix-list to ports 80 and 443 (HTTP and HTTPS) to then accept those packets
  • The second term allow-icmp states the different type of icmp packets that I want allowed and then those are accepted
  • The final term deny-all states that any other packets should be counted under deny-all, logged and discarded. By using the action discard, this will silently drop all packets without sending an ICMP reply back to the requestor
With Junos, it is important to remember that when creating a Firewall Filter:

  • They works as Top-Down List, so the order of your rules is very significant, because once a rule has been matched, any rules below WILL NOT be checked.
  • Additionally just like with Cisco Firewall Filters come with an Implicit Deny at the end. If any packets don’t match any of the previous terms then they will be dropped automatically. Although this Implicit Deny is there, best practice to add a deny-all term at the end any Firewall Filter or ACL.
  • Finally, you can have only one input and one output filter per interface however have as many terms as you like. You can find all the guidelines that come with Firewall Filters here on Juniper’s TechLibrary page

Having created the filter, it will an input filter, as it is configured to filter traffic coming into the switch. Additionally, it will be place on the outside-facing interface, in this example, that has KM-VM3 in (vlan.300). This is because with any Filter, ACL or Firewall Policy, you want to stop any unnecessary traffic traversing your network at the furthest possible point, which is normally the edge of your network.

So under interface vlan unit 300 family inet6 filter stanza the Firewall Filter is placed as an input filter:

{master:0}[edit interfaces vlan unit 300]
[email protected]# show 
family inet6 {
    filter {
        input ALLOW-HTTP/HTTPS;
    address 2001:123:212:1::1/64;

Having committed the configuration, if we go back onto KM-VM3 and do some testing we’ll be able to see the effect of the Firewall Filter. As we can see below, when the port scan was run again, only ports 80 and 433 are in an OPEN STATE and SSH port 22 isn’t shown at all now, and we’re able to ping. When we try SSH we get nothing, which shows that this filter is working as expected.

Port ScanICMP PingSSH access
[email protected]:~$ nmap -6 2001:192:168:2::2

Starting Nmap 6.40 ( ) at 2015-11-11 15:30 GMT
Nmap scan report for 2001:192:168:2::2
Host is up (0.00072s latency).
Not shown: 998 filtered ports
80/tcp  open  http
443/tcp open  https
[email protected]:~$ ping6 2001:192:168:2::2
PING 2001:192:168:2::2(2001:192:168:2::2) 56 data bytes
9 packets transmitted, 9 received, 0% packet loss, time 7999ms
rtt min/avg/max/mdev = 0.464/0.545/0.662/0.066 ms
[email protected]:~$ ssh 2001:192:168:2::2

For further verification, we can check the counter that was set under the deny-all term to see how many packets have been dropped. By running the command show firewall counter filter ALLOW-HTTP/HTTPS deny-all we’re able to see the counters at that time.

[email protected]> show firewall counter filter ALLOW-HTTP/HTTPS deny-all 

Filter: ALLOW-HTTP/HTTPS                                       
Name                                                Bytes              Packets
deny-all                                              490                    5

As I said, when I started this post, the method of applying a Firewall Filter is exactly same in IPv6 world as it is in IPv4, with the exception of the filter location. Firewall Filters are extremely important in giving protection to hosts and devices connected to the switch if a stateful firewall such as a Juniper SRX or Cisco ASA isn’t suitable and/or available in your network design.

Share this:

SSH login with 2-Factor Authentication

During the holiday time, I was discussing with a mate on ways I could make my server more secure and he said why don’t I have 2-Factor Authentication. Of course, I dismissed him as a crazy man saying you can do that on SSH! When I actually looked I saw it could be done and it is a common place to have it done as well. I found a super page that explains how 2-Factor Authentication all works! With this in mind, this post will show how you can enable a SSH server with 2-Factor Authentication.

As always, I’ll be using Ubuntu 14.04 LTS. Because I use Google Authenticator for other things, I was happy to see that you can install Google Authenticator’s time-based one-time password (TOTP) via the apt-get repository. To install 2-factor authentication with Google Authenticator, we’ll need the open-source Google Authenticator PAM module. PAM stands for Pluggable Authentication Modules (PAM) provide dynamic authentication support for applications and services in a Linux. Essentially, it’s a way to easily plug different forms of authentication into a Linux system.

Firstly you will need to have Google Authenticator or Authentication App installed on your phone before doing anything. Personally I use Google’s Authenticator, for iOS App Store, for Android Google Play. Microsoft has their own Authenticator App for Windows Phones.

With the Authenticator installed on your phone, next you will need to install the Google package. You will need to have root and/or sudo access to the server and apt-get libpam-google-authenticator

sudo apt-get install libpam-google-authenticator

With the Module installed, you can set up your users with their OTP token. Run the google-authenticator utility, once ran you will be asked a series of questions that you can answer however best for you environment.

[email protected]:~$ google-authenticator 

Do you want authentication tokens to be time-based (y/n) y|0&cht=qr&chl=otpauth://totp/[email protected]%3Fsecret%3DXYC73MOQV7SMPOSJ
Your new secret key is: XYC73MOQV7SMPOSJ
Your verification code is 194186
Your emergency scratch codes are:

Do you want me to update your "/home/marquk01/.google_authenticator" file (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, tokens are good for 30 seconds and in order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with poor
time synchronization, you can increase the window from its default
size of 1:30min to about 4min. Do you want to do so (y/n) y

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting (y/n) y
[email protected]:~$ 
Important Notes
You will need to keep safe the Emergency Scratch codes, just in case you lose access or have an issue with your OTP token. Your secret key will be used on the Authenticator app to generate your verification code. You can either manual enter the code or you can use scan QR-code that is generated on the cli to your phone. This is what you should expect to see when you run the google-authenticator utility. Once that’s has been done you will you should get something like this on your app

Next we will need to activate Google Authenticator within the sshd daemon. Firstly you will need to edit /etc/pam.d/sshd file by adding following lines below:

[email protected]:~$ sudo nano /etc/pam.d/sshd 
# To allow Google Authenticator for 2 factor authentication 
auth required

Then you will need to edit the /etc/ssh/sshd_config file. Look for the ChallengeResponseAuthentication and ensure that this is yes

[email protected]:~$ sudo nano /etc/ssh/sshd_config 
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication yes

The full files should look something like this sshd and sshd_config

Now we need to restart the sshd daemon.

[email protected]:~$ sudo service ssh restart

Now that the ssh daemon has been restarted when you try and ssh back onto the server, you will be asked for your password and the OTP verification code

[[email protected] ~]$ ssh
Verification code: 

It also worked with Secure Copy Protocol (SCP), which allows transfer files via Secure Shell (SSH)

[[email protected] ~]$ scp bird.conf.oringial [email protected]:/home/marquk01
Verification code: 
bird.conf.oringial                            100% 6222     6.1KB/s   00:00
ALL Users will need to be configured to have 2-factor authentication before editing the ssh daemon. When I tried this the first time, I assumed it was pre-user enabled the everything to find out my main account was locked out… #GenuisAtWork! In addition, if you have a key-based authentication, they will take supersede 2-Factor Authentication and this will be ignored
Share this:

Checking ISO and/or File Images via CLI

If you have downloaded an iso or image and you want to check that image/iso hasn’t been tampered or corrupted. Ubuntu has a md5 and sha hash checker pre-installed within the OS.

For MD5 checking you will use md5sum

md5sum path/to/image

[email protected]:/tmp$ md5sum ubuntu-14.04.2-server-amd64.iso 
83aabd8dcf1e8f469f3c72fff2375195  ubuntu-14.04.2-server-amd64.iso

For Sha checking, you will use one of the below (depending on the hashing value)

[email protected]:~$ sha
sha1sum       sha256sum     sha512sum     shasum        
sha224sum     sha384sum     shadowconfig

sha1 path/to/image

[email protected]:/tmp$ sha1sum ubuntu-14.04.2-server-amd64.iso 
3bfa6eac84d527380d0cc52db9092cde127f161e  ubuntu-14.04.2-server-amd64.iso

You then can check the md5/sha hashes against the known correct has values. If they match (which these do):

Screenshot 2015-07-03 09.19.05
Screenshot 2015-07-03 09.18.39









You are good to go, knowing you have a legit version! 😀

Share this:

JNCIA Refresher #4 – Routing Fundamentals

Packet Forwarding Concepts
Routing Tables
Routing vs. Forwarding Tables
Route Preference
Routing Instances
Static Routing
Dynamic Routing Protocols

Packet Forwarding Concepts

Packet forwarding is the movement of data packets from device to device. This is key for any network, as if the networking devices don’t know how to move a packet outside of its own segment/area, the packet will be dropped and the reason we have networks is to move data/information from one place to another. With that being said, a device doesn’t need to know whole Internet or even a whole network. The most important information; a switch, router or any layer 2/3 device needs to know is the next-hop address. The next-hop provides an exit for the device if the destination of the packet isn’t located on the device, it will pass the packet on to “the next hop” device and that device will do the same thing until the destination of the packet is located. This is basis of packet forwarding.

A Juniper device (or any network device in fact) will have Routing Engine (RE) and Packet Forwarding Engine (PFE). These engines (software or hardware based) are what will used to move packets and ultimately controls the routing on the device.

The Routing Engine is the control plane of the device. The control plane is where all the Routing Information Base (RIB) will be stored and from the RE the creation of the packet forwarding switching fabric that will be used for the movement of packets. The RE is responsible for providing filtering information, route lookups and determining of what the next-hop address will be. It is important to note, that the RE does not control how the packets are moved, it is where the RIB is stored. The Packet Forwarding Engine uses this information.

The Packet Forwarding Engine is the where the forwarding of transit traffic is processed. The PFE directly affects the packets. The PFE will use the information from the RE and apply the information to the packets by applying any firewall filters, routing and/or security policies before forwarding the packet onto the next-hop destination.

Routing Tables

With Junos, it is different compared to other vendors when it comes to see information within the Routing Table. Other vendors will have multiple commands that you use will use to see different tables (i.e. the routing table for IPv4 and IPv6). In Junos, we just need to use the show route command we will see the multiple routing tables under the single command. Each of the tables are populated with routes as and when they are needed, you can say each of table is a database of information for it’s particular routing type.

As you can see, my router only has IPv4 currently configured, so it will only have the inet.0 table

[email protected]_SRX> show route 

inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both          *[Static/5] 1d 23:54:16
                    > to via ge-0/0/7.0        *[Direct/0] 1d 23:54:16
                    > via ge-0/0/7.0      *[Local/0] 1d 23:54:20
                      Local via ge-0/0/7.0    *[Direct/0] 1d 23:54:16
                    > via ge-0/0/1.0    *[Local/0] 1d 23:54:20
                      Local via ge-0/0/1.0

It is important to note, that I have 5 routes and they all active. When looking at the routing table ideally you would like to have Active routes. Routes in holddown state are in pending state before declared inactive. Hidden routes are not in the routing table because of a routing policy.

Juniper’s definition on Routing Tables

Junos OS automatically creates and maintains several routing tables. Each routing table is used for a specific purpose. In addition to these automatically created routing tables, you can create your own routing tables. Each routing table populates a portion of the forwarding table. Thus, the forwarding table is partitioned based on routing tables. This allows for specific forwarding behaviour for each routing table.

The table below shows, all the tables that are created by default by Junos. At the JNCIA level you will only need to worry about the inet.0 and inet6.0 tables. However it’s always good to have bit more info to look into later 😀

Junos Default Routing Tables
Routing Table Description
inet.0 IPv4 unicast routes. This table stores interface local and direct routes, static routes, and dynamically learned routes.
inet.2 This table is created when multiprotocol BGP (MBGP) is enabled. This table stores unicast routes that are used for multicast reverse-path-forwarding (RPF) lookup. You can import routes from inet.0 into inet.2 using routing information base (RIB) groups, or install routes directly into inet.2 from a multicast routing protocol.
inet.3 IPv4 MPLS routes. This table stores the egress address of an MPLS label-swiched path (LSP), the LSP name, and the outgoing interface name. This routing table is used only when the local device is the ingress node to an LSP.
inet6.0 IPv6 unicast routes. This table stores interface local and direct routes, static routes, and dynamically learned routes.
instance-name.inet.0 This table is created when you configure a routing instance, Junos OS creates the default unicast routing table.
instance-name.inet.2 This table is created when you configure routing-instances instance-name protocols bgp family inet multicast in a routing instance of type VRF, Junos OS creates the instance-name.inet.2 table
bgp.l2vpn.0 This table is created for Layer 2 VPN routes learned from BGP. This table stores routes learned from other provider edge (PE) routers. The Layer 2 routing information is copied into Layer 2 VPN routing and forwarding instances (VRFs) based on target communities.
bgp.l3vpn.0 IPv4 unicast routes. This table is created for Layer 3 VPN routes learned from BGP. This table stores routes learned from other PE routers. R.stores interface local and direct routes, static routes, and dynamically learned routes.
mpls.0 This table is created for MPLS label switching operations. This table is used when the local device is a transit router.
iso.0 This table is for IS-IS routes. When you are using IS-IS to support IP routing, this table contains only the local device’s network entity title (NET)
juniper_private For Junos OS to communicate internally between the Routing Engine and PIC hardware.

Routing vs. Forwarding Tables

The Routing Information Base (RIB) is located within with the Routing Table (RT). As stated in the packet forwarding concepts, the RIB are stored in the Control Plane, this would makes the Routing Table is part of the Control Plane within Junos. As such, the RT has information about all available routes that the router could use, but critically doesn’t make forwarding decisions.

The Forwarding Table (FT) has all the information from the RT, creates the best path for transit traffic and only keeps the best/active paths in compressed or pre-complied format for optimised route lookups. Therefore, the FT is both Control and Forwarding Plane. This makes the relationship between the RT and FT important, as without one, the other will fail.

In essence, the process packet movement would be:

Packet In --> Routing Information Base --> Routing Table --> Forwarding Table --> Packet Out

We can see the different between the Routing and Forwarding Tables. We can view the routing Table by running the show route command. As we can see from the ‘show route’ tab, there is some detail however not a great deal, when compared to the forwarding table.

To see the forwarding table, we will need to run show route forwarding-table. We can see from ‘show route forwarding-table’ tab, the level of detail is greater. In addition, from the forwarding-table the key thing you will need to know for the JNCIA exam are the two different types (Destination Types and Next-Hop Types) and what their type variables mean. This is shown below on Destination and Next-Hop Types tabs.

show routeshow route forwarding-tableDestination TypesNext-Hop Types
[email protected]_SRX> show route 

inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both          *[Static/5] 3d 20:13:19
                    > to via ge-0/0/7.0        *[Direct/0] 3d 20:13:19
                    > via ge-0/0/7.0      *[Local/0] 3d 20:13:23
                      Local via ge-0/0/7.0    *[Direct/0] 3d 20:13:19
                    > via ge-0/0/1.0    *[Local/0] 3d 20:13:23
                      Local via ge-0/0/1.0
[email protected]e_SRX> show route forwarding-table    
Routing table: default.inet
Destination        Type RtRef Next hop           Type Index NhRef Netif
default            user     0 ac:4b:c8:79:41:10  ucst   554     3 ge-0/0/7.0
default            perm     0                    rjct    36     1         perm     0                    dscd    34     1        intf     0                    rslv   547     1 ge-0/0/7.0        dest     0           recv   545     1 ge-0/0/7.0        dest     0 ac:4b:c8:79:41:10  ucst   554     3 ge-0/0/7.0       dest     1 18:a9:5:40:1a:0    ucst   556     2 ge-0/0/7.0      intf     0         locl   546     2      dest     0         locl   546     2      dest     0         bcst   544     1 ge-0/0/7.0    intf     0                    rslv   543     1 ge-0/0/1.0    intf     0       locl   542     2    dest     0       locl   542     2    dest     1 10:e:7e:4e:f:80    ucst   555     2 ge-0/0/1.0        perm     0                    mdsc    35     1       perm     0          mcst    31     1 perm     0                    bcst    32     1
{omitted output}
Destination Type Description
intf (Interface) This is where an interface has been manually configured
dest (Destination) The destination of an address that is directly reachable. You would see an IP address (in the next-hop column) if the address is local or a network address. You would see a mac-address if the address isn’t local
perm (Permanent) This is installed as part of the Junos Kernel and can’t be removed
user (Routing) These are routes learnt via a routing protocol i.e. ISIS, RIP, OSPF, BGP and Static Routes
Next-Hop Type Description
ucst (Unicast) This is where an interface has been manually configured
dscd (Discard) The destination of an address that is directly reachable. You would see an IP address (in the next-hop column) if the address is local or a network address. You would see a mac-address if the address isn’t local
rjct (Reject) This is installed as part of the Junos Kernel and can’t be removed
bcst (Broadcast) These are routes learnt via a routing protocol i.e. ISIS, RIP, OSPF, BGP and Static Routes
locl (Local Address) Local Addresses to the device
mcst (Multicast) Multicast addresses

Route Preference

When we look at the routing table, we can see that see that we have some details about the routes we have learnt:

[email protected]_SRX> show route 

inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both          *[Static/5] 3d 20:13:19
                    > to via ge-0/0/7.0
{omitted output}    *[Direct/0] 3d 20:13:19
                    > via ge-0/0/1.0    *[Local/0] 3d 20:13:23
                      Local via ge-0/0/1.0

As you can see from the output, we are told the how the route is connected to the device and given a value. The value would be the Route Preference (Known As Administrative Distance). The preference is taken from the RIB to determine, if you receive a route from two different protocols, which route would make the Routing-Table. Its important to note when we have Direct and Local preference, junos uses the most specific route and where in the example above has been assigned as the local interface address it’s given /32 net mask telling the device that this is their address.

The table below has a summary of the default route preference values.


Route Preference Number Protocol
0 Direct/Local Address
5 Static Route
10 OSPF (Internal)
100 RIP
130 Aggregate Routes (Summary Routes)
150 OSPF (External)
170 BGP

You can check the full Default Route Preference Values are on the Juniper Website here

Routing Instances

Routing instances (VRFs on cisco) are a way of dividing your switch, firewall or router, to allow the device to have multiple independent Routing Tables within the single device. Each routing-instance will need to have its physical (or logical) interface(s) and its instance-type defined. As you can see below when you have routing-instance configured you will have the each routing-instance has its own routing-table and they are shown as instance-name.inet.0. It important to note, that all configuration for the routing-instance will need to be done under the routing-instance stanza. This is shown on “Routing-Instance Configuration” tab

Instance TypesRouting-Instance ConfigGlobal Routing TableRouting-Instance TrustRouting-Instance Untrust
[email protected]_SRX# set routing-instances untrust instance-type ?
Possible completions:
  forwarding           Forwarding instance
  l2backhaul-vpn       L2Backhaul/L2Wholesale routing instance
  l2vpn                Layer 2 VPN routing instance
  layer2-control       Layer 2 control protocols
  mpls-internet-multicast  Internet Multicast over MPLS routing instance
  no-forwarding        Nonforwarding instance
  virtual-router       Virtual routing instance
  virtual-switch       Virtual switch routing instance
  vpls                 VPLS routing instance
  vrf                  Virtual routing forwarding instance
root> show configuration routing-instances 
trust {
    instance-type virtual-router;
    interface vlan.20;
    routing-options {
        static {
            route next-hop;
untrust {
    instance-type virtual-router;
    interface vlan.10;
    routing-options {
        static {
            route next-hop;
root> show route 

inet.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both        *[Direct/0] 2w6d 04:28:28
                    > via me0.0      *[Local/0] 2w6d 04:28:28
                      Local via me0.0      *[IGMP/0] 2w6d 04:28:29
trust.inet.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both      *[Static/5] 2w2d 01:20:57
                    > to via vlan.20     *[Direct/0] 2w2d 01:20:57
                    > via vlan.20     *[Local/0] 2w4d 01:10:24
                      Local via vlan.20
untrust.inet.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both      *[Direct/0] 2w2d 01:26:30
                    > via vlan.10      *[Local/0] 2w4d 01:10:24
                      Local via vlan.10     *[Static/5] 2w2d 01:26:30
                    > to via vlan.10

Static Routing

As the name suggests static routing is a route that has been created manually and doesn’t change, unless it’s manually updated. When creating a static route, knowing the next-hop information is key as you are saying I want this IP address/range to go next. For my example below, I have created a static default route on this device. I have used the “no-readvertise” option, so that this route IS NOT readvertised into the routing-table and NOT routable

[email protected]_SRX# show routing-options 
static {
    route {

When creating static route, there’s a number of different options that are available:

[email protected]_SRX# set routing-options static route ?
Possible completions:
  active               Remove inactive route from forwarding table
+ apply-groups         Groups from which to inherit configuration data
+ apply-groups-except  Don't inherit configuration data from these groups
> as-path              Autonomous system path
  backup-pe-group      Multicast source redundancy group
> bfd-liveness-detection  Bidirectional Forwarding Detection (BFD) options
> color                Color (preference) value
> color2               Color (preference) value 2
+ community            BGP community identifier
  discard              Drop packets to destination; send no ICMP unreachables
  install              Install route into forwarding table
> lsp-next-hop         LSP next hop
> metric               Metric value
> metric2              Metric value 2
> metric3              Metric value 3
> metric4              Metric value 4
+ next-hop             Next hop to destination
  next-table           Next hop to another table
  no-install           Don't install route into forwarding table
  no-readvertise       Don't mark route as eligible to be readvertised
  no-resolve           Don't allow resolution of indirectly connected next hops
  no-retain            Don't always keep route in forwarding table
> p2mp-lsp-next-hop    Point-to-multipoint LSP next hop
  passive              Retain inactive route in forwarding table
> preference           Preference value
> preference2          Preference value 2
> qualified-next-hop   Next hop with qualifiers
  readvertise          Mark route as eligible to be readvertised
  receive              Install a receive route for the destination
  reject               Drop packets to destination; send ICMP unreachables
  resolve              Allow resolution of indirectly connected next hops
  retain               Always keep route in forwarding table
> static-lsp-next-hop  Static LSP next hop
> tag                  Tag string
> tag2                 Tag string 2

The key ones to look into for the JNCIA level would:

next-hop: This is set the next-hop address for the subnet to use to leave the local device
qualified-next-hop: This is a secondary next-hop address (Known as a floating IP address). If the first next-hop address is unavailable, the router will use that qualified next-hop address. In addition, you are able to set the route preference for the qualified-next-hop manually
discard: This will silently drop packets, providing no reply
reject: This will drop packets and provide an ICMP reply

Only using static routing in a network is a lot of manual work and you will have to do this for every device on your network and trying to maintain this would be a ridiculous and is un-scalable. This leads into why the need for Dynamic Routing Protocols in a network is important in conjunction with static routes.

Dynamic Routing Protocols

When talking about dynamic routing, we can break it down into 2 categories Internal Gateway Protocols and External Gateway Protocols.

Internal Gateway Protocols

Internal Gateway Protocols (IGPs) is a type of protocol used for exchanging routing information between gateways within an Autonomous System. With IGPs there two types protocols; Distance-vector routing protocol and Link-state routing protocol

Distance-vector routing protocol each router does not possess information about the full network topology. It advertises its distance value (DV) calculated to other routers and receives similar advertisements from other routers unless changes are done in local network or by neighbours (routers). Using these routing advertisements each router populates its routing table. In the next advertisement cycle, a router advertises updated information from its routing table. This process continues until the routing tables of each router converge to stable values.

Distance Vector Protocols include:

Routing Information Protocol (RIP)
Routing Information Protocol Version 2 (RIPv2)
Routing Information Protocol Next Generation (RIPng), an extension of RIP version 2 with support for IPv6
Interior Gateway Routing Protocol (IGRP)

Whereas, Link-state routing protocols, each router possesses information about the complete network topology. Each router then independently calculates the best next hop from it for every possible destination in the network using local information of the topology. The collection of best-next-hops forms the routing table.

This contrasts with distance-vector routing protocols, which work by having each node share its routing table with its neighbours. In a link-state protocol, the only information passed between the nodes is information used to construct the connectivity maps.

Link-state routing protocols include:

Open Shortest Path First (OSPF)
Intermediate system to intermediate system (IS-IS)
External Gateway Protocols

External Gateway Protocols (EGPs) is a routing protocol used to exchange routing information between autonomous systems. This exchange is crucial for communications across the Internet. Notable exterior gateway protocols include Exterior Gateway Protocol and Border Gateway Protocol.

Share this: