Monday 14 September 2020

Juniper Home Lab - virtual lab topology on a single physical device

One of the things I've wanted for a long time is a few Juniper devices lying around my home to keep my Juniper CLI skills up to scratch and to experiment with new concepts as I learn them. Sure, you can run great labs in things like EVE-NG, but you ultimately need licensed VM images (and a machine with a fair amount of RAM and CPU grunt for any complex topologies), and those licenses are quite expensive (although if you have a juniper.net login, you can download a free 60 day evaluation copy of vMX router, vSRX firewall or vQFX switch; apparently, you can simply recycle trial licenses - not that this is recommended [see e.g. page 351 of the Junos beginner's Day One guide]). Indeed, even if you (re)use trial licenses, you'll probably need a fairly hefty - expensive - server to run them on, which will cost a similar amount to quite a lot of second hand devices; the key advantage of the former, perhaps, is you're more likely to have a more current Junos image to work with in the virtualised space as opposed to from the old second hand gear market.

Old second hand Juniper gear, however, is quite cheap, and although you won't get support or upgrades, will then also not cost you any ongoing support. I'd be very wary of downloading random Junos images off the internet - some people do seem to share them if you look hard enough. I ordered two SRX 110H2-VA routers off Ebay to scratch this itch (I further scratched this itch with more gear...). I don't need anything particularly fancy, and these units are quite cheap, fairly compact, and lack fans, so they are nice and quiet. There are a lot of basic SRX firewalls available online; as Junos is somewhat consistent across most of the platforms, you will find getting a thing marketed as a "firewall" also lets you learn most of the Juniper platform features for not only firewalling, but switching and routing too from across their portfolio - aside, of course, for those features not supported on this platform or software version. 

By the end of this post, you should be able to create a single router that has 8 virtual routers configured on it with a fairly complex, but easily understood, topology. 

Read on for some ideas... 


"Out of Box" experience

The SRX units were factory reset by the Ebay seller (in Amnesiac mode) and already upgraded to the latest stable 12.x train available (12.3X48-D85.1) for these now somewhat obsolete units.  You need a valid support contract to be able to download the Junos images for a given device, so it's worth checking that the units you buy are at least somewhat up-to-date. If you are undergoing certifications, you may need to use particular versions of Junos (and possibly particular hardware), as the features and commands can (and do) change a little between versions and platforms. 

They do take a few minutes to boot up after you apply power, so don't be too impatient!

