|
| 1 | +--- |
| 2 | +RFC: RFCNNNN |
| 3 | +Author: Paul Higinbotham |
| 4 | +Status: Draft |
| 5 | +Area: Microsoft.PowerShell.Core |
| 6 | +Comments Due: 5/20/2022 |
| 7 | +Plan to implement: Yes |
| 8 | +--- |
| 9 | + |
| 10 | +# PowerShell Local Session Configuration |
| 11 | + |
| 12 | +PowerShell currently supports extensive session configuration for WinRM remoting endpoints. |
| 13 | +The configuration is defined in a .pssc file, which can be passed to the `Register-PSSessionConfiguration` cmdlet when creating a remoting endpoint. |
| 14 | +This session configuration is limited to remoting endpoints based on WinRM (Windows Remote Management) connections only. |
| 15 | +All other PowerShell remoting connections, such as SSH based remoting, cannot define endpoint configurations, and will connect to a PowerShell session having a default configuration. |
| 16 | +A default session configuration is essentially a full PowerShell session without any restrictions. |
| 17 | + |
| 18 | +PowerShell session configuration is useful in remoting scenarios as it can restrict what is available to a user in that session, greatly improving the security stance of that session. |
| 19 | +PowerShell uses remote session configuration to support JEA (Just Enough Administration) sessions, where a user role is limited to a small number of commands and actions that can be taken within the session. |
| 20 | +Thus, the JEA session endpoint can be used to safely managed a high value machine, such as a domain controller, where the connected user can perform only a predetermined set of functions. |
| 21 | + |
| 22 | +But being able to configure a **local** PowerShell session is also useful. |
| 23 | +For example, a machine policy, could enforce a PowerShell configuration that denies direct access to the file system, or the system registry, making it more difficult for malicious actors. |
| 24 | + |
| 25 | +Local sessions are also used to implement other PowerShell remoting connections, such as SSH, and being able to configure a local session would allow these non-WinRM remoting connections to have configurable endpoints. |
| 26 | +This is important for high value machines where allowing a full PowerShell remote session is considered a security risk. |
| 27 | + |
| 28 | +## Motivation |
| 29 | + |
| 30 | +As a system administrator, I want to create a PowerShell SSH remoting endpoint that does not allow full access to the target system but pre-defined allowed capabilities. |
| 31 | + |
| 32 | +### Example 1 |
| 33 | + |
| 34 | +```powershell |
| 35 | +PS C:\> Enter-PSSession -Host TargetComputer1 -User domain\user1 -ConfigurationName MySSHEndpoint |
| 36 | +[domain\user1@TargetComputer1]: PS > dir c:\ |
| 37 | +
|
| 38 | +Error: The term 'dir' is not recognized as a name of a cmdlet, function, script file, or executable program. |
| 39 | +Check the spelling of the name, or if a path was included, verify that the path is correct and try again. |
| 40 | +
|
| 41 | +[domain\user1@TargetComputer1]: PS > Get-SystemState |
| 42 | +
|
| 43 | +com1 : @{data_len=1; inner=; io_port_base=1016} |
| 44 | +com2 : @{data_len=1; inner=; io_port_base=760} |
| 45 | +com3 : @{data_len=1; inner=; io_port_base=1000} |
| 46 | +com4 : @{data_len=1; inner=; io_port_base=744} |
| 47 | +... |
| 48 | +
|
| 49 | +[domain\user1@TargetComputer1]: PS > $NewSystemState | Set-SystemState |
| 50 | +VERBOSE: System state successfully updated |
| 51 | +[domain\user1@TargetComputer1]: PS > |
| 52 | +``` |
| 53 | + |
| 54 | +## Design |
| 55 | + |
| 56 | +### PowerShell Session Configuration |
| 57 | + |
| 58 | +PowerShell already supports session configuration through the `InitialSessionState` class. |
| 59 | +It is used to initialize a PowerShell runspace, which essentially contains the runtime session configuration state. |
| 60 | +The `InitialSessionState` class contains a number of static creation methods used to create predetermined configurations. |
| 61 | +It also contains a number of properties that expose various session functions, such as LanguageMode, Providers, Variables, etc. |
| 62 | +In addition, the `InitialSessionState` class has a static `CreateFromSessionConfigurationFile()` method that takes a path to a .pssc file, which contains session configuration options in PowerShell psd1 file format. |
| 63 | + |
| 64 | +```powershell |
| 65 | +@' |
| 66 | +@{ |
| 67 | + SchemaVersion = '2.0.0.0' |
| 68 | + GUID = 'eaa72cae-fafe-4d3d-bf65-84ff02d58fd9' |
| 69 | + Author = 'contoso' |
| 70 | + Description = 'Test configuration' |
| 71 | + CompanyName = 'Unknown' |
| 72 | + Copyright = '(c) Contoso. All rights reserved.' |
| 73 | + SessionType = 'Default' |
| 74 | +} |
| 75 | +'@ | Out-File -FilePath c:\test.pssc |
| 76 | +
|
| 77 | +$isstate = [initialsessionstate]::CreateFromSessionConfigurationFile('C:\test.pssc') |
| 78 | +[runspacefactory]::CreateRunspace($isstate) |
| 79 | +
|
| 80 | +Id Name ComputerName Type State Availability |
| 81 | + -- ---- ------------ ---- ----- ------------ |
| 82 | + 4 Runspace4 localhost Local BeforeOpen None |
| 83 | +``` |
| 84 | + |
| 85 | +So it is currently possible to create a configured PowerShell runspace through the PowerShell API. |
| 86 | +But what most users want is a way to configure PowerShell from the command line, so that when running `pwsh.exe`, a PowerShell shell starts with the desired configuration. |
| 87 | + |
| 88 | +### PowerShell Server Mode |
| 89 | + |
| 90 | +The PowerShell executable, `pwsh.exe`, can be started in 'server mode' by including the non-public `-S` command line switch. |
| 91 | +In this mode, PowerShell does not present a console window and prompt for command line input. |
| 92 | +Instead, it runs a listener on the process standard input stream, listening for remoting protocol (PSRP) messages, and sending protocol message responses on the process standard output stream. |
| 93 | +In this way PowerShell functions as a remoting endpoint for PowerShell remoting connections. |
| 94 | +PowerShell's `job`, `named pipe`, and `SSH` remoting connections all use PowerShell in server mode as an endpoint to connect to. |
| 95 | +In addition, the new [Custom Remote Connections feature](https://github.com/PowerShell/PowerShell-RFC/blob/master/Archive/Draft/RFC0063-Custom-Remote-Connections.md), will also use PowerShell in server mode for a remoting endpoint. |
| 96 | + |
| 97 | +However, PowerShell in server mode has no way to configure the session and currently runs in its normal 'default' configuration. |
| 98 | + |
| 99 | +### PowerShell `-ConfigurationFile` Command Line Switch |
| 100 | + |
| 101 | +The main proposal of this RFC is to add a new command line switch to `pwsh.exe` that takes an optional file path string to a PowerShell configuration (.pssc) file. |
| 102 | +This file would then be used to configure the default session runspace with the contained configuration information. |
| 103 | +The new command line switch would make configuring PowerShell running in server mode very easy. |
| 104 | + |
| 105 | +For example, a PowerShell SSH connection endpoint is created by setting up a SSH 'subsystem' that runs `pwsh.exe`. |
| 106 | +Multiple PowerShell remoting endpoints could be created by using the new `-ConfigurationFile` command line switch: |
| 107 | + |
| 108 | +sshd_config file: |
| 109 | + |
| 110 | +```powershell |
| 111 | +... |
| 112 | +# override default of no subsystems |
| 113 | +#Subsystem sftp sftp-server |
| 114 | +# PowerShell endpoint configurations |
| 115 | +Subsystem powershell1 /opt/microsoft/powershell/7/pwsh -S -NOLOGO -ConfigurationFile /etc/ssh/PSConfig1.pssc |
| 116 | +Subsystem powershell2 /opt/microsoft/powershell/7/pwsh -S -NOLOGO -ConfigurationFile /etc/ssh/PSConfig2.pssc |
| 117 | +... |
| 118 | +``` |
| 119 | + |
| 120 | +### Windows/WinRM Configuration Elements |
| 121 | + |
| 122 | +Unfortunately, some of the configuration elements supported in a .pssc configuration file is for Windows/WinRM remote connections only. |
| 123 | +For example, `virtual` and `group managed` accounts are Windows platform only. |
| 124 | +And JEA role definitions are based on Windows platform accounts and groups. |
| 125 | + |
| 126 | +We want to separate Windows/WinRM specific configuration elements from what PowerShell supports implicitly. |
| 127 | +The new `-ConfigurationFile` command line switch and policy setting will support PowerShell configurations only, and will throw a terminating error if unsupported WinRM/Windows configurations are specified. |
| 128 | + |
| 129 | +The following are Windows/WinRM configuration elements that will **not** be supported for local sessions: |
| 130 | + |
| 131 | +```powershell |
| 132 | +RunAsVirtualAccount |
| 133 | +RunAsVirtualAccountGroups |
| 134 | +GroupManagedServiceAccount |
| 135 | +RoleDefinitions |
| 136 | +RequiredGroups |
| 137 | +PowerShellVersion |
| 138 | +``` |
| 139 | + |
| 140 | +### PowerShell Configuration Elements |
| 141 | + |
| 142 | +The following are configuration elements that **will** be supported: |
| 143 | + |
| 144 | +```powershell |
| 145 | +SessionType |
| 146 | +TranscriptDirectory |
| 147 | +MountUserDrive |
| 148 | +UserDriveMaximumSize |
| 149 | +ScriptsToProcess |
| 150 | +LanguageMode |
| 151 | +ExecutionPolicy |
| 152 | +ModulesToImport |
| 153 | +VisibleAliases |
| 154 | +VisibleCmdlets |
| 155 | +VisibleFunctions |
| 156 | +VisibleExternalCommands |
| 157 | +VisibleProviders |
| 158 | +AliasDefinitions |
| 159 | +FunctionDefinitions |
| 160 | +VariableDefinitions |
| 161 | +EnvironmentVariables |
| 162 | +TypesToProcess |
| 163 | +FormatsToProcess |
| 164 | +AssembliesToLoad |
| 165 | +``` |
| 166 | + |
| 167 | +## Alternate Design Options |
| 168 | + |
| 169 | +### PowerShell `SessionConfiguration` Policy Setting |
| 170 | + |
| 171 | +Additional to the `-ConfigurationFile` command line switch, session configuration could also be settable via Windows Group Policy or PowerShell configuration file. |
| 172 | +The policy session configuration would be specified by either a configuration file path or a string defining the configuration. |
| 173 | + |
| 174 | +```powershell |
| 175 | +HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PowerShellCore\SessionConfiguration |
| 176 | + ConfigurationFile REG_SZ 'C:\Windows\System32\PowerShell\v7.2.3\SessionConfig.pssc' |
| 177 | + ConfigurationHash REG_SZ '@{ SchemaVersion = "2.0.0.0"; GUID = "eaa72cae-fafe-4d3d-bf65-84ff02d58fd9"; ...}' |
| 178 | +``` |
| 179 | + |
| 180 | +### PowerShell `-Configuration` Command Line Switch |
| 181 | + |
| 182 | +A possible variation is to also include a `-Configuration` command line that takes a text string containing session configuration information in PowerShell hash table format. |
| 183 | +But this seems less useful, since configurations can be very complex. |
| 184 | + |
| 185 | +```powershell |
| 186 | +C:\> pwsh.exe -Configuration '@{SessionType = "Default"; ...}' |
| 187 | +``` |
| 188 | + |
| 189 | +### Configuration Through Application Control Policies |
| 190 | + |
| 191 | +Another idea is to extend this ability to specify a machine wide PowerShell session configuration to Application Control policies. |
| 192 | +For example, the Windows WDAC (Windows Defender Application Control) policy could include the ability to specify a .pssc file used for PowerShell sessions when the system has WDAC polices enforced. |
0 commit comments