1. 程式人生 > >Win10 Ubuntu子系統設定Git伺服器和SSH Server 證書登入,實現win10和macOS原始碼同步

Win10 Ubuntu子系統設定Git伺服器和SSH Server 證書登入,實現win10和macOS原始碼同步

首先是安裝Win10的Ubuntu子系統,如果沒有,可以看到我另外一篇博文的相關內容:

Visual Studio Code 與 Win10 64bit Ubuntu bash 的ESP8266 編譯開發環境搭建(無需編譯toolchain)

1. 設定Git伺服器

首先右鍵點選開始按鈕-”執行“-"bash",進入Ubuntu bash命令列

如果沒有安裝過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
[email protected]:/mnt/f$ sudo mkdir gitRepo
[email protected]:/mnt/f$ cd gitRepo
[email protected]
:/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埠,先點選右下角工作列的盾牌,彈出的對話方塊中選擇 “防火牆和網路保護”- “高階設定”

然後點選“入站規則”-“新建規則”

選擇埠

然後選擇 “TCP”-“特定本地埠”,輸入888

選擇“允許連線”

視情況勾選何時應用規則,作為家裡的nas,我都選了。 

然後輸入名稱和描述

 

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”,開啟服務對話方塊

然後雙擊OpenSSH Authentication Agent服務,將其改為“自動”即可。

 

然後新增金鑰。

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://[email protected]/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://[email protected]/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://[email protected]/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. 多使用者許可權管理,這個不在本文討論了。