Skip to content

Latest commit

 

History

History
232 lines (201 loc) · 9.84 KB

README.md

File metadata and controls

232 lines (201 loc) · 9.84 KB

Mikrotik RouterOS boxes for Vagrant

Box URLs

Status

⚠️beta - The boxes are fully functional, but this project is work-in-progress: breaking changes may be introduced at any time.

Plugin

The boxes require vagrant-routeros plugin, which is bundled with box file and installed/updated automatically. The plugin is not stable enough to be published on rubygems.org, that's why it is bundled. Eventually it shoud be moved to a separate repository and published separately.

⚠️ Important note: to fix the error "Unable to resolve dependency: user requested 'vagrant-routeros (= x.x.x)'" after Vagrant update, just remove the plugin with the following command:

vagrant plugin uninstall vagrant-routeros

The plugin will reinstall itself automatically when needed.

Providers

Currently only VirtualBox provider is available.

Security

By default the boxes have no firewall rules configured and come with two user accounts:

  • admin with vagrant password
  • vagrant with password vagrant and Vagrant insecure private key authentication enabled

⚠️ This unsecure setup is intended for use in isolated testing environments. To secure a box you need at least change passwords for both users and the private SSH key for vagrant user. Disabling unused services and adding firewall rules is also recommended.
References:

Usage

vagrant init cheretbe/routeros
# or
vagrant init cheretbe/routeros-long-term
# or
vagrant init cheretbe/routeros7

vagrant up

vagrant-routeros plugin provides two additional provisioners: routeros_file, routeros_command and guest capability to change name.
routeros_file provisioner allows you to upload a file from the host machine to the guest machine.
routeros_command allows you to execute a RouterOS command within the guest machine.

Vagrantfile example that uses this functionality

Vagrant.configure("2") do |config|
  config.vm.box = "cheretbe/routeros"
  
  # Change guest name
  config.vm.hostname = "new-name"
  # Execute command
  config.vm.provision "routeros_command", name: "Command test", command: "/system resource print"
  # Upload and execute a script file
  config.vm.provision "routeros_file", name: "Upload test", source: "custom_script.rsc", destination: "custom_script.rsc"
  config.vm.provision "routeros_command", name: "Exec custom script",
    command: "/import custom_script.rsc", check_script_error: true
end

Accessing the VM from host

  1. Interactive SSH session
    • Use vagrant ssh command
  2. Built-in web interface (WebFig)
    • Find out VM's IP using vagrant ssh -- /ip address print where interface=host_only command
    • Note the returned IP and access it from your browser
    • For example if the command has returned 172.28.128.3/24, use http://172.28.128.3 as the address
  3. Winbox (works fine on Linux using Wine)
    • Download winbox.exe or winbox64.exe from https://mikrotik.com/download and launch it
    • Option 1 - access by IP address
      • Find out VM's IP using vagrant ssh -- /ip address print where interface=host_only command
      • Enter the address in "Connect to" field
    • Option 2 - access using neighbor discovery
      • Select Neighbors tab in Winbox connect dialog
      • Find the VM by it's name and click on IP or MAC address column to connect to it. If you click on IP address then IP will be used to connect, but if you click on MAC Address then MAC address will be used to connect to the VM
  4. Run commands during provision stage
    • Use routeros_file/routeros_command provisioners in the Vagrantfile

Network configuration

