gravitational / teleport

The easiest, and most secure way to access and protect all of your infrastructure.
https://goteleport.com
GNU Affero General Public License v3.0
17.63k stars 1.76k forks source link

Errors in desktop access configuration scripts #20271

Closed mighty-services closed 5 months ago

mighty-services commented 1 year ago

Expected behavior: the given teleport.yaml file should not throw any error when generated through the teleport script

Current behavior: When I generate a teleport.yaml config according to the new youtube-Guideline, it´s bringing up several error in the powershell file, because I have a separate CA-Authority and not one sitting on the Domain Controller. I fixed it with hrowing in some "invoke-command" Blocks to get the output working like expected, but the yaml file stil throws errors.

error 1 is: ERROR: failed parsing the config file: yaml: unmarshal errors: line 44: field discovery not found in type config.LDAPConfig

error 2 is: ERROR: failed parsing the config file: yaml: unmarshal errors: line 46: field labels not found in type config.LDAPConfig

this is my teleport.yaml file:

version: v3
teleport:
  auth_token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  proxy_server: teleport.exaplme-domain.com:443

auth_service:
  enabled: no
ssh_service:
  enabled: no
proxy_service:
  enabled: no

windows_desktop_service:
  enabled: yes
  ldap:
    addr:     '192.168.1.10:636'
    domain:   'dev.example-domain.local'
    username: 'DEV\svc-teleport'
    sid: 'S-1-5-21-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    server_name: 'dev_dc1.example-domain.local'
    insecure_skip_verify: false
    ldap_ca_cert: |
        -----BEGIN CERTIFICATE-----
        MIIDiTCCAnGgAwIBAgIQQvbfEjREJrBPyPmJop5WhDANBgkqhkiG9w0BAQ0FADBX
        .............
        thegR2HWHqhIiJKgSYurIjSpFbFZXRwBxcx5rYqYXAPbZIbL5yyVMIN8lyYR
        -----END CERTIFICATE-----
    discovery:
      base_dn: '*'
    labels:
      teleport.internal/resource-id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

I am running teleport cluster version 11.2.1 and also telport clients are up to date.

stevenGravy commented 1 year ago

@mighty-services how are you running this? From the output it's shifted in the right place for me

mighty-services commented 1 year ago

Hy Steven,

I´m running the powershell-script

Since it´s a separate environment and your script expects the CA on the same server I had to tweak the script a bit to invoke the certutil on a remote instance. I also had to do a workaround of all the errors coming from the "New-Item" Lines which throws error of already existing elements.

mighty-services commented 1 year ago

I hope I´ll have time today to build in the script some things to catch the errors and fialures, but this is the tweaked script, which I had to use to get it working in my dev-env:

$ErrorActionPreference = "continue"

$TELEPORT_CA_CERT_PEM = "-----BEGIN CERTIFICATE-----
xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX
xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX
xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX
-----END CERTIFICATE-----
"
$TELEPORT_CA_CERT_SHA1 = "xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx"
$TELEPORT_CA_CERT_BLOB_BASE64 = "xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX"
$TELEPORT_PROXY_PUBLIC_ADDR = "tpxport.it-mighty.de:443"
$TELEPORT_PROVISION_TOKEN = "xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx" # TODO need to be changed!!!
$TELEPORT_INTERNAL_RESOURCE_ID = "xXxXxXxXxXxXxXxXxXxXxXxX" # TODO need to be changed!!!

$AD_USER_NAME="Teleport Service Account"
$SAM_ACCOUNT_NAME="svc-teleport"

$DOMAIN_NAME=(Get-ADDomain).DNSRoot
$DOMAIN_DN=$((Get-ADDomain).DistinguishedName)

# Generate a random password that meets the "Password must meet complexity requirements" security policy setting.
# Note: if the minimum complexity requirements have been changed from the Windows default, this part of the script may need to be modified.
Add-Type -AssemblyName 'System.Web'
do {
   $PASSWORD=[System.Web.Security.Membership]::GeneratePassword(15,1)
} until ($PASSWORD -match '\d')
$SECURE_STRING_PASSWORD=ConvertTo-SecureString $PASSWORD -AsPlainText -Force

