Merge pull request #650 from clong/move_exchange_stuff

Move Exchange to AddOns Folder
This commit is contained in:
Chris Long
2021-05-13 19:08:18 -07:00
committed by GitHub
27 changed files with 274 additions and 233 deletions

View File

@@ -8,7 +8,7 @@ jobs:
- run:
name: Download and Install Terraform
command: |
wget -O terraform.zip https://releases.hashicorp.com/terraform/0.12.2/terraform_0.12.2_linux_amd64.zip
wget -O terraform.zip https://releases.hashicorp.com/terraform/0.13.5/terraform_0.13.5_linux_amd64.zip
unzip terraform.zip
sudo mv terraform /usr/local/bin/terraform

4
.gitignore vendored
View File

@@ -8,8 +8,10 @@ Boxes/*
*.tfstate
*.tfstate.*
*.tfvars
inventory.yml
ESXi/Ansible/inventory.yml
Azure/Ansible/inventory.yml
inventory.yml.bak
inventory.yml
*.box
manifest.xml
HyperV/.vagrant/*

View File

@@ -12,7 +12,6 @@ win10:
hosts:
z.z.z.z:
#exchange:
# hosts:
# w.w.w.w:
exchange:
hosts:
# v.v.v.v:

View File

@@ -53,12 +53,14 @@
post_reboot_delay: 60
- name: Install Exchange Prereqs
win_shell: .\\install-exchange.ps1
win_command: powershell.exe .\\install-exchange.ps1
args:
chdir: 'c:\vagrant\scripts'
register: exchange_prereqs
changed_when: "'A reboot is required to continue installation of exchange.' in exchange_prereqs.stdout"
- debug: msg="{{ exchange_prereqs.stdout_lines }}"
- name: Reboot After Installing Exchange PreReqs
win_reboot:
msg: "Exchange Prereqs installed. Rebooting..."

View File

@@ -0,0 +1,10 @@
## Remove the block comment to enable the creation of the Exchange server
/*
module "exchange" {
source = "./modules/exchange"
resource_group_name = azurerm_resource_group.detectionlab.name
region = var.region
subnet_id = azurerm_subnet.detectionlab-subnet.id
}
*/

View File

@@ -4,5 +4,4 @@ locals {
ata_url = "https://${azurerm_public_ip.wef-publicip.ip_address}"
guacamole_url = "http://${azurerm_public_ip.logger-publicip.ip_address}:8080/guacamole"
velociraptor_url = "https://${azurerm_public_ip.logger-publicip.ip_address}:9999"
exchange_url = "https://${var.create_exchange_server ? azurerm_public_ip.exchange-publicip[0].ip_address : ""}"
}

View File

