TEAP Configuration for Home Users
Overview
TEAP (Tunnel Extensible Authentication Protocol, RFC 7170) provides secure 802.1X authentication with support for EAP chaining. This guide configures TEAP programmatically using PowerShell for Windows home users without domain membership.
Why TEAP?
| Feature | PEAP | TEAP |
|---|---|---|
Inner Methods |
EAP-MSCHAPv2, EAP-TLS |
EAP-MSCHAPv2, EAP-TLS, EAP chaining |
EAP Chaining |
No |
Yes (machine + user auth) |
Cryptobinding |
Optional |
Required |
Windows Support |
All versions |
Windows 10 1903+ |
RFC |
Draft (never finalized) |
RFC 7170 |
Prerequisites
-
Windows 10 version 1903 or later
-
DOMUS-ROOT-CA certificate in Trusted Root store
-
Client certificate (for EAP-TLS inner method)
-
Administrative PowerShell
Automated Configuration Script
Create and run this PowerShell script as Administrator.
Full Script: Configure-TEAP.ps1
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Configures TEAP 802.1X authentication for wired network.
.DESCRIPTION
Programmatically configures Windows for TEAP authentication without GPO.
Supports both EAP-TLS (certificate) and EAP-MSCHAPv2 (password) inner methods.
.PARAMETER InnerMethod
Inner authentication method: EapTls or EapMsChapV2
.PARAMETER NetworkProfileName
Name for the wired network profile
.EXAMPLE
.\Configure-TEAP.ps1 -InnerMethod EapTls
#>
param(
[ValidateSet("EapTls", "EapMsChapV2")]
[string]$InnerMethod = "EapTls",
[string]$NetworkProfileName = "Domus-Secure-TEAP"
)
# Enable Wired AutoConfig service
Write-Host "[1/5] Enabling Wired AutoConfig service..." -ForegroundColor Cyan
Set-Service -Name dot3svc -StartupType Automatic
Start-Service -Name dot3svc
# Generate TEAP profile XML based on inner method
Write-Host "[2/5] Generating TEAP profile XML (Inner: $InnerMethod)..." -ForegroundColor Cyan
if ($InnerMethod -eq "EapTls") {
# TEAP with EAP-TLS inner (certificate-based)
$eapConfig = @"
<?xml version="1.0"?>
<EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
<EapMethod>
<Type xmlns="http://www.microsoft.com/provisioning/EapCommon">55</Type>
<VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId>
<VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType>
<AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId>
</EapMethod>
<Config xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
<Eap xmlns="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1">
<Type>55</Type>
<TeapConfig xmlns="http://www.microsoft.com/provisioning/TeapConnectionPropertiesV1">
<ServerValidation>
<DisableUserPromptForServerValidation>true</DisableUserPromptForServerValidation>
<ServerNames></ServerNames>
<TrustedRootCA>REPLACE_WITH_ROOT_CA_THUMBPRINT</TrustedRootCA>
</ServerValidation>
<Phase2Authentication>
<InnerMethodConfig>
<EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
<EapMethod>
<Type xmlns="http://www.microsoft.com/provisioning/EapCommon">13</Type>
<VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId>
<VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType>
<AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId>
</EapMethod>
<Config xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
<Eap xmlns="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1">
<Type>13</Type>
<EapType xmlns="http://www.microsoft.com/provisioning/EapTlsConnectionPropertiesV1">
<CredentialsSource>
<CertificateStore>
<SimpleCertSelection>true</SimpleCertSelection>
</CertificateStore>
</CredentialsSource>
<ServerValidation>
<DisableUserPromptForServerValidation>true</DisableUserPromptForServerValidation>
<ServerNames></ServerNames>
<TrustedRootCA>REPLACE_WITH_ROOT_CA_THUMBPRINT</TrustedRootCA>
</ServerValidation>
<DifferentUsername>false</DifferentUsername>
<PerformServerValidation xmlns="http://www.microsoft.com/provisioning/EapTlsConnectionPropertiesV2">true</PerformServerValidation>
<AcceptServerName xmlns="http://www.microsoft.com/provisioning/EapTlsConnectionPropertiesV2">false</AcceptServerName>
</EapType>
</Eap>
</Config>
</EapHostConfig>
</InnerMethodConfig>
</Phase2Authentication>
<EnableQuarantineChecks>false</EnableQuarantineChecks>
<RequireCryptoBinding>true</RequireCryptoBinding>
</TeapConfig>
</Eap>
</Config>
</EapHostConfig>
"@
} else {
# TEAP with EAP-MSCHAPv2 inner (password-based)
$eapConfig = @"
<?xml version="1.0"?>
<EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
<EapMethod>
<Type xmlns="http://www.microsoft.com/provisioning/EapCommon">55</Type>
<VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId>
<VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType>
<AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId>
</EapMethod>
<Config xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
<Eap xmlns="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1">
<Type>55</Type>
<TeapConfig xmlns="http://www.microsoft.com/provisioning/TeapConnectionPropertiesV1">
<ServerValidation>
<DisableUserPromptForServerValidation>true</DisableUserPromptForServerValidation>
<ServerNames></ServerNames>
<TrustedRootCA>REPLACE_WITH_ROOT_CA_THUMBPRINT</TrustedRootCA>
</ServerValidation>
<Phase2Authentication>
<InnerMethodConfig>
<EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
<EapMethod>
<Type xmlns="http://www.microsoft.com/provisioning/EapCommon">26</Type>
<VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId>
<VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType>
<AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId>
</EapMethod>
<Config xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
<Eap xmlns="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1">
<Type>26</Type>
<EapType xmlns="http://www.microsoft.com/provisioning/MsChapV2ConnectionPropertiesV1">
<UseWinLogonCredentials>false</UseWinLogonCredentials>
</EapType>
</Eap>
</Config>
</EapHostConfig>
</InnerMethodConfig>
</Phase2Authentication>
<EnableQuarantineChecks>false</EnableQuarantineChecks>
<RequireCryptoBinding>true</RequireCryptoBinding>
</TeapConfig>
</Eap>
</Config>
</EapHostConfig>
"@
}
# Find DOMUS-ROOT-CA thumbprint
Write-Host "[3/5] Locating DOMUS-ROOT-CA certificate..." -ForegroundColor Cyan
$rootCA = Get-ChildItem -Path Cert:\LocalMachine\Root | Where-Object { $_.Subject -like "*DOMUS-ROOT-CA*" }
if (-not $rootCA) {
Write-Error "DOMUS-ROOT-CA not found in Trusted Root store. Import it first."
exit 1
}
$thumbprint = $rootCA.Thumbprint
Write-Host " Found: $($rootCA.Subject)" -ForegroundColor Green
Write-Host " Thumbprint: $thumbprint" -ForegroundColor Green
# Replace placeholder with actual thumbprint
$eapConfig = $eapConfig -replace "REPLACE_WITH_ROOT_CA_THUMBPRINT", $thumbprint
# Create wired profile XML
Write-Host "[4/5] Creating wired network profile..." -ForegroundColor Cyan
$profileXml = @"
<?xml version="1.0"?>
<LANProfile xmlns="http://www.microsoft.com/networking/LAN/profile/v1">
<MSM>
<security>
<OneXEnforced>false</OneXEnforced>
<OneXEnabled>true</OneXEnabled>
<OneX xmlns="http://www.microsoft.com/networking/OneX/v1">
<cacheUserData>true</cacheUserData>
<authMode>machineOrUser</authMode>
<EAPConfig>
$eapConfig
</EAPConfig>
</OneX>
</security>
</MSM>
</LANProfile>
"@
# Save profile to temp file
$profilePath = "$env:TEMP\$NetworkProfileName.xml"
$profileXml | Out-File -FilePath $profilePath -Encoding UTF8
# Apply profile using netsh
Write-Host "[5/5] Applying profile via netsh..." -ForegroundColor Cyan
# Get the wired interface name
$wiredInterface = Get-NetAdapter | Where-Object { $_.PhysicalMediaType -eq "802.3" -and $_.Status -eq "Up" } | Select-Object -First 1
if (-not $wiredInterface) {
$wiredInterface = Get-NetAdapter | Where-Object { $_.PhysicalMediaType -eq "802.3" } | Select-Object -First 1
}
if (-not $wiredInterface) {
Write-Warning "No wired interface found. Profile saved to: $profilePath"
Write-Host "Apply manually: netsh lan add profile filename=`"$profilePath`" interface=`"YOUR_INTERFACE`""
exit 0
}
$interfaceName = $wiredInterface.Name
Write-Host " Interface: $interfaceName" -ForegroundColor Green
# Apply the profile
netsh lan add profile filename="$profilePath" interface="$interfaceName"
if ($LASTEXITCODE -eq 0) {
Write-Host "`nTEAP configuration complete!" -ForegroundColor Green
Write-Host "Profile: $NetworkProfileName"
Write-Host "Interface: $interfaceName"
Write-Host "Inner Method: $InnerMethod"
} else {
Write-Error "Failed to apply profile. Exit code: $LASTEXITCODE"
Write-Host "Profile saved to: $profilePath"
}
# Cleanup temp file
Remove-Item -Path $profilePath -Force -ErrorAction SilentlyContinue
# Verify configuration
Write-Host "`n=== Verification ===" -ForegroundColor Yellow
netsh lan show profiles interface="$interfaceName"
Manual Verification
# Check Wired AutoConfig service
Get-Service dot3svc | Format-List Name, Status, StartType
# List wired profiles
netsh lan show profiles
# Show profile details
netsh lan show profiles interface="Ethernet"
# Check authentication state
netsh lan show interfaces
Troubleshooting
View Authentication Events
# Wired AutoConfig events
Get-WinEvent -LogName "Microsoft-Windows-Wired-AutoConfig/Operational" -MaxEvents 20 |
Format-Table TimeCreated, Id, Message -Wrap
# EAP events
Get-WinEvent -LogName "Microsoft-Windows-EapHost/Operational" -MaxEvents 20 |
Format-Table TimeCreated, Id, Message -Wrap
Remove TEAP Profile
# List profiles
netsh lan show profiles
# Remove specific profile
netsh lan delete profile interface="Ethernet"
Verify Certificates
Check Client Certificate
# List certificates in Personal store
Get-ChildItem Cert:\LocalMachine\My | Format-Table Subject, NotAfter, Thumbprint
# Check specific cert details
Get-ChildItem Cert:\LocalMachine\My | Where-Object {{ $_.Subject -like "*inside.domusdigitalis.dev*" }} | Format-List *
# Verify certificate has private key
Get-ChildItem Cert:\LocalMachine\My | Where-Object {{ $_.HasPrivateKey }}
# Check EKU includes Client Authentication
Get-ChildItem Cert:\LocalMachine\My | ForEach-Object {{
$_.EnhancedKeyUsageList | Where-Object {{ $_.FriendlyName -eq "Client Authentication" }}
}}
Inner Method Comparison
| Aspect | EAP-TLS | EAP-MSCHAPv2 |
|---|---|---|
Security |
Strongest (mutual TLS) |
Strong (encrypted tunnel) |
Requirements |
Client certificate |
Username/password |
Identity Source |
Any (certificate-based) |
AD, LDAP with NT hashes |
FreeIPA Support |
Yes (via Vault PKI) |
Requires ipa-adtrust-install |
User Experience |
Seamless (certificate auto-select) |
Password prompt (unless cached) |