New-ADUser -Name $AD_USER_NAME -SamAccountName $SAM_ACCOUNT_NAME -AccountPassword $SECURE_STRING_PASSWORD -Enabled $true # TODO -ErrorAction SilentlyContinue

# Create the CDP/Teleport container.
# If the command fails with "New-ADObject : An attempt was made to add an object to the directory with a name that is already in use",
# it means the object already exists and you can move on to the next step.
New-ADObject -Name "Teleport" -Type "container" -Path "CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN" # TODO -ErrorAction SilentlyContinue

# Gives Teleport the ability to create LDAP containers in the CDP container.
dsacls "CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN" /I:T /G "$($SAM_ACCOUNT_NAME):CC;container;"
# Gives Teleport the ability to create and delete cRLDistributionPoint objects in the CDP/Teleport container.
dsacls "CN=Teleport,CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN" /I:T /G "$($SAM_ACCOUNT_NAME):CCDC;cRLDistributionPoint;"
# Gives Teleport the ability to write the certificateRevocationList property in the CDP/Teleport container.
dsacls "CN=Teleport,CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN " /I:T /G "$($SAM_ACCOUNT_NAME):WP;certificateRevocationList;"
# Gives Teleport the ability to create and delete certificationAuthority objects in the NTAuthCertificates container.
dsacls "CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN" /I:T /G "$($SAM_ACCOUNT_NAME):CCDC;certificationAuthority;"
# Gives Teleport the ability to write the cACertificate property in the NTAuthCertificates container.
dsacls "CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN" /I:T /G "$($SAM_ACCOUNT_NAME):WP;cACertificate;"

$SAM_ACCOUNT_SID=(Get-ADUser -Identity $SAM_ACCOUNT_NAME).SID.Value

# Step 2/7. Prevent the service account from performing interactive logins

$BLOCK_GPO_NAME="Block teleport-svc Interactive Login"
New-GPO -Name $BLOCK_GPO_NAME | New-GPLink -Target $DOMAIN_DN # TODO -ErrorAction SilentlyContinue

$DENY_SECURITY_TEMPLATE=@'
[Unicode]
Unicode=yes
[Version]
signature="$CHICAGO$"
[Privilege Rights]
SeDenyRemoteInteractiveLogonRight=*{0}
SeDenyInteractiveLogonRight=*{0}
'@ -f $SAM_ACCOUNT_SID

$BLOCK_POLICY_GUID=((Get-GPO -Name $BLOCK_GPO_NAME).Id.Guid).ToUpper()
$BLOCK_GPO_PATH="$env:SystemRoot\SYSVOL\sysvol\$DOMAIN_NAME\Policies\{$BLOCK_POLICY_GUID}\Machine\Microsoft\Windows NT\SecEdit"
New-Item -Type Directory -Path $BLOCK_GPO_PATH # TODO -ErrorAction SilentlyContinue
New-Item -Path $BLOCK_GPO_PATH -Name "GptTmpl.inf" -ItemType "file" -Value $DENY_SECURITY_TEMPLATE # TODO -ErrorAction SilentlyContinue

# Step 3/7. Configure a GPO to allow Teleport connections
$ACCESS_GPO_NAME="Teleport Access Policy"
New-GPO -Name $ACCESS_GPO_NAME | New-GPLink -Target $DOMAIN_DN

$CERT = [System.Convert]::FromBase64String($TELEPORT_CA_CERT_BLOB_BASE64)
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SystemCertificates\Root\Certificates\$TELEPORT_CA_CERT_SHA1" -ValueName "Blob" -Type Binary -Value $CERT

$TeleportPEMFile = $env:TEMP + "\teleport.pem"
Write-Output $TELEPORT_CA_CERT_PEM | Out-File -FilePath $TeleportPEMFile