By default two network interfaces are configured in the VM: NAT (Vagrant's default) and Host-only, named host_nat and host_only respectively. Both interfaces configured as DHCP clients, but they do not receive default route and DNS server. This is done to isolate virtual environments from host's physical networks.
If you need Internet access in the VM you can configure host_nat adapter using the following RouterOS command:

/ip dhcp-client set [find interface="host_nat"] use-peer-dns=yes add-default-route=yes

Currently guest capability "Configure networks" is not implemented. Therefore you can't configure static IP or DHCP for additional network interfaces like this:

- (won't work) config.vm.network "private_network", type: "dhcp", virtualbox__intnet: "vagrant-intnet-1"
- (won't work) config.vm.network "private_network", ip: "172.24.0.1", virtualbox__intnet: "vagrant-intnet-2"

Instead you need to disable auto-config in Vagrantfile:

config.vm.network "private_network", virtualbox__intnet: "vagrant-intnet-1", auto_config: false
config.vm.network "private_network", virtualbox__intnet: "vagrant-intnet-2", auto_config: false

And then configure network addresses using RouterOS command:

/ip dhcp-client add disabled=no interface=ether3
/ip address add address=172.24.0.1/24 interface=ether4 network=172.24.0.0

Interface order in the VM does not always match interface order in the Vagrant file. To work around this issue the boxes contain a script file named vagrant_provision_mac_addr.rsc, that sets two global variables: vmNICCount and vmNICMACs. vmNICCount is used internally during provision, but you can use vmNICMACs to reference interface by index like this:

/import vagrant_provision_mac_addr.rsc
:global vmNICMACs
# vmNICMACs array is zero-based
:local eth3MACaddr [:pick $vmNICMACs 2]
:local eth3name [/interface ethernet get [find mac-address="$eth3MACaddr"] name]
/ip address add address=172.24.0.1/24 interface=$eth3name network=172.24.0.0

💡 You can automate RouterOS commands execution by using vagrant ssh -- <RouterOS command> command or routeros_file/ routeros_command provisioners.

Building the boxes

Option 1. Use pyinvoke script.

inv build
# Batch mode, no prompts
inv build --batch

The script needs Python3 installed and uses additional packages. They can be installed using pip (setting up a virtual environment is strongly recommended - see Step 2 here for details)

pip3 install -r requirements.txt

Go to https://www.vagrantup.com/ and manually publish build/boxes/routeros*.box files or use vagrant_box_publish.py script

# Interactive mode
vagrant-box-publish --version-separator - --dry-run
# Batch mode
vagrant-box-publish --box-file build/boxes/routeros_6.48.1.box --version-separator - --batch --dry-run

Option 2. Manual build.

  1. Build vagrant-routeros plugin
cd tools/vagrant-plugin-builder
vagrant up && vagrant ssh
cd /mnt/packer-mikrotik/vagrant-plugins-routeros/
bundle install && bundle exec rake build
logout
cd ../..
  1. Get current RouterOS version
# Version 6 stable branch
ros_version=$(curl -s http://upgrade.mikrotik.com/routeros/LATEST.6 | cut -d' ' -f1)
# Version 6 long-term branch
ros_version=$(curl -s http://upgrade.mikrotik.com/routeros/LATEST.6fix | cut -d' ' -f1)
# Version 7 stable branch
ros_version=$(curl -s http://upgrade.mikrotik.com/routeros/NEWEST7.stable | cut -d' ' -f1)

echo ${ros_version}
  1. Build the box
rm packer_cache -rf; packer build -var ros_ver=${ros_version} \
  -var-file vagrant-plugins-routeros/vagrant_routeros_plugin_version.json \
  -on-error=ask -force routeros.json
  1. Go to https://www.vagrantup.com/ and manually publish build/boxes/routeros.box

Windows

powershell '[System.Text.Encoding]::ASCII.GetString((Invoke-WebRequest "http://download2.mikrotik.com/routeros/LATEST.6").Content)'
rmdir /s /q packer_cache && packer build -var "ros_ver=6.44.2" -var-file vagrant-plugins-routeros/vagrant_routeros_plugin_version.json -on-error=ask -force routeros.json

Notes

vagrant box add -f mt-test ./build/boxes/routeros.box
Vagrant.configure("2") do |config|
  config.vm.box = "cheretbe/routeros7"
  # config.vm.box = "cheretbe/routeros"
  # config.vm.box = "cheretbe/routeros-long-term"
  # config.vm.box = "mt-test"
  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--groups", "/__vagrant"]
  end
end

~/.vagrant.d/boxes/mt-test/0/virtualbox/Vagrantfile:

# ln -s /home/user/projects/packer-mikrotik/vagrantfile-mikrotik.template template.rb
require (File.dirname(__FILE__) + "/template")
vagrant cloud box show cheretbe/routeros
curl -sS https://app.vagrantup.com/api/v1/box/cheretbe/routeros | jq -r ".current_version.version"