惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CERT Recently Published Vulnerability Notes
U
Unit 42
T
The Blog of Author Tim Ferriss
H
Hackread – Cybersecurity News, Data Breaches, AI and More
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Securelist
L
Lohrmann on Cybersecurity
Blog — PlanetScale
Blog — PlanetScale
Recorded Future
Recorded Future
D
DataBreaches.Net
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
I
Intezer
P
Palo Alto Networks Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
I
InfoQ
宝玉的分享
宝玉的分享
Security Latest
Security Latest
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threatpost
Cisco Talos Blog
Cisco Talos Blog
P
Proofpoint News Feed
博客园 - 司徒正美
H
Hacker News: Front Page
Y
Y Combinator Blog
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
NISL@THU
NISL@THU
月光博客
月光博客
有赞技术团队
有赞技术团队
Cloudbric
Cloudbric
酷 壳 – CoolShell
酷 壳 – CoolShell
G
Google Developers Blog
A
Arctic Wolf
博客园 - 【当耐特】
W
WeLiveSecurity
V
Visual Studio Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
V
V2EX
C
Cyber Attacks, Cyber Crime and Cyber Security
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow Blog

Posts on Noah Bailey

How to turn anything into a router Deploy to Cloudfront from GitHub using OpenID Connect Backup Postgres databases with Kubernetes CronJobs The spelling error made 200 billion times a day Restarting Kubernetes pods using a CronJob You've just bought a new domain. Now what? Who Sawed My Motherboard??? Linux on the P8 Aliexpress Mini Laptop Recovering Mysql/Mariadb after a nasty crash Using EXIF data to pick my next lens Converting and developing RAW photos on Linux automatically Thank you, 2016 iPhone Don't Make It Work Self-hosted Surveillance with ZoneMinder Backups, Monitoring, and Security for small Mastodon servers Block web scanners with ipset & iptables Executing commands over SSH with GitHub Actions Debian Sid on encrypted ZFS Protect your dangerously insecure redis server Debian: the luxurious boring lifestyle Monitor radiation with a Raspberry Pi Simple Linux server alerts: Know your performance, errors, security, syslog, and security NUC crashes on debian 11 - How I fixed it Basic Linux server security with fail2ban, ossec, and firewall Windows 11 will create heaps of needless trash Domesticated Kubernetes Networking The Cursed Certificate Our mostly disposable and entirely stupid world Trying out OpenBSD (as a Linux geek) Making VoIP Calls with Antique Rotary Phones Monitoring WAN speed with speedtest-cli and ElasticSearch Monitoring WAN latency with InfluxDB The Zeroshell botnet returns Installing Gentoo on a vintage Thinkpad T60 Malware emails 2: Russian boogaloo TP-Link Device Weirdness ElasticSearch broke all my nice things (a story of cascading failure) A New Botnet is Targeting Network Infrastructure Malware on the Wire: Monitoring Network Traffic with Suricata and ClamAV Cloud Threat Protection with OSSEC and Suricata Malware Emails From Jerks Surviving the Apocalypse with an Offline Wikipedia Server Being Attacked by Bots Linux Router, Firewall and IDS Appliance You Probably Don't Need a VPN Fix an Oversharded Elasticsearch Cluster Automating KVM Virtualization Update all your linux servers as fast as possible Cleanup Systemd Journald Storage Stop Putting Your SSH Keys on Github! Clustering KVM with Ceph Storage Stealing Windows Sessions FreeRadius Active Directory Integration Retrieving WPA2 Keys on Windows Generating MSI transform files with Orca The Inflatable Dinghy Generating Cisco IOS config files with Python Homebrew SAN Getting Cloudy
Deploy MDT Litetouch on Linux with TFTPD and Syslinux
2018-10-04 · via Posts on Noah Bailey

No, I would not like to say hello, Cortana.

Nothing is as monotonous, boring, and brain-numbingly automatable as installing Windows, installing applications, joining a domain, and clicking all the right boxes in all the right places. And it’s even worse in the latest versions of Windows 10, where we’re greeted by the condescending robot voice of Halo’s deceptive antagonist artificial intelligence during the OOBE setup phase.

I’ve taken a particular liking to MDT, Microsoft’s solution to the absolute eye-glazing snorefest of configuring a new workstation or server. Not only does it automatically apply an answer file to get past the distorted screaming of your PC speaker, it gets you past almost all of the setup routine, so you can focus on more important things.

In seriousness, I’m a big fan of automation for a number of reasons. Not only can a tool like this save you time, it can also make sure that every machine you deploy is consistent and compliant with the policies of your organization. Can you really trust a human to go through all the correct steps during setup?

The licensing problem

First off, volume licensing is required to run MDT, or modify images in any way. So don’t do this unless your org is set up correctly.

Next is the issue of server licensing. To do this the ‘right’ way a WDS server would be used to host the PXE boot for MDT litetouch deploys. To me, this doesn’t make a ton of sense. There are plenty of free alternatives that don’t require thousands of dollars in licensing, and more importantly aren’t as cumbersome. If you update MDT boot media with new drivers or directives it requires an RDP session into your WDS server to add the new WIM files to the deployment directory, then removing the old version of the boot media from the server. At its best it’s a simple way to run PXE boot on a fairly static environment, and at its worst it’s a waste of precious Standard licenses and a waste of time managing and patching a Windows server.

Using a Linux server to deploy Windows

If that isn’t sacrilegious, then I don’t know what is.

