updated: 12th of May 2018
published: 3rd of December 2017
In this post I will install a Juniper vSRX for use with the vagrant-libvirt provider. Prior to installing the vSRX there are some required steps to get the KVM host prepped which I will not cover. These steps are covered in the Juniper documentation here.
For reference the following software will be used in this post.
Juniper does not provide a Vagrant Libvirt box, but they do provide a qcow2 image. You will need to download the qcow2 from the Juniper software download section.
Create and change into directory for vSRX files. I like to keep my custom vagrant boxes under ~/vagrant/boxes/ .
mkdir -p ~/vagrant/boxes/juniper
cd ~/vagrant/boxes/juniper
Copy the qcow2 file downloaded earlier to the ~/vagrant/boxes/juniper directory.
cp ~/Downloads/media-vsrx-vmdisk-15.1X49-D120.3.qcow2 .
The maintainers of the vagrant-libvirt plugin have a script that can be used to convert qcow2 images to a vagrant box. Download the libvirt conversion script.
curl -O https://raw.githubusercontent.com/vagrant-libvirt/vagrant-libvirt/master/tools/create_box.sh
Create a bootstrap configuration file named juniper.conf with following contents that will be applied on boot to the vSRX.
system {
host-name vsrx;
root-authentication {
encrypted-password "$1$nq.N1UsY$JxA/ESAj3KuXseXE597gg0"; ## SECRET-DATA
ssh-rsa "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"; ## SECRET-DATA
}
login {
user vagrant {
uid 2000;
class super-user;
authentication {
ssh-rsa "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"; ## SECRET-DATA
}
}
}
services {
ssh {
root-login allow;
}
netconf {
ssh;
}
}
syslog {
user * {
any emergency;
}
file messages {
any any;
authorization info;
}
file interactive-commands {
interactive-commands any;
}
}
license {
autoupdate {
url https://ae1.juniper.net/junos/key_retrieval;
}
}
}
interfaces {
fxp0 {
unit 0 {
family inet {
dhcp;
}
}
}
}
security {
forwarding-options {
family {
inet6 {
mode packet-based;
}
mpls {
mode packet-based;
}
}
}
}
Place the juniper.conf file in a directory named iso_dir .
ls -l iso_dir
# output
total 4
-rw-rw-r-- 1 bradmin bradmin 2050 Nov 29 23:13 juniper.conf
Create an iso image named bootstrap.iso .
mkisofs -l -o bootstrap.iso iso_dir
# output
I: -input-charset not specified, using utf-8 (detected in locale settings)
Total translation table size: 0
Total rockridge attributes bytes: 0
Total directory bytes: 0
Path table size(bytes): 10
Max brk space used 0
176 extents written (0 MB)
Now lets build the vSRX VM.
virt-install \
--name vsrx \
--os-type linux \
--os-variant rhel7 \
--cpu host \
--vcpus=2 \
--hvm \
--arch=x86_64 \
--ram 4096 \
--disk path=junos-media-vsrx-x86-64-vmdisk-18.1R1.9.qcow2,size=16,device=disk,bus=ide,format=qcow2 \
--disk path=bootstrap.iso,device=cdrom,bus=ide \
--boot hd \
--network=network:vagrant-libvirt,model=virtio \
--graphics none \
--import
A virtual console will be connected to the VM and you will be able to see the VM boot up. Once the VM is booted login with the username root and password Juniper and check the IP address assigned to the fxp0.0 interface.
vsrx (ttyd0)
login: root
Password:
--- JUNOS 18.1R1.9 Kernel 64-bit JNPR-11.0-20180308.0604c57_buil
root@vsrx%
root@vsrx% cli
root@vsrx> show interfaces terse | match fxp0.0
# output
fxp0.0 up up inet 192.168.121.99/24
From another host terminal confirm that it is possible to SSH to the VM with the Vagrant insecure_private_key .
# from host shell
ssh vagrant@192.168.121.99 -i ~/.vagrant.d/insecure_private_key
# now logged into guest vsrx
--- JUNOS 18.1R1.9 Kernel 64-bit JNPR-11.0-20180308.0604c57_buil
vagrant@vsrx>
If you can successfully SSH to the vSRX with the Vagrant insecure_private_key its time to package the VM into a Vagrant box. First shutdown the VM.
request system power-off
# output
Power Off the system ? [yes,no] (no) yes
*** FINAL System shutdown message from vagrant@vsrx ***
System going down IMMEDIATELY
To exit the console use one of these key combinations (Assuming English keyboard).
Create a metadata.json file with the following contents.
{"provider":"libvirt","format":"qcow2","virtual_size":16}
Use the previously downloaded create_box.sh script to make a Vagrant box from the qcow2 image.
bash create_box.sh junos-media-vsrx-x86-64-vmdisk-18.1R1.9.qcow2
# output
{16}
==> Creating box, tarring and gzipping
./metadata.json
./Vagrantfile
./box.img
Total bytes written: 4768798720 (4.5GiB, 24MiB/s)
==> junos-media-vsrx-x86-64-vmdisk-18.1R1.9.box created
==> You can now add the box:
==> 'vagrant box add junos-media-vsrx-x86-64-vmdisk-18.1R1.9.box --name junos-media-vsrx-x86-64-vmdisk-18.1R1.9'
Create a metadata file called vsrx.json so that the box is added with the correct version number.
{
"name": "juniper/vsrx",
"description": "Juniper vSRX",
"versions": [
{
"version": "18.1R1.9-packetmode",
"providers": [
{
"name": "libvirt",
"url": "file:///home/bradmin/vagrant/boxes/juniper/junos-media-vsrx-x86-64-vmdisk-18.1R1.9.box"
}
]
}
]
}
Add the box to Vagrant using the vsrx.json file.
vagrant box add vsrx.json
# output
==> box: Loading metadata for box 'vsrx.json'
box: URL: file:///home/bradmin/vagrant/boxes/juniper/vsrx.json
==> box: Adding box 'juniper/vsrx' (v18.1R1.9-packetmode) for provider: libvirt
box: Unpacking necessary files from: file:///home/bradmin/vagrant/boxes/juniper/junos-media-vsrx-x86-64-vmdisk-18.1R1.9.box
==> box: Successfully added box 'juniper/vsrx' (v18.1R1.9-packetmode) for 'libvirt'!
Confirm the vsrx box was added successfully.
vagrant box list
# output
CumulusCommunity/cumulus-vx (libvirt, 3.6.0)
.
. <snip>
.
juniper/vsrx (libvirt, 12.1X47-D15.4-packetmode)
juniper/vsrx (libvirt, 12.1X47-D15.4)
juniper/vsrx (libvirt, 18.1R1.9-packetmode)
Use this Vagrantfile to test out the new vSRX Vagrant box.
# -*- mode: ruby -*-
# vi: set ft=ruby :
cwd = Dir.pwd.split("/").last
Vagrant.configure("2") do |config|
config.vm.define "rt01" do |node|
hostname = "rt01"
node.vm.box = "juniper/vsrx"
node.vm.box_version = "18.1R1.9-packetmode"
node.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
node.ssh.insert_key = false
# Limit CPU once Box has finished booting.
node.trigger.after :up do |trigger|
trigger.name = "Finished Message"
trigger.info = "Machine is up! : #{cwd}_#{hostname}"
trigger.run = {inline: "virsh schedinfo #{cwd}_#{hostname} --set vcpu_quota=33000"}
end
node.vm.provider :libvirt do |domain|
domain.nic_adapter_count = 1
domain.disk_bus = "ide"
domain.cpus = 2
domain.memory = 4096
end
end
end
Lets vagrant up and make sure we can connect to the vSRX.
vagrant up
# output
Bringing machine 'rt01' up with 'libvirt' provider...
==> rt01: Checking if box 'juniper/vsrx' is up to date...
==> rt01: Uploading base box image as volume into libvirt storage...
==> rt01: Creating image (snapshot of base box volume).
==> rt01: Creating domain with the following settings...
==> rt01: -- Name: vsrx_rt01
==> rt01: -- Domain type: kvm
==> rt01: -- Cpus: 2
==> rt01:
==> rt01: -- Feature: acpi
==> rt01: -- Feature: apic
==> rt01: -- Feature: pae
==> rt01: -- Memory: 4096M
==> rt01: -- Management MAC:
==> rt01: -- Loader:
==> rt01: -- Base box: juniper/vsrx
==> rt01: -- Storage pool: disk1
==> rt01: -- Image: /var/lib/libvirt/images/vsrx_rt01.img (16G)
==> rt01: -- Volume Cache: default
==> rt01: -- Kernel:
==> rt01: -- Initrd:
==> rt01: -- Graphics Type: vnc
==> rt01: -- Graphics Port: -1
==> rt01: -- Graphics IP: 127.0.0.1
==> rt01: -- Graphics Password: Not defined
==> rt01: -- Video Type: cirrus
==> rt01: -- Video VRAM: 9216
==> rt01: -- Sound Type:
==> rt01: -- Keymap: en-us
==> rt01: -- TPM Path:
==> rt01: -- INPUT: type=mouse, bus=ps2
==> rt01: Creating shared folders metadata...
==> rt01: Starting domain.
==> rt01: Waiting for domain to get an IP address...
==> rt01: Waiting for SSH to become available...
==> rt01: Configuring and enabling network interfaces...
rt01: SSH address: 192.168.121.175:22
rt01: SSH username: vagrant
rt01: SSH auth method: private key
==> rt01: Running triggers after up ...
==> rt01: Running trigger: Finished Message...
==> rt01: Machine is up! : vsrx_rt01
rt01: Running local: Inline script
rt01: virsh schedinfo vsrx_rt01 --set vcpu_quota=33000
rt01: Scheduler : posix
rt01: cpu_shares : 1024
rt01: vcpu_period : 100000
rt01: vcpu_quota : 33000
rt01: emulator_period: 100000
rt01: emulator_quota : -1
Now SSH into vSRX.
# from host shell
vagrant ssh
# now in vSRX shell
Last login: Sat May 12 04:39:58 2018
--- JUNOS 18.1R1.9 Kernel 64-bit JNPR-11.0-20180308.0604c57_buil
vagrant@vsrx> show version
Hostname: vsrx
Model: vsrx
Junos: 18.1R1.9
Now that we are able to connect now lets clean up the box.
# from host shell
vagrant destroy -f
# output
==> rt01: Removing domain...
Remove the original KVM image.
rm -f junos-media-vsrx-x86-64-vmdisk-18.1R1.9.qcow2
virsh undefine vsrx
# output
Domain vsrx has been undefined
The vSRX is a staple platform in the Juniper product line. If you made it this far you will have a modern Juniper vSRX Vagrant box configured for use with the vagrant-libvirt provider. Now it's time to go out and build some Juniper labs.