vSRX - your personal laptop firewall!
I love to lab.
One of the problems of running anything in a 'lab' environment, however, is that it can be a bit too clinical. Traffic generation can become a chore. Earlier this week, I was using Vagrant to spin up some vSRX labs on my laptop when it occurred to me that I could probably just gateway my native traffic through a VM.
There's probably a few ways to achieve this but here are the steps I followed:
1. sudo apt update
2. sudo apt install virtualbox
3. wget https://releases.hashicorp.com/vagrant/2.2.6/vagrant_2.2.6_x86_64.deb (earlier versions are plagued with bugs)
4. sudo dpkg -i vagrant_2.2.6_x86_64.deb
5. vagrant plugin install vagrant-host-shell
6. vagrant plugin install vagrant-junos
7. mkdir vsrx
8. cd vsrx
9. vagrant init juniper/ffp-12.1X47-D15.4
10. vagrant up
Michael@schumacher:/vsrx$ vagrant status Current machine states: default running (virtualbox) The VM is running. To stop this VM, you can run `vagrant halt` to shut it down forcefully, or you can run `vagrant suspend` to simply suspend the virtual machine. In either case, to restart it again, simply run `vagrant up`. Michael@schumacher:/vsrx$ vagrant ssh default --- JUNOS 12.1X47-D15.4 built 2014-11-12 02:13:59 UTC root@vsrx% cli root@vsrx> show interfaces terse Interface Admin Link Proto Local Remote ge-0/0/0 up up ge-0/0/0.0 up up inet 10.0.2.15/24 gr-0/0/0 up up ip-0/0/0 up up lsq-0/0/0 up up lt-0/0/0 up up mt-0/0/0 up up sp-0/0/0 up up sp-0/0/0.0 up up inet inet6 sp-0/0/0.16383 up up inet 10.0.0.1 --> 10.0.0.16 10.0.0.6 --> 0/0 128.0.0.1 --> 128.0.1.16 128.0.0.6 --> 0/0 dsc up up gre up up ipip up up irb up up lo0 up up lo0.16384 up up inet 127.0.0.1 --> 0/0 lo0.16385 up up inet 10.0.0.1 --> 0/0 10.0.0.16 --> 0/0 128.0.0.1 --> 0/0 128.0.0.4 --> 0/0 128.0.1.16 --> 0/0 lo0.32768 up up lsi up up mtun up up pimd up up pime up up pp0 up up ppd0 up up ppe0 up up st0 up up tap up up vlan up down root@vsrx> exit root@vsrx% exit logout Connection to 127.0.0.1 closed. Michael@schumacher:/vsrx$ vagrant destroy -f ==> default: Forcing shutdown of VM... ==> default: Destroying VM and associated drives...
So that gets us a basic vSRX up and running.
Next, we'll need to define an inside (tap0) interface and an outside (wlan0) interface that we can bridge the VM to. Wireless access points tend to be picky about allowing foreign MACs through the front door so we'll allow the native adapter to authenticate to the AP but we'll remove the ability to initialise the IP stack, before gifting the native MAC to vSRX.
First, let's check the MAC address on wlan0:
Michael@schumacher:/vsrx$ ifconfig wlan0 | grep ether ether a1:b1:c1:d1:e1:f1 txqueuelen 1000 (Ethernet)
Next, let's replace the Vagrantfile. Don't forget to pop your MAC address in there:
Vagrant.configure(2) do |config| config.vm.box = "juniper/ffp-12.1X47-D15.4" config.vm.provider "virtualbox" do |vb| vb.memory = 512 vb.cpus = 2 vb.gui = false end config.vm.define "vsrx" do |vsrx| vsrx.vm.host_name = "vSRX" vsrx.vm.network "public_network", auto_config: false, bridge: "wlan0", :mac => "a1b1c1d1e1f1" vsrx.vm.network "public_network", auto_config: false, bridge: "tap0" vsrx.vm.provision "file", source: "scripts/vsrx.sh", destination: "/tmp/vsrx.sh" vsrx.vm.provision :host_shell do |host_shell| host_shell.inline = 'vagrant ssh vsrx -c "/usr/sbin/cli -f /tmp/vsrx.sh"' end end end
We'll also need to create a 'scripts' directory within the vsrx folder to hold the vsrx.sh file we've referenced above. Vagrant commandeers ge-0/0/0 for management, which leaves us with ge-0/0/1 for wlan0 and ge-0/0/2 for our virtual adapter, tap0:
configure set system services web-management http interface ge-0/0/2.0 set security zones security-zone untrust interfaces ge-0/0/1 host-inbound-traffic system-services dhcp set security zones security-zone untrust host-inbound-traffic system-services ping set security zones security-zone trust interfaces ge-0/0/2 host-inbound-traffic system-services protocols all set security zones security-zone trust host-inbound-traffic system-services all set routing-instances INTERNET instance-type virtual-router set routing-instances INTERNET interface ge-0/0/1.0 set routing-instances INTERNET interface ge-0/0/2.0 set security nat source rule-set TRUST-TO-UNTRUST from zone trust set security nat source rule-set TRUST-TO-UNTRUST to zone untrust set security nat source rule-set TRUST-TO-UNTRUST rule TRUST-TO-INTERNET match source-address 10.88.88.0/24 set security nat source rule-set TRUST-TO-UNTRUST rule TRUST-TO-INTERNET match destination-address 0.0.0.0/0 set security nat source rule-set TRUST-TO-UNTRUST rule TRUST-TO-INTERNET then source-nat interface set interfaces ge-0/0/1 description "Bridged - wlan0" set interfaces ge-0/0/1 unit 0 family inet dhcp set interfaces ge-0/0/2 description "Bridged - tap0" set interfaces ge-0/0/2 unit 0 family inet address 10.88.88.1/24 commit and-quit
The vsrx.sh is simply the config we will automatically push to the device every time it's instantiated.
Next, let's bring up the virtual interface and fire some DNS into resolv.conf:
ip tuntap add tap0 mode tap ip addr add 10.88.88.111/24 dev tap0 ip link set dev tap0 up ip route add default via 10.88.88.1 echo "nameserver 8.8.8.8" >> /etc/resolv.conf
Let's not forget to disable any IP allocation on the wireless interface. Do the same for IPv6, too. All traffic must go via vSRX:
Time to bring up the VM and test:
root@vSRX> ping routing-instance INTERNET 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 64 bytes from 8.8.8.8: icmp_seq=0 ttl=57 time=30.447 ms 64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=14.362 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=15.521 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=14.575 ms 64 bytes from 8.8.8.8: icmp_seq=4 ttl=57 time=15.369 ms 64 bytes from 8.8.8.8: icmp_seq=5 ttl=57 time=17.851 ms ^C --- 8.8.8.8 ping statistics --- 6 packets transmitted, 6 packets received, 0% packet loss round-trip min/avg/max/stddev = 14.362/18.021/30.447/5.671 ms
Silky smooth but does the host, my laptop, actually have internet connectivity?
Michael@schumacher:/vsrx$ ping bbc.co.uk PING bbc.co.uk (151.101.128.81) 56(84) bytes of data. 64 bytes from 151.101.128.81 (151.101.128.81): icmp_seq=1 ttl=59 time=14.7 ms 64 bytes from 151.101.128.81 (151.101.128.81): icmp_seq=2 ttl=59 time=18.3 ms 64 bytes from 151.101.128.81 (151.101.128.81): icmp_seq=3 ttl=59 time=15.3 ms 64 bytes from 151.101.128.81 (151.101.128.81): icmp_seq=4 ttl=59 time=15.2 ms 64 bytes from 151.101.128.81 (151.101.128.81): icmp_seq=5 ttl=59 time=15.4 ms ^C --- bbc.co.uk ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4002ms rtt min/avg/max/mdev = 14.743/15.812/18.377/1.307 ms Michael@schumacher:/vsrx$ route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface default _gateway 0.0.0.0 UG 0 0 0 tap0 10.88.88.0 0.0.0.0 255.255.255.0 U 0 0 0 tap0 link-local 0.0.0.0 255.255.0.0 U 1000 0 0 virbr0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0 192.168.123.0 0.0.0.0 255.255.255.0 U 0 0 0 green_net 192.168.124.0 0.0.0.0 255.255.255.0 U 0 0 0 red_net root@vSRX> show security flow session | match icmp In: 10.88.88.111/2 --> 151.101.128.81/13698;icmp, If: ge-0/0/2.0, Pkts: 1, Bytes: 84 Out: 151.101.128.81/13698 --> 10.14.41.109/29492;icmp, If: ge-0/0/1.0, Pkts: 1, Bytes: 84 In: 10.88.88.111/3 --> 151.101.128.81/13698;icmp, If: ge-0/0/2.0, Pkts: 1, Bytes: 84 Out: 151.101.128.81/13698 --> 10.14.41.109/22708;icmp, If: ge-0/0/1.0, Pkts: 1, Bytes: 84
Job done!
If you prefer, you could manage the firewall from the web interface, jweb, too:
Login with root / Juniper:
Problems? Just 'vagrant destroy' and start again. Other things to consider? Do you really need to keep UFW running? :)