diff --git a/Vagrant/Vagrantfile b/Vagrant/Vagrantfile index 31273f5..c5712f0 100644 --- a/Vagrant/Vagrantfile +++ b/Vagrant/Vagrantfile @@ -26,7 +26,7 @@ Vagrant.configure("2") do |config| end config.vm.define "dc" do |cfg| - cfg.vm.box = "../Boxes/windows_2016_virtualbox.box" + cfg.vm.box = "detectionlab/win2016" cfg.vm.hostname = "dc" cfg.vm.boot_timeout = 600 # use the plaintext WinRM transport and force it to use basic authentication. @@ -63,7 +63,6 @@ Vagrant.configure("2") do |config| cfg.vm.provision "shell", inline: "Set-SmbServerConfiguration -AuditSmb1Access $true -Force", privileged: false cfg.vm.provider "vmware_desktop" do |v, override| - override.vm.box = "../Boxes/windows_2016_vmware.box" v.vmx["displayname"] = "dc.windomain.local" v.memory = 2560 v.cpus = 2 @@ -84,7 +83,7 @@ Vagrant.configure("2") do |config| end config.vm.define "wef" do |cfg| - cfg.vm.box = "../Boxes/windows_2016_virtualbox.box" + cfg.vm.box = "detectionlab/win2016" cfg.vm.hostname = "wef" cfg.vm.boot_timeout = 600 cfg.vm.communicator = "winrm" @@ -116,7 +115,6 @@ Vagrant.configure("2") do |config| cfg.vm.provision "shell", path: "scripts/install-microsoft-ata.ps1", privileged: false cfg.vm.provider "vmware_desktop" do |v, override| - override.vm.box = "../Boxes/windows_2016_vmware.box" v.vmx["displayname"] = "wef.windomain.local" v.memory = 2048 v.cpus = 2 @@ -137,7 +135,7 @@ Vagrant.configure("2") do |config| end config.vm.define "win10" do |cfg| - cfg.vm.box = "../Boxes/windows_10_virtualbox.box" + cfg.vm.box = "detectionlab/win10" cfg.vm.hostname = "win10" cfg.vm.boot_timeout = 600 cfg.vm.communicator = "winrm" @@ -165,7 +163,6 @@ Vagrant.configure("2") do |config| cfg.vm.provision "shell", path: "scripts/install-autorunstowineventlog.ps1", privileged: false cfg.vm.provider "vmware_desktop" do |v, override| - override.vm.box = "../Boxes/windows_10_vmware.box" v.vmx["displayname"] = "win10.windomain.local" v.vmx["gui.fullscreenatpoweron"] = "FALSE" v.vmx["gui.viewModeAtPowerOn"] = "windowed" diff --git a/Vagrant/bootstrap.sh b/Vagrant/bootstrap.sh index 622c958..4d0f977 100644 --- a/Vagrant/bootstrap.sh +++ b/Vagrant/bootstrap.sh @@ -19,13 +19,55 @@ install_python_apt_source() { apt_install_prerequisites() { # Install prerequisites and useful tools - apt-get update - apt-get install -y apt-fast - apt-fast install -y jq whois build-essential git docker docker-compose unzip mongodb-org python3.6 python3.6-dev + echo "Running apt-get update..." + apt-get -qq update + apt-get -qq install -y apt-fast + echo "Running apt-fast install..." + apt-fast -qq install -y jq whois build-essential git docker docker-compose unzip mongodb-org python3.6 python3.6-dev # Install pip for Python 3.6 + echo "Installing Pip3.6..." curl https://bootstrap.pypa.io/get-pip.py | sudo -H python3.6 } +test_prerequisites() { + for package in jq whois build-essential git docker docker-compose unzip mongodb-org python3.6 python3.6-dev + do + echo "[TEST] Validating that $package is correctly installed..." + # Loop through each package using dpkg + if ! dpkg -S $package > /dev/null; then + # If which returns a non-zero return code, try to re-install the package + echo "[-] $package was not found. Attempting to reinstall." + apt-get -qq update && apt-get install -y $package + if ! which $package > /dev/null; then + # If the reinstall fails, give up + echo "[X] Unable to install $package even after a retry. Exiting." + exit 1 + fi + else + echo "[+] $package was successfully installed!" + fi + done + + # One-off support for packages which aren't installed via dpkg + for package in "pip3.6" + do + echo "[TEST] Validating that $package is correctly installed..." + # Loop through each package using which + if ! which $package > /dev/null; then + # If which returns a non-zero return code, try to re-install the package + echo "[-] $package was not found. Attempting to reinstall." + curl https://bootstrap.pypa.io/get-pip.py | sudo -H python3.6 + if ! which $package > /dev/null; then + # If the reinstall fails, give up + echo "[X] Unable to install $package even after a retry. Exiting." + exit 1 + fi + else + echo "[+] $package was successfully installed!" + fi + done +} + fix_eth1_static_ip() { # There's a fun issue where dhclient keeps messing with eth1 despite the fact # that eth1 has a static IP set. We workaround this by setting a static DHCP lease. @@ -55,7 +97,7 @@ install_golang() { if ! which go > /dev/null; then echo "Installing Golang v.1.12..." cd /home/vagrant || exit - wget https://dl.google.com/go/go1.12.linux-amd64.tar.gz + wget --progress=bar:force https://dl.google.com/go/go1.12.linux-amd64.tar.gz tar -C /usr/local -xzf go1.12.linux-amd64.tar.gz mkdir /root/go else @@ -124,6 +166,7 @@ install_fleet() { else echo "Installing Fleet..." echo -e "\n127.0.0.1 kolide" >> /etc/hosts + echo -e "\n127.0.0.1 logger" >> /etc/hosts git clone https://github.com/kolide/kolide-quickstart.git cd kolide-quickstart || echo "Something went wrong while trying to clone the kolide-quickstart repository" cp /vagrant/resources/fleet/server.* . @@ -149,7 +192,7 @@ download_palantir_osquery_config() { } import_osquery_config_into_fleet() { - wget https://github.com/kolide/fleet/releases/download/2.0.1/fleet_2.0.1.zip + wget --progress=bar:force https://github.com/kolide/fleet/releases/download/2.0.1/fleet_2.0.1.zip unzip fleet_2.0.1.zip -d fleet_2.0.1 cp fleet_2.0.1/linux/fleetctl /usr/local/bin/fleetctl && chmod +x /usr/local/bin/fleetctl fleetctl config set --address https://192.168.38.105:8412 @@ -192,8 +235,8 @@ install_caldera() { systemctl enable mongod.service cd /home/vagrant/caldera || exit mkdir -p dep/crater/crater - wget https://github.com/mitre/caldera-crater/releases/download/v0.1.0/CraterMainWin8up.exe -O /home/vagrant/caldera/dep/crater/crater/CraterMain.exe - cp /vagrant/resources/caldera/cert.pem /vagrant/resources/caldera/key.pem /vagrant/resources/caldera/settings.yml /home/vagrant/caldera/caldera/conf + wget --progress=bar:force https://github.com/mitre/caldera-crater/releases/download/v0.1.0/CraterMainWin8up.exe -O /home/vagrant/caldera/dep/crater/crater/CraterMain.exe + cp /vagrant/resources/caldera/cert.pem /vagrant/resources/caldera/key.pem /vagrant/resources/caldera/settings.yml /home/vagrant/caldera/caldera/conf service caldera start systemctl enable caldera.service fi @@ -283,17 +326,19 @@ install_suricata() { # Run iwr -Uri testmyids.com -UserAgent "BlackSun" in Powershell to generate test alerts # Install yq to maniuplate the suricata.yaml inline - /usr/local/go/bin/go get -u github.com/mikefarah/yq + /usr/local/go/bin/go get -u github.com/mikefarah/yq + # Install suricata add-apt-repository -y ppa:oisf/suricata-stable apt-get -qq -y update && apt-get -qq -y install suricata crudini + test_suricata_prerequisites # Install suricata-update cd /home/vagrant || exit 1 git clone https://github.com/OISF/suricata-update.git cd /home/vagrant/suricata-update || exit 1 python setup.py install # Add DC_SERVERS variable to suricata.yaml in support et-open signatures - /root/go/bin/yq w -i /etc/suricata/suricata.yaml vars.address-groups.DC_SERVERS '$HOME_NET' + /root/go/bin/yq w -i /etc/suricata/suricata.yaml vars.address-groups.DC_SERVERS '$HOME_NET' # It may make sense to store the suricata.yaml file as a resource file if this begins to become too complex # Add more verbose alert logging @@ -341,10 +386,47 @@ install_suricata() { fi } +test_suricata_prerequisites() { + for package in suricata crudini + do + echo "[TEST] Validating that $package is correctly installed..." + # Loop through each package using dpkg + if ! dpkg -S $package > /dev/null; then + # If which returns a non-zero return code, try to re-install the package + echo "[-] $package was not found. Attempting to reinstall." + apt-get -qq update && apt-get install -y $package + if ! which $package > /dev/null; then + # If the reinstall fails, give up + echo "[X] Unable to install $package even after a retry. Exiting." + exit 1 + fi + else + echo "[+] $package was successfully installed!" + fi + done + + # One-off support for packages which aren't installed via dpkg + echo "[TEST] Validating that yq is correctly installed..." + # Loop through each package using which + if ! [ -f /root/go/bin/yq ]; then + # If which returns a non-zero return code, try to re-install the package + echo "[-] yq was not found. Attempting to reinstall." + /usr/local/go/bin/go get -u github.com/mikefarah/yq + if ! [ -f /root/go/bin/yq ]; then + # If the reinstall fails, give up + echo "[X] Unable to install yq even after a retry. Exiting." + exit 1 + fi + else + echo "[+] yq was successfully installed!" + fi +} + main() { install_mongo_db_apt_key install_python_apt_source apt_install_prerequisites + test_prerequisites fix_eth1_static_ip install_golang install_splunk diff --git a/build.ps1 b/build.ps1 index b7f3e67..3add422 100644 --- a/build.ps1 +++ b/build.ps1 @@ -26,7 +26,7 @@ The full path to the packer executable. Default is C:\Hashicorp\packer.exe .PARAMETER VagrantOnly - This switch skips building packer boxes and instead downloads from www.detectionlab.network + This switch skips building packer boxes and instead downloads from Vagrant Cloud .EXAMPLE build.ps1 -ProviderName virtualbox @@ -54,14 +54,6 @@ Param( $DL_DIR = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition $LAB_HOSTS = ('logger', 'dc', 'wef', 'win10') -# Register-EngineEvent PowerShell.Exiting -SupportEvent -Action { -# Set-Location $DL_DIR -# } - -# Register-ObjectEvent -InputObject ([System.Console]) -EventName CancelKeyPress -Action { -# Set-Location $DL_DIR -# } - function install_checker { param( [string]$Name @@ -177,55 +169,6 @@ function list_providers { return $ProviderName } -function download_boxes { - Write-Host '[download_boxes] Running..' - if ($PackerProvider -eq 'virtualbox') { - $win10Hash = 'c03f10f21b8d79e6acca2b2965b23046' - $win2016Hash = '231b54077d4396cad01e4cd60651b1e0' - } - if ($PackerProvider -eq 'vmware') { - $win10Hash = 'b334c3ba5be3b29840567ffe368db5fe' - $win2016Hash = '2bbaf5a1177e0499dc3aacdb0246eb38' - } - - $win10Filename = "windows_10_$PackerProvider.box" - $win2016Filename = "windows_2016_$PackerProvider.box" - - $wc = New-Object System.Net.WebClient - Write-Host "[download_boxes] Downloading $win10Filename" - $wc.DownloadFile("https://www.detectionlab.network/$win10Filename", "$DL_DIR\Boxes\$win10Filename") - Write-Host "[download_boxes] Downloading $win2016Filename" - $wc.DownloadFile("https://www.detectionlab.network/$win2016Filename", "$DL_DIR\Boxes\$win2016Filename") - $wc.Dispose() - - if (-Not (Test-Path "$DL_DIR\Boxes\$win2016Filename")) { - Write-Error 'Windows 2016 box is missing from the Boxes directory. Qutting.' - break - } - if (-Not (Test-Path "$DL_DIR\Boxes\$win10Filename")) { - Write-Error 'Windows 10 box is missing from the Boxes directory. Qutting.' - break - } - - Write-Host "[download_boxes] Getting filehash for: $win10Filename" - $win10Filehash = (Get-FileHash -Path "$DL_DIR\Boxes\$win10Filename" -Algorithm MD5).Hash - Write-Host "[download_boxes] Getting filehash for: $win2016Filename" - $win2016Filehash = (Get-FileHash -Path "$DL_DIR\Boxes\$win2016Filename" -Algorithm MD5).Hash - - Write-Host '[download_boxes] Checking Filehashes..' - if ($win10hash -ne $win10Filehash) { - Write-Error 'Hash mismatch on windows_10_virtualbox.box' - Write-Error 'The boxes may have been updated since you last ran the build script. Try updating the git repository to retrieve the latest hashes.' - break - } - if ($win2016hash -ne $win2016Filehash) { - Write-Error 'Hash mismatch on windows_2016_virtualbox.box' - Write-Error 'The boxes may have been updated since you last ran the build script. Try updating the git repository to retrieve the latest hashes.' - break - } - Write-Host '[download_boxes] Finished.' -} - function preflight_checks { Write-Host '[preflight_checks] Running..' # Check to see that no boxes exist @@ -390,7 +333,6 @@ function download { Write-Host "Error occured on webrequest: $_" return $false } - } } @@ -412,7 +354,6 @@ function post_build_checks { $ATA_CHECK = download -URL 'https://192.168.38.103' -SuccessOn401 Write-Host "[post_build_checks] ATA Result: $ATA_CHECK" - if ($CALDERA_CHECK -eq $false) { Write-Warning 'Caldera failed post-build tests and may not be functioning correctly.' } @@ -427,7 +368,6 @@ function post_build_checks { } } - # If no ProviderName was provided, get a provider if ($ProviderName -eq $Null -or $ProviderName -eq "") { $ProviderName = list_providers @@ -441,15 +381,11 @@ else { $PackerProvider = 'virtualbox' } - # Run check functions preflight_checks # Build Packer Boxes -if ($VagrantOnly) { - download_boxes -} -else { +if ! ($VagrantOnly) { packer_build_box -Box 'windows_2016' packer_build_box -Box 'windows_10' # Move Packer Boxes @@ -477,7 +413,6 @@ forEach ($VAGRANT_HOST in $LAB_HOSTS) { Write-Host "[main] Finished for: $VAGRANT_HOST" } - Write-Host "[main] Running post_build_checks" post_build_checks Write-Host "[main] Finished post_build_checks" diff --git a/build.sh b/build.sh index c87905a..b892288 100755 --- a/build.sh +++ b/build.sh @@ -3,7 +3,7 @@ # This script is meant to be used with a fresh clone of DetectionLab and # will fail to run if boxes have already been created or any of the steps # from the README have already been run followed. -# Only MacOS and Linux are supported. +# Only MacOS and Linux are supported. Use build.ps1 for Windows. # If you encounter issues, feel free to open an issue at # https://github.com/clong/DetectionLab/issues @@ -48,6 +48,16 @@ check_virtualbox_installed() { fi } +# Returns 0 if not installed or 1 if installed +# Check for VMWare Workstation on Linux +check_vmware_workstation_installed() { + if which vmrun >/dev/null; then + echo "1" + else + echo "0" + fi +} + # Returns 0 if not installed or 1 if installed check_vmware_fusion_installed() { if [ -e "/Applications/VMware Fusion.app" ]; then @@ -68,16 +78,18 @@ check_vmware_desktop_vagrant_plugin_installed() { fi VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT="$(vagrant plugin list | grep -c 'vagrant-vmware-desktop')" if [ "$VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT" -eq 0 ]; then - (echo >&2 "VMWare Fusion is installed, but the vagrant-vmware-desktop plugin is not.") + (echo >&2 "VMWare Fusion or Workstation is installed, but the vagrant-vmware-desktop plugin is not.") (echo >&2 "If you are seeing this, you may have the deprecated vagrant-vmware-fusion plugin installed. Please remove it and install the vagrant-vmware-desktop plugin.") (echo >&2 "Visit https://www.hashicorp.com/blog/introducing-the-vagrant-vmware-desktop-plugin for more information on how to purchase and install it") - (echo >&2 "VMWare Fusion will not be listed as a provider until the vagrant-vmware-desktop plugin has been installed.") + (echo >&2 "VMWare Fusion or Workstation will not be listed as a provider until the vagrant-vmware-desktop plugin has been installed.") echo "0" else echo "$VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT" fi } + + # List the available Vagrant providers present on the system list_providers() { VBOX_PRESENT=0 @@ -87,10 +99,14 @@ list_providers() { # Detect Providers on OSX VBOX_PRESENT=$(check_virtualbox_installed) VMWARE_FUSION_PRESENT=$(check_vmware_fusion_installed) + VMWARE_WORKSTATION_PRESENT=0 # Workstation doesn't exists on Darwain-based OS VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT=$(check_vmware_desktop_vagrant_plugin_installed) else # Assume the only other available provider is VirtualBox VBOX_PRESENT=$(check_virtualbox_installed) + VMWARE_WORKSTATION_PRESENT=$(check_vmware_workstation_installed) + VMWARE_FUSION_PRESENT=0 # Fusion doesn't exist on non-Darwin OS + VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT=$(check_vmware_desktop_vagrant_plugin_installed) fi (echo >&2 "Available Providers:") @@ -100,7 +116,10 @@ list_providers() { if [[ $VMWARE_FUSION_PRESENT -eq 1 ]] && [[ $VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT -eq 1 ]]; then (echo >&2 "vmware_desktop") fi - if [[ $VBOX_PRESENT -eq 0 ]] && [[ $VMWARE_FUSION_PRESENT -eq 0 ]]; then + if [[ $VMWARE_WORKSTATION_PRESENT -eq 1 ]] && [[ $VAGRANT_VMWARE_DESKTOP_PLUGIN_PRESENT -eq 1 ]]; then + (echo >&2 "vmware_desktop") + fi + if [[ $VBOX_PRESENT -eq 0 ]] && [[ $VMWARE_FUSION_PRESENT -eq 0 ]] && [[ $VMWARE_WORKSTATION -eq 0 ]]; then (echo >&2 "You need to install a provider such as VirtualBox or VMware Fusion to continue.") exit 1 fi @@ -114,28 +133,6 @@ list_providers() { echo "$PROVIDER" } -# Check to see if boxes exist in the "Boxes" directory already -check_boxes_built() { - BOXES_BUILT=$(find "$DL_DIR"/Boxes -name "*.box" | wc -l) - if [ "$BOXES_BUILT" -gt 0 ]; then - if [ "$VAGRANT_ONLY" -eq 1 ]; then - (echo >&2 "WARNING: You seem to have at least one .box file present in $DL_DIR/Boxes already. If you would like fresh boxes downloaded, please remove all files from the Boxes directory and re-run this script.") - DOWNLOAD_BOXES=0 - else - (echo >&2 "You seem to have at least one .box file in $DL_DIR/Boxes. This script does not support pre-built boxes. Please either delete the existing boxes or follow the build steps in the README to continue.") - exit 1 - fi - fi -} - -# Check to ensure either "md5" or "md5sum" is installed for verifying integrity of downloaded boxes -check_md5_tool_exists() { - if ! which md5 > /dev/null && ! which md5sum > /dev/null; then - (echo >&2 "md5 or md5sum not found in PATH. Please install at least one of these utilities to continue.") - exit 1 - fi -} - # Check to see if any Vagrant instances exist already check_vagrant_instances_exist() { cd "$DL_DIR"/Vagrant/ || exit 1 @@ -163,7 +160,7 @@ check_vagrant_reload_plugin() { check_disk_free_space() { FREE_DISK_SPACE=$(df -m "$HOME" | tr -s ' ' | grep '/' | cut -d ' ' -f 4) if [ "$FREE_DISK_SPACE" -lt 80000 ]; then - (echo >&2 -e "Warning: You appear to have less than 80GB of HDD space free on your primary partition. If you are using a separate parition, you may ignore this warning.\\n") + (echo >&2 -e "Warning: You appear to have less than 80GB of HDD space free on your primary partition. If you are using a separate parition, you may ignore this warning.\n") (df >&2 -m "$HOME") (echo >&2 "") fi @@ -191,10 +188,6 @@ preflight_checks() { if [ "$VAGRANT_ONLY" -eq 0 ]; then check_packer_path check_packer_known_bad - else - # If it is a Vagrant-only build, set appropriate checks - DOWNLOAD_BOXES=1 - check_md5_tool_exists fi # If it's not a Packer-only build, then run Vagrant-related checks @@ -368,62 +361,6 @@ done fi } -choose_md5_tool() { - if which md5; then - MD5TOOL="$(which md5)" - CUT_INDEX=4 - else - MD5TOOL="$(which md5sum)" - CUT_INDEX=1 - fi -} - -# Downloads pre-built Packer boxes from detectionlab.network to save time during CI builds -download_boxes() { - choose_md5_tool - if [ "$PROVIDER" == "virtualbox" ]; then - wget "https://www.detectionlab.network/windows_2016_virtualbox.box" -O "$DL_DIR"/Boxes/windows_2016_virtualbox.box - wget "https://www.detectionlab.network/windows_10_virtualbox.box" -O "$DL_DIR"/Boxes/windows_10_virtualbox.box - elif [ "$PROVIDER" == "vmware_desktop" ]; then - wget "https://www.detectionlab.network/windows_2016_vmware.box" -O "$DL_DIR"/Boxes/windows_2016_vmware.box - wget "https://www.detectionlab.network/windows_10_vmware.box" -O "$DL_DIR"/Boxes/windows_10_vmware.box - fi - - # Ensure Windows 10 box exists - if [ ! -f "$DL_DIR"/Boxes/windows_10_"$PACKER_PROVIDER".box ]; then - (echo >&2 "Windows 10 box is missing from the Boxes directory. Qutting.") - exit 1 - fi - # Ensure Windows 2016 box exists - if [ ! -f "$DL_DIR"/Boxes/windows_2016_"$PACKER_PROVIDER".box ]; then - (echo >&2 "Windows 2016 box is missing from the Boxes directory. Qutting.") - exit 1 - fi - # Verify hashes of VirtualBox boxes - if [ "$PACKER_PROVIDER" == "virtualbox" ]; then - if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_10_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "c03f10f21b8d79e6acca2b2965b23046" ]; then - (echo >&2 "Hash mismatch on windows_10_virtualbox.box") - (echo >&2 "The boxes may have been updated since you last ran the build script. Try updating the git repository to retrieve the latest hashes.") - fi - if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_2016_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "231b54077d4396cad01e4cd60651b1e0" ]; then - (echo >&2 "Hash mismatch on windows_2016_virtualbox.box") - (echo >&2 "The boxes may have been updated since you last ran the build script. Try updating the git repository to retrieve the latest hashes.") - fi - # Verify hashes of VMware boxes - elif [ "$PACKER_PROVIDER" == "vmware" ]; then - if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_10_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "b334c3ba5be3b29840567ffe368db5fe" ]; then - (echo >&2 "Hash mismatch on windows_10_vmware.box") - (echo >&2 "The boxes may have been updated since you last ran the build script. Try updating the git repository to retrieve the latest hashes.") - exit 1 - fi - if [ "$("$MD5TOOL" "$DL_DIR"/Boxes/windows_2016_"$PACKER_PROVIDER".box | cut -d ' ' -f "$CUT_INDEX")" != "2bbaf5a1177e0499dc3aacdb0246eb38" ]; then - (echo >&2 "Hash mismatch on windows_2016_vmware.box") - (echo >&2 "The boxes may have been updated since you last ran the build script. Try updating the git repository to retrieve the latest hashes.") - exit 1 - fi - fi -} - build_vagrant_hosts() { LAB_HOSTS=("logger" "dc" "wef" "win10") @@ -457,9 +394,6 @@ main() { parse_cli_arguments "$@" preflight_checks - if [[ "$DOWNLOAD_BOXES" -eq 1 ]] && [[ "$VAGRANT_ONLY" -eq 1 ]]; then - download_boxes - fi # Build Packer boxes if this isn't a Vagrant-only build if [ "$VAGRANT_ONLY" -eq 0 ]; then