Fundamentally, what we’re doing is mounting the MDT boot images network share to the TFTP boot directory (readonly of course), configuring a simple PXELINUX loader with memdisk, and configuring our DHCP server to point to this tftp location for boot media.

The first step is to spin up a Ubuntu 18.04 (or whatever your flavour is!) virtual machine, give it a static address, and get it up to date.

Setting it up

Next, the needed packages are installed on the system:

sudo apt install tftpd-hpa pxelinux syslinux cifs-utils 

To mount the cifs share containing the MDT content, best practice is to use a service account with as little access as possible. In this case, we will make sure our service account is denied interactive logon, restricted in its logon types, and only allowed network access to the MDT share. Lately I’ve taken to using randomly generated GUIDs as service account passwords.

$pw = New-Guid
New-ADUser -Name mdtmount -SamAccountName mdtmount -AccountPassword:($pw | Convertto-SecureString -AsPlainText -Force) -CannotChangePassword:$true -ChangePasswordAtLogon:$false

Now, we hop on over to the Linux server and set up the mount point.

In the interest of best practices, we’re using a credential file that only root has access to.

/root/.cifs

username=mdtmount
userdomain=bork.internal
password=aedb8aeb-6073-446d-96dd-aa993b275741

Then the /etc/fstab is set up such that the MDT directory will mount automatically.

//bork.internal/system/deployment/boot /var/lib/tftpboot/pxelinux/boot cifs _netdev,user=mdtsvc,credentials=/root/.cifs 0 0

Note that this is a DFS namespace in the example. Depending on domain level and the features enabled on the share, it may be required to configure some additional Kerberos parameters for it to work reliably.

PXELINUX configuration

First, we move the PXELINUX boot files to the TFTP directory.

cp /usr/lib/PXELINUX/pxelinux.0 /var/lib/tftpboot/pxelinux
cp /usr/lib/syslinux/modules/efi64/[menu.c32 ldlinux.c32 libutil.c32] /var/lib/tftpboot/pxelinux
cp /usr/lib/syslinux/memdisk /var/lib/tftpboot/pxelinux

Second, we create a simple config file to boot into the LiteTouch boot media.


DEFAULT menu.c32

MENU TITLE PXE Boot Menu
MENU AUTOBOOT Starting local system in # seconds

label bootlocal
  MENU LABEL Boot local device
  MENU DEFAULT
  LOCALBOOT 0
TIMEOUT 100
TOTALTIMEOUT 9000

label mdt_litetouch
  menu label [MDT] LiteTouch PE
  KERNEL memdisk
  INITRD boot/LiteTouchPE_x64.iso
  APPEND iso raw

DHCP Server Config

With the files in place, the DHCP server scope options for the Imaging VLAN are set:

Option Description Value
066 TFTP Server 10.1.10.30
067 File Name pxelinux/pxelinux.0

Of course, the standard principles apply for hardening an MDT deployment.

  • File share securables:
    • Remove Authenticated Users read access
    • Add mdt client service accounts with read only access
  • AD securables:
    • Lock down service accounts
    • Delegated access for domain join service account in ‘holding tank’ OU

With that said, we configure the MDT share to generate ISO images (for x64 only) and set up the config files.

Bootstrap.ini

[Settings]
Priority=Default

[Default]
DeployRoot=\\bork.internal\system\deployment
UserDomain=bork.internal
UserID=mdtsvc
UserPassword=288ea175-c7b6-44aa-8aa8-27075142cb7f
SkipBDDWelcome=YES

CustomSettings.ini

[Settings]
Priority=Default
Properties=MyCustomProperty

[Default]
_SMSTSORGNAME=BORK!
OSDComputerName=ws-#right(replace(replace("%SerialNumber%"," ",""),"-",""),10)#
OSInstall=Yes
SkipCapture=YES
SkipAdminPassword=YES
SkipProductKey=YES
SkipComputerBackup=YES
SkipBitLocker=NO
TimeZoneName=Eastern Standard Time 
SkipLocaleSelection=YES
SkipTaskSequence=NO
SkipRoles=NO
SkipRoleDisplay=NO
SkipTimeZone=YES

JoinDomain=bork.internal
DomainAdmin=mdtjoin
DomainAdminDomain=bork.internal
DomainAdminPassword=98600de8-e53e-4576-bf86-2f3c80061ce5
MachineObjectOU=OU=Holding Tank,DC=bork,dc=internal

Using this config file template, our deployments will automatically be named after the service tag, serial number, or UUID, then join the domain inside the ‘Holding Tank’ OU, where an administrator can review the deployment and move the machine object to the correct location within their hierarchy.

Bringing it all together

The process for deploying a new machine will look like this:

  1. Computer boots to UEFI network stack
  2. Computer receives TFTP information from DHCP server
  3. Computer loads PXELINUX boot screen
  4. Technician selects MDT boot from the menu
  5. Computer loads ISO into memdisk before boot:
    • Computer requests ISO file from Linux server
    • Linux server loads ISO file from DFS/File Share
  6. Computer boots into WinPE and uses mdtsvc credentials from the bootstrap config to access the network share directly, and loads configuration settings and task sequence info.
  7. Technician selects a deployment task sequence, either accepting the automatically configured hostname or entering a custom one, and starts the deployment.

A couple coffees later, the deployment is done exactly to the spec with little intervention from either technicians or administrators, and most importantly, Microsoft doesn’t get an extra dime from your tight budget!