Pages

Monday, March 2, 2015

Installing JunOS Olive12.1 in VirtualBox on Linux

If you don't have a real Juniper equipment, there is way to practice with  JUNOS. Of course best way is to have the actual Juniper router since many functions cannot be simulated/emulated. Googling around you will find different methods either using VirtualBox, VMware or Qemu. Methods vary from extremely easy to difficult ( if you want to do it from scratch using FreeBSD - JUNOS is based on FreeBSD kernel.)
Below you can find instructions in 5 steps on how to install JUNOS Olive 12.1 in VirtualBox on Linux. For more details and capabilities of JUNOS Olive check this excellent website.

For this Lab setup I want to uses three Juniper routers in the topology they appear below.

Lab topology for testing three juniper routers


I'm using Linux Mint 17 Qiana and Oracle VirtualBox version 4.3.22r98236
Junos Olive.12.1 is available for download on the internet as a virtual appliance in an Open Virtualization Format Archive (OVA). ( will not be provided here)
Using the OVA file is the fastest way to have a JUNOS up and running.

Step 1 - Import appliance in VirtualBox

From VirtualBox , goto import Appliance and load the Junos Olive.12.1 OVA file. It will create a new VM  named "Junos Olive". All necessary settings are preselected. You may rename the router to a more appropriate name : e.g juniper-R1

Step 2 - Serial Terminal

A serial terminal to the Juniper Router is not really necessary but in case you need it there are many ways. First use the VirtualBox option to enable a serial port to send output through Host pipe to a raw file. Choose an arbitrary file name to connect that pipe.
Example :
Serial Port1
Port Number : COM1
Port Mode : Host Pipe
Port/File path : /tmp/junos_serial_S0

Serial Port configuration for router juniper-R1

All it remains is to redirect that pipe to an output. It appears that from Linux there are many way to do this. Three methods (using the utility socat and GNU screen )  are described  in In Maciej BliziƄski website and a fourth method (using minicom) is described in ReactOS wiki.
I have tested all methods on my workstation and are working properly. I find it easier to use minicom since you can start it before starting the VM juniper routers and waits there for the bootstrap messages. So you cannot miss any bootstrap messages while the juniper router is loading compared to the other methods that require to open 2 terminals after you start the VM juniper routers.


a. Using socat to redirect to a TCP port
Use a TCP Forwarder  to redirect the Host pipe output raw file to a TCP socket ( using any port from 1024 and above).
Open one terminal and type the following (will hang if VM started and pipe is created else will return a prompt):
 sudo socat UNIX-CONNECT:/tmp/junos_serial_S0 TCP-LISTEN:4000
Open a second  terminal and telnet to the local port 4000.
 telnet localhost 4000    

b. Using socat to redirect to screen
Converting to a pty (pseudo teletype device).
Open one terminal and type the following  (will hang if VM started and pipe is created else will return a prompt):
 socat UNIX-CONNECT:/tmp/junos_serial_S0 PTY,link=/tmp/junos_serial_S0_pty    
Open a second terminal and type:
 screen /tmp/junos_serial_S0_pty    


c. Using socat to redirect to STDIO
Redirect the Host pipe output raw file to STDIO
Open one terminal and type the below commands (will return a prompt if pipe is not ready). When Juniper Router is ready, the same terminal window will start showing the complete boot messages as if they were send to the serial console.
 socat UNIX-CONNECT:/tmp/junos_serial_S0 STDIO,raw,echo=0    

d. Using minicom 
Open minicom and goto  "Configure serial ports". Name the device unix#pipe_path where "pipe_path" is a file like /tmp/junos_serial_S0 (exactly as configured in VirtualBox serial port). 

Minicom configuration for the serial device to the pipe raw file

Minicom output showing bootstrap messages as soon as the VM juniper router starts loading


Step 3 - Create more Juniper Routers in VirtualBox

If you are going to have many Juniper Routers in your virtual Lab then create full clone of the already created Juniper-R1  and name the new clones accordingly e.g Juniper-R2, Juniper-R3 etc . Always reinitialize MAC address of network cards. Also modify the serial port pipe file respectively. 
In my example I will have three juniper routers. So we have :
for Juniper-R2 for Serial port Host Pipe Port/File path : /tmp/junos_serial_S1
for Juniper-R3 for Serial port Host Pipe Port/File path : /tmp/junos_serial_S2


Step 4- Interconnecting VM Juniper Routers

Back to my Lab topology diagram adding more details on ip addressing and interface names. Here I went one step further and manually configure the MAC addresses of the interfaces for easily identifying the ports. You can do that from VirtualBox Network adapter advance features.