certutil -dspublish -f $TeleportPEMFile RootCA
certutil -dspublish -f $TeleportPEMFile NTAuthCA
certutil -pulse

$ACCESS_SECURITY_TEMPLATE=@'
[Unicode]
Unicode=yes
[Version]
signature="$CHICAGO$"
[Service General Setting]
"SCardSvr",2,""
'@

$COMMENT_XML=@'
<?xml version='1.0' encoding='utf-8'?>
<policyComments xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.0" schemaVersion="1.0" xmlns="http://www.microsoft.com/GroupPolicy/CommentDefinitions">
  <policyNamespaces>
    <using prefix="ns0" namespace="Microsoft.Policies.TerminalServer"></using>
  </policyNamespaces>
  <comments>
    <admTemplate></admTemplate>
  </comments>
  <resources minRequiredRevision="1.0">
    <stringTable></stringTable>
  </resources>
</policyComments>
'@

$ACCESS_POLICY_GUID=((Get-GPO -Name $ACCESS_GPO_NAME).Id.Guid).ToUpper()
$ACCESS_GPO_PATH="$env:SystemRoot\SYSVOL\sysvol\$DOMAIN_NAME\Policies\{$ACCESS_POLICY_GUID}\Machine\Microsoft\Windows NT\SecEdit"
New-Item -Type Directory -Path $ACCESS_GPO_PATH # TODO -ErrorAction SilentlyContinue
New-Item -Path $ACCESS_GPO_PATH -Name "GptTmpl.inf" -ItemType "file" -Value $ACCESS_SECURITY_TEMPLATE # TODO -ErrorAction SilentlyContinue
New-Item -Path "$env:SystemRoot\SYSVOL\sysvol\$DOMAIN_NAME\Policies\{$ACCESS_POLICY_GUID}\Machine" -Name "comment.cmtx" -ItemType "file" -Value $COMMENT_XML # TODO -ErrorAction SilentlyContinue

# Firewall
$FIREWALL_USER_MODE_IN_TCP = "v2.31|Action=Allow|Active=TRUE|Dir=In|Protocol=6|LPort=3389|App=%SystemRoot%\system32\svchost.exe|Svc=termservice|Name=@FirewallAPI.dll,-28775|Desc=@FirewallAPI.dll,-28756|EmbedCtxt=@FirewallAPI.dll,-28752|"
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall" -ValueName "PolicyVersion" -Type DWORD -Value 543
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Type String -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\FirewallRules" -ValueName "RemoteDesktop-UserMode-In-TCP" -Value $FIREWALL_USER_MODE_IN_TCP

# Allow remote RDP connections
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" -ValueName "fDenyTSConnections" -Type DWORD -Value 0
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" -ValueName "UserAuthentication" -Type DWORD -Value 0

# Disable "Always prompt for password upon connection"
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" -ValueName "fPromptForPassword" -Type DWORD -Value 0

# # Step 5/7. Export your LDAP CA certificate
$WindowsDERFile = $env:TEMP + "\windows.der"
$WindowsPEMFile = $env:TEMP + "\windows.pem"
Invoke-Command -ComputerName dev-ca01 -scriptblock {certutil "-ca.cert" $using:WindowsDERFile }
Invoke-Command -ComputerName dev-ca01 -scriptblock {certutil -encode $using:WindowsDERFile $using:WindowsPEMFile}

gpupdate.exe /force

Invoke-Command -ComputerName dev-ca01 -scriptblock { 
  $CA_CERT_PEM = Get-Content -Path $using:WindowsPEMFile
  $CA_CERT_YAML = $CA_CERT_PEM | ForEach-Object { "        " + $_  } | Out-String
  $CA_CERT_YAML
} -OutVariable $CA_CERT_YAM

