Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步

首先是安装Win10的Ubuntu子系统,如果没有,可以看到我另外一篇博文的相关内容:

Visual Studio Code 与 Win10 64bit Ubuntu bash 的ESP8266 编译开发环境搭建(无需编译toolchain)

1. 设置Git服务器

首先右键点击开始按钮-”运行“-"bash",进入Ubuntu bash命令行

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第1张图片

如果没有安装过git,那么安装一下:

$ sudo apt install git

然后添加一个git用户, 输入 sudo adduser git

$ sudo adduser git

然后根据提示输入密码

Adding user `git' ...
Adding new group `git' (1001) ...
Adding new user `git' (1001) with group `git' ...
Creating home directory `/home/git' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for git
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n] y

然后把git用户加入sudo组,切换到git用户,那么当前目录就是/home/git

$ sudo  usermod -aG sudo git
$ su - git

 先切换到非系统盘,既然是重要的代码数据,那么就不要放在默认的C盘,因为Ubuntu的用户目录是在系统盘下的。

比如我放在F盘的gitRepo目录,然后初始化一个空的仓库 (例如smartlight.git)

$ cd /mnt/f
git@DESKTOP-JF56RKP:/mnt/f$ sudo mkdir gitRepo
git@DESKTOP-JF56RKP:/mnt/f$ cd gitRepo
git@DESKTOP-JF56RKP:/mnt/f/gitRepo$ sudo git init --bare smartlight.git
[sudo] password for git:
Initialized empty Git repository in /mnt/f/gitRepo/smartlight.git/

更改目录所有者

sudo chown -R git:git smartlight.git

2. SSH Server证书登录设置

创建一个用户主目录下的.ssh文件夹并切换到这个文件夹 

$ cd ~
$ mkdir .ssh
$ cd .ssh

收集所有需要登录的用户的公钥(id_rsa.pub)文件,把所有公钥导入到 /home/git/.ssh/authorized_keys 文件内,一行一个。如果没有公钥,那么在bash中可以直接创建:

 $ ssh-keygen -t rsa  -C"[email protected]"

然后把 id_rsa.pub文件复制为~/.ssh/authorized_keys文件 ,更改其权限为600

$ cp -a ./id_rsa.pub /home/git/.ssh/authorized_keys
$ sudo chmod 600 /home/git/.ssh/authorized_keys

id_rsa文件则复制到客户端那里。

以下是SSH Server服务器端设置:

默认情况下,安装了win10的Ubuntu子系统以后,Ubuntu 的SSH Server默认已经启动了,如果没有那么需要安装一下:

sudo apt install openssh-server

修改配置

sudo nano /etc/ssh/sshd_config

主要是以下几行,Port 默认为22,但是它会和Win10自带的Open SSH Server冲突,所以需要一个新的端口号,比如888(我没有找到停用windows默认ssh服务器或者更改其端口的方法),其中 PasswordAuthentication no 这一行可以先用默认的yes,等到测试成功了,再改为no,否则如果你是远程的机器没配置好然后登录不上,又没有别的办法进入shell,那就杯具了

Port 888
StrictModes no
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys
PasswordAuthentication no

修改完毕重启sshd服务

$ sudo service ssh restart

可能会提示:

Command 'service' is available in '/usr/sbin/service'
The command could not be located because '/usr/sbin' is not included in the PATH environment variable.
This is most likely caused by the lack of administrative privileges associated with your user account.

把 usr/sbin/加入当前用户的bashrc路径即可:

$nano ~/.bashrc

添加一行

export PATH=/usr/sbin:$PATH

然后source使其生效

$source ~/.bashrc

然后再次重启服务

$ sudo service ssh restart

然后还要在Win10 防火墙中建立一个入站规则,打开888端口,先点击右下角任务栏的盾牌,弹出的对话框中选择 “防火墙和网络保护”- “高级设置”

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第2张图片

然后点击“入站规则”-“新建规则”

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第3张图片

选择端口

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第4张图片

然后选择 “TCP”-“特定本地端口”,输入888

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第5张图片

选择“允许连接”

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第6张图片

视情况勾选何时应用规则,作为家里的nas,我都选了。 

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第7张图片

然后输入名称和描述

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第8张图片

 

3. 客户端设置 

macOS用户:

复制id_rsa到~/.ssh/目录下,配置/etc/ssh/ssh_config,添加一个Host,例如我的Server是nas,ip地址为192.168.1.234:

  Host nas
        HostName        192.168.1.234
        User git
        Port 888
        IdentityFile ~/.ssh/id_rsa

此时使用 ssh nas 即可使用ssh登录nas上的ssh server了。

win10用户:

a) Windows Ubuntu bash环境下,设置参考macOS用户。

b) Windows命令行下(cmd或power shell),输入ssh -V查看是否安装了OpenSSH客户端。我的win10专业版已经默认安装了OpenSSH客户端。

C:\Users\simonliu>ssh -V
OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5

然后同样在当前用户目录(C:\Users\simonliu>)下创建.ssh文件夹,将id_rsa复制到该文件夹下,并且创建一个名为config的文件(无后缀名),文件内容(注意最后一行需要修改为你的文件实际绝对路径)。因为我的Win10就是NAS本机,所以ip地址改为127.0.0.1或者localhost均可,你的具体情况具体分析哟。

  Host nas
        HostName        localhost
        User git
        Port 888
        IdentityFile C:/Users/simonliu/.ssh/id_rsa

然后运行ssh-agent 

C:\Users\simonliu\.ssh>ssh-agent

注意:

如果是Win10 1803版本,默认关闭了ssh-agent服务,运行ssh-agent可能会提示:

unable to start ssh-agent service, error :1058

解决方法:在左下角快速搜索栏中输入“Service”,打开服务对话框

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第9张图片

然后双击OpenSSH Authentication Agent服务,将其改为“自动”即可。

Win10 Ubuntu子系统设置Git服务器和SSH Server 证书登录,实现win10和macOS源码同步_第10张图片

 

然后添加密钥。

C:\Users\simonliu\.ssh>ssh-add id_rsa

如果生成密钥的时候设置了密码,这时需要输入密码 

Enter passphrase for id_rsa:
Identity added: id_rsa (id_rsa)

但是这只对一个shell的session有效,当你重启shell的一个新的session,就需要重新输入密码。如果你想一劳永逸,那么请看另外一篇博文,按照那篇博文设置之后,每次重启只需要输入一次密码即可,对新的shell session有效。

4. Git仓库的推送和克隆,实现win10和macOS源码同步

现在我的应用场景是:

i) nas 的Win10 Unbuntu子系统作为Git服务器,同时又是开发机,最初的源码都在nas上进行本地git版本管理。

ii) macOS刚搭建好了编译环境,但是没有源码,所以需要Git服务器进行版本管理和同步。

现在需要做两件事情:

a) 将nas每个项目源码的所有分支push到nas的Ubuntu Git server上

b) 在macOS将所有分支全部下载下来。

4.1 将nas每个项目源码的所有分支push到nas的Ubuntu git server上

        前面添加好了ssh-key以后,不论是在cmd命令行窗口,还是power shell,或者Visual Studio Code的Terminal窗口,都可以通过如下方式把一个项目的所有分支推送到Git Server的远程仓库上,我们前面已经初始化了一个仓库,位于 /mnt/f/gitRepo/smartlight.git/ 目录下。

那么本地先切换到smartlight的源码所在目录(例如 E:\Documents\Eclipseworkspace\smartlight),因为已经进行了git版本管理,所以需要先添加远程路径

E:\Documents\Eclipseworkspace\smartlight>git remote add origin ssh://git@nas/mnt/f/gitRepo/smartlight.git

然后一个命令即可将所有分支和标签推送过去:

E:\Documents\Eclipseworkspace\smartlight>git push --all origin

Option:如果你加入一个参数 -u,

git push --all origin -u

那么将会自动进行跟踪将来如果修改了多个分支,将来只需要git push就可以推送所有分支了。

git push

 

4.2 macOS 或者其他新机器获取Git服务器上的全部分支

注意,简单使用git clone 理论上已经获取远程的所有分支,但是如果你此时输入 git branch -a ,只能看到本地的master分支和remote的所有分支,如果你要在本地显示每个分支,需要分别checkout到相应的同名分支上。很遗憾git没有提供一个内置的功能让你一次性做这个事情,所以需要创建一个脚本。(以本人的macOS的zsh shell为例)。

4.2.1. 首先,在shell profile (~/.zshrc)里面建立一个函数gclone(),方便将来使用,使用函数是因为通常bash里的alias不支持传递参数:

function gclone(){
    git clone ssh://git@nas/mnt/f/gitRepo/$1.git
}

 4.2.2. 其次,source 使其生效。

>source ~/.zshrc 

4.2.3. 然后,在~/目录创建一个脚本gpa.sh (gpa是git pull all的缩写),内容是

#!/bin/zsh
git checkout master ;
remote=origin ;
for brname in ` git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}' `;
do
    git branch -D $brname ;
    git checkout -b $brname $remote/$brname ;
