Skip to content

Security protection of various files in Win32 OpenSSH

Manoj Ampalam edited this page May 15, 2017 · 28 revisions

Secure protection of keys and config files

Starting with the release of v0.0.13.0, Win32-OpenSSH ensures any configuration and key files are secure before they are loaded.

Specifically, following permission checks are enforced:

  • User specific resources on client side -
    • User's private keys should not be accessible to other users.
    • User's ssh_config (%userprofile%.ssh\config) should not be accessible to other users.
    • Ex. ssh would fail to use the following private key for userA, since "someotheruser" also has access.
c:\>icacls userkey
userkey  userA(F)
         someotheruser(R) 
  • User specific resources on server side - authorized_keys
    • Should not be accessible to other users.
    • "NT Service/sshd" can only have (R) access.
    • Ex. sshd would not respect the following authorized_keys for userA, since "someotheruser" also has access.
c:\>icacls authorized_keys 
authorized_keys   NT SERVICE\sshd:(R)
                  userA(F)
                  someotheruser(R) 
  • Host specific resources on server side - host private keys
    • Should not be owned by a non-admin user
    • Should not be accessible to any non-admin user
    • "NT Service/sshd" can only have (R) access.
    • Ex. sshd would not respect the following host key, since "nonadmin" has access.
c:\>icacls hostkey 
hostkey   NT SERVICE\sshd:(R)
          admin(F)
          nonadmin(R) 

Tips to adjust permissions

icacls

You could use icacls to add / remove permissions on a given file Ex. you could do the following to fix permissions on user's private key file

c:\>icacls userkey
userkey  userA(F)
         someotheruser(R) 
c:>icacls userkey /remove someotheruser
c:\>icacls userkey
userkey  userA(F)

You could also user the following PowerShell based routines to help with adjusting permissions

Set-SecureFileACL

Set-SecureFileACL removes inherited ACLs on a file, assigns the current user as an owner (unless the -Owner parameter is specified), and grants the owner Full Control of the file:

function Set-SecureFileACL
{
    param(
        [string]$FilePath,
        [System.Security.Principal.NTAccount]$Owner = $null
        )

    $myACL = Get-ACL -Path $FilePath
    $myACL.SetAccessRuleProtection($True, $True)
    Set-Acl -Path $FilePath -AclObject $myACL

    $myACL = Get-ACL $FilePath
    $actualOwner = $null
    if($owner -eq $null)
    {
        $actualOwner = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
    }
    else
    {
        $actualOwner = $Owner
    }

    $myACL.SetOwner($actualOwner)

    if($myACL.Access)
    {
        $myACL.Access | % {
            if(-not ($myACL.RemoveAccessRule($_)))
            {
                throw "failed to remove access of $($_.IdentityReference.Value) rule in setup "
            }
        }
    }

    $objACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
        ($actualOwner, "FullControl", "None", "None", "Allow")
    $myACL.AddAccessRule($objACE)
    Set-Acl -Path $FilePath -AclObject $myACL
}

Example: Setting the owner of authorized_keys

$user = "<myusername>"
$objUser = New-Object System.Security.Principal.NTAccount($user)
Set-SecureFileACL -filepath $env:systemdrive\Users\$user\.ssh\authorized_keys -owner $objUser

Add-PermissionToFileACL

Add-PermissionToFileACL grants an user a file permission to access a file.

function Add-PermissionToFileACL
{
    param(
        [string]$FilePath,
        [System.Security.Principal.NTAccount] $User,
        [System.Security.AccessControl.FileSystemRights]$Perm)

    $myACL = Get-ACL $filePath
    $objACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
        ($User, $perm, "None", "None", "Allow")
    $myACL.AddAccessRule($objACE)
    Set-Acl -Path $filePath -AclObject $myACL
}

Example: Grants NT Service\sshd Read permission to a host public key file

Add-PermissionToFileACL -FilePath "$hostKeyFilePath -User "NT Service\sshd" -Perm "Read"

Managing keys and config files end-to-end for Win32-OpenSSH

Generating new keys using v0.0.13.0

If you've generated your host or user keys with ssh-keygen.exe after build v0.0.13.0, the user you've used to generated them will be the owner and have Full Control access. However, some files will still require some ACL modification.

  1. If the generated keys (both private and public) are going to be used as host keys, you must grant NT Service\sshd Read access:
Add-PermissionToFileACL -FilePath $hostKeyFilePath -User "NT Service\sshd" -Perm "Read"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User "NT Service\sshd" -Perm "Read"
  1. On the server running sshd, grant NT Service\sshd Read access to authorized_keys in ~\.ssh\:
$user = '<myusername>'
$userProfilePath = "$env:systemdrive\Users\$user"
Add-PermissionToFileACL -FilePath "$userProfilePath\.ssh\authorized_keys" -User "NT Service\sshd" -Perm "Read"
  1. On the client machine, if an user has a ssh_config at ~\.ssh\config, make sure that the user is the owner and has Full Control:
Set-SecureFileACL '~\.ssh\config'

Transitioning existing keys and files to v0.0.13.0

If you have host or user keys that were generated before build v0.0.13.0, you'll need to secure those key files before using them v0.0.13.0 or later.

The keys generated by ssh-keygen.exe before v0.0.13.0 inherit permissions from the parent folder. That means that some disallowed accounts may also have access to the file.

  1. On the server running sshd, change the file permission of the private host key to set the current user as owner and grant current user Full Control and NT Service\sshd Read access.
Set-SecureFileACL -FilePath $hostPrivateKeyFilePath
Add-PermissionToFileACL -FilePath $hostPrivateKeyFilePath -User "NT Service\sshd" -Perm "Read"
  1. On the server running sshd, grant NT Service\sshd Read access to the public host key:
Add-PermissionToFileACL -FilePath $hostPublicKeyFilePath -User "NT Service\sshd" -Perm "Read"
  1. Before using a user key file with ssh-add, scp, ssh, or sftp, make sure that the file is owned by the user, and that the user has Full Control.
Set-SecureFileACL -FilePath $userPrivateKeyFilePath
  1. On the server running sshd, change the file permission of authorized_keys in a user's home directory to set the current user as owner and grant the current user Full Control and NT Server\sshd Read access.
$user = '<myusername>'
$userProfilePath = "$env:systemdrive\Users\<user>"
$objUser = New-Object System.Security.Principal.NTAccount($user)
Set-SecureFileACL "$userProfilePath\.ssh\authorized_keys" -owner $objUser
Add-PermissionToFileACL -FilePath "$userProfilePath\.ssh\authorized_keys" -User "NT Service\sshd" -Perm "Read"
  1. On the client, if a user has their own ssh_config located at ~\.ssh\config, make sure that the user is the owner and has Full Control:
Set-SecureFileACL "~\.ssh\config"
Clone this wiki locally