$NET_BIOS_NAME = (Get-ADDomain).NetBIOSName
$LDAP_USERNAME = "$NET_BIOS_NAME\$SAM_ACCOUNT_NAME"
$LDAP_USER_SID=(Get-ADUser -Identity $SAM_ACCOUNT_NAME).SID.Value

$COMPUTER_NAME = (Resolve-DnsName -Type A $Env:COMPUTERNAME).Name
$COMPUTER_IP = (Resolve-DnsName -Type A $Env:COMPUTERNAME).Address
$LDAP_ADDR="$COMPUTER_IP" + ":636"

$DESKTOP_ACCESS_CONFIG_YAML=@"
version: v3
teleport:
    auth_token: $TELEPORT_PROVISION_TOKEN
    proxy_server: $TELEPORT_PROXY_PUBLIC_ADDR

auth_service:
    enabled: no
ssh_service:
    enabled: no
proxy_service:
    enabled: no

windows_desktop_service:
    enabled: yes
    ldap:
    addr:     '$LDAP_ADDR'
    domain:   '$DOMAIN_NAME'
    username: '$LDAP_USERNAME'
    sid: '$LDAP_USER_SID'
    server_name: '$COMPUTER_NAME'
    insecure_skip_verify: false
    ldap_ca_cert: |
$CA_CERT_YAML
    discovery:
    base_dn: '*'
    labels:
    teleport.internal/resource-id: $TELEPORT_INTERNAL_RESOURCE_ID
"@

$OUTPUT=@'

Use the following teleport.yaml to start a Windows Desktop Service.
For a detailed configuration reference, see

https://goteleport.com/docs/desktop-access/reference/configuration/

{0}

'@ -f $DESKTOP_ACCESS_CONFIG_YAML

$WHITESPACE_WARNING=@'
# WARNING:
# When copying and pasting the config from below, PowerShell ISE will add whitespace to the start - delete this before you save the config.
'@

if ($host.name -match 'ISE')
{
    Write-Output $WHITESPACE_WARNING
}

Write-Output $OUTPUT

# cleanup files that were created during execution of this script
Remove-Item $TeleportPEMFile -Recurse
Remove-Item $WindowsDERFile -Recurse
Remove-Item $WindowsPEMFile -Recurse
mighty-services commented 1 year ago

The Variable $CA_CERT_YAML doesn't work jet, because the output is happening on the remote site. I'll fix that today, hopefully. The $TeleportPEMFile, $WindowsDERFile, $WindowsPEMFile aren't referenced in the right way since they need to be on the reomte CA-instance - that needs to be adjusted as well.

I also wanna try to put "-Force" behind every "New-Item" CMDlet to avoid erros of already existing files. That would mean to overwrite the existing object, but that´s fine for my dev-environment.

mighty-services commented 1 year ago

So because it´s not working out of the box for me yet, I had to display the variables and output manually.

Therefore I took a closer look on the examples on the youtube video, the documentation and the web-UI Guide - where you can see an example of the yaml file. I had to adjust the intendation, because it was even more to the right initially, so i took 2 spaces out on each line (minimum) to make it like the examples I looked at.

I also pasted it into vscode and it didn´t gave me any warnings about the intendation or wrong whitespaces.

mighty-services commented 1 year ago

Since I found another ticket dealing with the indepotence of the skript - based on error of already existing files. I added this area of my errors there. I edited the skript to fit my need (means no errors anymore) and youl find my suggestion for errors about already existing items here in Desktop access setup script should be idempotent #20193

mighty-services commented 1 year ago

Here´s the template with all the edits I did to make it work in my dev-Envirnment to fit the need of a separate /Remote CA-Instance.

NOTE: The Script need to run on the DomainController, otherwise the "dsacls" command won´t work.

mighty-services commented 1 year ago

Since powershell-Scripts can't be uploaded, I just paste it in directly:

$ErrorActionPreference = "Stop"

