4.4 伺服器上的 Git - 配置伺服器

牧之丨發表於2024-07-23

配置伺服器

我們來看看如何配置伺服器端的 SSH 訪問。 本例中,我們將使用 authorized_keys 方法來對使用者進行認證。 同時我們假設你使用的作業系統是標準的 Linux 發行版,比如 Ubuntu。 首先,建立一個作業系統使用者 git,併為其建立一個 .ssh 目錄。

Note

以下操作可透過 ssh-copy-id 命令自動完成,這樣就不必手動複製並安裝公鑰了。

首先,建立一個作業系統使用者 git,併為其建立一個 .ssh 目錄。

$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys

接著,我們需要為系統使用者 gitauthorized_keys 檔案新增一些開發者 SSH 公鑰。 假設我們已經獲得了若干受信任的公鑰,並將它們儲存在臨時檔案中。 與前文類似,這些公鑰看起來是這樣的:

$ cat /tmp/id_rsa.john.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L
ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k
Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez
Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv
O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq
dAv8JggJICUvax2T9va5 gsg-keypair

將這些公鑰加入系統使用者 git.ssh 目錄下 authorized_keys 檔案的末尾:

$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys

現在我們來為開發者新建一個空倉庫。可以藉助帶 --bare 選項的 git init 命令來做到這一點,該命令在初始化倉庫時不會建立工作目錄:

$ cd /srv/git
$ mkdir project.git
$ cd project.git
$ git init --bare
Initialized empty Git repository in /srv/git/project.git/

接著,John、Josie 或者 Jessica 中的任意一人可以將他們專案的最初版本推送到這個倉庫中, 他只需將此倉庫設定為專案的遠端倉庫並向其推送分支。 請注意,每新增一個新專案,都需要有人登入伺服器取得 shell,並建立一個裸倉庫。 我們假定這個設定了 git 使用者和 Git 倉庫的伺服器使用 gitserver 作為主機名。 同時,假設該伺服器執行在內網,並且你已在 DNS 配置中將 gitserver 指向此伺服器。 那麼我們可以執行如下命令(假定 myproject 是已有專案且其中已包含檔案):

# on John's computer
$ cd myproject
$ git init
$ git add .
$ git commit -m 'initial commit'
$ git remote add origin git@gitserver:/srv/git/project.git
$ git push origin master

此時,其他開發者可以克隆此倉庫,並推回各自的改動,步驟很簡單:

$ git clone git@gitserver:/srv/git/project.git
$ cd project
$ vim README
$ git commit -am 'fix for the README file'
$ git push origin master

透過這種方法,你可以快速搭建一個具有讀寫許可權、面向多個開發者的 Git 伺服器。

需要注意的是,目前所有(獲得授權的)開發者使用者都能以系統使用者 git 的身份登入伺服器從而獲得一個普通 shell。 如果你想對此加以限制,則需要修改 /etc/passwd 檔案中(git 使用者所對應)的 shell 值。

藉助一個名為 git-shell 的受限 shell 工具,你可以方便地將使用者 git 的活動限制在與 Git 相關的範圍內。 該工具隨 Git 軟體包一同提供。如果將 git-shell 設定為使用者 git 的登入 shell(login shell), 那麼該使用者便不能獲得此伺服器的普通 shell 訪問許可權。 若要使用 git-shell,需要用它替換掉 bash 或 csh,使其成為該使用者的登入 shell。 為進行上述操作,首先你必須確保 git-shell 的完整路徑名已存在於 /etc/shells 檔案中:

$ cat /etc/shells   # see if git-shell is already in there. If not...
$ which git-shell   # make sure git-shell is installed on your system.
$ sudo -e /etc/shells  # and add the path to git-shell from last command

現在你可以使用 chsh <username> -s <shell> 命令修改任一系統使用者的 shell:

$ sudo chsh git -s $(which git-shell)

這樣,使用者 git 就只能利用 SSH 連線對 Git 倉庫進行推送和拉取操作,而不能登入機器並取得普通 shell。 如果試圖登入,你會發現嘗試被拒絕,像這樣:

$ ssh git@gitserver
fatal: Interactive git shell is not enabled.
hint: ~/git-shell-commands should exist and have read and execute access.
Connection to gitserver closed.

此時,使用者仍可透過 SSH 埠轉發來訪問任何可達的 git 伺服器。 如果你想要避免它,可編輯 authorized_keys 檔案並在所有想要限制的公鑰之前新增以下選項:

no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty

其結果如下:

$ cat ~/.ssh/authorized_keys
no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4LojG6rs6h
PB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4kYjh6541N
YsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9EzSdfd8AcC
IicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myivO7TCUSBd
LQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPqdAv8JggJ
ICUvax2T9va5 gsg-keypair

no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQDEwENNMomTboYI+LJieaAY16qiXiH3wuvENhBG...

現在,網路相關的 Git 命令依然能夠正常工作,但是開發者使用者已經無法得到一個普通 shell 了。 正如輸出資訊所提示的,你也可以在 git 使用者的主目錄下建立一個目錄,來對 git-shell 命令進行一定程度的自定義。 比如,你可以限制掉某些本應被伺服器接受的 Git 命令,或者對剛才的 SSH 拒絕登入資訊進行自定義,這樣,當有開發者使用者以類似方式嘗試登入時,便會看到你的資訊。 要了解更多有關自定義 shell 的資訊,請執行 git help shell

相關文章