One thing I'll note is that they get remarkably warm - particularly if you stack them on top of each other. I don't recommend doing that as a result, which is a shame (the hardware guides don't specifically say not to do so). I'll probably order a small rack or something to house them in eventually. They are apparently rated up to about 40 degrees Celsius ambient temperature (it is low 20s around here at the moment), but will probably thermally throttle or shutdown before getting anywhere near that if they bake each other at the same time. They're clearly meant for desktop use as a single unit (or as a single unit in a roomy, not particularly full rack, if you have a rack mount kit). As a lab device and not a production device, turning them off is probably a good idea - they'll last longer if kept cooler, and they will save you power, so long as you also unplug the power supplies. If you don't have a small rack, a very large desk or separate table to use as a workspace is quite useful to construct your topologies.

You're supposed to ground the devices, although if you're not using ADSL, it probably won't be the end of the world if you don't; if you're installing them for production use, however, follow the manufacturer's instructions - or your site-specific requirements. 

Although you can achieve a lot through the web GUI or an SSH connection to the device, I recommend having a "yost" or rollover serial cable for management purposes. You can get USB ones cheaply now. 


Junos crash course

I've been using Juniper's Junos since 2016, so I'm reasonably familiar with it - although if you're not, you will find Juniper has spent a lot of time and effort putting together learning resources like the tech library; the Day One books on various topics are particularly good, and available as free PDFs, as well as for a nominal cost as Kindle e-books - or as print-on-demand hardcopy through Vervante (or their presence on the likes of Amazon). The Day One guides are typically around 100 pages or so, allowing you to very quickly get up and running on a platform or technology. You should recognise that there is a lot more to learn (I have hundreds of pages of Juniper reading to plough through on my bookshelf), but it gives you some "quick wins" and a solid introduction to the topic. 

You can also make use of the extensive courses and learning materials on Junos Genius; until recently at least, you've been able to complete a course and get a free voucher for their five Associate level certification exams (JNCIA Junos, Sec, DevOps, Cloud & JNCDA); I think this has been popular enough that this now only nets you a 75% discount - although a free digital training course is still a nice touch. 

A commonly encountered difference is between those platforms using "ELS" command syntax and the older ones that don't - to me the most obvious manifestation of ELS vs. non-ELS is what the logical routing Layer 3 interface you put an IP address on a VLAN for ethernet-switching is called. If it's called "vlan.<id>", then it's the old non-ELS syntax; if it's called "irb.<id>" then it is ELS - but there are other differences. Fortunately, Juniper is quite good at giving you very helpful contextual clues by hitting the ? key where you're not certain where to go next (not to mention the builtin help with the help apropos <keyword>) - for the most part, there are few surprises about where you would need to go within the configuration hierarchy, particularly after a few days or weeks of playing around in the ecosystem. Another big difference is between those platforms that still make use of FreeBSD as the underlying OS, and those which are now using a version of Linux as the host, and basically run Junos as a VM within that; day to day, that makes fairly little operational difference - it's mainly noticeably different when it comes to upgrading Junos versions during maintenance windows and the slightly different ways this is done between the two host OSs. Whilst Juniper have long claimed a "one Junos" (where all the commands are hypothetically uniform across the entire hardware range), this is starting to break down a little, so do be prepared for the odd difference between different Juniper hardware platforms and software versions; another, perhaps unsurprising, difference is configuring bridges and VLANs on things that are "switches" (EX series) vs things that are "routers" (MX series). 

Having a physical device (or preferably several) as you learn things is really quite helpful. Although you can make use of the free vLabs platforms, it is often nicer to have complete freedom to configure things as you wish - and without time limits. 

Download a few of those resources, or sign up to the courses that look most interesting; start with the JNCIA-Junos course for a solid grounding and go from there. I'm going to assume you're going to embark on your own learning journey here, and will explore the CLI in your own time, so I don't cover all the details below. 

In the rest of this post, I'll suggest a few things you might want to play with in your lab.

See also: 


Flow and Packet Mode

The SRX platform is intended to be a stateful firewall. Out of the box, this makes using them as routers a little harder than it needs to be. The SRX110 ships with a configuration that make the first port (fe-0/0/0) and the ADSL port "WAN ports" with a DHCP client, and members of the "untrust" firewall zone. The rest of the ports are bridged together in a VLAN with a DHCP server which can also be used to managed the device, in the Trust zone, with NAT set up out the WAN port, and a basic permissive outgoing firewall ruleset. This makes it work like a lot of consumer "routers" - plug the WAN port into something with a working Internet connection, and connect your PC to one of the "LAN" ports, and it will "just work" as a stateful firewall (although if you're using the ADSL port or 3G USB modem port, you'll need to do some config to get them to work). 

If you're trying to learn routing on Junos, get the firewall features out of the way (obviously in production you keep firewalls firmly in the way!). The stateful firewall mode is known as "flow" mode (because, of course, a stateful firewall keeps track of connections - flows - of traffic); the alternative is known as "packet" mode, as it treats each packet separately, as a typical router would. 

An SRX in flow mode looks like this when you issue the show security flow status command:

root> show security flow status

  Flow forwarding mode:
  Inet forwarding mode: flow based
    Inet6 forwarding mode: drop
    MPLS forwarding mode: drop
    ISO forwarding mode: drop
  Flow trace status
    Flow tracing status: off
  Flow session distribution
    Distribution mode: RR-based
  Flow ipsec performance acceleration: off
  Flow packet ordering
    Ordering mode: Hardware

You may find things like MPLS forwarding mode: drop cramp your style!

Putting most SRX devices into packet mode is a question of two commands in configure mode:

delete security

to remove the flow security filters, and

set security forwarding-options family mpls mode packet-based

to set up packet mode and then, of course, a commit and a request system reboot

If you issue the show security flow status command after doing that - but before rebooting - you'll notice the output changes a bit: 

root@srx2> show security flow status
 Flow forwarding mode:
    Inet forwarding mode: flow based (reboot needed to change to packet based)
    Inet6 forwarding mode: drop
    MPLS forwarding mode: drop (reboot needed to change to packet based)
    ISO forwarding mode: drop
  Flow trace status
    Flow tracing status: off
  Flow session distribution
    Distribution mode: RR-based
  Flow ipsec performance acceleration: off
  Flow packet ordering
    Ordering mode: Hardware

(I also set the hostname, hence the @srx2 in the prompt).

After rebooting, you'll have: 

root@srx2> show security flow status
 Flow forwarding mode:
    Inet forwarding mode: packet based
    Inet6 forwarding mode: drop
    MPLS forwarding mode: packet based
    ISO forwarding mode: drop
  Flow trace status
    Flow tracing status: off
  Flow session distribution
    Distribution mode: RR-based
  Flow ipsec performance acceleration: off
  Flow packet ordering
    Ordering mode: Hardware

In particular, you will find it much easier to work in packet mode if you're learning features that require packet mode handling of packets to work; in flow mode, you may keep hitting barriers to learning that are not because you misconfigured something, but rather because you haven't managed to get the particular packets you need to be processed in packet mode instead of in flow mode. 

Whilst you can make use of "selective stateless packet based services" interface packet filters to force those packets that need to be handled packet by packet in packet mode, you may be better served learning the underlying technology first (in packet mode), and knowing that you can make it work without complicating it with a bunch of special exceptions for traffic that needs "special" handling (in flow mode). In other words, learn the routing protocols you want to learn, learn Juniper's stateful SRX firewalling, and then stateless interface packet filters - and only then combine them once you're confident with all of them, instead of wondering whether you've messed up something with the protocol - or just not got the filters right. Start simple, then complicate! 

If you later want to learn the firewall features AND making them work with packet mode protocols, you can always just revert back to factory settings and go from there - or change the configuration to remove the packet mode configuration and put back stateful flow mode rules. You'll probably have to add the host-inbound-traffic configuration for the protocols you want to work on, too within each relevant zone. 

see also: 


How many should I buy, and which ones?

SRX devices are common in home labs for people that work with Juniper gear - they seem to be widely available and quite cheap second hand. You want at least two, although three or more is probably better, because you can construct more complex topologies - but you can get away with just one if you're happy to deal with the initially mind-bending nature of a virtualised topology within a single router - stay tuned for how to do this a bit later in this post. Another bonus of physical units is it is pretty easy to simulate link failures - just pull the cable out; that can be more of a challenge in virtualised environments (but is pretty easy - disable the interface).

If you want to try inter-vendor compatibility, buy at least one router from another vendor, perhaps a Cisco if you want to be pretty "industry standard", or something else if you want to save some money - many Mikrotik routers can be bought new for less money than a 5 year old "enterprise" router. I learnt a lot of my early networking on Mikrotik 750 units (hEX lite is the current equivalent; hAP lite are even cheaper) - but they have their quirks. 

If you want to experience more platforms in the Juniper range, then get other devices (perhaps two EX series that can do Virtual Chassis, and at least one MX router; QFX are pretty new, high end and therefore expensive). Ideally, make sure the platform you're buying is still somewhat supported and has a reasonably recent version of Junos installed (preferably the version currently being targeted in certifications for said platform). Unfortunately, the EX series switches are still quite expensive, and some of the basic modes don't support virtual chassis (VC) - and some of the mid range ones need accessory modules to configure VC (like EX4200s need an EX-UM-2X4SFP). 

If you are trying to learn the concepts, buying EoL/EoS units is not a problem. However, if you're trying to experiment and learn with specific current technologies not available in the older platforms, or latest versions of the operating system, you may find this cramps your style (particularly if they aren't available in a vLab) - but if you're doing that, hopefully your employer will supply you with what you need to demonstrate the concept in a work lab, because it's going to cost you a huge amount to build for yourself at home!