$TELEPORT_CA_CERT_PEM = "-----BEGIN CERTIFICATE-----
xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX
...
xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX==
-----END CERTIFICATE-----
"
$TELEPORT_CA_CERT_SHA1 = "xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX"
$TELEPORT_CA_CERT_BLOB_BASE64 = "xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX=="
$TELEPORT_PROXY_PUBLIC_ADDR = "teleport.example.com:443"
$TELEPORT_PROVISION_TOKEN = "xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX"
$TELEPORT_INTERNAL_RESOURCE_ID = "xXxXxXxXxXxXxXxXxXxXxXxXxXxXxX" 

$AD_USER_NAME="Teleport Service Account"
$SAM_ACCOUNT_NAME="svc-teleport"

$DOMAIN_NAME=(Get-ADDomain).DNSRoot
$DOMAIN_DN=$((Get-ADDomain).DistinguishedName)
$CA_Server=($CA -match "name")[0].split('"')[1]

# Generate a random password that meets the "Password must meet complexity requirements" security policy setting.
# Note: if the minimum complexity requirements have been changed from the Windows default, this part of the script may need to be modified.
Add-Type -AssemblyName 'System.Web'
do {
   $PASSWORD=[System.Web.Security.Membership]::GeneratePassword(15,1)
} until ($PASSWORD -match '\d')
$SECURE_STRING_PASSWORD=ConvertTo-SecureString $PASSWORD -AsPlainText -Force

if (-not (get-ADUser -filter * | where-object {$_.Name -eq $($AD_USER_NAME)})) {
    New-ADUser -Name $AD_USER_NAME -SamAccountName $SAM_ACCOUNT_NAME -AccountPassword $SECURE_STRING_PASSWORD -Enabled $true
}

# Create the CDP/Teleport container.
# If the command fails with "New-ADObject : An attempt was made to add an object to the directory with a name that is already in use",
# it means the object already exists and you can move on to the next step.

if (-not (Get-ADObject -identity "CN=Teleport,CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN")){
    New-ADObject -Name "Teleport" -Type "container" -Path "CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN"
}

# Gives Teleport the ability to create LDAP containers in the CDP container.
dsacls "CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN" /I:T /G "$($SAM_ACCOUNT_NAME):CC;container;"
# Gives Teleport the ability to create and delete cRLDistributionPoint objects in the CDP/Teleport container.
dsacls "CN=Teleport,CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN" /I:T /G "$($SAM_ACCOUNT_NAME):CCDC;cRLDistributionPoint;"
# Gives Teleport the ability to write the certificateRevocationList property in the CDP/Teleport container.
dsacls "CN=Teleport,CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN " /I:T /G "$($SAM_ACCOUNT_NAME):WP;certificateRevocationList;"
# Gives Teleport the ability to create and delete certificationAuthority objects in the NTAuthCertificates container.
dsacls "CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN" /I:T /G "$($SAM_ACCOUNT_NAME):CCDC;certificationAuthority;"
# Gives Teleport the ability to write the cACertificate property in the NTAuthCertificates container.
dsacls "CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,$DOMAIN_DN" /I:T /G "$($SAM_ACCOUNT_NAME):WP;cACertificate;"

$SAM_ACCOUNT_SID=(Get-ADUser -Identity $SAM_ACCOUNT_NAME).SID.Value

# Step 2/7. Prevent the service account from performing interactive logins

$BLOCK_GPO_NAME="Block teleport-svc Interactive Login"
if (-not (Get-GPO -Name $BLOCK_GPO_NAME)) {
    New-GPO -Name $BLOCK_GPO_NAME | New-GPLink -Target $DOMAIN_DN
}

$DENY_SECURITY_TEMPLATE=@'
[Unicode]
Unicode=yes
[Version]
signature="$CHICAGO$"
[Privilege Rights]
SeDenyRemoteInteractiveLogonRight=*{0}
SeDenyInteractiveLogonRight=*{0}
'@ -f $SAM_ACCOUNT_SID

