asp.net-mvcgithubiissshlibgit2sharp

How can I configure libgit2sharp ssh authentication within an IIS, ASP.NET MVC, C# application?


I am using libgit2sharp within an ASP.NET MVC application writtein in C# and running on IIS v.10.0 (Windows Server 2019). It is working well to execute git commands against the local server's git repository.

However, I also want to be able to push/pull to a remote repository (GitHub) using SSH authentication. Libgit2Sharp supports SSH since release 0.31.0 (yay!). But I'm struggling to make SSH authentication work in the context of a running IIS application.

The ASP.NET MVC application is running in its own IIS Application Pool in "Integrated" Managed Pipeline mode with .Net CLR version v4.0. The Application Pool name is (let's pretend) myorg-webapp. (The Application Pool name becomes the name of the IIS virtual user that the web app runs as.)


Solution

  • I finally found that the following configuration works:

    Prerequisites

    In my case, my git remote -v URLs look like:

        origin  ssh://git@github.com/MyOrganizationName/MyWebAppRepository.git (fetch)
        origin  ssh://git@github.com/MyOrganizationName/MyWebAppRepository.git (push)
    

    The SSH public and private keys are contained in the files myorg-webapp_id_rsa.pub and myorg-webapp_id_rsa, respectively, in the %USERPROFILE%\.ssh folder.

    My %USERPROFILE%\.ssh\config file contains the following:

    ServerAliveInterval 30
    ServerAliveCountMax 20
    # TCPKeepAlive no recommended by https://unix.stackexchange.com/a/616355
    TCPKeepAlive no
    ConnectionAttempts 5
    
    Host github.com
        HostName github.com
        User myorg-webapp
        IdentityFile ~/.ssh/myorg-webapp_id_rsa
        PreferredAuthentications publickey
    

    Working Configuration

    The key to making this work for the web app was ensuring that system-level SSH configuration files were set up correctly, and that private SSH key was configured to only allow access for the IIS Application Pool virtual user.

    The server's C:\ProgramData\ssh\ssh_known_hosts file contains the following (GitHub-specific):

    github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
    github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
    github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
    

    You can find GitHub's latest SSH key fingerprints here. (If you're connecting to some other remote Git repository, you should be able to find and copy host's SSH key fingerprints from your %USERPROFILE%\.ssh\known_hosts file to the C:\ProgramData\ssh\ssh_known_hosts file.

    The server's C:\ProgramData\ssh\ssh_config contains:

    KbdInteractiveAuthentication no
    PasswordAuthentication no
    
    Host github.com
        HostName github.com
        User myorg-webapp
        IdentityFile C:/Users/Public/ssh/myorg-webapp-id_rsa
        PreferredAuthentications publickey
    

    I created the C:/Users/Public/ssh/ folder and copied the myorg-webapp-id_rsa SSH private key file into that folder.

    Crucially, the permissions for the myorg-webapp-id_rsa file must be set to only allow access for the IIS App Pool virtual user:

    permissions for SSH private key file

    To configure the file in this way, you must:

    Windows Security Select Users or Groups Dialog

    Thanks to https://stackoverflow.com/a/36597241/1086134 for showing the right way to specify the IIS virtual user in the "Select Users or Groups" dialog.

    The IIS virtual user matches the name of your IIS Application Pool: IIS Manager Application Pool List


    To troubleshoot and finally arrive at the above configuration, I configured the global Git config file C:\Program Files\Git\etc\gitconfig as follows:

    # some stuff removed...
    
    [http]
        sslBackend = openssl
        sslCAInfo = C:/Program Files/Git/mingw64/etc/ssl/certs/ca-bundle.crt
    
    [core]
        autocrlf = true
        fscache = true
        symlinks = false
        sshCommand = C:/Windows/System32/OpenSSH/ssh.exe -E C:/Users/Public/ssh/ssh-client.log -v -v -v
    
    [credential]
        helper = manager
    
    [safe]
        directory = *
    
    # other stuff removed...
    

    In particular, setting sshCommand = C:/Windows/System32/OpenSSH/ssh.exe -E C:/Users/Public/ssh/ssh-client.log -v -v -v allowed me to inspect the ssh-client.log file to determine what ssh was attempting and where it was failing. (The log file reported "UNPROTECTED PRIVATE KEY FILE" until the C:/Users/Public/ssh/myorg-webapp-id_rsa file permissions were finally satisfactory.)

    Good luck!