@@ -366,33 +366,6 @@ resource "azurerm_public_ip" "win10-publicip" {
}
}
resource "azurerm_network_interface" "exchange-nic" {
count = var.create_exchange_server ? 1 : 0
name = "exchange-nic"
location = var.region
resource_group_name = azurerm_resource_group.detectionlab.name
ip_configuration {
name = "myNicConfiguration"
subnet_id = azurerm_subnet.detectionlab-subnet.id
private_ip_address_allocation = "Static"
private_ip_address = "192.168.38.106"
public_ip_address_id = azurerm_public_ip.exchange-publicip[count.index].id
}
}
resource "azurerm_public_ip" "exchange-publicip" {
count = var.create_exchange_server ? 1 : 0
name = "exchange-public-ip"
location = var.region
resource_group_name = azurerm_resource_group.detectionlab.name
allocation_method = "Static"
tags = {
role = "exchange"
}
}
resource "azurerm_virtual_machine" "dc" {
name = "dc.windomain.local"
location = var.region
@@ -506,64 +479,6 @@ resource "azurerm_virtual_machine" "wef" {
}
}
resource "azurerm_virtual_machine" "exchange" {
count = var.create_exchange_server ? 1 : 0
name = "exchange.windomain.local"
location = var.region
resource_group_name = azurerm_resource_group.detectionlab.name
network_interface_ids = [azurerm_network_interface.exchange-nic[count.index].id]
vm_size = "Standard_D3_v2"
delete_os_disk_on_termination = true
storage_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2016-Datacenter"
version = "latest"
}
os_profile {
computer_name = "exchange"
admin_username = "vagrant"
admin_password = "Vagrant123"
custom_data = local.custom_data_content
}
os_profile_windows_config {
provision_vm_agent = true
enable_automatic_upgrades = false
# Auto-Login's required to configure WinRM
additional_unattend_config {
pass = "oobeSystem"
component = "Microsoft-Windows-Shell-Setup"
setting_name = "AutoLogon"
content = "<AutoLogon><Password><Value>Vagrant123</Value></Password><Enabled>true</Enabled><LogonCount>1</LogonCount><Username>vagrant</Username></AutoLogon>"
}
# Unattend config is to enable basic auth in WinRM, required for the provisioner stage.
# https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/examples/virtual-machines/provisioners/windows/files/FirstLogonCommands.xml
additional_unattend_config {
pass = "oobeSystem"
component = "Microsoft-Windows-Shell-Setup"
setting_name = "FirstLogonCommands"
content = file("${path.module}/files/FirstLogonCommands.xml")
}
}
storage_os_disk {
name = "OsDiskExchange"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
tags = {
role = "exchange"
}
}
resource "azurerm_virtual_machine" "win10" {
name = "win10.windomain.local"
location = var.region

View File

@@ -0,0 +1,3 @@
locals {
exchange_url = "https://${azurerm_public_ip.exchange-publicip.ip_address}"
}

View File

@@ -0,0 +1,91 @@
# https://github.com/terraform-providers/terraform-provider-azurerm/blob/1940d84dba45e41b2f1f868a22d7f7af1adea8a0/examples/virtual-machines/virtual_machine/vm-joined-to-active-directory/modules/active-directory/2-virtual-machine.tf
locals {
custom_data_content = file("${path.module}/../../files/winrm.ps1")
}
provider "azurerm" {
version = "=2.12.0"
features {}
}
resource "azurerm_virtual_machine" "exchange" {
name = "exchange.windomain.local"
location = var.region
resource_group_name = var.resource_group_name
network_interface_ids = [azurerm_network_interface.exchange-nic.id]
vm_size = "Standard_D3_v2"
delete_os_disk_on_termination = true
storage_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2016-Datacenter"
version = "latest"
}
os_profile {
computer_name = "exchange"
admin_username = "vagrant"
admin_password = "Vagrant123"
custom_data = local.custom_data_content
}
os_profile_windows_config {
provision_vm_agent = true
enable_automatic_upgrades = false
# Auto-Login's required to configure WinRM
additional_unattend_config {
pass = "oobeSystem"
component = "Microsoft-Windows-Shell-Setup"
setting_name = "AutoLogon"
content = "<AutoLogon><Password><Value>Vagrant123</Value></Password><Enabled>true</Enabled><LogonCount>1</LogonCount><Username>vagrant</Username></AutoLogon>"
}
# Unattend config is to enable basic auth in WinRM, required for the provisioner stage.
# https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/examples/virtual-machines/provisioners/windows/files/FirstLogonCommands.xml
additional_unattend_config {
pass = "oobeSystem"
component = "Microsoft-Windows-Shell-Setup"
setting_name = "FirstLogonCommands"
content = file("${path.module}/../../files/FirstLogonCommands.xml")
}
}
storage_os_disk {
name = "OsDiskExchange"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
tags = {
role = "exchange"
}
}
resource "azurerm_network_interface" "exchange-nic" {
name = "exchange-nic"
location = var.region
resource_group_name = var.resource_group_name
ip_configuration {
name = "myNicConfiguration"
subnet_id = var.subnet_id
private_ip_address_allocation = "Static"
private_ip_address = "192.168.38.106"
public_ip_address_id = azurerm_public_ip.exchange-publicip.id
}
}
resource "azurerm_public_ip" "exchange-publicip" {
name = "exchange-public-ip"
location = var.region
resource_group_name = var.resource_group_name
allocation_method = "Static"
tags = {
role = "exchange"
}
}

View File

@@ -0,0 +1,7 @@
output "exchange_public_ip" {
value = azurerm_public_ip.exchange-publicip
}
output "exchange_url" {
value = local.exchange_url
}

View File

@@ -0,0 +1,11 @@
variable "resource_group_name" {
type = string
}
variable "region" {
type = string
}
variable "subnet_id" {
type = string
}

View File

@@ -18,10 +18,6 @@ output "win10_public_ip" {
value = azurerm_public_ip.win10-publicip.ip_address
}
output "exchange_public_ip" {
value = "${var.create_exchange_server ? azurerm_public_ip.exchange-publicip[0].ip_address : null}"
}
output "ata_url" {
value = local.ata_url
}
@@ -41,7 +37,3 @@ output "guacamole_url" {
output "velociraptor_url" {
value = local.velociraptor_url
}
output "exchange_url" {
value = "${var.create_exchange_server ? local.exchange_url : null}"
}

View File

@@ -39,10 +39,4 @@ variable "external_dns_servers" {
description = "Configure lab to allow external DNS resolution"
type = list(string)
default = ["8.8.8.8"]
}
variable "create_exchange_server" {
description = "If set to true, adds an additional host that installs exchange"
type = bool
default = false
}

View File

@@ -1,3 +1,9 @@
terraform {
required_version = ">= 0.12, < 15.0.0"
required_providers {
azurerm = {
version = "=2.12.0"
}
}
}

View File

@@ -23,10 +23,8 @@ TF_OUTPUT=$(terraform output)
DC_IP=$(echo "$TF_OUTPUT" | grep -E -o "dc_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
WEF_IP=$(echo "$TF_OUTPUT" | grep -E -o "wef_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
EXCHANGE_IP=$(echo "$TF_OUTPUT" | grep -E -o "exchange_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
WIN10_IP=$(echo "$TF_OUTPUT" | grep -E -o "win10_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
# Code needs to be added for exchange
EXCHANGE_IP=$(echo "$TF_OUTPUT" | grep -E -o "exchange_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
# Don't update unless there's default values in inventory.yml
GREP_COUNT=$(grep -E -c 'x\.x\.x\.x|y\.y\.y\.y|z\.z\.z\.z' ../Ansible/inventory.yml)
@@ -40,9 +38,9 @@ fi
echo "Replacing the default values in DetectionLab/Azure/Ansible/inventory.yml..."
sed -i.bak "s/x.x.x.x/$DC_IP/g; s/y.y.y.y/$WEF_IP/g; s/z.z.z.z/$WIN10_IP/g" ../Ansible/inventory.yml
if [ ! -z $EXCHANGE_IP ]; then
echo "Found Exchange IP address in Terraform output. Adding to inventory."
sed -i.bak "s/#exchange:/exchange:/g; s/# hosts:/ hosts:/g; s/# w.w.w.w/ $EXCHANGE_IP/g" ../Ansible/inventory.yml
if [ ! -e "$EXCHANGE_IP" ]; then
echo "Exchange server found! Adding the IP to the Ansible inventory..."
sed -i.bak "s/# v.v.v.v/$EXCHANGE_IP/g" ../Ansible/inventory.yml
fi
echo "Displaying the updated inventory.yml below!"

View File

@@ -16,14 +16,16 @@
- common
tags: wef
- hosts: exchange
roles:
- exchange
- common
tags: exchange
- hosts: win10
roles:
- win10
- common
tags: win10
- hosts: exchange
roles:
- exchange
- common
tags: exchange

View File

@@ -2,7 +2,7 @@
logger:
hosts:
192.168.3.205:
w.w.w.w:
ansible_user: vagrant
ansible_password: vagrant
ansible_port: 22
@@ -21,6 +21,4 @@ win10:
hosts:
z.z.z.z:
#exchange:
# hosts:
# w.w.w.w:

9
ESXi/exchange.tf Normal file
View File

@@ -0,0 +1,9 @@
## Remove the block comment to enable the creation of the Exchange server
/*
module "exchange" {
source = "./modules/exchange"
disk_store = var.esxi_datastore
vm_network = var.vm_network
hostonly_network = var.hostonly_network
}
*/

View File

@@ -121,36 +121,6 @@ resource "esxi_guest" "wef" {
guest_shutdown_timeout = 30
}
resource "esxi_guest" "exchange" {
# See https://blog.gruntwork.io/terraform-tips-tricks-loops-if-statements-and-gotchas-f739bbae55f9#0223 for explanation about count
count = var.create_exchange_server ? 1 : 0
guest_name = "exchange"
disk_store = var.esxi_datastore
guestos = "windows9srv-64"
boot_disk_type = "thin"
memsize = "8192"
numvcpus = "4"
resource_pool_name = "/"
power = "on"
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:c5"
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:c5"
nic_type = "e1000"
}
guest_startup_timeout = 45
guest_shutdown_timeout = 30
}
resource "esxi_guest" "win10" {
guest_name = "win10"
disk_store = var.esxi_datastore

View File

@@ -0,0 +1,37 @@
terraform {
required_version = ">= 0.13"
required_providers {
esxi = {
source = "josenk/esxi"
version = "1.8.0"
}
}
}
resource "esxi_guest" "exchange" {
guest_name = "exchange"
disk_store = var.disk_store
guestos = "windows9srv-64"
boot_disk_type = "thin"
memsize = "8192"
numvcpus = "4"
resource_pool_name = "/"
power = "on"
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:c5"
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:c5"
nic_type = "e1000"
}
guest_startup_timeout = 45
guest_shutdown_timeout = 30
}

View File

@@ -0,0 +1,7 @@
output "exchange_interfaces" {
value = esxi_guest.exchange.network_interfaces
}
output "exchange_ips" {
value = esxi_guest.exchange.ip_address
}

View File

@@ -0,0 +1,11 @@
variable "vm_network" {
default = "VM Network"
}
variable "hostonly_network" {
default = "HostOnly Network"
}
variable "disk_store" {
type = string
}

View File

@@ -22,14 +22,6 @@ output "wef_ips" {
value = esxi_guest.wef.ip_address
}
output "exchange_interfaces" {
value = esxi_guest.exchange[0].network_interfaces
}
output "exchange_ips" {
value = "${var.create_exchange_server ? esxi_guest.exchange[0].ip_address : null}"
}
output "win10_interfaces" {
value = esxi_guest.win10.network_interfaces
}

View File

@@ -30,9 +30,3 @@ variable "vm_network" {
variable "hostonly_network" {
default = "HostOnly Network"
}
variable "create_exchange_server" {
description = "If set to true, adds an additional host that installs exchange"
type = bool
default = false
}

59
Vagrant/Exchange/Vagrantfile vendored Normal file
View File

@@ -0,0 +1,59 @@
config.vm.define "exchange" do |cfg|
cfg.vm.box = "detectionlab/win2016"
cfg.vm.hostname = "exchange"
cfg.vm.boot_timeout = 600
cfg.vm.communicator = "winrm"
cfg.winrm.basic_auth_only = true
cfg.winrm.timeout = 300
cfg.winrm.retry_limit = 20
cfg.vm.network :private_network, ip: "192.168.38.106", gateway: "192.168.38.1", dns: "192.168.38.102"
cfg.vm.provision "shell", path: "../scripts/fix-second-network.ps1", privileged: true, args: "-ip 192.168.38.106 -dns 8.8.8.8 -gateway 192.168.38.1"
cfg.vm.provision "shell", path: "../scripts/provision.ps1", privileged: false
cfg.vm.provision "reload"
cfg.vm.provision "shell", path: "../scripts/provision.ps1", privileged: false
cfg.vm.provision "shell", path: "../scripts/download_palantir_wef.ps1", privileged: false
cfg.vm.provision "shell", inline: 'wevtutil el | Select-String -notmatch "Microsoft-Windows-LiveId" | Foreach-Object {wevtutil cl "$_"}', privileged: false
cfg.vm.provision "shell", path: "../scripts/install-splunkuf.ps1", privileged: false
cfg.vm.provision "shell", path: "../scripts/install-windows_ta.ps1", privileged: false
cfg.vm.provision "shell", path: "../scripts/install-utilities.ps1", privileged: false
cfg.vm.provision "shell", path: "../scripts/install-redteam.ps1", privileged: false
cfg.vm.provision "shell", path: "../scripts/install-choco-extras.ps1", privileged: false
cfg.vm.provision "shell", path: "../scripts/install-osquery.ps1", privileged: false
cfg.vm.provision "shell", path: "../scripts/install-sysinternals.ps1", privileged: false
cfg.vm.provision "shell", path: "../scripts/install-velociraptor.ps1", privileged: false
cfg.vm.provision "shell", inline: "Set-SmbServerConfiguration -AuditSmb1Access $true -Force", privileged: false
cfg.vm.provision "shell", inline: 'cscript c:\windows\system32\slmgr.vbs /dlv', privileged: false
cfg.vm.provider "vmware_desktop" do |v, override|
v.vmx["displayname"] = "exchange.windomain.local"
v.memory = 8192
v.cpus = 4
v.gui = true
v.enable_vmrun_ip_lookup = false
end
cfg.vm.provider "virtualbox" do |vb, override|
vb.gui = true
vb.name = "exchange.windomain.local"
vb.default_nic_type = "82545EM"
vb.customize ["modifyvm", :id, "--memory", 8192]
vb.customize ["modifyvm", :id, "--cpus", 4]
vb.customize ["modifyvm", :id, "--vram", "32"]
vb.customize ["modifyvm", :id, "--clipboard", "bidirectional"]
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["setextradata", "global", "GUI/SuppressMessages", "all" ]
end
cfg.vm.provider "libvirt" do |lv, override|
lv.graphics_type = "spice"
lv.video_type = "qxl"
lv.input :type => "tablet", :bus => "usb"
override.vm.box = "../Boxes/windows_2016_libvirt.box"
lv.video_vram = 32768
lv.memory = 8192
lv.cpus = 4
override.vm.synced_folder '.', '/', type: 'winrm'
end
end
end

63
Vagrant/Vagrantfile vendored
View File

@@ -1,5 +1,3 @@
build_exchange = false
Vagrant.configure("2") do |config|
config.vm.define "logger" do |cfg|
@@ -182,67 +180,6 @@ Vagrant.configure("2") do |config|
end
end
if build_exchange
config.vm.define "exchange" do |cfg|
cfg.vm.box = "detectionlab/win2016"
cfg.vm.hostname = "exchange"
cfg.vm.boot_timeout = 600
cfg.vm.communicator = "winrm"
cfg.winrm.basic_auth_only = true
cfg.winrm.timeout = 300
cfg.winrm.retry_limit = 20
cfg.vm.network :private_network, ip: "192.168.38.106", gateway: "192.168.38.1", dns: "192.168.38.102"
cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: true, args: "-ip 192.168.38.106 -dns 8.8.8.8 -gateway 192.168.38.1"
cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false
cfg.vm.provision "reload"
cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false
cfg.vm.provision "shell", path: "scripts/download_palantir_wef.ps1", privileged: false
cfg.vm.provision "shell", inline: 'wevtutil el | Select-String -notmatch "Microsoft-Windows-LiveId" | Foreach-Object {wevtutil cl "$_"}', privileged: false
cfg.vm.provision "shell", path: "scripts/install-splunkuf.ps1", privileged: false
cfg.vm.provision "shell", path: "scripts/install-windows_ta.ps1", privileged: false
cfg.vm.provision "shell", path: "scripts/install-utilities.ps1", privileged: false
cfg.vm.provision "shell", path: "scripts/install-redteam.ps1", privileged: false
cfg.vm.provision "shell", path: "scripts/install-choco-extras.ps1", privileged: false
cfg.vm.provision "shell", path: "scripts/install-osquery.ps1", privileged: false
cfg.vm.provision "shell", path: "scripts/install-sysinternals.ps1", privileged: false
cfg.vm.provision "shell", path: "scripts/install-velociraptor.ps1", privileged: false
cfg.vm.provision "shell", inline: "Set-SmbServerConfiguration -AuditSmb1Access $true -Force", privileged: false
cfg.vm.provision "shell", inline: 'cscript c:\windows\system32\slmgr.vbs /dlv', privileged: false
cfg.vm.provider "vmware_desktop" do |v, override|
v.vmx["displayname"] = "exchange.windomain.local"
v.memory = 8192
v.cpus = 4
v.gui = true
v.enable_vmrun_ip_lookup = false
end
cfg.vm.provider "virtualbox" do |vb, override|
vb.gui = true
vb.name = "exchange.windomain.local"
vb.default_nic_type = "82545EM"
vb.customize ["modifyvm", :id, "--memory", 8192]
vb.customize ["modifyvm", :id, "--cpus", 4]
vb.customize ["modifyvm", :id, "--vram", "32"]
vb.customize ["modifyvm", :id, "--clipboard", "bidirectional"]
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["setextradata", "global", "GUI/SuppressMessages", "all" ]
end
cfg.vm.provider "libvirt" do |lv, override|
lv.graphics_type = "spice"
lv.video_type = "qxl"
lv.input :type => "tablet", :bus => "usb"
override.vm.box = "../Boxes/windows_2016_libvirt.box"
lv.video_vram = 32768
lv.memory = 8192
lv.cpus = 4
override.vm.synced_folder '.', '/', type: 'winrm'
end
end
end
config.vm.define "win10" do |cfg|
cfg.vm.box = "detectionlab/win10"
cfg.vm.hostname = "win10"

View File

@@ -31,10 +31,6 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) [+] Failure to reboot will cause the
# Warn the user if less than 8GB of memory
If ($physicalMemory -lt 8000000000) {
Write-Host "It is STRONGLY recommended that you provide this host with 8GB+ of memory before continuing or it is highly likely that it will run out of memory while installing Exchange."
$ignore = Read-Host "Type 'ignore' to continue anyways, otherwise this script will exit."
If ($ignore -ne "ignore") {
Write-Host "Exiting."
}
}
# Gotta temporarily re-enable these services