$BLOCK_POLICY_GUID=((Get-GPO -Name $BLOCK_GPO_NAME).Id.Guid).ToUpper()
$BLOCK_GPO_PATH="$env:SystemRoot\SYSVOL\sysvol\$DOMAIN_NAME\Policies\{$BLOCK_POLICY_GUID}\Machine\Microsoft\Windows NT\SecEdit"
New-Item -Type Directory -Path $BLOCK_GPO_PATH -Force
New-Item -Path $BLOCK_GPO_PATH -Name "GptTmpl.inf" -ItemType "file" -Value $DENY_SECURITY_TEMPLATE -Force

# Step 3/7. Configure a GPO to allow Teleport connections
$ACCESS_GPO_NAME="Teleport Access Policy"
if (-not (Get-GPO -Name $ACCESS_GPO_NAME)) {
    New-GPO -Name $ACCESS_GPO_NAME | New-GPLink -Target $DOMAIN_DN
}

$CERT = [System.Convert]::FromBase64String($TELEPORT_CA_CERT_BLOB_BASE64)
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SystemCertificates\Root\Certificates\$TELEPORT_CA_CERT_SHA1" -ValueName "Blob" -Type Binary -Value $CERT

$TeleportPath = "\\$($CA_Server)\"
$TeleportPath += Invoke-Command -ComputerName $CA_Server -ScriptBlock { ([System.IO.Path]::GetTempPath()) }
$TeleportPath = $TeleportPath.Replace(':\','$\')
$TeleportPEMFile = $TeleportPath + "teleport.pem"

Write-Output $TELEPORT_CA_CERT_PEM | Out-File -FilePath $TeleportPEMFile

certutil -dspublish -f $TeleportPEMFile RootCA
certutil -dspublish -f $TeleportPEMFile NTAuthCA
certutil -pulse

$ACCESS_SECURITY_TEMPLATE=@'
[Unicode]
Unicode=yes
[Version]
signature="$CHICAGO$"
[Service General Setting]
"SCardSvr",2,""
'@

$COMMENT_XML=@'
<?xml version='1.0' encoding='utf-8'?>
<policyComments xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.0" schemaVersion="1.0" xmlns="http://www.microsoft.com/GroupPolicy/CommentDefinitions">
  <policyNamespaces>
    <using prefix="ns0" namespace="Microsoft.Policies.TerminalServer"></using>
  </policyNamespaces>
  <comments>
    <admTemplate></admTemplate>
  </comments>
  <resources minRequiredRevision="1.0">
    <stringTable></stringTable>
  </resources>
</policyComments>
'@

$ACCESS_POLICY_GUID=((Get-GPO -Name $ACCESS_GPO_NAME).Id.Guid).ToUpper()
$ACCESS_GPO_PATH="$env:SystemRoot\SYSVOL\sysvol\$DOMAIN_NAME\Policies\{$ACCESS_POLICY_GUID}\Machine\Microsoft\Windows NT\SecEdit"
New-Item -Type Directory -Path $ACCESS_GPO_PATH -Force
New-Item -Path $ACCESS_GPO_PATH -Name "GptTmpl.inf" -ItemType "file" -Value $ACCESS_SECURITY_TEMPLATE -Force
New-Item -Path "$env:SystemRoot\SYSVOL\sysvol\$DOMAIN_NAME\Policies\{$ACCESS_POLICY_GUID}\Machine" -Name "comment.cmtx" -ItemType "file" -Value $COMMENT_XML -Force

# Firewall
$FIREWALL_USER_MODE_IN_TCP = "v2.31|Action=Allow|Active=TRUE|Dir=In|Protocol=6|LPort=3389|App=%SystemRoot%\system32\svchost.exe|Svc=termservice|Name=@FirewallAPI.dll,-28775|Desc=@FirewallAPI.dll,-28756|EmbedCtxt=@FirewallAPI.dll,-28752|"
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall" -ValueName "PolicyVersion" -Type DWORD -Value 543
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Type String -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\FirewallRules" -ValueName "RemoteDesktop-UserMode-In-TCP" -Value $FIREWALL_USER_MODE_IN_TCP

# Allow remote RDP connections
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" -ValueName "fDenyTSConnections" -Type DWORD -Value 0
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" -ValueName "UserAuthentication" -Type DWORD -Value 0

# Disable "Always prompt for password upon connection"
Set-GPRegistryValue -Name $ACCESS_GPO_NAME -Key "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services" -ValueName "fPromptForPassword" -Type DWORD -Value 0

# # Step 5/7. Export your LDAP CA certificate
$WindowsDERFile = $TeleportPath + "windows.der"
$WindowsPEMFile = $TeleportPath + "windows.pem"
Invoke-Command -ComputerName dev-ca01 -scriptblock {certutil "-ca.cert" $using:WindowsDERFile }
Invoke-Command -ComputerName dev-ca01 -scriptblock {certutil -encode $using:WindowsDERFile $using:WindowsPEMFile}

gpupdate.exe /force

$CA_CERT_PEM = Invoke-Command -ComputerName dev-ca01 -scriptblock { Get-Content -Path $using:WindowsPEMFile }
$CA_CERT_YAML = $CA_CERT_PEM | ForEach-Object { "        " + $_  } | Out-String

$NET_BIOS_NAME = (Get-ADDomain).NetBIOSName
$LDAP_USERNAME = "$NET_BIOS_NAME\$SAM_ACCOUNT_NAME"
$LDAP_USER_SID =(Get-ADUser -Identity $SAM_ACCOUNT_NAME).SID.Value

$COMPUTER_NAME = (Resolve-DnsName -Type A $Env:COMPUTERNAME).Name
$COMPUTER_IP   = (Resolve-DnsName -Type A $Env:COMPUTERNAME).Address
$LDAP_ADDR     ="$COMPUTER_IP" + ":636"

$DESKTOP_ACCESS_CONFIG_YAML=@"
version: v3
teleport:
    auth_token: $TELEPORT_PROVISION_TOKEN
    proxy_server: $TELEPORT_PROXY_PUBLIC_ADDR

auth_service:
    enabled: no
ssh_service:
    enabled: no
proxy_service:
    enabled: no

windows_desktop_service:
    enabled: yes
    ldap:
    addr:     '$LDAP_ADDR'
    domain:   '$DOMAIN_NAME'
    username: '$LDAP_USERNAME'
    sid: '$LDAP_USER_SID'
    server_name: '$COMPUTER_NAME'
    insecure_skip_verify: false
    ldap_ca_cert: |
$CA_CERT_YAML
    discovery:
    base_dn: '*'
    labels:
    teleport.internal/resource-id: $TELEPORT_INTERNAL_RESOURCE_ID
"@

$OUTPUT=@'

Use the following teleport.yaml to start a Windows Desktop Service.
For a detailed configuration reference, see

https://goteleport.com/docs/desktop-access/reference/configuration/

{0}

'@ -f $DESKTOP_ACCESS_CONFIG_YAML

$WHITESPACE_WARNING=@'
# WARNING:
# When copying and pasting the config from below, PowerShell ISE will add whitespace to the start - delete this before you save the config.
'@

if ($host.name -match 'ISE')
{
    Write-Output $WHITESPACE_WARNING
}

Write-Output $OUTPUT

# cleanup files that were created during execution of this script
Remove-Item $TeleportPEMFile -Recurse
Remove-Item $WindowsDERFile -Recurse
Remove-Item $WindowsPEMFile -Recurse
mighty-services commented 1 year ago

Now, that I ran the script again and checked it (again) with the generated one from my cluster-instance, I found out there really was an intendation error at the end of the yaml-file: grafik

Once corrected, the service started without errors.

zmb3 commented 1 year ago

FYI @LKozlowski - see above for a few important details

@mighty-services - thanks so much for sharing this!

zmb3 commented 5 months ago

These installation scripts make too many assumptions that don't hold true in enterprise environments, so they are being deprecated as of Teleport 16.