A suggestion...

Although I will give a lot of configuration below that you could just copy and paste, I strongly recommend that you come up with your own topology, numbering scheme and ideas - and manually type the commands in yourself. I know from my own personal experience that it is MUCH easier to learn (and remember) the command syntax that way - and you'll understand what and why configuration is done in a particular way much better - if you do it yourself, line by line. Words in a book (or blog!) or config copy/pasted - or existing production routers you look at the config for - will never teach you as much as actually implementing things from scratch on you own. By all means start out by copy/pasting "working" configurations to get a feel for a platform or topic - but you will ultimately get more value out of truly doing it yourself - designing the topology, deciding on various architectural choices, and implementing - and testing (and even documenting) - the entire configuration yourself. 

In terms of how you ought to proceed, arguably, whichever way your brain best "gets" it - but my suggestion is to start with a business need, plan for the design you're trying to do to meet that need, then creating all the necessary interfaces with required addresses, assigning them to routing instances as needed, then adding in the various protocols, filters, and of course, verification/testing. 

In other words the suggested basic steps are:

  1. identify needs
  2. design (decide what you want to achieve; make an annotated network diagram / sketch)
  3. create interfaces and physical (or logical) interconnections
  4. assign IP addresses
  5. create (virtual) routers
  6. assign interfaces to virtual routers, if necessary
  7. set up routing protocols or static routes, assigning to virtual routers if necessary.
  8. set up any additional configuration you want to learn about (many routing protocols need route filters, or you may need to "leak" routes between routing instances)
  9. verification - does it work?
  10. documentation - cement your learning by writing it all down.

Virtual Routers and Interfaces

Of course, if you only have a few routers (or just one), you might like to try creating additional virtual routers inside the one(s) you have. This also helps if you're struggling to run big topologies of virtualised routers in something like eve-ng on a modest machine. On some of the higher end Juniper platforms, you can have literally thousands of virtual routers. Obviously, on more basic routers, you're not going to try carrying entire Internet routing tables many times over (or at all!) over tens or hundreds of virtual devices - a few illustrative prefixes are all you need to learn a platform and experiment. 

Don't have enough physical ports? You can use sub-interfaces and VLANs or even logical tunnel interfaces. In this post, I'm going to pretend I only have a single SRX and need to create a topology between several routers - on a single device. 

Note that you should be quite far along in your understanding Junos journey before you start playing with these, as it can get quite confusing (use your network diagram!), but as you grow out of the basic lab scenarios and want to create something a bit more complicated (crazy?) and don't have a lot of gear, this is definitely a route to explore. It will help you greatly to design something on paper, and then figure out how to make it work, annotating the diagram as you go (with interface names and IP addresses - and any other information you find useful). 

Obviously, there are limits to how many of these you can make on the lower end platforms (and even the high end platforms) - so you're certainly not going to simulate the entire internet or a large campus LAN or enterprise WAN on a single device. You're likely to find the number is surprisingly high, although performance might not be stellar, it will be good enough to learn on!

Before you start, draw your intended topology out - consider putting boxes grouping the physical and virtual routers belonging to each actual unit you have, so you know "where" each unit is and what it is called. Label the physical or virtual interconnections (ports, VLANs, or any other interfaces) and IP addresses between them, too. 

Aside from the typically licensed feature of logical-systems, there are two major types of router virtualisation you'll encounter - routing-instances instance-type vrf and routing-instances instance-type virtual-router (there are of course a few others as well as Node Slicing!).  In this context, you typically want virtual-router; vrf is more commonly deployed in service provider scenarios involving L3 VPNs; in my head I file them as "VRF is for service providers wanting to segregate multiple client VPN networks; virtual-router is when I want to segregate my own network - or pretend I have more routers than I really do". As well as the handy "make more routers for my lab" potential of these, they're quite useful in the real world, too - at my last job, we used virtual-router quite extensively across our core and distribution routers to segregate a campus network into different segments that only "met" on our edge routers and had to traverse the firewall (both ways, so the policies relevant to each segment applied, as necessary) to do so, even though they shared physical infrastructure, they were logically segregated with routing instances. 


Creating virtual-routers

Creating a virtual router in Junos is very easy. The syntax is:

set routing-instances <name> instance-type virtual-router 

for example, to create one called VR1: 

set routing-instances VR1 instance-type virtual-router

You should get into the habit of always adding loopback interfaces and IP addresses to routers - virtual routers are no different than "real" ones in this regard! 

set interface lo0 unit 1 family inet address 10.255.2.1/32
set interface lo0 unit 2 family inet address 10.255.2.2/32

We'll associate these interfaces with the virtual router in a later step.  

Furthermore, you should get into the habit of specifying the router-id used in routing protocols as the loopback IP address. If you don't, Junos will pick one of the configured router IP addresses as the router-id, typically either the IP address of the loopback, or the lowest numbered IP on an interface if a loopback IP is not configured. This may not be what you want; operationally, it is VERY useful to have the router ID and the loopback IP match, so you can easily - and consistently - determine which router is sending what. Setting this is pretty easy. 

set routing-instances VR1 routing-options router-id 10.255.2.1
set routing-instances VR2 routing-options router-id 10.255.2.2

Now, any routing protocol you happen to run on those routing-instances will have the router-id match the loopback IP address. 

 

Creating virtual interfaces (logical tunnels)

The next handy virtual construct for a complex virtual lab topology is virtual interfaces - logical tunnels. You can simply create an interface like lt-0/0/0.0, assign it an IP address and assign it to one of your virtual routing-instances. Logical tunnels, somewhat like loopbacks, never really go down, so they will still keep on going even if you unplug ethernet cables. Pretty handy!

