Windows ssh/git Server

If you are developing software and are using Git on Windows 10 and don't want to push to github, gitlab, etc., you might find this useful. 

You can turn your Windows OS into a git server, by just configuring ssh access.


1. Add the features for OpenSSH (part of Windows 10)

Open Settings - Apps - Optional Features - Add a feature

and install "OpenSSH Server" and "OpenSSH client"



2. Create a git user

Create a user git, member of sshusers, who cannot change his password, who is active and whose password never expires.

Open Control Panel - Administrative Tools - Computer Management

Under System Tools - Local Users and Groups - Right click on Users - New User...



3. Configure the git user

Login with the git user and create the c:\Users\git\.ssh directory.

Inside, create the "authorized_keys" text file with your public ssh key and make it accessible only by user git.

Here is how to generate them if you don't have them yet (replace myuser with your username):

C:\>cd Users\myuser

C:\Users\myuser>mkdir .ssh

C:\Users\myuser>cd .ssh

C:\Users\myuser\.ssh>ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\myuser/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\myuser/.ssh/id_rsa.
Your public key has been saved in C:\Users\myuser/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:eQvCN29huOlevkadqB99LicDuYVxoa/dZB9i5NkXMYQ myuser@MY-PC
The key's randomart image is:
+---[RSA 2048]----+
|              o. |
|            .E o |
|           . .  o|
|     .   oo .. . |
|      o S +Oo.o .|
|       o O*+==oo.|
|        oo**o+o.o|
|       ..++.=oo .|
|       .oo+. =.  |
+----[SHA256]-----+

C:\Users\myuser\.ssh>dir
 Volume in drive C is Windows
 Volume Serial Number is 4A94-7934

 Directory of C:\Users\myuser\.ssh

19.11.2020  21:14    <DIR>          .
19.11.2020  21:14    <DIR>          ..
19.11.2020  21:14             1.679 id_rsa
19.11.2020  21:14               399 id_rsa.pub
               2 File(s)          2.078 bytes
               2 Dir(s)  188.401.049.600 bytes free

C:\Users\myuser\.ssh>

❕Important: Limit the access to your private key to your user only!

Leave the passphrase empty if you don't want to enter it on each git command.

Add the contents of id_rsa.pub to the previously mentioned authorized_keys.


4. Configure the git repositories directory

Either create a direcory, e.g. git, in the home directory of the git user: 

C:\>mkdir C:\Users\git\git

or add a sym link (shortcut) named "git", pointing to the desired location:

C:\>cd Users\git

C:\Users\git>mklink /D "C:\Users\git\git" "E:\git"


5. Configure the console client

By default, Windows uses its own console for SSH, which is really weird, when called from Unix/Linux devices. Fortunately, git comes with a bash console client for Windows and we can use it instead.

In the registry, under HKEY_LOCAL_MACHINE\SOFTWARE\OpenSSH, add String entry "DefaultShell" with value "C:\Program Files\Git\bin\bash.exe" (or wherever your git is installed).

Here is a reg file for this:



6. Configure the ssh daemon.

In sshd_config under C:\ProgramData\ssh\

Disable 2nd authorized_keys:

AuthorizedKeysFile	.ssh/authorized_keys

Allow access only to users from the group sshusers:

AllowGroups sshusers

Disable password authentication (use only ssh keys):

PasswordAuthentication no


7. Try SSH

C:\>ssh git@localhost

8. Try Git

Create a repository in the git repository dir:

E:\git>mkdir test.git

E:\git>cd test.git

E:\git\test.git>git init --bare
Initialized empty Git repository in E:/git/test.git/

E:\git\test.git>

Try to clone it:

D:\tmp>git clone git@localhost:git/test.git
Cloning into 'test'...
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is SHA256:blablablablablablablablablablablabla.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
warning: You appear to have cloned an empty repository.

D:\tmp>

And let's push something:

D:\tmp>cd test

D:\tmp\test>echo "test" > test.txt

D:\tmp\test>git add test.txt
warning: CRLF will be replaced by LF in test.txt.
The file will have its original line endings in your working directory

D:\tmp\test>git commit -a -m "test"
[master (root-commit) 3db3470] test
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

D:\tmp\test>git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 221 bytes | 221.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To localhost:git/test.git
 * [new branch]      master -> master

D:\tmp\test>

SSH with password authentication

In the steps above, I suggested to disable password authentication with ssh. Although it is not mandatory, there are many reasons for this, including:
- it's easier - you don't have to type and remember passwords
- it's more secure - avoiding brute force attacks