Lab topology with three juniper routers and details on interfaces and ip addressing

My host workstation has two Ethernet interfaces eth0 and eth9 both connected to the DSL router.

For interconnecting the routers you can use the VirtualBox Internal Adapter (default is "intnet"). In my example I created intnet1 and intnet2 and seem to be working properly. If you run into any problems running a specific topology let me know.

See below all three routers as they appear in VirtualBox with their settings.

Juniper Router R1 settings

Juniper Router R2 settings

Juniper Router R3 settings

Alternatives in interconnect the routers
An alternative way to interconnect the routers in VirtualBox is using the Host-only networking.
One more way to interconnect router in VirtualBox is the VDE which stands for “Virtual Distributed Ethernet“ as suggested in this website.
I have not tried the last two methods yet.

Step 5 - Juniper Basic Configuration / verification

I configure the three juniper routers with basic configuration for testing purposes. Basically edit the hostname, change root password and give ip addresses to the interfaces.

(default username: root, with no password)

JUNIPER-R1
cli
edit
set system host-name juniper-R1
set system root-authentication plain-text-password
set interface em0 unit 0 family inet address 192.168.3.51/24
set interface em1 unit 0 family inet address 10.20.30.1/30
set routing-options static route 0.0.0.0/0 next-hop 192.168.3.1
commit  


JUNIPER-R2
cli
edit
set system host-name juniper-R2
set system root-authentication plain-text-password
set interface em0 unit 0 family inet address 192.168.3.52/24
set interface em1 unit 0 family inet address 10.20.30.2/30
set interface em2 unit 0 family inet address 10.10.10.2/30
set routing-options static route 0.0.0.0/0 next-hop 192.168.3.1
commit  



JUNIPER-R3
cli
edit
set system host-name juniper-R3
set system root-authentication plain-text-password
set interface em0 unit 0 family inet address 10.10.10.1/30
commit  


Verifying the interfaces IP addresses and MAC addresses as per topology diagram.

Output of show interface terse and interface MAC addresses on Juniper R1

Output of show interface terse and interface MAC addresses on Juniper R2

Output of show interface terse and interface MAC addresses on Juniper R3

Now from each router ping to each opposite side to confirm connectivity as well as internet connectivity from Juniper-R1 and Juniper-R2.

Juniper-R1
root@juniper-R1# run ping 8.8.8.8 count 4
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=53 time=89.702 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=53 time=81.044 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=53 time=77.947 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=53 time=78.783 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 77.947/81.869/89.702/4.662 ms

root@juniper-R1# run ping 192.168.3.52 count 3
PING 192.168.3.52 (192.168.3.52): 56 data bytes
64 bytes from 192.168.3.52: icmp_seq=0 ttl=64 time=2.035 ms
64 bytes from 192.168.3.52: icmp_seq=1 ttl=64 time=1.423 ms
64 bytes from 192.168.3.52: icmp_seq=2 ttl=64 time=0.858 ms

--- 192.168.3.52 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.858/1.439/2.035/0.481 ms

root@juniper-R1# run ping 10.20.30.2 count 3    
PING 10.20.30.2 (10.20.30.2): 56 data bytes
64 bytes from 10.20.30.2: icmp_seq=0 ttl=64 time=1.203 ms
64 bytes from 10.20.30.2: icmp_seq=1 ttl=64 time=0.508 ms
64 bytes from 10.20.30.2: icmp_seq=2 ttl=64 time=0.409 ms

--- 10.20.30.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.409/0.707/1.203/0.353 ms

Juniper-R2
root@juniper-R2# run ping 8.8.8.8 count 4  
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=53 time=79.908 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=53 time=82.012 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=53 time=79.156 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=53 time=79.352 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 79.156/80.107/82.012/1.134 ms

root@juniper-R2# run ping 192.168.3.51 count 3 
PING 192.168.3.51 (192.168.3.51): 56 data bytes
64 bytes from 192.168.3.51: icmp_seq=0 ttl=64 time=1.559 ms
64 bytes from 192.168.3.51: icmp_seq=1 ttl=64 time=1.065 ms
64 bytes from 192.168.3.51: icmp_seq=2 ttl=64 time=1.517 ms

--- 192.168.3.51 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.065/1.380/1.559/0.224 ms