There are a few minor complications with this. Firstly, you should think of them as point-to-point interfaces - indeed, you need to specify which lt interfaces are "connected" with each other; you therefore need to configure them in pairs. 

I like to keep some kind of consistency in naming and numbering so I don't have to think too hard about which bits belong with which other bits, so I keep things like virtual-router names and interface units consistent - so a virtual router called VR1 will use Unit 1 not only for a lo0 interface, but also for its lt interfaces; VR2 will use Unit 2 - and so on. Eventually, this can break down somewhat (if you've already used Unit 1 and Unit 2 to link router one and two together, what do you use to link router 2 to router 3? You can of course contrive more complex numbering schemes (like unit 12 links router 1 to router 2; unit 21 links router 2 to router 1 - and so on). Unit numbers are 14 bits long, so you can have over 16,000 of them! If you've not already come across the concept, you ALWAYS need to configure a logical sub-interface on a physical interface in Junos before you can use it - most commonly, you'll use unit 0, but you don't have to label sequentially, and you don't always have to assign unit 0 (as long as you assign at least one unit subinterface of some numeric value; in some cases, you are restricted to unit 0, but Junos will let you know if you're trying to do something it doesn't like during commit or commit check).
If you're applying IP addresses to VLAN units, it is strongly recommended that you match the unit number to the VLAN ID, although it is not mandatory.
If you've not noticed, you'll often see the unit number appended to the interface name - so lt-0/0/0.0 is unit 0 on lt-0/0/0.
You can save yourself a tiny bit of typing by specifying the interface with the unit number - so 

set interface lt-0/0/0 unit 0 family inet address 10.0.0.0/30
and 
set interface lt-0/0/0.0 family inet address 10.0.0.0/30 

are both valid set commands for the same logical sub-interface; the former is the more commonly used command syntax - basically, note that typing .<unit number> after the physical interface is equivalent to unit <unit number>.

Labeling things (adding descriptions) can also be very useful, for example:

set interfaces lt-0/0/0 unit 1 description VR1-VR2 
set interfaces lt-0/0/0.2 description "VR2 to VR1"

If you want to include spaces in your text, make sure you quote the text - it can be a good habit to get into to always add quotes to your descriptions, just in case. 

In order to create the logical tunnel, first set up the VR1 side. Note the peer-unit is the unit number I want as the "other end" of the connection. In this instance, I want to assign Unit 1 to Virtual Router 1, and Unit 2 to Virtual Router 2 - and use these two interfaces to link between these two virtual routers.  

set interfaces lt-0/0/0 unit 1 encapsulation vlan
set interfaces lt-0/0/0 unit 1 vlan-id 1
set interfaces lt-0/0/0 unit 1 peer-unit 2
set interfaces lt-0/0/0 unit 1 family inet address 10.10.1.1/30
You can also do this as one very long set command, but the order of the elements matters; some attempts at this will be syntactically invalid. If you do them in the same order as show above (interface unit, encapsulation type, vlan-id, peer-unit, IP addressing) it works: 
set interfaces lt-0/0/0.1 encapsulation vlan vlan-id 1 peer-unit 2 family inet address 10.10.1.1/30 
Next, set up the other side of the connection:

set interfaces lt-0/0/0 unit 2 encapsulation vlan
set interfaces lt-0/0/0 unit 2 vlan-id 1
set interfaces lt-0/0/0 unit 2 peer-unit 1
set interfaces lt-0/0/0 unit 2 family inet address 10.10.1.2/30

