Adding final ESXI deployment code
This commit is contained in:
6
ESXi/Packer/_common/metadata.sh
Executable file
6
ESXi/Packer/_common/metadata.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
mkdir -p /etc;
|
||||
cp /tmp/bento-metadata.json /etc/bento-metadata.json;
|
||||
chmod 0444 /etc/bento-metadata.json;
|
||||
rm -f /tmp/bento-metadata.json;
|
||||
36
ESXi/Packer/_common/minimize.sh
Normal file
36
ESXi/Packer/_common/minimize.sh
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
case "$PACKER_BUILDER_TYPE" in
|
||||
qemu) exit 0 ;;
|
||||
esac
|
||||
|
||||
# Whiteout root
|
||||
count=$(df --sync -kP / | tail -n1 | awk -F ' ' '{print $4}')
|
||||
count=$(($count-1))
|
||||
dd if=/dev/zero of=/tmp/whitespace bs=1M count=$count || echo "dd exit code $? is suppressed";
|
||||
rm /tmp/whitespace
|
||||
|
||||
# Whiteout /boot
|
||||
count=$(df --sync -kP /boot | tail -n1 | awk -F ' ' '{print $4}')
|
||||
count=$(($count-1))
|
||||
dd if=/dev/zero of=/boot/whitespace bs=1M count=$count || echo "dd exit code $? is suppressed";
|
||||
rm /boot/whitespace
|
||||
|
||||
set +e
|
||||
swapuuid="`/sbin/blkid -o value -l -s UUID -t TYPE=swap`";
|
||||
case "$?" in
|
||||
2|0) ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
set -e
|
||||
|
||||
if [ "x${swapuuid}" != "x" ]; then
|
||||
# Whiteout the swap partition to reduce box size
|
||||
# Swap is disabled till reboot
|
||||
swappart="`readlink -f /dev/disk/by-uuid/$swapuuid`";
|
||||
/sbin/swapoff "$swappart";
|
||||
dd if=/dev/zero of="$swappart" bs=1M || echo "dd exit code $? is suppressed";
|
||||
/sbin/mkswap -U "$swapuuid" "$swappart";
|
||||
fi
|
||||
|
||||
sync;
|
||||
21
ESXi/Packer/_common/motd.sh
Normal file
21
ESXi/Packer/_common/motd.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
bento='
|
||||
This system is built by the Bento project by Chef Software
|
||||
More information can be found at https://github.com/chef/bento'
|
||||
|
||||
if [ -d /etc/update-motd.d ]; then
|
||||
MOTD_CONFIG='/etc/update-motd.d/99-bento'
|
||||
|
||||
cat >> "$MOTD_CONFIG" <<BENTO
|
||||
#!/bin/sh
|
||||
|
||||
cat <<'EOF'
|
||||
$bento
|
||||
EOF
|
||||
BENTO
|
||||
|
||||
chmod 0755 "$MOTD_CONFIG"
|
||||
else
|
||||
echo "$bento" >> /etc/motd
|
||||
fi
|
||||
20
ESXi/Packer/_common/sshd.sh
Normal file
20
ESXi/Packer/_common/sshd.sh
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
SSHD_CONFIG="/etc/ssh/sshd_config"
|
||||
|
||||
# ensure that there is a trailing newline before attempting to concatenate
|
||||
sed -i -e '$a\' "$SSHD_CONFIG"
|
||||
|
||||
USEDNS="UseDNS no"
|
||||
if grep -q -E "^[[:space:]]*UseDNS" "$SSHD_CONFIG"; then
|
||||
sed -i "s/^\s*UseDNS.*/${USEDNS}/" "$SSHD_CONFIG"
|
||||
else
|
||||
echo "$USEDNS" >>"$SSHD_CONFIG"
|
||||
fi
|
||||
|
||||
GSSAPI="GSSAPIAuthentication no"
|
||||
if grep -q -E "^[[:space:]]*GSSAPIAuthentication" "$SSHD_CONFIG"; then
|
||||
sed -i "s/^\s*GSSAPIAuthentication.*/${GSSAPI}/" "$SSHD_CONFIG"
|
||||
else
|
||||
echo "$GSSAPI" >>"$SSHD_CONFIG"
|
||||
fi
|
||||
19
ESXi/Packer/_common/vagrant.sh
Normal file
19
ESXi/Packer/_common/vagrant.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
# set a default HOME_DIR environment variable if not set
|
||||
HOME_DIR="${HOME_DIR:-/home/vagrant}";
|
||||
|
||||
pubkey_url="https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub";
|
||||
mkdir -p $HOME_DIR/.ssh;
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
wget --no-check-certificate "$pubkey_url" -O $HOME_DIR/.ssh/authorized_keys;
|
||||
elif command -v curl >/dev/null 2>&1; then
|
||||
curl --insecure --location "$pubkey_url" > $HOME_DIR/.ssh/authorized_keys;
|
||||
elif command -v fetch >/dev/null 2>&1; then
|
||||
fetch -am -o $HOME_DIR/.ssh/authorized_keys "$pubkey_url";
|
||||
else
|
||||
echo "Cannot download vagrant public key";
|
||||
exit 1;
|
||||
fi
|
||||
chown -R vagrant $HOME_DIR/.ssh;
|
||||
chmod -R go-rwsx $HOME_DIR/.ssh;
|
||||
34
ESXi/Packer/_common/vmware.sh
Normal file
34
ESXi/Packer/_common/vmware.sh
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
# set a default HOME_DIR environment variable if not set
|
||||
HOME_DIR="${HOME_DIR:-/home/vagrant}";
|
||||
|
||||
case "$PACKER_BUILDER_TYPE" in
|
||||
vmware-iso|vmware-vmx)
|
||||
|
||||
# make sure we have /sbin in our path. RHEL systems lack this
|
||||
PATH=/sbin:$PATH
|
||||
export PATH
|
||||
|
||||
mkdir -p /tmp/vmware;
|
||||
mkdir -p /tmp/vmware-archive;
|
||||
mount -o loop $HOME_DIR/linux.iso /tmp/vmware;
|
||||
|
||||
TOOLS_PATH="`ls /tmp/vmware/VMwareTools-*.tar.gz`";
|
||||
VER="`echo "${TOOLS_PATH}" | cut -f2 -d'-'`";
|
||||
MAJ_VER="`echo ${VER} | cut -d '.' -f 1`";
|
||||
|
||||
echo "VMware Tools Version: $VER";
|
||||
|
||||
tar xzf ${TOOLS_PATH} -C /tmp/vmware-archive;
|
||||
if [ "${MAJ_VER}" -lt "10" ]; then
|
||||
/tmp/vmware-archive/vmware-tools-distrib/vmware-install.pl --default;
|
||||
else
|
||||
/tmp/vmware-archive/vmware-tools-distrib/vmware-install.pl --force-install;
|
||||
fi
|
||||
umount /tmp/vmware;
|
||||
rm -rf /tmp/vmware;
|
||||
rm -rf /tmp/vmware-archive;
|
||||
rm -f $HOME_DIR/*.iso;
|
||||
;;
|
||||
esac
|
||||
35
ESXi/Packer/http/preseed.cfg
Normal file
35
ESXi/Packer/http/preseed.cfg
Normal file
@@ -0,0 +1,35 @@
|
||||
choose-mirror-bin mirror/http/proxy string
|
||||
d-i base-installer/kernel/override-image string linux-server
|
||||
d-i clock-setup/utc boolean true
|
||||
d-i clock-setup/utc-auto boolean true
|
||||
d-i finish-install/reboot_in_progress note
|
||||
d-i grub-installer/only_debian boolean true
|
||||
d-i grub-installer/with_other_os boolean true
|
||||
d-i mirror/country string manual
|
||||
d-i mirror/http/directory string /ubuntu/
|
||||
d-i mirror/http/hostname string archive.ubuntu.com
|
||||
d-i mirror/http/proxy string
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
d-i partman-auto/choose_recipe select atomic
|
||||
d-i partman-auto/method string lvm
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm_nooverwrite boolean true
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
d-i partman/choose_partition select finish
|
||||
d-i partman/confirm boolean true
|
||||
d-i partman/confirm_nooverwrite boolean true
|
||||
d-i partman/confirm_write_new_label boolean true
|
||||
d-i passwd/user-fullname string vagrant
|
||||
d-i passwd/user-uid string 1000
|
||||
d-i passwd/user-password password vagrant
|
||||
d-i passwd/user-password-again password vagrant
|
||||
d-i passwd/username string vagrant
|
||||
d-i pkgsel/include string openssh-server cryptsetup build-essential libssl-dev libreadline-dev zlib1g-dev linux-source dkms nfs-common linux-headers-$(uname -r) perl cifs-utils software-properties-common rsync ifupdown
|
||||
d-i pkgsel/install-language-support boolean false
|
||||
d-i pkgsel/update-policy select none
|
||||
d-i pkgsel/upgrade select full-upgrade
|
||||
d-i time/zone string UTC
|
||||
d-i user-setup/allow-password-weak boolean true
|
||||
d-i user-setup/encrypt-home boolean false
|
||||
tasksel tasksel/first multiselect standard, server
|
||||
81
ESXi/Packer/scripts/cleanup.sh
Normal file
81
ESXi/Packer/scripts/cleanup.sh
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
# Delete all Linux headers
|
||||
dpkg --list \
|
||||
| awk '{ print $2 }' \
|
||||
| grep 'linux-headers' \
|
||||
| xargs apt-get -y purge;
|
||||
|
||||
# Remove specific Linux kernels, such as linux-image-3.11.0-15-generic but
|
||||
# keeps the current kernel and does not touch the virtual packages,
|
||||
# e.g. 'linux-image-generic', etc.
|
||||
dpkg --list \
|
||||
| awk '{ print $2 }' \
|
||||
| grep 'linux-image-.*-generic' \
|
||||
| grep -v `uname -r` \
|
||||
| xargs apt-get -y purge;
|
||||
|
||||
# Delete Linux source
|
||||
dpkg --list \
|
||||
| awk '{ print $2 }' \
|
||||
| grep linux-source \
|
||||
| xargs apt-get -y purge;
|
||||
|
||||
# Delete development packages
|
||||
dpkg --list \
|
||||
| awk '{ print $2 }' \
|
||||
| grep -- '-dev$' \
|
||||
| xargs apt-get -y purge;
|
||||
|
||||
# delete docs packages
|
||||
dpkg --list \
|
||||
| awk '{ print $2 }' \
|
||||
| grep -- '-doc$' \
|
||||
| xargs apt-get -y purge;
|
||||
|
||||
# Delete X11 libraries
|
||||
apt-get -y purge libx11-data xauth libxmuu1 libxcb1 libx11-6 libxext6;
|
||||
|
||||
# Delete obsolete networking
|
||||
apt-get -y purge ppp pppconfig pppoeconf;
|
||||
|
||||
# Delete oddities
|
||||
apt-get -y purge popularity-contest installation-report command-not-found friendly-recovery bash-completion fonts-ubuntu-font-family-console laptop-detect;
|
||||
|
||||
# 19.10+ don't have this package so fail gracefully
|
||||
apt-get -y purge command-not-found-data || true;
|
||||
|
||||
# Exlude the files we don't need w/o uninstalling linux-firmware
|
||||
echo "==> Setup dpkg excludes for linux-firmware"
|
||||
cat <<_EOF_ | cat >> /etc/dpkg/dpkg.cfg.d/excludes
|
||||
#BENTO-BEGIN
|
||||
path-exclude=/lib/firmware/*
|
||||
path-exclude=/usr/share/doc/linux-firmware/*
|
||||
#BENTO-END
|
||||
_EOF_
|
||||
|
||||
# Delete the massive firmware packages
|
||||
rm -rf /lib/firmware/*
|
||||
rm -rf /usr/share/doc/linux-firmware/*
|
||||
|
||||
apt-get -y autoremove;
|
||||
apt-get -y clean;
|
||||
|
||||
# Remove docs
|
||||
rm -rf /usr/share/doc/*
|
||||
|
||||
# Remove caches
|
||||
find /var/cache -type f -exec rm -rf {} \;
|
||||
|
||||
# truncate any logs that have built up during the install
|
||||
find /var/log -type f -exec truncate --size=0 {} \;
|
||||
|
||||
# Blank netplan machine-id (DUID) so machines get unique ID generated on boot.
|
||||
truncate -s 0 /etc/machine-id
|
||||
|
||||
# remove the contents of /tmp and /var/tmp
|
||||
rm -rf /tmp/* /var/tmp/*
|
||||
|
||||
# clear the history so our install isn't there
|
||||
export HISTSIZE=0
|
||||
rm -f /root/.wget-hsts
|
||||
25
ESXi/Packer/scripts/networking.sh
Normal file
25
ESXi/Packer/scripts/networking.sh
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
ubuntu_version="`lsb_release -r | awk '{print $2}'`";
|
||||
major_version="`echo $ubuntu_version | awk -F. '{print $1}'`";
|
||||
|
||||
if [ "$major_version" -ge "18" ]; then
|
||||
echo "Create netplan config for eth0"
|
||||
cat <<EOF >/etc/netplan/01-netcfg.yaml;
|
||||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
eth0:
|
||||
dhcp4: true
|
||||
EOF
|
||||
else
|
||||
# Adding a 2 sec delay to the interface up, to make the dhclient happy
|
||||
echo "pre-up sleep 2" >> /etc/network/interfaces;
|
||||
fi
|
||||
|
||||
if [ "$major_version" -ge "16" ]; then
|
||||
# Disable Predictable Network Interface names and use eth0
|
||||
sed -i 's/en[[:alnum:]]*/eth0/g' /etc/network/interfaces;
|
||||
sed -i 's/GRUB_CMDLINE_LINUX="\(.*\)"/GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 \1"/g' /etc/default/grub;
|
||||
update-grub;
|
||||
fi
|
||||
7
ESXi/Packer/scripts/sudoers.sh
Normal file
7
ESXi/Packer/scripts/sudoers.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
sed -i -e '/Defaults\s\+env_reset/a Defaults\texempt_group=sudo' /etc/sudoers;
|
||||
|
||||
# Set up password-less sudo for the vagrant user
|
||||
echo 'vagrant ALL=(ALL) NOPASSWD:ALL' >/etc/sudoers.d/99_vagrant;
|
||||
chmod 440 /etc/sudoers.d/99_vagrant;
|
||||
40
ESXi/Packer/scripts/update.sh
Normal file
40
ESXi/Packer/scripts/update.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/sh -eux
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ubuntu_version="`lsb_release -r | awk '{print $2}'`";
|
||||
major_version="`echo $ubuntu_version | awk -F. '{print $1}'`";
|
||||
|
||||
# Disable release-upgrades
|
||||
sed -i.bak 's/^Prompt=.*$/Prompt=never/' /etc/update-manager/release-upgrades;
|
||||
|
||||
# Disable systemd apt timers/services
|
||||
if [ "$major_version" -ge "16" ]; then
|
||||
systemctl stop apt-daily.timer;
|
||||
systemctl stop apt-daily-upgrade.timer;
|
||||
systemctl disable apt-daily.timer;
|
||||
systemctl disable apt-daily-upgrade.timer;
|
||||
systemctl mask apt-daily.service;
|
||||
systemctl mask apt-daily-upgrade.service;
|
||||
systemctl daemon-reload;
|
||||
fi
|
||||
|
||||
# Disable periodic activities of apt to be safe
|
||||
cat <<EOF >/etc/apt/apt.conf.d/10periodic;
|
||||
APT::Periodic::Enable "0";
|
||||
APT::Periodic::Update-Package-Lists "0";
|
||||
APT::Periodic::Download-Upgradeable-Packages "0";
|
||||
APT::Periodic::AutocleanInterval "0";
|
||||
APT::Periodic::Unattended-Upgrade "0";
|
||||
EOF
|
||||
|
||||
# Clean and nuke the package from orbit
|
||||
rm -rf /var/log/unattended-upgrades;
|
||||
apt-get -y purge unattended-upgrades;
|
||||
|
||||
# Update the package list
|
||||
apt-get -y update;
|
||||
|
||||
# Upgrade all installed packages incl. kernel and kernel headers
|
||||
apt-get -y dist-upgrade -o Dpkg::Options::="--force-confnew";
|
||||
|
||||
reboot
|
||||
14
ESXi/Packer/scripts/vagrant.sh
Normal file
14
ESXi/Packer/scripts/vagrant.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
pubkey_url="https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub";
|
||||
mkdir -p $HOME_DIR/.ssh;
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
wget --no-check-certificate "$pubkey_url" -O $HOME_DIR/.ssh/authorized_keys;
|
||||
elif command -v curl >/dev/null 2>&1; then
|
||||
curl --insecure --location "$pubkey_url" > $HOME_DIR/.ssh/authorized_keys;
|
||||
else
|
||||
echo "Cannot download vagrant public key";
|
||||
exit 1;
|
||||
fi
|
||||
chown -R vagrant $HOME_DIR/.ssh;
|
||||
chmod -R go-rwsx $HOME_DIR/.ssh;
|
||||
10
ESXi/Packer/scripts/vmware.sh
Normal file
10
ESXi/Packer/scripts/vmware.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
case "$PACKER_BUILDER_TYPE" in
|
||||
vmware-iso|vmware-vmx)
|
||||
apt-get install -y open-vm-tools;
|
||||
mkdir /mnt/hgfs;
|
||||
systemctl enable open-vm-tools
|
||||
systemctl start open-vm-tools
|
||||
echo "platform specific vmware.sh executed";
|
||||
esac
|
||||
105
ESXi/Packer/ubuntu1804_esxi.json
Normal file
105
ESXi/Packer/ubuntu1804_esxi.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"builders": [
|
||||
{
|
||||
"boot_command": [
|
||||
"<esc><wait>",
|
||||
"<esc><wait>",
|
||||
"<enter><wait>",
|
||||
"/install/vmlinuz<wait>",
|
||||
" auto<wait>",
|
||||
" console-setup/ask_detect=false<wait>",
|
||||
" console-setup/layoutcode=us<wait>",
|
||||
" console-setup/modelcode=pc105<wait>",
|
||||
" debconf/frontend=noninteractive<wait>",
|
||||
" debian-installer=en_US.UTF-8<wait>",
|
||||
" fb=false<wait>",
|
||||
" initrd=/install/initrd.gz<wait>",
|
||||
" kbd-chooser/method=us<wait>",
|
||||
" keyboard-configuration/layout=USA<wait>",
|
||||
" keyboard-configuration/variant=USA<wait>",
|
||||
" locale=en_US.UTF-8<wait>",
|
||||
" netcfg/get_domain=vm<wait>",
|
||||
" netcfg/get_hostname=vagrant<wait>",
|
||||
" grub-installer/bootdev=/dev/sda<wait>",
|
||||
" preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg<wait>",
|
||||
" -- <wait>",
|
||||
"<enter><wait>"
|
||||
],
|
||||
"boot_wait": "10s",
|
||||
"keep_registered": true,
|
||||
"remote_datastore": "{{user `esxi_datastore`}}",
|
||||
"remote_host": "{{user `esxi_host`}}",
|
||||
"remote_username": "{{user `esxi_username`}}",
|
||||
"remote_password": "{{user `esxi_password`}}",
|
||||
"remote_type": "esx5",
|
||||
"vnc_disable_password": true,
|
||||
"vnc_port_min": 5900,
|
||||
"vnc_port_max": 5980,
|
||||
"disk_size": "{{user `disk_size`}}",
|
||||
"guest_os_type": "ubuntu-64",
|
||||
"http_directory": "{{user `http_directory`}}",
|
||||
"iso_checksum": "{{user `iso_checksum`}}",
|
||||
"iso_checksum_type": "{{user `iso_checksum_type`}}",
|
||||
"iso_url": "{{user `mirror`}}/{{user `mirror_directory`}}/{{user `iso_name`}}",
|
||||
"shutdown_command": "echo 'vagrant' | sudo -S shutdown -P now",
|
||||
"ssh_password": "vagrant",
|
||||
"ssh_port": 22,
|
||||
"ssh_username": "vagrant",
|
||||
"ssh_wait_timeout": "10000s",
|
||||
"tools_upload_flavor": "linux",
|
||||
"type": "vmware-iso",
|
||||
"vm_name": "Ubuntu1804",
|
||||
"memory": "{{ user `memory` }}",
|
||||
"cpus": "{{ user `cpus` }}",
|
||||
"vmx_data": {
|
||||
"ethernet0.networkName": "{{ esxi_network_with_dhcp_and_internet }}",
|
||||
"cpuid.coresPerSocket": "1",
|
||||
"ethernet0.pciSlotNumber": "32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"provisioners": [
|
||||
{
|
||||
"environment_vars": [
|
||||
"HOME_DIR=/home/vagrant"
|
||||
],
|
||||
"execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E sh -eux '{{.Path}}'",
|
||||
"expect_disconnect": true,
|
||||
"scripts": [
|
||||
"{{template_dir}}/scripts/update.sh",
|
||||
"{{template_dir}}/_common/motd.sh",
|
||||
"{{template_dir}}/_common/sshd.sh",
|
||||
"{{template_dir}}/scripts/networking.sh",
|
||||
"{{template_dir}}/scripts/sudoers.sh",
|
||||
"{{template_dir}}/scripts/vagrant.sh",
|
||||
"{{template_dir}}/scripts/vmware.sh",
|
||||
"{{template_dir}}/scripts/cleanup.sh"
|
||||
],
|
||||
"type": "shell"
|
||||
}
|
||||
],
|
||||
"variables": {
|
||||
"box_basename": "ubuntu-18.04",
|
||||
"http_directory": "{{template_dir}}/http",
|
||||
"build_timestamp": "{{isotime \"20060102150405\"}}",
|
||||
"cpus": "2",
|
||||
"disk_size": "65536",
|
||||
"esxi_datastore": "",
|
||||
"esxi_host": "",
|
||||
"esxi_username": "",
|
||||
"esxi_password": "",
|
||||
"headless": "false",
|
||||
"guest_additions_url": "",
|
||||
"iso_checksum": "e2ecdace33c939527cbc9e8d23576381c493b071107207d2040af72595f8990b",
|
||||
"iso_checksum_type": "sha256",
|
||||
"iso_name": "ubuntu-18.04.4-server-amd64.iso",
|
||||
"memory": "4096",
|
||||
"mirror": "http://cdimage.ubuntu.com",
|
||||
"mirror_directory": "ubuntu/releases/18.04.4/release",
|
||||
"name": "ubuntu-18.04",
|
||||
"no_proxy": "{{env `no_proxy`}}",
|
||||
"preseed_path": "preseed.cfg",
|
||||
"template": "ubuntu-18.04-amd64",
|
||||
"version": "TIMESTAMP"
|
||||
}
|
||||
}
|
||||
7
ESXi/Packer/variables.json
Normal file
7
ESXi/Packer/variables.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"esxi_host": "",
|
||||
"esxi_datastore": "",
|
||||
"esxi_username": "",
|
||||
"esxi_password": "",
|
||||
"esxi_network_with_dhcp_and_internet": "",
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
{
|
||||
"vnc_disable_password": true,
|
||||
"keep_registered": true,
|
||||
"remote_datastore": "<fill_me_in>",
|
||||
"remote_host": "<fill_me_in>",
|
||||
"remote_username": "<fill_me_in>",
|
||||
"remote_password": "<fill_me_in>",
|
||||
"remote_datastore": "{{user `esxi_datastore`}}",
|
||||
"remote_host": "{{user `esxi_host`}}",
|
||||
"remote_username": "{{user `esxi_username`}}",
|
||||
"remote_password": "{{user `esxi_password`}}",
|
||||
"remote_type": "esx5",
|
||||
"type": "vmware-iso",
|
||||
"vm_name":"Windows10",
|
||||
@@ -29,20 +29,20 @@
|
||||
"version": 11,
|
||||
"floppy_files": [
|
||||
"{{user `autounattend`}}",
|
||||
"../Packer/floppy/WindowsPowershell.lnk",
|
||||
"../Packer/floppy/PinTo10.exe",
|
||||
"../Packer/scripts/fixnetwork.ps1",
|
||||
"../Packer/scripts/rearm-windows.ps1",
|
||||
"../Packer/scripts/disable-screensaver.ps1",
|
||||
"../Packer/scripts/disable-winrm.ps1",
|
||||
"../Packer/scripts/enable-winrm.ps1",
|
||||
"../Packer/scripts/microsoft-updates.bat",
|
||||
"../Packer/scripts/win-updates.ps1",
|
||||
"../Packer/scripts/unattend.xml",
|
||||
"../Packer/scripts/sysprep.bat"
|
||||
"../../Packer/floppy/WindowsPowershell.lnk",
|
||||
"../../Packer/floppy/PinTo10.exe",
|
||||
"../../Packer/scripts/fixnetwork.ps1",
|
||||
"../../Packer/scripts/rearm-windows.ps1",
|
||||
"../../Packer/scripts/disable-screensaver.ps1",
|
||||
"../../Packer/scripts/disable-winrm.ps1",
|
||||
"../../Packer/scripts/enable-winrm.ps1",
|
||||
"../../Packer/scripts/microsoft-updates.bat",
|
||||
"../../Packer/scripts/win-updates.ps1",
|
||||
"../../Packer/scripts/unattend.xml",
|
||||
"../../Packer/scripts/sysprep.bat"
|
||||
],
|
||||
"vmx_data": {
|
||||
"ethernet0.networkName": "VM Network",
|
||||
"ethernet0.networkName": "{{ esxi_network_with_dhcp_and_internet }}",
|
||||
"memsize": "2048",
|
||||
"numvcpus": "2",
|
||||
"scsi0.virtualDev": "lsisas1068"
|
||||
@@ -55,14 +55,14 @@
|
||||
"remote_path": "/tmp/script.bat",
|
||||
"execute_command": "{{ .Vars }} cmd /c \"{{ .Path }}\"",
|
||||
"scripts": [
|
||||
"../Packer/scripts/vm-guest-tools.bat",
|
||||
"../Packer/scripts/enable-rdp.bat"
|
||||
"../../Packer/scripts/vm-guest-tools.bat",
|
||||
"../../Packer/scripts/enable-rdp.bat"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "powershell",
|
||||
"scripts": [
|
||||
"../Packer/scripts/debloat-windows.ps1"
|
||||
"../../Packer/scripts/debloat-windows.ps1"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -71,8 +71,8 @@
|
||||
{
|
||||
"type": "powershell",
|
||||
"scripts": [
|
||||
"../Packer/scripts/set-powerplan.ps1",
|
||||
"../Packer/scripts/docker/disable-windows-defender.ps1"
|
||||
"../../Packer/scripts/set-powerplan.ps1",
|
||||
"../../Packer/scripts/docker/disable-windows-defender.ps1"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -80,26 +80,22 @@
|
||||
"remote_path": "/tmp/script.bat",
|
||||
"execute_command": "{{ .Vars }} cmd /c \"{{ .Path }}\"",
|
||||
"scripts": [
|
||||
"../Packer/scripts/pin-powershell.bat",
|
||||
"../Packer/scripts/compile-dotnet-assemblies.bat",
|
||||
"../Packer/scripts/set-winrm-automatic.bat",
|
||||
"../Packer/scripts/dis-updates.bat"
|
||||
"../../Packer/scripts/pin-powershell.bat",
|
||||
"../../Packer/scripts/compile-dotnet-assemblies.bat",
|
||||
"../../Packer/scripts/set-winrm-automatic.bat",
|
||||
"../../Packer/scripts/dis-updates.bat"
|
||||
]
|
||||
}
|
||||
],
|
||||
"post-processors": [
|
||||
{
|
||||
"type": "vagrant",
|
||||
"keep_input_artifact": false,
|
||||
"output": "windows_10_{{.Provider}}.box",
|
||||
"vagrantfile_template": "vagrantfile-windows_10.template"
|
||||
}
|
||||
],
|
||||
"variables": {
|
||||
"esxi_datastore": "",
|
||||
"esxi_host": "",
|
||||
"esxi_username": "",
|
||||
"esxi_password": "",
|
||||
"iso_checksum": "ab4862ba7d1644c27f27516d24cb21e6b39234eb3301e5f1fb365a78b22f79b3",
|
||||
"iso_checksum_type": "sha256",
|
||||
"iso_url": "https://software-download.microsoft.com/download/pr/18362.30.190401-1528.19h1_release_svc_refresh_CLIENTENTERPRISEEVAL_OEMRET_x64FRE_en-us.iso",
|
||||
"autounattend": "../Packer/answer_files/10/Autounattend.xml",
|
||||
"autounattend": "../../Packer/answer_files/10/Autounattend.xml",
|
||||
"disk_size": "61440"
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
{
|
||||
"vnc_disable_password": true,
|
||||
"keep_registered": true,
|
||||
"remote_datastore": "<fill_me_in>",
|
||||
"remote_host": "<fill_me_in>",
|
||||
"remote_username": "<fill_me_in>",
|
||||
"remote_password": "<fill_me_in>",
|
||||
"remote_datastore": "{{user `esxi_datastore`}}",
|
||||
"remote_host": "{{user `esxi_host`}}",
|
||||
"remote_username": "{{user `esxi_username`}}",
|
||||
"remote_password": "{{user `esxi_password`}}",
|
||||
"remote_type": "esx5",
|
||||
"vm_name":"WindowsServer2016",
|
||||
"type": "vmware-iso",
|
||||
@@ -26,18 +26,18 @@
|
||||
"version": 11,
|
||||
"floppy_files": [
|
||||
"{{user `autounattend`}}",
|
||||
"../Packer/floppy/WindowsPowershell.lnk",
|
||||
"../Packer/floppy/PinTo10.exe",
|
||||
"../Packer/scripts/unattend.xml",
|
||||
"../Packer/scripts/sysprep.bat",
|
||||
"../Packer/scripts/disable-screensaver.ps1",
|
||||
"../Packer/scripts/disable-winrm.ps1",
|
||||
"../Packer/scripts/enable-winrm.ps1",
|
||||
"../Packer/scripts/microsoft-updates.bat",
|
||||
"../Packer/scripts/win-updates.ps1"
|
||||
"../../Packer/floppy/WindowsPowershell.lnk",
|
||||
"../../Packer/floppy/PinTo10.exe",
|
||||
"../../Packer/scripts/unattend.xml",
|
||||
"../../Packer/scripts/sysprep.bat",
|
||||
"../../Packer/scripts/disable-screensaver.ps1",
|
||||
"../../Packer/scripts/disable-winrm.ps1",
|
||||
"../../Packer/scripts/enable-winrm.ps1",
|
||||
"../../Packer/scripts/microsoft-updates.bat",
|
||||
"../../Packer/scripts/win-updates.ps1"
|
||||
],
|
||||
"vmx_data": {
|
||||
"ethernet0.networkName": "VM Network",
|
||||
"ethernet0.networkName": "{{ esxi_network_with_dhcp_and_internet }}",
|
||||
"memsize": "2048",
|
||||
"numvcpus": "2",
|
||||
"scsi0.virtualDev": "lsisas1068"
|
||||
@@ -49,14 +49,14 @@
|
||||
"type": "windows-shell",
|
||||
"execute_command": "{{ .Vars }} cmd /c \"{{ .Path }}\"",
|
||||
"scripts": [
|
||||
"../Packer/scripts/vm-guest-tools.bat",
|
||||
"../Packer/scripts/enable-rdp.bat"
|
||||
"../../Packer/scripts/vm-guest-tools.bat",
|
||||
"../../Packer/scripts/enable-rdp.bat"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "powershell",
|
||||
"scripts": [
|
||||
"../Packer/scripts/debloat-windows.ps1"
|
||||
"../../Packer/scripts/debloat-windows.ps1"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -66,27 +66,23 @@
|
||||
"type": "windows-shell",
|
||||
"execute_command": "{{ .Vars }} cmd /c \"{{ .Path }}\"",
|
||||
"scripts": [
|
||||
"../Packer/scripts/pin-powershell.bat",
|
||||
"../Packer/scripts/set-winrm-automatic.bat",
|
||||
"../Packer/scripts/compile-dotnet-assemblies.bat",
|
||||
"../Packer/scripts/uac-enable.bat",
|
||||
"../Packer/scripts/compact.bat"
|
||||
"../../Packer/scripts/pin-powershell.bat",
|
||||
"../../Packer/scripts/set-winrm-automatic.bat",
|
||||
"../../Packer/scripts/compile-dotnet-assemblies.bat",
|
||||
"../../Packer/scripts/uac-enable.bat",
|
||||
"../../Packer/scripts/compact.bat"
|
||||
]
|
||||
}
|
||||
],
|
||||
"post-processors": [
|
||||
{
|
||||
"type": "vagrant",
|
||||
"keep_input_artifact": false,
|
||||
"output": "windows_2016_{{.Provider}}.box",
|
||||
"vagrantfile_template": "vagrantfile-windows_2016.template"
|
||||
}
|
||||
],
|
||||
"variables": {
|
||||
"esxi_datastore": "",
|
||||
"esxi_host": "",
|
||||
"esxi_username": "",
|
||||
"esxi_password": "",
|
||||
"iso_url": "https://software-download.microsoft.com/download/pr/Windows_Server_2016_Datacenter_EVAL_en-us_14393_refresh.ISO",
|
||||
"iso_checksum_type": "md5",
|
||||
"iso_checksum": "70721288BBCDFE3239D8F8C0FAE55F1F",
|
||||
"autounattend": "../Packer/answer_files/2016/Autounattend.xml"
|
||||
"autounattend": "../../Packer/answer_files/2016/Autounattend.xml"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,65 @@
|
||||
# Building DetectionLab on ESXi
|
||||
|
||||
NOTE: This is a work in progress and provisioning is not yet functional. At this time here is what works:
|
||||
NOTE: This is an early release and it's possible that certain features may not work perfectly for everyone yet
|
||||
|
||||
* Building Packer Windows images on ESXi
|
||||
* Bringing the Windows Images online using Terraform
|
||||
|
||||
Here is what doesn't work yet:
|
||||
|
||||
* Setting IP Addresses
|
||||
* Provisioning (Domain creation, software installation, etc)
|
||||
* Pretty much everything else
|
||||
|
||||
## Prereqs
|
||||
## Prereqs (~30-60 minutes)
|
||||
0. Have an ESXi instance version 6 or higher. VSphere is **NOT** required.
|
||||
1. Install the [requirements from the ESXi Terraform Provider](https://github.com/josenk/terraform-provider-esxi#requirements)
|
||||
* If building on MacOS, don't forget to change the GOOS from linux to darwin!
|
||||
* `GOOS=linux` -> `GOOS=darwin`
|
||||
2. Build and install the [terraform-provider-esxi](https://github.com/josenk/terraform-provider-esxi#building-the-provider) provider
|
||||
3. Your ESXi must have at least two separate networks - one that is accessible from your host (VM Network) and a NAT network to allow the VMs to have internet access (NAT Network). Here's a decent guide to help you with the NAT network: https://medium.com/@glmdev/how-to-set-up-virtualized-pfsense-on-vmware-esxi-6-x-2c2861b25931
|
||||
3. Your ESXi must have at least two separate networks - one that is accessible from your current machine (VM Network) and a HostOnly network to allow the VMs to have internet access (HostOnly).
|
||||
4. [OVFTool](https://my.vmware.com/web/vmware/details?downloadGroup=OVFTOOL420&productId=618) must be installed and in your path.
|
||||
* On MacOS, I solved this by creating a symbolic link to the ovftool included in VMWare Fusion: `sudo ln -s "/Applications/VMware Fusion.app/Contents/Library/VMware OVF Tool/ovftool" "/usr/local/bin/ovftool"`
|
||||
5. On your ESXI, you must:
|
||||
1. Enable SSH
|
||||
2. Enable the "Guest IP Hack"
|
||||
3. Open VNC ports on the firewall
|
||||
* Instructions for those steps are here: https://nickcharlton.net/posts/using-packer-esxi-6.html
|
||||
6. [Install Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)
|
||||
|
||||
## Steps
|
||||
1. Edit the following variables in `windows_10_esxi.json` and `windows_2016_esxi.json` to match your ESXi configuration:
|
||||
* remote_datastore
|
||||
* remote_host
|
||||
* remote_username
|
||||
* remote_password
|
||||
|
||||
2. From the ESXi directory, run `packer build windows_10_esxi.json` and `packer build windows_2016_esxi.json`. These can be run in parallel from two separate terminal sessions.
|
||||
3. Once the Packer builds complete, ensure you now see Windows10 and WindowsServer2016 in your ESXi console
|
||||
4. Edit the variables in `ESXi/variables.tf` to match your local ESXi configuration
|
||||
5. Run `terraform init && terraform apply`
|
||||
1. **(5 Minutes)** Edit the variables in `DetectionLab/ESXi/Packer/variables.json` to match your ESXi configuration. The `esxi_network_with_dhcp_and_internet` variable refers to any ESXi network that will be able to provide DHCP and internet access to the VM while it's being built in Packer.
|
||||
|
||||
It takes quite some time (30m on my host) for the linked clones to be created, but once they're finished, they should be accessible!
|
||||
2. **(45 Minutes)** From the `DetectionLab/ESXi/Packer` directory, run:
|
||||
* `PACKER_CACHE_DIR=../../Packer/packer_cache packer build -var-file variables.json windows_10_esxi.json`
|
||||
* `PACKER_CACHE_DIR=../../Packer/packer_cache packer build -var-file variables.json windows_2016_esxi.json`
|
||||
* `PACKER_CACHE_DIR=../../Packer/packer_cache packer build -var-file variables.json ubuntu1804_esxi.json`
|
||||
|
||||
These commands can be run in parallel from three separate terminal sessions.
|
||||
|
||||

|
||||
|
||||
3. **(1 Minute)** Once the Packer builds finish, verify that you now see Windows10, WindowsServer2016, and Ubuntu1804 in your ESXi console
|
||||

|
||||
4. **(5 Minutes)** Edit the variables in `ESXi/variables.tf` to match your local ESXi configuration or [create a terraform.tfvars file] (RECOMMENDED)(https://www.terraform.io/docs/configuration/variables.html#variable-definitions-tfvars-files) to override them.
|
||||
5. **(25 Minutes)** From `DetectionLab/ESXi`, run `terraform init && terraform apply`
|
||||
6. Once Terraform has finished bringing the hosts online, change your directory to `DetectionLab/ESXi/ansible`
|
||||
7. **(1 Minute)** Edit `DetectionLab/ESXi/ansible/inventory.yml` and replace the IP Addresses with the respective IP Addresses of your ESXi VMs. **These IP addresses much be reachable from your host machine!**
|
||||
8. **(3 Minute)s** Edit `DetectionLab/ESXi/ansible/resources/01-netcfg.yaml`. These are the IP addresses that will be applied to the logger network interfaces. These should be be able to be found in your ESXi console or from the Terraform outputs.
|
||||
9. **(3 Minute)** Before running any Ansible playbooks, I highly recommend taking snapshots of all your VMs! If anything goes wrong with provisioning, you can simply restore the snapshot and easily debug the issue.
|
||||
10. Change your directory to `DetectionLab/ESXi/ansible`
|
||||
11. **(30 Minutes)** Run `ansible-playbook -vvv detectionlab.yml`
|
||||
12. If all goes well, you should see the following and your lab is complete!
|
||||

|
||||
|
||||
If you run into any issues along the way, please open an issue on Github and I'll do my best to find a solution.
|
||||
|
||||
## Future work required
|
||||
* The logger host needs to be implemented. This should be fairly straightforward.
|
||||
* The provisioning for the Windows hosts needs to be figured out. I'm not sure if it makes more sense to build it all out in Packer and then just bring the VMs online using Terraform, or if it makes more sense to provision them using something like Ansible.
|
||||
* It probably makes sense to abstract all of the logic in `bootstrap.sh` into individual Ansible tasks
|
||||
* There's a lot of areas to make reliability improvements
|
||||
* I'm guessing there's a way to parallelize some of this execution: https://medium.com/developer-space/parallel-playbook-execution-in-ansible-30799ccda4e0
|
||||
|
||||
I'm completely open to any and all input here as this is not my area of expertise :)
|
||||
## Debugging / Troubleshooting
|
||||
* If an Ansible playbook fails, you can pick up where it left off with `ansible-playbook -vvv detectionlab.yml --start-at-task="taskname"`
|
||||
|
||||
## Credits
|
||||
As usual, this work is based off the heavy lifting that others have done. My primary sources for this work were:
|
||||
* [Josenk's Terraform-ESXI-Provider](https://github.com/josenk/terraform-provider-esxi) - Without this, there would be no way to deploy DL to ESXi without paying for VSphere. Send him/her some love 💌
|
||||
* [Automate Windows VM Creation and Configuration in vSphere Using Packer, Terraform and Ansible - Dmitry Teslya](https://dteslya.engineer/automation/2019-02-19-configuring_vms_with_ansible/#setting-up-ansible)
|
||||
* [Building Virtual Machines with Packer on ESXi 6 - Nick Charlton](https://nickcharlton.net/posts/using-packer-esxi-6.html)
|
||||
* [The DetectionLab work that juju4 has been doing on Azure and Ansible](https://github.com/juju4/DetectionLab/tree/devel-azureansible/Ansible)
|
||||
* [lofi hip hop radio - beats to relax/study to](https://www.youtube.com/watch?v=5qap5aO4i9A) 🔉
|
||||
|
||||
Thank you to all of the sponsors who made this possible!
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
[defaults]
|
||||
inventory = inventory.yml
|
||||
host_key_checking = False
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
|
||||
- name: Hostname -> DC
|
||||
win_hostname:
|
||||
name: dc
|
||||
register: res
|
||||
|
||||
- name: Reboot
|
||||
win_reboot:
|
||||
when: res.reboot_required
|
||||
|
||||
- name: Install git
|
||||
win_chocolatey:
|
||||
name: git
|
||||
state: present
|
||||
|
||||
- name: Check if existing DetectionLab directory
|
||||
win_stat:
|
||||
path: 'c:\DetectionLab'
|
||||
register: dir
|
||||
|
||||
- name: Git clone Detectionlab
|
||||
win_shell: git clone https://github.com/clong/DetectionLab.git
|
||||
args:
|
||||
chdir: 'c:\'
|
||||
when: not dir.stat.exists
|
||||
|
||||
- name: Copy scripts to c:\vagrant
|
||||
win_shell: Copy-Item -Recurse c:\DetectionLab\Vagrant c:\vagrant
|
||||
|
||||
- name: Provision
|
||||
win_shell: .\\provision.ps1
|
||||
args:
|
||||
chdir: 'c:\vagrant\scripts'
|
||||
|
||||
- name: reboot server
|
||||
win_reboot:
|
||||
msg: "Installing AD. Rebooting..."
|
||||
pre_reboot_delay: 15
|
||||
reboot_timeout: 600
|
||||
post_reboot_delay: 420
|
||||
@@ -1,4 +1,19 @@
|
||||
---
|
||||
- hosts: logger
|
||||
roles:
|
||||
- logger
|
||||
|
||||
- hosts: dc
|
||||
roles:
|
||||
- dc
|
||||
- common
|
||||
|
||||
- hosts: wef
|
||||
roles:
|
||||
- wef
|
||||
- common
|
||||
|
||||
- hosts: win10
|
||||
roles:
|
||||
- win10
|
||||
- common
|
||||
4
ESXi/ansible/group_vars/linux.yml
Normal file
4
ESXi/ansible/group_vars/linux.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
ansible_user: vagrant
|
||||
ansible_password: vagrant
|
||||
ansible_port: 22
|
||||
ansible_connection: ssh
|
||||
@@ -1,4 +1,23 @@
|
||||
---
|
||||
|
||||
logger:
|
||||
hosts:
|
||||
192.168.3.151:
|
||||
ansible_user: vagrant
|
||||
ansible_password: vagrant
|
||||
ansible_port: 22
|
||||
ansible_connection: ssh
|
||||
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
|
||||
|
||||
dc:
|
||||
hosts:
|
||||
192.168.3.189:
|
||||
|
||||
wef:
|
||||
hosts:
|
||||
192.168.3.194:
|
||||
|
||||
win10:
|
||||
hosts:
|
||||
192.168.3.193:
|
||||
|
||||
|
||||
36
ESXi/ansible/roles/common/tasks/main.yml
Normal file
36
ESXi/ansible/roles/common/tasks/main.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
|
||||
- name: Run Common Tasks
|
||||
win_shell: ".\\{{ item }}"
|
||||
args:
|
||||
chdir: 'c:\vagrant\scripts'
|
||||
with_items:
|
||||
- "download_palantir_wef.ps1"
|
||||
- "download_palantir_osquery.ps1"
|
||||
- "install-osquery.ps1"
|
||||
- "install-sysinternals.ps1"
|
||||
- "install-autorunstowineventlog.ps1"
|
||||
- "install-redteam.ps1"
|
||||
|
||||
- name: Install utilities
|
||||
win_chocolatey:
|
||||
name:
|
||||
- NotepadPlusPlus
|
||||
- GoogleChrome
|
||||
- WinRar
|
||||
- wireshark
|
||||
- winpcap
|
||||
state: present
|
||||
|
||||
- name: Install classic-shell with chocolatey
|
||||
win_chocolatey:
|
||||
name:
|
||||
- classic-shell
|
||||
state: present
|
||||
install_args: "ADDLOCAL=ClassicStartMenu"
|
||||
|
||||
- name: DetectionLab Menu
|
||||
win_shell: "\"C:\\Program Files\\Classic Shell\\ClassicStartMenu.exe -xml c:\\vagrant\\resources\\windows\\MenuSettings.xml\""
|
||||
|
||||
|
||||
|
||||
67
ESXi/ansible/roles/dc/tasks/main.yml
Normal file
67
ESXi/ansible/roles/dc/tasks/main.yml
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
|
||||
- name: Hostname -> DC
|
||||
win_hostname:
|
||||
name: dc
|
||||
register: res
|
||||
|
||||
- name: Reboot
|
||||
win_reboot:
|
||||
when: res.reboot_required
|
||||
|
||||
- name: Set HostOnly IP Address
|
||||
win_shell: "New-NetIPAddress –InterfaceAlias Ethernet2 –AddressFamily IPv4 -IPAddress 192.168.38.102 –PrefixLength 24 -DefaultGateway 192.168.38.1"
|
||||
|
||||
- name: Set DNS Address
|
||||
win_shell: "Set-DnsClientServerAddress -InterfaceAlias Ethernet2 -ServerAddresses 127.0.0.1,8.8.8.8"
|
||||
|
||||
- name: Install git
|
||||
win_chocolatey:
|
||||
name: git
|
||||
state: present
|
||||
|
||||
- name: Check if existing DetectionLab directory
|
||||
win_stat:
|
||||
path: 'c:\DetectionLab'
|
||||
register: dir
|
||||
|
||||
- name: Git clone Detectionlab
|
||||
win_shell: git clone https://github.com/clong/DetectionLab.git
|
||||
args:
|
||||
chdir: 'c:\'
|
||||
when: not dir.stat.exists
|
||||
|
||||
- name: Copy scripts to c:\vagrant
|
||||
win_shell: Copy-Item -Recurse c:\DetectionLab\Vagrant c:\vagrant
|
||||
|
||||
- name: Create the Domain
|
||||
win_shell: .\\provision.ps1
|
||||
args:
|
||||
chdir: 'c:\vagrant\scripts'
|
||||
|
||||
- name: reboot server
|
||||
win_reboot:
|
||||
msg: "Installing AD. Rebooting..."
|
||||
pre_reboot_delay: 15
|
||||
reboot_timeout: 600
|
||||
post_reboot_delay: 60
|
||||
|
||||
- name: Configure DC Host
|
||||
win_shell: ".\\{{ item }}"
|
||||
args:
|
||||
chdir: 'c:\vagrant\scripts'
|
||||
with_items:
|
||||
- "configure-ou.ps1"
|
||||
- "configure-wef-gpo.ps1"
|
||||
- "configure-powershelllogging.ps1"
|
||||
- "configure-AuditingPolicyGPOs.ps1"
|
||||
- "configure-disable-windows-defender-gpo.ps1"
|
||||
- "configure-rdp-user-gpo.ps1"
|
||||
|
||||
- name: Configure DC with raw Commands
|
||||
win_shell: "{{ item }}"
|
||||
with_items:
|
||||
- "wevtutil el | Select-String -notmatch \"Microsoft-Windows-LiveId\" | Foreach-Object {wevtutil cl \"$_\"}"
|
||||
- "Set-SmbServerConfiguration -AuditSmb1Access $true -Force"
|
||||
|
||||
|
||||
48
ESXi/ansible/roles/logger/tasks/main.yml
Normal file
48
ESXi/ansible/roles/logger/tasks/main.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
|
||||
- name: Set hostname to logger
|
||||
hostname:
|
||||
name: logger
|
||||
become: yes
|
||||
|
||||
- name: Create a directory if it does not exist
|
||||
file:
|
||||
path: /vagrant
|
||||
state: directory
|
||||
mode: '0755'
|
||||
become: yes
|
||||
|
||||
- name: Copy vagrant resources
|
||||
synchronize:
|
||||
src: ../../Vagrant/resources
|
||||
dest: /vagrant/
|
||||
become: yes
|
||||
|
||||
- name: Copy bootstrap file
|
||||
copy:
|
||||
src: ../../Vagrant/bootstrap.sh
|
||||
dest: /home/vagrant
|
||||
owner: vagrant
|
||||
group: vagrant
|
||||
mode: u+x,g+x
|
||||
|
||||
- name: Copy netplan file
|
||||
copy:
|
||||
src: ../resources/01-netcfg.yaml
|
||||
dest: /tmp
|
||||
owner: vagrant
|
||||
group: vagrant
|
||||
|
||||
- name: Copy the netplan file over as root
|
||||
shell: "mv /tmp/01-netcfg.yaml /etc/netplan/01-netcfg.yaml"
|
||||
become: yes
|
||||
|
||||
- name: Apply the new netplan
|
||||
shell: netplan apply
|
||||
become: yes
|
||||
|
||||
- name: Run bootstrap.sh
|
||||
shell: /home/vagrant/bootstrap.sh | tee -a /home/vagrant/bootstrap.log
|
||||
args:
|
||||
executable: /bin/bash
|
||||
become: yes
|
||||
72
ESXi/ansible/roles/wef/tasks/main.yml
Normal file
72
ESXi/ansible/roles/wef/tasks/main.yml
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
|
||||
- name: Hostname -> WEF
|
||||
win_hostname:
|
||||
name: wef
|
||||
register: res
|
||||
|
||||
- name: Reboot
|
||||
win_reboot:
|
||||
when: res.reboot_required
|
||||
|
||||
# This needs to be made idempodent
|
||||
- name: Set HostOnly IP Address
|
||||
win_shell: "New-NetIPAddress –InterfaceAlias Ethernet2 –AddressFamily IPv4 -IPAddress 192.168.38.103 –PrefixLength 24 -DefaultGateway 192.168.38.1"
|
||||
|
||||
# This needs to be made idempodent
|
||||
- name: Set HostOnly DNS Address
|
||||
win_shell: "Set-DnsClientServerAddress -InterfaceAlias Ethernet2 -ServerAddresses 192.168.38.102,8.8.8.8"
|
||||
|
||||
- name: Install git
|
||||
win_chocolatey:
|
||||
name: git
|
||||
state: present
|
||||
|
||||
- name: Check if existing DetectionLab directory
|
||||
win_stat:
|
||||
path: 'c:\DetectionLab'
|
||||
register: dir
|
||||
|
||||
- name: Git clone Detectionlab
|
||||
win_shell: git clone https://github.com/clong/DetectionLab.git
|
||||
args:
|
||||
chdir: 'c:\'
|
||||
when: not dir.stat.exists
|
||||
|
||||
- name: Copy scripts to c:\vagrant
|
||||
win_shell: Copy-Item -Recurse c:\DetectionLab\Vagrant c:\vagrant
|
||||
|
||||
- name: Join the Domain
|
||||
win_shell: .\\provision.ps1
|
||||
args:
|
||||
chdir: 'c:\vagrant\scripts'
|
||||
|
||||
- name: reboot server
|
||||
win_reboot:
|
||||
msg: "Joining the domain. Rebooting..."
|
||||
pre_reboot_delay: 15
|
||||
reboot_timeout: 600
|
||||
post_reboot_delay: 60
|
||||
|
||||
- name: Clear Event Logs
|
||||
win_shell: "wevtutil el | Select-String -notmatch \"Microsoft-Windows-LiveId\" | Foreach-Object {wevtutil cl \"$_\"}"
|
||||
|
||||
- name: Configure WEF Host
|
||||
win_shell: ".\\{{ item }}"
|
||||
args:
|
||||
chdir: 'c:\vagrant\scripts'
|
||||
with_items:
|
||||
- "download_palantir_wef.ps1"
|
||||
- "install-wefsubscriptions.ps1"
|
||||
- "install-splunkuf.ps1"
|
||||
- "install-windows_ta.ps1"
|
||||
- "configure-pslogstranscriptsshare.ps1"
|
||||
- "install-microsoft-ata.ps1"
|
||||
|
||||
- name: Configure WEF with raw Commands
|
||||
win_shell: "{{ item }}"
|
||||
with_items:
|
||||
- "wevtutil el | Select-String -notmatch \"Microsoft-Windows-LiveId\" | Foreach-Object {wevtutil cl \"$_\"}"
|
||||
- "Set-SmbServerConfiguration -AuditSmb1Access $true -Force"
|
||||
|
||||
|
||||
61
ESXi/ansible/roles/win10/tasks/main.yml
Normal file
61
ESXi/ansible/roles/win10/tasks/main.yml
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
|
||||
- name: Hostname -> WIN10
|
||||
win_hostname:
|
||||
name: win10
|
||||
register: res
|
||||
|
||||
- name: Reboot
|
||||
win_reboot:
|
||||
when: res.reboot_required
|
||||
|
||||
- name: Set HostOnly IP Address
|
||||
win_shell: "New-NetIPAddress –InterfaceAlias Ethernet2 –AddressFamily IPv4 -IPAddress 192.168.38.104 –PrefixLength 24 -DefaultGateway 192.168.38.1"
|
||||
|
||||
- name: Set HostOnly DNS Address
|
||||
win_shell: "Set-DnsClientServerAddress -InterfaceAlias Ethernet2 -ServerAddresses 192.168.38.102,8.8.8.8"
|
||||
|
||||
- name: Install git
|
||||
win_chocolatey:
|
||||
name: git
|
||||
state: present
|
||||
|
||||
- name: Check if existing DetectionLab directory
|
||||
win_stat:
|
||||
path: 'c:\DetectionLab'
|
||||
register: dir
|
||||
|
||||
- name: Git clone Detectionlab
|
||||
win_shell: git clone https://github.com/clong/DetectionLab.git
|
||||
args:
|
||||
chdir: 'c:\'
|
||||
when: not dir.stat.exists
|
||||
|
||||
- name: Copy scripts to c:\vagrant
|
||||
win_shell: Copy-Item -Recurse c:\DetectionLab\Vagrant c:\vagrant
|
||||
|
||||
- name: Making Windows10 Great Again
|
||||
win_shell: .\\MakeWindows10GreatAgain.ps1
|
||||
args:
|
||||
chdir: 'c:\vagrant\scripts'
|
||||
|
||||
- name: Join the Domain
|
||||
win_shell: .\\provision.ps1
|
||||
args:
|
||||
chdir: 'c:\vagrant\scripts'
|
||||
|
||||
- name: Update group policy
|
||||
win_shell: "gpupdate /force"
|
||||
|
||||
- name: Reboot Server
|
||||
win_reboot:
|
||||
msg: "Joined the domain. Rebooting..."
|
||||
pre_reboot_delay: 15
|
||||
reboot_timeout: 600
|
||||
post_reboot_delay: 60
|
||||
|
||||
- name: Clear Event Logs
|
||||
win_shell: "wevtutil el | Select-String -notmatch \"Microsoft-Windows-LiveId\" | Foreach-Object {wevtutil cl \"$_\"}"
|
||||
|
||||
|
||||
|
||||
86
ESXi/main.tf
86
ESXi/main.tf
@@ -14,13 +14,57 @@ provider "esxi" {
|
||||
#########################################
|
||||
# ESXI Guest resource
|
||||
#########################################
|
||||
#
|
||||
# This Guest VM is a clone of an existing Guest VM named "centos7" (must exist and
|
||||
# be powered off), located in the "Templates" resource pool. vmtest02 will be powered
|
||||
# on by default by terraform. The virtual network "VM Network", must already exist on
|
||||
# your esxi host!
|
||||
#
|
||||
# https://github.com/josenk/vagrant-vmware-esxi/wiki/VMware-ESXi-6.5-guestOS-types
|
||||
resource "esxi_guest" "logger" {
|
||||
guest_name = "logger"
|
||||
disk_store = "datastore1"
|
||||
guestos = "ubuntu-64"
|
||||
|
||||
boot_disk_type = "thin"
|
||||
boot_disk_size = "35"
|
||||
|
||||
memsize = "4096"
|
||||
numvcpus = "2"
|
||||
resource_pool_name = "/"
|
||||
power = "on"
|
||||
clone_from_vm = "Ubuntu1804"
|
||||
|
||||
provisioner "remote-exec" {
|
||||
inline = [
|
||||
"sudo ifconfig up eth1 | echo 'eth1 up'",
|
||||
"sudo ifconfig up eth2 || echo 'eth2 up'",
|
||||
"sudo dhclient -v eth1 || echo 'eth1 dhcp'",
|
||||
"sudo route add default gw 192.168.76.1 || echo 'route exists'"
|
||||
]
|
||||
|
||||
connection {
|
||||
host = self.ip_address
|
||||
type = "ssh"
|
||||
user = "vagrant"
|
||||
password = "vagrant"
|
||||
}
|
||||
}
|
||||
# This is the network that bridges your host machine with the ESXi VM
|
||||
network_interfaces {
|
||||
virtual_network = var.vm_network
|
||||
mac_address = "00:50:56:a3:b1:c2"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# OPTIONAL: You can comment out this interface stanza if your vm_network provides internet access
|
||||
network_interfaces {
|
||||
virtual_network = var.nat_network
|
||||
mac_address = "00:50:56:a3:b1:c3"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# This is the local network that will be used for 192.168.38.x addressing
|
||||
network_interfaces {
|
||||
virtual_network = var.hostonly_network
|
||||
mac_address = "00:50:56:a3:b1:c4"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
guest_startup_timeout = 45
|
||||
guest_shutdown_timeout = 30
|
||||
}
|
||||
|
||||
resource "esxi_guest" "dc" {
|
||||
guest_name = "dc"
|
||||
disk_store = "datastore2"
|
||||
@@ -33,23 +77,20 @@ resource "esxi_guest" "dc" {
|
||||
numvcpus = "2"
|
||||
resource_pool_name = "/"
|
||||
power = "on"
|
||||
|
||||
# clone_from_vm uses ovftool to clone an existing Guest on your esxi host. This example will clone a Guest VM named "centos7", located in the "Templates" resource pool.
|
||||
# ovf_source uses ovftool to produce a clone from an ovf or vmx image. (typically produced using the ovf_tool).
|
||||
# Basically clone_from_vm clones from sources on the esxi host and ovf_source clones from sources on your local hard disk or a URL.
|
||||
# These two options are mutually exclusive.
|
||||
clone_from_vm = "WindowsServer2016"
|
||||
|
||||
# This is the network that bridges your host machine with the ESXi VM
|
||||
network_interfaces {
|
||||
virtual_network = var.vm_network
|
||||
mac_address = "00:50:56:a1:b1:c2"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# OPTIONAL: You can comment out this interface stanza if your vm_network provides internet access
|
||||
network_interfaces {
|
||||
virtual_network = var.nat_network
|
||||
mac_address = "00:50:56:a1:b1:c3"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# This is the local network that will be used for 192.168.38.x addressing
|
||||
network_interfaces {
|
||||
virtual_network = var.hostonly_network
|
||||
mac_address = "00:50:56:a1:b1:c4"
|
||||
@@ -71,23 +112,20 @@ resource "esxi_guest" "wef" {
|
||||
numvcpus = "2"
|
||||
resource_pool_name = "/"
|
||||
power = "on"
|
||||
|
||||
# clone_from_vm uses ovftool to clone an existing Guest on your esxi host. This example will clone a Guest VM named "centos7", located in the "Templates" r$
|
||||
# ovf_source uses ovftool to produce a clone from an ovf or vmx image. (typically produced using the ovf_tool).
|
||||
# Basically clone_from_vm clones from sources on the esxi host and ovf_source clones from sources on your local hard disk or a URL.
|
||||
# These two options are mutually exclusive.
|
||||
clone_from_vm = "WindowsServer2016"
|
||||
|
||||
# This is the network that bridges your host machine with the ESXi VM
|
||||
network_interfaces {
|
||||
virtual_network = var.vm_network
|
||||
mac_address = "00:50:56:a1:b2:c2"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# OPTIONAL: You can comment out this interface stanza if your vm_network provides internet access
|
||||
network_interfaces {
|
||||
virtual_network = var.nat_network
|
||||
mac_address = "00:50:56:a1:b3:c3"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# This is the local network that will be used for 192.168.38.x addressing
|
||||
network_interfaces {
|
||||
virtual_network = var.hostonly_network
|
||||
mac_address = "00:50:56:a1:b4:c4"
|
||||
@@ -97,7 +135,6 @@ resource "esxi_guest" "wef" {
|
||||
guest_shutdown_timeout = 30
|
||||
}
|
||||
|
||||
|
||||
resource "esxi_guest" "win10" {
|
||||
guest_name = "win10"
|
||||
disk_store = "datastore2"
|
||||
@@ -110,23 +147,20 @@ resource "esxi_guest" "win10" {
|
||||
numvcpus = "2"
|
||||
resource_pool_name = "/"
|
||||
power = "on"
|
||||
|
||||
# clone_from_vm uses ovftool to clone an existing Guest on your esxi host. This example will clone a Guest VM named "centos7", located in the "Templates" r$
|
||||
# ovf_source uses ovftool to produce a clone from an ovf or vmx image. (typically produced using the ovf_tool).
|
||||
# Basically clone_from_vm clones from sources on the esxi host and ovf_source clones from sources on your local hard disk or a URL.
|
||||
# These two options are mutually exclusive.
|
||||
clone_from_vm = "Windows10"
|
||||
|
||||
# This is the network that bridges your host machine with the ESXi VM
|
||||
network_interfaces {
|
||||
virtual_network = var.vm_network
|
||||
mac_address = "00:50:56:a2:b1:c2"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# OPTIONAL: You can comment out this interface stanza if your vm_network provides internet access
|
||||
network_interfaces {
|
||||
virtual_network = var.nat_network
|
||||
mac_address = "00:50:56:a2:b1:c3"
|
||||
nic_type = "e1000"
|
||||
}
|
||||
# This is the local network that will be used for 192.168.38.x addressing
|
||||
network_interfaces {
|
||||
virtual_network = var.hostonly_network
|
||||
mac_address = "00:50:56:a2:b1:c4"
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
output "logger_interfaces" {
|
||||
value = esxi_guest.logger.network_interfaces
|
||||
}
|
||||
|
||||
output "logger_ips" {
|
||||
value = esxi_guest.logger.ip_address
|
||||
}
|
||||
|
||||
output "dc_interfaces" {
|
||||
value = esxi_guest.dc.network_interfaces
|
||||
}
|
||||
|
||||
16
ESXi/resources/01-netcfg.yaml
Normal file
16
ESXi/resources/01-netcfg.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
eth0:
|
||||
dhcp4: true
|
||||
routes:
|
||||
- to: 192.168.1.0/24
|
||||
via: 192.168.3.1
|
||||
eth1:
|
||||
dhcp4: true
|
||||
gateway4: 192.168.76.1
|
||||
nameservers:
|
||||
addresses: [8.8.8.8,8.8.4.4]
|
||||
eth2:
|
||||
dhcp4: false
|
||||
addresses: [192.168.38.105/24]
|
||||
@@ -1,7 +1,6 @@
|
||||
#
|
||||
# See https://www.terraform.io/intro/getting-started/variables.html for more details.
|
||||
#
|
||||
|
||||
# Change these defaults to fit your needs!
|
||||
|
||||
variable "esxi_hostname" {
|
||||
|
||||
@@ -62,6 +62,12 @@ fix_eth1_static_ip() {
|
||||
echo "[*] Using KVM, no need to fix DHCP for eth1 iface"
|
||||
return 0
|
||||
fi
|
||||
if [ -f /sys/class/net/eth2/address ]; then
|
||||
if [ "$(cat /sys/class/net/eth2/address)" == "00:50:56:a3:b1:c4" ]; then
|
||||
echo "[*] Using ESXi, no need to change anything"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
# 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.
|
||||
echo -e 'interface "eth1" {
|
||||
|
||||
@@ -122,8 +122,7 @@ Invoke-Command -computername dc -Credential (new-object pscredential("windomain\
|
||||
{
|
||||
Write-Host "[$env:computername] ATA Gateway already installed. Moving On."
|
||||
}
|
||||
Write-Host "Sleeping 5 minutes to allow ATA gateway to start up..."
|
||||
Start-Sleep -Seconds 300
|
||||
(Get-Service ATAGateway).WaitForStatus('Running', '00:10:00')
|
||||
If ((Get-Service "ATAGateway").Status -ne "Running")
|
||||
{
|
||||
throw "ATA lightweight gateway not running"
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing Red Team Tooling..."
|
||||
|
||||
# Windows Defender should be disabled already by O&O ShutUp10
|
||||
# Adding Defender exclusions just in case
|
||||
Add-MpPreference -ExclusionPath “C:\Tools”
|
||||
Add-MpPreference -ExclusionPath “C:\Users\vagrant\AppData\Local\Temp”
|
||||
|
||||
# Purpose: Downloads and unzips a copy of the latest Mimikatz trunk
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Determining latest release of Mimikatz..."
|
||||
@@ -48,11 +51,4 @@ if (-not (Test-Path $atomicRedTeamRepoPath)) {
|
||||
Write-Host "Atomic Red Team was already installed. Moving On."
|
||||
}
|
||||
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Configuring Invoke-AtomicTest..."
|
||||
# Copy over a Powershell profile that includes the Atomic Red Team stuff
|
||||
Copy-Item "C:\vagrant\resources\windows\Microsoft.PowerShell_profile.ps1" "C:\Windows\System32\WindowsPowerShell\v1.0" -Force
|
||||
# Install prereqs
|
||||
Install-PackageProvider -Name NuGet -force
|
||||
Install-Module -Name powershell-yaml -Force
|
||||
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Red Team tooling installation complete!"
|
||||
Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Red Team tooling installation complete!"
|
||||
Reference in New Issue
Block a user