diff --git a/deployment/administration/SHM_Manage_VMs.ps1 b/deployment/administration/SHM_Manage_VMs.ps1 index 2675b7f3b0..9cc8f2b20b 100644 --- a/deployment/administration/SHM_Manage_VMs.ps1 +++ b/deployment/administration/SHM_Manage_VMs.ps1 @@ -34,7 +34,6 @@ if ($Group -eq "Identity") { } elseif ($Group -eq "Mirrors") { # Remove Identity VMs from list $vmsByRg.Remove($config.dc.rg) - $vmsByRg.Remove($config.nps.rg) } switch ($Action) { @@ -48,23 +47,19 @@ switch ($Action) { $primaryDCAlreadyRunning = Confirm-VmRunning -Name $config.dc.vmName -ResourceGroupName $config.dc.rg if ($primaryDCAlreadyRunning) { Add-LogMessage -Level InfoSuccess "VM '$($config.dc.vmName)' already running." - # Start Secondary DC and NPS + # Start Secondary DC Start-VM -Name $config.dcb.vmName -ResourceGroupName $config.dc.rg - Start-VM -Name $config.nps.vmName -ResourceGroupName $config.nps.rg -SkipIfNotExist } else { - # Stop Secondary DC and NPS as these must start after Primary DC + # Stop Secondary DC as it must start after Primary DC Add-LogMessage -Level Info "Stopping Secondary DC and NPS as Primary DC is not running." Stop-Vm -Name $config.dcb.vmName -ResourceGroupName $config.dc.rg - Stop-Vm -Name $config.nps.vmName -ResourceGroupName $config.nps.rg -SkipIfNotExist # Start Primary DC Start-VM -Name $config.dc.vmName -ResourceGroupName $config.dc.rg - # Start Secondary DC and NPS + # Start Secondary DC Start-VM -Name $config.dcb.vmName -ResourceGroupName $config.dc.rg - Start-VM -Name $config.nps.vmName -ResourceGroupName $config.nps.rg -SkipIfNotExist } # Remove Identity VMs from general VM list so they are not processed twice $vmsByRg.Remove($config.dc.rg) - $vmsByRg.Remove($config.nps.rg) } # Process remaining SHM VMs covered by the specified group foreach ($key in $vmsByRg.Keys) { diff --git a/deployment/administration/SRE_Manage_VMs.ps1 b/deployment/administration/SRE_Manage_VMs.ps1 index 3a6cf45d3c..6ac5e77377 100644 --- a/deployment/administration/SRE_Manage_VMs.ps1 +++ b/deployment/administration/SRE_Manage_VMs.ps1 @@ -27,6 +27,7 @@ $vmsByRg = Get-VMsByResourceGroupPrefix -ResourceGroupPrefix $config.sre.rgPrefi switch ($Action) { "EnsureStarted" { # Remove remote desktop VMs to process last + # May be able to simplify this further now that MSRDS is removed $remoteDesktopVms = $vmsByRg[$config.sre.remoteDesktop.rg] $vmsByRg.Remove($config.sre.remoteDesktop.rg) # Start all other VMs before RDS VMs so all services will be available when users can login via RDS @@ -40,32 +41,8 @@ switch ($Action) { } # Ensure remote desktop VMs are started Add-LogMessage -Level Info "Ensuring VMs in resource group '$($config.sre.remoteDesktop.rg)' are started..." - if ($config.sre.remoteDesktop.provider -eq "ApacheGuacamole") { - # Start Guacamole VMs - $remoteDesktopVms | ForEach-Object { Start-VM -VM $_ } - } elseif ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - # RDS gateway must be started before RDS session hosts - $gatewayAlreadyRunning = Confirm-VmRunning -Name $config.sre.remoteDesktop.gateway.vmName -ResourceGroupName $config.sre.remoteDesktop.rg - if ($gatewayAlreadyRunning) { - Add-LogMessage -Level InfoSuccess "VM '$($config.sre.remoteDesktop.gateway.vmName)' already running." - # Ensure session hosts started - foreach ($vm in $remoteDesktopVms | Where-Object { $_.Name -ne $config.sre.remoteDesktop.gateway.vmName }) { - Start-VM -VM $vm - } - } else { - # Stop session hosts as they must start after gateway - Add-LogMessage -Level Info "Stopping RDS session hosts as gateway is not running." - foreach ($vm in $remoteDesktopVms | Where-Object { $_.Name -ne $config.sre.remoteDesktop.gateway.vmName }) { - Stop-VM -VM $vm - } - # Start gateway - Start-VM -Name $config.sre.remoteDesktop.gateway.vmName -ResourceGroupName $config.sre.remoteDesktop.rg - # Start session hosts - foreach ($vm in $remoteDesktopVms | Where-Object { $_.Name -ne $config.sre.remoteDesktop.gateway.vmName }) { - Start-VM -VM $vm - } - } - } + # Start Guacamole VMs + $remoteDesktopVms | ForEach-Object { Start-VM -VM $_ } } "EnsureStopped" { foreach ($key in $vmsByRg.Keys) { diff --git a/deployment/common/Configuration.psm1 b/deployment/common/Configuration.psm1 index c1090d9bb8..9c21a51232 100644 --- a/deployment/common/Configuration.psm1 +++ b/deployment/common/Configuration.psm1 @@ -186,14 +186,12 @@ function Get-ShmConfig { netbiosName = ($shmConfigBase.netbiosName ? $shmConfigBase.netbiosName : $shm.id).ToUpper() | Limit-StringLength -MaximumLength 15 -FailureIsFatal dn = "DC=$(($shmConfigBase.domain).Replace('.',',DC='))" ous = [ordered]@{ - databaseServers = [ordered]@{ name = "Secure Research Environment Database Servers" } - linuxServers = [ordered]@{ name = "Secure Research Environment Linux Servers" } - rdsGatewayServers = [ordered]@{ name = "Secure Research Environment RDS Gateway Servers" } - rdsSessionServers = [ordered]@{ name = "Secure Research Environment RDS Session Servers" } - researchUsers = [ordered]@{ name = "Safe Haven Research Users" } - securityGroups = [ordered]@{ name = "Safe Haven Security Groups" } - serviceAccounts = [ordered]@{ name = "Safe Haven Service Accounts" } - identityServers = [ordered]@{ name = "Safe Haven Identity Servers" } + databaseServers = [ordered]@{ name = "Secure Research Environment Database Servers" } + linuxServers = [ordered]@{ name = "Secure Research Environment Linux Servers" } + researchUsers = [ordered]@{ name = "Safe Haven Research Users" } + securityGroups = [ordered]@{ name = "Safe Haven Security Groups" } + serviceAccounts = [ordered]@{ name = "Safe Haven Service Accounts" } + identityServers = [ordered]@{ name = "Safe Haven Identity Servers" } } } $shm.domain.fqdnLower = ($shm.domain.fqdn).ToLower() @@ -400,31 +398,21 @@ function Get-ShmConfig { # --------- $shm.users = [ordered]@{ computerManagers = [ordered]@{ - databaseServers = [ordered]@{ + databaseServers = [ordered]@{ name = "$($shm.domain.netbiosName) Database Servers Manager" samAccountName = "$($shm.id)databasesrvrs".ToLower() | Limit-StringLength -MaximumLength 20 passwordSecretName = "shm-$($shm.id)-computer-manager-password-database-servers".ToLower() } - identityServers = [ordered]@{ + identityServers = [ordered]@{ name = "$($shm.domain.netbiosName) Identity Servers Manager" samAccountName = "$($shm.id)identitysrvrs".ToLower() | Limit-StringLength -MaximumLength 20 passwordSecretName = "shm-$($shm.id)-computer-manager-password-identity-servers".ToLower() } - linuxServers = [ordered]@{ + linuxServers = [ordered]@{ name = "$($shm.domain.netbiosName) Linux Servers Manager" samAccountName = "$($shm.id)linuxsrvrs".ToLower() | Limit-StringLength -MaximumLength 20 passwordSecretName = "shm-$($shm.id)-computer-manager-password-linux-servers".ToLower() } - rdsGatewayServers = [ordered]@{ - name = "$($shm.domain.netbiosName) RDS Gateway Manager" - samAccountName = "$($shm.id)gatewaysrvrs".ToLower() | Limit-StringLength -MaximumLength 20 - passwordSecretName = "shm-$($shm.id)-computer-manager-password-rds-gateway-servers".ToLower() - } - rdsSessionServers = [ordered]@{ - name = "$($shm.domain.netbiosName) RDS Session Servers Manager" - samAccountName = "$($shm.id)sessionsrvrs".ToLower() | Limit-StringLength -MaximumLength 20 - passwordSecretName = "shm-$($shm.id)-computer-manager-password-rds-session-servers".ToLower() - } } serviceAccounts = [ordered]@{ aadLocalSync = [ordered]@{ @@ -624,22 +612,17 @@ function Get-SreConfig { # Import minimal management config parameters from JSON config file - we can derive the rest from these $sreConfigBase = Get-CoreConfig -shmId $shmId -sreId $sreId + # Support for "MicrosoftRDS" has been removed. The "remotedDesktopProvider" field now defaults to "ApacheGuacamole" + if ($sreConfigBase.remoteDesktopProvider -ne "ApacheGuacamole") { + Add-LogMessage -Level Fatal "Support for remote desktops other than ApacheGuacamole has been removed" + } elseif ($sreConfigBase.remoteDesktopProvider -eq "ApacheGuacamole") { + Add-LogMessage -Level Warning "The remoteDesktopProvider configuration option has been deprecated and will be removed in the future" + } + $sreConfigBase.remoteDesktopProvider = "ApacheGuacamole" + # Secure research environment config # ---------------------------------- - # Check that one of the allowed remote desktop providers is selected - $remoteDesktopProviders = @("ApacheGuacamole", "MicrosoftRDS") - if (-not $sreConfigBase.remoteDesktopProvider) { - Add-LogMessage -Level Warning "No remoteDesktopType was provided. Defaulting to $($remoteDesktopProviders[0])" - $sreConfigBase.remoteDesktopProvider = $remoteDesktopProviders[0] - } - if (-not $remoteDesktopProviders.Contains($sreConfigBase.remoteDesktopProvider)) { - Add-LogMessage -Level Fatal "Did not recognise remote desktop provider '$($sreConfigBase.remoteDesktopProvider)' as one of the allowed remote desktop types: $remoteDesktopProviders" - } - if ( - ($sreConfigBase.remoteDesktopProvider -eq "MicrosoftRDS") -and (-not @(2, 3, 4).Contains([int]$sreConfigBase.tier)) - ) { - Add-LogMessage -Level Fatal "RemoteDesktopProvider '$($sreConfigBase.remoteDesktopProvider)' cannot be used for tier '$($sreConfigBase.tier)'" - } + # Setup the basic config $config = [ordered]@{ shm = Get-ShmConfig -shmId $sreConfigBase.shmId @@ -879,8 +862,8 @@ function Get-SreConfig { } } - # Remote desktop either through Apache Guacamole or Microsoft RDS - # --------------------------------------------------------------- + # Apache Guacamole remote desktop + # ------------------------------- $config.sre.remoteDesktop.rg = "$($config.sre.rgPrefix)_REMOTE_DESKTOP".ToUpper() if ($config.sre.remoteDesktop.provider -eq "ApacheGuacamole") { $config.sre.network.vnet.subnets.remoteDesktop.nsg = [ordered]@{ @@ -900,44 +883,6 @@ function Get-SreConfig { } } } - } elseif ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - $config.sre.remoteDesktop.gateway = [ordered]@{ - adminPasswordSecretName = "$($config.sre.shortName)-vm-admin-password-rds-gateway" - vmName = "RDG-SRE-$($config.sre.id)".ToUpper() | Limit-StringLength -MaximumLength 15 - vmSize = "Standard_DS2_v2" - ip = Get-NextAvailableIpInRange -IpRangeCidr $config.sre.network.vnet.subnets.remoteDesktop.cidr -Offset 4 - installationDirectory = "C:\Installation" - nsg = [ordered]@{ - name = "$($config.sre.nsgPrefix)_RDS_SERVER".ToUpper() - rules = "sre-nsg-rules-gateway.json" - } - disks = [ordered]@{ - data = [ordered]@{ - sizeGb = "1023" - type = $config.sre.diskTypeDefault - } - os = [ordered]@{ - sizeGb = "128" - type = $config.sre.diskTypeDefault - } - } - } - $config.sre.remoteDesktop.appSessionHost = [ordered]@{ - adminPasswordSecretName = "$($config.sre.shortName)-vm-admin-password-rds-sh1" - vmName = "APP-SRE-$($config.sre.id)".ToUpper() | Limit-StringLength -MaximumLength 15 - vmSize = "Standard_DS2_v2" - ip = Get-NextAvailableIpInRange -IpRangeCidr $config.sre.network.vnet.subnets.remoteDesktop.cidr -Offset 5 - nsg = [ordered]@{ - name = "$($config.sre.nsgPrefix)_RDS_SESSION_HOSTS".ToUpper() - rules = "sre-nsg-rules-session-hosts.json" - } - disks = [ordered]@{ - os = [ordered]@{ - sizeGb = "128" - type = $config.sre.diskTypeDefault - } - } - } } else { Add-LogMessage -Level Fatal "Remote desktop type '$($config.sre.remoteDesktop.type)' was not recognised!" } diff --git a/deployment/safe_haven_management_environment/arm_templates/shm-nps-template.json b/deployment/safe_haven_management_environment/arm_templates/shm-nps-template.json deleted file mode 100644 index f9fb6d3ae6..0000000000 --- a/deployment/safe_haven_management_environment/arm_templates/shm-nps-template.json +++ /dev/null @@ -1,244 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "administratorPassword": { - "type": "securestring", - "metadata": { - "description": "Password for domain administrator" - } - }, - "administratorUsername": { - "type": "string", - "metadata": { - "description": "Username for domain administrator" - } - }, - "bootDiagnosticsAccountName": { - "type": "string", - "metadata": { - "description": "Name of storage account used for boot diagnostics" - } - }, - "domainJoinOuPath": { - "type": "string", - "metadata": { - "description": "OU path to add this VM to" - } - }, - "domainJoinPassword": { - "type": "securestring", - "metadata": { - "description": "Password for domain joining" - } - }, - "domainJoinUser": { - "type": "string", - "metadata": { - "description": "Username for domain joining" - } - }, - "domainName": { - "type": "string", - "metadata": { - "Description": "Public domain name for the SHM" - } - }, - "virtualNetworkName": { - "type": "string", - "metadata": { - "description": "Name of virtual network to provision these VMs" - } - }, - "virtualNetworkResourceGroupName": { - "type": "string", - "metadata": { - "description": "Name of resource group that is associated with the virtual network above" - } - }, - "virtualNetworkSubnetName": { - "type": "string", - "metadata": { - "description": "Name of subnet where you want to provision this VM" - } - }, - "vmHostName": { - "type": "string", - "metadata": { - "description": "Hostname for NPS" - } - }, - "vmName": { - "type": "string", - "metadata": { - "description": "VM name of NPS" - } - }, - "vmOsDiskSizeGb": { - "type": "int", - "metadata": { - "description": "Size of NPS OS disk in GB" - } - }, - "vmOsDiskType": { - "type": "string", - "metadata": { - "description": "Type of NPS OS disk" - } - }, - "vmPrivateIpAddress": { - "type": "string", - "metadata": { - "description": "Private IP address for NPS" - } - }, - "vmSize": { - "type": "string", - "metadata": { - "description": "VM size of NPS" - } - } - }, - "variables": { - "npsnic": "[concat(parameters('vmName'),'-','NIC')]", - "vnetID": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]", - "subnetId": "[concat(variables('vnetID'),'/subnets/', parameters('virtualNetworkSubnetName'))]" - }, - "resources": [ - { - "type": "Microsoft.Compute/virtualMachines", - "name": "[parameters('vmName')]", - "apiVersion": "2021-11-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "hardwareProfile": { - "vmSize": "[parameters('vmSize')]" - }, - "storageProfile": { - "imageReference": { - "publisher": "MicrosoftWindowsServer", - "offer": "WindowsServer", - "sku": "2022-Datacenter", - "version": "latest" - }, - "osDisk": { - "osType": "Windows", - "name": "[concat(parameters('vmName'),'-OS-DISK')]", - "createOption": "FromImage", - "caching": "ReadWrite", - "writeAcceleratorEnabled": false, - "managedDisk": { - "storageAccountType": "[parameters('vmOsDiskType')]" - }, - "diskSizeGB": "[parameters('vmOsDiskSizeGb')]" - } - }, - "osProfile": { - "computerName": "[parameters('vmHostName')]", - "adminUsername": "[parameters('administratorUsername')]", - "adminPassword": "[parameters('administratorPassword')]", - "windowsConfiguration": { - "enableAutomaticUpdates": false, - "provisionVMAgent": true - }, - "secrets": [], - "allowExtensionOperations": true - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('npsnic'))]", - "properties": { - "primary": true - } - } - ] - }, - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": true, - "storageUri": "[concat('https', '://', parameters('bootDiagnosticsAccountName'), '.blob.core.windows.net', '/')]" - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/networkInterfaces', variables('npsnic'))]" - ] - }, - { - "type": "Microsoft.Network/networkInterfaces", - "name": "[variables('npsnic')]", - "apiVersion": "2020-05-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "ipConfigurations": [ - { - "name": "ipconfig1", - "properties": { - "privateIPAddress": "[parameters('vmPrivateIpAddress')]", - "privateIPAllocationMethod": "Static", - "subnet": { - "id": "[variables('subnetId')]" - }, - "primary": true, - "privateIPAddressVersion": "IPv4" - } - } - ], - "dnsSettings": { - "dnsServers": [], - "appliedDnsServers": [] - }, - "enableAcceleratedNetworking": false, - "enableIPForwarding": false, - "primary": true, - "tapConfigurations": [] - }, - "dependsOn": [] - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "name": "[concat(parameters('vmName'), '/', 'bginfo')]", - "apiVersion": "2019-07-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "autoUpgradeMinorVersion": true, - "publisher": "Microsoft.Compute", - "type": "bginfo", - "typeHandlerVersion": "2.1" - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]" - ] - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "name": "[concat(parameters('vmName'),'/joindomain')]", - "apiVersion": "2019-07-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]", - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('vmName'),'bginfo')]" - ], - "properties": { - "publisher": "Microsoft.Compute", - "type": "JsonADDomainExtension", - "typeHandlerVersion": "1.3", - "autoUpgradeMinorVersion": true, - "settings": { - "Name": "[parameters('domainName')]", - "OUPath": "[parameters('domainJoinOuPath')]", - "User": "[concat(parameters('domainName'), '\\', parameters('domainJoinUser'))]", - "Restart": "true", - "Options": "3" - }, - "protectedSettings": { - "Password": "[parameters('domainJoinPassword')]" - } - } - } - ] -} \ No newline at end of file diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/DC1DesiredState.ps1 b/deployment/safe_haven_management_environment/desired_state_configuration/DC1DesiredState.ps1 index f5475372c9..8c21de41be 100755 --- a/deployment/safe_haven_management_environment/desired_state_configuration/DC1DesiredState.ps1 +++ b/deployment/safe_haven_management_environment/desired_state_configuration/DC1DesiredState.ps1 @@ -467,14 +467,6 @@ configuration ApplyGroupPolicies { [ValidateNotNullOrEmpty()] [string]$OuNameLinuxServers, - [Parameter(HelpMessage = "RDS gateway servers OU name (eg. 'Secure Research Environment RDS Gateway Servers')")] - [ValidateNotNullOrEmpty()] - [string]$OuNameRdsGatewayServers, - - [Parameter(HelpMessage = "RDS session servers OU name (eg. 'Secure Research Environment RDS Session Servers')")] - [ValidateNotNullOrEmpty()] - [string]$OuNameRdsSessionServers, - [Parameter(HelpMessage = "Research users OU name (eg. 'Safe Haven Research Users')")] [ValidateNotNullOrEmpty()] [string]$OuNameResearchUsers, @@ -520,8 +512,7 @@ configuration ApplyGroupPolicies { Write-Verbose -Verbose "Importing GPOs..." foreach ($sourceTargetPair in (("0AF343A0-248D-4CA5-B19E-5FA46DAE9F9C", "All servers - Local Administrators"), ("EE9EF278-1F3F-461C-9F7A-97F2B82C04B4", "All Servers - Windows Update"), - ("742211F9-1482-4D06-A8DE-BA66101933EB", "All Servers - Windows Services"), - ("B0A14FC3-292E-4A23-B280-9CC172D92FD5", "Session Servers - Remote Desktop Control"))) { + ("742211F9-1482-4D06-A8DE-BA66101933EB", "All Servers - Windows Services"))) { $source, $target = $sourceTargetPair $null = Import-GPO -BackupId "$source" -TargetName "$target" -Path $using:GpoOutputPath -CreateIfNeeded if ($?) { @@ -545,19 +536,12 @@ configuration ApplyGroupPolicies { Write-Verbose -Verbose "Linking GPOs to OUs..." foreach ($gpoOuNamePair in (("All servers - Local Administrators", "$using:OuNameDatabaseServers"), ("All servers - Local Administrators", "$using:OuNameIdentityServers"), - ("All servers - Local Administrators", "$using:OuNameRdsSessionServers"), - ("All servers - Local Administrators", "$using:OuNameRdsGatewayServers"), ("All Servers - Windows Services", "Domain Controllers"), ("All Servers - Windows Services", "$using:OuNameDatabaseServers"), ("All Servers - Windows Services", "$using:OuNameIdentityServers"), - ("All Servers - Windows Services", "$using:OuNameRdsSessionServers"), - ("All Servers - Windows Services", "$using:OuNameRdsGatewayServers"), ("All Servers - Windows Update", "Domain Controllers"), ("All Servers - Windows Update", "$using:OuNameDatabaseServers"), - ("All Servers - Windows Update", "$using:OuNameIdentityServers"), - ("All Servers - Windows Update", "$using:OuNameRdsSessionServers"), - ("All Servers - Windows Update", "$using:OuNameRdsGatewayServers"), - ("Session Servers - Remote Desktop Control", "$using:OuNameRdsSessionServers"))) { + ("All Servers - Windows Update", "$using:OuNameIdentityServers"))) { $gpoName, $ouName = $gpoOuNamePair $gpo = Get-GPO -Name "$gpoName" # Check for a match in existing GPOs @@ -628,29 +612,6 @@ configuration ApplyGroupPolicies { TestScript = { $false } DependsOn = "[Script]ImportGroupPolicies" } - - Script SetRemoteDesktopServerLayout { - SetScript = { - try { - Write-Verbose -Verbose "Setting the layout file for the Remote Desktop servers..." - $null = Set-GPRegistryValue -Key "HKCU\Software\Policies\Microsoft\Windows\Explorer\" ` - -Name "Session Servers - Remote Desktop Control" ` - -Type "ExpandString" ` - -ValueName "StartLayoutFile" ` - -Value "\\$($using:DomainFqdn)\SYSVOL\$($using:DomainFqdn)\scripts\ServerStartMenu\LayoutModification.xml" - if ($?) { - Write-Verbose -Verbose "Setting the layout file for the Remote Desktop servers succeeded" - } else { - throw "Setting the layout file for the Remote Desktop servers failed!" - } - } catch { - Write-Error "SetRemoteDesktopServerLayout: $($_.Exception)" - } - } - GetScript = { @{} } - TestScript = { $false } - DependsOn = "[Script]ImportGroupPolicies" - } } } @@ -831,8 +792,6 @@ configuration ConfigurePrimaryDomainController { OuNameDatabaseServers = $domainOus.databaseServers.name OuNameIdentityServers = $domainOus.identityServers.name OuNameLinuxServers = $domainOus.linuxServers.name - OuNameRdsGatewayServers = $domainOus.rdsGatewayServers.name - OuNameRdsSessionServers = $domainOus.rdsSessionServers.name OuNameResearchUsers = $domainOus.researchUsers.name OuNameSecurityGroups = $domainOus.securityGroups.name OuNameServiceAccounts = $domainOus.serviceAccounts.name diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/NPSBootstrap.ps1 b/deployment/safe_haven_management_environment/desired_state_configuration/NPSBootstrap.ps1 deleted file mode 100644 index 46fab947aa..0000000000 --- a/deployment/safe_haven_management_environment/desired_state_configuration/NPSBootstrap.ps1 +++ /dev/null @@ -1,7 +0,0 @@ -# Here we install -# - NuGet (for module management) -# - PowerShellModule (to allow modules to be installed in DSC) -# - various x* modules (to enable DSC functions) -# Other Powershell modules should be installed through DSC -Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force; -Install-Module PowerShellModule -MinimumVersion 0.3 -Force; diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/NPSDesiredState.ps1 b/deployment/safe_haven_management_environment/desired_state_configuration/NPSDesiredState.ps1 deleted file mode 100755 index e41a22d982..0000000000 --- a/deployment/safe_haven_management_environment/desired_state_configuration/NPSDesiredState.ps1 +++ /dev/null @@ -1,209 +0,0 @@ -configuration InstallPowershellModules { - Import-DscResource -ModuleName PowerShellModule - - Node localhost { - PSModuleResource MSOnline { - Ensure = "present" - Module_Name = "MSOnline" - } - - PSModuleResource PackageManagement { - Ensure = "present" - Module_Name = "PackageManagement" - } - - PSModuleResource PowerShellGet { - Ensure = "present" - Module_Name = "PowerShellGet" - } - - PSModuleResource PSWindowsUpdate { - Ensure = "present" - Module_Name = "PSWindowsUpdate" - } - } -} - - -configuration UploadArtifacts { - param ( - [Parameter(HelpMessage = "Absolute path to directory which blobs should be downloaded to")] - [ValidateNotNullOrEmpty()] - [string]$ArtifactsDirectory, - - [Parameter(HelpMessage = "Array of blob names to download from storage blob container")] - [ValidateNotNullOrEmpty()] - [PSCustomObject]$BlobNames, - - [Parameter(HelpMessage = "SAS token with read/list rights to the storage blob container")] - [ValidateNotNullOrEmpty()] - [string]$BlobSasToken, - - [Parameter(HelpMessage = "Name of the storage account")] - [ValidateNotNullOrEmpty()] - [string]$StorageAccountName, - - [Parameter(HelpMessage = "Name of the storage container")] - [ValidateNotNullOrEmpty()] - [string]$StorageContainerName - ) - - Node localhost { - Script EmptyDirectory { - SetScript = { - try { - Write-Verbose -Verbose "Clearing all pre-existing files and folders from '$using:ArtifactsDirectory'" - if (Test-Path -Path $using:ArtifactsDirectory) { - Get-ChildItem $using:ArtifactsDirectory -Recurse | Remove-Item -Recurse -Force - } else { - New-Item -ItemType directory -Path $using:ArtifactsDirectory - } - } catch { - Write-Error "EmptyDirectory: $($_.Exception)" - } - } - GetScript = { @{} } - TestScript = { (Test-Path -Path $using:ArtifactsDirectory) -and -not (Test-Path -Path "$using:ArtifactsDirectory/*") } - } - - Script DownloadArtifacts { - SetScript = { - try { - Write-Verbose -Verbose "Downloading $($using:BlobNames.Length) files to '$using:ArtifactsDirectory'..." - foreach ($BlobName in $using:BlobNames) { - # Ensure that local directory exists - $LocalDir = Join-Path $using:ArtifactsDirectory $(Split-Path -Parent $BlobName) - if (-not (Test-Path -Path $LocalDir)) { - $null = New-Item -ItemType Directory -Path $LocalDir - } - $LocalFilePath = Join-Path $LocalDir (Split-Path -Leaf $BlobName) - - # Download file from blob storage - $BlobUrl = "https://$($using:StorageAccountName).blob.core.windows.net/$($using:StorageContainerName)/${BlobName}$($using:BlobSasToken)" - Write-Verbose -Verbose " [ ] Fetching $BlobUrl..." - $null = Invoke-WebRequest -Uri $BlobUrl -OutFile $LocalFilePath - if ($?) { - Write-Verbose -Verbose "Downloading $BlobUrl succeeded" - } else { - throw "Downloading $BlobUrl failed!" - } - } - } catch { - Write-Error "DownloadArtifacts: $($_.Exception)" - } - } - GetScript = { @{} } - TestScript = { $false } - DependsOn = "[Script]EmptyDirectory" - } - } -} - - -configuration CreateNetworkPolicyServer { - param ( - [Parameter(HelpMessage = "Path to the NPS MFA plugin installer")] - [ValidateNotNullOrEmpty()] - [string]$AzureMfaInstallerPath, - - [Parameter(HelpMessage = "Path to the NPS policy XML file")] - [ValidateNotNullOrEmpty()] - [string]$NpsPolicyXmlPath - ) - - Node localhost { - WindowsFeature NPAS { - Ensure = "Present" - Name = "NPAS" - } - - WindowsFeature NPASTools { - Ensure = "Present" - Name = "RSAT-NPAS" - DependsOn = "[WindowsFeature]NPAS" - } - - Script InstallNpsExtension { - SetScript = { - try { - Write-Verbose -Verbose "Installing NPS extension..." - Start-Process -FilePath $using:AzureMfaInstallerPath -ArgumentList '/install', '/quiet' - if ($?) { - Write-Verbose -Verbose "Successfully installed NPS extension" - } else { - throw "Failed to install NPS extension!" - } - } catch { - Write-Error "InstallNpsExtension: $($_.Exception)" - } - } - GetScript = { @{} } - TestScript = { $false } - DependsOn = "[WindowsFeature]NPASTools" - } - - Script ImportNpsConditionalAccessPolicy { - SetScript = { - try { - Write-Verbose -Verbose "Importing NPS configuration for RDG_CAP policy..." - Import-NpsConfiguration -Path $using:NpsPolicyXmlPath - } catch { - Write-Error "ImportNpsConditionalAccessPolicy: $($_.Exception)" - } - } - GetScript = { @{} } - TestScript = { $false } - DependsOn = "[Script]InstallNpsExtension" - } - } -} - - -configuration ConfigureNetworkPolicyServer { - param ( - [Parameter(Mandatory = $true, HelpMessage = "Base-64 encoded array of blob names to download from storage blob container")] - [ValidateNotNullOrEmpty()] - [string]$ArtifactsBlobNamesB64, - - [Parameter(Mandatory = $true, HelpMessage = "Base-64 encoded SAS token with read/list rights to the storage blob container")] - [ValidateNotNullOrEmpty()] - [string]$ArtifactsBlobSasTokenB64, - - [Parameter(Mandatory = $true, HelpMessage = "Name of the artifacts storage account")] - [ValidateNotNullOrEmpty()] - [string]$ArtifactsStorageAccountName, - - [Parameter(Mandatory = $true, HelpMessage = "Name of the artifacts storage container")] - [ValidateNotNullOrEmpty()] - [string]$ArtifactsStorageContainerName, - - [Parameter(Mandatory = $true, HelpMessage = "Absolute path to directory which blobs should be downloaded to")] - [ValidateNotNullOrEmpty()] - [string]$ArtifactsTargetDirectory - ) - - # Construct variables for passing to DSC configurations - $artifactsBlobNames = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($ArtifactsBlobNamesB64)) | ConvertFrom-Json - $artifactsBlobSasToken = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($ArtifactsBlobSasTokenB64)) - $azureMfaInstallerPath = (Join-Path $ArtifactsTargetDirectory "NpsExtnForAzureMfaInstaller.exe") - $npsPolicyXmlPath = (Join-Path $ArtifactsTargetDirectory "nps_config.xml") - - Node localhost { - InstallPowershellModules InstallPowershellModules {} - - UploadArtifacts UploadArtifacts { - BlobNames = $artifactsBlobNames - BlobSasToken = $artifactsBlobSasToken - StorageAccountName = $ArtifactsStorageAccountName - StorageContainerName = $ArtifactsStorageContainerName - ArtifactsDirectory = $ArtifactsTargetDirectory - DependsOn = "[InstallPowershellModules]InstallPowershellModules" - } - - CreateNetworkPolicyServer CreateNetworkPolicyServer { - AzureMfaInstallerPath = $azureMfaInstallerPath - NpsPolicyXmlPath = $npsPolicyXmlPath - DependsOn = "[UploadArtifacts]UploadArtifacts" - } - } -} diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/Backup.xml b/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/Backup.xml deleted file mode 100755 index 1e620c2023..0000000000 --- a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/Backup.xml +++ /dev/null @@ -1,20 +0,0 @@ - - 01 00 04 9c 00 00 00 00 00 00 00 00 00 00 00 00 14 00 00 00 04 00 ec 00 08 00 00 00 05 02 28 00 00 01 00 00 01 00 00 00 8f fd ac ed b3 ff d1 11 b4 1d 00 a0 c9 68 f9 39 01 01 00 00 00 00 00 05 0b 00 00 00 00 00 24 00 ff 00 0f 00 01 05 00 00 00 00 00 05 15 00 00 00 b2 02 19 6c 8a 79 30 07 b6 4d ff 37 00 02 00 00 00 02 24 00 ff 00 0f 00 01 05 00 00 00 00 00 05 15 00 00 00 b2 02 19 6c 8a 79 30 07 b6 4d ff 37 00 02 00 00 00 02 24 00 ff 00 0f 00 01 05 00 00 00 00 00 05 15 00 00 00 b2 02 19 6c 8a 79 30 07 b6 4d ff 37 07 02 00 00 00 02 14 00 94 00 02 00 01 01 00 00 00 00 00 05 09 00 00 00 00 02 14 00 94 00 02 00 01 01 00 00 00 00 00 05 0b 00 00 00 00 02 14 00 ff 00 0f 00 01 01 00 00 00 00 00 05 12 00 00 00 00 0a 14 00 ff 00 0f 00 01 01 00 00 00 00 00 03 00 00 00 00 - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/Machine/comment.cmtx b/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/Machine/comment.cmtx deleted file mode 100755 index 4f729bb80f..0000000000 --- a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/Machine/comment.cmtx +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/Machine/microsoft/windows nt/SecEdit/GptTmpl.inf b/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/Machine/microsoft/windows nt/SecEdit/GptTmpl.inf deleted file mode 100755 index 91061e3d80..0000000000 Binary files a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/Machine/microsoft/windows nt/SecEdit/GptTmpl.inf and /dev/null differ diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/Machine/registry.pol b/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/Machine/registry.pol deleted file mode 100755 index 22e3194e7a..0000000000 Binary files a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/Machine/registry.pol and /dev/null differ diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/User/comment.cmtx b/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/User/comment.cmtx deleted file mode 100755 index 07652973a4..0000000000 --- a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/User/comment.cmtx +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/User/registry.pol b/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/User/registry.pol deleted file mode 100755 index cc51e09d89..0000000000 Binary files a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/DomainSysvol/GPO/User/registry.pol and /dev/null differ diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/bkupInfo.xml b/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/bkupInfo.xml deleted file mode 100755 index e8f9c8626a..0000000000 --- a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/bkupInfo.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/gpreport.xml b/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/gpreport.xml deleted file mode 100755 index 904285f8a7..0000000000 Binary files a/deployment/safe_haven_management_environment/desired_state_configuration/dc1Artifacts/source/{B0A14FC3-292E-4A23-B280-9CC172D92FD5}/gpreport.xml and /dev/null differ diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/npsArtifacts/Ensure_MFA_SP_AAD.ps1 b/deployment/safe_haven_management_environment/desired_state_configuration/npsArtifacts/Ensure_MFA_SP_AAD.ps1 deleted file mode 100644 index 541098fefe..0000000000 --- a/deployment/safe_haven_management_environment/desired_state_configuration/npsArtifacts/Ensure_MFA_SP_AAD.ps1 +++ /dev/null @@ -1,4 +0,0 @@ -Import-Module MSOnline -ErrorAction Stop -Connect-MsolService -New-MsolServicePrincipal -AppPrincipalId 981f26a1-7f43-403b-a875-f8b09b8cd720 -DisplayName "Azure Multi-Factor Auth Client" -New-MsolServicePrincipal -AppPrincipalId 1f5530b3-261a-47a9-b357-ded261e17918 -DisplayName "Azure Multi-Factor Auth Connector" diff --git a/deployment/safe_haven_management_environment/desired_state_configuration/npsArtifacts/nps_config.xml b/deployment/safe_haven_management_environment/desired_state_configuration/npsArtifacts/nps_config.xml deleted file mode 100644 index 9b0a1a2e72..0000000000 --- a/deployment/safe_haven_management_environment/desired_state_configuration/npsArtifacts/nps_config.xml +++ /dev/null @@ -1,1190 +0,0 @@ - - - <_locDefinition> - <_locDefault _loc="locNone"/> - <_locDefaultAttr _loc="locNone"/> - <_locTag _loc="locNone" _locAttrData="name">Connections_to_other_access_servers - <_locTag _loc="locNone" _locAttrData="name">Connections_to_Microsoft_Routing_and_Remote_Access_server - <_locTag _loc="locNone" _locAttrData="name">Use_Windows_authentication_for_all_users - - - 257 - - - - NPS - - - - - - - 1 - 2 - 3 - 4 - 9 - 10 - 0 - - - - - 1 - 2 - 5 - 4 - 10 - 3 - 9 - 1a000000000000000000000000000000 - 0d000000000000000000000000000000 - 0 - 2 - 14 - 0100000048000000010000000100FFFF2800000001000000200000000000000001000000010000000100000000000000000000000000000000000000000000000000000000000000 - - - {00000000-0000-0000-0000-000000000000}{00000000-0000-0000-0000-000000000000}0139410712 - - - - - Connections to other access servers - TIMEOFDAY("0 00:00-24:00; 1 00:00-24:00; 2 00:00-24:00; 3 00:00-24:00; 4 00:00-24:00; 5 00:00-24:00; 6 00:00-24:00") - 999999 - - - - - Connections to Microsoft Routing and Remote Access server - MATCH("MS-RAS-Vendor=^311$") - 999998 - - - 10{00000000-0000-0000-0000-000000000000}RDG_CAPTIMEOFDAY("0 00:00-24:00; 1 00:00-24:00; 2 00:00-24:00; 3 00:00-24:00; 4 00:00-24:00; 5 00:00-24:00; 6 00:00-24:00")1 - - - - - Use Windows authentication for all users - TIMEOFDAY("0 00:00-24:00; 1 00:00-24:00; 2 00:00-24:00; 3 00:00-24:00; 4 00:00-24:00; 5 00:00-24:00; 6 00:00-24:00") - 999999 - - - - - - - - - 1 - - - - - - - - - IAS.IasHelper - 262145 - - - - - IAS.RadiusProtocol - 262144 - 1812,1645 - 1813,1646 - - - - - - - 0 - - - <_Com name="3Com"> - - 43 - - - - - 5 - - - - - 181 - - - - - 529 - - - - - 14 - - - - - 272 - - - - - 52 - - - - - 9 - - - - - 332 - - - - - 434 - - - - - 64 - - - - - 343 - - - - - 244 - - - - - 307 - - - - - 1 - - - - - 166 - - - - - 117 - - - - - 429 - - - - - 15 - - - - - 311 - - - - - 2352 - - - - - 562 - - - - - - - - - - - - - - - - - IAS.PolicyEnforcer - 7 - - - - - IAS.NTSamAuthentication - 1 - 1 - - - - - IAS.ProxyPolicyEnforcer - 5 - - - - - IAS.RadiusProxy - 8 - - - - 9IAS.Accounting1111C:\windows\system32\LogFiles0111110{00000000-0000-0000-0000-000000000000} - 13IAS.DatabaseAccounting0000020{00000000-0000-0000-0000-000000000000} - - - - - - IAS.NTEventLog - 524288 - 1 - 1 - 1 - - - - - - - - - - - - - - - - - IAS.SdoClient - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Require_Signature - Shared_Secret - NAS_Manufacturer - IP_Address - Radius_Client_Enabled - Template_Guid - Opaque_Data - Client_Secret_Template_Guid - - - - - IAS.SdoCondition - Condition_Text - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - - - - - IAS.SdoPolicy - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - msNPConstraint - msNPSequence - msNPAction - Policy_Action - Conditions - Policy_Enabled - Policy_SourceTag - Template_Guid - Opaque_Data - - - - - IAS.SdoProfile - Profile_Attributes - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Template_Guid - Opaque_Data - IP_Filter_Template_Guid - - - - - IAS.NTEventLog - Component_Id - Component_Prog_Id - Log_Application_Events - Log_Malformed_Packets - Log_Verbose - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - - - - - IAS.PolicyEnforcer - Component_Id - Component_Prog_Id - NAP_Policies - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - - - - - IAS.NTSamAuthentication - Allow_LM_Authentication - Component_Id - Component_Prog_Id - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - - - - - IAS.Accounting - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Component_Id - Component_Prog_Id - Log_Accounting_Packets - Log_Interim_Accounting_Packets - Log_Authentication_Packets - New_Log_Frequency - New_Log_Size - Log_File_Directory - Log_Format - Delete_If_Full - Log_Interim_Authentication_Packets - Log_File_Is_Backup - Discard_On_Failure - Template_Guid - Opaque_Data - - - - - IAS.SdoServiceIAS - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Description - Policies - Profiles - Protocols - Auditors - Request_Handlers - RADIUS_Server_Groups - Proxy_Policies - Proxy_Profiles - - - - - IAS.SdoTemplatesRoot - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Description - Policies_Templates - Profiles_Templates - Profiles_InPolicyTemplates - ProxyPolicies_Templates - ProxyProfiles_Templates - ProxyProfiles_InPolicyTemplates - Radius_Clients_Templates - RADIUS_Servers_Templates - RADIUS_Shared_Secrets_Templates - IP_Filters_Templates - - - - - IAS.RadiusProtocol - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Component_Id - Component_Prog_Id - Vendor_Information - Clients - Authentication_Port - Accounting_Port - - - - - IAS.IasHelper - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Component_Id - Component_Prog_Id - - - - - IAS.SdoVendor - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - NAS_Vendor_Id - - - - - IAS.SdoRadiusServerGroup - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Servers - - - - - IAS.SdoRadiusServer - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Server_Accounting_Port - Server_Authentication_Port - Accounting_Secret - Authentication_Secret - Address - Forward_Accounting_On_Off - Priority - Weight - Timeout - Maximum_Lost_Packets - Blackout_Interval - Send_Signature - Template_Guid - Opaque_Data - Auth_Secret_Template_Guid - Acct_Secret_Template_Guid - - - - - IAS.ProxyPolicyEnforcer - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Component_Id - Component_Prog_Id - NAP_Policies - - - - - IAS.RadiusProxy - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Component_Id - Component_Prog_Id - Server_Groups - - - - - IAS.DatabaseAccounting - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Component_Id - Component_Prog_Id - Log_Accounting_Packets - Log_Interim_Accounting_Packets - Log_Authentication_Packets - SQL_Max_Sessions - Log_Interim_Authentication_Packets - Discard_On_Failure - Template_Guid - Opaque_Data - - - - - IAS.SdoIPFilter - IP_Filter_Attributes - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Template_Guid - - - - - IAS.SdoSharedSecret - RADIUS_Shared_Secret - {46557888-4DB8-11d2-8ECE-00C04FC2F519} - {46557889-4DB8-11d2-8ECE-00C04FC2F519} - Template_Guid - - - - - - - - - 3 - 96 - 8 - 255 - - - - - 6 - 3120 - 8 - 38 - 38 - {00000000-0000-0000-0000-000000000000} - - - - - 7 - 1024 - 8 - - - - - - 1025 - 450 - 9 - - - - - 1026 - 450 - 9 - - - - - 1027 - 450 - 9 - - - - - 1028 - 450 - 9 - - - - - 1029 - 450 - 9 - - - - - 1024 - 1088 - 11 - 0 - - - - - 1026 - 112 - 8 - 0 - 64 - - - - - 1027 - 1088 - 3 - 0 - - - - - 1028 - 64 - 8 - - - - - 1024 - 64 - 8 - - - - - 1027 - 3136 - 8 - 1813,1646 - - - - - 1028 - 3136 - 8 - 1812,1645 - - - - - 1029 - 2498 - 9 - - - - - 1026 - 3136 - 11 - 1 - - - - - 1027 - 3136 - 11 - 0 - - - - - 1028 - 3136 - 11 - 0 - - - - - 1026 - 3136 - 11 - 1 - - - - - 1026 - 3136 - 11 - 0 - - - - - 1027 - 3136 - 11 - 0 - - - - - 1028 - 3136 - 11 - 0 - - - - - 1029 - 3148 - 3 - 0 - 0 - 5 - - - - - 1030 - 3148 - 3 - 10 - 1 - 100000 - - - - - 1031 - 3184 - 8 - 1 - 255 - %windir%\LogFiles - - - - - 1032 - 3136 - 3 - 0 - - - - - 1024 - 64 - 3 - - - - - 1025 - 64 - 8 - - - - - 1025 - 448 - 8 - - - - - 1026 - 2242 - 9 - - - - - 1024 - 576 - 8 - - - - - 1025 - 64 - 3 - - - - - 1028 - 112 - 8 - 1 - 255 - - - - - 1029 - 193 - 9 - - - - - 1030 - 450 - 9 - - - - - 1024 - 450 - 9 - - - - - 1036 - 192 - 0 - - - - - 1024 - 320 - 3 - - - - - 1030 - 450 - 9 - - - - - 1030 - 450 - 9 - - - - - 1031 - 450 - 9 - - - - - 1024 - 450 - 9 - - - - - 1024 - 450 - 9 - - - - - 1026 - 1024 - 3 - 1813 - - - - - 1027 - 0 - 8 - - - - - 1024 - 1024 - 3 - 1812 - - - - - 1025 - 1024 - 8 - - - -
- - 1028 - 0 - 8 - -
- - - 1029 - 1024 - 11 - 1 - - - - - 1030 - 1024 - 3 - 1 - - - - - 1031 - 1024 - 3 - 50 - - - - - 1026 - 2242 - 9 - - - - - 1032 - 1024 - 3 - 3 - - - - - 1033 - 1024 - 3 - 5 - - - - - 1034 - 1024 - 3 - 30 - - - - - 1034 - 3072 - 11 - 0 - - - - - 1035 - 2060 - 3 - 1 - 100 - - - - - 1036 - 3072 - 11 - 0 - - - - - 1031 - 1088 - 11 - 1 - - - - - 1030 - 1088 - 11 - 1 - - - - - 1035 - 1088 - 11 - 1 - - - - - 1032 - 1088 - 3 - 0 - - - - - 1037 - 3136 - 11 - 0 - - - - - 1038 - 3136 - 11 - 1 - - - - - 1024 - 450 - 9 - - - - - 1025 - 450 - 9 - - - - - 1026 - 450 - 9 - - - - - 1027 - 450 - 9 - - - - - 1028 - 450 - 9 - - - - - 1029 - 450 - 9 - - - - - 1032 - 450 - 9 - - - - - 1033 - 450 - 9 - - - - - 1024 - 450 - 9 - - - - - 1024 - 1024 - 8 - - - - - - 1034 - 450 - 9 - - - - - 1035 - 450 - 9 - - - - - 1025 - 3120 - 8 - 38 - 38 - {00000000-0000-0000-0000-000000000000} - - - - - 1036 - 3120 - 8 - 38 - 38 - {00000000-0000-0000-0000-000000000000} - - - - - 1037 - 3120 - 8 - 38 - 38 - {00000000-0000-0000-0000-000000000000} - - - - - 1031 - 3120 - 8 - 38 - 38 - {00000000-0000-0000-0000-000000000000} - - -
-
-
-
-
- - - - - - - - - - - - - - - -
diff --git a/deployment/safe_haven_management_environment/network_rules/shm-nsg-rules-identity.json b/deployment/safe_haven_management_environment/network_rules/shm-nsg-rules-identity.json index 86219b1118..178af1e085 100644 --- a/deployment/safe_haven_management_environment/network_rules/shm-nsg-rules-identity.json +++ b/deployment/safe_haven_management_environment/network_rules/shm-nsg-rules-identity.json @@ -59,18 +59,6 @@ "sourceAddressPrefix": "VirtualNetwork", "sourcePortRange": "*" }, - { - "name": "AllowRADIUSAuthenticationInbound", - "access": "Allow", - "description": "Allows RDS servers to connect to NPS server for MFA", - "destinationAddressPrefix": "{{nps.ip}}", - "destinationPortRange": ["1645", "1646", "1812", "1813"], - "direction": "Inbound", - "priority": 1300, - "protocol": "UDP", - "sourceAddressPrefix": "VirtualNetwork", - "sourcePortRange": "*" - }, { "name": "AllowAdminVPNInbound", "access": "Allow", diff --git a/deployment/safe_haven_management_environment/setup/Deploy_SHM.ps1 b/deployment/safe_haven_management_environment/setup/Deploy_SHM.ps1 index bd79417d1c..52d4a7489c 100755 --- a/deployment/safe_haven_management_environment/setup/Deploy_SHM.ps1 +++ b/deployment/safe_haven_management_environment/setup/Deploy_SHM.ps1 @@ -85,11 +85,6 @@ Invoke-Command -ScriptBlock { & "$(Join-Path $PSScriptRoot 'Setup_SHM_DC.ps1')" Invoke-Command -ScriptBlock { & "$(Join-Path $PSScriptRoot 'Setup_SHM_Update_Servers.ps1')" -shmId $shmId } -# Setup SHM network policy server -# ------------------------------- -Invoke-Command -ScriptBlock { & "$(Join-Path $PSScriptRoot 'Setup_SHM_NPS.ps1')" -shmId $shmId } - - # Setup SHM package repositories # ------------------------------ Invoke-Command -ScriptBlock { & "$(Join-Path $PSScriptRoot 'Setup_SHM_Package_Repositories.ps1')" -shmId $shmId } diff --git a/deployment/safe_haven_management_environment/setup/Setup_SHM_Key_Vault_And_Emergency_Admin.ps1 b/deployment/safe_haven_management_environment/setup/Setup_SHM_Key_Vault_And_Emergency_Admin.ps1 index 274b7ea571..f53e0bc012 100644 --- a/deployment/safe_haven_management_environment/setup/Setup_SHM_Key_Vault_And_Emergency_Admin.ps1 +++ b/deployment/safe_haven_management_environment/setup/Setup_SHM_Key_Vault_And_Emergency_Admin.ps1 @@ -77,7 +77,6 @@ try { try { $null = Resolve-KeyVaultSecret -VaultName $config.keyVault.name -SecretName $config.keyVault.secretNames.domainAdminPassword -DefaultLength 20 -AsPlaintext $null = Resolve-KeyVaultSecret -VaultName $config.keyVault.name -SecretName $config.dc.safemodePasswordSecretName -DefaultLength 20 -AsPlaintext - $null = Resolve-KeyVaultSecret -VaultName $config.keyVault.name -SecretName $config.nps.adminPasswordSecretName -DefaultLength 20 -AsPlaintext $null = Resolve-KeyVaultSecret -VaultName $config.keyVault.name -SecretName $config.monitoring.updateServers.linux.adminPasswordSecretName -DefaultLength 20 -AsPlaintext foreach ($repositoryTier in $config.repository.Keys) { $null = Resolve-KeyVaultSecret -VaultName $config.keyVault.name -SecretName $config.repository[$repositoryTier].nexus.adminPasswordSecretName -DefaultLength 20 -AsPlaintext diff --git a/deployment/safe_haven_management_environment/setup/Setup_SHM_NPS.ps1 b/deployment/safe_haven_management_environment/setup/Setup_SHM_NPS.ps1 deleted file mode 100644 index 21a96849bc..0000000000 --- a/deployment/safe_haven_management_environment/setup/Setup_SHM_NPS.ps1 +++ /dev/null @@ -1,130 +0,0 @@ -param( - [Parameter(Mandatory = $true, HelpMessage = "Enter SHM ID (e.g. use 'testa' for Turing Development Safe Haven A)")] - [string]$shmId -) - -Import-Module Az.Accounts -ErrorAction Stop -Import-Module Az.Compute -ErrorAction Stop -Import-Module Az.Storage -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureCompute -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureKeyVault -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureResources -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureStorage -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Configuration -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Cryptography -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/DataStructures -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Logging -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/RemoteCommands -Force -ErrorAction Stop - - -# Get config and original context before changing subscription -# ------------------------------------------------------------ -$config = Get-ShmConfig -shmId $shmId -$originalContext = Get-AzContext -$null = Set-AzContext -SubscriptionId $config.subscriptionName -ErrorAction Stop - - -# Create resource group if it does not exist -# ------------------------------------------ -$null = Deploy-ResourceGroup -Name $config.nps.rg -Location $config.location - - -# Retrieve passwords from the Key Vault -# ------------------------------------- -Add-LogMessage -Level Info "Creating/retrieving secrets from Key Vault '$($config.keyVault.name)'..." -$domainJoinPassword = Resolve-KeyVaultSecret -VaultName $config.keyVault.name -SecretName $config.users.computerManagers.identityServers.passwordSecretName -DefaultLength 20 -AsPlaintext -$vmAdminUsername = Resolve-KeyVaultSecret -VaultName $config.keyVault.name -SecretName $config.keyVault.secretNames.vmAdminUsername -DefaultValue "shm$($config.id)admin".ToLower() -AsPlaintext -$vmAdminPassword = Resolve-KeyVaultSecret -VaultName $config.keyVault.name -SecretName $config.nps.adminPasswordSecretName -DefaultLength 20 -AsPlaintext - - -# Ensure that artifacts resource group, storage account and storage container exist -# --------------------------------------------------------------------------------- -$null = Deploy-ResourceGroup -Name $config.storage.artifacts.rg -Location $config.location -$storageAccount = Deploy-StorageAccount -Name $config.storage.artifacts.accountName -ResourceGroupName $config.storage.artifacts.rg -Location $config.location -$null = Deploy-StorageContainer -Name $config.storage.artifacts.containers.shmArtifactsNPS -StorageAccount $storageAccount - - -# Upload artifacts -# ---------------- -Add-LogMessage -Level Info "Uploading NPS artifacts to storage account '$($config.storage.artifacts.accountName)'..." -try { - $success = $true - # Desired state - $dscPath = Join-Path $PSScriptRoot ".." "desired_state_configuration" - $null = Publish-AzVMDscConfiguration -ConfigurationPath (Join-Path $dscPath "NPSDesiredState.ps1") ` - -ContainerName $config.storage.artifacts.containers.shmDesiredState ` - -Force ` - -ResourceGroupName $config.storage.artifacts.rg ` - -SkipDependencyDetection ` - -StorageAccountName $config.storage.artifacts.accountName - $success = $success -and $? - # Local artifacts - foreach ($filePath in $(Get-ChildItem (Join-Path $dscPath "npsArtifacts") -Recurse)) { - $null = Set-AzStorageBlobContent -Container $config.storage.artifacts.containers.shmArtifactsNPS -Context $storageAccount.Context -File $filePath -Force - $success = $success -and $? - } - # Remote artifacts - $null = Set-AzureStorageBlobFromUri -FileUri "https://raw.githubusercontent.com/Azure-Samples/azure-mfa-nps-extension-health-check/master/MFA_NPS_Troubleshooter.ps1" -StorageContainer $config.storage.artifacts.containers.shmArtifactsNPS -StorageContext $storageAccount.Context - $null = Set-AzureStorageBlobFromUri -FileUri "https://download.microsoft.com/download/B/F/F/BFFB4F12-9C09-4DBC-A4AF-08E51875EEA9/NpsExtnForAzureMfaInstaller.exe" -StorageContainer $config.storage.artifacts.containers.shmArtifactsNPS -StorageContext $storageAccount.Context - if (-not $success) { throw } - Add-LogMessage -Level Success "Uploaded NPS artifacts to storage account '$($config.storage.artifacts.accountName)'" -} catch { - Add-LogMessage -Level Fatal "Failed to upload NPS artifacts to storage account '$($config.storage.artifacts.accountName)'!" -} - - -# Deploy NPS from template -# ------------------------ -Add-LogMessage -Level Info "Deploying network policy server (NPS) from template..." -$params = @{ - administratorPassword = (ConvertTo-SecureString $vmAdminPassword -AsPlainText -Force) - administratorUsername = $vmAdminUsername - bootDiagnosticsAccountName = $config.storage.bootdiagnostics.accountName - domainJoinOuPath = $config.domain.ous.identityServers.path - domainJoinPassword = (ConvertTo-SecureString $domainJoinPassword -AsPlainText -Force) - domainJoinUser = $config.users.computerManagers.identityServers.samAccountName - domainName = $config.domain.fqdn - virtualNetworkName = $config.network.vnet.name - virtualNetworkResourceGroupName = $config.network.vnet.rg - virtualNetworkSubnetName = $config.network.vnet.subnets.identity.name - vmHostName = $config.nps.hostname - vmName = $config.nps.vmName - vmOsDiskSizeGb = [int]$config.nps.disks.os.sizeGb - vmOsDiskType = $config.nps.disks.os.type - vmPrivateIpAddress = $config.nps.ip - vmSize = $config.nps.vmSize -} -Deploy-ArmTemplate -TemplatePath (Join-Path $PSScriptRoot ".." "arm_templates" "shm-nps-template.json") -TemplateParameters $params -ResourceGroupName $config.nps.rg - - -# Apply SHM NPS desired state -# --------------------------- -Add-LogMessage -Level Info "Installing desired state prerequisites on NPS..." -$null = Invoke-RemoteScript -Shell "PowerShell" -ScriptPath (Join-Path $dscPath "NPSBootstrap.ps1") -VMName $config.nps.vmName -ResourceGroupName $config.nps.rg -SuppressOutput -$params = @{ - ArtifactsBlobNamesB64 = Get-AzStorageBlob -Container $config.storage.artifacts.containers.shmArtifactsNPS -Context $storageAccount.Context | ForEach-Object { $_.Name } | ConvertTo-Json -Depth 99 | ConvertTo-Base64 - ArtifactsBlobSasTokenB64 = (New-ReadOnlyStorageAccountSasToken -SubscriptionName $config.subscriptionName -ResourceGroup $config.storage.artifacts.rg -AccountName $config.storage.artifacts.accountName) | ConvertTo-Base64 - ArtifactsStorageAccountName = $config.storage.artifacts.accountName - ArtifactsStorageContainerName = $config.storage.artifacts.containers.shmArtifactsNPS - ArtifactsTargetDirectory = $config.nps.installationDirectory -} -$null = Invoke-AzureVmDesiredState -ArchiveBlobName "NPSDesiredState.ps1.zip" ` - -ArchiveContainerName $config.storage.artifacts.containers.shmDesiredState ` - -ArchiveResourceGroupName $config.storage.artifacts.rg ` - -ArchiveStorageAccountName $config.storage.artifacts.accountName ` - -ConfigurationName "ConfigureNetworkPolicyServer" ` - -ConfigurationParameters $params ` - -VmLocation $config.location ` - -VmName $config.nps.vmName ` - -VmResourceGroupName $config.nps.rg - - -# Set locale, install updates and reboot -# -------------------------------------- -Add-LogMessage -Level Info "Updating NPS VM '$($config.nps.vmName)'..." -Invoke-WindowsConfiguration -VMName $config.nps.vmName -ResourceGroupName $config.nps.rg -TimeZone $config.time.timezone.windows -NtpServer ($config.time.ntp.serverAddresses)[0] - - -# Switch back to original subscription -# ------------------------------------ -$null = Set-AzContext -Context $originalContext -ErrorAction Stop diff --git a/deployment/secure_research_environment/arm_templates/sre-rds-template.json b/deployment/secure_research_environment/arm_templates/sre-rds-template.json deleted file mode 100644 index bc01b3920f..0000000000 --- a/deployment/secure_research_environment/arm_templates/sre-rds-template.json +++ /dev/null @@ -1,481 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "administratorUsername": { - "type": "string", - "metadata": { - "description": "Enter name for VM Administrator" - } - }, - "bootDiagnosticsAccountName": { - "type": "string", - "metadata": { - "description": "Enter name of storage account used for boot diagnostics" - } - }, - "domainName": { - "type": "string", - "metadata": { - "Description": "Public domain name for the SHM" - } - }, - "gatewayAdministratorPassword": { - "type": "securestring", - "metadata": { - "description": "Password for RDS gateway" - } - }, - "gatewayDataDiskSizeGb": { - "type": "int" - }, - "gatewayDataDiskType": { - "type": "string" - }, - "gatewayDomainJoinOuPath": { - "type": "string", - "metadata": { - "description": "Enter OU path for gateway VMs" - } - }, - "gatewayDomainJoinPassword": { - "type": "securestring", - "metadata": { - "description": "Enter name for DC Administrator Password" - } - }, - "gatewayDomainJoinUser": { - "type": "string", - "metadata": { - "description": "Enter name for DC Administrator" - } - }, - "gatewayNsgName": { - "type": "string", - "metadata": { - "description": "Enter NSG Gateway Name" - } - }, - "gatewayOsDiskSizeGb": { - "type": "int" - }, - "gatewayOsDiskType": { - "type": "string" - }, - "gatewayPrivateIpAddress": { - "type": "string", - "defaultValue": "10.250.x.250", - "metadata": { - "description": "Enter IP address for RDS Gateway VM, must end in 250" - } - }, - "gatewayVmName": { - "type": "string", - "metadata": { - "description": "Name of the RDS gateway VM" - } - }, - "gatewayVmSize": { - "type": "string", - "defaultValue": "Standard_B2ms", - "metadata": { - "description": "Select size of RDS Gateway VM" - } - }, - - "sessionHostAppsAdministratorPassword": { - "type": "securestring", - "metadata": { - "description": "Password for RDS gateway" - } - }, - "sessionHostAppsOsDiskSizeGb": { - "type": "int" - }, - "sessionHostAppsOsDiskType": { - "type": "string" - }, - "sessionHostAppsPrivateIpAddress": { - "type": "string", - "defaultValue": "10.250.x.249", - "metadata": { - "description": "Enter IP address for RDS_Session_Host_Apps VM, must end in 249" - } - }, - "sessionHostAppsVmName": { - "type": "string", - "metadata": { - "description": "Name of the RDS apps session host VM" - } - }, - "sessionHostAppsVmSize": { - "type": "string", - "defaultValue": "Standard_B2ms", - "metadata": { - "description": "Select size of RDS_Session_Host_Apps VM" - } - }, - "sessionHostsDomainJoinOuPath": { - "type": "string", - "metadata": { - "description": "Enter OU path for session host VMs" - } - }, - "sessionHostsDomainJoinPassword": { - "type": "securestring", - "metadata": { - "description": "Enter name for DC Administrator Password" - } - }, - "sessionHostsDomainJoinUser": { - "type": "string", - "metadata": { - "description": "Enter name for DC Administrator" - } - }, - "virtualNetworkGatewaySubnetName": { - "type": "string", - "metadata": { - "description": "Name of the subnet that the RDS gateway should belong to" - } - }, - "virtualNetworkName": { - "type": "string", - "metadata": { - "description": "Name of virtual network to provision these VMs" - } - }, - "virtualNetworkResourceGroupName": { - "type": "string", - "metadata": { - "description": "Name of resource group that is associated with the virtual network above" - } - }, - "virtualNetworkSessionHostsSubnetName": { - "type": "string", - "metadata": { - "description": "Name of the subnet that the RDS gateway should belong to" - } - }, - }, - "variables": { - "rdsGatewayNic": "[concat(parameters('gatewayVmName'),'-','NIC')]", - "rdsAppSessionHostNic": "[concat(parameters('sessionHostAppsVmName'),'-','NIC')]", - "rdsGatewayPip": "[concat(parameters('gatewayVmName'),'-','PIP')]", - "vnetID": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]", - "rdsGatewaySubnet": "[concat(variables('vnetID'),'/subnets/', parameters('virtualNetworkGatewaySubnetName'))]", - "rdsServersSubnet": "[concat(variables('vnetID'),'/subnets/', parameters('virtualNetworkSessionHostsSubnetName'))]" - }, - "resources": [ - { - "type": "Microsoft.Compute/virtualMachines", - "name": "[parameters('gatewayVmName')]", - "apiVersion": "2021-11-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "hardwareProfile": { - "vmSize": "[parameters('gatewayVmSize')]" - }, - "storageProfile": { - "imageReference": { - "publisher": "MicrosoftWindowsServer", - "offer": "WindowsServer", - "sku": "2022-Datacenter", - "version": "latest" - }, - "osDisk": { - "osType": "Windows", - "name": "[concat(parameters('gatewayVmName'),'-OS-DISK')]", - "createOption": "FromImage", - "caching": "ReadWrite", - "writeAcceleratorEnabled": false, - "managedDisk": { - "storageAccountType": "[parameters('gatewayOsDiskType')]" - }, - "diskSizeGB": "[parameters('gatewayOsDiskSizeGb')]" - }, - "dataDisks": [ - { - "lun": 0, - "name": "[concat(parameters('gatewayVmName'),'-DATA-DISK')]", - "createOption": "Empty", - "caching": "None", - "writeAcceleratorEnabled": false, - "managedDisk": { - "storageAccountType": "[parameters('gatewayDataDiskType')]" - }, - "diskSizeGB": "[parameters('gatewayDataDiskSizeGb')]" - } - ] - }, - "osProfile": { - "computerName": "[parameters('gatewayVmName')]", - "adminUsername": "[parameters('administratorUsername')]", - "adminPassword": "[parameters('gatewayAdministratorPassword')]", - "windowsConfiguration": { - "enableAutomaticUpdates": true, - "provisionVMAgent": true - }, - "secrets": [], - "allowExtensionOperations": true - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('rdsGatewayNic'))]", - "properties": { - "primary": true - } - } - ] - }, - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": true, - "storageUri": "[concat('https://', parameters('bootDiagnosticsAccountName'), '.blob.core.windows.net/')]" - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/networkInterfaces', variables('rdsGatewayNic'))]" - ] - }, - { - "type": "Microsoft.Compute/virtualMachines", - "name": "[parameters('sessionHostAppsVmName')]", - "apiVersion": "2021-11-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "hardwareProfile": { - "vmSize": "[parameters('sessionHostAppsVmSize')]" - }, - "storageProfile": { - "imageReference": { - "publisher": "MicrosoftWindowsServer", - "offer": "WindowsServer", - "sku": "2022-Datacenter", - "version": "latest" - }, - "osDisk": { - "osType": "Windows", - "name": "[concat(parameters('sessionHostAppsVmName'),'-OS-DISK')]", - "createOption": "FromImage", - "caching": "ReadWrite", - "writeAcceleratorEnabled": false, - "managedDisk": { - "storageAccountType": "[parameters('sessionHostAppsOsDiskType')]" - }, - "diskSizeGB": "[parameters('sessionHostAppsOsDiskSizeGb')]" - }, - "dataDisks": [] - }, - "osProfile": { - "computerName": "[parameters('sessionHostAppsVmName')]", - "adminUsername": "[parameters('administratorUsername')]", - "adminPassword": "[parameters('sessionHostAppsAdministratorPassword')]", - "windowsConfiguration": { - "enableAutomaticUpdates": true, - "provisionVMAgent": true - }, - "secrets": [], - "allowExtensionOperations": true - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('rdsAppSessionHostNic'))]", - "properties": { - "primary": true - } - } - ] - }, - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": true, - "storageUri": "[concat('https://', parameters('bootDiagnosticsAccountName'), '.blob.core.windows.net/')]" - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/networkInterfaces', variables('rdsAppSessionHostNic'))]" - ] - }, - { - "type": "Microsoft.Network/networkInterfaces", - "name": "[variables('rdsAppSessionHostNic')]", - "apiVersion": "2020-11-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "ipConfigurations": [ - { - "name": "ipConfigRdsAppSessionHost", - "properties": { - "privateIPAddress": "[parameters('sessionHostAppsPrivateIpAddress')]", - "privateIPAllocationMethod": "Static", - "subnet": { - "id": "[variables('rdsServersSubnet')]" - }, - "primary": true, - "privateIPAddressVersion": "IPv4" - } - } - ], - "dnsSettings": { - "dnsServers": [], - "appliedDnsServers": [] - }, - "enableAcceleratedNetworking": false, - "enableIPForwarding": false, - "primary": true, - "tapConfigurations": [] - }, - "dependsOn": [] - }, - { - "type": "Microsoft.Network/networkInterfaces", - "name": "[variables('rdsGatewayNic')]", - "apiVersion": "2020-11-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "ipConfigurations": [ - { - "name": "ipConfigRdsGateway", - "properties": { - "privateIPAddress": "[parameters('gatewayPrivateIpAddress')]", - "privateIPAllocationMethod": "Static", - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('rdsGatewayPip'))]" - }, - "subnet": { - "id": "[variables('rdsGatewaySubnet')]" - }, - "primary": true, - "privateIPAddressVersion": "IPv4" - } - } - ], - "dnsSettings": { - "dnsServers": [], - "appliedDnsServers": [] - }, - "enableAcceleratedNetworking": false, - "enableIPForwarding": false, - "networkSecurityGroup": { - "id": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/networkSecurityGroups', parameters('gatewayNsgName'))]" - }, - "primary": true, - "tapConfigurations": [] - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses', variables('rdsGatewayPip'))]" - ] - }, - { - "type": "Microsoft.Network/publicIPAddresses", - "sku": { - "name": "Basic", - "tier": "Regional" - }, - "name": "[variables('rdsGatewayPip')]", - "apiVersion": "2020-11-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "publicIPAddressVersion": "IPv4", - "publicIPAllocationMethod": "Static", - "idleTimeoutInMinutes": 4, - "ipTags": [] - }, - "dependsOn": [] - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "name": "[concat(parameters('gatewayVmName'), '/', 'bginfo')]", - "apiVersion": "2021-11-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "autoUpgradeMinorVersion": true, - "publisher": "Microsoft.Compute", - "type": "bginfo", - "typeHandlerVersion": "2.1" - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('gatewayVmName'))]" - ] - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "name": "[concat(parameters('sessionHostAppsVmName'), '/', 'bginfo')]", - "apiVersion": "2021-11-01", - "location": "[resourceGroup().location]", - "scale": null, - "properties": { - "autoUpgradeMinorVersion": true, - "publisher": "Microsoft.Compute", - "type": "bginfo", - "typeHandlerVersion": "2.1" - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('sessionHostAppsVmName'))]" - ] - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "name": "[concat(parameters('gatewayVmName'),'/joindomain')]", - "apiVersion": "2021-11-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('gatewayVmName'))]", - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('gatewayVmName'),'bginfo')]" - ], - "properties": { - "publisher": "Microsoft.Compute", - "type": "JsonADDomainExtension", - "typeHandlerVersion": "1.3", - "autoUpgradeMinorVersion": true, - "settings": { - "Name": "[parameters('domainName')]", - "OUPath": "[parameters('gatewayDomainJoinOuPath')]", - "User": "[concat(parameters('domainName'), '\\', parameters('gatewayDomainJoinUser'))]", - "Restart": "true", - "Options": "3" - }, - "protectedSettings": { - "Password": "[parameters('gatewayDomainJoinPassword')]" - } - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "name": "[concat(parameters('sessionHostAppsVmName'),'/joindomain')]", - "apiVersion": "2021-11-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('sessionHostAppsVmName'))]", - "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('sessionHostAppsVmName'),'bginfo')]" - ], - "properties": { - "publisher": "Microsoft.Compute", - "type": "JsonADDomainExtension", - "typeHandlerVersion": "1.3", - "autoUpgradeMinorVersion": true, - "settings": { - "Name": "[parameters('domainName')]", - "OUPath": "[parameters('sessionHostsDomainJoinOuPath')]", - "User": "[concat(parameters('domainName'), '\\', parameters('sessionHostsDomainJoinUser'))]", - "Restart": "true", - "Options": "3" - }, - "protectedSettings": { - "Password": "[parameters('sessionHostsDomainJoinPassword')]" - } - } - } - ] -} \ No newline at end of file diff --git a/deployment/secure_research_environment/network_rules/sre-nsg-rules-gateway.json b/deployment/secure_research_environment/network_rules/sre-nsg-rules-gateway.json deleted file mode 100644 index 3fbd5c0b10..0000000000 --- a/deployment/secure_research_environment/network_rules/sre-nsg-rules-gateway.json +++ /dev/null @@ -1,222 +0,0 @@ -[ - { - "name": "AllowRDSSessionHostsInbound", - "access": "Allow", - "description": "Allow inbound connections from RDS session hosts", - "destinationAddressPrefix": "{{sre.remoteDesktop.gateway.ip}}", - "destinationPortRange": ["135", "137-139", "443", "445", "3389", "3391", "5504", "5985", "49152-65535"], - "direction": "Inbound", - "priority": 700, - "protocol": "*", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowAdminVPNInbound", - "access": "Allow", - "description": "Allow RDP connection to servers from admin P2S VPN", - "destinationAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "destinationPortRange": "3389", - "direction": "Inbound", - "priority": 2000, - "protocol": "TCP", - "sourceAddressPrefix": "{{shm.network.vpn.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowUsersApprovedHttpsInbound", - "access": "Allow", - "description": "Allow inbound https connections from clients to RDS server", - "destinationAddressPrefix": "{{sre.remoteDesktop.gateway.ip}}", - "destinationPortRange": "443", - "direction": "Inbound", - "priority": 2200, - "protocol": "TCP", - "sourceAddressPrefix": [ - {{#sre.remoteDesktop.networkRules.allowedSources}} - "{{.}}", - {{/sre.remoteDesktop.networkRules.allowedSources}} - ], - "sourcePortRange": "*" - }, - { - "name": "AllowExternalSslLabsHttpsInbound", - "access": "Allow", - "description": "Allow inbound https connections from ssllabs.com for SSL quality reporting", - "destinationAddressPrefix": "{{sre.remoteDesktop.gateway.ip}}", - "destinationPortRange": "443", - "direction": "Inbound", - "priority": 3400, - "protocol": "TCP", - "sourceAddressPrefix": "64.41.200.0/24", - "sourcePortRange": "*" - }, - { - "name": "DenyAllOtherInbound", - "access": "Deny", - "description": "Deny all other inbound traffic.", - "destinationAddressPrefix": "*", - "destinationPortRange": "*", - "direction": "Inbound", - "priority": 4096, - "protocol": "*", - "sourceAddressPrefix": "*", - "sourcePortRange": "*" - }, - { - "name": "AllowPrivateDataEndpointsOutbound", - "access": "Allow", - "description": "Allow outbound connections to private endpoints in the VNet", - "destinationAddressPrefix": "{{sre.network.vnet.subnets.data.cidr}}", - "destinationPortRange": "*", - "direction": "Outbound", - "priority": 400, - "protocol": "*", - "sourceAddressPrefix": "{{sre.remoteDesktop.gateway.ip}}", - "sourcePortRange": "*" - }, - { - "name": "AllowRDSSessionHostsOutbound", - "access": "Allow", - "description": "Allow outbound connections to RDS session hosts", - "destinationAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "destinationPortRange": ["135", "137-139", "443", "445", "3389", "3391", "5504", "5985", "49152-65535"], - "direction": "Outbound", - "priority": 700, - "protocol": "*", - "sourceAddressPrefix": "{{sre.remoteDesktop.gateway.ip}}", - "sourcePortRange": "*" - }, - { - "name": "AllowDomainJoinedClientsUdpOutbound", - "access": "Allow", - "description": "Allow domain-joined client requests over UDP: Kerberos; LDAP.", - "destinationAddressPrefix": "{{shm.network.vnet.subnets.identity.cidr}}", - "destinationPortRange": ["88", "389"], - "direction": "Outbound", - "priority": 1000, - "protocol": "UDP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowDomainJoinedClientsTcpOutbound", - "access": "Allow", - "description": "Allow domain-joined client requests over TCP: (see https://devopstales.github.io/linux/pfsense-ad-join/ for details).", - "destinationAddressPrefix": "{{shm.network.vnet.subnets.identity.cidr}}", - "destinationPortRange": ["88", "135", "139", "389", "445", "464", "636", "3268", "3269", "49152-65535"], - "direction": "Outbound", - "priority": 1100, - "protocol": "TCP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowDNSOutbound", - "access": "Allow", - "description": "Allow DNS requests to SHM", - "destinationAddressPrefix": "{{shm.network.vnet.subnets.identity.cidr}}", - "destinationPortRange": "53", - "direction": "Outbound", - "priority": 1200, - "protocol": "*", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowRADIUSAuthenticationOutbound", - "access": "Allow", - "description": "Allows RDS servers to connect to NPS server for MFA", - "destinationAddressPrefix": "{{shm.nps.ip}}", - "destinationPortRange": ["1645", "1646", "1812", "1813"], - "direction": "Outbound", - "priority": 1300, - "protocol": "UDP", - "sourceAddressPrefix": "{{sre.remoteDesktop.gateway.ip}}", - "sourcePortRange": "*" - }, - { - "name": "AllowMonitoringToolsOutbound", - "access": "Allow", - "description": "Allow connections to local monitoring tools", - "destinationAddressPrefix": "{{shm.network.vnet.subnets.monitoring.cidr}}", - "destinationPortRange": "443", - "direction": "Outbound", - "priority": 1500, - "protocol": "TCP", - "sourceAddressPrefix": "{{sre.remoteDesktop.gateway.ip}}", - "sourcePortRange": "*" - }, - { - "name": "AllowExternalNTPOutbound", - "access": "Allow", - "description": "Allow outbound connections to external NTP servers", - "destinationAddressPrefix": [ - {{#shm.time.ntp.serverAddresses}} - "{{.}}", - {{/shm.time.ntp.serverAddresses}} - ], - "destinationPortRange": "123", - "direction": "Outbound", - "priority": 3000, - "protocol": "UDP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowWindowsUpdatesOutbound", - "access": "Allow", - "description": "Allow outbound connections to Windows update servers", - "destinationAddressPrefix": [ - {{#shm.monitoring.updateServers.externalIpAddresses.windows}} - "{{.}}", - {{/shm.monitoring.updateServers.externalIpAddresses.windows}} - ], - "destinationPortRange": ["80", "443"], - "direction": "Outbound", - "priority": 3700, - "protocol": "TCP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowAzureAutomationOutbound", - "access": "Allow", - "description": "Allow outbound connections to Azure automation servers", - "destinationAddressPrefix": [ - {{#shm.monitoring.updateServers.externalIpAddresses.azureAutomation}} - "{{.}}", - {{/shm.monitoring.updateServers.externalIpAddresses.azureAutomation}} - ], - "destinationPortRange": ["443"], - "direction": "Outbound", - "priority": 3800, - "protocol": "TCP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowExternalInternetOutbound", - "access": "Allow", - "description": "Allow outbound connections to internet", - "destinationAddressPrefix": "Internet", - "destinationPortRange": "*", - "direction": "Outbound", - "priority": 3900, - "protocol": "*", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "DenyAllOtherOutbound", - "access": "Deny", - "description": "Deny all other outbound traffic.", - "destinationAddressPrefix": "*", - "destinationPortRange": "*", - "direction": "Outbound", - "priority": 4096, - "protocol": "*", - "sourceAddressPrefix": "*", - "sourcePortRange": "*" - } -] diff --git a/deployment/secure_research_environment/network_rules/sre-nsg-rules-session-hosts.json b/deployment/secure_research_environment/network_rules/sre-nsg-rules-session-hosts.json deleted file mode 100644 index 90b87ac4e6..0000000000 --- a/deployment/secure_research_environment/network_rules/sre-nsg-rules-session-hosts.json +++ /dev/null @@ -1,194 +0,0 @@ -[ - { - "name": "AllowRDSGatewayInbound", - "access": "Allow", - "description": "Allow inbound connections from RDS gateway", - "destinationAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "destinationPortRange": ["135", "137-139", "443", "445", "3389", "3391", "5504", "5985", "49152-65535"], - "direction": "Inbound", - "priority": 700, - "protocol": "*", - "sourceAddressPrefix": "{{sre.remoteDesktop.gateway.ip}}", - "sourcePortRange": "*" - }, - { - "name": "DenyAdminVPNInbound", - "access": "Deny", - "description": "Deny connections from admin P2S VPN", - "destinationAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "destinationPortRange": "*", - "direction": "Inbound", - "priority": 2000, - "protocol": "*", - "sourceAddressPrefix": "{{shm.network.vpn.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "DenyAllOtherInbound", - "access": "Deny", - "description": "Deny all other inbound traffic.", - "destinationAddressPrefix": "*", - "destinationPortRange": "*", - "direction": "Inbound", - "priority": 4096, - "protocol": "*", - "sourceAddressPrefix": "*", - "sourcePortRange": "*" - }, - { - "name": "AllowWebappsSubnetOutbound", - "access": "Allow", - "description": "Allow outbound http(s) connections to the webapps subnet", - "destinationAddressPrefix": "{{sre.network.vnet.subnets.webapps.cidr}}", - "destinationPortRange": ["80", "443"], - "direction": "Outbound", - "priority": 600, - "protocol": "TCP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowRDSGatewayOutbound", - "access": "Allow", - "description": "Allow outbound connections to RDS gateway", - "destinationAddressPrefix": "{{sre.remoteDesktop.gateway.ip}}", - "destinationPortRange": ["135", "137-139", "443", "445", "3389", "3391", "5504", "5985", "49152-65535"], - "direction": "Outbound", - "priority": 700, - "protocol": "*", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowSRDOutbound", - "access": "Allow", - "description": "Allow connections to SRDs from session hosts", - "destinationAddressPrefix": "{{sre.network.vnet.subnets.compute.cidr}}", - "destinationPortRange": ["22", "3389"], - "direction": "Outbound", - "priority": 800, - "protocol": "*", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowDomainJoinedClientsUdpOutbound", - "access": "Allow", - "description": "Allow domain-joined client requests over UDP: Kerberos; LDAP.", - "destinationAddressPrefix": "{{shm.network.vnet.subnets.identity.cidr}}", - "destinationPortRange": ["88", "389"], - "direction": "Outbound", - "priority": 1000, - "protocol": "UDP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowDomainJoinedClientsTcpOutbound", - "access": "Allow", - "description": "Allow domain-joined client requests over TCP: (see https://devopstales.github.io/linux/pfsense-ad-join/ for details).", - "destinationAddressPrefix": "{{shm.network.vnet.subnets.identity.cidr}}", - "destinationPortRange": ["88", "135", "139", "389", "445", "464", "636", "3268", "3269", "49152-65535"], - "direction": "Outbound", - "priority": 1100, - "protocol": "TCP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowDNSOutbound", - "access": "Allow", - "description": "Allow DNS requests to SHM", - "destinationAddressPrefix": "{{shm.network.vnet.subnets.identity.cidr}}", - "destinationPortRange": "53", - "direction": "Outbound", - "priority": 1200, - "protocol": "*", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowMonitoringToolsOutbound", - "access": "Allow", - "description": "Allow connections to local monitoring tools", - "destinationAddressPrefix": "{{shm.network.vnet.subnets.monitoring.cidr}}", - "destinationPortRange": "443", - "direction": "Outbound", - "priority": 1500, - "protocol": "TCP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowExternalNTPOutbound", - "access": "Allow", - "description": "Allow outbound connections to external NTP servers", - "destinationAddressPrefix": [ - {{#shm.time.ntp.serverAddresses}} - "{{.}}", - {{/shm.time.ntp.serverAddresses}} - ], - "destinationPortRange": "123", - "direction": "Outbound", - "priority": 3000, - "protocol": "UDP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.remoteDesktop.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowWindowsUpdatesOutbound", - "access": "Allow", - "description": "Allow outbound connections to Windows update servers", - "destinationAddressPrefix": [ - {{#shm.monitoring.updateServers.externalIpAddresses.windows}} - "{{.}}", - {{/shm.monitoring.updateServers.externalIpAddresses.windows}} - ], - "destinationPortRange": ["80", "443"], - "direction": "Outbound", - "priority": 3700, - "protocol": "TCP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.databases.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "AllowAzureAutomationOutbound", - "access": "Allow", - "description": "Allow outbound connections to Azure automation servers", - "destinationAddressPrefix": [ - {{#shm.monitoring.updateServers.externalIpAddresses.azureAutomation}} - "{{.}}", - {{/shm.monitoring.updateServers.externalIpAddresses.azureAutomation}} - ], - "destinationPortRange": ["443"], - "direction": "Outbound", - "priority": 3800, - "protocol": "TCP", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.databases.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "DenyExternalInternetOutbound", - "access": "Deny", - "description": "Allow outbound connections to internet", - "destinationAddressPrefix": "Internet", - "destinationPortRange": "*", - "direction": "Outbound", - "priority": 3900, - "protocol": "*", - "sourceAddressPrefix": "{{sre.network.vnet.subnets.databases.cidr}}", - "sourcePortRange": "*" - }, - { - "name": "DenyAllOtherOutbound", - "access": "Deny", - "description": "Deny all other outbound traffic.", - "destinationAddressPrefix": "*", - "destinationPortRange": "*", - "direction": "Outbound", - "priority": 4096, - "protocol": "*", - "sourceAddressPrefix": "*", - "sourcePortRange": "*" - } -] diff --git a/deployment/secure_research_environment/remote/configure_shm_dc/scripts/Remove_RDS_Gateway_RADIUS_Client_Remote.ps1 b/deployment/secure_research_environment/remote/configure_shm_dc/scripts/Remove_RDS_Gateway_RADIUS_Client_Remote.ps1 deleted file mode 100644 index a7f6926353..0000000000 --- a/deployment/secure_research_environment/remote/configure_shm_dc/scripts/Remove_RDS_Gateway_RADIUS_Client_Remote.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -# Don't make parameters mandatory as if there is any issue binding them, the script will prompt for them -# and remote execution will stall waiting for the non-present user to enter the missing parameter on the -# command line. This take up to 90 minutes to timeout, though you can try running resetState.cmd in -# C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.0 on the remote VM to cancel a stalled -# job, but this does not seem to have an immediate effect -# For details, see https://docs.microsoft.com/en-gb/azure/virtual-machines/windows/run-command -param( - [Parameter(Mandatory = $false, HelpMessage = "FQDN of RDS gateway")] - [String]$rdsGatewayFqdn -) - -if (Get-NpsRadiusClient | Where-Object { $_.Name -eq "$rdsGatewayFqdn" }) { - Write-Output " [ ] Removing RADIUS Client '$rdsGatewayFqdn'" - Remove-NpsRadiusClient -Name "$rdsGatewayFqdn" - if ($?) { - Write-Output " [o] Succeeded" - } else { - Write-Output " [x] Failed" - exit 1 - } -} else { - Write-Output "No RADIUS Client '$rdsGatewayFqdn' exists" -} diff --git a/deployment/secure_research_environment/remote/create_rds/scripts/Add_RDS_Gateway_RADIUS_Client_Remote.ps1 b/deployment/secure_research_environment/remote/create_rds/scripts/Add_RDS_Gateway_RADIUS_Client_Remote.ps1 deleted file mode 100644 index d75e0e5074..0000000000 --- a/deployment/secure_research_environment/remote/create_rds/scripts/Add_RDS_Gateway_RADIUS_Client_Remote.ps1 +++ /dev/null @@ -1,72 +0,0 @@ -# Don't make parameters mandatory as if there is any issue binding them, the script will prompt for them -# and remote execution will stall waiting for the non-present user to enter the missing parameter on the -# command line. This take up to 90 minutes to timeout, though you can try running resetState.cmd in -# C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.0 on the remote VM to cancel a stalled -# job, but this does not seem to have an immediate effect -# For details, see https://docs.microsoft.com/en-gb/azure/virtual-machines/windows/run-command -param( - [Parameter(HelpMessage = "Base-64 encoded NPS secret")] - [ValidateNotNullOrEmpty()] - [string]$npsSecretB64, - [Parameter(HelpMessage = "IP address of RDS gateway")] - [ValidateNotNullOrEmpty()] - [string]$rdsGatewayIp, - [Parameter(HelpMessage = "FQDN of RDS gateway")] - [ValidateNotNullOrEmpty()] - [string]$rdsGatewayFqdn, - [Parameter(HelpMessage = "SRE ID")] - [ValidateNotNullOrEmpty()] - [string]$sreId -) - - -# Deserialise Base-64 encoded variables -# ------------------------------------- -$npsSecret = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($npsSecretB64)) - - -# Ensure that RADIUS client is registered -# --------------------------------------- -Write-Output "Ensuring that RADIUS client '$rdsGatewayFqdn' is registered..." -if (Get-NpsRadiusClient | Where-Object { $_.Name -eq "$rdsGatewayFqdn" }) { - Write-Output " [o] RADIUS client '$rdsGatewayFqdn' already exists" - Write-Output "Updating RADIUS client '$rdsGatewayFqdn' at '$rdsGatewayIp'..." - $null = Set-NpsRadiusClient -Address $rdsGatewayIp -Name "$rdsGatewayFqdn" -SharedSecret "$npsSecret" - if ($?) { - Write-Output " [o] Successfully updated RADIUS client" - } else { - Write-Output " [x] Failed to update RADIUS client!" - } -} else { - Write-Output "Creating RADIUS client '$rdsGatewayFqdn' at '$rdsGatewayIp'..." - $null = New-NpsRadiusClient -Address $rdsGatewayIp -Name "$rdsGatewayFqdn" -SharedSecret "$npsSecret" - if ($?) { - Write-Output " [o] Successfully created RADIUS client" - } else { - Write-Output " [x] Failed to create RADIUS client!" - } -} - - -# Add RDS gateway inbound rule -# ---------------------------- -Write-Output "Adding RDS gateway inbound rule..." -$ruleName = "SRE $($sreId.ToUpper()) RDS Gateway RADIUS inbound ($rdsGatewayIp)" -if (Get-NetFirewallRule | Where-Object { $_.DisplayName -eq "$ruleName" }) { - Write-Output " [o] Inbound RADIUS firewall rule '$ruleName' already exists" - Write-Output "Updating '$ruleName' inbound RADIUS firewall rule for $rdsGatewayFqdn ($rdsGatewayIp)..." - $null = Set-NetFirewallRule -DisplayName $ruleName -Direction Inbound -RemoteAddress $rdsGatewayIp -Action Allow -Protocol UDP -LocalPort "1645", "1646", "1812", "1813" -Profile Domain -Enabled True - if ($?) { - Write-Output " [o] Successfully updated RDS gateway inbound rule" - } else { - Write-Output " [x] Failed to update RDS gateway inbound rule!" - } -} else { - Write-Output "Adding '$ruleName' inbound RADIUS firewall rule for $rdsGatewayFqdn ($rdsGatewayIp)..." - $null = New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -RemoteAddress $rdsGatewayIp -Action Allow -Protocol UDP -LocalPort "1645", "1646", "1812", "1813" -Profile Domain -Enabled True - if ($?) { - Write-Output " [o] Successfully added RDS gateway inbound rule" - } else { - Write-Output " [x] Failed to add RDS gateway inbound rule!" - } -} diff --git a/deployment/secure_research_environment/remote/create_rds/scripts/Configure_CAP_And_RAP_Remote.ps1 b/deployment/secure_research_environment/remote/create_rds/scripts/Configure_CAP_And_RAP_Remote.ps1 deleted file mode 100644 index 87ccd00830..0000000000 --- a/deployment/secure_research_environment/remote/create_rds/scripts/Configure_CAP_And_RAP_Remote.ps1 +++ /dev/null @@ -1,119 +0,0 @@ -# Don't make parameters mandatory as if there is any issue binding them, the script will prompt for them -# and remote execution will stall waiting for the non-present user to enter the missing parameter on the -# command line. This take up to 90 minutes to timeout, though you can try running resetState.cmd in -# C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.0 on the remote VM to cancel a stalled -# job, but this does not seem to have an immediate effect -# For details, see https://docs.microsoft.com/en-gb/azure/virtual-machines/windows/run-command -param( - [Parameter(HelpMessage = "Base-64 encoded secret that is shared with the NPS server")] - [ValidateNotNullOrEmpty()] - [string]$npsSecretB64, - [Parameter(HelpMessage = "Blackout for NPS server")] - [ValidateNotNullOrEmpty()] - [string]$remoteNpsBlackout, - [Parameter(HelpMessage = "Priority for NPS server")] - [ValidateNotNullOrEmpty()] - [string]$remoteNpsPriority, - [Parameter(HelpMessage = "Whether NPS server requires authentication")] - [ValidateNotNullOrEmpty()] - [string]$remoteNpsRequireAuthAttrib, - [Parameter(HelpMessage = "Server group to check for NPS servers")] - [ValidateNotNullOrEmpty()] - [string]$remoteNpsServerGroup, - [Parameter(HelpMessage = "Timeout for NPS server")] - [ValidateNotNullOrEmpty()] - [string]$remoteNpsTimeout, - [Parameter(HelpMessage = "NetBios name for the SHM domain")] - [ValidateNotNullOrEmpty()] - [string]$shmNetbiosName, - [Parameter(HelpMessage = "IP address for the NPS server")] - [ValidateNotNullOrEmpty()] - [string]$shmNpsIp, - [Parameter(HelpMessage = "Security group that research users belong to")] - [ValidateNotNullOrEmpty()] - [string]$sreResearchUserSecurityGroup -) - -Import-Module NPS -ErrorAction Stop -Import-Module RemoteDesktopServices -ErrorAction Stop - -function Get-NpsServerAddresses { - param( - [Parameter(Mandatory = $true, HelpMessage = "Server group to check for NPS servers")] - [string]$remoteServerGroup - ) - $npserverAddresses = netsh nps show remoteserver "$remoteServerGroup" | Select-String "Address + =" | ForEach-Object { ($_.ToString() -replace '(Address + = )(.*)', '$2').Trim() } - return $npserverAddresses -} - - -# Deserialise Base-64 encoded variables -# ------------------------------------- -$npsSecret = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($npsSecretB64)) - - -# Set RAP user groups -# ------------------- -# Format user group as @ -$sreResearchUserSecurityGroupWithDomain = "${sreResearchUserSecurityGroup}@${shmNetbiosName}" -foreach ($rapName in ("RDG_AllDomainComputers", "RDG_RDConnectionBrokers")) { - $success = $true - - # NOTE: Need to add SRE Researcher user group / ensure it exists prior to removing existing - # user groups as there must always be at least one user group assigned for each RAP - # Ensure SRE Researcher user group is assigned to RAP - if (-not (Get-Item "RDS:\GatewayServer\RAP\${rapName}\UserGroups\" | Get-ChildItem | Where-Object { $_.Name -eq $sreResearchUserSecurityGroupWithDomain })) { - $null = New-Item "RDS:\GatewayServer\RAP\${rapName}\UserGroups\" -Name "$sreResearchUserSecurityGroupWithDomain" -ErrorAction SilentlyContinue - $success = $success -and $? - } - - # Remove all other user groups from RAP - # If the SRE Researcher group is not in the RAP User Group list (e.g. if the `New-Item` command above failed) - # this command to remove all other groups will fail, as there must always be at least one User Group. - $null = Get-Item "RDS:\GatewayServer\RAP\${rapName}\UserGroups\" | Get-ChildItem | Where-Object { $_.Name -ne "$sreResearchUserSecurityGroupWithDomain" } | Remove-Item -ErrorAction SilentlyContinue - $success = $success -and $? - # Report success / failure - if ($success) { - Write-Output " [o] Successfully restricted '$rapName' user groups to '$sreResearchUserSecurityGroupWithDomain'." - } else { - Write-Output " [x] Failed to restrict '$rapName' user groups to '$sreResearchUserSecurityGroupWithDomain'!" - } -} - -# Configure remote NPS server -# --------------------------- -# Remove all existing remote NPS servers -foreach ($npsServerAddress in (Get-NpsServerAddresses -remoteServerGroup $remoteNpsServerGroup)) { - $null = netsh nps delete remoteserver remoteservergroup = "$remoteNpsServerGroup" address = "$npsServerAddress" -} -# Add SHM NPS server -$null = netsh nps add remoteserver ` - remoteServerGroup = "$remoteNpsServerGroup" ` - address = "$shmNpsIp" ` - authsharedsecret = "$npsSecret" ` - requireauthattrib = "$remoteNpsRequireAuthAttrib" ` - acctsharedsecret = "$npsSecret" ` - priority = "$remoteNpsPriority" ` - timeout = "$remoteNpsTimeout" ` - blackout = "$remoteNpsBlackout" -# Check that the change has actually been made (the netsh nps command always returns "ok") -[array]$npsServerAddresses = (Get-NpsServerAddresses -remoteServerGroup $remoteNpsServerGroup) -$success = ($npsServerAddresses.Length -eq 1) -if ($success) { - $firstNpsServerAddress = $npsServerAddresses[0] - $success = $success -and ($firstNpsServerAddress -eq $shmNpsIp) -} -if ($success) { - Write-Output " [o] Successfully configured '$firstNpsServerAddress' as the only remote NPS server." -} else { - Write-Output " [x] Failed to configure remote NPS server. Found $($npsServerAddresses.Length) candidates!" -} - -# Set RDS Gateway to use remote NPS server -# ---------------------------------------- -$null = Set-Item RDS:\GatewayServer\CentralCAPEnabled\ -Value 1 -ErrorAction SilentlyContinue -if ($?) { - Write-Output " [o] Successfully set remote NPS server as RD CAP store." -} else { - Write-Output " [x] Failed to set remote NPS server as RD CAP store!" -} diff --git a/deployment/secure_research_environment/remote/create_rds/scripts/Disable_Legacy_TLS_Remote.ps1 b/deployment/secure_research_environment/remote/create_rds/scripts/Disable_Legacy_TLS_Remote.ps1 deleted file mode 100644 index 6dd4af91f4..0000000000 --- a/deployment/secure_research_environment/remote/create_rds/scripts/Disable_Legacy_TLS_Remote.ps1 +++ /dev/null @@ -1,121 +0,0 @@ -# Don't make parameters mandatory as if there is any issue binding them, the script will prompt for them -# and remote execution will stall waiting for the non-present user to enter the missing parameter on the -# command line. This take up to 90 minutes to timeout, though you can try running resetState.cmd in -# C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.0 on the remote VM to cancel a stalled -# job, but this does not seem to have an immediate effect -# For details, see https://docs.microsoft.com/en-gb/azure/virtual-machines/windows/run-command -param( - [Parameter(Mandatory = $false, HelpMessage = "Base64-encoded list of TLS ciphers")] - [string]$allowedCiphersB64 -) - - -# Throwing an exception in a remote script means we have to wait 90 minutes for the remote call to time out -# Accordingly we don't validate any parameters or make them mandatory -# In reality, all three parameters are required and both 'Role' and 'Action' will only accept certain values -function Set-ProtocolForRole { - param( - [Parameter(HelpMessage = "Name of protocol")] - $Protocol, - [Parameter(HelpMessage = "Name of protocol [must be 'Server' or 'Client']")] - $Role, - [Parameter(HelpMessage = "Set whether we are enabling or disabling [must be 'Enable' or 'Disable']")] - $Action - ) - if ($Action -eq "Enable") { - $EnabledValue = 1 - $DisabledByDefaultValue = 0 - } elseif ($Action -eq "Disable") { - $EnabledValue = 0 - $DisabledByDefaultValue = 1 - } else { - Write-Output " [x] Could not interpret '$Action'. Please use either 'Enable' or 'Disable'." - return - } - - # Disable protocol for role - New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$Protocol\$Role" -Force | Out-Null - New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$Protocol\$Role" -Name 'Enabled' -Value $EnabledValue -PropertyType 'DWord' -Force | Out-Null - New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$Protocol\$Role" -Name 'DisabledByDefault' -Value $DisabledByDefaultValue -PropertyType 'DWord' -Force | Out-Null - # Check status - $status = Get-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$Protocol\$Role" - if (($status.GetValue("Enabled") -eq $EnabledValue) -and ($status.GetValue("DisabledByDefault") -eq $DisabledByDefaultValue)) { - Write-Output " [o] '$Protocol' protocol is '${Action}d' for '$Role' role." - } else { - Write-Output " [x] Failed to ensure '$Protocol' protocol is '${Action}d' for '$Role' role." - Write-Output $status - } -} - -function Set-Protocol { - param( - [Parameter(HelpMessage = "Name of protocol")] - $Protocol, - [Parameter(HelpMessage = "Set whether we are enabling or disabling [must be 'Enable' or 'Disable']")] - $Action - ) - Write-Output "Ensuring '$Protocol' is ${Action}d..." - Set-ProtocolForRole -Protocol $Protocol -Role "Client" -Action $Action - Set-ProtocolForRole -Protocol $Protocol -Role "Server" -Action $Action -} - - -# Disable all legacy protocols -# ---------------------------- -Set-Protocol -Protocol "SSL 2.0" -Action Disable -Set-Protocol -Protocol "SSL 3.0" -Action Disable -Set-Protocol -Protocol "TLS 1.0" -Action Disable -Set-Protocol -Protocol "TLS 1.1" -Action Disable - - -# Construct allowed/disallowed cipher lists -# - unserialise JSON and read into PSCustomObject -# ----------------------------------------------- -$allowedCiphers = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($allowedCiphersB64)) | ConvertFrom-Json -$disallowedCiphers = Get-TlsCipherSuite | ForEach-Object { $_.Name } | Where-Object { -not $allowedCiphers.Contains($_) } - - -# Disable all ciphers that are not in the allowed list -# ---------------------------------------------------- -# By disabling before enabling, we ensure that this will not remove any ciphers that we want to keep. -Write-Output "Disabling any disallowed ciphersuites..." -foreach ($disallowedCipher in $disallowedCiphers) { - # Note that running Disable-TlsCipherSuite on eg. TLS_DHE_RSA_WITH_AES_128_CCM will also disable TLS_DHE_RSA_WITH_AES_128_CCM_8 - # Disable-TlsCipherSuite raises an error if the suite is already disabled. Therefore suites are enabled before being disabled. - if (Get-TlsCipherSuite -Name $disallowedCipher) { - Enable-TlsCipherSuite -Name $disallowedCipher - Disable-TlsCipherSuite -Name $disallowedCipher - if ($?) { - Write-Output " [o] Disabled '$disallowedCipher' suite." - } else { - Write-Output " [x] Failed to ensure '$disallowedCipher' suite is disabled." - } - } -} - - -# Enable all ciphers that are in the allowed list -# ----------------------------------------------- -Write-Output "Enabling all allowed ciphersuites..." -foreach ($allowedCipher in $allowedCiphers) { - if (-not $(Get-TlsCipherSuite | ForEach-Object { $_.Name }).Contains($allowedCipher)) { - Enable-TlsCipherSuite -Name $allowedCipher - if ($?) { - # Check whether this cipher is supported by Windows. - # If it is not [ie. it has no CipherSuite entry] then immediately disable it. - if ($((Get-TlsCipherSuite -Name $allowedCipher).CipherSuite) -eq 0) { - Disable-TlsCipherSuite -Name $allowedCipher - } else { - Write-Output " [o] Enabled '$allowedCipher' suite." - } - } else { - Write-Output " [x] Failed to ensure '$allowedCipher' suite is enabled." - } - } -} - - -# List all cipher suites that are still allowed -# --------------------------------------------- -Write-Output "There are $(((Get-TlsCipherSuite) | Measure-Object).Count) allowed cipher suites:" -(Get-TlsCipherSuite) | ForEach-Object { Write-Output "... $($_.Name)" } diff --git a/deployment/secure_research_environment/remote/create_rds/scripts/Import_And_Install_Blobs.ps1 b/deployment/secure_research_environment/remote/create_rds/scripts/Import_And_Install_Blobs.ps1 deleted file mode 100644 index 7789bf07fe..0000000000 --- a/deployment/secure_research_environment/remote/create_rds/scripts/Import_And_Install_Blobs.ps1 +++ /dev/null @@ -1,75 +0,0 @@ -# Don't make parameters mandatory as if there is any issue binding them, the script will prompt for them -# and remote execution will stall waiting for the non-present user to enter the missing parameter on the -# command line. This take up to 90 minutes to timeout, though you can try running resetState.cmd in -# C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.0 on the remote VM to cancel a stalled -# job, but this does not seem to have an immediate effect -# For details, see https://docs.microsoft.com/en-gb/azure/virtual-machines/windows/run-command -param( - [Parameter(HelpMessage = "Base-64 encoded array of blob names to download from storage blob container")] - [string]$blobNameArrayB64, - [Parameter(HelpMessage = "Absolute path to directory which blobs should be downloaded to")] - [string]$downloadDir, - [Parameter(HelpMessage = "Base-64 encoded SAS token with read/list rights to the storage blob container")] - [string]$sasTokenB64, - [Parameter(HelpMessage = "File share or blob container name")] - [string]$shareOrContainerName, - [Parameter(HelpMessage = "Storage account name")] - [string]$storageAccountName, - [Parameter(HelpMessage = "Storage service")] - [string]$storageService -) - -# Deserialise Base-64 encoded variables -# ------------------------------------- -$blobNames = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($blobNameArrayB64)) | ConvertFrom-Json -$sasToken = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($sasTokenB64)) - - -# Clear any previously downloaded artifacts -# ----------------------------------------- -Write-Output "Clearing all pre-existing files and folders from '$downloadDir'" -if (Test-Path -Path $downloadDir) { - Get-ChildItem $downloadDir -Recurse | Remove-Item -Recurse -Force -} else { - $null = New-Item -ItemType directory -Path $downloadDir -} - -# Download artifacts -Write-Output "Downloading $($blobNames.Count) files to '$downloadDir'" -foreach ($blobName in $blobNames) { - # Ensure that local directory exists - $localDir = Join-Path $downloadDir $(Split-Path -Parent $blobName) - if (-Not (Test-Path -Path $localDir)) { - $null = New-Item -ItemType directory -Path $localDir - } - $fileName = Split-Path -Leaf $blobName - $localFilePath = Join-Path $localDir $fileName - - # Download file from blob storage - $blobUrl = "https://${storageAccountName}.${storageService}.core.windows.net/${shareOrContainerName}/${blobName}" - Write-Output " [ ] Fetching $blobUrl..." - $null = Invoke-WebRequest -Uri "${blobUrl}${sasToken}" -OutFile $localFilePath - if ($?) { - Write-Output " [o] Succeeded" - } else { - Write-Output " [x] Failed!" - } - - # If this file is an msi/exe then install it - if ((Test-Path -Path $localFilePath) -And ($fileName -Match ".*\.(msi|exe)\b")) { - if ($fileName -like "*.msi") { - Write-Output " [ ] Installing $fileName..." - Start-Process $localFilePath -ArgumentList '/quiet' -Verbose -Wait - } elseif ($fileName -like "*WinSCP*exe") { - Write-Output " [ ] Installing $fileName..." - Start-Process $localFilePath -ArgumentList '/SILENT', '/ALLUSERS' -Verbose -Wait - } else { - continue - } - if ($?) { - Write-Output " [o] Succeeded" - } else { - Write-Output " [x] Failed!" - } - } -} diff --git a/deployment/secure_research_environment/remote/create_rds/scripts/Install_Signed_Ssl_Cert.ps1 b/deployment/secure_research_environment/remote/create_rds/scripts/Install_Signed_Ssl_Cert.ps1 deleted file mode 100644 index 6a2e9c5e7c..0000000000 --- a/deployment/secure_research_environment/remote/create_rds/scripts/Install_Signed_Ssl_Cert.ps1 +++ /dev/null @@ -1,96 +0,0 @@ -# Don't make parameters mandatory as if there is any issue binding them, the script will prompt for them -# and remote execution will stall waiting for the non-present user to enter the missing parameter on the -# command line. This take up to 90 minutes to timeout, though you can try running resetState.cmd in -# C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.0 on the remote VM to cancel a stalled -# job, but this does not seem to have an immediate effect -# For details, see https://docs.microsoft.com/en-gb/azure/virtual-machines/windows/run-command -param( - [Parameter(HelpMessage = "Fully qualified domain name for RDS broker")] - [string]$rdsFqdn, - [Parameter(HelpMessage = "Thumbprint for the relevant certificate")] - [string]$certThumbPrint, - [Parameter(HelpMessage = "Remote folder to write SSL certificate to")] - [string]$remoteDirectory -) - -# Set common variables -# -------------------- -# NB. Cert:\LocalMachine\My is the default Machine Certificate store and is used by IIS -$certDirLocal = New-Item -ItemType Directory -Path $remoteDirectory -Force -$certStore = "Cert:\LocalMachine\My" - -Write-Output "Looking for certificate with thumbprint: $certThumbPrint" -$certificate = Get-ChildItem $certStore | Where-Object { $_.Thumbprint -eq $certThumbPrint } -if ($null -ne $certificate) { - Write-Output " [o] Found certificate with correct thumbprint" -} else { - Write-Output " [x] Failed to find any certificate with the correct thumbprint!" - throw "Could not load certificate" -} - - -# Update RDS roles to use new certificate by thumbprint -# ----------------------------------------------------- -Write-Output "Updating RDS roles to use new certificate..." -try { - Set-RDCertificate -Role RDPublishing -Thumbprint $certificate.Thumbprint -ConnectionBroker $rdsFqdn -ErrorAction Stop -Force - Set-RDCertificate -Role RDRedirector -Thumbprint $certificate.Thumbprint -ConnectionBroker $rdsFqdn -ErrorAction Stop -Force - Set-RDCertificate -Role RDWebAccess -Thumbprint $certificate.Thumbprint -ConnectionBroker $rdsFqdn -ErrorAction Stop -Force - Set-RDCertificate -Role RDGateway -Thumbprint $certificate.Thumbprint -ConnectionBroker $rdsFqdn -ErrorAction Stop -Force - Write-Output " [o] Successfully updated RDS roles" -} catch { - Write-Output " [x] Failed to update RDS roles!" - throw -} -Write-Output "Currently installed certificates:" -Get-RDCertificate -ConnectionBroker $rdsFqdn - - -# Extract a base64-encoded certificate -# ------------------------------------ -Write-Output "Extracting a base64-encoded certificate..." -$derCert = (Join-Path $certDirLocal "letsencrypt_der.cer") -$b64Cert = (Join-Path $certDirLocal "letsencrypt_b64.cer") -$null = Export-Certificate -filepath $derCert -cert $certificate -type CERT -Force -$success = $? -$null = CertUtil -f -encode $derCert $b64Cert -$success = $success -and $? -if ($success) { - Write-Output " [o] Base64-encoded certificate extracted to $b64Cert" -} else { - Write-Output " [x] Failed to extract base64-encoded certificate" - throw "Could not extract base64-encoded certificate" -} - - -# Import certificate to RDS Web Client -# ------------------------------------ -Write-Output "Importing certificate to RDS Web Client..." -Import-RDWebClientBrokerCert $b64Cert -Publish-RDWebClientPackage -Type Production -Latest -if ($?) { - Write-Output " [o] Certificate installed on RDS Web Client" -} else { - Write-Output " [x] Failed to install certificate on RDS Web Client" - throw "Failed to install certificate on RDS Web Client" -} - - -# Check certificates -# ------------------ -Write-Output "Checking webclient broker certificate..." -$webclientThumbprint = (Get-RDWebClientBrokerCert).Thumbprint -if ($webclientThumbprint -eq $certThumbPrint) { - Write-Output " [o] Webclient broker certificate has the correct thumbprint: '$webclientThumbprint'" -} else { - Write-Output " [x] Webclient broker certificate has incorrect thumbprint: '$webclientThumbprint'" - throw "Webclient broker certificate has incorrect thumbprint" -} -Write-Output "Checking RDGateway certificate..." -$gatewayThumbprint = (Get-RDCertificate -Role RDGateway -ConnectionBroker $rdsFqdn).Thumbprint -if ($gatewayThumbprint -eq $certThumbPrint) { - Write-Output " [o] RDGateway certificate has the correct thumbprint: '$gatewayThumbprint'" -} else { - Write-Output " [x] RDGateway certificate has incorrect thumbprint: '$gatewayThumbprint'" - throw "RDGateway certificate has incorrect thumbprint" -} diff --git a/deployment/secure_research_environment/remote/create_rds/scripts/install_ssl_certificate_tier1.sh b/deployment/secure_research_environment/remote/create_rds/scripts/install_ssl_certificate_tier1.sh deleted file mode 100644 index b3b7811dae..0000000000 --- a/deployment/secure_research_environment/remote/create_rds/scripts/install_ssl_certificate_tier1.sh +++ /dev/null @@ -1,15 +0,0 @@ -#! /bin/bash -# This script is designed to be deployed to an Azure Linux VM via -# the Powershell Invoke-AzVMRunCommand, which sets all variables -# passed in its -Parameter argument as environment variables -# It expects the following parameters: -# CERT_THUMBPRINT - -sudo mkdir -p /opt/ssl -sudo chmod 0700 /opt/ssl -sudo rm -rf /opt/ssl/letsencrypt* -sudo cp /var/lib/waagent/${CERT_THUMBPRINT}.crt /opt/ssl/letsencrypt.cert -sudo cp /var/lib/waagent/${CERT_THUMBPRINT}.prv /opt/ssl/letsencrypt.key -sudo chown -R root:root /opt/ssl/ -sudo chmod 0600 /opt/ssl/*.* -ls -alh /opt/ssl/ \ No newline at end of file diff --git a/deployment/secure_research_environment/remote/create_rds/templates/Deploy_RDS_Environment.mustache.ps1 b/deployment/secure_research_environment/remote/create_rds/templates/Deploy_RDS_Environment.mustache.ps1 deleted file mode 100644 index 031d61cbb1..0000000000 --- a/deployment/secure_research_environment/remote/create_rds/templates/Deploy_RDS_Environment.mustache.ps1 +++ /dev/null @@ -1,181 +0,0 @@ -# Enable the RDS-Gateway feature -$null = Add-WindowsFeature -Name RDS-Gateway -IncludeAllSubFeature -ErrorAction Stop - -# Note that RemoteDesktopServices is installed by `Add-WindowsFeature -Name RDS-Gateway` -Import-Module RemoteDesktop -ErrorAction Stop -Import-Module RemoteDesktopServices -ErrorAction Stop - -# Configure attached disk drives -# ------------------------------ -Stop-Service ShellHWDetection -# Initialise disks -Write-Output "Initialising data drives..." -$null = Get-Disk | Where-Object { $_.PartitionStyle -eq "raw" } | ForEach-Object { Initialize-Disk -PartitionStyle GPT -Number $_.Number } -# Check that all disks are correctly partitioned -Write-Output "Checking drive partitioning..." -$DataDisks = Get-Disk | Where-Object { $_.Model -ne "Virtual HD" } | Sort -Property Number # This excludes the OS and temp disks -foreach ($DataDisk in $DataDisks) { - $existingPartitions = @(Get-Partition -DiskNumber $DataDisk.Number | Where-Object { $_.Type -eq "Basic" }) # This selects normal partitions that are not system-reserved - # Remove all basic partitions if there is not exactly one - if ($existingPartitions.Count -gt 1) { - Write-Output " [ ] Found $($existingPartitions.Count) partitions on disk $($DataDisk.DiskNumber) but expected 1! Removing all of them." - $existingPartitions | ForEach-Object { Remove-Partition -DiskNumber $DataDisk.DiskNumber -PartitionNumber $_.PartitionNumber -Confirm:$false } - } - # Remove any non-lettered partitions - $existingPartition = @(Get-Partition -DiskNumber $DataDisk.Number | Where-Object { $_.Type -eq "Basic" })[0] - if ($existingPartition -and (-not $existingPartition.DriveLetter)) { - Write-Output "Removing non-lettered partition $($existingPartition.PartitionNumber) from disk $($DataDisk.DiskNumber)!" - Remove-Partition -DiskNumber $DataDisk.DiskNumber -PartitionNumber $existingPartition.PartitionNumber -Confirm:$false - } - # Create a new partition if one does not exist - $existingPartition = @(Get-Partition -DiskNumber $DataDisk.Number | Where-Object { $_.Type -eq "Basic" })[0] - if ($existingPartition) { - Write-Output " [o] Partition $($existingPartition.PartitionNumber) of disk $($DataDisk.DiskNumber) is mounted at drive letter '$($existingPartition.DriveLetter)'" - } else { - $LUN = $(Get-WmiObject Win32_DiskDrive | Where-Object { $_.Index -eq $DataDisk.Number }).SCSILogicalUnit - $Label = "DATA-$LUN" - $Partition = New-Partition -DiskNumber $DataDisk.Number -UseMaximumSize -AssignDriveLetter - Write-Output " [o] Formatting partition $($Partition.PartitionNumber) of disk $($DataDisk.Number) with label '$Label' at drive letter '$($Partition.DriveLetter)'" - $null = Format-Volume -Partition $Partition -FileSystem NTFS -NewFileSystemLabel $Label -Confirm:$false - } -} -Start-Service ShellHWDetection -# Construct map of folders to disk labels -$DiskLabelMap = @{ - "AppFileShares" = "DATA-0" -} - - -# Remove any old RDS settings -# --------------------------- -Write-Output "Removing any old RDS settings..." -foreach ($collection in $(Get-RDSessionCollection -ErrorAction SilentlyContinue)) { - Write-Output "... removing existing RDSessionCollection: '$($collection.CollectionName)'" - Remove-RDSessionCollection -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName $collection.CollectionName -Force -ErrorAction SilentlyContinue -} -foreach ($server in $(Get-RDServer -ErrorAction SilentlyContinue)) { - Write-Output "... removing existing RDServer: '$($server.Server)'" - foreach ($role in $server.Roles) { - Remove-RDServer -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -Server $server.Server -Role $role -Force -ErrorAction SilentlyContinue - } -} -foreach ($policyName in $(Get-Item "RDS:\GatewayServer\RAP" -ErrorAction SilentlyContinue | Get-ChildItem | ForEach-Object { $_.Name })) { - Write-Output "... removing existing RAP policy '$policyName'" - Remove-Item "RDS:\GatewayServer\RAP\${policyName}" -Recurse -ErrorAction SilentlyContinue -} -$null = Set-Item "RDS:\GatewayServer\CentralCAPEnabled" -Value 0 -ErrorAction SilentlyContinue -foreach ($policyName in $(Get-Item "RDS:\GatewayServer\CAP" -ErrorAction SilentlyContinue | Get-ChildItem | ForEach-Object { $_.Name })) { - Write-Output "... removing existing CAP policy '$policyName'" - Remove-Item "RDS:\GatewayServer\CAP\${policyName}" -Recurse -ErrorAction SilentlyContinue -} - - -# Create RDS Environment -# ---------------------- -Write-Output "Creating RDS Environment..." -try { - New-RDSessionDeployment -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -WebAccessServer "{{sre.remoteDesktop.gateway.fqdn}}" -SessionHost @("{{sre.remoteDesktop.appSessionHost.fqdn}}") -ErrorAction Stop - # Setup licensing server - Add-RDServer -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -Server "{{sre.remoteDesktop.gateway.fqdn}}" -Role RDS-LICENSING -ErrorAction Stop - Set-RDLicenseConfiguration -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -LicenseServer "{{sre.remoteDesktop.gateway.fqdn}}" -Mode PerUser -Force -ErrorAction Stop - # Setup gateway server - Add-RDServer -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -Server "{{sre.remoteDesktop.gateway.fqdn}}" -Role RDS-GATEWAY -GatewayExternalFqdn "{{sre.domain.fqdn}}" -ErrorAction Stop - Set-RDWorkspace -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -Name "Safe Haven Applications" - Write-Output " [o] RDS environment configuration update succeeded" -} catch { - Write-Output " [x] RDS environment configuration update failed!" - throw -} - - -# Create collections -# ------------------ -foreach ($rdsConfiguration in @(, @("Applications", "{{sre.remoteDesktop.appSessionHost.fqdn}}", "{{sre.domain.securityGroups.researchUsers.name}}", "AppFileShares"))) { - $collectionName, $sessionHost, $userGroup, $shareName = $rdsConfiguration - $sharePath = Join-Path "$((Get-Volume | Where-Object { $_.FileSystemLabel -eq $DiskLabelMap[$shareName] }).DriveLetter):" $shareName - - # Setup user profile disk shares - Write-Output "Creating user profile disk shares..." - $null = New-Item -ItemType Directory -Force -Path $sharePath - $sessionHostComputerName = $sessionHost.Split(".")[0] - if ($null -eq $(Get-SmbShare | Where-Object -Property Path -EQ $sharePath)) { - $null = New-SmbShare -Path $sharePath -Name $shareName -FullAccess "{{shm.domain.netbiosName}}\{{sre.remoteDesktop.gateway.vmName}}$", "{{shm.domain.netbiosName}}\${sessionHostComputerName}$", "{{shm.domain.netbiosName}}\Domain Admins" - } - - # Create collections - Write-Output "Creating '$collectionName' collection..." - try { - $null = New-RDSessionCollection -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "$collectionName" -SessionHost "$sessionHost" -ErrorAction Stop - $null = Set-RDSessionCollectionConfiguration -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "$collectionName" -UserGroup "{{shm.domain.netbiosName}}\$userGroup" -ClientPrinterRedirected $false -ClientDeviceRedirectionOptions None -DisconnectedSessionLimitMin 5 -IdleSessionLimitMin 720 -ErrorAction Stop - $null = Set-RDSessionCollectionConfiguration -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "$collectionName" -EnableUserProfileDisk -MaxUserProfileDiskSizeGB "20" -DiskPath "\\{{sre.remoteDesktop.gateway.vmName}}\$shareName" -ErrorAction Stop - Write-Output " [o] Creating '$collectionName' collection succeeded" - } catch { - Write-Output " [x] Creating '$collectionName' collection failed!" - throw - } -} - - -# Create applications -# ------------------- -Write-Output "Registering applications..." -Get-RDRemoteApp | Remove-RDRemoteApp -Force -ErrorAction SilentlyContinue -try { - $null = New-RDRemoteApp -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "Applications" -DisplayName "SRD Main (Desktop)" -FilePath "C:\Windows\system32\mstsc.exe" -ShowInWebAccess 1 -CommandLineSetting Require -RequiredCommandLine "-v {{rdsTemplates.ipAddressFirstSRD}}" -ErrorAction Stop - $null = New-RDRemoteApp -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "Applications" -DisplayName "SRD Other (Desktop)" -FilePath "C:\Windows\system32\mstsc.exe" -ShowInWebAccess 1 -ErrorAction Stop - $null = New-RDRemoteApp -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "Applications" -DisplayName "CoCalc" -FilePath "C:\Program Files\Google\Chrome\Application\chrome.exe" -ShowInWebAccess 1 -CommandLineSetting Require -RequiredCommandLine "http://{{sre.webapps.cocalc.ip}}" -ErrorAction Stop - $null = New-RDRemoteApp -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "Applications" -DisplayName "CodiMD" -FilePath "C:\Program Files\Google\Chrome\Application\chrome.exe" -ShowInWebAccess 1 -CommandLineSetting Require -RequiredCommandLine "http://{{sre.webapps.codimd.ip}}" -ErrorAction Stop - $null = New-RDRemoteApp -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "Applications" -DisplayName "GitLab" -FilePath "C:\Program Files\Google\Chrome\Application\chrome.exe" -ShowInWebAccess 1 -CommandLineSetting Require -RequiredCommandLine "http://{{sre.webapps.gitlab.ip}}" -ErrorAction Stop - $null = New-RDRemoteApp -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "Applications" -DisplayName "SRD Main (SSH)" -FilePath "C:\Program Files\PuTTY\putty.exe" -ShowInWebAccess 1 -CommandLineSetting Require -RequiredCommandLine "-ssh {{rdsTemplates.ipAddressFirstSRD}}" -ErrorAction Stop - $null = New-RDRemoteApp -ConnectionBroker "{{sre.remoteDesktop.gateway.fqdn}}" -CollectionName "Applications" -DisplayName "SRD Other (SSH)" -FilePath "C:\Program Files\PuTTY\putty.exe" -ShowInWebAccess 1 -ErrorAction Stop - Write-Output " [o] Registering applications succeeded" -} catch { - Write-Output " [x] Registering applications failed!" - throw -} - - -# Update server configuration -# --------------------------- -Write-Output "Updating server configuration..." -try { - Get-Process ServerManager -ErrorAction SilentlyContinue | Stop-Process -Force - foreach ($targetDirectory in @("C:\Users\{{rdsTemplates.domainAdminUsername}}\AppData\Roaming\Microsoft\Windows\ServerManager", - "C:\Users\{{rdsTemplates.domainAdminUsername}}.{{shm.domain.netbiosName}}\AppData\Roaming\Microsoft\Windows\ServerManager")) { - $null = New-Item -ItemType Directory -Path $targetDirectory -Force -ErrorAction Stop - Copy-Item -Path "{{sre.remoteDesktop.gateway.installationDirectory}}\ServerList.xml" -Destination "$targetDirectory\ServerList.xml" -Force -ErrorAction Stop - } - Start-Process -FilePath $env:SystemRoot\System32\ServerManager.exe -WindowStyle Maximized -ErrorAction Stop - Write-Output " [o] Server configuration update succeeded" -} catch { - Write-Output " [x] Server configuration update failed!" - throw -} - - -# Install RDS webclient -# --------------------- -Write-Output "Installing RDS webclient..." -try { - Install-RDWebClientPackage -ErrorAction Stop - # We cannot publish the WebClient here as we have not yet setup a broker certificate. - # We do not configure the broker cert here as our RDS SSL certificates are set up in a - # separate script to support easy renewal. This means that, until the SSL certificate - # installation script is run for the first time, the RDS WebClient URL will return a 404 page. - Write-Output " [o] RDS webclient installation succeeded" -} catch { - Write-Output " [x] RDS webclient installation failed!" - throw -} - - -# Remove the requirement for the /RDWeb/webclient/ suffix by setting up a redirect in IIS -# --------------------------------------------------------------------------------------- -Write-Output "Setting up IIS redirect..." -try { - Set-WebConfiguration system.webServer/httpRedirect "IIS:\sites\Default Web Site" -Value @{enabled = "true"; destination = "/RDWeb/webclient/"; httpResponseStatus = "Permanent" } -ErrorAction Stop - Write-Output " [o] IIS redirection succeeded" -} catch { - Write-Output " [x] IIS redirection failed!" - throw -} diff --git a/deployment/secure_research_environment/remote/create_rds/templates/ServerList.mustache.xml b/deployment/secure_research_environment/remote/create_rds/templates/ServerList.mustache.xml deleted file mode 100644 index 0aa539434e..0000000000 --- a/deployment/secure_research_environment/remote/create_rds/templates/ServerList.mustache.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/deployment/secure_research_environment/setup/Apply_SRE_Network_Configuration.ps1 b/deployment/secure_research_environment/setup/Apply_SRE_Network_Configuration.ps1 index 6a83dbc637..401f21f0f0 100644 --- a/deployment/secure_research_environment/setup/Apply_SRE_Network_Configuration.ps1 +++ b/deployment/secure_research_environment/setup/Apply_SRE_Network_Configuration.ps1 @@ -34,8 +34,8 @@ $nsgs = @{} Add-LogMessage -Level Info "Applying network configuration for SRE '$($config.sre.id)' (Tier $($config.sre.tier)), hosted on subscription '$($config.sre.subscriptionName)'" -# ApacheGuacamole and MicrosoftRDS have several NSGs -# -------------------------------------------------- +# ApacheGuacamole has several NSGs +# -------------------------------- # Remote desktop if ($config.sre.remoteDesktop.provider -eq "ApacheGuacamole") { # RDS gateway @@ -47,15 +47,6 @@ if ($config.sre.remoteDesktop.provider -eq "ApacheGuacamole") { } else { Add-LogMessage -Level Fatal "Guacamole server is not bound to NSG '$($nsgs["remoteDesktop"].Name)'!" } -} elseif ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - # RDS gateway - Add-LogMessage -Level Info "Ensure RDS gateway is bound to correct NSG..." - Add-VmToNSG -VMName $config.sre.remoteDesktop.gateway.vmName -VmResourceGroupName $config.sre.remoteDesktop.rg -NSGName $config.sre.remoteDesktop.gateway.nsg.name -NsgResourceGroupName $config.sre.network.vnet.rg - $nsgs["gateway"] = Get-AzNetworkSecurityGroup -Name $config.sre.remoteDesktop.gateway.nsg.name -ResourceGroupName $config.sre.network.vnet.rg -ErrorAction Stop - # RDS sesssion hosts - Add-LogMessage -Level Info "Ensure RDS session hosts are bound to correct NSG..." - Add-VmToNSG -VMName $config.sre.remoteDesktop.appSessionHost.vmName -VmResourceGroupName $config.sre.remoteDesktop.rg -NSGName $config.sre.remoteDesktop.appSessionHost.nsg.name -NsgResourceGroupName $config.sre.network.vnet.rg - $nsgs["sessionhosts"] = Get-AzNetworkSecurityGroup -Name $config.sre.remoteDesktop.appSessionHost.nsg.name -ResourceGroupName $config.sre.network.vnet.rg -ErrorAction Stop } else { Add-LogMessage -Level Fatal "Remote desktop type '$($config.sre.remoteDesktop.type)' was not recognised!" } @@ -94,9 +85,6 @@ if ($computeSubnet.NetworkSecurityGroup.Id -eq $nsgs["compute"].Id) { if ($config.sre.remoteDesktop.provider -eq "ApacheGuacamole") { Add-LogMessage -Level Info "Setting inbound connection rules on Guacamole NSG..." $null = Update-NetworkSecurityGroupRule -Name $inboundApprovedUsersRuleName -NetworkSecurityGroup $nsgs["remoteDesktop"] -SourceAddressPrefix $allowedSources -} elseif ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - Add-LogMessage -Level Info "Setting inbound connection rules on RDS Gateway NSG..." - $null = Update-NetworkSecurityGroupRule -Name $inboundApprovedUsersRuleName -NetworkSecurityGroup $nsgs["gateway"] -SourceAddressPrefix $allowedSources } else { Add-LogMessage -Level Fatal "Remote desktop type '$($config.sre.remoteDesktop.type)' was not recognised!" } diff --git a/deployment/secure_research_environment/setup/Configure_SRE_RDS_CAP_And_RAP.ps1 b/deployment/secure_research_environment/setup/Configure_SRE_RDS_CAP_And_RAP.ps1 deleted file mode 100644 index 3649c68d8d..0000000000 --- a/deployment/secure_research_environment/setup/Configure_SRE_RDS_CAP_And_RAP.ps1 +++ /dev/null @@ -1,91 +0,0 @@ -param( - [Parameter(Mandatory = $true, HelpMessage = "Enter SHM ID (e.g. use 'testa' for Turing Development Safe Haven A)")] - [string]$shmId, - [Parameter(Mandatory = $true, HelpMessage = "Enter SRE ID (e.g. use 'sandbox' for Turing Development Sandbox SREs)")] - [string]$sreId -) - -Import-Module Az.Accounts -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureCompute -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureKeyVault -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Configuration -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Cryptography -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Logging -Force -ErrorAction Stop - - -# Get config and original context before changing subscription -# ------------------------------------------------------------ -$config = Get-SreConfig -shmId $shmId -sreId $sreId -$originalContext = Get-AzContext -$null = Set-AzContext -SubscriptionId $config.sre.subscriptionName -ErrorAction Stop - - -# Check that we are using the correct provider -# -------------------------------------------- -if ($config.sre.remoteDesktop.provider -ne "MicrosoftRDS") { - Add-LogMessage -Level Fatal "You should not be running this script when using remote desktop provider '$($config.sre.remoteDesktop.provider)'" -} - - -# Configure CAP and RAP settings -# ------------------------------ -Add-LogMessage -Level Info "Creating/retrieving NPS secret from Key Vault '$($config.sre.keyVault.name)'..." -$npsSecret = Resolve-KeyVaultSecret -VaultName $config.sre.keyVault.name -SecretName $config.sre.keyVault.secretNames.npsSecret -DefaultLength 12 -AsPlaintext - - -# Configure CAP and RAP settings -# ------------------------------ -Add-LogMessage -Level Info "[ ] Configuring CAP and RAP settings on RDS Gateway" -$params = @{ - npsSecretB64 = $npsSecret | ConvertTo-Base64 - remoteNpsBlackout = "60" - remoteNpsPriority = "1" - remoteNpsRequireAuthAttrib = "Yes" - remoteNpsServerGroup = "TS GATEWAY SERVER GROUP" # "TS GATEWAY SERVER GROUP" is the group name created when manually configuring an RDS Gateway to use a remote NPS server - remoteNpsTimeout = "60" - shmNetbiosName = $config.shm.domain.netbiosName - shmNpsIp = $config.shm.nps.ip - sreResearchUserSecurityGroup = $config.sre.domain.securityGroups.researchUsers.name -} -$scriptPath = Join-Path $PSScriptRoot ".." "remote" "create_rds" "scripts" "Configure_CAP_And_RAP_Remote.ps1" -$null = Invoke-RemoteScript -Shell "PowerShell" -ScriptPath $scriptPath -VMName $config.sre.remoteDesktop.gateway.vmName -ResourceGroupName $config.sre.remoteDesktop.rg -Parameter $params - - -# Configure SHM NPS for SRE RDS RADIUS client -# ------------------------------------------- -$null = Set-AzContext -SubscriptionId $config.shm.subscriptionName -ErrorAction Stop -Add-LogMessage -Level Info "Adding RDS Gateway as RADIUS client on SHM NPS" -# Run remote script -$params = @{ - npsSecretB64 = $npsSecret | ConvertTo-Base64 - rdsGatewayIp = $config.sre.remoteDesktop.gateway.ip - rdsGatewayFqdn = $config.sre.remoteDesktop.gateway.fqdn - sreId = $config.sre.id -} -$scriptPath = Join-Path $PSScriptRoot ".." "remote" "create_rds" "scripts" "Add_RDS_Gateway_RADIUS_Client_Remote.ps1" -$null = Invoke-RemoteScript -Shell "PowerShell" -ScriptPath $scriptPath -VMName $config.shm.nps.vmName -ResourceGroupName $config.shm.nps.rg -Parameter $params -$null = Set-AzContext -SubscriptionId $config.sre.subscriptionName -ErrorAction Stop - - -# Restart SHM NPS server -# ---------------------- -# We restart the SHM NPS server because we get login failures with an "Event 13" error - -# "A RADIUS message was received from the invalid RADIUS client IP address 10.150.9.250" -# The two reliable ways we have found to fix this are: -# 1. Log into the SHM NPS and reset the RADIUS shared secret via the GUI -# 2. Restart the NPS server -# We can only do (2) in a script, so that is what we do. An NPS restart is quite quick. -# ------------------------------------------------------------------------------------- -$null = Set-AzContext -SubscriptionId $config.shm.subscriptionName -ErrorAction Stop -Add-LogMessage -Level Info "Restarting NPS Server..." -# Restart SHM NPS -Start-VM -Name $config.shm.nps.vmName -ResourceGroupName $config.shm.nps.rg -ForceRestart -# Wait 2 minutes for NPS to complete post-restart boot and start NPS services -Add-LogMessage -Level Info "Waiting 2 minutes for NPS services to start..." -Start-Sleep 120 -$null = Set-AzContext -SubscriptionId $config.sre.subscriptionName -ErrorAction Stop - - -# Switch back to original subscription -# ------------------------------------ -$null = Set-AzContext -Context $originalContext -ErrorAction Stop diff --git a/deployment/secure_research_environment/setup/Disable_Legacy_TLS.ps1 b/deployment/secure_research_environment/setup/Disable_Legacy_TLS.ps1 deleted file mode 100644 index 7093aaf61e..0000000000 --- a/deployment/secure_research_environment/setup/Disable_Legacy_TLS.ps1 +++ /dev/null @@ -1,47 +0,0 @@ -param( - [Parameter(Mandatory = $true, HelpMessage = "Enter SHM ID (e.g. use 'testa' for Turing Development Safe Haven A)")] - [string]$shmId, - [Parameter(Mandatory = $true, HelpMessage = "Enter SRE ID (e.g. use 'sandbox' for Turing Development Sandbox SREs)")] - [string]$sreId -) - -Import-Module Az.Accounts -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureCompute -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Configuration -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Cryptography -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/DataStructures -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Logging -Force -ErrorAction Stop - - -# Get config and original context before changing subscription -# ------------------------------------------------------------ -$config = Get-SreConfig -shmId $shmId -sreId $sreId -$originalContext = Get-AzContext -$null = Set-AzContext -SubscriptionId $config.sre.subscriptionName -ErrorAction Stop - - -# Check that we are using the correct provider -# -------------------------------------------- -if ($config.sre.remoteDesktop.provider -ne "MicrosoftRDS") { - Add-LogMessage -Level Fatal "You should not be running this script when using remote desktop provider '$($config.sre.remoteDesktop.provider)'" -} - - -# Disable legacy TLS protocols on RDS Gateway -# ------------------------------------------- -Add-LogMessage -Level Info "[ ] Disabling legacy SSL/TLS protocols on RDS Gateway" -$ScriptPath = Join-Path $PSScriptRoot ".." "remote" "create_rds" "scripts" "Disable_Legacy_TLS_Remote.ps1" -$params = @{ - allowedCiphersB64 = (Get-SslCipherSuites)["tls"] | ConvertTo-Json -Depth 99 | ConvertTo-Base64 -} -$null = Invoke-RemoteScript -Shell "PowerShell" -ScriptPath $ScriptPath -VMName $config.sre.remoteDesktop.gateway.vmName -ResourceGroupName $config.sre.remoteDesktop.rg -Parameter $params - - -# Reboot RDS Gateway -# ------------------ -Start-VM -Name $config.sre.remoteDesktop.gateway.vmName -ResourceGroupName $config.sre.remoteDesktop.rg -ForceRestart - - -# Switch back to original subscription -# ------------------------------------ -$null = Set-AzContext -Context $originalContext -ErrorAction Stop diff --git a/deployment/secure_research_environment/setup/Remove_SRE_Data_From_SHM.ps1 b/deployment/secure_research_environment/setup/Remove_SRE_Data_From_SHM.ps1 index cbd52853c5..a2e67c06c6 100644 --- a/deployment/secure_research_environment/setup/Remove_SRE_Data_From_SHM.ps1 +++ b/deployment/secure_research_environment/setup/Remove_SRE_Data_From_SHM.ps1 @@ -98,18 +98,6 @@ if ($sreResources -or $sreResourceGroups) { $null = Invoke-RemoteScript -Shell "PowerShell" -ScriptPath $scriptPath -VMName $config.shm.dc.vmName -ResourceGroupName $config.shm.dc.rg -Parameter $params - # Remove RDS Gateway RADIUS Client from SHM NPS - # --------------------------------------------- - if ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - Add-LogMessage -Level Info "Removing RDS Gateway RADIUS Client from SHM NPS..." - $scriptPath = Join-Path $PSScriptRoot ".." "remote" "configure_shm_dc" "scripts" "Remove_RDS_Gateway_RADIUS_Client_Remote.ps1" -Resolve - $params = @{ - rdsGatewayFqdn = $config.sre.remoteDesktop.gateway.fqdn - } - $null = Invoke-RemoteScript -Shell "PowerShell" -ScriptPath $scriptPath -VMName $config.shm.nps.vmName -ResourceGroupName $config.shm.nps.rg -Parameter $params - } - - # Remove SRE DNS Zone # ------------------- $null = Set-AzContext -SubscriptionId $config.shm.dns.subscriptionName -ErrorAction Stop @@ -157,8 +145,6 @@ if ($sreResources -or $sreResourceGroups) { # Remote desktop server CNAME record if ($config.sre.remoteDesktop.provider -eq "ApacheGuacamole") { $serverHostname = "$($config.sre.remoteDesktop.guacamole.hostname)".ToLower() - } elseif ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - $serverHostname = "$($config.sre.remoteDesktop.gateway.hostname)".ToLower() } else { Add-LogMessage -Level Fatal "Remote desktop type '$($config.sre.remoteDesktop.type)' was not recognised!" } diff --git a/deployment/secure_research_environment/setup/Secure_SRE_Remote_Desktop_Gateway.ps1 b/deployment/secure_research_environment/setup/Secure_SRE_Remote_Desktop_Gateway.ps1 deleted file mode 100644 index 88539dbeef..0000000000 --- a/deployment/secure_research_environment/setup/Secure_SRE_Remote_Desktop_Gateway.ps1 +++ /dev/null @@ -1,46 +0,0 @@ -param( - [Parameter(Mandatory = $true, HelpMessage = "Enter SHM ID (e.g. use 'testa' for Turing Development Safe Haven A)")] - [string]$shmId, - [Parameter(Mandatory = $true, HelpMessage = "Enter SRE ID (e.g. use 'sandbox' for Turing Development Sandbox SREs)")] - [string]$sreId, - [Parameter(Mandatory = $false, HelpMessage = "Do a 'dry run' against the Let's Encrypt staging server.")] - [switch]$dryRun, - [Parameter(Mandatory = $false, HelpMessage = "Force the installation step even for dry runs.")] - [switch]$forceInstall -) - -Import-Module $PSScriptRoot/../../common/Configuration -Force -ErrorAction Stop - - -# Get config and original context before changing subscription -# ------------------------------------------------------------ -$config = Get-SreConfig -shmId $shmId -sreId $sreId -$originalContext = Get-AzContext -$null = Set-AzContext -SubscriptionId $config.sre.subscriptionName -ErrorAction Stop - - -# Check that we are using the correct provider -# -------------------------------------------- -if ($config.sre.remoteDesktop.provider -ne "MicrosoftRDS") { - Add-LogMessage -Level Fatal "You should not be running this script when using remote desktop provider '$($config.sre.remoteDesktop.provider)'" -} - - -# Disable legacy TLS on the RDS gateway -# ------------------------------------- -Invoke-Command -ScriptBlock { & "$(Join-Path $PSScriptRoot 'Disable_Legacy_TLS.ps1')" -shmId $shmId -sreId $sreId } - - -# Configure CAP and RAP settings on the RDS gateway -# ------------------------------------------------- -Invoke-Command -ScriptBlock { & "$(Join-Path $PSScriptRoot 'Configure_SRE_RDS_CAP_And_RAP.ps1')" -shmId $shmId -sreId $sreId } - - -# Update the SSL certificates on the RDS gateway -# ---------------------------------------------- -Invoke-Command -ScriptBlock { & "$(Join-Path $PSScriptRoot 'Update_SRE_SSL_Certificate.ps1')" -shmId $shmId -sreId $sreId -dryRun:$dryRun -forceInstall:$forceInstall } - - -# Switch back to original subscription -# ------------------------------------ -$null = Set-AzContext -Context $originalContext -ErrorAction Stop diff --git a/deployment/secure_research_environment/setup/Setup_SRE_Key_Vault_And_Users.ps1 b/deployment/secure_research_environment/setup/Setup_SRE_Key_Vault_And_Users.ps1 index d35671c265..7b403758a7 100644 --- a/deployment/secure_research_environment/setup/Setup_SRE_Key_Vault_And_Users.ps1 +++ b/deployment/secure_research_environment/setup/Setup_SRE_Key_Vault_And_Users.ps1 @@ -50,9 +50,6 @@ try { # Remote desktop if ($config.sre.remoteDesktop.provider -eq "ApacheGuacamole") { $null = Resolve-KeyVaultSecret -VaultName $config.sre.keyVault.name -SecretName $config.sre.remoteDesktop.guacamole.adminPasswordSecretName -DefaultLength 20 -AsPlaintext - } elseif ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - $null = Resolve-KeyVaultSecret -VaultName $config.sre.keyVault.name -SecretName $config.sre.remoteDesktop.gateway.adminPasswordSecretName -DefaultLength 20 -AsPlaintext - $null = Resolve-KeyVaultSecret -VaultName $config.sre.keyVault.name -SecretName $config.sre.remoteDesktop.appSessionHost.adminPasswordSecretName -DefaultLength 20 -AsPlaintext } else { Add-LogMessage -Level Fatal "Remote desktop type '$($config.sre.remoteDesktop.type)' was not recognised!" } diff --git a/deployment/secure_research_environment/setup/Setup_SRE_Networking.ps1 b/deployment/secure_research_environment/setup/Setup_SRE_Networking.ps1 index 85860f2b98..3cdc722af1 100644 --- a/deployment/secure_research_environment/setup/Setup_SRE_Networking.ps1 +++ b/deployment/secure_research_environment/setup/Setup_SRE_Networking.ps1 @@ -87,15 +87,6 @@ if ($config.sre.remoteDesktop.provider -eq "ApacheGuacamole") { $rules = Get-JsonFromMustacheTemplate -TemplatePath (Join-Path $PSScriptRoot ".." "network_rules" $config.sre.network.vnet.subnets.remoteDesktop.nsg.rules) -Parameters $config -AsHashtable $null = Set-NetworkSecurityGroupRules -NetworkSecurityGroup $guacamoleNsg -Rules $rules $remoteDesktopSubnet = Set-SubnetNetworkSecurityGroup -Subnet $remoteDesktopSubnet -NetworkSecurityGroup $guacamoleNsg -} elseif ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - # Ensure that gateway NSG exists with correct rules - $gatewayNsg = Deploy-NetworkSecurityGroup -Name $config.sre.remoteDesktop.gateway.nsg.name -ResourceGroupName $config.sre.network.vnet.rg -Location $config.sre.location - $rules = Get-JsonFromMustacheTemplate -TemplatePath (Join-Path $PSScriptRoot ".." "network_rules" $config.sre.remoteDesktop.gateway.nsg.rules) -Parameters $config -AsHashtable - $null = Set-NetworkSecurityGroupRules -NetworkSecurityGroup $gatewayNsg -Rules $rules - # Ensure that session host NSG exists with correct rules - $sessionHostNsg = Deploy-NetworkSecurityGroup -Name $config.sre.remoteDesktop.appSessionHost.nsg.name -ResourceGroupName $config.sre.network.vnet.rg -Location $config.sre.location - $rules = Get-JsonFromMustacheTemplate -TemplatePath (Join-Path $PSScriptRoot ".." "network_rules" $config.sre.remoteDesktop.appSessionHost.nsg.rules) -Parameters $config -AsHashtable - $null = Set-NetworkSecurityGroupRules -NetworkSecurityGroup $sessionHostNsg -Rules $rules } else { Add-LogMessage -Level Fatal "Remote desktop type '$($config.sre.remoteDesktop.type)' was not recognised!" } diff --git a/deployment/secure_research_environment/setup/Setup_SRE_Remote_Desktop.ps1 b/deployment/secure_research_environment/setup/Setup_SRE_Remote_Desktop.ps1 deleted file mode 100644 index 105fd806d6..0000000000 --- a/deployment/secure_research_environment/setup/Setup_SRE_Remote_Desktop.ps1 +++ /dev/null @@ -1,261 +0,0 @@ -param( - [Parameter(Mandatory = $true, HelpMessage = "Enter SHM ID (e.g. use 'testa' for Turing Development Safe Haven A)")] - [string]$shmId, - [Parameter(Mandatory = $true, HelpMessage = "Enter SRE ID (e.g. use 'sandbox' for Turing Development Sandbox SREs)")] - [string]$sreId -) - -Import-Module Az.Accounts -ErrorAction Stop -Import-Module Az.Compute -ErrorAction Stop -Import-Module Az.Dns -ErrorAction Stop -Import-Module Az.Network -ErrorAction Stop -Import-Module Az.Storage -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureCompute -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureDns -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureKeyVault -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureNetwork -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureResources -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/AzureStorage -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Configuration -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Cryptography -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/DataStructures -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Logging -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/RemoteCommands -Force -ErrorAction Stop -Import-Module $PSScriptRoot/../../common/Templates -Force -ErrorAction Stop - - -# Get config and original context before changing subscription -# ------------------------------------------------------------ -$config = Get-SreConfig -shmId $shmId -sreId $sreId -$originalContext = Get-AzContext -$null = Set-AzContext -SubscriptionId $config.sre.subscriptionName -ErrorAction Stop - - -# Check that we are using the correct provider -# -------------------------------------------- -if ($config.sre.remoteDesktop.provider -ne "MicrosoftRDS") { - Add-LogMessage -Level Fatal "You should not be running this script when using remote desktop provider '$($config.sre.remoteDesktop.provider)'" -} - - -# Set constants used in this script -# --------------------------------- -$vmNamePairs = @(("RDS Gateway", $config.sre.remoteDesktop.gateway.vmName), - ("RDS Session Host (App server)", $config.sre.remoteDesktop.appSessionHost.vmName)) - - -# Retrieve variables from SHM Key Vault -# ------------------------------------- -Add-LogMessage -Level Info "Creating/retrieving secrets from Key Vault '$($config.shm.keyVault.name)'..." -$null = Set-AzContext -SubscriptionId $config.shm.subscriptionName -ErrorAction Stop -$domainAdminUsername = Resolve-KeyVaultSecret -VaultName $config.shm.keyVault.name -SecretName $config.shm.keyVault.secretNames.domainAdminUsername -AsPlaintext -$domainJoinGatewayPassword = Resolve-KeyVaultSecret -VaultName $config.shm.keyVault.name -SecretName $config.shm.users.computerManagers.rdsGatewayServers.passwordSecretName -DefaultLength 20 -AsPlaintext -$domainJoinSessionHostPassword = Resolve-KeyVaultSecret -VaultName $config.shm.keyVault.name -SecretName $config.shm.users.computerManagers.rdsSessionServers.passwordSecretName -DefaultLength 20 -AsPlaintext -$null = Set-AzContext -SubscriptionId $config.sre.subscriptionName -ErrorAction Stop - - -# Retrieve variables from SRE Key Vault -# ------------------------------------- -Add-LogMessage -Level Info "Creating/retrieving secrets from Key Vault '$($config.sre.keyVault.name)'..." -$ipAddressFirstSRD = Get-NextAvailableIpInRange -IpRangeCidr $config.sre.network.vnet.subnets.compute.cidr -Offset 160 -$rdsGatewayAdminPassword = Resolve-KeyVaultSecret -VaultName $config.sre.keyVault.name -SecretName $config.sre.remoteDesktop.gateway.adminPasswordSecretName -DefaultLength 20 -AsPlaintext -$rdsAppSessionHostAdminPassword = Resolve-KeyVaultSecret -VaultName $config.sre.keyVault.name -SecretName $config.sre.remoteDesktop.appSessionHost.adminPasswordSecretName -DefaultLength 20 -AsPlaintext -$sreAdminUsername = Resolve-KeyVaultSecret -VaultName $config.sre.keyVault.name -SecretName $config.sre.keyVault.secretNames.adminUsername -DefaultValue "sre$($config.sre.id)admin".ToLower() -AsPlaintext - - -# Ensure that boot diagnostics resource group and storage account exist -# --------------------------------------------------------------------- -$null = Deploy-ResourceGroup -Name $config.sre.storage.bootdiagnostics.rg -Location $config.sre.location -$null = Deploy-StorageAccount -Name $config.sre.storage.bootdiagnostics.accountName -ResourceGroupName $config.sre.storage.bootdiagnostics.rg -Location $config.sre.location - - -# Ensure that SRE resource group and storage accounts exist -# --------------------------------------------------------- -$null = Deploy-ResourceGroup -Name $config.sre.storage.artifacts.rg -Location $config.sre.location -$sreStorageAccount = Get-StorageAccount -Name $config.sre.storage.artifacts.account.name -ResourceGroupName $config.sre.storage.artifacts.rg -SubscriptionName $config.sre.subscriptionName -ErrorAction Stop - -# Get SHM storage account -# ----------------------- -$null = Set-AzContext -Subscription $config.shm.subscriptionName -ErrorAction Stop -$shmStorageAccount = Deploy-StorageAccount -Name $config.shm.storage.artifacts.accountName -ResourceGroupName $config.shm.storage.artifacts.rg -Location $config.shm.location -$null = Set-AzContext -Subscription $config.sre.subscriptionName -ErrorAction Stop - - -# Create RDS resource group if it does not exist -# ---------------------------------------------- -$null = Deploy-ResourceGroup -Name $config.sre.remoteDesktop.rg -Location $config.sre.location - - -# Deploy RDS from template -# ------------------------ -Add-LogMessage -Level Info "Deploying RDS from template..." -$params = @{ - administratorUsername = $sreAdminUsername - bootDiagnosticsAccountName = $config.sre.storage.bootdiagnostics.accountName - domainName = $config.shm.domain.fqdn - gatewayAdministratorPassword = (ConvertTo-SecureString $rdsGatewayAdminPassword -AsPlainText -Force) - gatewayDataDiskSizeGb = [int]$config.sre.remoteDesktop.gateway.disks.data.sizeGb - gatewayDataDiskType = $config.sre.remoteDesktop.gateway.disks.data.type - gatewayDomainJoinOuPath = $config.shm.domain.ous.rdsGatewayServers.path - gatewayDomainJoinPassword = (ConvertTo-SecureString $domainJoinGatewayPassword -AsPlainText -Force) - gatewayDomainJoinUser = $config.shm.users.computerManagers.rdsGatewayServers.samAccountName - gatewayNsgName = $config.sre.remoteDesktop.gateway.nsg.name - gatewayOsDiskSizeGb = [int]$config.sre.remoteDesktop.gateway.disks.os.sizeGb - gatewayOsDiskType = $config.sre.remoteDesktop.gateway.disks.os.type - gatewayPrivateIpAddress = $config.sre.remoteDesktop.gateway.ip - gatewayVmName = $config.sre.remoteDesktop.gateway.vmName - gatewayVmSize = $config.sre.remoteDesktop.gateway.vmSize - sessionHostAppsAdministratorPassword = (ConvertTo-SecureString $rdsAppSessionHostAdminPassword -AsPlainText -Force) - sessionHostAppsOsDiskSizeGb = [int]$config.sre.remoteDesktop.appSessionHost.disks.os.sizeGb - sessionHostAppsOsDiskType = $config.sre.remoteDesktop.appSessionHost.disks.os.type - sessionHostAppsPrivateIpAddress = $config.sre.remoteDesktop.appSessionHost.ip - sessionHostAppsVmName = $config.sre.remoteDesktop.appSessionHost.vmName - sessionHostAppsVmSize = $config.sre.remoteDesktop.appSessionHost.vmSize - sessionHostsDomainJoinOuPath = $config.shm.domain.ous.rdsSessionServers.path - sessionHostsDomainJoinPassword = (ConvertTo-SecureString $domainJoinSessionHostPassword -AsPlainText -Force) - sessionHostsDomainJoinUser = $config.shm.users.computerManagers.rdsSessionServers.samAccountName - virtualNetworkGatewaySubnetName = $config.sre.network.vnet.subnets.remoteDesktop.name - virtualNetworkName = $config.sre.network.vnet.name - virtualNetworkResourceGroupName = $config.sre.network.vnet.rg - virtualNetworkSessionHostsSubnetName = $config.sre.network.vnet.subnets.remoteDesktop.name -} -Deploy-ArmTemplate -TemplatePath (Join-Path $PSScriptRoot ".." "arm_templates" "sre-rds-template.json") -TemplateParameters $params -ResourceGroupName $config.sre.remoteDesktop.rg - - -# Get public IP address of RDS gateway -# ------------------------------------ -$rdsGatewayVM = Get-AzVM -ResourceGroupName $config.sre.remoteDesktop.rg -Name $config.sre.remoteDesktop.gateway.vmName -$rdsGatewayPrimaryNicId = ($rdsGateWayVM.NetworkProfile.NetworkInterfaces | Where-Object { $_.Primary })[0].Id -$rdsGatewayPublicIp = (Get-AzPublicIpAddress -ResourceGroupName $config.sre.remoteDesktop.rg | Where-Object { $_.IpConfiguration.Id -like "$rdsGatewayPrimaryNicId*" }).IpAddress - - -# Add DNS records for RDS Gateway -# ------------------------------- -Deploy-DnsRecordCollection -PublicIpAddress $rdsGatewayPublicIp ` - -RecordNameA "@" ` - -RecordNameCAA "letsencrypt.org" ` - -RecordNameCName $serverHostname ` - -ResourceGroupName $config.shm.dns.rg ` - -SubscriptionName $config.shm.dns.subscriptionName ` - -TtlSeconds 30 ` - -ZoneName $config.sre.domain.fqdn - - -# Create blob containers in SRE storage account -# --------------------------------------------- -Add-LogMessage -Level Info "Creating blob storage containers in storage account '$($sreStorageAccount.StorageAccountName)'..." -foreach ($containerName in $config.sre.storage.artifacts.containers.Values) { - $null = Deploy-StorageContainer -Name $containerName -StorageAccount $sreStorageAccount - $null = Clear-StorageContainer -Name $containerName -StorageAccount $sreStorageAccount -} - - -# Upload RDS deployment scripts to SRE storage -# -------------------------------------------- -Add-LogMessage -Level Info "Upload RDS deployment scripts to storage..." -# Expand mustache template variables -$config["rdsTemplates"] = @{ - domainAdminUsername = $domainAdminUsername - ipAddressFirstSRD = $ipAddressFirstSRD -} -# Upload deploy script -try { - Add-LogMessage -Level Info "[ ] Uploading RDS deployment script to storage account '$($sreStorageAccount.StorageAccountName)'" - $temporaryPath = (New-TemporaryFile).FullName - Expand-MustacheTemplate -TemplatePath (Join-Path $PSScriptRoot ".." "remote" "create_rds" "templates" "Deploy_RDS_Environment.mustache.ps1") -Parameters $config | Out-File $temporaryPath - $null = Set-AzStorageBlobContent -Container $config.sre.storage.artifacts.containers.sreScriptsRDS -Context $sreStorageAccount.Context -File $temporaryPath -Blob "Deploy_RDS_Environment.ps1" -Force -ErrorAction Stop - Remove-Item -Path $temporaryPath -} catch { - Add-LogMessage -Level Fatal "Uploading RDS deployment script failed!" -Exception $_.Exception -} -# Upload deploy script -try { - Add-LogMessage -Level Info "[ ] Uploading RDS server list to storage account '$($sreStorageAccount.StorageAccountName)'" - $temporaryPath = (New-TemporaryFile).FullName - Expand-MustacheTemplate -TemplatePath (Join-Path $PSScriptRoot ".." "remote" "create_rds" "templates" "ServerList.mustache.xml") -Parameters $config | Out-File $temporaryPath - $null = Set-AzStorageBlobContent -Container $config.sre.storage.artifacts.containers.sreScriptsRDS -Context $sreStorageAccount.Context -File $temporaryPath -Blob "ServerList.xml" -Force -ErrorAction Stop - Remove-Item -Path $temporaryPath -} catch { - Add-LogMessage -Level Fatal "Uploading RDS server list failed!" -Exception $_.Exception -} - - -# Upload RDS package installers to SRE storage -# -------------------------------------------- -Add-LogMessage -Level Info "[ ] Uploading Windows package installers to storage account '$($sreStorageAccount.StorageAccountName)'..." -try { - # Chrome - $null = Set-AzureStorageBlobFromUri -FileUri "http://dl.google.com/edgedl/chrome/install/GoogleChromeStandaloneEnterprise64.msi" -BlobFilename "GoogleChrome_x64.msi" -StorageContainer $config.sre.storage.artifacts.containers.sreArtifactsRDS -StorageContext $sreStorageAccount.Context - # PuTTY - $baseUri = "https://the.earth.li/~sgtatham/putty/latest/w64/" - $filename = $(Invoke-WebRequest -Uri $baseUri).Links | Where-Object { $_.href -like "*installer.msi" } | ForEach-Object { $_.href } | Select-Object -First 1 - $version = ($filename -split "-")[2] - $null = Set-AzureStorageBlobFromUri -FileUri "$($baseUri.Replace('latest', $version))/$filename" -BlobFilename "PuTTY_x64.msi" -StorageContainer $config.sre.storage.artifacts.containers.sreArtifactsRDS -StorageContext $sreStorageAccount.Context - Add-LogMessage -Level Success "Uploaded Windows package installers" -} catch { - Add-LogMessage -Level Fatal "Failed to upload Windows package installers!" -Exception $_.Exception -} - - -# Import files to RDS VMs -# ----------------------- -Add-LogMessage -Level Info "Importing files from storage to RDS VMs..." -# Set correct list of packages from blob storage for each session host -$blobfiles = @{} -$vmNamePairs | ForEach-Object { $blobfiles[$_[1]] = @() } -foreach ($blob in Get-AzStorageBlob -Container $config.sre.storage.artifacts.containers.sreArtifactsRDS -Context $sreStorageAccount.Context) { - $blobfiles[$config.sre.remoteDesktop.appSessionHost.vmName] += @{$config.sre.storage.artifacts.containers.sreArtifactsRDS = $blob.Name } -} -# ... and for the gateway -foreach ($blob in Get-AzStorageBlob -Container $config.sre.storage.artifacts.containers.sreScriptsRDS -Context $sreStorageAccount.Context) { - $blobfiles[$config.sre.remoteDesktop.gateway.vmName] += @{$config.sre.storage.artifacts.containers.sreScriptsRDS = $blob.Name } -} -# Copy software and/or scripts to RDS VMs -$scriptPath = Join-Path $PSScriptRoot ".." "remote" "create_rds" "scripts" "Import_And_Install_Blobs.ps1" -foreach ($nameVMNameParamsPair in $vmNamePairs) { - $name, $vmName = $nameVMNameParamsPair - $containerName = $blobfiles[$vmName] | ForEach-Object { $_.Keys } | Select-Object -First 1 - $fileNames = $blobfiles[$vmName] | ForEach-Object { $_.Values } - $sasToken = New-ReadOnlyStorageAccountSasToken -SubscriptionName $config.sre.subscriptionName -ResourceGroup $config.sre.storage.artifacts.rg -AccountName $sreStorageAccount.StorageAccountName - Add-LogMessage -Level Info "[ ] Copying $($fileNames.Count) files to $name" - $params = @{ - blobNameArrayB64 = $fileNames | ConvertTo-Json -Depth 99 | ConvertTo-Base64 - downloadDir = $config.sre.remoteDesktop.gateway.installationDirectory - sasTokenB64 = $sasToken | ConvertTo-Base64 - shareOrContainerName = $containerName - storageAccountName = $sreStorageAccount.StorageAccountName - storageService = "blob" - } - $null = Invoke-RemoteScript -Shell "PowerShell" -ScriptPath $scriptPath -VMName $vmName -ResourceGroupName $config.sre.remoteDesktop.rg -Parameter $params -} - - -# Set locale, install updates and reboot -# -------------------------------------- -foreach ($nameVMNameParamsPair in $vmNamePairs) { - $name, $vmName = $nameVMNameParamsPair - Add-LogMessage -Level Info "Updating ${name}: '$vmName'..." - $params = @{} - # The RDS Gateway needs the RDWebClientManagement Powershell module - if ($name -eq "RDS Gateway") { $params["AdditionalPowershellModules"] = @("RDWebClientManagement") } - Invoke-WindowsConfiguration -VMName $vmName -ResourceGroupName $config.sre.remoteDesktop.rg -TimeZone $config.sre.time.timezone.windows -NtpServer ($config.shm.time.ntp.serverAddresses)[0] @params -} - - -# Add VMs to correct NSG -# ---------------------- -Add-VmToNSG -VMName $config.sre.remoteDesktop.gateway.vmName -VmResourceGroupName $config.sre.remoteDesktop.rg -NSGName $config.sre.remoteDesktop.gateway.nsg.name -NsgResourceGroupName $config.sre.network.vnet.rg -Add-VmToNSG -VMName $config.sre.remoteDesktop.appSessionHost.vmName -VmResourceGroupName $config.sre.remoteDesktop.rg -NSGName $config.sre.remoteDesktop.appSessionHost.nsg.name -NsgResourceGroupName $config.sre.network.vnet.rg - - -# Reboot all the RDS VMs -# ---------------------- -foreach ($nameVMNameParamsPair in $vmNamePairs) { - $null, $vmName = $nameVMNameParamsPair - Start-VM -Name $vmName -ResourceGroupName $config.sre.remoteDesktop.rg -ForceRestart -} - - -# Switch back to original subscription -# ------------------------------------ -$null = Set-AzContext -Context $originalContext -ErrorAction Stop diff --git a/deployment/secure_research_environment/setup/Update_SRE_SSL_Certificate.ps1 b/deployment/secure_research_environment/setup/Update_SRE_SSL_Certificate.ps1 index 9f8d7cae24..ff32d9ac0d 100644 --- a/deployment/secure_research_environment/setup/Update_SRE_SSL_Certificate.ps1 +++ b/deployment/secure_research_environment/setup/Update_SRE_SSL_Certificate.ps1 @@ -44,8 +44,6 @@ if ($dryRun) { $certificateName += "-dryrun" } # ------------------------------------ if ($config.sre.remoteDesktop.provider -eq "ApacheGuacamole") { $remoteDesktopVmFqdn = $config.sre.remoteDesktop.guacamole.fqdn -} elseif ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - $remoteDesktopVmFqdn = $config.sre.remoteDesktop.gateway.fqdn } else { Add-LogMessage -Level Fatal "SSL certificate updating is not configured for remote desktop type '$($config.sre.remoteDesktop.type)'!" } @@ -263,16 +261,6 @@ if ($doInstall) { CERT_THUMBPRINT = $kvCertificate.Thumbprint } $scriptType = "UnixShell" - } elseif ($config.sre.remoteDesktop.provider -eq "MicrosoftRDS") { - $targetVM = Get-AzVM -ResourceGroupName $config.sre.remoteDesktop.rg -Name $config.sre.remoteDesktop.gateway.vmName | Remove-AzVMSecret - $scriptParams = @{ - rdsFqdn = $remoteDesktopVmFqdn - certThumbPrint = $kvCertificate.Thumbprint - remoteDirectory = "/Certificates" - } - $scriptPath = Join-Path $PSScriptRoot ".." "remote" "create_rds" "scripts" "Install_Signed_Ssl_Cert.ps1" - $scriptType = "PowerShell" - $addSecretParams["CertificateStore"] = "My" } else { Add-LogMessage -Level Fatal "SSL certificate updating is not configured for remote desktop type '$($config.sre.remoteDesktop.type)'!" } diff --git a/docs/source/deployment/deploy_shm.md b/docs/source/deployment/deploy_shm.md index 94f652b1f1..df3ea4c6e4 100644 --- a/docs/source/deployment/deploy_shm.md +++ b/docs/source/deployment/deploy_shm.md @@ -535,26 +535,6 @@ PS> ./Setup_SHM_Update_Servers.ps1 -shmId -(roles_system_deployer_shm_deploy_nps)= - -
-Deploy network policy server - -![Powershell: twenty minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=twenty%20minutes) at {{file_folder}} `./deployment/safe_haven_management_environment/setup` - -```powershell -PS> ./Setup_SHM_NPS.ps1 -shmId -``` - -- where `` is the {ref}`management environment ID ` for this SHM - -```{error} -If you see an error similar to `New-AzResourceGroupDeployment: Resource Microsoft.Compute/virtualMachines/extensions NPS-SHM-/joindomain' failed with message` you may find this error resolves if you wait and retry later. -Alternatively, you can try deleting the extension from the `NPS-SHM- > Extensions` blade in the Azure portal. -``` - -
- (roles_system_deployer_shm_deploy_mirrors)=
@@ -974,119 +954,7 @@ If you see a message about buying licences, you may need to refresh the page for
-(roles_system_deployer_configure_nps)= - -## 10. {{station}} Configure network policy server - -(roles_system_deployer_shm_remote_desktop_nps)= - -### Configure the network policy server (NPS) via Remote Desktop - -![Portal: one minute](https://img.shields.io/static/v1?style=for-the-badge&logo=microsoft-azure&label=portal&color=blue&message=one%20minute) - -- Navigate to the **network policy server** VM in the portal at `Resource Groups > RG_SHM__NPS > NPS-SHM-` and note the `Private IP address` for this VM -- Use the same `` and `` as for the **SHM primary domain controller** (`DC1-SHM-`) - -#### Configure NPS logging - -![Remote: ten minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=microsoft-onedrive&label=remote&color=blue&message=ten%20minutes) - -- Log into the **network policy server** (`NPS-SHM-`) VM using the `private IP address`, `` and `` that you {ref}`obtained from the portal above `. -- Open Server Manager and select `Tools > Network Policy Server` (or open the `Network Policy Server` desktop app directly) -- Configure NPS to log to a local text file: - - - Select `NPS (Local) > Accounting` on the left-hand sidebar -
Screenshots - - ```{image} deploy_shm/nps_accounting.png - :alt: NPS accounting - :align: center - ``` - -
- - - Click on `Accounting > Configure Accounting` - - On the `Introduction` screen, click `Next`. - - On the `Select Accounting Options` screen, select `Log to text file on the local computer` then click `Next`. - - On the `Configure Local File Logging` screen, click `Next`. - - On the `Summary` screen, click `Next`. - - On the `Conclusion` screen, click `Close`. - - Click on `Log file properties > Change log file properties` - - On the `Log file` tab, select `Daily` under `Create a new log file` - - Click `Ok` - -#### Configure MFA - -![Remote: ten minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=microsoft-onedrive&label=remote&color=blue&message=ten%20minutes) - -- Log into the **network policy server** (`NPS-SHM-`) VM using the `private IP address`, `` and `` that you {ref}`obtained from the portal above `. -- Run the following command on the remote network policy server VM to configure MFA -- On the webpage pop-up, provide credentials for your **native** Global Administrator for the SHM Azure AD - -```powershell -& "C:\Program Files\Microsoft\AzureMfa\Config\AzureMfaNpsExtnConfigSetup.ps1" -``` - -- Enter `A` if prompted to install `Powershell` modules -- On the webpage pop-up, provide credentials for your **native** Global Administrator for the SHM Azure AD -- Back on the `Connect to Azure AD` screen, click `Next` -- Approve the login with MFA if required -- When prompted to `Provide your Tenant ID`, enter the Tenant ID that you {ref}`obtained from Azure Active Directory ` earlier -- At the message `Configuration complete. Press Enter to continue`, press `Enter` - -```{note} -Take care to consider any differences in the keyboard of your machine and the Windows remote desktop when entering the password. -``` - -```{error} -If you receive an error box `We can't sign you in. Javascript is required to sign you in. Do you want to continue running scripts on this page` -- Click `Yes` -- Close the dialog by clicking `X` -``` - -```{error} -If you get a Javascript error that prevents the script from running then simply run this script again. -``` - -```{error} -If you receive an Internet Explorer pop-up dialog like `Content within this application coming from the website below is being blocked by Internet Explorer Advanced Security Configuration` -- Add these webpages to the exceptions allowlist by clicking `Add` and clicking `Close` -``` - -```{error} -If you see a Windows Security Warning when connecting to Azure AD, check `Don't show this message again` and click `Yes`. -``` - -```{error} -If you see an error `New-MsolServicePrincipalCredential : Service principal was not found`, this indicates that the `Azure Multi-Factor Auth Client` is not enabled in Azure Active Directory. -
Enabling Multi-Factor Auth Client - - - Look at [the documentation here](https://docs.microsoft.com/en-us/azure/active-directory/authentication/howto-mfa-nps-extension#troubleshooting). - - Make sure the Safe Haven Azure Active Directory has valid P1 licenses: - - Go to the Azure Portal and click `Azure Active Directories` in the left hand side bar - - Click `Licenses`in the left hand side bar then `Manage > All products` - - You should see `Azure Active Directory Premium P1` in the list of products, with a non-zero number of available licenses. - - If you do not have P1 licences, purchase some following the instructions at the end of the {ref}`add additional administrators ` section above, making sure to also follow the final step to configure the MFA settings on the Azure Active Directory. - - If you are using the trial `Azure Active Directory Premium P2` licences, you may find that enabling a trial of `Enterprise Mobility + Security E5` licences will resolve this. - - Make sure that you have added a P1 licence to at least one user in the `Azure Active Directory` and have gone through the MFA setup procedure for that user. - You may have to wait a few minutes after doing this - - If you've done all of these things and nothing is working, you may have accidentally removed the `Azure Multi-Factor Auth Client` Enterprise Application from your `Azure Active Directory`. - Run `C:\Installation\Ensure_MFA_SP_AAD.ps1` to create a new service principal and try the previous steps again. -
-``` - -```{error} -If you get a `New-MsolServicePrincipalCredential: Access denied` error stating `You do not have permissions to call this cmdlet` please try the following: -
Check user credentials - -- Make sure you are logged in to the NPS server as a **domain** user rather than a local user. - - The output of the `whoami` command in Powershell should be `\` rather than `NPS-SHM-\`. - - If it is not, reconnect to the remote desktop with the username `admin@`, using the same password as before -- Make sure you authenticate to `Azure Active Directory` your own **native** Global Administrator (i.e. `admin.firstname.lastname@`) and that you have successfully logged in and verified your phone number and email address and configured MFA on your account. -
-``` - -## 11. {{closed_lock_with_key}} Apply conditional access policies +## 10. {{closed_lock_with_key}} Apply conditional access policies (roles_system_deployer_shm_require_mfa)= @@ -1167,7 +1035,7 @@ Security defaults must be disabled in order to create this policy. This should have been done when creating a policy to {ref}`require MFA for all users `. ``` -## 12. {{no_pedestrians}} Add MFA licences to any non-admin users +## 11. {{no_pedestrians}} Add MFA licences to any non-admin users Administrator accounts can use MFA and reset their passwords without a licence needing to be assigned. However, when you create non-admin users they will need to be assigned an Azure Active Directory licence in order to reset their own password. diff --git a/docs/source/deployment/deploy_shm/nps_accounting.png b/docs/source/deployment/deploy_shm/nps_accounting.png deleted file mode 100644 index 045c6ffb09..0000000000 Binary files a/docs/source/deployment/deploy_shm/nps_accounting.png and /dev/null differ diff --git a/docs/source/deployment/deploy_sre.md b/docs/source/deployment/deploy_sre.md index 8777a824b8..e1dfbef923 100644 --- a/docs/source/deployment/deploy_sre.md +++ b/docs/source/deployment/deploy_sre.md @@ -1,20 +1,262 @@ (deploy_sre)= -# Deploy a Secure Research Environment (SRE) +# Deploy a Secure Research Environment with Apache Guacamole -```{toctree} -:hidden: +These instructions will walk you through deploying a Secure Research Environment (SRE) that uses an existing Safe Haven Management (SHM) environment. -deploy_sre_apache_guacamole.md -deploy_sre_microsoft_rds.md +```{include} snippets/00_symbols.partial.md +:relative-images: ``` -These instructions will walk you through deploying a Secure Research Environment (SRE) that uses an existing Safe Haven Management (SHM) environment. +## 1. {{seedling}} Prerequisites + +```{include} snippets/01_prerequisites.partial.md +:relative-images: +``` + +(roles_deployer_sre_id)= + +## 2. {{clipboard}} Secure Research Environment configuration + +```{include} snippets/02_configuration.partial.md +:relative-images: +``` + +## 3. {{computer}} Deploy SRE + +![Powershell: a few hours](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=a%20few%20hours) at {{file_folder}} `./deployment/secure_research_environment/setup` + +```powershell +PS> ./Deploy_SRE.ps1 -shmId -sreId -VMs +``` + +- where `` is the {ref}`management environment ID ` for this SHM +- where `` is the {ref}`secure research environment ID ` for this SRE +- where `` is a list of [Azure VM sizes](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes) that you want to create. For example `'Standard_D2s_v3', 'default', 'Standard_NC6s_v3'`. If you are unsure of the appropriate VM sizes, run the script with a single `'default'`. +- VMs can be resized after deployment. See how to do so in the {ref}`System Manager instructions `. + +You will be prompted for credentials for: + +- a user with admin rights over the Azure subscriptions you plan to deploy into +- a user with Global Administrator privileges over the SHM Azure Active Active directory + +This will perform the following actions, which can be run individually if desired: + +
+Remove data from previous deployments + +```{include} snippets/03_01_remove_data.partial.md +:relative-images: +``` + +
+ +
+Register SRE with the SHM + +```{include} snippets/03_02_register_sre.partial.md +:relative-images: +``` + +
+ +
+Create SRE DNS Zone + +```{include} snippets/04_01_sre_dns.partial.md +:relative-images: +``` + +
+ +```{include} snippets/04_02_manual_dns.partial.md +:relative-images: +``` + +
+Deploy the virtual network + +```{include} snippets/04_03_deploy_vnet.partial.md +:relative-images: +``` + +
+ +
+Deploy storage accounts + +```{include} snippets/05_storage_accounts.partial.md +:relative-images: +``` + +
+ +
+Deploy Apache Guacamole remote desktop + +![Powershell: ten minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=ten%20minutes) at {{file_folder}} `./deployment/secure_research_environment/setup` + +```powershell +PS> ./Setup_SRE_Guacamole_Servers.ps1 -shmId -sreId +``` + +- where `` is the {ref}`management environment ID ` for this SHM. +- where `` is the {ref}`secure research environment ID ` for this SRE. + +
+ +
+Deploy web applications (CoCalc, CodiMD and GitLab) + +```{include} snippets/07_deploy_webapps.partial.md +:relative-images: +``` + +
+ +
+Deploy databases -We currently support two different end-user remote desktop interfaces. +```{include} snippets/08_databases.partial.md +:relative-images: +``` + +
+ +
+Deploy Secure Research Desktops (SRDs) + +The `-VmSizes` parameter that you provided to the `Deploy_SRE.ps1` script determines how many SRDs are created and how large each one will be. + +```{note} +The following script will be run once for each `` that you specified. +If you specify the same size more than once, you will create multiple SRDs of that size. +``` + +```{include} snippets/09_single_srd.partial.md +:relative-images: +``` + +
+ +
+Apply network configuration + +```{include} snippets/10_network_lockdown.partial.md +:relative-images: +``` + +
+ +
+Configure firewall + +```{include} snippets/11_configure_firewall.partial.md +:relative-images: +``` + +
+ +
+Configure monitoring + +```{include} snippets/12_configure_monitoring.partial.md +:relative-images: +``` + +
+ +
+Enable backup + +```{include} snippets/13_enable_backup.partial.md +:relative-images: +``` + +
-[User guide: Apache Guacamole](deploy_sre_apache_guacamole.md) -: {{sparkles}} **Recommended** {{sparkles}} Step-by-step instructions to deploy an SRE using `Apache Guacamole` (**tiers 0-3**) +## 4. {{microscope}} Test deployed SRE -[User guide: Microsoft Remote Desktop](deploy_sre_microsoft_rds.md) -: Step-by-step instructions to deploy an SRE using `Microsoft Remote Desktop` (**tiers 2-3 only**) +(deploy_sre_apache_guacamole_create_user_account)= + +### {{bicyclist}} Verify non-privileged user account is set up + +```{include} snippets/06_01_create_user_account.partial.md +:relative-images: +``` + +To complete the account setup, follow the instructions for password and MFA setup present in the {ref}`user guide `. + +(deploy_sre_apache_guacamole_test_remote_desktop)= + +### {{pear}} Test the Apache Guacamole remote desktop + +- Launch a local web browser on your **deployment machine** and go to `https://.` and log in with the user name and password you set up for the non-privileged user account. + - For example for ` = project.turingsafehaven.ac.uk` and ` = sandbox` this would be `https://sandbox.project.turingsafehaven.ac.uk/` +- You should see a screen like the following. If you do not, follow the **troubleshooting** instructions below. + + ```{image} ../roles/researcher/user_guide/guacamole_dashboard.png + :alt: Guacamole dashboard + :align: center + ``` + +- At this point you should double click on the {{computer}} `Ubuntu0` link under `All Connections` which should bring you to the secure remote desktop (SRD) login screen +- You will need the short-form of the user name (ie. without the `@` part) and the same password as before +- This should bring you to the SRD that will look like the following + + ```{image} deploy_sre/guacamole_desktop.png + :alt: Guacamole dashboard + :align: center + ``` + +```{important} +Ensure that you are connecting from one of the **permitted IP ranges** specified in the `inboundAccessFrom` section of the SRE config file. +For example, if you have authorised a corporate VPN, check that you have correctly configured you client to connect to it. +``` + +````{error} +If you see an error like the following when attempting to log in, it is likely that the AzureAD application is not registered as an `ID token` provider. + +```{image} deploy_sre/guacamole_aad_idtoken_failure.png +:alt: AAD ID token failure +:align: center +``` + +
Register AzureAD application + +![Azure AD: one minute](https://img.shields.io/static/v1?style=for-the-badge&logo=microsoft-academic&label=Azure%20AD&color=blue&message=one%20minute) + +- From the Azure portal, navigate to the AAD you have created. +- Navigate to `Azure Active Directory > App registrations`, and select the application called `Guacamole SRE `. +- Click on `Authentication` on the left-hand sidebar +- Ensure that the `ID tokens` checkbox is ticked and click on the `Save` icon if you had to make any changes + ```{image} deploy_sre/guacamole_aad_app_registration_idtoken.png + :alt: AAD app registration + :align: center + ``` +
+```` + +### {{snowflake}} Test CoCalc, CodiMD and GitLab servers + +- Connect to the remote desktop {ref}`using the instructions above ` +- Test `CoCalc` by clicking on the `CoCalc` desktop icon. + - This should open a web browser inside the remote desktop + - You will get a warning about a `Potential Security Risk` related to a self-signed certificate. It is safe to trust this by selecting `Advanced > Accept the risk and continue`. + - Create a new username and password and use this to log in. +- Test `CodiMD` by clicking on the `CodiMD` desktop icon. + - This should open a web browser inside the remote desktop + - Log in with the short-form `username` of a user in the `SG Research Users` security group. +- Test `GitLab` by clicking on the `GitLab` desktop icon. + - This should open a web browser inside the remote desktop + - Log in with the short-form `username` of a user in the `SG Research Users` security group. + +````{error} +Should there be any issues using the web apps (e.g. unable to log in, or log in page not appearing) you can inspect the build log and access the console for the relevant VMs following the guide for {ref}`System Managers ` +```` + +### {{fire}} Run smoke tests on SRD + +```{include} snippets/14_run_smoke_tests.partial.md +:relative-images: +``` diff --git a/docs/source/deployment/deploy_sre/msrds_desktop.png b/docs/source/deployment/deploy_sre/msrds_desktop.png deleted file mode 100644 index fd3dd74713..0000000000 Binary files a/docs/source/deployment/deploy_sre/msrds_desktop.png and /dev/null differ diff --git a/docs/source/deployment/deploy_sre_apache_guacamole.md b/docs/source/deployment/deploy_sre_apache_guacamole.md deleted file mode 100644 index 9f5f69533e..0000000000 --- a/docs/source/deployment/deploy_sre_apache_guacamole.md +++ /dev/null @@ -1,262 +0,0 @@ -(deploy_sre_apache_guacamole)= - -# Deploy an SRE with Apache Guacamole - -These instructions will walk you through deploying a Secure Research Environment (SRE) that uses an existing Safe Haven Management (SHM) environment. - -```{include} snippets/00_symbols.partial.md -:relative-images: -``` - -## 1. {{seedling}} Prerequisites - -```{include} snippets/01_prerequisites.partial.md -:relative-images: -``` - -(roles_deployer_sre_id)= - -## 2. {{clipboard}} Secure Research Environment configuration - -```{include} snippets/02_configuration.partial.md -:relative-images: -``` - -## 3. {{computer}} Deploy SRE - -![Powershell: a few hours](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=a%20few%20hours) at {{file_folder}} `./deployment/secure_research_environment/setup` - -```powershell -PS> ./Deploy_SRE.ps1 -shmId -sreId -VMs -``` - -- where `` is the {ref}`management environment ID ` for this SHM -- where `` is the {ref}`secure research environment ID ` for this SRE -- where `` is a list of [Azure VM sizes](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes) that you want to create. For example `'Standard_D2s_v3', 'default', 'Standard_NC6s_v3'`. If you are unsure of the appropriate VM sizes, run the script with a single `'default'`. -- VMs can be resized after deployment. See how to do so in the {ref}`System Manager instructions `. - -You will be prompted for credentials for: - -- a user with admin rights over the Azure subscriptions you plan to deploy into -- a user with Global Administrator privileges over the SHM Azure Active Active directory - -This will perform the following actions, which can be run individually if desired: - -
-Remove data from previous deployments - -```{include} snippets/03_01_remove_data.partial.md -:relative-images: -``` - -
- -
-Register SRE with the SHM - -```{include} snippets/03_02_register_sre.partial.md -:relative-images: -``` - -
- -
-Create SRE DNS Zone - -```{include} snippets/04_01_sre_dns.partial.md -:relative-images: -``` - -
- -```{include} snippets/04_02_manual_dns.partial.md -:relative-images: -``` - -
-Deploy the virtual network - -```{include} snippets/04_03_deploy_vnet.partial.md -:relative-images: -``` - -
- -
-Deploy storage accounts - -```{include} snippets/05_storage_accounts.partial.md -:relative-images: -``` - -
- -
-Deploy Apache Guacamole remote desktop - -![Powershell: ten minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=ten%20minutes) at {{file_folder}} `./deployment/secure_research_environment/setup` - -```powershell -PS> ./Setup_SRE_Guacamole_Servers.ps1 -shmId -sreId -``` - -- where `` is the {ref}`management environment ID ` for this SHM. -- where `` is the {ref}`secure research environment ID ` for this SRE. - -
- -
-Deploy web applications (CoCalc, CodiMD and GitLab) - -```{include} snippets/07_deploy_webapps.partial.md -:relative-images: -``` - -
- -
-Deploy databases - -```{include} snippets/08_databases.partial.md -:relative-images: -``` - -
- -
-Deploy Secure Research Desktops (SRDs) - -The `-VmSizes` parameter that you provided to the `Deploy_SRE.ps1` script determines how many SRDs are created and how large each one will be. - -```{note} -The following script will be run once for each `` that you specified. -If you specify the same size more than once, you will create multiple SRDs of that size. -``` - -```{include} snippets/09_single_srd.partial.md -:relative-images: -``` - -
- -
-Apply network configuration - -```{include} snippets/10_network_lockdown.partial.md -:relative-images: -``` - -
- -
-Configure firewall - -```{include} snippets/11_configure_firewall.partial.md -:relative-images: -``` - -
- -
-Configure monitoring - -```{include} snippets/12_configure_monitoring.partial.md -:relative-images: -``` - -
- -
-Enable backup - -```{include} snippets/13_enable_backup.partial.md -:relative-images: -``` - -
- -## 4. {{microscope}} Test deployed SRE - -(deploy_sre_apache_guacamole_create_user_account)= - -### {{bicyclist}} Verify non-privileged user account is set up - -```{include} snippets/06_01_create_user_account.partial.md -:relative-images: -``` - -To complete the account setup, follow the instructions for password and MFA setup present in the {ref}`user guide `. - -(deploy_sre_apache_guacamole_test_remote_desktop)= - -### {{pear}} Test the Apache Guacamole remote desktop - -- Launch a local web browser on your **deployment machine** and go to `https://.` and log in with the user name and password you set up for the non-privileged user account. - - For example for ` = project.turingsafehaven.ac.uk` and ` = sandbox` this would be `https://sandbox.project.turingsafehaven.ac.uk/` -- You should see a screen like the following. If you do not, follow the **troubleshooting** instructions below. - - ```{image} ../roles/researcher/user_guide/guacamole_dashboard.png - :alt: Guacamole dashboard - :align: center - ``` - -- At this point you should double click on the {{computer}} `Ubuntu0` link under `All Connections` which should bring you to the secure remote desktop (SRD) login screen -- You will need the short-form of the user name (ie. without the `@` part) and the same password as before -- This should bring you to the SRD that will look like the following - - ```{image} deploy_sre/guacamole_desktop.png - :alt: Guacamole dashboard - :align: center - ``` - -```{important} -Ensure that you are connecting from one of the **permitted IP ranges** specified in the `inboundAccessFrom` section of the SRE config file. -For example, if you have authorised a corporate VPN, check that you have correctly configured you client to connect to it. -``` - -````{error} -If you see an error like the following when attempting to log in, it is likely that the AzureAD application is not registered as an `ID token` provider. - -```{image} deploy_sre/guacamole_aad_idtoken_failure.png -:alt: AAD ID token failure -:align: center -``` - -
Register AzureAD application - -![Azure AD: one minute](https://img.shields.io/static/v1?style=for-the-badge&logo=microsoft-academic&label=Azure%20AD&color=blue&message=one%20minute) - -- From the Azure portal, navigate to the AAD you have created. -- Navigate to `Azure Active Directory > App registrations`, and select the application called `Guacamole SRE `. -- Click on `Authentication` on the left-hand sidebar -- Ensure that the `ID tokens` checkbox is ticked and click on the `Save` icon if you had to make any changes - ```{image} deploy_sre/guacamole_aad_app_registration_idtoken.png - :alt: AAD app registration - :align: center - ``` -
-```` - -### {{snowflake}} Test CoCalc, CodiMD and GitLab servers - -- Connect to the remote desktop {ref}`using the instructions above ` -- Test `CoCalc` by clicking on the `CoCalc` desktop icon. - - This should open a web browser inside the remote desktop - - You will get a warning about a `Potential Security Risk` related to a self-signed certificate. It is safe to trust this by selecting `Advanced > Accept the risk and continue`. - - Create a new username and password and use this to log in. -- Test `CodiMD` by clicking on the `CodiMD` desktop icon. - - This should open a web browser inside the remote desktop - - Log in with the short-form `username` of a user in the `SG Research Users` security group. -- Test `GitLab` by clicking on the `GitLab` desktop icon. - - This should open a web browser inside the remote desktop - - Log in with the short-form `username` of a user in the `SG Research Users` security group. - -````{error} -Should there be any issues using the web apps (e.g. unable to log in, or log in page not appearing) you can inspect the build log and access the console for the relevant VMs following the guide for {ref}`System Managers ` -```` - -### {{fire}} Run smoke tests on SRD - -```{include} snippets/14_run_smoke_tests.partial.md -:relative-images: -``` diff --git a/docs/source/deployment/deploy_sre_microsoft_rds.md b/docs/source/deployment/deploy_sre_microsoft_rds.md deleted file mode 100644 index a850afe52a..0000000000 --- a/docs/source/deployment/deploy_sre_microsoft_rds.md +++ /dev/null @@ -1,368 +0,0 @@ -(deploy_sre_microsoft_rds)= - -# Deploy an SRE with Microsoft RDS - -```{warning} -Support for Microsoft Remote Desktop is deprecated. Deployment scripts and related documentation will be removed in version `4.2.0` of the Data Safe Haven. -``` - -These instructions will walk you through deploying a Secure Research Environment (SRE) that uses an existing Safe Haven Management (SHM) environment. - -```{important} -If you are deploying a {ref}`policy_tier_0` or {ref}`policy_tier_1` environment, or a development environment, we would suggest deploying with {ref}`Guacamole `. -``` - -```{include} snippets/00_symbols.partial.md -:relative-images: -``` - -## 1. {{seedling}} Prerequisites - -```{include} snippets/01_prerequisites.partial.md -:relative-images: -``` - -### VPN connection to the SHM VNet - -For some operations, you will need to log on to some of the VMs that you deploy and make manual changes. -This is done using the VPN which should have been deployed {ref}`when setting up the SHM environment `. - -## 2. {{clipboard}} Secure Research Environment configuration - -```{include} snippets/02_configuration.partial.md -:relative-images: -``` - -## 3. {{cop}} Prepare SHM environment - -### (Optional) {{fast_forward}} Remove data from previous deployments - -```{include} snippets/03_01_remove_data.partial.md -:relative-images: -``` - -### {{registered}} Register SRE with the SHM - -```{include} snippets/03_02_register_sre.partial.md -:relative-images: -``` - -## 4. {{station}} Deploy networking components - -### {{clubs}} Create SRE DNS Zone - -```{include} snippets/04_01_sre_dns.partial.md -:relative-images: -``` - -```{include} snippets/04_02_manual_dns.partial.md -:relative-images: -``` - -### {{ghost}} Deploy the virtual network - -```{include} snippets/04_03_deploy_vnet.partial.md -:relative-images: -``` - -## 5. {{floppy_disk}} Deploy storage accounts - -```{include} snippets/05_storage_accounts.partial.md -:relative-images: -``` - -(deploy_sre_microsoft_deploy_remote_desktop)= - -## 6. {{satellite}} Deploy remote desktop - -### {{tropical_fish}} Deploy the remote desktop servers - -![Powershell: fifty minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=fifty%20minutes) at {{file_folder}} `./deployment/secure_research_environment/setup` - -```powershell -PS> ./Setup_SRE_Remote_Desktop.ps1 -shmId -sreId -``` - -- where `` is the {ref}`management environment ID ` for this SHM -- where `` is the {ref}`secure research environment ID ` for this SRE - -```{error} -If you encounter errors with the deployment of the remote desktop servers, re-running `Setup_SRE_Remote_Desktop.ps1` should fix them. -If this does not work, please try deleting everything that has been deployed into the `RG_SHM__SRE__REMOTE_DESKTOP` resource group for this SRE and {ref}`attempt to run this step again `. -``` - -### {{satellite}} Configure RDS webclient - -![Remote: twenty minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=microsoft-onedrive&label=remote&color=blue&message=twenty%20minutes) - -- Navigate to the **RDS Gateway** VM in the portal at `Resource Groups > RG_SHM__SRE__REMOTE_DESKTOP > RDG-SRE-` and note the `Private IP address` for this VM -- Log into the **RDS Gateway** (`RDG-SRE-`) VM using this `private IP address` together with the same `` and `` that you used to {ref}`log into the SHM domain controller `. -- Run the following command on the RDS VM to configure the remote desktop environment - -```powershell -PS> C:\Installation\Deploy_RDS_Environment.ps1 -``` - -```{caution} -This script cannot be run remotely since remote `Powershell` runs as a local admin but this script has to be run as a domain admin. -``` - -```{error} -![Windows](https://img.shields.io/badge/-555?&logo=windows&logoColor=white) when deploying on Windows, the SHM VPN needs to be redownloaded/reconfigured each time an SRE is deployed. -Otherwise, there may be difficulties connecting to the **RDS Gateway**. -``` - -### {{closed_lock_with_key}} Secure RDS webclient - -![Powershell: fifteen minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=fifteen%20minutes) at {{file_folder}} `./deployment/secure_research_environment/setup` - -```powershell -PS> ./Secure_SRE_Remote_Desktop_Gateway.ps1 -shmId -sreId -``` - -- where `` is the {ref}`management environment ID ` for this SHM -- where `` is the {ref}`secure research environment ID ` for this SRE - -This will perform the following actions, which can be run individually if desired: - -#### Disable insecure TLS connections - -
-Details - -![Powershell: five minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=five%20minutes) at {{file_folder}} `./deployment/secure_research_environment/setup` - -```powershell -PS> ./Disable_Legacy_TLS.ps1 -shmId -sreId -``` - -- where `` is the {ref}`management environment ID ` for this SHM -- where `` is the {ref}`secure research environment ID ` for this SRE - -```{tip} -If additional TLS protocols become available (or existing ones are found to be insecure) during the lifetime of the SRE, then you can re-run `./Disable_Legacy_TLS.ps1` to update the list of accepted protocols -``` - -
- -(deploy_sre_microsoft_rds_configure_cap_rap)= - -#### Configure RDS CAP and RAP settings - -
-Details - -![Powershell: five minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=five%20minutes) at {{file_folder}} `./deployment/secure_research_environment/setup` - -```powershell -PS> ./Configure_SRE_RDS_CAP_And_RAP.ps1 -shmId -sreId -``` - -- where `` is the {ref}`management environment ID ` for this SHM -- where `` is the {ref}`secure research environment ID ` for this SRE - -
- -(deploy_sre_microsoft_update_ssl_certificate)= - -#### Update SSL certificate - -
-Details - -![Powershell: five minutes](https://img.shields.io/static/v1?style=for-the-badge&logo=powershell&label=local&color=blue&message=five%20minutes) at {{file_folder}} `./deployment/secure_research_environment/setup` - -```powershell -PS> ./Update_SRE_RDS_SSL_Certificate.ps1 -shmId -sreId -emailAddress -``` - -- where `` is the {ref}`management environment ID ` for this SHM -- where `` is the {ref}`secure research environment ID ` for this SRE -- where `` is an email address that you want to be notified when certificates are close to expiry - -```{tip} -`./Update_SRE_RDS_SSL_Certificate.ps1` should be run again whenever you want to update the certificate for this SRE. -``` - -```{caution} -`Let's Encrypt` will only issue **5 certificates per week** for a particular host (e.g. `rdg-sre-sandbox.project.turingsafehaven.ac.uk`). -To reduce the number of calls to `Let's Encrypt`, the signed certificates are stored in the Key Vault for easy redeployment. -For production environments this should usually not be an issue. -``` - -````{important} -If you find yourself frequently redeploying a test environment and hit the `Let's Encrypt` certificate limit, you can can use: - -```powershell -> ./Update_SRE_RDS_SSL_Certificate.ps1 -dryRun $true -``` - -to use the `Let's Encrypt` staging server, which will issue certificates more frequently. -These certificates will **not** be trusted by your browser, and so should not be used in production. -```` - -
- -### {{bicyclist}} Verify non-privileged user account is set up - -```{include} snippets/06_01_create_user_account.partial.md -:relative-images: -``` - -To complete the account setup, follow the instructions for password and MFA setup present in the {ref}`user guide `. - -### {{nut_and_bolt}} Test the Microsoft RDS remote desktop - -- Launch a local web browser on your **deployment machine** and go to `https://.` and log in with the user name and password you set up for the non-privileged user account. - - For example for ` = project.turingsafehaven.ac.uk` and ` = sandbox` this would be `https://sandbox.project.turingsafehaven.ac.uk/` -- You should see a screen like the following. If you do not, follow the **troubleshooting** instructions below. - - ```{image} deploy_sre/msrds_desktop.png - :alt: Microsoft RDS desktop - :align: center - ``` - -```{important} -Ensure that you are connecting from one of the **permitted IP ranges** specified in the `inboundAccessFrom` section of the SRE config file. -For example, if you have authorised a corporate VPN, check that you have correctly configured you client to connect to it. -``` - -```{note} -Clicking on the apps will not work until the other servers have been deployed. -``` - -```{error} -If you get a `404 resource not found` error when accessing the webclient URL, it is likely that the RDS webclient failed to install correctly. -- Go back to the previous section and rerun the `C:\Installation\Deploy_RDS_Environment.ps1` script on the RDS gateway. -- After doing this, follow the instructions to {ref}`configure RDS CAP and RAP settings ` and to {ref}`update the SSL certificate `. -``` - -```{error} -If you get an `unexpected server authentication certificate error` , your browser has probably cached a previous certificate for this domain. -- Do a [hard reload](https://www.getfilecloud.com/blog/2015/03/tech-tip-how-to-do-hard-refresh-in-browsers/) of the page (permanent fix) -- OR open a new private / incognito browser window and visit the page. -``` - -```{error} -If you can see an empty screen with `Work resources` but no app icons, your user has not been correctly added to the security group. -- Ensure that the user you have logged in with is a member of the `SG Research Users` group on the domain controller -``` - -## 7. {{snowflake}} Deploy web applications (CoCalc, CodiMD and GitLab) - -```{include} snippets/07_deploy_webapps.partial.md -:relative-images: -``` - -### {{microscope}} Test CoCalc, CodiMD and GitLab servers - -- Launch a local web browser on your **deployment machine** and go to `https://.` and log in with the user name and password you set up for the non-privileged user account. - - for example for ` = project.turingsafehaven.ac.uk` and ` = sandbox` this would be `https://sandbox.project.turingsafehaven.ac.uk/` -- Test `CoCalc` by clicking on the `CoCalc` app icon. - - You should receive an MFA request to your phone or authentication app. - - Once you have approved the sign in, you should see a Chrome window with the CoCalc login page. - - You will get a warning about a `Potential Security Risk` related to a self-signed certificate. It is safe to trust this by selecting `Advanced > Accept the risk and continue`. - - Create a new username and password and use this to log in. -- Test `CodiMD` by clicking on the `CodiMD` app icon. - - You should receive an MFA request to your phone or authentication app. - - Once you have approved the sign in, you should see a Chrome window with the GitLab login page. - - Log in with the short-form `username` of a user in the `SG Research Users` security group. -- Test `GitLab` by clicking on the `GitLab` app icon. - - You should receive an MFA request to your phone or authentication app. - - Once you have approved the sign in, you should see a Chrome window with the GitLab login page. - - Log in with the short-form `username` of a user in the `SG Research Users` security group. -- If you do not get an MFA prompt or you cannot connect to one of the servers, follow the **troubleshooting** instructions below. - -```{error} -If you can log in to the initial webclient authentication but do not get the MFA request, then the issue is likely that the configuration of the connection between the SHM NPS server and the RDS Gateway server is not correct. - -In order to diagnose whether this is an issue with the NPS settings or the MFA connection, run the diagnostic script on the NPS server at `C:\Installation\MFA_NPS_Troubleshooter.ps1` and follow the instructions there. - -If the "Checking if Azure MFA SPN exists" test fails, then run `C:\Installation\Ensure_MFA_SP_AAD.ps1` to restore it. -``` - -```{error} -If running the previous script did not help to diagnose the issue then try the following: - -- Ensure that both the SHM NPS server and the RDS Gateway are running -- Follow the instructions to {ref}`configure RDS CAP and RAP settings ` to reset the configuration of the RDS gateway and NPS VMs. -- Ensure that the default UDP ports `1812`, `1813`, `1645` and `1646` are all open on the SHM NPS network security group (`NSG_SHM_SUBNET_IDENTITY`). [This documentation]() gives further details. -``` - -```{error} -If this does not resolve the issue, trying checking the Windows event logs - -- Use `Event Viewer` on the SRE RDS Gateway (`Custom views > Server roles > Network Policy and Access Services`) to check whether the NPS server is contactable and whether it is discarding requests -- Use `Event Viewer` on the SHM NPS server (`Custom views > Server roles > Network Policy and Access Services`) to check whether NPS requests are being received and whether the NPS server has an LDAP connection to the SHM DC. - - Ensure that the requests are being received from the **private** IP address of the RDS Gateway and **not** its public one. -- One common error on the NPS server is `A RADIUS message was received from the invalid RADIUS client IP address x.x.x.x` . [This help page]() might be useful. - - This may indicate that the NPS server could not join the SHM domain. Try `ping DC1-SHM-` from the NPS server and if this does not resolve, try rebooting it. -- Ensure that the `Windows Firewall` is set to `Domain Network` on both the SHM NPS server and the SRE RDS Gateway -``` - -```{error} -If you get a `We couldn't connect to the gateway because of an error` message, it's likely that the `Remote RADIUS Server` authentication timeouts have not been set correctly. -- Follow the instructions to {ref}`configure RDS CAP and RAP settings ` to reset the authentication timeouts on the RDS gateway. -``` - -```{error} -If you get multiple MFA requests with no change in the `Opening ports` message, it may be that the shared RADIUS secret does not match on the SHM server and SRE RDS Gateway. -- Follow the instructions to {ref}`configure RDS CAP and RAP settings ` to reset the secret on both the RDS gateway and NPS VMs. -- Alternatively, this can happen if the NPS secret stored in the Key Vault is too long. We found that a 20 character secret caused problems but the (default) 12 character secret works. -``` - -```{error} -Should there be any issues using the web apps (e.g. unable to log in, or log in page not appearing) you can inspect the build log and access the console for the relevant VMs following the guide for {ref}`System Managers ` -```` - -## 8. {{baseball}} Deploy databases - -```{include} snippets/08_databases.partial.md -:relative-images: -``` - -## 9. {{computer}} Deploy secure research desktops (SRDs) - -```{include} snippets/09_single_srd.partial.md -:relative-images: -``` - -```{hint} -If desired, you can also provide a VM size by passing the optional `-vmSize` parameter. -``` - -If you want to deploy several SRDs, simply repeat the above steps with a different IP address last octet. - -```{important} -The initial shared `SRD Main` shared VM should be deployed with the last octet `160` as the dashboard is hard-coded to expect this. -``` - -## 10. {{lock}} Apply network configuration - -```{include} snippets/10_network_lockdown.partial.md -:relative-images: -``` - -## 11. {{fire_engine}} Configure firewall - -```{include} snippets/11_configure_firewall.partial.md -:relative-images: -``` - -## 12. {{chart_with_upwards_trend}} Configure logging - -```{include} snippets/12_configure_monitoring.partial.md -:relative-images: -``` - -## 13. {{left_right_arrow}} Enable backup - -```{include} snippets/13_enable_backup.partial.md -:relative-images: -``` - -## 14. {{fire}} Run smoke tests on SRD - -```{include} snippets/14_run_smoke_tests.partial.md -:relative-images: -``` diff --git a/docs/source/deployment/security_checklist.md b/docs/source/deployment/security_checklist.md index f8dcc553c6..3895be133a 100644 --- a/docs/source/deployment/security_checklist.md +++ b/docs/source/deployment/security_checklist.md @@ -34,7 +34,7 @@ Some parts of the checklist are only relevant when there are multiple SREs attac ```{important} - If you haven't already, you'll need download a VPN certificate and configure {ref}`VPN access ` for the SHM -- Make sure you can use Remote Desktop to log in to the {ref}`domain controller (DC1) ` and the {ref}`network policy server (NPS) `. +- Make sure you can use Remote Desktop to log in to the {ref}`domain controller (DC1) `. ``` The following users will be needed for this checklist @@ -68,23 +68,13 @@ Attempt to login to the remote desktop web client as the **SRE standard user** ````{attention} {{camera}} Verify that: - -{{pear}} **Guacamole**: -
user is prompted to setup MFA +
user is prompted to setup MFA ```{image} security_checklist/login_no_mfa_guacamole.png :alt: Guacamole MFA setup prompt :align: center ``` -
- -{{bento_box}} **Microsoft Remote Desktop**: -
login works but apps cannot be viewed -```{image} security_checklist/login_no_mfa_msrds.png -:alt: Microsoft RDS dashboard with no apps -:align: center -```
```` @@ -94,31 +84,13 @@ Add the **SRE standard user** to the relevant `Research Users` group under `Safe ````{attention} {{camera}} Verify that: - -{{pear}} **Guacamole**:
user is prompted to setup MFA ```{image} security_checklist/login_no_mfa_guacamole.png :alt: Guacamole MFA setup prompt :align: center ``` -
- -{{bento_box}} **Microsoft Remote Desktop**: -
login works and apps can be viewed - -```{image} security_checklist/msrds_dashboard_with_apps.png -:alt: Microsoft RDS dashboard with apps -:align: center -``` -
- -
attempting to login to SRD Main fails -```{image} security_checklist/msrds_failed_to_connect.png -:alt: Microsoft RDS failed to connect -:align: center -```
```` @@ -155,23 +127,13 @@ Check that the **SRE standard user** can authenticate with MFA. ````{attention} {{camera}} Verify that: - -{{pear}} **Guacamole**:
you are prompted for MFA and can respond ```{image} security_checklist/aad_mfa_approve_signin_request.png :alt: AAD MFA approve sign-in request :align: center ``` -
-{{bento_box}} **Microsoft Remote Desktop**: -
you are prompted for MFA and can respond when attempting to log in to SRD Main (Desktop) - -```{image} security_checklist/aad_mfa_approve_signin_request.png -:alt: AAD MFA approve sign-in request -:align: center -```
```` @@ -183,23 +145,13 @@ Check that the **SRE standard user** can access the Secure Research Desktop (SRD ````{attention} {{camera}} Verify that: - -{{pear}} **Guacamole**:
you can connect to Desktop: Ubuntu0 ```{image} security_checklist/guacamole_srd_desktop.png :alt: SRD desktop :align: center ``` -
- -{{bento_box}} **Microsoft Remote Desktop**: -
you can connect to SRD Main (Desktop) -```{image} security_checklist/msrds_srd_desktop.png -:alt: SRD desktop -:align: center -```
```` @@ -248,6 +200,7 @@ Check that the **SRE standard user** can access the Secure Research Desktop (SRD :alt: SRD no internet :align: center ``` +
you cannot access the website using curl @@ -256,6 +209,7 @@ Check that the **SRE standard user** can access the Secure Research Desktop (SRD :alt: SRD no curl :align: center ``` +
you cannot look up the IP address for the website using nslookup @@ -284,6 +238,7 @@ Check that users cannot connect from one SRE to another one in the same SHM, eve :alt: SSH connection failure :align: center ``` +
```` @@ -372,8 +327,7 @@ A device is able to connect to the environment if and only if it is managed (wit There are network rules permitting access to the remote desktop gateway from allow-listed IP addresses only - Navigate to the NSG for this SRE in the portal: - - {{bento_box}} **Microsoft Remote Desktop:** `NSG_SHM__SRE__RDS_SERVER` - - {{pear}} **Guacamole:** `NSG_SHM__SRE__GUACAMOLE` + - {{pear}} `NSG_SHM__SRE__GUACAMOLE` ````{attention} {{camera}} Verify that: @@ -461,8 +415,7 @@ Connection from within the secure physical space is possible. ```` - Find the public IP address for the remote desktop server VM by searching for this VM in the portal, then looking at `Connect` under `Settings`. - - {{pear}} **Guacamole:** VM name will be `GUACAMOLE-SRE-` - - {{bento_box}} **Microsoft Remote Desktop:** VM name will be `RDG-SRE-` + - {{pear}} VM name will be `GUACAMOLE-SRE-` - Attempt to login as the **SRE standard user** via `SSH` with `ssh @` (e.g. `ssh ada.lovelace@8.8.8.8`) ````{attention} diff --git a/docs/source/deployment/security_checklist/login_no_mfa_msrds.png b/docs/source/deployment/security_checklist/login_no_mfa_msrds.png deleted file mode 100644 index ecd4667232..0000000000 Binary files a/docs/source/deployment/security_checklist/login_no_mfa_msrds.png and /dev/null differ diff --git a/docs/source/deployment/security_checklist/msrds_dashboard_with_apps.png b/docs/source/deployment/security_checklist/msrds_dashboard_with_apps.png deleted file mode 100644 index 13e75bd4e7..0000000000 Binary files a/docs/source/deployment/security_checklist/msrds_dashboard_with_apps.png and /dev/null differ diff --git a/docs/source/deployment/security_checklist/msrds_failed_to_connect.png b/docs/source/deployment/security_checklist/msrds_failed_to_connect.png deleted file mode 100644 index 222b562aed..0000000000 Binary files a/docs/source/deployment/security_checklist/msrds_failed_to_connect.png and /dev/null differ diff --git a/docs/source/deployment/security_checklist/msrds_srd_desktop.png b/docs/source/deployment/security_checklist/msrds_srd_desktop.png deleted file mode 100644 index 1c0199ef18..0000000000 Binary files a/docs/source/deployment/security_checklist/msrds_srd_desktop.png and /dev/null differ diff --git a/docs/source/deployment/snippets/02_configuration.partial.md b/docs/source/deployment/snippets/02_configuration.partial.md index 40148c2d2e..32ebec2242 100644 --- a/docs/source/deployment/snippets/02_configuration.partial.md +++ b/docs/source/deployment/snippets/02_configuration.partial.md @@ -28,7 +28,7 @@ The following core SRE properties are required - look in the `environment_config "type": "The name of the SRD image (most commonly 'Ubuntu')", "version": "The version of the SRD image (e.g. 0.1.2019082900)" }, - "remoteDesktopProvider": "Which remote desktop provider to use. Either 'ApacheGuacamole' (recommended, tiers 0-3) or 'MicrosoftRDS' (tiers 2-3 only)", + "remoteDesktopProvider": "[Deprecated] Only 'ApacheGuacamole' is supported. If this parameter is not supplied, it will default to 'ApacheGuacamole'", "azureAdminGroupName": "[Optional] Azure Security Group that admins of this SRE will belong to. If not specified then the same one as the SHM will be used.", "dataAdminIpAddresses": "A list of one or more IP addresses which admins will be using to transfer sensitive data to/from the secure Azure storage area (if not specified then Turing IP addresses will be used).", "databases": "[Optional] A list of zero or more database flavours from the following list ('MSSQL', 'PostgreSQL'). For example ['MSSQL', 'PostgreSQL'] would deploy both an MS-SQL and a PostgreSQL database.", diff --git a/docs/source/deployment/snippets/14_run_smoke_tests.partial.md b/docs/source/deployment/snippets/14_run_smoke_tests.partial.md index cd864a4c97..4bc8bca0b5 100644 --- a/docs/source/deployment/snippets/14_run_smoke_tests.partial.md +++ b/docs/source/deployment/snippets/14_run_smoke_tests.partial.md @@ -10,4 +10,4 @@ They are automatically uploaded to the SRD during the deployment step. - if any of the tests fail, check the `README.md` in this folder for help in diagnosing the issues - Copy `tests/test_jupyter.ipynb` to your home directory - activate each of the available Python versions in turn - - run `jupyter notebook` in each case and check that you can run the notebook and that all versions and paths match throughout. See [Available Python and R versions](/roles/researcher/user_guide_guacamole.md#available-python-and-r-versions) + - run `jupyter notebook` in each case and check that you can run the notebook and that all versions and paths match throughout. See [Available Python and R versions](/roles/researcher/user_guide.md#available-python-and-r-versions) diff --git a/docs/source/design/architecture/shm_architecture.png b/docs/source/design/architecture/shm_architecture.png index a625a35101..77b2acdab2 100644 Binary files a/docs/source/design/architecture/shm_architecture.png and b/docs/source/design/architecture/shm_architecture.png differ diff --git a/docs/source/design/architecture/shm_details.md b/docs/source/design/architecture/shm_details.md index 98057bbf96..636cafc67f 100644 --- a/docs/source/design/architecture/shm_details.md +++ b/docs/source/design/architecture/shm_details.md @@ -16,8 +16,6 @@ The Windows Servers are running Active Directory and are acting as Domain Contro They are configured within an Azure availability set to ensure maximum up time. The Domain Controllers synchronise user details to the Azure Active Directory that is associated with the Management subscription to support self-service account activation and password reset. -In addition to the Domain Controllers there is a Windows Network Policy server, this server provides Multifactor Authentication services to the Remote Desktop Servers hosted within the SREs, connecting with Azure AD to provide this service. - Network security is provided by Azure Network Security Groups that ensure that inbound connections from the SREs are limited to Active Directory and RADIUS traffic. For management of the environment there is an Azure point-to-site (P2S) VPN service configured. diff --git a/docs/source/design/architecture/sre_architecture.png b/docs/source/design/architecture/sre_architecture.png index e35ee154a3..e9a44d2ff7 100644 Binary files a/docs/source/design/architecture/sre_architecture.png and b/docs/source/design/architecture/sre_architecture.png differ diff --git a/docs/source/design/architecture/sre_details.md b/docs/source/design/architecture/sre_details.md index 127286151f..f6b05929fc 100644 --- a/docs/source/design/architecture/sre_details.md +++ b/docs/source/design/architecture/sre_details.md @@ -15,7 +15,7 @@ This infrastructure comprises: - A `Gitlab` server to provide source code management and version control - A `CodiMD` server for collaborative writing - A `CoCalc` server for collaborative editing of computational notebook -- A remote desktop server to provide secure remote desktop access to the SRE resources. This can be configured on a per-SRE basis as either `Apache Guacamole` or `Microsoft Remote Desktop Services`. +- `Apache Guacamole` provides a clientless remote desktop gateway to provide secure remote desktop access to the SRE resources. Hosting each secure project environment in its own resource group supports a clean lifecycle management process, making it easy to verifiably delete all project data and resources at the end of a project. @@ -26,7 +26,7 @@ Hosting each secure project environment in its own resource group supports a cle :align: center ``` -The SREs use either `Microsoft Remote Desktop Services` or `Apache Guacamole` to provide a secure connection to the resources within the environment. +The SREs use `Apache Guacamole` to provide a secure connection to the resources within the environment. Only the remote desktop server is accessible from outside the SRE. Connections to this are made via an SSL/TLS secured connection that requires the user to authenticate using credentials provided by the Data Safe Haven and validated with MFA. diff --git a/docs/source/roles/researcher/snippets/02_account_setup.partial.md b/docs/source/roles/researcher/snippets/02_account_setup.partial.md deleted file mode 100644 index a6c7788699..0000000000 --- a/docs/source/roles/researcher/snippets/02_account_setup.partial.md +++ /dev/null @@ -1,89 +0,0 @@ -## {{rocket}} Set up your account - -This section of the user guide will help you set up your new account on the SRE you'll be using. - -### {{seedling}} Prerequisites - -Make sure you have all of the following in front of you when connecting to the SRE. - -- {{email}} The email from your {ref}`System Manager ` with your account details. -- {{wrench}} Your [username](#username), given in an email from your {ref}`System Manager `. -- {{european_castle}} The [domain name and URL](#domain-names) for the SRE, given in an email from your {ref}`System Manager `. -- {{computer}} Your computer. -- {{satellite}} [Access](#network-access) to the specific wired or wireless network detailed in the email from your {ref}`System Manager `. -- {{lock}} [Data security training](#data-security-training-requirements) for those working on health datasets. -- {{iphone}} Your [phone](#your-phone-for-multi-factor-authentication), with good signal connectivity. - -You should also know who the **designated contact** for your SRE is. -This might be an administrator or one of the people working on the project with you. -They will be your primary point of contact if you have any issues in connecting to or using the SRE. - -```{note} -For example, during the Turing Data Study Groups, the **facilitator** of each SRE is the designated contact -``` - -#### Username - -Your username will usually be in the format `firstname.lastname`. -In some places, you will need to enter it in the form `username@` - -```{tip} -You can find your username in the email you received from your {ref}`System Manager `. -``` - -```{caution} -If you have a hyphenated last name, or multiple surnames, or a long family name, your assigned username may not follow the same pattern of `firstname.lastname`. -Please check with the designated contact for your SRE if you are unsure about your username. -``` - -```{note} -In this document we will use **Ada Lovelace** as our example user. -Her username is: -- short-form: `ada.lovelace` -- long-form: `ada.lovelace@projects.turingsafehaven.ac.uk` -``` - -#### Network access - -The SRE that you're using may be configured to allow access only from a specific set of IP addresses. -This may involve being connected to a specific wired or wireless network or using a VPN. -You also may be required to connect from a specific, secure location. -You will be told what these requirements are for your particular environment. - -```{tip} -Make sure you know the networks from which you must connect to your SRE. -This information will be available in the email you received with your connection information. -``` - -#### Data security training requirements - -Depending on your project, you may be required to undertake {ref}`data security awareness training `. - -```{tip} -Check with your designated contact to see whether this is the case for you. -``` - -#### Your phone for multi-factor authentication - -Multi-factor authentication (MFA) is one of the most powerful ways of verifying user identity online. -We therefore use MFA to protect the project data - specifically, we will use your phone number. - -```{important} -Make sure to have your phone with you and that you have good signal connectivity when you are connecting to the SRE. -``` - -```{caution} -You may encounter some connectivity challenges if your phone network has poor connectivity. -The SRE is not set up to allow you to authenticate through other methods. -``` - -#### Domain names - -You should be given the {ref}`username domain ` in the initial email from your {ref}`System Manager `. -You might receive the {ref}`SRE URL ` at this time, or you might be assigned to a particular SRE at a later point. - -```{note} -In this document Ada Lovelace - our example user - will be participating in the `sandbox` project at a Turing Data Study Group. -- Her **{ref}`username domain `** is `projects.turingsafehaven.ac.uk` . -- Her **{ref}`SRE URL `** is `https://sandbox.projects.turingsafehaven.ac.uk` -``` diff --git a/docs/source/roles/researcher/snippets/03_01_prerequisites.partial.md b/docs/source/roles/researcher/snippets/03_01_prerequisites.partial.md deleted file mode 100644 index 1d52efe7bb..0000000000 --- a/docs/source/roles/researcher/snippets/03_01_prerequisites.partial.md +++ /dev/null @@ -1,12 +0,0 @@ -### {{seedling}} Prerequisites - -After going through the account setup procedure, you should have access to: - -- Your `username` -- Your `password` -- The {ref}`SRE URL ` -- Multifactor authentication - -```{tip} -If you aren't sure about any of these then please return to the [**Set up your account**](#set-up-your-account) section above. -``` diff --git a/docs/source/roles/researcher/snippets/03_02_srd_login.partial.md b/docs/source/roles/researcher/snippets/03_02_srd_login.partial.md deleted file mode 100644 index d44628f777..0000000000 --- a/docs/source/roles/researcher/snippets/03_02_srd_login.partial.md +++ /dev/null @@ -1,35 +0,0 @@ -- Insert your username and password. - - ````{note} - Our example user, Ada Lovelace, would enter `ada.lovelace` and her password. - ```{image} user_guide/srd_login_screen.png - :alt: SRD login screen - :align: center - ``` - ```` - - ````{error} - If you enter your username and/or password incorrectly you will see a warning like the one below. - If this happens, please try again, entering your username and password carefully. - - ```{image} user_guide/srd_login_failure.png - :alt: SRD login failure - :align: center - ``` - ```` - - ```{caution} - We recommend _not_ including special characters in your password as the keyboard layout expected by the login screen may be different from the one you're using. - - if you want to reset your password, follow the steps defined in the [Password and MFA](#password-and-mfa) section above. - - if you want to continue with special characters in your password, please test that they are being entered correctly by typing them in the username field. - ``` - -- You should now be greeted by a Linux desktop. - - ```{image} user_guide/srd_xfce_initial.png - :alt: SRD initial desktop - :align: center - ``` - -You are now logged into the Data Safe Haven SRE! -Welcome {{wave}} diff --git a/docs/source/roles/researcher/snippets/04_using_srd.partial.md b/docs/source/roles/researcher/snippets/04_using_srd.partial.md deleted file mode 100644 index 92c0ed1cfc..0000000000 --- a/docs/source/roles/researcher/snippets/04_using_srd.partial.md +++ /dev/null @@ -1,186 +0,0 @@ -## {{computer}} Analysing sensitive data - -The SRD has several pre-installed applications and programming languages to help with your data analysis. - -### {{package}} Pre-installed applications - -#### Programming languages / compilers - -```{include} snippets/software_languages.partial.md -:relative-images: -``` - -#### Editors / IDEs - -```{include} snippets/software_editors.partial.md -:relative-images: -``` - -#### Writing / presentation tools - -```{include} snippets/software_presentation.partial.md -:relative-images: -``` - -#### Database access tools - -```{include} snippets/software_database.partial.md -:relative-images: -``` - -#### Other useful software - -```{include} snippets/software_other.partial.md -:relative-images: -``` - -If you need anything that is not already installed, please discuss this with the designated contact for your SRE. - -```{attention} -This secure research desktop SRD is your interface to a single computer running in the cloud. -You may have access to [additional SRDs](#access-additional-srds) so be careful to check which machine you are working in as files and installed packages may not be the same across the machines. -``` - -### {{musical_keyboard}} Keyboard mapping - -When you access the SRD you are actually connecting through the cloud to another computer - via a few intermediate computers/servers that monitor and maintain the security of the SRE. - -```{caution} -You may find that the keyboard mapping on your computer is not the same as the one set for the SRD. -``` - -Click on `Desktop` and `Applications > Settings > Keyboard` to change the layout. - -```{tip} -We recommend opening a text editor (such as `Atom` , see [Access applications](#access-applications) below) to check what keys the remote desktop thinks you're typing – especially if you need to use special characters. -``` - -### {{unlock}} Access applications - -You can access applications from the desktop in two ways: the terminal or via a drop down menu. - -Applications can be accessed from the dropdown menu. -For example: - -- `Applications > Development > Atom` -- `Applications > Development > Jupyter Notebook` -- `Applications > Development > PyCharm` -- `Applications > Development > RStudio` -- `Applications > Education > QGIS Desktop` - -Applications can be accessed from a terminal. -For example: - -- Open `Terminal` and run `jupyter notebook &` if you want to use `Python` within a jupyter notebook. - -```{image} user_guide/access_desktop_applications.png -:alt: How to access applications from the desktop -:align: center -``` - -### {{snake}} Available Python and R versions - -Typing `R` at the command line will give you the system version of `R` with many custom packages pre-installed. - -There are several versions of `Python` installed, which are managed through [pyenv](https://github.com/pyenv/pyenv). -You can see the default version (indicated by a '\*') and all other installed versions using the following command: - -```none -> pyenv versions -``` - -This will give output like: - -```none - system - 3.8.12 -* 3.9.10 (set by /home/ada.lovelace/.pyenv_version) - 3.10.2 -``` - -You can change your preferred Python version globally or on a folder-by-folder basis using - -- `pyenv global ` (to change the version globally) -- `pyenv local ` (to change the version for the folder you are currently in) - -#### Creating virtual environments - -We recommend that you use a dedicated [virtual environment](https://docs.python.org/3/tutorial/venv.html) for developing your code in `Python`. -You can easily create a new virtual environment based on any of the available `Python` versions - -```none -> pyenv virtualenv 3.8.12 myvirtualenv -``` - -You can then activate it with: - -```none -> pyenv shell myvirtualenv -``` - -or if you want to automatically switch to it whenever you are in the current directory - -```none -> pyenv local myvirtualenv -``` - -### {{gift}} Install R and python packages - -There are local copies of the `PyPI` and `CRAN` package repositories available within the SRE. -You can install packages you need from these copies in the usual way, for example `pip install` and `install.packages` for Python and R respectively. - -```{caution} -You **will not** have access to install packages system-wide and will therefore need to install packages in a user directory. -``` - -- For `CRAN` you will be prompted to make a user package directory when you [install your first package](#r-packages). -- For `PyPI` you will need to [install using the `--user` argument to `pip`](#python-packages). - -#### R packages - -You can install `R` packages from inside `R` (or `RStudio`): - -```R -> install.packages() -``` - -You will see something like the following: - -```R -Installing package into '/usr/local/lib/R/site-library' -(as 'lib' is unspecified) -Warning in install.packages("cluster") : - 'lib = "/usr/local/lib/R/site-library"' is not writable -Would you like to use a personal library instead? (yes/No/cancel) -``` - -Enter `yes`, which prompts you to confirm the name of the library: - -```R -Would you like to create a personal library -'~/R/x86_64-pc-linux-gnu-library/3.5' -to install packages into? (yes/No/cancel) -``` - -Enter `yes`, to install the packages. - -#### Python packages - -You can install `python` packages from a terminal. - -```bash -pip install --user -``` - -```{tip} -If you are using a virtual environment as recommended above, you will not need the `--user` flag. -``` - -#### Package availability - -Depending on the type of data you are accessing, different `R` and `python` packages will be available to you (in addition to the ones that are pre-installed): - -- {ref}`Tier 2 ` (medium security) environments have full mirrors of `PyPI` and `CRAN` available. -- {ref}`Tier 3 ` (high security) environments only have pre-authorised packages available. - -If you need to use a package that is not on the allowlist see the section on how to [bring software or data into the environment](#bring-in-new-files-to-the-sre) below. diff --git a/docs/source/roles/researcher/snippets/05_share_files.partial.md b/docs/source/roles/researcher/snippets/05_share_files.partial.md deleted file mode 100644 index 7a397b0fc5..0000000000 --- a/docs/source/roles/researcher/snippets/05_share_files.partial.md +++ /dev/null @@ -1,83 +0,0 @@ -## {{link}} Share files with collaborators - -### {{open_file_folder}} Shared directories within the SRE - -There are several shared areas on the SRD that all collaborators within a research project team can see and access: - -- [input data](#input-data-data): `/data/` -- [shared space](#shared-space-shared): `/shared/` -- [scratch space](#scratch-space-scratch): `/scratch/` -- [backup space](#backup-space-backup): `/backup/` -- [output resources](#output-resources-output): `/output/` - -#### Input data: `/data/` - -Data that has been "ingressed" - approved and brought into the secure research environment - can be found in the `/data/` folder. - -Everyone in your group will be able to access it, but it is **read-only**. - -```{important} -You will not be able to change any of the files in `/data/` . -If you want to make derived datasets, for example cleaned and reformatted data, please add those to the `/shared/` or `/output/` directories. -``` - -The contents of `/data/` will be **identical** on all SRDs in your SRE. -For example, if your group requests a GPU-enabled machine, this will contain an identical `/data/` folder. - -```{tip} -If you are using the Data Safe Haven as part of an organised event, you might find example slides or document templates in the `/data/` drive. -``` - -#### Shared space: `/shared/` - -The `/shared/` folder should be used for any work that you want to share with your group. -Everyone in your group will be able to access it, and will have **read-and-write access**. - -The contents of `/shared/` will be **identical** on all SRDs in your SRE. - -#### Scratch space: `/scratch/` - -The `/scratch/` folder should be used for any work-in-progress that isn't ready to share yet. -Although everyone in your group will have **read-and-write access**, you can create your own folders inside `/scratch` and choose your own permissions for them. - -The contents of `/scratch/` will be **different** on different VMs in your SRE. - -#### Backup space: `/backup/` - -The `/backup/` folder should be used for any work-in-progress that you want to have backed up. -In the event of any accidental data loss, your system administrator can restore the `/backup` folder to the state it was in at an earlier time. -This **cannot** be used to recover individual files - only the complete contents of the folder. -Everyone in your group will have **read-and-write access** to all folders on `/backup`. - -The contents of `/backup/` will be **identical** on all SRDs in your SRE. - -#### Output resources: `/output/` - -Any outputs that you want to extract from the secure environment should be placed in the `/output/` folder on the SRD. -Everyone in your group will be able to access it, and will have **read-and-write access**. -Anything placed in here will be considered for data egress - removal from the secure research environment - by the project's principal investigator together with the data provider. - -```{tip} -You may want to consider having subfolders of `/output/` to make the review of this directory easier. -``` - -```{hint} -For the Turing Data Study Groups, we recommend the following categories: -- Presentation -- Transformed data/derived data -- Report -- Code -- Images -``` - -### {{newspaper}} Bring in new files to the SRE - -Bringing software into a secure research environment may constitute a security risk. -Bringing new data into the SRE may mean that the environment needs to be updated to a more secure tier. - -The review of the "ingress" of new code or data will be coordinated by the designated contact for your SRE. -They will have to discuss whether this is an acceptable risk to the data security with the project's principle investigator and data provider and the decision might be "no". - -```{hint} -You can make the process as easy as possible by providing as much information as possible about the code or data you'd like to bring into the environment and about how it is to be used. -``` diff --git a/docs/source/roles/researcher/snippets/06_cocalc.partial.md b/docs/source/roles/researcher/snippets/06_cocalc.partial.md deleted file mode 100644 index 7940aa7f2b..0000000000 --- a/docs/source/roles/researcher/snippets/06_cocalc.partial.md +++ /dev/null @@ -1,40 +0,0 @@ -## {{couple}} Collaborate on code using CoCalc - -`CoCalc` is a collaborative calculation and data science environment. -It lets you work with others on projects, using `Jupyter`, `LaTeX`, `Octave`, `Python` or `R` in collaborative notebooks. - -The `CoCalc` instance within the SRE is the easiest way to work directly with others in your team (for example pair-programming) who might not be physically near you. -You do not need to worry about the security of the information you upload there as it is fully contained within the SRE and there is no access to the internet and / or external servers. - -```{important} -The `CoCalc` instance within the SRE is entirely separate from the https://cocalc.com service. -``` - -### {{unlock}} Access CoCalc - -You can access `CoCalc` from an internet browser in the SRD using the desktop shortcut. -The first time that you login, you will see a security warning. -This is expected, please click on `Advanced` and then `Accept the Risk and Continue`. - -```{image} user_guide/cocalc_security_warning.png -:alt: CoCalc security warning -:align: center -``` - -You will then get to the CoCalc homepage where you should click on `Sign In` - -```{image} user_guide/cocalc_homepage.png -:alt: CoCalc homepage -:align: center -``` - -You will need to create a new account. -You can use any username/password here - it is not connected to your main Safe Haven account. - -````{note} -Our example user, Ada Lovelace has used `ada.lovelace@projects.turingsafehaven.ac.uk` as her username and set her own password -```{image} user_guide/cocalc_account_creation.png -:alt: CoCalc account creation -:align: center -``` -```` diff --git a/docs/source/roles/researcher/snippets/07_gitlab.partial.md b/docs/source/roles/researcher/snippets/07_gitlab.partial.md deleted file mode 100644 index 66299ebed9..0000000000 --- a/docs/source/roles/researcher/snippets/07_gitlab.partial.md +++ /dev/null @@ -1,73 +0,0 @@ -## {{pill}} Versioning code using GitLab - -`GitLab` is a code hosting platform for version control and collaboration - similar to `GitHub`. -It allows you to use `git` to **version control** your work, coordinate tasks using `GitLab` **issues** and review work using `GitLab` **merge requests**. - -```{note} -`GitLab` is a fully open source project. -This information doesn't matter at all for how you use `GitLab` within the SRE, but we do want to thank the community for maintaining free and open source software for us to use and reuse. -You can read more about `GitLab` at [their code repository](). -``` - -The `GitLab` instance within the SRE can contain code, documentation and results from your team's analyses. -You do not need to worry about the security of the information you upload there as it is fully contained within the SRE and there is no access to the internet and/or external servers. - -```{important} -The `GitLab` instance within the SRE is entirely separate from the `https://gitlab.com` service. -``` - -### {{books}} Maintaining an archive of the project - -The Data Safe Haven SRE is hosted on the Microsoft Azure cloud platform. -One of the benefits of having cloud based infastructure is that it can be deleted forever when the project is over. -Deleting the infrastructure ensures that neither sensitive data nor insights derived from the data or modelling techniques persist. - -Make sure that every piece of code you think might be useful is stored in a `GitLab` repository within the secure environment. -Any other work should be transferred to the shared `/shared/` drive. -Anything that you think should be considered for **egress** from the environment (eg. images or processed datasets) should be transferred to the shared `/output/` drive. - -```{caution} -If you are participating in a Turing Data Study Group, everything that is not stored in a GitLab repository or on the shared `/shared/` or `/output/` drives by Friday lunchtime will be **DESTROYED FOR EVER**. -``` - -### {{unlock}} Access GitLab - -You can access `GitLab` from an internet browser in the SRD using the desktop shortcut. -Login with username `firstname.lastname` (the domain is not needed) and `password` . - -````{note} -Our example user, Ada Lovelace would enter `ada.lovelace` in the `LDAP Username` box, enter her password and then click `Sign in` . - -```{image} user_guide/gitlab_screenshot_login.png -:alt: GitLab login -:align: center -``` -```` - -Accessing `GitLab` from the browser on the SRD is an easy way to switch between analysis work and documenting the process or results. - -```{warning} -Do not use your username and password from a pre-existing `GitLab` account! -The `GitLab` instance within the SRE is entirely separate from the `https://gitlab.com` service and is expecting the same username and password that you used to log into the SRE. -``` - -### {{open_hands}} Public repositories within the SRE - -The `GitLab` instance inside the secure research environment is entirely contained _inside_ the SRE. - -When you make a repository inside the SRE "public" it is visible to your collaborators who also have access to the SRE. -A "public" repository within the SRE is only visible to others with the same data access approval, it is not open to the general public via the internet. - -```{tip} -We recommend that you make your repositories public to facilitate collaboration within the secure research environment. -``` - -### {{construction_worker}} Support for GitLab use - -If you have not used GitLab before: - -- There is a small tutorial available as an [Appendix](#appendix-b-gitlab-tutorial-notes) to this user guide. -- You can find the official documentation on the [GitLab website](https://docs.gitlab.com/ee/user/index.html). -- Ask your team mates for help. -- Ask the designated contact for your SRE. -- There may be a dedicated discussion channel, for example during Turing Data Study Groups you can ask in the Slack channel. diff --git a/docs/source/roles/researcher/snippets/08_codimd.partial.md b/docs/source/roles/researcher/snippets/08_codimd.partial.md deleted file mode 100644 index e9d2d691a4..0000000000 --- a/docs/source/roles/researcher/snippets/08_codimd.partial.md +++ /dev/null @@ -1,83 +0,0 @@ -## {{book}} Collaborate on documents using CodiMD - -`CodiMD` is a locally installed tool that allows you to collaboratively write reports. -It uses `Markdown` which is a simple way to format your text so that it renders nicely in full HTML. - -```{note} -`CodiMD` is a fully open source version of the `HackMD` software. -This information doesn't matter at all for how you use `CodiMD` within the SRE, but we do want to thank the community for maintaining free and open source software for us to use and reuse. -You can read more about `CodiMD` at [their GitHub repository](). -``` - -We recommend [this Markdown cheat sheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). - -### {{unlock}} Access CodiMD - -You can access `CodiMD` from an internet browser from the SRD using the desktop shortcut. -Login with username `firstname.lastname` (the domain is not needed) and `password` . - -````{note} -Our example user, Ada Lovelace would enter `ada.lovelace` in the `Username` box, enter her password and then click `Sign in` . - -```{image} user_guide/codimd_logon.png -:alt: CodiMD login -:align: center -``` -```` - -Accessing CodiMD from the browser on the SRD is an easy way to switch between analysis work and documenting the process or results. - -### {{busts_in_silhouette}} Editing other people's documents - -The CodiMD instance inside the secure research environment is entirely contained _inside_ the SRE. - -When you make a markdown document inside the SRE "editable" your collaborators who also have access to the SRE can access it via the URL at the top of the page. -They will have the right to change the file if they are signed into the CodiMD instance. - -The link will only work for people who have the same data access approval, it is not open to the general public via the internet. - -```{image} user_guide/codimd_access_options.png -:alt: CodiMD access options -:align: center -``` - -```{tip} -We recommend that you make your documents **editable** to facilitate collaboration within the secure research environment. -Alternatively, the **locked** option allows others to read but not edit the document. -``` - -The default URL is quite long and difficult to share with your collaborators. -We recommend **publishing** the document to get a much shorter URL which is easier to share with others. - -Click the `Publish` button to publish the document and generate the short URL. -Click the pen button (shown in the image below) to return to the editable markdown view. - -```{image} user_guide/codimd_publishing.png -:alt: CodiMD publishing -:align: center -``` - -```{important} -Remember that the document is not published to the internet, it is only available to others within the SRE. -``` - -```{tip} -If you are attending a Turing Data Study Group you will be asked to write a report describing the work your team undertook over the five days of the projects. -Store a copy of the CodiMD URL in a text file in the outputs folder. -You will find some example report templates that outline the recommended structure. -We recommend writing the report in CodiMD - rather than GitLab - so that everyone can edit and contribute quickly. -``` - -### {{microscope}} Troubleshooting CodiMD - -We have noticed that a lower case `L` and an upper case `I` look very similar and often trip up users in the SRE. - -```{tip} -Double check the characters in the URL, and if there are ambiguous ones try the one you haven't tried yet! -``` - -Rather than proliferate lots of documents, we recommend that one person is tasked with creating the file and sharing the URL with other team members. - -```{tip} -You could use the GitLab wiki or `README` file to share links to collaboratively written documents. -``` diff --git a/docs/source/roles/researcher/snippets/10_databases.partial.md b/docs/source/roles/researcher/snippets/10_databases.partial.md deleted file mode 100644 index cfc32bde9f..0000000000 --- a/docs/source/roles/researcher/snippets/10_databases.partial.md +++ /dev/null @@ -1,177 +0,0 @@ -## {{green_book}} Access databases - -Your project might use a database for holding the input data. -You might also/instead be provided with a database for use in analysing the data. -The database server will use either `Microsoft SQL` or `PostgreSQL`. - -If you have access to one or more databases, you can access them using the following details, replacing `` with the {ref}`SRE ID ` for your project. - -### {{bento_box}} Microsoft SQL - -- Server name: `MSSQL-` (e.g. `MSSQL-SANDBOX` ) -- Database name: \`> -- Port: 1433 - -### {{postbox}} PostgreSQL - -- Server name: `PSTGRS-` (e.g. `PSTGRS-SANDBOX` ) -- Database name: \`> -- Port: 5432 - -Examples are given below for connecting using `Azure Data Studio`, `DBeaver`, `Python` and `R`. -The instructions for using other graphical interfaces or programming languages will be similar. - -### {{art}} Connecting using Azure Data Studio - -`Azure Data Studio` is currently only able to connect to `Microsoft SQL` databases. - -````{note} -Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using Azure Data Studio as follows: - - -```{image} user_guide/db_azure_data_studio.png -:alt: Azure Data Studio connection details -:align: center -``` -```` - -```{important} -Be sure to select `Windows authentication` here so that your username and password will be passed through to the database. -``` - -### {{bear}} Connecting using DBeaver - -Click on the `New database connection` button (which looks a bit like an electrical plug with a plus sign next to it) - -#### Microsoft SQL - -- Select `SQL Server` as the database type -- Enter the necessary information in the `Host` and `Port` boxes and set `Authentication` to `Kerberos` -- Tick `Show All Schemas` otherwise you will not be able to see the input data - -````{note} -Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using DBeaver as follows: - -```{image} user_guide/db_dbeaver_mssql.png -:alt: DBeaver connection details for Microsoft SQL -:align: center -``` -```` - -```{important} -Be sure to select `Kerberos authentication` so that your username and password will be passed through to the database -``` - -#### PostgreSQL - -- Select `PostgreSQL` as the database type -- Enter the necessary information in the `Host` and `Port` boxes and set `Authentication` to `Database Native` - -```{important} -You do not need to enter any information in the `Username` or `Password` fields -``` - -````{note} -Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using DBeaver as follows: - -```{image} user_guide/db_dbeaver_postgres_connection.png -:alt: DBeaver connection details for PostgreSQL -:align: center -``` -```` - -````{tip} -If you are prompted for `Username` or `Password` when connecting, you can leave these blank and the correct username and password will be automatically passed through to the database -```{image} user_guide/db_dbeaver_postgres_ignore.png -:alt: DBeaver username/password prompt -:align: center -``` -```` - -### {{snake}} Connecting using Python - -Database connections can be made using `pyodbc` or `psycopg2` depending on which database flavour is being used. -The data can be read into a dataframe for local analysis. - -```{note} -Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using DBeaver as follows: -``` - -#### Microsoft SQL - -```python -import pyodbc -import pandas as pd - -server = "MSSQL-SANDBOX.projects.turingsafehaven.ac.uk" -port = "1433" -db_name = "master" - -cnxn = pyodbc.connect("DRIVER={ODBC Driver 17 for SQL Server};SERVER=" + server + "," + port + ";DATABASE=" + db_name + ";Trusted_Connection=yes;") - -df = pd.read_sql("SELECT * FROM information_schema.tables;", cnxn) -print(df.head(3)) -``` - -#### PostgreSQL - -```python -import psycopg2 -import pandas as pd - -server = "PSTGRS-SANDBOX.projects.turingsafehaven.ac.uk" -port = 5432 -db_name = "postgres" - -cnxn = psycopg2.connect(host=server, port=port, database=db_name) -df = pd.read_sql("SELECT * FROM information_schema.tables;", cnxn) -print(df.head(3)) -``` - -### {{rose}} Connecting using R - -Database connections can be made using `odbc` or `RPostgres` depending on which database flavour is being used. -The data can be read into a dataframe for local analysis. - -```{note} -Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using DBeaver as follows: -``` - -#### Microsoft SQL - -```R -library(DBI) -library(odbc) - -# Connect to the databases -cnxn <- DBI::dbConnect( - odbc::odbc(), - Driver = "ODBC Driver 17 for SQL Server", - Server = "MSSQL-SANDBOX.projects.turingsafehaven.ac.uk,1433", - Database = "master", - Trusted_Connection = "yes" -) - -# Run a query and save the output into a dataframe -df <- dbGetQuery(cnxn, "SELECT * FROM information_schema.tables;") -head(df, 3) -``` - -#### PostgreSQL - -```R -library(DBI) -library(RPostgres) - -# Connect to the databases -cnxn <- DBI::dbConnect( - RPostgres::Postgres(), - host = "PSTGRS-SANDBOX.projects.turingsafehaven.ac.uk", - port = 5432, - dbname = "postgres" -) - -# Run a query and save the output into a dataframe -df <- dbGetQuery(cnxn, "SELECT * FROM information_schema.tables;") -head(df, 3) -``` diff --git a/docs/source/roles/researcher/snippets/11_report_bugs.partial.md b/docs/source/roles/researcher/snippets/11_report_bugs.partial.md deleted file mode 100644 index bf17cc9ab7..0000000000 --- a/docs/source/roles/researcher/snippets/11_report_bugs.partial.md +++ /dev/null @@ -1,39 +0,0 @@ -## {{bug}} Report a bug - -The Data Safe Haven SRE has been developed in close collaboration with our users: you! - -We try to make the user experience as smooth as possible and this document has been greatly improved by feedback from project participants and researchers going through the process for the first time. -We are constantly working to improve the SRE and we really appreciate your input and support as we develop the infrastructure. - -```{important} -If you find problems with the IT infrastructure, please contact the designated contact for your SRE. -``` - -### {{wrench}} Help us to help you - -To help us fix your issues please do the following: - -- Make sure you have **read this document** and checked if it answers your query. - - Please do not log an issue before you have read all of the sections in this document. -- Log out of the SRE and log back in again at least once - - Re-attempt the process leading to the bug/error at least twice. - - We know that "turn it off and turn it back on again" is a frustrating piece of advice to receive, but in our experience it works rather well! (Particularly when there are lots of folks trying these steps at the same time.) - - The multi-factor authentication step in particular is known to have quite a few gremlins. - - If you are getting frustrated, log out of everything, turn off your computer, take a 15 minute coffee break, and then start the process from the beginning. - -- Write down a comprehensive summary of the issue. -- A really good bug report makes it much easier to pin down what the problem is. Please include: - - Your computer's operating system and operating system version. - - Precise condition under which the error occurs. - - What steps would someone need to take to get the exact same error? - - A precise description of the problem. - - What happens? What would you expect to happen if there were no error? - - Any workarounds/fixes you have found. - -- Send the bug report to the designated contact for your SRE. - -```{hint} -We very strongly recommend "rubber ducking" this process before you talk to the designated contact for your SRE. -Either talk through to your imaginary rubber duck, or find a team member to describe the error to, as you write down the steps you have taken. -It is amazing how often working through your problem out loud helps you realise what the answer might be. -``` diff --git a/docs/source/roles/researcher/snippets/12_end_matter.partial.md b/docs/source/roles/researcher/snippets/12_end_matter.partial.md deleted file mode 100644 index 0ee2b42808..0000000000 --- a/docs/source/roles/researcher/snippets/12_end_matter.partial.md +++ /dev/null @@ -1,323 +0,0 @@ -## {{pray}} Acknowledgments - -This user guide is based on an initial document written in March/April 2018 by Kirstie Whitaker. - -Updates: - -- December 2018 by Catherine Lawrence, Franz Király, Martin O'Reilly, and Sebastian Vollmer. -- March/April 2019 by Miguel Morin, Catherine Lawrence, Alvaro Cabrejas Egea, Kirstie Whitaker, James Robinson and Martin O'Reilly. -- November 2019 by Ben Walden, James Robinson and Daisy Parry. -- April 2020 by Jules Manser, James Robinson and Kirstie Whitaker. -- November 2021 by James Robinson - -## {{passport_control}} Appendix A: Command Line Basics - -If you have never used a Linux desktop before, you might find some of the following commands useful if you are using a terminal. - -Go into a project directory to work in it - -```bash -cd NAME-OF-PROJECT -``` - -Go back one directory - -```bash -cd .. -``` - -List what’s in the current directory - -```bash -ls -``` - -Create a new directory - -```bash -mkdir NAME-OF-YOUR-DIRECTORY -``` - -Remove a file - -```bash -rm NAME-OF-FILE -``` - -Remove a directory and all of its contents - -```bash -rm -r NAME-OF-DIRECTORY -``` - -View command history - -```bash -history -``` - -Show which directory I am in - -```bash -pwd -``` - -Clear the shell window - -```bash -clear -``` - -## {{notebook}} Appendix B: Gitlab tutorial notes - -`GitLab` can be thought of as a local version of `GitHub` - that is a git server along with useful features such as: - -- **Project wiki** - exactly what it says -- **Project pastebin** - share bits of code -- **Project issue tracker** - track things TODO and bugs -- **Pull requests** - Way to keep track of changes individuals have made to be included in master - -Some teams design their entire workflows around these things. -A comparison in terms of features can be found [here](https://usersnap.com/blog/gitlab-github/). - -### Getting started with Git - -If you have never used `git` before, you might want to take a look at an introductory guide. -There are multiple `git` cheat sheets such as[this one from the JIRA authors](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) and [this interactive one](https://ndpsoftware.com/git-cheatsheet.html) and . - -### Repositories - -A repository is usually used to organize a single project. -Repositories can contain folders and files, images, videos, spreadsheets, and data sets – anything your project needs. -We recommend including a README, or a file with information about your project. -Over the course of the work that you do in your SRE, you will often be accessing and adding files to the same project repository. - -### Add your Git username and set your email - -It is important to configure your `git` username and email address, since every `git` commit will use this information to identify you as the author. -On your shell, type the following command to add your username: - -```bash -git config --global user.name "YOUR_USERNAME" -``` - -Then verify that you have the correct username: - -```bash -git config --global user.name -``` - -To set your email address, type the following command: - -```bash -git config --global user.email "your_email_address@example.com" -``` - -To verify that you entered your email correctly, type: - -```bash -git config --global user.email -``` - -You'll need to do this only once, since you are using the `--global` option. -It tells Git to always use this information for anything you do on that system. -If you want to override this with a different username or email address for specific projects, you can run the command without the `--global` option when you’re in that project. - -### Cloning projects - -In `git`, when you copy a project you say you "clone" it. -To work on a `git` project in the SRD, you will need to clone it. -To do this, sign in to `GitLab`. - -When you are on your Dashboard, click on the project that you’d like to clone. -To work in the project, you can copy a link to the `git` repository through a SSH or a HTTPS protocol. -SSH is easier to use after it’s been set up, [you can find the details here](https://docs.gitlab.com/ee/user/ssh.html). -While you are at the Project tab, select HTTPS or SSH from the dropdown menu and copy the link using the Copy URL to clipboard button (you’ll have to paste it on your shell in the next step>). - -```{image} user_guide/gitlab_clone_url.png -:alt: Clone GitLab project -:align: center -``` - -Go to your computer’s shell and type the following command with your SSH or HTTPS URL: - -```bash -git clone -``` - -### Branches - -Branching is the way to work on different versions of a repository at one time. -By default your repository has one branch usually named `master` or `main` which is considered to be the definitive branch. -We use branches to experiment and make edits before committing them to `main`. - -When you create a branch off the `main` branch, you’re making a copy, or snapshot, of `main` as it was at that point in time. -If someone else made changes to the `main` branch while you were working on your branch, you could pull in those updates. - -To create a branch: - -```bash -git checkout -b NAME-OF-BRANCH -``` - -Work on an existing branch: - -```bash -git checkout NAME-OF-BRANCH -``` - -To merge the `main` branch into a created branch you need to be on the created branch. - -```bash -git checkout NAME-OF-BRANCH -git merge main -``` - -To merge a created branch into the `main` branch you need to be on the created branch. - -```bash -git checkout main -git merge NAME-OF-BRANCH -``` - -### Downloading the latest changes in a project - -This is for you to work on an up-to-date copy (it is important to do this every time you start working on a project), while you set up tracking branches. -You pull from remote repositories to get all the changes made by users since the last time you cloned or pulled the project. -Later, you can push your local commits to the remote repositories. - -```bash -git pull REMOTE NAME-OF-BRANCH -``` - -When you first clone a repository, REMOTE is typically `origin`. -This is where the repository came from, and it indicates the SSH or HTTPS URL of the repository on the remote server. -NAME-OF-BRANCH is usually `main`, but it may be any existing branch. - -### Add and commit local changes - -You’ll see your local changes in red when you type `git status`. -These changes may be new, modified, or deleted files/folders. -Use `git add` to stage a local file/folder for committing. -Then use `git commit` to commit the staged files: - -```bash -git add FILE OR FOLDER -git commit -m "COMMENT TO DESCRIBE THE INTENTION OF THE COMMIT" -``` - -To add and commit all local changes in one command: - -```bash -git add . -git commit -m "COMMENT TO DESCRIBE THE INTENTION OF THE COMMIT" -``` - -To push all local commits to the remote repository: - -```bash -git push REMOTE NAME-OF-BRANCH -``` - -For example, to push your local commits to the `main` branch of the origin remote: - -```bash -git push origin main -``` - -To delete all local changes in the repository that have not been added to the staging area, and leave unstaged files/folders, type: - -```bash -git checkout . -``` - -**Note:** The . character typically means all in Git. - -### How to create a Merge Request - -Merge requests are useful to integrate separate changes that you’ve made to a project, on different branches. -This is a brief guide on how to create a merge request. -For more information, check the [merge requests documentation](https://docs.gitlab.com/ee/user/project/merge_requests/index.html). - -- Before you start, you should have already created a branch and pushed your changes to `GitLab`. -- Go to the project where you’d like to merge your changes and click on the `Merge requests` tab. -- Click on `New merge request` on the right side of the screen. -- From there on, you have the option to select the source branch and the target branch you’d like to compare to. - -The default target project is the upstream repository, but you can choose to compare across any of its forks. - -```{image} user_guide/gitlab_new_merge_request.png -:alt: New GitLab merge request -:align: center -``` - -- When ready, click on the Compare branches and continue button. -- At a minimum, add a title and a description to your merge request. -- Optionally, select a user to review your merge request and to accept or close it. You may also select a milestone and labels. - -```{image} user_guide/gitlab_merge_request_details.png -:alt: GitLab merge request details -:align: center -``` - -- When ready, click on the `Submit merge request` button. - -Your merge request will be ready to be approved and merged. - -## {{microscope}} Appendix C: Troubleshooting - -### {{exclamation}} No applications available - -#### Symptom - -- You can successfully log into the remote desktop web interface - -```{note} -For our example user, Ada Lovelace, this would be `https://sandbox.projects.turingsafehaven.ac.uk` . -``` - -- You do not see any available connections - - ```{image} user_guide/msrds_no_work_resources.png - :alt: No connections available - :align: center - ``` - -#### Cause - -You have not been added to the correct SRE security group. - -#### Solution - -Ask your {ref}`System Manager ` to add you to the appropriate SRE security group. - -### {{exclamation}} Unexpected certificate error - -#### Symptom - -- You can successfully log into the remote desktop web interface - - ```{note} - For our example user, Ada Lovelace, this would be `https://sandbox.projects.turingsafehaven.ac.uk`. - ``` - -- You can see several apps, but when you try to launch one of them, you receive an error saying "Your session ended because an unexpected server authentication certificate was received from the remote PC." -- When you click on the padlock icon in the address bar and view the SSL certificate, the "SHA-1 Fingerprint" in the certificate matches the "SHA-1 Thumbprint" in the error message. - - ```{image} user_guide/msrds_unexpected_certificate_error.png - :alt: Unexpected certificate error - :align: center - ``` - -#### Cause - -The SSL certificate protecting your connection to the RDS webclient expires every three months and is renewed every two months. -The new SSL certificate is seamlessly picked up by your browser when connecting to the web page. -However, the webclient downloads a separate copy of the certificate for its own use to validate connections to the apps it serves. -This downloaded certificate is cached by your browser, which means that the old certificate will continue to be used by the web app when the browser is allowed to load things from its cache. - -#### Solution - -Get your browser to do a [hard reload](https://www.getfilecloud.com/blog/2015/03/tech-tip-how-to-do-hard-refresh-in-browsers/) of the page (instructions vary by browser and operating system). -You may also need to [clear your cache](https://www.refreshyourcache.com/en/home/) for this site. -In either case, removing locally cached data should mean that you retrieve a copy of the new certificate. diff --git a/docs/source/roles/researcher/snippets/13_MFA.partial.md b/docs/source/roles/researcher/snippets/13_MFA.partial.md deleted file mode 100644 index bc4812d709..0000000000 --- a/docs/source/roles/researcher/snippets/13_MFA.partial.md +++ /dev/null @@ -1,226 +0,0 @@ -For security reasons, you must reset your password before you log in for the first time. -Please follow these steps carefully. - -- Open a private/incognito browser session on your computer. - - ```{tip} - One of the most common problems that users have in connecting to the SRE is automatic completion of usernames and passwords from other accounts on their computer. - This can be quite confusing, particularly for anyone who logs into Microsoft services for work or personal use. - ``` - - ```{caution} - Look out for usernames or passwords that are automatically completed, and make sure that you're using the correct details needed to access the SRE. - ``` - -- Navigate to the following URL in your browser: `https://aka.ms/mfasetup` . - This short link starts the process of logging into your account. - -- At the login prompt enter `username@` and confirm/proceed. - Remember that your username will probably be in the format `firstname.lastname` . - - ```{note} - Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, would enter `ada.lovelace@projects.turingsafehaven.ac.uk` - ``` - -- There will then be a password prompt. - - The first time you log in you need to click **"Forgotten my password"**. - - ```{image} user_guide/account_setup_forgotten_password.png - :alt: Forgotten my password - :align: center - ``` - - ```{caution} - If you reset your password, you will need to wait 5-10 mins before logging in again, to allow the user management system to sync up with the new password. - ``` - -- Fill out the requested CAPTCHA (your username should be pre-filled). - - ```{image} user_guide/account_setup_captcha.png - :alt: CAPTCHA - :align: center - ``` - -- Confirm your phone number, which you provided to the {ref}`System Manager ` when you registered for access to the environment. - - ```{image} user_guide/account_setup_verify_phone.png - :alt: Verify phone number - :align: center - ``` - -- Select a password. - - Your password must comply with the following requirements: - - ```{important} - - alphanumeric - - minimum 12 characters - - at least one each of: - - {{input_latin_uppercase}} uppercase character - - {{input_latin_lowercase}} lowercase character - - {{input_numbers}} number - - you should choose a unique password for the SRE to ensure it is secure - ``` - - ```{caution} - Do not use special characters or symbols in your password! - The virtual keyboard inside the SRE may not be the same as your physical keyboard and this can make it difficult to type some symbols. - ``` - - Note that this will also ensure that it passes the [Microsoft Azure AD password requirements](https://docs.microsoft.com/en-us/azure/active-directory/authentication/concept-sspr-policy). - - ```{tip} - We recommend using a password generator [like this one](https://bitwarden.com/password-generator/) to create a password that meets these requirements. - This will ensure that the password is different from any others that you might use and that it is unlikely to be on any list of commonly used passwords. - ``` - - If your password is too difficult to memorise, we recommend using a password manager, for example [BitWarden](https://bitwarden.com) or [LastPass](https://www.lastpass.com/), to store it securely. - -- Enter your password into the `Enter new password` and `Confirm new password` fields. - - ```{image} user_guide/account_setup_new_password.png - :alt: New password - :align: center - ``` - -- Then continue to the next step - - ```{image} user_guide/account_setup_new_password_sign_in.png - :alt: Click to continue - :align: center - ``` - -- Log into your account when prompted and at this point you will be asked for additional security verification. - - ```{image} user_guide/account_setup_more_information_required.png - :alt: Click to continue - :align: center - ``` - -### {{door}} Set up multi-factor authentication - -The next step in setting up your account is to authenticate your account from your phone. -This additional security verification is to make it harder for people to impersonate you and connect to the environment without permission. -This is known as multi-factor authentication (MFA). - -#### {{telephone_receiver}} Phone number registration - -- In order to set up MFA you will need to enter your phone number - - ```{image} user_guide/account_setup_mfa_additional_security_verification.png - :alt: Additional security verification - :align: center - ``` - -- Once you click next you will receive a phone call straight away. - - ```{image} user_guide/account_setup_mfa_verifying_phone.png - :alt: Verifying phone number - :align: center - ``` - - ```{tip} - The call might say _press the pound key_ or _press the hash key_ both mean hit the `#` button. - ``` - -- After following the instructions you will see the following screen - - ```{image} user_guide/account_setup_mfa_verified_phone.png - :alt: Verified phone number - :align: center - ``` - -- Click `Next` to register this phone number for MFA - - ```{image} user_guide/account_setup_mfa_registered_phone.png - :alt: Registered phone number - :align: center - ``` - -- You should now see the Security Information dashboard that lists all your verified MFA methods - - ```{image} user_guide/account_setup_mfa_dashboard_phone_only.png - :alt: Registered phone number - :align: center - ``` - -#### {{iphone}} Authenticator app registration - -- If you want to use the Microsoft Authenticator app for MFA (which will work if you have wifi but no phone signal) then click on `+ Add sign-in method` and select `Authenticator app` - - ```{image} user_guide/account_setup_mfa_add_authenticator_app.png - :alt: Add Authenticator app - :align: center - ``` - -- This will prompt you to download the `Microsoft Authenticator` phone app. - - ```{image} user_guide/account_setup_mfa_download_authenticator_app.png - :alt: Add Authenticator app - :align: center - ``` - -You can click on the link in the prompt or follow the appropriate link for your phone here: - -- {{apple}} iOS: `https://bit.ly/iosauthenticator` -- {{robot}} Android: `https://bit.ly/androidauthenticator` -- {{bento_box}} Windows mobile: `https://bit.ly/windowsauthenticator` - -You will now be prompted to open the app and: - -- To allow notifications -- Select `Add an account` -- Select `Work or School account` - - ```{image} user_guide/account_setup_mfa_allow_notifications.png - :alt: Allow Authenticator notifications - :align: center - ``` - - ```{important} - You must give permission for the authenticator app to send you notifications for the app to work as an MFA method. - ``` - -- The next prompt will give you a QR code to scan, like the one shown below -- Scan the QR code on the screen - - ```{image} user_guide/account_setup_mfa_app_qrcode.png - :alt: Setup Authenticator app - :align: center - ``` - -- Once this is completed, Microsoft will send you a test notification to respond to - - ```{image} user_guide/account_setup_mfa_authenticator_app_test.png - :alt: Authenticator app test notification - :align: center - ``` - -- When you click `Approve` on the phone notification, you will get the following message in your browser - - ```{image} user_guide/account_setup_mfa_authenticator_app_approved.png - :alt: Authenticator app test approved - :align: center - ``` - -- You should now be returned to the Security Information dashboard that lists two verified MFA methods - - ```{image} user_guide/account_setup_mfa_dashboard_two_methods.png - :alt: Registered MFA methods - :align: center - ``` - -- Choose whichever you prefer to be your `Default sign-in methods`. - -- You have now finished setting up MFA and you can close your browser - -#### Troubleshooting MFA - -Sometimes setting up MFA can be problematic. -You may find the following tips helpful: - -- {{inbox_tray}} Make sure you allow notifications on your authenticator app. -- {{sleeping}} Check you don't have _Do not Disturb_ mode on. -- {{zap}} You have to be SUPER FAST at acknowledging the notification on your app, since the access codes update every 30 seconds. -- {{confused}} Sometimes just going through the steps again solves the problem diff --git a/docs/source/roles/researcher/user_guide.md b/docs/source/roles/researcher/user_guide.md index 2861c30393..402e908625 100644 --- a/docs/source/roles/researcher/user_guide.md +++ b/docs/source/roles/researcher/user_guide.md @@ -1,21 +1,1464 @@ -# User guide +(role_researcher_user_guide_guacamole)= -```{toctree} -:hidden: +# User Guide -user_guide_guacamole.md -user_guide_msrds.md +## {{beginner}} Introduction + +{{tada}} Welcome to the Turing Data Safe Haven! {{tada}} + +Secure research environments (SREs) for analysis of sensitive datasets are essential to give data providers confidence that their datasets will be kept secure over the course of a project. +The Data Safe Haven is a prescription for how to set up one or more SREs and give users access to them. +The Data Safe Haven SRE design is aimed at allowing groups of researchers to work together on projects that involve sensitive or confidential datasets at scale. +Our goal is to ensure that you are able to implement the most cutting edge data science techniques while maintaining all ethical and legal responsibilities of information governance and access. + +The data you are working on will have been classified into one of five sensitivity tiers, ranging from open data at Tier 0, to highly sensitive and high risk data at Tier 4. +The tiers are defined by the most sensitive data in your project, and may be increased if the combination of data is deemed to be require additional levels of security. +You can read more about this process in our policy paper: _Arenas et al, 2019_, [`arXiv:1908.08737`](https://arxiv.org/abs/1908.08737). + +The level of sensitivity of your data determines whether you have access to the internet within the SRE and whether you are allowed to copy and paste between the secure research environment and other windows on your computer. +This means you may be limited in which data science tools you are allowed to install. +You will find that many software packages are already available, and the administrator of the SRE will ingress - bring into the environment - as many additional resources as possible. + +```{important} +Please read this user guide carefully and remember to refer back to it when you have questions. +In many cases the answer is already here, but if you think this resource could be clearer, please let us know so we can improve the documentation for future users. +``` + +### Definitions + +The following definitions might be useful during the rest of this guide + +Secure Research Environment (SRE) +: the environment that you will be using to access the sensitive data. + +Data Safe Haven +: the overall project that details how to create and manage one or more SREs. + +(user_guide_username_domain)= +Username domain +: the domain (for example `projects.turingsafehaven.ac.uk`) which your user account will belong to. Multiple SREs can share the same domain for managing users in common. + +(user_guide_sre_id)= +SRE ID +: each SRE has a unique short ID, for example `sandbox` which your {ref}`System Manager ` will use to distinguish different SREs in the same Data Safe Haven. + +(user_guide_sre_url)= +SRE URL +: each SRE has a unique URL (for example `sandbox.projects.turingsafehaven.ac.uk`) which is used to access the data. + +(roles_researcher_user_guide_setup_mfa)= + +## {{rocket}} Set up your account + +This section of the user guide will help you set up your new account on the SRE you'll be using. + +### {{seedling}} Prerequisites + +Make sure you have all of the following in front of you when connecting to the SRE. + +- {{email}} The email from your {ref}`System Manager ` with your account details. +- {{wrench}} Your [username](#username), given in an email from your {ref}`System Manager `. +- {{european_castle}} The [domain name and URL](#domain-names) for the SRE, given in an email from your {ref}`System Manager `. +- {{computer}} Your computer. +- {{satellite}} [Access](#network-access) to the specific wired or wireless network detailed in the email from your {ref}`System Manager `. +- {{lock}} [Data security training](#data-security-training-requirements) for those working on health datasets. +- {{iphone}} Your [phone](#your-phone-for-multi-factor-authentication), with good signal connectivity. + +You should also know who the **designated contact** for your SRE is. +This might be an administrator or one of the people working on the project with you. +They will be your primary point of contact if you have any issues in connecting to or using the SRE. + +```{note} +For example, during the Turing Data Study Groups, the **facilitator** of each SRE is the designated contact +``` + +#### Username + +Your username will usually be in the format `firstname.lastname`. +In some places, you will need to enter it in the form `username@` + +```{tip} +You can find your username in the email you received from your {ref}`System Manager `. +``` + +```{caution} +If you have a hyphenated last name, or multiple surnames, or a long family name, your assigned username may not follow the same pattern of `firstname.lastname`. +Please check with the designated contact for your SRE if you are unsure about your username. +``` + +```{note} +In this document we will use **Ada Lovelace** as our example user. +Her username is: +- short-form: `ada.lovelace` +- long-form: `ada.lovelace@projects.turingsafehaven.ac.uk` +``` + +#### Network access + +The SRE that you're using may be configured to allow access only from a specific set of IP addresses. +This may involve being connected to a specific wired or wireless network or using a VPN. +You also may be required to connect from a specific, secure location. +You will be told what these requirements are for your particular environment. + +```{tip} +Make sure you know the networks from which you must connect to your SRE. +This information will be available in the email you received with your connection information. +``` + +#### Data security training requirements + +Depending on your project, you may be required to undertake {ref}`data security awareness training `. + +```{tip} +Check with your designated contact to see whether this is the case for you. +``` + +#### Your phone for multi-factor authentication + +Multi-factor authentication (MFA) is one of the most powerful ways of verifying user identity online. +We therefore use MFA to protect the project data - specifically, we will use your phone number. + +```{important} +Make sure to have your phone with you and that you have good signal connectivity when you are connecting to the SRE. +``` + +```{caution} +You may encounter some connectivity challenges if your phone network has poor connectivity. +The SRE is not set up to allow you to authenticate through other methods. +``` + +#### Domain names + +You should be given the {ref}`username domain ` in the initial email from your {ref}`System Manager `. +You might receive the {ref}`SRE URL ` at this time, or you might be assigned to a particular SRE at a later point. + +```{note} +In this document Ada Lovelace - our example user - will be participating in the `sandbox` project at a Turing Data Study Group. +- Her **{ref}`username domain `** is `projects.turingsafehaven.ac.uk` . +- Her **{ref}`SRE URL `** is `https://sandbox.projects.turingsafehaven.ac.uk` +``` + +(user_setup_password_mfa)= + +## {{closed_lock_with_key}} Password and MFA + +For security reasons, you must reset your password before you log in for the first time. +Please follow these steps carefully. + +- Open a private/incognito browser session on your computer. + + ```{tip} + One of the most common problems that users have in connecting to the SRE is automatic completion of usernames and passwords from other accounts on their computer. + This can be quite confusing, particularly for anyone who logs into Microsoft services for work or personal use. + ``` + + ```{caution} + Look out for usernames or passwords that are automatically completed, and make sure that you're using the correct details needed to access the SRE. + ``` + +- Navigate to the following URL in your browser: `https://aka.ms/mfasetup` . + This short link starts the process of logging into your account. + +- At the login prompt enter `username@` and confirm/proceed. + Remember that your username will probably be in the format `firstname.lastname` . + + ```{note} + Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, would enter `ada.lovelace@projects.turingsafehaven.ac.uk` + ``` + +- There will then be a password prompt. + + The first time you log in you need to click **"Forgotten my password"**. + + ```{image} user_guide/account_setup_forgotten_password.png + :alt: Forgotten my password + :align: center + ``` + + ```{caution} + If you reset your password, you will need to wait 5-10 mins before logging in again, to allow the user management system to sync up with the new password. + ``` + +- Fill out the requested CAPTCHA (your username should be pre-filled). + + ```{image} user_guide/account_setup_captcha.png + :alt: CAPTCHA + :align: center + ``` + +- Confirm your phone number, which you provided to the {ref}`System Manager ` when you registered for access to the environment. + + ```{image} user_guide/account_setup_verify_phone.png + :alt: Verify phone number + :align: center + ``` + +- Select a password. + + Your password must comply with the following requirements: + + ```{important} + - alphanumeric + - minimum 12 characters + - at least one each of: + - {{input_latin_uppercase}} uppercase character + - {{input_latin_lowercase}} lowercase character + - {{input_numbers}} number + - you should choose a unique password for the SRE to ensure it is secure + ``` + + ```{caution} + Do not use special characters or symbols in your password! + The virtual keyboard inside the SRE may not be the same as your physical keyboard and this can make it difficult to type some symbols. + ``` + + Note that this will also ensure that it passes the [Microsoft Azure AD password requirements](https://docs.microsoft.com/en-us/azure/active-directory/authentication/concept-sspr-policy). + + ```{tip} + We recommend using a password generator [like this one](https://bitwarden.com/password-generator/) to create a password that meets these requirements. + This will ensure that the password is different from any others that you might use and that it is unlikely to be on any list of commonly used passwords. + ``` + + If your password is too difficult to memorise, we recommend using a password manager, for example [BitWarden](https://bitwarden.com) or [LastPass](https://www.lastpass.com/), to store it securely. + +- Enter your password into the `Enter new password` and `Confirm new password` fields. + + ```{image} user_guide/account_setup_new_password.png + :alt: New password + :align: center + ``` + +- Then continue to the next step + + ```{image} user_guide/account_setup_new_password_sign_in.png + :alt: Click to continue + :align: center + ``` + +- Log into your account when prompted and at this point you will be asked for additional security verification. + + ```{image} user_guide/account_setup_more_information_required.png + :alt: Click to continue + :align: center + ``` + +### {{door}} Set up multi-factor authentication + +The next step in setting up your account is to authenticate your account from your phone. +This additional security verification is to make it harder for people to impersonate you and connect to the environment without permission. +This is known as multi-factor authentication (MFA). + +#### {{telephone_receiver}} Phone number registration + +- In order to set up MFA you will need to enter your phone number + + ```{image} user_guide/account_setup_mfa_additional_security_verification.png + :alt: Additional security verification + :align: center + ``` + +- Once you click next you will receive a phone call straight away. + + ```{image} user_guide/account_setup_mfa_verifying_phone.png + :alt: Verifying phone number + :align: center + ``` + + ```{tip} + The call might say _press the pound key_ or _press the hash key_. Both mean hit the `#` button. + ``` + +- After following the instructions you will see the following screen + + ```{image} user_guide/account_setup_mfa_verified_phone.png + :alt: Verified phone number + :align: center + ``` + +- Click `Next` to register this phone number for MFA + + ```{image} user_guide/account_setup_mfa_registered_phone.png + :alt: Registered phone number + :align: center + ``` + +- You should now see the Security Information dashboard that lists all your verified MFA methods + + ```{image} user_guide/account_setup_mfa_dashboard_phone_only.png + :alt: Registered phone number + :align: center + ``` + +#### {{iphone}} Authenticator app registration + +- If you want to use the Microsoft Authenticator app for MFA (which will work if you have wifi but no phone signal) then click on `+ Add sign-in method` and select `Authenticator app` + + ```{image} user_guide/account_setup_mfa_add_authenticator_app.png + :alt: Add Authenticator app + :align: center + ``` + +- This will prompt you to download the `Microsoft Authenticator` phone app. + + ```{image} user_guide/account_setup_mfa_download_authenticator_app.png + :alt: Add Authenticator app + :align: center + ``` + +You can click on the link in the prompt or follow the appropriate link for your phone here: + +- {{apple}} iOS: `https://bit.ly/iosauthenticator` +- {{robot}} Android: `https://bit.ly/androidauthenticator` +- {{bento_box}} Windows mobile: `https://bit.ly/windowsauthenticator` + +You will now be prompted to open the app and: + +- To allow notifications +- Select `Add an account` +- Select `Work or School account` + + ```{image} user_guide/account_setup_mfa_allow_notifications.png + :alt: Allow Authenticator notifications + :align: center + ``` + + ```{important} + You must give permission for the authenticator app to send you notifications for the app to work as an MFA method. + ``` + +- The next prompt will give you a QR code to scan, like the one shown below +- Scan the QR code on the screen + + ```{image} user_guide/account_setup_mfa_app_qrcode.png + :alt: Setup Authenticator app + :align: center + ``` + +- Once this is completed, Microsoft will send you a test notification to respond to + + ```{image} user_guide/account_setup_mfa_authenticator_app_test.png + :alt: Authenticator app test notification + :align: center + ``` + +- When you click `Approve` on the phone notification, you will get the following message in your browser + + ```{image} user_guide/account_setup_mfa_authenticator_app_approved.png + :alt: Authenticator app test approved + :align: center + ``` + +- You should now be returned to the Security Information dashboard that lists two verified MFA methods + + ```{image} user_guide/account_setup_mfa_dashboard_two_methods.png + :alt: Registered MFA methods + :align: center + ``` + +- Choose whichever you prefer to be your `Default sign-in methods`. + +- You have now finished setting up MFA and you can close your browser + +#### Troubleshooting MFA + +Sometimes setting up MFA can be problematic. +You may find the following tips helpful: + +- {{inbox_tray}} Make sure you allow notifications on your authenticator app. +- {{sleeping}} Check you don't have _Do not Disturb_ mode on. +- {{zap}} You have to be SUPER FAST at acknowledging the notification on your app, since the access codes update every 30 seconds. +- {{confused}} Sometimes just going through the steps again solves the problem + +## {{unlock}} Access the Secure Research Environment + +### {{seedling}} Prerequisites + +After going through the account setup procedure, you should have access to: + +- Your `username` +- Your `password` +- The {ref}`SRE URL ` +- Multifactor authentication + +```{tip} +If you aren't sure about any of these then please return to the [**Set up your account**](#set-up-your-account) section above. +``` + +### {{house}} Log into the research environment + +- Open a **private/incognito** browser session, so that you don't pick up any existing Microsoft logins + +- Go to the {ref}`SRE URL ` given by your {ref}`System Manager `. + + ```{note} + Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, would navigate to `https://sandbox.projects.turingsafehaven.ac.uk`. + ``` + + ```{important} + Don't forget the **https://** as you will not be able to login without it! + ``` + +- You should arrive at a login page that needs you to enter: + + - your `username@` + - your password + + then click `Login`. + +- You should arrive at a login page that looks like the image below: + + ````{note} + Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, would enter `ada.lovelace@projects.turingsafehaven.ac.uk` in the `User name` box, enter her password and then click `Login`. + ```{image} user_guide/logon_environment_guacamole.png + :alt: Research environment log in + :align: center + ``` + ```` + +- You will now **receive a call or mobile app notification** to authenticate using multifactor authentication (MFA). + + ```{image} user_guide/guacamole_mfa.png + :alt: MFA trigger + :align: center + ``` + + {{telephone_receiver}} For the call, you may have to move to an area with good reception and/or press the hash (`#`) key multiple times in-call. + + {{iphone}} For the app you will see a notification saying _"You have received a sign in verification request"_. Go to the app to approve the request. + + ```{caution} + If you don't respond to the MFA request quickly enough, or if it fails, you may get an error. If this happens, please retry + ``` + +- If you are successful, you'll see the a screen with icons for the available apps. + + ```{image} user_guide/guacamole_dashboard.png + :alt: Research environment dashboard + :align: center + ``` + + Welcome to the Data Safe Haven! {{wave}} + +### {{penguin}} Log into the Secure Research Desktop + +The primary method of performing data analysis in the SRE is using the Secure Research Desktop (SRD). + +This is a virtual machine (VM) with many different applications and programming languages pre-installed on it. +Once connected to it, you can analyse the sensitive data belonging to your project while remaining completely isolated from the internet. + +- Click on one of the `Desktop` connections (for example `Ubuntu0_CPU2_8GB (Desktop)` to connect to the desktop. + +- Insert your username and password. + + ````{note} + Our example user, Ada Lovelace, would enter `ada.lovelace` and her password. + ```{image} user_guide/srd_login_screen.png + :alt: SRD login screen + :align: center + ``` + ```` + + ````{error} + If you enter your username and/or password incorrectly you will see a warning like the one below. + If this happens, please try again, entering your username and password carefully. + + ```{image} user_guide/srd_login_failure.png + :alt: SRD login failure + :align: center + ``` + ```` + + ```{caution} + We recommend _not_ including special characters in your password as the keyboard layout expected by the login screen may be different from the one you're using. + - if you want to reset your password, follow the steps defined in the [Password and MFA](#password-and-mfa) section above. + - if you want to continue with special characters in your password, please test that they are being entered correctly by typing them in the username field. + ``` + +- You should now be greeted by a Linux desktop. + + ```{image} user_guide/srd_xfce_initial.png + :alt: SRD initial desktop + :align: center + ``` + +You are now logged into the Data Safe Haven SRE! +Welcome {{wave}} + +## {{computer}} Analysing sensitive data + +The SRD has several pre-installed applications and programming languages to help with your data analysis. + +### {{package}} Pre-installed applications + +#### Programming languages / compilers + +```{include} snippets/software_languages.partial.md +:relative-images: +``` + +#### Editors / IDEs + +```{include} snippets/software_editors.partial.md +:relative-images: +``` + +#### Writing / presentation tools + +```{include} snippets/software_presentation.partial.md +:relative-images: +``` + +#### Database access tools + +```{include} snippets/software_database.partial.md +:relative-images: +``` + +#### Other useful software + +```{include} snippets/software_other.partial.md +:relative-images: +``` + +If you need anything that is not already installed, please discuss this with the designated contact for your SRE. + +```{attention} +This secure research desktop SRD is your interface to a single computer running in the cloud. +You may have access to [additional SRDs](#access-additional-srds) so be careful to check which machine you are working in as files and installed packages may not be the same across the machines. +``` + +### {{musical_keyboard}} Keyboard mapping + +When you access the SRD you are actually connecting through the cloud to another computer - via a few intermediate computers/servers that monitor and maintain the security of the SRE. + +```{caution} +You may find that the keyboard mapping on your computer is not the same as the one set for the SRD. +``` + +Click on `Desktop` and `Applications > Settings > Keyboard` to change the layout. + +```{tip} +We recommend opening a text editor (such as `Atom` , see [Access applications](#access-applications) below) to check what keys the remote desktop thinks you're typing – especially if you need to use special characters. +``` + +### {{unlock}} Access applications + +You can access applications from the desktop in two ways: the terminal or via a drop down menu. + +Applications can be accessed from the dropdown menu. +For example: + +- `Applications > Development > Atom` +- `Applications > Development > Jupyter Notebook` +- `Applications > Development > PyCharm` +- `Applications > Development > RStudio` +- `Applications > Education > QGIS Desktop` + +Applications can be accessed from a terminal. +For example: + +- Open `Terminal` and run `jupyter notebook &` if you want to use `Python` within a jupyter notebook. + +```{image} user_guide/access_desktop_applications.png +:alt: How to access applications from the desktop +:align: center +``` + +### {{snake}} Available Python and R versions + +Typing `R` at the command line will give you the system version of `R` with many custom packages pre-installed. + +There are several versions of `Python` installed, which are managed through [pyenv](https://github.com/pyenv/pyenv). +You can see the default version (indicated by a '\*') and all other installed versions using the following command: + +```none +> pyenv versions +``` + +This will give output like: + +```none + system + 3.8.12 +* 3.9.10 (set by /home/ada.lovelace/.pyenv_version) + 3.10.2 +``` + +You can change your preferred Python version globally or on a folder-by-folder basis using + +- `pyenv global ` (to change the version globally) +- `pyenv local ` (to change the version for the folder you are currently in) + +#### Creating virtual environments + +We recommend that you use a dedicated [virtual environment](https://docs.python.org/3/tutorial/venv.html) for developing your code in `Python`. +You can easily create a new virtual environment based on any of the available `Python` versions + +```none +> pyenv virtualenv 3.8.12 myvirtualenv +``` + +You can then activate it with: + +```none +> pyenv shell myvirtualenv +``` + +or if you want to automatically switch to it whenever you are in the current directory + +```none +> pyenv local myvirtualenv +``` + +### {{gift}} Install R and python packages + +There are local copies of the `PyPI` and `CRAN` package repositories available within the SRE. +You can install packages you need from these copies in the usual way, for example `pip install` and `install.packages` for Python and R respectively. + +```{caution} +You **will not** have access to install packages system-wide and will therefore need to install packages in a user directory. +``` + +- For `CRAN` you will be prompted to make a user package directory when you [install your first package](#r-packages). +- For `PyPI` you will need to [install using the `--user` argument to `pip`](#python-packages). + +#### R packages + +You can install `R` packages from inside `R` (or `RStudio`): + +```R +> install.packages() +``` + +You will see something like the following: + +```R +Installing package into '/usr/local/lib/R/site-library' +(as 'lib' is unspecified) +Warning in install.packages("cluster") : + 'lib = "/usr/local/lib/R/site-library"' is not writable +Would you like to use a personal library instead? (yes/No/cancel) +``` + +Enter `yes`, which prompts you to confirm the name of the library: + +```R +Would you like to create a personal library +'~/R/x86_64-pc-linux-gnu-library/3.5' +to install packages into? (yes/No/cancel) +``` + +Enter `yes`, to install the packages. + +#### Python packages + +You can install `python` packages from a terminal. + +```bash +pip install --user +``` + +```{tip} +If you are using a virtual environment as recommended above, you will not need the `--user` flag. +``` + +#### Package availability + +Depending on the type of data you are accessing, different `R` and `python` packages will be available to you (in addition to the ones that are pre-installed): + +- {ref}`Tier 2 ` (medium security) environments have full mirrors of `PyPI` and `CRAN` available. +- {ref}`Tier 3 ` (high security) environments only have pre-authorised packages available. + +If you need to use a package that is not on the allowlist see the section on how to [bring software or data into the environment](#bring-in-new-files-to-the-sre) below. + +(role_researcher_user_guide_shared_storage)= + +## {{link}} Share files with collaborators + +### {{open_file_folder}} Shared directories within the SRE + +There are several shared areas on the SRD that all collaborators within a research project team can see and access: + +- [input data](#input-data-data): `/data/` +- [shared space](#shared-space-shared): `/shared/` +- [scratch space](#scratch-space-scratch): `/scratch/` +- [backup space](#backup-space-backup): `/backup/` +- [output resources](#output-resources-output): `/output/` + +#### Input data: `/data/` + +Data that has been "ingressed" - approved and brought into the secure research environment - can be found in the `/data/` folder. + +Everyone in your group will be able to access it, but it is **read-only**. + +```{important} +You will not be able to change any of the files in `/data/` . +If you want to make derived datasets, for example cleaned and reformatted data, please add those to the `/shared/` or `/output/` directories. +``` + +The contents of `/data/` will be **identical** on all SRDs in your SRE. +For example, if your group requests a GPU-enabled machine, this will contain an identical `/data/` folder. + +```{tip} +If you are using the Data Safe Haven as part of an organised event, you might find example slides or document templates in the `/data/` drive. +``` + +#### Shared space: `/shared/` + +The `/shared/` folder should be used for any work that you want to share with your group. +Everyone in your group will be able to access it, and will have **read-and-write access**. + +The contents of `/shared/` will be **identical** on all SRDs in your SRE. + +#### Scratch space: `/scratch/` + +The `/scratch/` folder should be used for any work-in-progress that isn't ready to share yet. +Although everyone in your group will have **read-and-write access**, you can create your own folders inside `/scratch` and choose your own permissions for them. + +The contents of `/scratch/` will be **different** on different VMs in your SRE. + +#### Backup space: `/backup/` + +The `/backup/` folder should be used for any work-in-progress that you want to have backed up. +In the event of any accidental data loss, your system administrator can restore the `/backup` folder to the state it was in at an earlier time. +This **cannot** be used to recover individual files - only the complete contents of the folder. +Everyone in your group will have **read-and-write access** to all folders on `/backup`. + +The contents of `/backup/` will be **identical** on all SRDs in your SRE. + +#### Output resources: `/output/` + +Any outputs that you want to extract from the secure environment should be placed in the `/output/` folder on the SRD. +Everyone in your group will be able to access it, and will have **read-and-write access**. +Anything placed in here will be considered for data egress - removal from the secure research environment - by the project's principal investigator together with the data provider. + +```{tip} +You may want to consider having subfolders of `/output/` to make the review of this directory easier. +``` + +```{hint} +For the Turing Data Study Groups, we recommend the following categories: +- Presentation +- Transformed data/derived data +- Report +- Code +- Images +``` + +### {{newspaper}} Bring in new files to the SRE + +Bringing software into a secure research environment may constitute a security risk. +Bringing new data into the SRE may mean that the environment needs to be updated to a more secure tier. + +The review of the "ingress" of new code or data will be coordinated by the designated contact for your SRE. +They will have to discuss whether this is an acceptable risk to the data security with the project's principle investigator and data provider and the decision might be "no". + +```{hint} +You can make the process as easy as possible by providing as much information as possible about the code or data you'd like to bring into the environment and about how it is to be used. +``` + +## {{couple}} Collaborate on code using CoCalc + +`CoCalc` is a collaborative calculation and data science environment. +It lets you work with others on projects, using `Jupyter`, `LaTeX`, `Octave`, `Python` or `R` in collaborative notebooks. + +The `CoCalc` instance within the SRE is the easiest way to work directly with others in your team (for example pair-programming) who might not be physically near you. +You do not need to worry about the security of the information you upload there as it is fully contained within the SRE and there is no access to the internet and / or external servers. + +```{important} +The `CoCalc` instance within the SRE is entirely separate from the https://cocalc.com service. +``` + +### {{unlock}} Access CoCalc + +You can access `CoCalc` from an internet browser in the SRD using the desktop shortcut. +The first time that you login, you will see a security warning. +This is expected, please click on `Advanced` and then `Accept the Risk and Continue`. + +```{image} user_guide/cocalc_security_warning.png +:alt: CoCalc security warning +:align: center +``` + +You will then get to the CoCalc homepage where you should click on `Sign In` + +```{image} user_guide/cocalc_homepage.png +:alt: CoCalc homepage +:align: center +``` + +You will need to create a new account. +You can use any username/password here - it is not connected to your main Safe Haven account. + +````{note} +Our example user, Ada Lovelace has used `ada.lovelace@projects.turingsafehaven.ac.uk` as her username and set her own password +```{image} user_guide/cocalc_account_creation.png +:alt: CoCalc account creation +:align: center +``` +```` + +## {{pill}} Versioning code using GitLab + +`GitLab` is a code hosting platform for version control and collaboration - similar to `GitHub`. +It allows you to use `git` to **version control** your work, coordinate tasks using `GitLab` **issues** and review work using `GitLab` **merge requests**. + +```{note} +`GitLab` is a fully open source project. +This information doesn't matter at all for how you use `GitLab` within the SRE, but we do want to thank the community for maintaining free and open source software for us to use and reuse. +You can read more about `GitLab` at [their code repository](). +``` + +The `GitLab` instance within the SRE can contain code, documentation and results from your team's analyses. +You do not need to worry about the security of the information you upload there as it is fully contained within the SRE and there is no access to the internet and/or external servers. + +```{important} +The `GitLab` instance within the SRE is entirely separate from the `https://gitlab.com` service. +``` + +### {{books}} Maintaining an archive of the project + +The Data Safe Haven SRE is hosted on the Microsoft Azure cloud platform. +One of the benefits of having cloud based infastructure is that it can be deleted forever when the project is over. +Deleting the infrastructure ensures that neither sensitive data nor insights derived from the data or modelling techniques persist. + +Make sure that every piece of code you think might be useful is stored in a `GitLab` repository within the secure environment. +Any other work should be transferred to the shared `/shared/` drive. +Anything that you think should be considered for **egress** from the environment (eg. images or processed datasets) should be transferred to the shared `/output/` drive. + +```{caution} +If you are participating in a Turing Data Study Group, everything that is not stored in a GitLab repository or on the shared `/shared/` or `/output/` drives by Friday lunchtime will be **DESTROYED FOR EVER**. +``` + +### {{unlock}} Access GitLab + +You can access `GitLab` from an internet browser in the SRD using the desktop shortcut. +Login with username `firstname.lastname` (the domain is not needed) and `password` . + +````{note} +Our example user, Ada Lovelace would enter `ada.lovelace` in the `LDAP Username` box, enter her password and then click `Sign in` . + +```{image} user_guide/gitlab_screenshot_login.png +:alt: GitLab login +:align: center +``` +```` + +Accessing `GitLab` from the browser on the SRD is an easy way to switch between analysis work and documenting the process or results. + +```{warning} +Do not use your username and password from a pre-existing `GitLab` account! +The `GitLab` instance within the SRE is entirely separate from the `https://gitlab.com` service and is expecting the same username and password that you used to log into the SRE. +``` + +### {{open_hands}} Public repositories within the SRE + +The `GitLab` instance inside the secure research environment is entirely contained _inside_ the SRE. + +When you make a repository inside the SRE "public" it is visible to your collaborators who also have access to the SRE. +A "public" repository within the SRE is only visible to others with the same data access approval, it is not open to the general public via the internet. + +```{tip} +We recommend that you make your repositories public to facilitate collaboration within the secure research environment. +``` + +### {{construction_worker}} Support for GitLab use + +If you have not used GitLab before: + +- There is a small tutorial available as an [Appendix](#appendix-b-gitlab-tutorial-notes) to this user guide. +- You can find the official documentation on the [GitLab website](https://docs.gitlab.com/ee/user/index.html). +- Ask your team mates for help. +- Ask the designated contact for your SRE. +- There may be a dedicated discussion channel, for example during Turing Data Study Groups you can ask in the Slack channel. + +## {{book}} Collaborate on documents using CodiMD + +`CodiMD` is a locally installed tool that allows you to collaboratively write reports. +It uses `Markdown` which is a simple way to format your text so that it renders nicely in full HTML. + +```{note} +`CodiMD` is a fully open source version of the `HackMD` software. +This information doesn't matter at all for how you use `CodiMD` within the SRE, but we do want to thank the community for maintaining free and open source software for us to use and reuse. +You can read more about `CodiMD` at [their GitHub repository](). +``` + +We recommend [this Markdown cheat sheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). + +### {{unlock}} Access CodiMD + +You can access `CodiMD` from an internet browser from the SRD using the desktop shortcut. +Login with username `firstname.lastname` (the domain is not needed) and `password` . + +````{note} +Our example user, Ada Lovelace would enter `ada.lovelace` in the `Username` box, enter her password and then click `Sign in` . + +```{image} user_guide/codimd_logon.png +:alt: CodiMD login +:align: center +``` +```` + +Accessing CodiMD from the browser on the SRD is an easy way to switch between analysis work and documenting the process or results. + +### {{busts_in_silhouette}} Editing other people's documents + +The CodiMD instance inside the secure research environment is entirely contained _inside_ the SRE. + +When you make a markdown document inside the SRE "editable" your collaborators who also have access to the SRE can access it via the URL at the top of the page. +They will have the right to change the file if they are signed into the CodiMD instance. + +The link will only work for people who have the same data access approval, it is not open to the general public via the internet. + +```{image} user_guide/codimd_access_options.png +:alt: CodiMD access options +:align: center +``` + +```{tip} +We recommend that you make your documents **editable** to facilitate collaboration within the secure research environment. +Alternatively, the **locked** option allows others to read but not edit the document. +``` + +The default URL is quite long and difficult to share with your collaborators. +We recommend **publishing** the document to get a much shorter URL which is easier to share with others. + +Click the `Publish` button to publish the document and generate the short URL. +Click the pen button (shown in the image below) to return to the editable markdown view. + +```{image} user_guide/codimd_publishing.png +:alt: CodiMD publishing +:align: center +``` + +```{important} +Remember that the document is not published to the internet, it is only available to others within the SRE. +``` + +```{tip} +If you are attending a Turing Data Study Group you will be asked to write a report describing the work your team undertook over the five days of the projects. +Store a copy of the CodiMD URL in a text file in the outputs folder. +You will find some example report templates that outline the recommended structure. +We recommend writing the report in CodiMD - rather than GitLab - so that everyone can edit and contribute quickly. +``` + +### {{microscope}} Troubleshooting CodiMD + +We have noticed that a lower case `L` and an upper case `I` look very similar and often trip up users in the SRE. + +```{tip} +Double check the characters in the URL, and if there are ambiguous ones try the one you haven't tried yet! +``` + +Rather than proliferate lots of documents, we recommend that one person is tasked with creating the file and sharing the URL with other team members. + +```{tip} +You could use the GitLab wiki or `README` file to share links to collaboratively written documents. +``` + +## {{unlock}} Access additional SRDs + +Your project might make use of further SRDs in addition to the main shared desktop. +Usually this is because of a requirement for a different type of computing resource, such as access to one or more GPUs (graphics processing units). + +You will access this machine in a similar way to the main shared desktop, by selecting a different `Desktop` connection. + +````{note} +Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, might select `Ubuntu1_CPU2_8GB (Desktop)` instead of `Ubuntu0_CPU2_8GB (Desktop)` +```{image} user_guide/guacamole_dashboard.png +:alt: Research environment dashboard +:align: center +``` +```` + +- This will bring you to the normal login screen, where you use the same `username` and `password` credentials as before. +- Any local files that you have created in the `/output/` folder on other VMs (e.g. analysis scripts, notes, derived data) will be automatically available in the new VM. + +```{tip} +The naming pattern of the available desktop connections lets you know their compute capabilities. +For example `Ubuntu1_CPU2_8GB` has 2 CPUs and 8GB of RAM. +``` + +## {{green_book}} Access databases + +Your project might use a database for holding the input data. +You might also/instead be provided with a database for use in analysing the data. +The database server will use either `Microsoft SQL` or `PostgreSQL`. + +If you have access to one or more databases, you can access them using the following details, replacing `` with the {ref}`SRE ID ` for your project. + +### {{bento_box}} Microsoft SQL + +- Server name: `MSSQL-` (e.g. `MSSQL-SANDBOX` ) +- Database name: \`> +- Port: 1433 + +### {{postbox}} PostgreSQL + +- Server name: `PSTGRS-` (e.g. `PSTGRS-SANDBOX` ) +- Database name: \`> +- Port: 5432 + +Examples are given below for connecting using `Azure Data Studio`, `DBeaver`, `Python` and `R`. +The instructions for using other graphical interfaces or programming languages will be similar. + +### {{art}} Connecting using Azure Data Studio + +`Azure Data Studio` is currently only able to connect to `Microsoft SQL` databases. + +````{note} +Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using Azure Data Studio as follows: + + +```{image} user_guide/db_azure_data_studio.png +:alt: Azure Data Studio connection details +:align: center +``` +```` + +```{important} +Be sure to select `Windows authentication` here so that your username and password will be passed through to the database. +``` + +### {{bear}} Connecting using DBeaver + +Click on the `New database connection` button (which looks a bit like an electrical plug with a plus sign next to it) + +#### Microsoft SQL + +- Select `SQL Server` as the database type +- Enter the necessary information in the `Host` and `Port` boxes and set `Authentication` to `Kerberos` +- Tick `Show All Schemas` otherwise you will not be able to see the input data + +````{note} +Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using DBeaver as follows: + +```{image} user_guide/db_dbeaver_mssql.png +:alt: DBeaver connection details for Microsoft SQL +:align: center +``` +```` + +```{important} +Be sure to select `Kerberos authentication` so that your username and password will be passed through to the database +``` + +#### PostgreSQL + +- Select `PostgreSQL` as the database type +- Enter the necessary information in the `Host` and `Port` boxes and set `Authentication` to `Database Native` + +```{important} +You do not need to enter any information in the `Username` or `Password` fields +``` + +````{note} +Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using DBeaver as follows: + +```{image} user_guide/db_dbeaver_postgres_connection.png +:alt: DBeaver connection details for PostgreSQL +:align: center +``` +```` + +````{tip} +If you are prompted for `Username` or `Password` when connecting, you can leave these blank and the correct username and password will be automatically passed through to the database +```{image} user_guide/db_dbeaver_postgres_ignore.png +:alt: DBeaver username/password prompt +:align: center +``` +```` + +### {{snake}} Connecting using Python + +Database connections can be made using `pyodbc` or `psycopg2` depending on which database flavour is being used. +The data can be read into a dataframe for local analysis. + +```{note} +Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using DBeaver as follows: +``` + +#### Microsoft SQL + +```python +import pyodbc +import pandas as pd + +server = "MSSQL-SANDBOX.projects.turingsafehaven.ac.uk" +port = "1433" +db_name = "master" + +cnxn = pyodbc.connect("DRIVER={ODBC Driver 17 for SQL Server};SERVER=" + server + "," + port + ";DATABASE=" + db_name + ";Trusted_Connection=yes;") + +df = pd.read_sql("SELECT * FROM information_schema.tables;", cnxn) +print(df.head(3)) ``` -We currently support several remote desktop interfaces. -Ask your {ref}`role_system_manager` if you are unsure which of these options your SRE is using. +#### PostgreSQL + +```python +import psycopg2 +import pandas as pd -[User guide: Apache Guacamole](user_guide_guacamole.md) -: Step-by-step instructions for **Researchers** working in a Data Safe Haven that uses `Apache Guacamole` +server = "PSTGRS-SANDBOX.projects.turingsafehaven.ac.uk" +port = 5432 +db_name = "postgres" -[User guide: Microsoft Remote Desktop](user_guide_msrds.md) -: Step-by-step instructions for **Researchers** working in a Data Safe Haven that uses `Microsoft Remote Desktop` +cnxn = psycopg2.connect(host=server, port=port, database=db_name) +df = pd.read_sql("SELECT * FROM information_schema.tables;", cnxn) +print(df.head(3)) +``` + +### {{rose}} Connecting using R + +Database connections can be made using `odbc` or `RPostgres` depending on which database flavour is being used. +The data can be read into a dataframe for local analysis. ```{note} -These user guides were written with [Turing Data Study Groups](https://www.turing.ac.uk/collaborate-turing/data-study-groups) in mind. +Our example user Ada Lovelace, working in the `sandbox` SRE on the `projects.turingsafehaven.ac.uk` Safe Haven, would connect using DBeaver as follows: +``` + +#### Microsoft SQL + +```R +library(DBI) +library(odbc) + +# Connect to the databases +cnxn <- DBI::dbConnect( + odbc::odbc(), + Driver = "ODBC Driver 17 for SQL Server", + Server = "MSSQL-SANDBOX.projects.turingsafehaven.ac.uk,1433", + Database = "master", + Trusted_Connection = "yes" +) + +# Run a query and save the output into a dataframe +df <- dbGetQuery(cnxn, "SELECT * FROM information_schema.tables;") +head(df, 3) ``` + +#### PostgreSQL + +```R +library(DBI) +library(RPostgres) + +# Connect to the databases +cnxn <- DBI::dbConnect( + RPostgres::Postgres(), + host = "PSTGRS-SANDBOX.projects.turingsafehaven.ac.uk", + port = 5432, + dbname = "postgres" +) + +# Run a query and save the output into a dataframe +df <- dbGetQuery(cnxn, "SELECT * FROM information_schema.tables;") +head(df, 3) +``` + +## {{bug}} Report a bug + +The Data Safe Haven SRE has been developed in close collaboration with our users: you! + +We try to make the user experience as smooth as possible and this document has been greatly improved by feedback from project participants and researchers going through the process for the first time. +We are constantly working to improve the SRE and we really appreciate your input and support as we develop the infrastructure. + +```{important} +If you find problems with the IT infrastructure, please contact the designated contact for your SRE. +``` + +### {{wrench}} Help us to help you + +To help us fix your issues please do the following: + +- Make sure you have **read this document** and checked if it answers your query. + - Please do not log an issue before you have read all of the sections in this document. +- Log out of the SRE and log back in again at least once + - Re-attempt the process leading to the bug/error at least twice. + - We know that "turn it off and turn it back on again" is a frustrating piece of advice to receive, but in our experience it works rather well! (Particularly when there are lots of folks trying these steps at the same time.) + - The multi-factor authentication step in particular is known to have quite a few gremlins. + - If you are getting frustrated, log out of everything, turn off your computer, take a 15 minute coffee break, and then start the process from the beginning. + +- Write down a comprehensive summary of the issue. +- A really good bug report makes it much easier to pin down what the problem is. Please include: + - Your computer's operating system and operating system version. + - Precise condition under which the error occurs. + - What steps would someone need to take to get the exact same error? + - A precise description of the problem. + - What happens? What would you expect to happen if there were no error? + - Any workarounds/fixes you have found. + +- Send the bug report to the designated contact for your SRE. + +```{hint} +We very strongly recommend "rubber ducking" this process before you talk to the designated contact for your SRE. +Either talk through to your imaginary rubber duck, or find a team member to describe the error to, as you write down the steps you have taken. +It is amazing how often working through your problem out loud helps you realise what the answer might be. +``` + +## {{pray}} Acknowledgments + +This user guide is based on an initial document written in March/April 2018 by Kirstie Whitaker. + +Updates: + +- December 2018 by Catherine Lawrence, Franz Király, Martin O'Reilly, and Sebastian Vollmer. +- March/April 2019 by Miguel Morin, Catherine Lawrence, Alvaro Cabrejas Egea, Kirstie Whitaker, James Robinson and Martin O'Reilly. +- November 2019 by Ben Walden, James Robinson and Daisy Parry. +- April 2020 by Jules Manser, James Robinson and Kirstie Whitaker. +- November 2021 by James Robinson + +## {{passport_control}} Appendix A: Command Line Basics + +If you have never used a Linux desktop before, you might find some of the following commands useful if you are using a terminal. + +Go into a project directory to work in it + +```bash +cd NAME-OF-PROJECT +``` + +Go back one directory + +```bash +cd .. +``` + +List what’s in the current directory + +```bash +ls +``` + +Create a new directory + +```bash +mkdir NAME-OF-YOUR-DIRECTORY +``` + +Remove a file + +```bash +rm NAME-OF-FILE +``` + +Remove a directory and all of its contents + +```bash +rm -r NAME-OF-DIRECTORY +``` + +View command history + +```bash +history +``` + +Show which directory I am in + +```bash +pwd +``` + +Clear the shell window + +```bash +clear +``` + +## {{notebook}} Appendix B: Gitlab tutorial notes + +`GitLab` can be thought of as a local version of `GitHub` - that is a git server along with useful features such as: + +- **Project wiki** - exactly what it says +- **Project pastebin** - share bits of code +- **Project issue tracker** - track things TODO and bugs +- **Pull requests** - Way to keep track of changes individuals have made to be included in master + +Some teams design their entire workflows around these things. +A comparison in terms of features can be found [here](https://usersnap.com/blog/gitlab-github/). + +### Getting started with Git + +If you have never used `git` before, you might want to take a look at an introductory guide. +There are multiple `git` cheat sheets such as[this one from the JIRA authors](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) and [this interactive one](https://ndpsoftware.com/git-cheatsheet.html) and . + +### Repositories + +A repository is usually used to organize a single project. +Repositories can contain folders and files, images, videos, spreadsheets, and data sets – anything your project needs. +We recommend including a README, or a file with information about your project. +Over the course of the work that you do in your SRE, you will often be accessing and adding files to the same project repository. + +### Add your Git username and set your email + +It is important to configure your `git` username and email address, since every `git` commit will use this information to identify you as the author. +On your shell, type the following command to add your username: + +```bash +git config --global user.name "YOUR_USERNAME" +``` + +Then verify that you have the correct username: + +```bash +git config --global user.name +``` + +To set your email address, type the following command: + +```bash +git config --global user.email "your_email_address@example.com" +``` + +To verify that you entered your email correctly, type: + +```bash +git config --global user.email +``` + +You'll need to do this only once, since you are using the `--global` option. +It tells Git to always use this information for anything you do on that system. +If you want to override this with a different username or email address for specific projects, you can run the command without the `--global` option when you’re in that project. + +### Cloning projects + +In `git`, when you copy a project you say you "clone" it. +To work on a `git` project in the SRD, you will need to clone it. +To do this, sign in to `GitLab`. + +When you are on your Dashboard, click on the project that you’d like to clone. +To work in the project, you can copy a link to the `git` repository through a SSH or a HTTPS protocol. +SSH is easier to use after it’s been set up, [you can find the details here](https://docs.gitlab.com/ee/user/ssh.html). +While you are at the Project tab, select HTTPS or SSH from the dropdown menu and copy the link using the Copy URL to clipboard button (you’ll have to paste it on your shell in the next step>). + +```{image} user_guide/gitlab_clone_url.png +:alt: Clone GitLab project +:align: center +``` + +Go to your computer’s shell and type the following command with your SSH or HTTPS URL: + +```bash +git clone +``` + +### Branches + +Branching is the way to work on different versions of a repository at one time. +By default your repository has one branch usually named `master` or `main` which is considered to be the definitive branch. +We use branches to experiment and make edits before committing them to `main`. + +When you create a branch off the `main` branch, you’re making a copy, or snapshot, of `main` as it was at that point in time. +If someone else made changes to the `main` branch while you were working on your branch, you could pull in those updates. + +To create a branch: + +```bash +git checkout -b NAME-OF-BRANCH +``` + +Work on an existing branch: + +```bash +git checkout NAME-OF-BRANCH +``` + +To merge the `main` branch into a created branch you need to be on the created branch. + +```bash +git checkout NAME-OF-BRANCH +git merge main +``` + +To merge a created branch into the `main` branch you need to be on the created branch. + +```bash +git checkout main +git merge NAME-OF-BRANCH +``` + +### Downloading the latest changes in a project + +This is for you to work on an up-to-date copy (it is important to do this every time you start working on a project), while you set up tracking branches. +You pull from remote repositories to get all the changes made by users since the last time you cloned or pulled the project. +Later, you can push your local commits to the remote repositories. + +```bash +git pull REMOTE NAME-OF-BRANCH +``` + +When you first clone a repository, REMOTE is typically `origin`. +This is where the repository came from, and it indicates the SSH or HTTPS URL of the repository on the remote server. +NAME-OF-BRANCH is usually `main`, but it may be any existing branch. + +### Add and commit local changes + +You’ll see your local changes in red when you type `git status`. +These changes may be new, modified, or deleted files/folders. +Use `git add` to stage a local file/folder for committing. +Then use `git commit` to commit the staged files: + +```bash +git add FILE OR FOLDER +git commit -m "COMMENT TO DESCRIBE THE INTENTION OF THE COMMIT" +``` + +To add and commit all local changes in one command: + +```bash +git add . +git commit -m "COMMENT TO DESCRIBE THE INTENTION OF THE COMMIT" +``` + +To push all local commits to the remote repository: + +```bash +git push REMOTE NAME-OF-BRANCH +``` + +For example, to push your local commits to the `main` branch of the origin remote: + +```bash +git push origin main +``` + +To delete all local changes in the repository that have not been added to the staging area, and leave unstaged files/folders, type: + +```bash +git checkout . +``` + +**Note:** The . character typically means all in Git. + +### How to create a Merge Request + +Merge requests are useful to integrate separate changes that you’ve made to a project, on different branches. +This is a brief guide on how to create a merge request. +For more information, check the [merge requests documentation](https://docs.gitlab.com/ee/user/project/merge_requests/index.html). + +- Before you start, you should have already created a branch and pushed your changes to `GitLab`. +- Go to the project where you’d like to merge your changes and click on the `Merge requests` tab. +- Click on `New merge request` on the right side of the screen. +- From there on, you have the option to select the source branch and the target branch you’d like to compare to. + +The default target project is the upstream repository, but you can choose to compare across any of its forks. + +```{image} user_guide/gitlab_new_merge_request.png +:alt: New GitLab merge request +:align: center +``` + +- When ready, click on the Compare branches and continue button. +- At a minimum, add a title and a description to your merge request. +- Optionally, select a user to review your merge request and to accept or close it. You may also select a milestone and labels. + +```{image} user_guide/gitlab_merge_request_details.png +:alt: GitLab merge request details +:align: center +``` + +- When ready, click on the `Submit merge request` button. + +Your merge request will be ready to be approved and merged. diff --git a/docs/source/roles/researcher/user_guide/logon_environment_msrds.png b/docs/source/roles/researcher/user_guide/logon_environment_msrds.png deleted file mode 100644 index 640f0f6685..0000000000 Binary files a/docs/source/roles/researcher/user_guide/logon_environment_msrds.png and /dev/null differ diff --git a/docs/source/roles/researcher/user_guide/msrds_dashboard.png b/docs/source/roles/researcher/user_guide/msrds_dashboard.png deleted file mode 100644 index 2768b5a425..0000000000 Binary files a/docs/source/roles/researcher/user_guide/msrds_dashboard.png and /dev/null differ diff --git a/docs/source/roles/researcher/user_guide/msrds_no_work_resources.png b/docs/source/roles/researcher/user_guide/msrds_no_work_resources.png deleted file mode 100644 index b76ab3dc74..0000000000 Binary files a/docs/source/roles/researcher/user_guide/msrds_no_work_resources.png and /dev/null differ diff --git a/docs/source/roles/researcher/user_guide/msrds_srd_connection.png b/docs/source/roles/researcher/user_guide/msrds_srd_connection.png deleted file mode 100644 index 333af53fe3..0000000000 Binary files a/docs/source/roles/researcher/user_guide/msrds_srd_connection.png and /dev/null differ diff --git a/docs/source/roles/researcher/user_guide/msrds_srd_connection_failure.png b/docs/source/roles/researcher/user_guide/msrds_srd_connection_failure.png deleted file mode 100644 index bbeb9f9fad..0000000000 Binary files a/docs/source/roles/researcher/user_guide/msrds_srd_connection_failure.png and /dev/null differ diff --git a/docs/source/roles/researcher/user_guide/msrds_srd_rdc_screen.png b/docs/source/roles/researcher/user_guide/msrds_srd_rdc_screen.png deleted file mode 100644 index 60f11b0078..0000000000 Binary files a/docs/source/roles/researcher/user_guide/msrds_srd_rdc_screen.png and /dev/null differ diff --git a/docs/source/roles/researcher/user_guide/msrds_srd_security_fingerprint.png b/docs/source/roles/researcher/user_guide/msrds_srd_security_fingerprint.png deleted file mode 100644 index 0c1f9b01e2..0000000000 Binary files a/docs/source/roles/researcher/user_guide/msrds_srd_security_fingerprint.png and /dev/null differ diff --git a/docs/source/roles/researcher/user_guide/msrds_unexpected_certificate_error.png b/docs/source/roles/researcher/user_guide/msrds_unexpected_certificate_error.png deleted file mode 100644 index c3bdeb138c..0000000000 Binary files a/docs/source/roles/researcher/user_guide/msrds_unexpected_certificate_error.png and /dev/null differ diff --git a/docs/source/roles/researcher/user_guide_guacamole.md b/docs/source/roles/researcher/user_guide_guacamole.md deleted file mode 100644 index 1dd58f5608..0000000000 --- a/docs/source/roles/researcher/user_guide_guacamole.md +++ /dev/null @@ -1,192 +0,0 @@ -(role_researcher_user_guide_guacamole)= - -# User Guide: Apache Guacamole - -## {{beginner}} Introduction - -{{tada}} Welcome to the Turing Data Safe Haven! {{tada}} - -Secure research environments (SREs) for analysis of sensitive datasets are essential to give data providers confidence that their datasets will be kept secure over the course of a project. -The Data Safe Haven is a prescription for how to set up one or more SREs and give users access to them. -The Data Safe Haven SRE design is aimed at allowing groups of researchers to work together on projects that involve sensitive or confidential datasets at scale. -Our goal is to ensure that you are able to implement the most cutting edge data science techniques while maintaining all ethical and legal responsibilities of information governance and access. - -The data you are working on will have been classified into one of five sensitivity tiers, ranging from open data at Tier 0, to highly sensitive and high risk data at Tier 4. -The tiers are defined by the most sensitive data in your project, and may be increased if the combination of data is deemed to be require additional levels of security. -You can read more about this process in our policy paper: _Arenas et al, 2019_, [`arXiv:1908.08737`](https://arxiv.org/abs/1908.08737). - -The level of sensitivity of your data determines whether you have access to the internet within the SRE and whether you are allowed to copy and paste between the secure research environment and other windows on your computer. -This means you may be limited in which data science tools you are allowed to install. -You will find that many software packages are already available, and the administrator of the SRE will ingress - bring into the environment - as many additional resources as possible. - -```{important} -Please read this user guide carefully and remember to refer back to it when you have questions. -In many cases the answer is already here, but if you think this resource could be clearer, please let us know so we can improve the documentation for future users. -``` - -### Definitions - -The following definitions might be useful during the rest of this guide - -Secure Research Environment (SRE) -: the environment that you will be using to access the sensitive data. - -Data Safe Haven -: the overall project that details how to create and manage one or more SREs. - -(user_guide_username_domain)= -Username domain -: the domain (for example `projects.turingsafehaven.ac.uk`) which your user account will belong to. Multiple SREs can share the same domain for managing users in common. - -(user_guide_sre_id)= -SRE ID -: each SRE has a unique short ID, for example `sandbox` which your {ref}`System Manager ` will use to distinguish different SREs in the same Data Safe Haven. - -(user_guide_sre_url)= -SRE URL -: each SRE has a unique URL (for example `sandbox.projects.turingsafehaven.ac.uk`) which is used to access the data. - -(roles_researcher_user_guide_setup_mfa)= - -```{include} snippets/02_account_setup.partial.md -:relative-images: -``` - -## {{closed_lock_with_key}} Password and MFA - -```{include} snippets/13_MFA.partial.md -:relative-images: -``` - -## {{unlock}} Access the Secure Research Environment - -```{include} snippets/03_01_prerequisites.partial.md -:relative-images: -``` - -### {{house}} Log into the research environment - -- Open a **private/incognito** browser session, so that you don't pick up any existing Microsoft logins - -- Go to the {ref}`SRE URL ` given by your {ref}`System Manager `. - - ```{note} - Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, would navigate to `https://sandbox.projects.turingsafehaven.ac.uk`. - ``` - - ```{important} - Don't forget the **https://** as you will not be able to login without it! - ``` - -- You should arrive at a login page that needs you to enter: - - - your `username@` - - your password - - then click `Login`. - -- You should arrive at a login page that looks like the image below: - - ````{note} - Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, would enter `ada.lovelace@projects.turingsafehaven.ac.uk` in the `User name` box, enter her password and then click `Login`. - ```{image} user_guide/logon_environment_guacamole.png - :alt: Research environment log in - :align: center - ``` - ```` - -- You will now **receive a call or mobile app notification** to authenticate using multifactor authentication (MFA). - - ```{image} user_guide/guacamole_mfa.png - :alt: MFA trigger - :align: center - ``` - - {{telephone_receiver}} For the call, you may have to move to an area with good reception and/or press the hash (`#`) key multiple times in-call. - - {{iphone}} For the app you will see a notification saying _"You have received a sign in verification request"_. Go to the app to approve the request. - - ```{caution} - If you don't respond to the MFA request quickly enough, or if it fails, you may get an error. If this happens, please retry - ``` - -- If you are successful, you'll see the a screen with icons for the available apps. - - ```{image} user_guide/guacamole_dashboard.png - :alt: Research environment dashboard - :align: center - ``` - - Welcome to the Data Safe Haven! {{wave}} - -### {{penguin}} Log into the Secure Research Desktop - -The primary method of performing data analysis in the SRE is using the Secure Research Desktop (SRD). - -This is a virtual machine (VM) with many different applications and programming languages pre-installed on it. -Once connected to it, you can analyse the sensitive data belonging to your project while remaining completely isolated from the internet. - -- Click on one of the `Desktop` connections (for example `Ubuntu0_CPU2_8GB (Desktop)` to connect to the desktop. - -```{include} snippets/03_02_srd_login.partial.md -:relative-images: -``` - -```{include} snippets/04_using_srd.partial.md -:relative-images: -``` - - - -(role_researcher_user_guide_shared_storage)= - -```{include} snippets/05_share_files.partial.md -:relative-images: -``` - -```{include} snippets/06_cocalc.partial.md -:relative-images: -``` - -```{include} snippets/07_gitlab.partial.md -:relative-images: -``` - -```{include} snippets/08_codimd.partial.md -:relative-images: -``` - -## {{unlock}} Access additional SRDs - -Your project might make use of further SRDs in addition to the main shared desktop. -Usually this is because of a requirement for a different type of computing resource, such as access to one or more GPUs (graphics processing units). - -You will access this machine in a similar way to the main shared desktop, by selecting a different `Desktop` connection. - -````{note} -Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, might select `Ubuntu1_CPU2_8GB (Desktop)` instead of `Ubuntu0_CPU2_8GB (Desktop)` -```{image} user_guide/guacamole_dashboard.png -:alt: Research environment dashboard -:align: center -``` -```` - -- This will bring you to the normal login screen, where you use the same `username` and `password` credentials as before. -- Any local files that you have created in the `/output/` folder on other VMs (e.g. analysis scripts, notes, derived data) will be automatically available in the new VM. - -```{tip} -The naming pattern of the available desktop connections lets you know their compute capabilities. -For example `Ubuntu1_CPU2_8GB` has 2 CPUs and 8GB of RAM. -``` - -```{include} snippets/10_databases.partial.md -:relative-images: -``` - -```{include} snippets/11_report_bugs.partial.md -:relative-images: -``` - -```{include} snippets/12_end_matter.partial.md -:relative-images: -``` diff --git a/docs/source/roles/researcher/user_guide_msrds.md b/docs/source/roles/researcher/user_guide_msrds.md deleted file mode 100644 index 263bf56650..0000000000 --- a/docs/source/roles/researcher/user_guide_msrds.md +++ /dev/null @@ -1,211 +0,0 @@ -(role_researcher_user_guide_msrds)= - -# User Guide: Microsoft Remote Desktop - -```{warning} -Support for Microsoft Remote Desktop is deprecated. Deployment scripts and related documentation will be removed in version `4.2.0` of the Data Safe Haven. -``` - -## {{beginner}} Introduction - -{{tada}} Welcome to the Turing Data Safe Haven! {{tada}} - -Secure research environments (SREs) for analysis of sensitive datasets are essential to give data providers confidence that their datasets will be kept secure over the course of a project. -The Data Safe Haven is a prescription for how to set up one or more SREs and give users access to them. -The Data Safe Haven SRE design is aimed at allowing groups of researchers to work together on projects that involve sensitive or confidential datasets at scale. -Our goal is to ensure that you are able to implement the most cutting edge data science techniques while maintaining all ethical and legal responsibilities of information governance and access. - -The data you are working on will have been classified into one of five sensitivity tiers, ranging from open data at Tier 0, to highly sensitive and high risk data at Tier 4. -The tiers are defined by the most sensitive data in your project, and may be increased if the combination of data is deemed to be require additional levels of security. -You can read more about this process in our policy paper: _Arenas et al, 2019_, [`arXiv:1908.08737`](https://arxiv.org/abs/1908.08737). - -The level of sensitivity of your data determines whether you have access to the internet within the SRE and whether you are allowed to copy and paste between the secure research environment and other windows on your computer. -This means you may be limited in which data science tools you are allowed to install. -You will find that many software packages are already available, and the administrator of the SRE will ingress - bring into the environment - as many additional resources as possible. - -```{important} -Please read this user guide carefully and remember to refer back to it when you have questions. -In many cases the answer is already here, but if you think this resource could be clearer, please let us know so we can improve the documentation for future users. -``` - -### Definitions - -The following definitions might be useful during the rest of this guide - -Secure Research Environment (SRE) -: the environment that you will be using to access the sensitive data. - -Data Safe Haven -: the overall project that details how to create and manage one or more SREs. - -(user_guide_username_domain_2)= -Username domain -: the domain (for example `projects.turingsafehaven.ac.uk`) which your user account will belong to. Multiple SREs can share the same domain for managing users in common. - -(user_guide_sre_id_2)= -SRE ID -: each SRE has a unique short ID, for example `sandbox` which your {ref}`System Manager ` will use to distinguish different SREs in the same Data Safe Haven. - -(user_guide_sre_url_2)= -SRE URL -: each SRE has a unique URL (for example `sandbox.projects.turingsafehaven.ac.uk`) which is used to access the data. - -```{include} snippets/02_account_setup.partial.md -:relative-images: -``` - -(user_setup_password_mfa)= - -## {{closed_lock_with_key}} Password and MFA - -```{include} snippets/13_MFA.partial.md -:relative-images: -``` - -## {{unlock}} Access the Secure Research Environment - -```{include} snippets/03_01_prerequisites.partial.md -:relative-images: -``` - -### {{house}} Log into the research environment - -- Open a **private/incognito** browser session, so that you don't pick up any existing Microsoft logins - -- Go to the {ref}`SRE URL ` given by your {ref}`System Manager `. - - ```{note} - Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, would navigate to `https://sandbox.projects.turingsafehaven.ac.uk`. - ``` - - ```{important} - Don't forget the **https://** as you will not be able to login without it! - ``` - -- You should arrive at a login page that needs you to enter: - - - your `username` - - your password - - then click `Sign in`. - - ````{note} - Our example user, Ada Lovelace, participating in the `sandbox` project at a Turing Data Study Group, would enter `ada.lovelace` in the `User name` box, enter her password and then click `Sign in`. - ```{image} user_guide/logon_environment_msrds.png - :alt: Research environment log in - :align: center - ``` - ```` - -- If you are successful, you'll see the a screen with icons for the available apps. - - ```{image} user_guide/msrds_dashboard.png - :alt: Research environment dashboard - :align: center - ``` - - Welcome to the Data Safe Haven! {{wave}} - -### {{penguin}} Log into the Secure Research Desktop - -The primary method of performing data analysis in the SRE is using the Secure Research Desktop (SRD). - -This is a virtual machine (VM) with many different applications and programming languages pre-installed on it. -Once connected to it, you can analyse the sensitive data belonging to your project while remaining completely isolated from the internet. - -- Click on the `SRD Main (Desktop)` app to connect to the desktop. - - You will now **receive a call or mobile app notification** to authenticate using MFA. - - {{telephone_receiver}} For the call, you may have to move to an area with good reception and/or press the hash ( `#` ) key multiple times in-call. - - {{iphone}} For the app you will see a notification saying _"You have received a sign in verification request"_. Go to the app to approve the request. - - ```{image} user_guide/msrds_srd_connection.png - :alt: SRD connection attempt - :align: center - ``` - - ````{caution} - If you don't respond to the MFA request quickly enough, or if it fails, you will likely get an error that looks like this: - - ```{image} user_guide/msrds_srd_connection_failure.png - :alt: SRD connection failure - :align: center - ``` - You can try again by clicking "Reconnect". - ```` - -- After verifying using MFA, you might get a security alert like this one. If you do, it is safe to tick the box and to click `Yes` . - - ```{image} user_guide/msrds_srd_security_fingerprint.png - :alt: SRD security fingerprint - :align: center - ``` - -```{include} snippets/03_02_srd_login.partial.md -:relative-images: -``` - -```{include} snippets/04_using_srd.partial.md -:relative-images: -``` - -```{include} snippets/05_share_files.partial.md -:relative-images: -``` - -```{include} snippets/06_cocalc.partial.md -:relative-images: -``` - -```{tip} -You can also access `CoCalc` from the `CoCalc` icon on the `Work Resources` dashboard page. -``` - -```{include} snippets/07_gitlab.partial.md -:relative-images: -``` - -```{tip} -You can also access `GitLab` from the `GitLab` icon on the `Work Resources` dashboard page. -``` - -```{include} snippets/08_codimd.partial.md -:relative-images: -``` - -```{tip} -You can also access `CodiMD` from the `CodiMD` icon on the `Work Resources` dashboard page. -``` - -## {{unlock}} Access additional SRDs - -Your project might make use of further SRDs in addition to the main shared desktop. -Usually this is because of a requirement for a different type of computing resource, such as access to one or more GPUs (graphics processing units). - -You will access this machine in a similar way to the main shared desktop, but by using the `SRD Other (Desktop)` icon inside of the usual `SRD Main (Desktop)` icon. -You will need to know the IP address of the new machine, which you will be told by the designated contact for your SRE. - -- When you click on the `SRD Other (Desktop)` icon you will see a screen asking you to identify the computer you wish to connect to. -- Enter the IP address of the desired SRD. - -```{image} user_guide/msrds_srd_rdc_screen.png -:alt: SRD IP address input -:align: center -``` - -- After entering the IP address, you will get the normal login screen, where you use the same `username` and `password` credentials as before. -- Any local files that you have created in the `/output/` folder on other VMs (e.g. analysis scripts, notes, derived data) will be automatically available in the new VM. - -```{include} snippets/10_databases.partial.md -:relative-images: -``` - -```{include} snippets/11_report_bugs.partial.md -:relative-images: -``` - -```{include} snippets/12_end_matter.partial.md -:relative-images: -``` diff --git a/docs/source/roles/system_manager/administrator_guide/srd_login_opening_port.png b/docs/source/roles/system_manager/administrator_guide/srd_login_opening_port.png deleted file mode 100644 index 1d19d86abb..0000000000 Binary files a/docs/source/roles/system_manager/administrator_guide/srd_login_opening_port.png and /dev/null differ diff --git a/docs/source/roles/system_manager/manage_users.md b/docs/source/roles/system_manager/manage_users.md index 100b6788b2..7c832132ff 100644 --- a/docs/source/roles/system_manager/manage_users.md +++ b/docs/source/roles/system_manager/manage_users.md @@ -231,22 +231,6 @@ If users give the wrong username or password they will not be able to progress p **Solution**: Check user credentials, password may need to be reset. ``` -### {{train}} Unable to open any remote apps - -Users are stuck at the `Opening remote port` message and never receive the MFA prompt. - -```{image} administrator_guide/srd_login_opening_port.png -:alt: Login failure - no MFA prompt -:align: center -``` - -```{tip} -**Solution**: Check MFA setup - -- Ensure that the user has been assigned a license in Azure Active Directory -- Check that the user has set up MFA (at [https://aka.ms/mfasetup](https://aka.ms/mfasetup) ) and is using the phone-call or app authentication method -``` - ### {{see_no_evil}} Unable to see SRD or SSH connection options After logging in with Microsoft, users can't see the option to log into the SRE via the SRD or SSH options. diff --git a/environment_configs/package_lists/allowlist-full-python-pypi-tier3.list b/environment_configs/package_lists/allowlist-full-python-pypi-tier3.list index 0afbdc7b3e..0bfe16e893 100644 --- a/environment_configs/package_lists/allowlist-full-python-pypi-tier3.list +++ b/environment_configs/package_lists/allowlist-full-python-pypi-tier3.list @@ -323,6 +323,7 @@ mercantile miniKanren missingno mistune +ml-dtypes mock modutil monotonic diff --git a/environment_configs/sre_bluet2msrds_core_config.json b/environment_configs/sre_bluet2msrds_core_config.json deleted file mode 100644 index 13e8a4e218..0000000000 --- a/environment_configs/sre_bluet2msrds_core_config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "sreId": "t2msrds", - "tier": "2", - "shmId": "blue", - "subscriptionName": "Data Safe Haven Development", - "ipPrefix": "10.162.0", - "inboundAccessFrom": ["193.60.220.253"], - "outboundInternetAccess": "default", - "computeVmImage": { - "type": "Ubuntu", - "version": "20.04.2023031401" - }, - "remoteDesktopProvider": "MicrosoftRDS", - "dataAdminIpAddresses": ["193.60.220.253"], - "databases": ["MSSQL", "PostgreSQL"] -} diff --git a/environment_configs/sre_bluet3msrds_core_config.json b/environment_configs/sre_bluet3msrds_core_config.json deleted file mode 100644 index c83c0833ab..0000000000 --- a/environment_configs/sre_bluet3msrds_core_config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "sreId": "t3msrds", - "tier": "3", - "shmId": "blue", - "subscriptionName": "Data Safe Haven Development", - "ipPrefix": "10.163.0", - "inboundAccessFrom": ["193.60.220.240"], - "outboundInternetAccess": "default", - "computeVmImage": { - "type": "Ubuntu", - "version": "20.04.2023031401" - }, - "remoteDesktopProvider": "MicrosoftRDS", - "dataAdminIpAddresses": ["193.60.220.240"], - "databases": ["MSSQL", "PostgreSQL"] -} diff --git a/environment_configs/sre_greent2msrds_core_config.json b/environment_configs/sre_greent2msrds_core_config.json deleted file mode 100644 index 20c6912ec9..0000000000 --- a/environment_configs/sre_greent2msrds_core_config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "sreId": "t2msrds", - "tier": "2", - "shmId": "green", - "subscriptionName": "Data Safe Haven Development", - "ipPrefix": "10.162.0", - "inboundAccessFrom": ["193.60.220.253"], - "outboundInternetAccess": "default", - "computeVmImage": { - "type": "Ubuntu", - "version": "20.04.2023031401" - }, - "remoteDesktopProvider": "MicrosoftRDS", - "dataAdminIpAddresses": ["193.60.220.253"], - "databases": ["MSSQL", "PostgreSQL"] -} diff --git a/environment_configs/sre_greent3msrds_core_config.json b/environment_configs/sre_greent3msrds_core_config.json deleted file mode 100644 index 1cd114f919..0000000000 --- a/environment_configs/sre_greent3msrds_core_config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "sreId": "t3msrds", - "tier": "3", - "shmId": "green", - "subscriptionName": "Data Safe Haven Development", - "ipPrefix": "10.163.0", - "inboundAccessFrom": ["193.60.220.240"], - "outboundInternetAccess": "default", - "computeVmImage": { - "type": "Ubuntu", - "version": "20.04.2023031401" - }, - "remoteDesktopProvider": "MicrosoftRDS", - "dataAdminIpAddresses": ["193.60.220.240"], - "databases": ["MSSQL", "PostgreSQL"] -} diff --git a/tests/resources/shm_blue_full_config.json b/tests/resources/shm_blue_full_config.json index ddc78b8f59..14d42975fb 100644 --- a/tests/resources/shm_blue_full_config.json +++ b/tests/resources/shm_blue_full_config.json @@ -51,14 +51,6 @@ "name": "Secure Research Environment Linux Servers", "path": "OU=Secure Research Environment Linux Servers,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" }, - "rdsGatewayServers": { - "name": "Secure Research Environment RDS Gateway Servers", - "path": "OU=Secure Research Environment RDS Gateway Servers,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, - "rdsSessionServers": { - "name": "Secure Research Environment RDS Session Servers", - "path": "OU=Secure Research Environment RDS Session Servers,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, "researchUsers": { "name": "Safe Haven Research Users", "path": "OU=Safe Haven Research Users,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" @@ -1068,16 +1060,6 @@ "name": "BLUE Linux Servers Manager", "passwordSecretName": "shm-blue-computer-manager-password-linux-servers", "samAccountName": "bluelinuxsrvrs" - }, - "rdsGatewayServers": { - "name": "BLUE RDS Gateway Manager", - "passwordSecretName": "shm-blue-computer-manager-password-rds-gateway-servers", - "samAccountName": "bluegatewaysrvrs" - }, - "rdsSessionServers": { - "name": "BLUE RDS Session Servers Manager", - "passwordSecretName": "shm-blue-computer-manager-password-rds-session-servers", - "samAccountName": "bluesessionsrvrs" } }, "serviceAccounts": { diff --git a/tests/resources/shm_green_full_config.json b/tests/resources/shm_green_full_config.json index d47cd3edb8..2d72b0a912 100644 --- a/tests/resources/shm_green_full_config.json +++ b/tests/resources/shm_green_full_config.json @@ -51,14 +51,6 @@ "name": "Secure Research Environment Linux Servers", "path": "OU=Secure Research Environment Linux Servers,DC=green,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" }, - "rdsGatewayServers": { - "name": "Secure Research Environment RDS Gateway Servers", - "path": "OU=Secure Research Environment RDS Gateway Servers,DC=green,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, - "rdsSessionServers": { - "name": "Secure Research Environment RDS Session Servers", - "path": "OU=Secure Research Environment RDS Session Servers,DC=green,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, "researchUsers": { "name": "Safe Haven Research Users", "path": "OU=Safe Haven Research Users,DC=green,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" @@ -1121,16 +1113,6 @@ "name": "GREEN Linux Servers Manager", "passwordSecretName": "shm-green-computer-manager-password-linux-servers", "samAccountName": "greenlinuxsrvrs" - }, - "rdsGatewayServers": { - "name": "GREEN RDS Gateway Manager", - "passwordSecretName": "shm-green-computer-manager-password-rds-gateway-servers", - "samAccountName": "greengatewaysrvrs" - }, - "rdsSessionServers": { - "name": "GREEN RDS Session Servers Manager", - "passwordSecretName": "shm-green-computer-manager-password-rds-session-servers", - "samAccountName": "greensessionsrvrs" } }, "serviceAccounts": { diff --git a/tests/resources/sre_bluet1guac_full_config.json b/tests/resources/sre_bluet1guac_full_config.json index 24f1f18747..0aed7c6062 100644 --- a/tests/resources/sre_bluet1guac_full_config.json +++ b/tests/resources/sre_bluet1guac_full_config.json @@ -52,14 +52,6 @@ "name": "Secure Research Environment Linux Servers", "path": "OU=Secure Research Environment Linux Servers,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" }, - "rdsGatewayServers": { - "name": "Secure Research Environment RDS Gateway Servers", - "path": "OU=Secure Research Environment RDS Gateway Servers,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, - "rdsSessionServers": { - "name": "Secure Research Environment RDS Session Servers", - "path": "OU=Secure Research Environment RDS Session Servers,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, "researchUsers": { "name": "Safe Haven Research Users", "path": "OU=Safe Haven Research Users,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" @@ -1069,16 +1061,6 @@ "name": "BLUE Linux Servers Manager", "passwordSecretName": "shm-blue-computer-manager-password-linux-servers", "samAccountName": "bluelinuxsrvrs" - }, - "rdsGatewayServers": { - "name": "BLUE RDS Gateway Manager", - "passwordSecretName": "shm-blue-computer-manager-password-rds-gateway-servers", - "samAccountName": "bluegatewaysrvrs" - }, - "rdsSessionServers": { - "name": "BLUE RDS Session Servers Manager", - "passwordSecretName": "shm-blue-computer-manager-password-rds-session-servers", - "samAccountName": "bluesessionsrvrs" } }, "serviceAccounts": { diff --git a/tests/resources/sre_bluet3msrds_full_config.json b/tests/resources/sre_bluet3guac_full_config.json similarity index 86% rename from tests/resources/sre_bluet3msrds_full_config.json rename to tests/resources/sre_bluet3guac_full_config.json index 1a59d3b537..de66cdf330 100644 --- a/tests/resources/sre_bluet3msrds_full_config.json +++ b/tests/resources/sre_bluet3guac_full_config.json @@ -52,14 +52,6 @@ "name": "Secure Research Environment Linux Servers", "path": "OU=Secure Research Environment Linux Servers,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" }, - "rdsGatewayServers": { - "name": "Secure Research Environment RDS Gateway Servers", - "path": "OU=Secure Research Environment RDS Gateway Servers,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, - "rdsSessionServers": { - "name": "Secure Research Environment RDS Session Servers", - "path": "OU=Secure Research Environment RDS Session Servers,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, "researchUsers": { "name": "Safe Haven Research Users", "path": "OU=Safe Haven Research Users,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" @@ -1069,16 +1061,6 @@ "name": "BLUE Linux Servers Manager", "passwordSecretName": "shm-blue-computer-manager-password-linux-servers", "samAccountName": "bluelinuxsrvrs" - }, - "rdsGatewayServers": { - "name": "BLUE RDS Gateway Manager", - "passwordSecretName": "shm-blue-computer-manager-password-rds-gateway-servers", - "samAccountName": "bluegatewaysrvrs" - }, - "rdsSessionServers": { - "name": "BLUE RDS Session Servers Manager", - "passwordSecretName": "shm-blue-computer-manager-password-rds-session-servers", - "samAccountName": "bluesessionsrvrs" } }, "serviceAccounts": { @@ -1101,25 +1083,18 @@ "disk": { "policy_name": "diskbackuppolicy" }, - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_BACKUP", + "rg": "RG_SHM_BLUE_SRE_T3GUAC_BACKUP", "vault": { - "name": "bv-blue-sre-t3msrds" + "name": "bv-blue-sre-t3guac" } }, "databases": { "enabled": true, "instances": [ { - "adminPasswordSecretName": "sre-t3msrds-vm-admin-password-mssql", - "dbAdminUsernameSecretName": "sre-t3msrds-db-admin-username-mssql", - "dbAdminPasswordSecretName": "sre-t3msrds-db-admin-password-mssql", - "vmName": "MSSQL-T3MSRDS", - "type": "MSSQL", - "ip": "10.163.3.4", - "port": "1433", - "sku": "sqldev-gen2", - "subnet": "databases", - "vmSize": "Standard_DS2_v2", + "adminPasswordSecretName": "sre-t3guac-vm-admin-password-mssql", + "dbAdminPasswordSecretName": "sre-t3guac-db-admin-password-mssql", + "dbAdminUsernameSecretName": "sre-t3guac-db-admin-username-mssql", "disks": { "data": { "sizeGb": "1024", @@ -1130,19 +1105,19 @@ "type": "Standard_LRS" } }, - "enableSSIS": true + "enableSSIS": true, + "ip": "10.153.3.4", + "port": "1433", + "sku": "sqldev-gen2", + "subnet": "databases", + "type": "MSSQL", + "vmName": "MSSQL-T3GUAC", + "vmSize": "Standard_DS2_v2" }, { - "adminPasswordSecretName": "sre-t3msrds-vm-admin-password-postgresql", - "dbAdminUsernameSecretName": "sre-t3msrds-db-admin-username-postgresql", - "dbAdminPasswordSecretName": "sre-t3msrds-db-admin-password-postgresql", - "vmName": "PSTGRS-T3MSRDS", - "type": "PostgreSQL", - "ip": "10.163.3.5", - "port": "5432", - "sku": "Ubuntu-latest", - "subnet": "databases", - "vmSize": "Standard_DS2_v2", + "adminPasswordSecretName": "sre-t3guac-vm-admin-password-postgresql", + "dbAdminPasswordSecretName": "sre-t3guac-db-admin-password-postgresql", + "dbAdminUsernameSecretName": "sre-t3guac-db-admin-username-postgresql", "disks": { "data": { "sizeGb": "1024", @@ -1152,135 +1127,120 @@ "sizeGb": "128", "type": "Standard_LRS" } - } + }, + "ip": "10.153.3.5", + "port": "5432", + "sku": "Ubuntu-latest", + "subnet": "databases", + "type": "PostgreSQL", + "vmName": "PSTGRS-T3GUAC", + "vmSize": "Standard_DS2_v2" } ], - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_DATABASES" + "rg": "RG_SHM_BLUE_SRE_T3GUAC_DATABASES" }, "diskTypeDefault": "Standard_LRS", "domain": { - "dn": "DC=t3msrds,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk", - "fqdn": "t3msrds.blue.develop.turingsafehaven.ac.uk", - "netbiosName": "T3MSRDS", + "dn": "DC=t3guac,DC=blue,DC=develop,DC=turingsafehaven,DC=ac,DC=uk", + "fqdn": "t3guac.blue.develop.turingsafehaven.ac.uk", + "netbiosName": "T3GUAC", "securityGroups": { "dataAdministrators": { - "description": "SG T3MSRDS Data Administrators", - "name": "SG T3MSRDS Data Administrators" + "description": "SG T3GUAC Data Administrators", + "name": "SG T3GUAC Data Administrators" }, "researchUsers": { - "description": "SG T3MSRDS Research Users", - "name": "SG T3MSRDS Research Users" + "description": "SG T3GUAC Research Users", + "name": "SG T3GUAC Research Users" }, "systemAdministrators": { - "description": "SG T3MSRDS System Administrators", - "name": "SG T3MSRDS System Administrators" + "description": "SG T3GUAC System Administrators", + "name": "SG T3GUAC System Administrators" } } }, "firewall": { - "routeTableName": "ROUTE-TABLE-SRE-T3MSRDS" + "routeTableName": "ROUTE-TABLE-SRE-T3GUAC" }, - "id": "t3msrds", + "id": "t3guac", "keyVault": { - "name": "kv-blue-sre-t3msrds", - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_SECRETS", + "name": "kv-blue-sre-t3guac", + "rg": "RG_SHM_BLUE_SRE_T3GUAC_SECRETS", "secretNames": { - "adminUsername": "sre-t3msrds-vm-admin-username", - "letsEncryptCertificate": "sre-t3msrds-lets-encrypt-certificate", - "npsSecret": "sre-t3msrds-other-nps-secret" + "adminUsername": "sre-t3guac-vm-admin-username", + "letsEncryptCertificate": "sre-t3guac-lets-encrypt-certificate", + "npsSecret": "sre-t3guac-other-nps-secret" } }, "location": "uksouth", "network": { "vnet": { - "cidr": "10.163.0.0/21", - "name": "VNET_SHM_BLUE_SRE_T3MSRDS", - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_NETWORKING", + "cidr": "10.153.0.0/21", + "name": "VNET_SHM_BLUE_SRE_T3GUAC", + "rg": "RG_SHM_BLUE_SRE_T3GUAC_NETWORKING", "subnets": { "compute": { - "cidr": "10.163.4.0/24", + "cidr": "10.153.4.0/24", "name": "ComputeSubnet", "nsg": { - "name": "NSG_SHM_BLUE_SRE_T3MSRDS_COMPUTE", + "name": "NSG_SHM_BLUE_SRE_T3GUAC_COMPUTE", "rules": "sre-nsg-rules-compute.json" } }, "data": { - "cidr": "10.163.2.0/24", + "cidr": "10.153.2.0/24", "name": "PrivateDataSubnet" }, "databases": { - "cidr": "10.163.3.0/24", + "cidr": "10.153.3.0/24", "name": "DatabasesSubnet", "nsg": { - "name": "NSG_SHM_BLUE_SRE_T3MSRDS_DATABASES", + "name": "NSG_SHM_BLUE_SRE_T3GUAC_DATABASES", "rules": "sre-nsg-rules-databases.json" } }, "deployment": { - "cidr": "10.163.0.0/24", + "cidr": "10.153.0.0/24", "name": "DeploymentSubnet", "nsg": { - "name": "NSG_SHM_BLUE_SRE_T3MSRDS_DEPLOYMENT", + "name": "NSG_SHM_BLUE_SRE_T3GUAC_DEPLOYMENT", "rules": "sre-nsg-rules-deployment.json" } }, "remoteDesktop": { - "cidr": "10.163.1.0/24", - "name": "RemoteDesktopSubnet" + "cidr": "10.153.1.0/24", + "name": "RemoteDesktopSubnet", + "nsg": { + "name": "NSG_SHM_BLUE_SRE_T3GUAC_GUACAMOLE", + "rules": "sre-nsg-rules-guacamole.json" + } }, "webapps": { - "cidr": "10.163.5.0/24", + "cidr": "10.153.5.0/24", "name": "WebappsSubnet", "nsg": { - "name": "NSG_SHM_BLUE_SRE_T3MSRDS_WEBAPPS", + "name": "NSG_SHM_BLUE_SRE_T3GUAC_WEBAPPS", "rules": "sre-nsg-rules-webapps.json" } } } } }, - "nsgPrefix": "NSG_SHM_BLUE_SRE_T3MSRDS", + "nsgPrefix": "NSG_SHM_BLUE_SRE_T3GUAC", "remoteDesktop": { - "appSessionHost": { - "adminPasswordSecretName": "sre-t3msrds-vm-admin-password-rds-sh1", + "guacamole": { + "adminPasswordSecretName": "sre-t3guac-vm-admin-password-guacamole", + "databaseAdminPasswordSecretName": "sre-t3guac-db-admin-password-guacamole", "disks": { "os": { "sizeGb": "128", "type": "Standard_LRS" } }, - "fqdn": "APP-SRE-T3MSRDS.blue.develop.turingsafehaven.ac.uk", - "hostname": "APP-SRE-T3MSRDS", - "ip": "10.163.1.5", - "nsg": { - "name": "NSG_SHM_BLUE_SRE_T3MSRDS_RDS_SESSION_HOSTS", - "rules": "sre-nsg-rules-session-hosts.json" - }, - "vmName": "APP-SRE-T3MSRDS", - "vmSize": "Standard_DS2_v2" - }, - "gateway": { - "adminPasswordSecretName": "sre-t3msrds-vm-admin-password-rds-gateway", - "disks": { - "data": { - "sizeGb": "1023", - "type": "Standard_LRS" - }, - "os": { - "sizeGb": "128", - "type": "Standard_LRS" - } - }, - "fqdn": "RDG-SRE-T3MSRDS.blue.develop.turingsafehaven.ac.uk", - "hostname": "RDG-SRE-T3MSRDS", - "installationDirectory": "C:\\Installation", - "ip": "10.163.1.4", - "nsg": { - "name": "NSG_SHM_BLUE_SRE_T3MSRDS_RDS_SERVER", - "rules": "sre-nsg-rules-gateway.json" - }, - "vmName": "RDG-SRE-T3MSRDS", + "fqdn": "GUACAMOLE-SRE-T3GUAC.blue.develop.turingsafehaven.ac.uk", + "hostname": "GUACAMOLE-SRE-T3GUAC", + "ip": "10.153.1.4", + "vmName": "GUACAMOLE-SRE-T3GUAC", "vmSize": "Standard_DS2_v2" }, "networkRules": { @@ -1290,8 +1250,8 @@ "outboundInternet": "Deny", "pasteAllowed": false }, - "provider": "MicrosoftRDS", - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_REMOTE_DESKTOP" + "provider": "ApacheGuacamole", + "rg": "RG_SHM_BLUE_SRE_T3GUAC_REMOTE_DESKTOP" }, "repositories": { "cran": { @@ -1307,10 +1267,10 @@ "indexUrl": "http://10.10.3.198:80/repository/pypi-proxy/simple" } }, - "rgPrefix": "RG_SHM_BLUE_SRE_T3MSRDS", - "shortName": "sre-t3msrds", + "rgPrefix": "RG_SHM_BLUE_SRE_T3GUAC", + "shortName": "sre-t3guac", "srd": { - "adminPasswordSecretName": "sre-t3msrds-vm-admin-password-compute", + "adminPasswordSecretName": "sre-t3guac-vm-admin-password-compute", "disks": { "os": { "sizeGb": "default", @@ -1321,7 +1281,7 @@ "type": "StandardSSD_LRS" } }, - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_COMPUTE", + "rg": "RG_SHM_BLUE_SRE_T3GUAC_COMPUTE", "vmImage": { "type": "Ubuntu", "version": "20.04.2023031401" @@ -1341,7 +1301,7 @@ "account": { "accessTier": "Cool", "allowedIpAddresses": "any", - "name": "bluet3msrdsartifactspjnk", + "name": "bluet3guacartifactsnrzab", "performance": "Standard_GRS", "storageKind": "BlobStorage" }, @@ -1349,34 +1309,34 @@ "sreArtifactsRDS": "sre-artifacts-rds", "sreScriptsRDS": "sre-scripts-rds" }, - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_STORAGE" + "rg": "RG_SHM_BLUE_SRE_T3GUAC_STORAGE" }, "bootdiagnostics": { - "accountName": "bluet3msrdsbootdiagspjnk", - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_STORAGE" + "accountName": "bluet3guacbootdiagsnrzab", + "rg": "RG_SHM_BLUE_SRE_T3GUAC_STORAGE" }, "persistentdata": { "account": { "accessTier": "Hot", "allowedIpAddresses": "193.60.220.240", - "name": "bluet3msrdsdatapjnkuhzcg", + "name": "bluet3guacdatanrzabxpjid", "performance": "Standard_GRS", "storageKind": "StorageV2" }, "containers": { "backup": { "accessPolicyName": "readWrite", - "connectionSecretName": "sre-t3msrds-data-backup-connection-readwrite", + "connectionSecretName": "sre-t3guac-data-backup-connection-readwrite", "mountType": "BlobSMB" }, "egress": { "accessPolicyName": "readWrite", - "connectionSecretName": "sre-t3msrds-data-egress-connection-readwrite", + "connectionSecretName": "sre-t3guac-data-egress-connection-readwrite", "mountType": "BlobSMB" }, "ingress": { "accessPolicyName": "readOnly", - "connectionSecretName": "sre-t3msrds-data-ingress-connection-readonly", + "connectionSecretName": "sre-t3guac-data-ingress-connection-readonly", "mountType": "BlobSMB" } } @@ -1384,9 +1344,9 @@ "userdata": { "account": { "accessTier": "Hot", - "name": "bluet3msrdsuserdatapjnku", + "name": "bluet3guacuserdatanrzabx", "performance": "Premium_ZRS", - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_STORAGE", + "rg": "RG_SHM_BLUE_SRE_T3GUAC_STORAGE", "storageKind": "FileStorage" }, "containers": { @@ -1415,20 +1375,20 @@ "users": { "serviceAccounts": { "ldapSearch": { - "name": "T3MSRDS LDAP Search Service Account", - "passwordSecretName": "sre-t3msrds-other-service-account-password-ldap-search", - "samAccountName": "t3msrdsldapsearch" + "name": "T3GUAC LDAP Search Service Account", + "passwordSecretName": "sre-t3guac-other-service-account-password-ldap-search", + "samAccountName": "t3guacldapsearch" }, "postgres": { - "name": "T3MSRDS Postgres DB Service Account", - "passwordSecretName": "sre-t3msrds-db-service-account-password-postgres", - "samAccountName": "t3msrdsdbpostgres" + "name": "T3GUAC Postgres DB Service Account", + "passwordSecretName": "sre-t3guac-db-service-account-password-postgres", + "samAccountName": "t3guacdbpostgres" } } }, "webapps": { "cocalc": { - "adminPasswordSecretName": "sre-t3msrds-vm-admin-password-cocalc", + "adminPasswordSecretName": "sre-t3guac-vm-admin-password-cocalc", "disks": { "data": { "sizeGb": "512", @@ -1440,15 +1400,15 @@ } }, "dockerVersion": "latest", - "fqdn": "COCALC.t3msrds.blue.develop.turingsafehaven.ac.uk", + "fqdn": "COCALC.t3guac.blue.develop.turingsafehaven.ac.uk", "hostname": "COCALC", - "ip": "10.163.5.7", + "ip": "10.153.5.7", "osVersion": "Ubuntu-latest", - "vmName": "COCALC-SRE-T3MSRDS", + "vmName": "COCALC-SRE-T3GUAC", "vmSize": "Standard_D2s_v3" }, "codimd": { - "adminPasswordSecretName": "sre-t3msrds-vm-admin-password-codimd", + "adminPasswordSecretName": "sre-t3guac-vm-admin-password-codimd", "codimd": { "dockerVersion": "2.4.1-cjk" }, @@ -1462,19 +1422,19 @@ "type": "Standard_LRS" } }, - "fqdn": "CODIMD.t3msrds.blue.develop.turingsafehaven.ac.uk", + "fqdn": "CODIMD.t3guac.blue.develop.turingsafehaven.ac.uk", "hostname": "CODIMD", - "ip": "10.163.5.6", + "ip": "10.153.5.6", "osVersion": "Ubuntu-latest", "postgres": { "dockerVersion": "13.4-alpine", - "passwordSecretName": "sre-t3msrds-other-codimd-password-postgresdb" + "passwordSecretName": "sre-t3guac-other-codimd-password-postgresdb" }, - "vmName": "CODIMD-SRE-T3MSRDS", + "vmName": "CODIMD-SRE-T3GUAC", "vmSize": "Standard_D2s_v3" }, "gitlab": { - "adminPasswordSecretName": "sre-t3msrds-vm-admin-password-gitlab", + "adminPasswordSecretName": "sre-t3guac-vm-admin-password-gitlab", "disks": { "data": { "sizeGb": "512", @@ -1485,15 +1445,15 @@ "type": "Standard_LRS" } }, - "fqdn": "GITLAB.t3msrds.blue.develop.turingsafehaven.ac.uk", + "fqdn": "GITLAB.t3guac.blue.develop.turingsafehaven.ac.uk", "hostname": "GITLAB", - "ip": "10.163.5.5", + "ip": "10.153.5.5", "osVersion": "Ubuntu-latest", - "rootPasswordSecretName": "sre-t3msrds-other-gitlab-root-password", - "vmName": "GITLAB-SRE-T3MSRDS", + "rootPasswordSecretName": "sre-t3guac-other-gitlab-root-password", + "vmName": "GITLAB-SRE-T3GUAC", "vmSize": "Standard_D2s_v3" }, - "rg": "RG_SHM_BLUE_SRE_T3MSRDS_WEBAPPS" + "rg": "RG_SHM_BLUE_SRE_T3GUAC_WEBAPPS" } } } diff --git a/tests/resources/sre_greent2guac_full_config.json b/tests/resources/sre_greent2guac_full_config.json index ca318c0553..33fa1bdc21 100644 --- a/tests/resources/sre_greent2guac_full_config.json +++ b/tests/resources/sre_greent2guac_full_config.json @@ -52,14 +52,6 @@ "name": "Secure Research Environment Linux Servers", "path": "OU=Secure Research Environment Linux Servers,DC=green,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" }, - "rdsGatewayServers": { - "name": "Secure Research Environment RDS Gateway Servers", - "path": "OU=Secure Research Environment RDS Gateway Servers,DC=green,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, - "rdsSessionServers": { - "name": "Secure Research Environment RDS Session Servers", - "path": "OU=Secure Research Environment RDS Session Servers,DC=green,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" - }, "researchUsers": { "name": "Safe Haven Research Users", "path": "OU=Safe Haven Research Users,DC=green,DC=develop,DC=turingsafehaven,DC=ac,DC=uk" @@ -1122,16 +1114,6 @@ "name": "GREEN Linux Servers Manager", "passwordSecretName": "shm-green-computer-manager-password-linux-servers", "samAccountName": "greenlinuxsrvrs" - }, - "rdsGatewayServers": { - "name": "GREEN RDS Gateway Manager", - "passwordSecretName": "shm-green-computer-manager-password-rds-gateway-servers", - "samAccountName": "greengatewaysrvrs" - }, - "rdsSessionServers": { - "name": "GREEN RDS Session Servers Manager", - "passwordSecretName": "shm-green-computer-manager-password-rds-session-servers", - "samAccountName": "greensessionsrvrs" } }, "serviceAccounts": { diff --git a/tests/srd_smoke_tests/README.md b/tests/srd_smoke_tests/README.md index 8e3a1436aa..62451bfb28 100644 --- a/tests/srd_smoke_tests/README.md +++ b/tests/srd_smoke_tests/README.md @@ -166,14 +166,14 @@ All packages installed successfully To test database connectivity you will need to know the connection details and can then run something like: ```none -> python tests/test_databases_python.py --db-type mssql --db-name master --port 1433 --server-name MSSQL-T3MSRDS.testc.dsgroupdev.co.uk +> python tests/test_databases_python.py --db-type mssql --db-name master --port 1433 --server-name MSSQL-T3GUAC.testc.dsgroupdev.co.uk ``` This will attempt to connect to the relevant database server The expected output for a successful test is: ```none -Attempting to connect to 'master' on 'MSSQL-T3MSRDS.testc.dsgroupdev.co.uk' via port 1433 +Attempting to connect to 'master' on 'MSSQL-T3GUAC.testc.dsgroupdev.co.uk' via port 1433 TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE 0 master dbo spt_fallback_db BASE TABLE 1 master dbo spt_fallback_dev BASE TABLE @@ -271,14 +271,14 @@ All packages installed successfully To test database connectivity you will need to know the connection details and can then run something like: ```none -> Rscript tests/test_databases_R.R mssql master 1433 MSSQL-T3MSRDS.testc.dsgroupdev.co.uk +> Rscript tests/test_databases_R.R mssql master 1433 MSSQL-T3GUAC.testc.dsgroupdev.co.uk ``` This will attempt to connect to the relevant database server The expected output for a successful test is: ```none -[1] "Attempting to connect to 'master' on 'MSSQL-T3MSRDS.testc.dsgroupdev.co.uk' via port '1433" +[1] "Attempting to connect to 'master' on 'MSSQL-T3GUAC.testc.dsgroupdev.co.uk' via port '1433" TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE 1 master dbo spt_fallback_db BASE TABLE 2 master dbo spt_fallback_dev BASE TABLE