(You could use the "one liner" syntax here, too. If you're struggling to work out the right order, pipe the output of a show command for an already configured grouping of stanzas to | display set to see a working order for a potential one liner - e.g. show configuration interfaces lt-0/0/0.1 | display set and follow that order).  

Note that you must set an encapsulation type on lt interfaces - vlan should meet most needs for this sort of labbing; ethernet may work just as well. You may want to use different VLAN IDs to keep things separate between router instances - but that of course the VLAN IDs on both sides of the connection need to match! Use one unique vlan-id per pair of interfaces.

This results in the following configuration listing: 

root@srx2> show configuration interfaces lt-0/0/0
unit 1 {
    description VR1-VR2;
    encapsulation vlan;
    vlan-id 1;
    peer-unit 2;
    family inet {
        address 10.10.1.1/30;
    }
}
unit 2 {
    description VR2-VR1;
    encapsulation vlan;
    vlan-id 1;
    peer-unit 1;
    family inet {
        address 10.10.1.2/30;
    }
}

You can always try using /31 subnets for point-to-point interfaces - Junos supports them in certain scenarios, and they can add up to a lot of saved IP addresses (or even the more exotic un-numbered interface). Of course, in a home lab you're not typically short of RFC1918 space - but particularly if you're using scarce publicly routable IPv4 addresses, you want to be efficient!

You then need to assign your newly minted interfaces to the relevant routing-instance. Issue the following commands to create virtual routers and assign interfaces to them: 

set routing-instances VR1 instance-type virtual-router
set routing-instances VR1 interface lt-0/0/0.1
set routing-instances VR1 interface lo0.1

set routing-instances VR2 instance-type virtual-router
set routing-instances VR2 interface lt-0/0/0.2
set routing-instances VR2 interface lo0.2

In the configuration listing, this will look like this: 

root@srx2# show routing-instances

VR1 {
    instance-type virtual-router;
    interface lt-0/0/0.1;
    interface lo0.1;
}
VR2 {
    instance-type virtual-router;
    interface lt-0/0/0.2;
    interface lo0.2;
}

You now have two routing instances, VR1 and VR2; they have both a loopback interface (lo0.<something>) and a point-to-point virtual logical tunnel interface (lt-0/0/0.<something>) between them. Time to check if it works!

First, can you ping one from the other? 

Below, you'll see that you can ping the other side of the connection from each virtual router; that you can't ping the loopback on the remote router (no route exists); but that the respective local loopback is accessible from within each virtual router: 

root@srx2> ping inet routing-instance VR1 10.10.1.2
PING 10.10.1.2 (10.10.1.2): 56 data bytes
64 bytes from 10.10.1.2: icmp_seq=0 ttl=64 time=2.255 ms
^C
--- 10.10.1.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 2.255/2.255/2.255/0.000 ms

root@srx2> ping inet routing-instance VR2 10.10.1.1
PING 10.10.1.1 (10.10.1.1): 56 data bytes
64 bytes from 10.10.1.1: icmp_seq=0 ttl=64 time=4.186 ms
64 bytes from 10.10.1.1: icmp_seq=1 ttl=64 time=2.209 ms
^C
--- 10.10.1.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 2.209/3.197/4.186/0.989 ms

root@srx2> ping inet routing-instance VR1 10.255.2.2
PING 10.255.2.2 (10.255.2.2): 56 data bytes
ping: sendto: No route to host
ping: sendto: No route to host
^C
--- 10.255.2.2 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

root@srx2> ping inet routing-instance VR2 10.255.2.1
PING 10.255.2.1 (10.255.2.1): 56 data bytes
ping: sendto: No route to host
ping: sendto: No route to host
^C
--- 10.255.2.1 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

root@srx2> ping inet routing-instance VR1 10.255.2.1
PING 10.255.2.1 (10.255.2.1): 56 data bytes
64 bytes from 10.255.2.1: icmp_seq=0 ttl=64 time=0.314 ms
^C
--- 10.255.2.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.314/0.314/0.314/0.000 ms

root@srx2> ping inet routing-instance VR2 10.255.2.2
PING 10.255.2.2 (10.255.2.2): 56 data bytes
64 bytes from 10.255.2.2: icmp_seq=0 ttl=64 time=1.292 ms
^C
--- 10.255.2.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.292/1.292/1.292/0.000 ms
You can see that in Junos, you can specify which routing-instance you want to ping from quite easily. You should of course deduce you can't reach the loopback of the other router - because there is no route to it. 

Routing between virtual routers

So how would we make routing work? We could use static routing, but that does not scale, and you need to get used to running an IGP. So, let's get OSPF working!

As you want to route between the virtual routers themselves with other routers, you need to set up OSPF within each of the routing-instances. In Juniper, you basically tell it what OSPF area you want each interface to be part of, and off it goes: 
set routing-instances VR1 protocols ospf area 0.0.0.0 interface lo0.1 passive
set routing-instances VR1 protocols ospf area 0.0.0.0 interface lt-0/0/0.1 
set routing-instances VR2 protocols ospf area 0.0.0.0 interface lt-0/0/0.2
set routing-instances VR2 protocols ospf area 0.0.0.0 interface lo0.2 passive
The passive command on the loopback interfaces sets them into passive mode - OSPF can advertise the directly connected IP address(es), but it will not send OSPF hello messages or form an adjacency on a passive interface. It is generally best practice to set any interface you're running OSPF on that you don't actively intend to communicate to a neighbor [sic] as passive. If you didn't include the routing-instances <name> argument in the set protocols ospf command, it would make these interfaces part of the main (physical) router's ospf calculations - which isn't quite what you want here. 

Can we now reach the loopback on the other end? 
root@srx2> ping inet routing-instance VR2 10.10.1.1
PING 10.10.1.1 (10.10.1.1): 56 data bytes
64 bytes from 10.10.1.1: icmp_seq=0 ttl=64 time=2.113 ms
64 bytes from 10.10.1.1: icmp_seq=1 ttl=64 time=2.343 ms
^C
--- 10.10.1.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 2.113/2.228/2.343/0.115 ms

root@srx2> ping inet routing-instance VR1 10.255.2.2
PING 10.255.2.2 (10.255.2.2): 56 data bytes
64 bytes from 10.255.2.2: icmp_seq=0 ttl=64 time=2.062 ms
64 bytes from 10.255.2.2: icmp_seq=1 ttl=64 time=2.274 ms
^C
--- 10.255.2.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 2.062/2.168/2.274/0.106 ms
Indeed we can! 

This means dynamic routing is working between the two virtual routers over a virtual interface. Fancy!

We can have a look at VR1's routing table to see where it is getting that information from:
root@srx2> show route table VR1.inet.0

VR1.inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

10.10.1.0/30       *[Direct/0] 01:20:47
                    > via lt-0/0/0.1
10.10.1.1/32       *[Local/0] 01:20:47
                      Local via lt-0/0/0.1
10.255.2.1/32      *[Direct/0] 01:47:51
                    > via lo0.1
10.255.2.2/32      *[OSPF/10] 00:06:40, metric 1
                    > to 10.10.1.2 via lt-0/0/0.1
Unsurprisingly, we can see that we've learned the VR2 router loopback IP (10.255.2.2) from OSPF as shown in the last line. Note the format of the routing table name - virtual router instance name <dot> inet <dot> 0. inet.0 is the routing table for IPv4 across Junos; each virtual router will create its own separate <name>.inet.0 table. In this case, obviously, we looked at the table VR1.inet.0. 

You can further check the status of OSPF in a few ways. 
Firstly show ospf neighbor instance <instance name>

root@srx2> show ospf neighbor instance VR1
Address          Interface              State     ID               Pri  Dead
10.10.1.2        lt-0/0/0.1             Full      10.255.2.2       128    33
Typically, you want to see the neighbors [sic] in the state "Full". 

You can also check the OSPF link state database for a routing instance, for example: 

root@srx2> show ospf database instance VR1

    OSPF database, Area 0.0.0.0
 Type       ID               Adv Rtr           Seq      Age  Opt  Cksum  Len
Router  *10.255.2.1       10.255.2.1       0x80000005   977  0x22 0x7852  48
Router   10.255.2.2       10.255.2.2       0x80000006   978  0x22 0x344c  60
Router   10.255.2.3       10.255.2.3       0x80000005   979  0x22 0x6b54  48
Network  10.10.1.2        10.255.2.2       0x80000002   983  0x22 0xfffb  32
Network  10.10.1.6        10.255.2.3       0x80000002   979  0x22 0xe513  32
More usefully: 

root@srx2> show ospf route instance VR1
Topology default Route Table:

Prefix             Path  Route      NH       Metric NextHop       Nexthop
                   Type  Type       Type            Interface     Address/LSP
10.255.2.2         Intra Router     IP            1 lt-0/0/0.1    10.10.1.2
10.255.2.3         Intra Router     IP            2 lt-0/0/0.1    10.10.1.2
10.10.1.0/30       Intra Network    IP            1 lt-0/0/0.1
10.10.1.4/30       Intra Network    IP            2 lt-0/0/0.1    10.10.1.2
10.255.2.1/32      Intra Network    IP            0 lo0.1
10.255.2.2/32      Intra Network    IP            1 lt-0/0/0.1    10.10.1.2
10.255.2.3/32      Intra Network    IP            2 lt-0/0/0.1    10.10.1.2
Basically any of the OSPF operational commands can be made specific to the relevant routing-instance by appending instance <instance name> to the end of the command; without this, the command will be executed against the main router's OSPF instance.

One thing that might surprise you (at first) is that you can't ping the virtual loopback from the non-virtual router itself!
root@srx2> ping 10.255.2.1
PING 10.255.2.1 (10.255.2.1): 56 data bytes
ping: sendto: No route to host

Note that we haven't specified a routing instance or table - we've just told the router to use its own resources - in other words, use inet.0.  

But, of course, that is exactly what we asked for - a separate, albeit virtual, router! To be able to ping the virtual routers, we need to connect the physical router up to the virtual one in some way, and ensure routing is working - more virtual tunnels, or use of sub-interfaces on a physical link that is up would allow this. An exercise for the reader! :) 

