From 255f4dc7c6211b6f61b21c66bfbad3b2e1866b24 Mon Sep 17 00:00:00 2001 From: James Ruskin Date: Tue, 15 Oct 2024 14:31:28 +0100 Subject: [PATCH] (#105) Removes "Hardened" Option, Always Secures There's no reason we shouldn't be recommending that users secure their environment to the extent possible. If they want to run a less secure environment, they can follow a different guide. --- README.md | 10 +-- Set-SslSecurity.ps1 | 158 +++++++++++++++----------------------------- 2 files changed, 60 insertions(+), 108 deletions(-) diff --git a/README.md b/README.md index b198779..e2399e0 100644 --- a/README.md +++ b/README.md @@ -181,26 +181,26 @@ Below are the minimum requirements for setting up your C4B server via this guide ```powershell Set-Location "$env:SystemDrive\choco-setup\files" - .\Set-SslSecurity.ps1 -Thumbprint '' -Hardened + .\Set-SslSecurity.ps1 -Thumbprint '' ``` > :warning:**REMINDER**: If you are using your own SSL certificate, be sure to place this certificate in the `Local Machine > Personal` certificate store before running the above script, and ensure that the private key is exportable. > :memo: **NOTE** - > You may have noticed the `-Hardened` parameter we've added above. When using a custom SSL certificate, this parameter will further secure access to your C4B Server. A Role and User credential will be configured to limit access to your Nexus repositories. As well, CCM Client and Service Salts are configured to further encrypt your connection between CCM and your endpoint clients. These additional settings are also incorporated into your `Register-C4bEndpoint.ps1` script for onboarding endpoints. We do require you to enable this option if your C4B Server will be Internet-facing, with a FQDN that resolves to a public IP. + > A Role and User credential will be configured to limit access to your Nexus repositories. As well, CCM Client and Service Salts are configured to further encrypt your connection between CCM and your endpoint clients. These additional settings are also incorporated into your `Register-C4bEndpoint.ps1` script for onboarding endpoints. **ALTERNATIVE 2 : Wildcard SSL Certificate** - If you have a wildcard certificate, you will also need to provide a DNS name you wish to use for that certificate: ```powershell Set-Location "$env:SystemDrive\choco-setup\files" - .\Set-SslSecurity.ps1 -Thumbprint '' -CertificateDnsName '' -Hardened + .\Set-SslSecurity.ps1 -Thumbprint '' -CertificateDnsName '' ``` For example, with a wildcard certificate with a thumbprint of `deee9b2fabb24bdaae71d82286e08de1` you wish to use `chocolatey.foo.org`, the following would be required: ```powershell Set-Location "$env:SystemDrive\choco-setup\files" - .\Set-SslSecurity.ps1 -Thumbprint deee9b2fabb24bdaae71d82286e08de1 -CertificateDnsName chocolatey.foo.org -Hardened + .\Set-SslSecurity.ps1 -Thumbprint deee9b2fabb24bdaae71d82286e08de1 -CertificateDnsName chocolatey.foo.org ``` >
@@ -215,7 +215,7 @@ Below are the minimum requirements for setting up your C4B server via this guide > >
- > :mag: **FYI**: A `Readme.html` file will now be generated on your desktop. This file contains login information for all 3 web portals (CCM, Nexus, and Jenkins). This `Readme.html`, along with all 3 web portals, will automatically be opened in your browser. + > :mag: **FYI**: A `Readme.html` file will now be generated on your desktop. This file contains login information for all 3 web portals (CCM, Nexus, and Jenkins). This `Readme.html`, along with all 3 web portals, will automatically be opened in your browser. ### Step 6: Verification diff --git a/Set-SslSecurity.ps1 b/Set-SslSecurity.ps1 index e2aa2be..70c569b 100644 --- a/Set-SslSecurity.ps1 +++ b/Set-SslSecurity.ps1 @@ -32,7 +32,11 @@ param( } })] [string] - $Thumbprint = (Get-ChildItem Cert:\LocalMachine\TrustedPeople -Recurse | Select-Object -ExpandProperty Thumbprint), + $Thumbprint = $( + Get-ChildItem Cert:\LocalMachine\TrustedPeople -Recurse | Sort-Object { + $_.Issuer -eq $_.Subject # Prioritise any certificates above self-signed + } | Select-Object -ExpandProperty Thumbprint -First 1 + ), # The certificate subject that identifies the target SSL certificate in # the local machine certificate stores. @@ -40,7 +44,7 @@ param( [string] $Subject, - #If using a wildcard certificate, provide a DNS name you want to use to access services secured by the certificate. + # If using a wildcard certificate, provide a DNS name you want to use to access services secured by the certificate. [Parameter(ParameterSetName='Subject')] [Parameter(ParameterSetName='Thumbprint')] [string] @@ -49,20 +53,6 @@ param( Get-ChocoEnvironmentProperty CertSubject ), - # This option security hardens your C4B server, in scenarios where you have a non-self-signed certificate. - # It adds a role and user credential to the Nexus server, which is used to authenticate the source setup on a client endpoint. - # It also adds a Client and Service Salt to further secure the SSL conneciton with CCM. - # Finally, it updates the Register-C4bEndpoint.ps1 script to use these new credentials. - [Parameter()] - [switch] - $Hardened, - - # The C4B server hostname for which to generate a new self-signed certificate. - # Ignored/unused if a certificate thumbprint or subject is supplied. - [Parameter(ParameterSetName='SelfSigned')] - [string] - $Hostname = [System.Net.Dns]::GetHostName(), - # API key of your Nexus repo, to add to the source setup on C4B Server. [string]$NuGetApiKey = $( if (-not (Get-Command Get-ChocoEnvironmentProperty -ErrorAction SilentlyContinue)) {. $PSScriptRoot\scripts\Get-Helpers.ps1} @@ -103,13 +93,6 @@ process { $SubjectWithoutCn = $CertificateDnsName } - if ($Hardened) { - $CertValidation = Test-SelfSignedCertificate -Certificate $Certificate - if ($CertValidation) { - throw "Self-Signed Certificates not valid for Internet-Hardened configurations. Please use a valid purchased or generated certificate." - } - } - <# Nexus #> # Stop Services/Processes/Websites required Stop-Service nexus @@ -151,59 +134,46 @@ process { (Get-Content -Path $ClientScript) -replace "{{hostname}}", $SubjectWithoutCn | Set-Content -Path $ClientScript New-NexusRawComponent -RepositoryName 'choco-install' -File $ClientScript - if ($Hardened) { - # Disable anonymous authentication - Set-NexusAnonymousAuth -Disabled - - if (-not (Get-NexusRole -Role 'chocorole' -ErrorAction SilentlyContinue)) { - # Create Nexus role - $RoleParams = @{ - Id = "chocorole" - Name = "chocorole" - Description = "Role for web enabled choco clients" - Privileges = @('nx-repository-view-nuget-*-browse', 'nx-repository-view-nuget-*-read', 'nx-repository-view-raw-*-read', 'nx-repository-view-raw-*-browse') - } - New-NexusRole @RoleParams - } + # Disable anonymous authentication + Set-NexusAnonymousAuth -Disabled - if (-not (Get-NexusUser -User 'chocouser' -ErrorAction SilentlyContinue)) { - $NexusPw = [System.Web.Security.Membership]::GeneratePassword(32, 12) - # Create Nexus user - $UserParams = @{ - Username = 'chocouser' - Password = ($NexusPw | ConvertTo-SecureString -AsPlainText -Force) - FirstName = 'Choco' - LastName = 'User' - EmailAddress = 'chocouser@foo.com' - Status = 'Active' - Roles = 'chocorole' - } - New-NexusUser @UserParams + if (-not (Get-NexusRole -Role 'chocorole' -ErrorAction SilentlyContinue)) { + # Create Nexus role + $RoleParams = @{ + Id = "chocorole" + Name = "chocorole" + Description = "Role for web enabled choco clients" + Privileges = @('nx-repository-view-nuget-*-browse', 'nx-repository-view-nuget-*-read', 'nx-repository-view-raw-*-read', 'nx-repository-view-raw-*-browse') } - - $ChocoArgs = @( - 'source', - 'add', - "--name='ChocolateyInternal'", - "--source='$RepositoryUrl'", - '--priority=1', - "--user='chocouser'", - "--password='$NexusPw'" - ) - & Invoke-Choco @ChocoArgs + New-NexusRole @RoleParams } - else { - $ChocoArgs = @( - 'source', - 'add', - "--name='ChocolateyInternal'", - "--source='$RepositoryUrl'", - '--priority=1' - ) - & Invoke-Choco @ChocoArgs + if (-not (Get-NexusUser -User 'chocouser' -ErrorAction SilentlyContinue)) { + $NexusPw = [System.Web.Security.Membership]::GeneratePassword(32, 12) + # Create Nexus user + $UserParams = @{ + Username = 'chocouser' + Password = ($NexusPw | ConvertTo-SecureString -AsPlainText -Force) + FirstName = 'Choco' + LastName = 'User' + EmailAddress = 'chocouser@foo.com' + Status = 'Active' + Roles = 'chocorole' + } + New-NexusUser @UserParams } + $ChocoArgs = @( + 'source', + 'add', + "--name='ChocolateyInternal'", + "--source='$RepositoryUrl'", + '--priority=1', + "--user='chocouser'", + "--password='$NexusPw'" + ) + & Invoke-Choco @ChocoArgs + # Update Repository API key $chocoArgs = @('apikey', "--source='$RepositoryUrl'", "--api-key='$NuGetApiKey'") & Invoke-Choco @chocoArgs @@ -255,11 +225,9 @@ process { # Generate Register-C4bEndpoint.ps1 $EndpointScript = "$PSScriptRoot\scripts\Register-C4bEndpoint.ps1" - if ($Hardened) { - - $ClientSaltValue = New-CCMSalt - $ServiceSaltValue = New-CCMSalt - $ScriptBlock = @" + $ClientSaltValue = New-CCMSalt + $ServiceSaltValue = New-CCMSalt + $ScriptBlock = @" `$ClientCommunicationSalt = '$ClientSaltValue' `$ServiceCommunicationSalt = '$ServiceSaltValue' `$FQDN = '$SubjectWithoutCN' @@ -288,37 +256,27 @@ process { & ([scriptblock]::Create(`$script)) @params "@ - $ScriptBlock | Set-Content -Path $EndpointScript - - # Agent Setup - $agentArgs = @{ - CentralManagementServiceUrl = "https://$($SubjectWithoutCn):24020/ChocolateyManagementService" - ServiceSalt = $ServiceSaltValue - ClientSalt = $ClientSaltValue - Source = "ChocolateyInternal" - } - - Install-ChocolateyAgent @agentArgs - } else { - # Agent Setup - $agentArgs = @{ - CentralManagementServiceUrl = "https://$($SubjectWithoutCn):24020/ChocolateyManagementService" - Source = "ChocolateyInternal" - } + $ScriptBlock | Set-Content -Path $EndpointScript - Install-ChocolateyAgent @agentArgs + # Agent Setup + $agentArgs = @{ + CentralManagementServiceUrl = "https://$($SubjectWithoutCn):24020/ChocolateyManagementService" + ServiceSalt = $ServiceSaltValue + ClientSalt = $ClientSaltValue + } + if (Test-SelfSignedCertificate -Certificate $Certificate) { # Register endpoint script (Get-Content -Path $EndpointScript) -replace "{{hostname}}", "'$SubjectWithoutCn'" | Set-Content -Path $EndpointScript - if ($IsSelfSigned) { $ScriptBlock = @" `$downloader = New-Object -TypeName System.Net.WebClient Invoke-Expression (`$downloader.DownloadString("http://`$(`$HostName):80/Import-ChocoServerCertificate.ps1")) "@ (Get-Content -Path $EndpointScript) -replace "# placeholder if using a self-signed cert", $ScriptBlock | Set-Content -Path $EndpointScript - } } + Install-ChocolateyAgent @agentArgs + Update-Clixml -Properties @{ CCMWebPortal = "https://$($SubjectWithoutCn)/Account/Login" CCMServiceURL = "https://$($SubjectWithoutCn):24020/ChocolateyManagementService" @@ -326,16 +284,10 @@ Invoke-Expression (`$downloader.DownloadString("http://`$(`$HostName):80/Import- CertThumbprint = $Certificate.Thumbprint CertExpiry = $Certificate.NotAfter IsSelfSigned = $IsSelfSigned - } - - if ($Hardened) { - Update-Clixml -Properties @{ - ServiceSalt = ConvertTo-SecureString $ServiceSaltValue -AsPlainText -Force - ClientSalt = ConvertTo-SecureString $ClientSaltValue -AsPlainText -Force - } + ServiceSalt = ConvertTo-SecureString $ServiceSaltValue -AsPlainText -Force + ClientSalt = ConvertTo-SecureString $ClientSaltValue -AsPlainText -Force } } - end { Write-Host 'Writing README to Desktop; this file contains login information for all C4B services.' New-QuickstartReadme