Milestone 9: Blue1.local - squatchulator/Tech-Journal GitHub Wiki

Milestone 9: Blue.local

Base Image Creation

  • Firsts steps here are to make two new sysprepped VMs, one with Windows Server Core 2019 and one with Windows 10 LTSC.
    • For the Windows 10 one, leaving things as defaults is fine because it really doesn't need to do much.
    • For the Server Core one, give it a little more juice. MAKE SURE TO THIN PROVISION THESE. Update it and do all that fun stuff first too. You might need to manually set an alternate DNS server to do anything internet-related though.
    • Make sure to install VMWare tools before sysprepping as well. Sysprepping can be done with:
powershell (only need to run this first on Server Core)
# Run in Admin window on Windows 10, and set execution policy
wget https://raw.githubusercontent.com/gmcyber/RangeControl/main/src/scripts/base-vms/windows/windows-prep.ps1 -o windows-prep.ps1
Unblock-File windows-prep.ps1
./windows-prep.ps1
  • To get VMWare tools on Server Core, mount it and run:
D:\setup.exe /v "/qn REBOOT=R"
  • Take snapshots named "Base" as well for both.

Creating the new Domain Controller

  • Once this is all done (and it will take a long time), run your 480-utils to make a linked clone of the Server Core base image named dc-blue1. This is gonna be our domain controller for Blue!
  • Also start the VM up using your script once it's made.
  • Add a new function to the script called Set-StaticIP which will do exactly what you think it'll do. We want to set our DC's IP to be static (10.0.5.5). The new function can look something like this:
function Set-StaticIP {
    param(
        [string] $vmName
    )

    $password = Read-Host "Passowrd for deployer user: " -AsSecureString
    $ipAddress = Read-Host "Enter the IP address"
    $subnetMask = Read-Host "Enter the subnet mask"
    $dnsPrimary = Read-Host "Enter the primary DNS server"
    $dnsAlternate = Read-Host "Enter the alternate DNS server"
    $gateway = Read-Host "Enter the default gateway"

    # Got some help from David on this one, apparently WSMan is required for this and we didn't have access to those libraries.
    # At this point, after figuring out the basic auth issue later on, I could probably replace this with the solution in
    # the lab, but this works well so I am going to leave it as it doesn't require additional configuration. 
    # A working solution he showed me is to use the Invoke-VMScript function rather than Invoke-Command to pass commands.
    $setAddr = "netsh interface ipv4 set address Ethernet0 static $ipAddress $subnetMask $gateway"
    $setDnsP = "netsh interface ipv4 add dnsserver Ethernet0 address=$dnsPrimary index=1"
    $setDnsA = "netsh interface ipv4 add dnsserver Ethernet0 address=$dnsAlternate index=2"

    
    Invoke-VMScript -ScriptText $setAddr -VM $vmName -GuestUser deployer -GuestPassword $password
    Invoke-VMScript -ScriptText $setDnsP -VM $vmName -GuestUser deployer -GuestPassword $password
    Invoke-VMScript -ScriptText $setDnsA -VM $vmName -GuestUser deployer -GuestPassword $password
}
  • It will set the default gatway, the subnet mask, and the appropriate DNS server for this VM.

Domain Provisioning with Ansible

  • Some actions first need to be run on the Windows server in order to get the playbook running. Thanks to this forum post, I was able to diagnose an issue in which WinRM would refuse authentication if unless it was encrypted. To allow Ansible WinRM basic authentication, run the following in Powershell on DC-blue1:
Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $true
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
Set-ExecutionPolicy Unrestricted
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
  • Now, we need to create some new Ansible files. Name them windows.yml (our inventory file), and blue-provision.yml. Place them in the appropriate folders as shown in the directory structure below:

image

  • Contents of blue-provision.yml:
---
- name: windows server provisioning
  hosts: servers
  vars_prompt:
    - name: ansible_dc_password
      prompt: "Enter local admin password"
      private: yes

  tasks:
    - name: change admin user password
      ansible.windows.win_shell: |
        net user Administrator "{{ ansible_dc_password }}"

    - name: set new hostname
      ansible.windows.win_hostname:
        name: dc-blue1

    - name: create blue.local domain
      ansible.windows.win_domain:
        hostname: dc-blue1
        domain_name: blue.local
        dns_domain_name: blue.local
        safe_mode_password: "{{ ansible_dc_password }}"
        
    - name: force reboot
      ansible.windows.win_reboot:
        reboot_timeout: 600

    - name: add dns forwarder
      ansible.windows.win_shell: Add-DnsServerForwarder -IPAddress 1.1.1.1

    - name: promote to domain controller
      ansible.windows.win_domain_controller:
        dns_domain_name: blue.local
        domain_log_path: 'C:\\Windows\\NTDS'
        domain_admin_password: "{{ ansible_dc_password }}"
        safe_mode_password: "{{ ansible_dc_password }}"
        domain_admin_user: blue.local\\Administrator
        local_admin_password: "{{ ansible_dc_password }}"
        sysvol_path: 'C:\\Windows\\SYSVOL'
        install_dns: yes
        state: domain_controller
        read_only: no
        site_name: Default-First-Site-Name

    - name: build ou structure
      ansible.windows.win_shell: |
        New-ADOrganizationalUnit -Name "Accounts" -Path "DC=BLUE,DC=local"
        New-ADOrganizationalUnit -Name "Groups" -Path "DC=BLUE,DC=local"
        New-ADOrganizationalUnit -Name "Computers" -Path "DC=BLUE,DC=local"
        New-ADOrganizationalUnit -Name "Servers" -Path "DC=BLUE,DC=local"
        New-ADOrganizationalUnit -Name "Workstations" -Path "DC=BLUE,DC=local"
        New-ADOrganizationalUnit -Name "Blue" -Path "DC=BLUE,DC=local"

    - name: force reboot
      ansible.windows.win_reboot:
        reboot_timeout: 600

  • Contents of windows.yml:
all:
  children:
    servers:
      hosts:
        dc-blue1:
          ansible_user: Administrator
          ansible_password: "{{ ansible_dc_password }}"
          ansible_connection: winrm
          ansible_host: 10.0.5.5
          ansible_winrm_transport: basic
          ansible_winrm_port: 5985
          ansible_winrm_server_cert_validation: ignore

  • Once all this setup is completed and the static network information is confirmed to be set, run the playbook using the following:
ansible-playbook -i ansible/inventory/windows.yml --ask-pass ansible/blue-provision.yml -K
  • It will reboot a few times and will take a while, but at the end you should be able to SSH into [email protected]@10.0.5.5 and perform the associated check commands!