Here's the physical router's inet.0 table. Pretty tiny at the moment!

root@srx2> show route table inet.0

inet.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

10.255.255.2/32    *[Direct/0] 02:12:49
                    > via lo0.0
192.168.1.1/32     *[Local/0] 08:09:28
                      Reject

If you want to create entirely "virtual routers" with separate management credentials and so on, take a look at logical systems; this is obviously more onerous for the hardware, and is a licensed feature on many platforms - you might do this if, for example, you had to hand over management of part of the system to another department. 


Disabling "always up" logical tunnels and virtual routers

If you are used to simply pulling out cables to simulate link failures, you may be wondering how you can cut some virtual wires. The easiest way is to simply deactivate one of the logical interfaces in the link. 

deactivate interfaces lt-0/0/0.2 

will cause the link between VR1 and VR2 to go down (with all the problems that may cause your topology). You'll have to commit the change before it will take effect. To reverse this, either rollback 1  and commit, or 

activate interfaces lt-/0/0/.2

and commit the change. 

You could even go so far as to disable entire virtual routers - similarly, you would use the deactivate command on routing-instance <name> and commit the change, perhaps simulating failure of a whole router or site.


Final Topology

I've not run through every step of this, but a possible end result could look something like this: 

Topology illustrating interface numbering for 8 virtual routers
8 router topology - all created using virtual routers and virtual logical tunnel interfaces.
Diagram created with draw.io.

To me, this represents:

  • some Customer Premises Equipment (CPE) (VR 1 & 8); 
  • some Point-of-Presence (PoP) Provider Edge (PE) routers (VR 2 & 7); 
  • a resilient core network (VR 3,4,5 & 6). 

With something like this, you can experiment extensively!

You could, for instance: 

  • start adding or changing the routing protocol or configuration associated with it, perhaps simulating a change (or even a live migration) of IGP from OSPF to ISIS, or adding BGP;
  • cause yourself immense pain by removing IGP and only using static routes; 
  • add in MPLS;
  • add in additional PoP and CPE sites;
  • multiply connect CPE device(s); 
  • add in an MP-BGP L3VPN between the CPEs or some other provider-style VPN link transparent to layer 2 (with all the required changes to all of the routers to make it work);
  • check the path traffic takes through the topology;
  • change the path traffic takes through the topology with the relevant configuration knobs, or see what effect router/link outages have; 
  • add or subtract available paths between routers, particularly something like LACP;
  • get the physical router to participate in this topology with OSPF and suitable interfaces;
  • add a physical interface into the topology on one of the routers that allows a physical device (like your own laptop) to participate in the topology - perhaps one of the CPEs, complete with a DHCP server you configure on the virtual router;
  • get the virtual topology to inter-operate with a physical router from another manufacturer;
  • allow Internet access from the virtual topology;
  • experiment with route filtering and policy; 
  • change the roles of the routers, adding or removing services, as needed; 
  • add in more routers, perhaps simulating connections to an IXP and/or one or more transit ISPs. 

Given a topology like this with all the point-to-point and loopbacks created, addressed, and interconnected - and a working IGP - you have a very flexible plaything that can teach you a lot. As I mentioned earlier, designing and building your own topology is a much more powerful learning aid, but sometimes, you want to see a working one and get a little more familiar with some of the concepts before you take the plunge yourself. I hope this helps you!


Config listing

If you want to just copy and paste a topology (the one in the diagram above, in fact), here you go; it should work on most Juniper devices, but it was developed and tested on a SRX110H2-VA: 