root@juniper-R2# run ping 10.20.30.1 count 3      
PING 10.20.30.1 (10.20.30.1): 56 data bytes
64 bytes from 10.20.30.1: icmp_seq=0 ttl=64 time=0.729 ms
64 bytes from 10.20.30.1: icmp_seq=1 ttl=64 time=0.594 ms
64 bytes from 10.20.30.1: icmp_seq=2 ttl=64 time=0.529 ms

--- 10.20.30.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.529/0.617/0.729/0.083 ms

root@juniper-R2# run ping 10.10.10.1 count 3    
PING 10.10.10.1 (10.10.10.1): 56 data bytes
64 bytes from 10.10.10.1: icmp_seq=0 ttl=64 time=1.648 ms
64 bytes from 10.10.10.1: icmp_seq=1 ttl=64 time=0.452 ms
64 bytes from 10.10.10.1: icmp_seq=2 ttl=64 time=0.482 ms

--- 10.10.10.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.452/0.861/1.648/0.557 ms


Juniper-R3
root@juniper-R3# run ping 10.10.10.2 count 3
PING 10.10.10.2 (10.10.10.2): 56 data bytes
64 bytes from 10.10.10.2: icmp_seq=0 ttl=64 time=1.060 ms
64 bytes from 10.10.10.2: icmp_seq=1 ttl=64 time=0.587 ms
64 bytes from 10.10.10.2: icmp_seq=2 ttl=64 time=0.582 ms

--- 10.10.10.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.582/0.743/1.060/0.224 ms

Checking MAC table to confirm IP addressing and MAC addresses
root@juniper-R1> show arp  
MAC Address       Address         Name                      Interface           Flags
08:00:27:44:44:44 10.20.30.2      10.20.30.2                em1.0               none
4c:5e:0c:5a:f7:52 192.168.3.1     192.168.3.1               em0.0               none
08:00:27:33:33:33 192.168.3.52    192.168.3.52              em0.0               none
Total entries: 3

root@juniper-R2> show arp  
MAC Address       Address         Name                      Interface           Flags
08:00:27:66:66:66 10.10.10.1      10.10.10.1                em2.0               none
08:00:27:22:22:22 10.20.30.1      10.20.30.1                em1.0               none
4c:5e:0c:5a:f7:52 192.168.3.1     192.168.3.1               em0.0               none
08:00:27:11:11:11 192.168.3.51    192.168.3.51              em0.0               none
Total entries: 4

root@juniper-R3> show arp  
MAC Address       Address         Name                      Interface           Flags
08:00:27:55:55:55 10.10.10.2      10.10.10.2                em0.0               none


Configuring SSH access
Login to a router ( e.g Juniper-R1) and configure ssh services.
set system services ssh protocol-version v2  

Open a terminal and connect by ssh to the router
ssh root@192.168.3.51  
The authenticity of host '192.168.3.51 (192.168.3.51)' can't be established.
ECDSA key fingerprint is a3:ad:7a:e3:79:61:97:4c:c8:83:ae:2e:f1:05:e4:ab.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.3.51' (ECDSA) to the list of known hosts.
root@192.168.3.51's password:
--- JUNOS 12.1R1.9 built 2012-03-24 12:52:33 UTC

root@juniper-R1%


Testing an OSPF configuration
Just to make sure that multicast traffic is passing when using the VirtualBox Internal Adapter we can activate OSPF between juniper-R2 and juniper-R3

Juniper-R2
set protocols ospf area 0.0.0.0 interface em2.0  

Juniper-R3
set protocols ospf area 0.0.0.0 interface em0.0

root@juniper-R2> show ospf neighbor    
Address          Interface              State     ID               Pri  Dead
10.10.10.1       em2.0                  Full      10.10.10.1       128    30


root@juniper-R3> show ospf neighbor     
Address          Interface              State     ID               Pri  Dead
10.10.10.2       em0.0                  Full      10.10.10.2       128    35



Other useful Juniper commands
To reset configuration to factory
request system zeroize


Reference :
https://automatthias.wordpress.com/2008/09/13/serial-port-in-virtualbox/
http://daemonkeeper.net/563/deploy-junos-on-a-virtualbox-virtual-machine/
https://www.reactos.org/wiki/VirtualBox
http://www.aelmans.eu/work/building-a-juniper-olive-lab/

2 comments:

Anonymous said...

hi, could you explain in mac version

Stelios Agapiou said...

Hi,
Sorry I don't have Mac to try it , but I see that VirtualBox is supported on MAC.
https://www.virtualbox.org/wiki/Mac%20OS%20X%20build%20instructions

So most of the configuration related to Virtual Box should be the same.

Someone else must have try it also, Google the subject you are interested.