done ;
git checkout master

4.2.4. 给gpa.sh添加执行权限:

>chmod +x ~/gpa.sh

4.2.5. 现在开始克隆远程仓库,输入 gclone smartlight ,

这个函数命令相当于 git clone ssh://git@nas/mnt/f/gitRepo/smartlight.git 

>gclone smartlight

Cloning into 'smartlight'...
remote: Counting objects: 232, done.
remote: Compressing objects: 100% (177/177), done.
remote: Total 232 (delta 37), reused 232 (delta 37)
Receiving objects: 100% (232/232), 8.08 MiB | 4.90 MiB/s, done.
Resolving deltas: 100% (37/37), done.

4.2.6 然后切换到这个目录

>cd smartlight

4.2.7 运行gpa.sh即可

>gpa.sh

5. 我踩过的坑

中间踩过好多坑,现在大致说明一下:

1. Ubuntu无法使用SSH服务器默认22端口。因为Ubuntu和Win10两个系统都存在Open SSH Server服务,所以默认22端口被Win占用,折腾了好久才发现这个问题,改了Ubuntu的SSH端口为888才能连上。在入站规则里面默认有两个SSHD(TCP/UDP)的规则,居然是监听所有端口?还没法改?这是什么鬼。以后有空再研究吧。

2. 证书登录 Permission denied (publickey)错误,这个错误的可能性有很多,比如证书复制有问题,authorized_keys文件权限没有改为600等等。我在mac下折腾了很久登录不上,后来发现默认终端窗口可以,iTerm2不行,关掉iTerm2窗口以后重新打开又可以了,在这里来回折腾服务器设置浪费了2个小时。最后发现是ssh_config文件里面的id_rsa文件路径使用了相对路径,所以切换到别的目录的时候,是无法找到密钥文件登录成功的。默认终端窗口或者iTerm2新开的窗口,默认路径都是用户的主目录,所以能正确找到密钥文件。后来win下面的配置文件改为绝对路径,mac下的前面加上一个~(即用户主目录)就好了。

3. Windows下每次登陆或者访问Git Server都要求输入密码。只需要启用OpenSSH Authentication Agent服务,通过ssh-agent添加密钥即可。最开始用了ssh-agent命令,结果添加了key每次git push还要输入密码,然而ssh nas 这个命令又不需要。后来才发现需要运行start-ssh-agent才可以。但是如果要更好地解决输入密码问题,需要参看我的另外一篇博文 Win10 cmd命令行,Powershell,Linux子系统Ubuntu bash自动启动ssh-agent 。

4. 虽然 git clone 有一个 --mirror 参数,但是这个参数会让你完全复制 git server 的整个目录结构,它并不是你原先的工作目录结构。

6. 进一步的安全设置

作为本地的nas机器,其实没有太大必要。但是如果是远程机器,那么最好进行设置。

1. 在密钥生成之后可以把git的bash禁掉,可以通过编辑 /etc/passwd 文件完成。

git:x:1003:1003::/home/git:/bin/bash

改为

git:x:1003:1003::/home/git:/usr/bin/git-shell

这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

2. 多用户权限管理,这个不在本文讨论了。

你可能感兴趣的:(Git,Windows,Ubuntu,Linux)