system {
    host-name srx2;
    name-server {
        208.67.222.222;
        208.67.220.220;
    }
    services {
        ssh;
        xnm-clear-text;
        web-management {
            http {
                interface vlan.0;
            }
            https {
                system-generated-certificate;
                interface vlan.0;
            }
        }
        dhcp {
            pool 192.168.1.0/24 {
                address-range low 192.168.1.2 high 192.168.1.254;
                router {
                    192.168.1.1;
                }
            }
            propagate-settings fe-0/0/0.0;
        }
    }
    syslog {
        archive size 100k files 3;
        user * {
            any emergency;
        }
        file messages {
            any critical;
            authorization info;
        }
        file interactive-commands {
            interactive-commands error;
        }
    }
    max-configurations-on-flash 5;
    max-configuration-rollbacks 5;
    license {
        autoupdate {
            url https://ae1.juniper.net/junos/key_retrieval;
        }
    }
}
interfaces {
    fe-0/0/0 {
        unit 0 {
            family inet;
        }
    }
    lt-0/0/0 {
        unit 1 {
            description VR1-VR2;
            encapsulation vlan;
            vlan-id 1;
            peer-unit 2;
            family inet {
                address 10.10.1.1/30;
            }
        }
        unit 2 {
            description VR2-VR1;
            encapsulation vlan;
            vlan-id 1;
            peer-unit 1;
            family inet {
                address 10.10.1.2/30;
            }
        }
        unit 23 {
            description VR2-VR3;
            encapsulation vlan;
            vlan-id 23;
            peer-unit 32;
            family inet {
                address 10.10.1.5/30;
            }
        }
        unit 25 {
            description VR2-VR5;
            encapsulation vlan;
            vlan-id 25;
            peer-unit 52;
            family inet {
                address 10.10.1.9/30;
            }
        }
        unit 32 {
            description VR3-VR2;
            encapsulation vlan;
            vlan-id 23;
            peer-unit 23;
            family inet {
                address 10.10.1.6/30;
            }
        }
        unit 34 {
            description "VR3 to VR4";
            encapsulation vlan;
            vlan-id 34;
            peer-unit 43;
            family inet {
                address 10.10.1.17/30;
            }
        }
        unit 35 {
            description "VR3 to VR5";
            encapsulation vlan;
            vlan-id 35;
            peer-unit 53;
            family inet {
                address 10.10.1.13/30;
            }
        }
        unit 36 {
            description "VR3 to VR6";
            encapsulation vlan;
            vlan-id 36;
            peer-unit 63;
            family inet {
                address 10.10.1.25/30;
            }
        }
        unit 43 {
            description "VR4 to VR3";
            encapsulation vlan;
            vlan-id 34;
            peer-unit 34;
            family inet {
                address 10.10.1.18/30;
            }
        }
        unit 45 {
            description "VR4 to VR5";
            encapsulation vlan;
            vlan-id 45;
            peer-unit 54;
            family inet {
                address 10.10.1.30/30;
            }
        }
        unit 46 {
            description "VR4 to VR6";
            encapsulation vlan;
            vlan-id 46;
            peer-unit 64;
            family inet {
                address 10.10.1.34/30;
            }
        }
        unit 47 {
            description "VR4 to VR7";
            encapsulation vlan;
            vlan-id 47;
            peer-unit 74;
            family inet {
                address 10.10.1.37/30;
            }
        }
        unit 52 {
            description VR5-VR2;
            encapsulation vlan;
            vlan-id 25;
            peer-unit 25;
            family inet {
                address 10.10.1.10/30;
            }
        }
        unit 53 {
            description "VR5 to VR3";
            encapsulation vlan;
            vlan-id 35;
            peer-unit 35;
            family inet {
                address 10.10.1.14/30;
            }
        }
        unit 54 {
            description "VR5 to VR4";
            encapsulation vlan;
            vlan-id 45;
            peer-unit 45;
            family inet {
                address 10.10.1.29/30;
            }
        }
        unit 56 {
            description "VR5 to VR6";
            encapsulation vlan;
            vlan-id 56;
            peer-unit 65;
            family inet {
                address 10.10.1.21/30;
            }
        }
        unit 63 {
            description "VR6 to VR3";
            encapsulation vlan;
            vlan-id 36;
            peer-unit 36;
            family inet {
                address 10.10.1.26/30;
            }
        }
        unit 64 {
            description "VR6 to VR4";
            encapsulation vlan;
            vlan-id 46;
            peer-unit 46;
            family inet {
                address 10.10.1.33/30;
            }
        }
        unit 65 {
            description "VR6 to VR5";
            encapsulation vlan;
            vlan-id 56;
            peer-unit 56;
            family inet {
                address 10.10.1.22/30;
            }
        }
        unit 67 {
            description "VR6 to VR7";
            encapsulation vlan;
            vlan-id 67;
            peer-unit 76;
            family inet {
                address 10.10.1.41/30;
            }
        }
        unit 74 {
            description "VR7 to VR4";
            encapsulation vlan;
            vlan-id 47;
            peer-unit 47;
            family inet {
                address 10.10.1.38/30;
            }
        }
        unit 76 {
            description "VR7 to VR6";
            encapsulation vlan;
            vlan-id 67;
            peer-unit 67;
            family inet {
                address 10.10.1.42/30;
            }
        }
        unit 78 {
            description "VR7 to VR8";
            encapsulation vlan;
            vlan-id 78;
            peer-unit 87;
            family inet {
                address 10.10.1.45/30;
            }
        }
        unit 87 {
            description "VR8 to VR7";
            encapsulation vlan;
            vlan-id 78;
            peer-unit 78;
            family inet {
                address 10.10.1.46/30;
            }
        }
    }
    fe-0/0/1 {
        unit 0 {
            family ethernet-switching {
                vlan {
                    members vlan-trust;
                }
            }
        }
    }
    fe-0/0/2 {
        unit 0 {
            family ethernet-switching {
                vlan {
                    members vlan-trust;
                }
            }
        }
    }
    fe-0/0/3 {
        unit 0 {
            family ethernet-switching {
                vlan {
                    members vlan-trust;
                }
            }
        }
    }
    fe-0/0/4 {
        unit 0 {
            family ethernet-switching {
                vlan {
                    members vlan-trust;
                }
            }
        }
    }
    fe-0/0/5 {
        unit 0 {
            family ethernet-switching {
                vlan {
                    members vlan-trust;
                }
            }
        }
    }
    fe-0/0/6 {
        unit 0 {
            family ethernet-switching {
                vlan {
                    members vlan-trust;
                }
            }
        }
    }
    fe-0/0/7 {
        vlan-tagging;
        unit 99 {
            description "client interface for VR1";
            vlan-id 99;
            family inet {
                address 192.168.99.1/24;
            }
        }
    }
    pt-1/0/0 {
        unit 0 {
            family inet;
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 10.255.255.2/32;
            }
        }
        unit 1 {
            family inet {
                address 10.255.2.1/32;
            }
        }
        unit 2 {
            family inet {
                address 10.255.2.2/32;
            }
        }
        unit 3 {
            family inet {
                address 10.255.2.3/32;
            }
        }
        unit 4 {
            family inet {
                address 10.255.2.4/32;
            }
        }
        unit 5 {
            family inet {
                address 10.255.2.5/32;
            }
        }
        unit 6 {
            family inet {
                address 10.255.2.6/32;
            }
        }
        unit 7 {
            family inet {
                address 10.255.2.7/32;
            }
        }
        unit 8 {
            family inet {
                address 10.255.2.8/32;
            }
        }
    }
    vlan {
        unit 0 {
            family inet {
                address 192.168.0.1/24;
            }
        }
        unit 1 {
            description "VLAN 1 on VR1 - client subnet";
            family inet {
                address 192.168.1.1/24;
            }
        }
    }
}
protocols {
    rstp;
}
security {
    forwarding-options {
        family {
            mpls {
                mode packet-based;
            }
        }
    }
}
routing-instances {
    VR1 {
        description CPE1;
        instance-type virtual-router;
        interface lt-0/0/0.1;
        interface fe-0/0/7.99;
        interface lo0.1;
        routing-options {
            router-id 10.255.2.1;
        }
        protocols {
            ospf {
                area 0.0.0.0 {
                    interface lo0.1 {
                        passive;
                    }
                    interface lt-0/0/0.1;
                    interface fe-0/0/7.99 {
                        passive;
                    }
                }
            }
        }
    }
    VR2 {
        description PE1;
        instance-type virtual-router;
        interface lt-0/0/0.2;
        interface lt-0/0/0.23;
        interface lt-0/0/0.25;
        interface lo0.2;
        routing-options {
            router-id 10.255.2.2;
        }
        protocols {
            ospf {
                area 0.0.0.0 {
                    interface lt-0/0/0.2;
                    interface lo0.2 {
                        passive;
                    }
                    interface lt-0/0/0.23;
                    interface lt-0/0/0.25;
                }
            }
        }
    }
    VR3 {
        description P1;
        instance-type virtual-router;
        interface lt-0/0/0.32;
        interface lt-0/0/0.34;
        interface lt-0/0/0.35;
        interface lt-0/0/0.36;
        interface lo0.3;
        routing-options {
            router-id 10.255.2.3;
        }
        protocols {
            ospf {
                area 0.0.0.0 {
                    interface lo0.3 {
                        passive;
                    }
                    interface lt-0/0/0.32;
                    interface lt-0/0/0.35;
                    interface lt-0/0/0.34;
                    interface lt-0/0/0.36;
                }
            }
        }
    }
    VR4 {
        description P2;
        instance-type virtual-router;
        interface lt-0/0/0.43;
        interface lt-0/0/0.45;
        interface lt-0/0/0.46;
        interface lt-0/0/0.47;
        interface lo0.4;
        routing-options {
            router-id 10.255.2.4;
        }
        protocols {
            ospf {
                area 0.0.0.0 {
                    interface lt-0/0/0.43;
                    interface lo0.4 {
                        passive;
                    }
                    interface lt-0/0/0.45;
                    interface lt-0/0/0.46;
                    interface lt-0/0/0.47;
                }
            }
        }
    }
    VR5 {
        description P3;
        instance-type virtual-router;
        interface lt-0/0/0.52;
        interface lt-0/0/0.53;
        interface lt-0/0/0.54;
        interface lt-0/0/0.56;
        interface lo0.5;
        routing-options {
            router-id 10.255.2.5;
        }
        protocols {
            ospf {
                area 0.0.0.0 {
                    interface lt-0/0/0.52;
                    interface lo0.5 {
                        passive;
                    }
                    interface lt-0/0/0.53;
                    interface lt-0/0/0.54;
                    interface lt-0/0/0.56;
                }
            }
        }
    }
    VR6 {
        description P4;
        instance-type virtual-router;
        interface lt-0/0/0.63;
        interface lt-0/0/0.64;
        interface lt-0/0/0.65;
        interface lt-0/0/0.67;
        interface lo0.6;
        routing-options {
            router-id 10.255.2.6;
        }
        protocols {
            ospf {
                area 0.0.0.0 {
                    interface lt-0/0/0.63;
                    interface lo0.6 {
                        passive;
                    }
                    interface lt-0/0/0.65;
                    interface lt-0/0/0.64;
                    interface lt-0/0/0.67;
                }
            }
        }
    }
    VR7 {
        description PE2;
        instance-type virtual-router;
        interface lt-0/0/0.74;
        interface lt-0/0/0.76;
        interface lt-0/0/0.78;
        interface lo0.7;
        routing-options {
            router-id 10.255.2.7;
        }
        protocols {
            ospf {
                area 0.0.0.0 {
                    interface lo0.7 {
                        passive;
                    }
                    interface lt-0/0/0.74;
                    interface lt-0/0/0.76;
                    interface lt-0/0/0.78;
                }
            }
        }
    }
    VR8 {
        description CPE2;
        instance-type virtual-router;
        interface lt-0/0/0.87;
        interface lo0.8;
        routing-options {
            router-id 10.255.2.8;
        }
        protocols {
            ospf {
                area 0.0.0.0 {
                    interface lo0.8 {
                        passive;
                    }
                    interface lt-0/0/0.87;
                }
            }
        }
    }
}
vlans {
    vlan-trust {
        vlan-id 3;
        l3-interface vlan.0;
    }
}
You may want to copy/paste through a text editor to get rid of any extraneous formatting it may pick up from being HTML-ised!

You may find this article useful. 

Note that no users or root authentication have been configured above - you should do this. 

No comments:

Post a Comment