背景介绍
目标: 在一台RHEL8 Linux主机配置一个Git Server(不采用GitLab),这样别的电脑可以连接到它上面并把该主机作为一个Remote Repository。
准备:
两台电脑: 1台RHEL8作为服务器,另一台Linux或者Mac,作为客户端
操作概要:
- 服务器端创建一个新用户,命名为git,稍后客户端将使用此用户名登陆。
- 客户端运行ssh-keygen命令生成用于SSH登陆的私钥和公钥,并把公钥保存到服务器上以实现客户端可以通过SSH Key文件方式远程登录到服务器, 因为稍后的git push和pull操作都需要通过SSH连接实现。
- 服务器端创建一个bare型git repo
- 客户端创建一个local repo并执行各种git 操作保存文件。 添加远程repo,成功后就可以实现远程操作了。
具体操作
1. 服务器端添加一个新用户git
# useradd git sudo useradd git useradd: cannot open /etc/passwd
原因: passwd文件以及shadown文件都被系统锁定,防止被删除或更改。需要先解锁这两个文件才可以继续创建新用户:
# use lsattr Command view /etc/passwd Hidden permissions $ lsattr /etc/passwd ----i--------------- /etc/passwd # i: Can't be deleted or changed sudo chattr -i /etc/passwd # -i : remove i, +i: add i
同样操作适用于/etc/shadow文件,都去掉i属性后,就可以创建新用户了,用户名git,密码随意,因为我们稍后不会再使用用户名密码方式登陆服务器。
# useradd git sudo useradd git # create user 'git' sudo passwd git # update password for new user 'git'
创建并修改完密码后就可以锁定上述两个文件了, 使用参数‘+i’:
sudo chattr +i /etc/passwd # -i : remove i, +i: add i sudo chattr +i /etc/shadow # -i : remove i, +i: add i
2.客户端生成用于SSH登陆的私钥和公钥
客户端Mac或Linux 命令行运行ssh-keygen命令生成用于SSH登陆的私钥和公钥。可以使用默认的私钥名称id_rsa, 也可以自己重新命名。生成的公钥文件名是'私钥.pub'格式以方便区分。如果客户端本地之前运行过ssh-kengen命令,也可以复用某个私钥公钥对,不过建议重新生成一组新的,并给予清晰命令以方便后续识别或移除。
执行完该命令后打开生成的公钥文件,里面是一段文本,这段文本稍后需要复制到远端服务器上。
以git用户名登陆到远端服务器后,在git用户home目录下/home/git检查是否存在.ssh文件夹,不存在,则创建,并修改属性为700,只允许git用户访问此文件夹
cd /home/git mkdir .ssh chmod 700 git
之后cd进入.ssh文件夹,查看是否存在名为authorized_keys的文件,不存在则创建并修改文件属性为600。之后编辑此文件,将客户端生成的公钥文件添加到此文件。
权限问题: 网上搜索文章都推荐设置.ssh文件夹和authorized_keys文件夹属性为700和600,经过我RHEL8测试,authorized_keys不能有执行权限,否则会导致无法登陆,报错“Received disconnect from xx: Too many authentication failures”。.ssh文件夹倒是要求不高,我试过不同数值755等都不影响登陆。如果出现该错误,请注意检查此两处的权限设置是否正确。推荐设置为700和600来降级系统风险。
nano authorized_keys
3. 服务器端创建一个bare型git repo
以git用户名登陆服务器,在home目录下创建一个文件夹用来保存repo文件。这里我们操作如下:
cd /home/git mkdir gitrepos cd gitrepos mkdir test.git # 采用一个明显的文件夹名用来区分各个repo cd test.git git init --bare # --bare 参数很重要
执行完毕后, /home/git/gitrepos/test.git文件夹下就生成了一堆文件,已经可以接受客户端的push了,如下所示:
[git@localhost test.git]$ ls -al total 12 drwxrwxr-x. 7 git git 119 Oct 15 00:00 . drwxrwxr-x. 3 git git 22 Oct 14 23:58 .. drwxrwxr-x. 2 git git 6 Oct 14 23:58 branches -rw-rw-r--. 1 git git 66 Oct 14 23:58 config -rw-rw-r--. 1 git git 73 Oct 14 23:58 description -rw-rw-r--. 1 git git 23 Oct 14 23:58 HEAD drwxrwxr-x. 2 git git 241 Oct 14 23:58 hooks drwxrwxr-x. 2 git git 21 Oct 14 23:58 info drwxrwxr-x. 7 git git 60 Oct 15 00:00 objects drwxrwxr-x. 4 git git 31 Oct 14 23:58 refs
4. 客户端创建一个local repo并执行各种git 操作保存文件
这个就是git的常规操作了,简单记录如下:
mkdir testlocalgit cd testlogcalgit git init nano README.txt git add . git commit -m "Init Commit with README file"
之后重点来了,给此repo添加Remote, 采用SSH方式连接,注意要和服务器上的repo路径一致。
# 添加远端Repo git add remote origin ssh://git@192.../home/git/gitrepos/test.git # push 本地repo到服务器上对应的远端Repo: git push origin master
讨论
本地客户端SSH配置以运行多个不同用户连接和Key文件
实际工作中常遇到的如下两种情况:
- 一台工作电脑可能要SSH连接到不同的服务器上,为了安全,每个服务器连接时会产生一对不同的私钥和公钥文件。
- 对于同一个远端服务器,可能需要使用不同用户名进行登陆链接,比如一个是git用户用于git repo操作,另一个是普通用户,用于执行其他各种操作,为了安全起见,分别给他们创建了不同的私钥和公钥文件。
针对上述两种情况,就需要对客户端的SSH进行配置。搜索了一下,找到了几个参考链接:
SSH config使用教程和总结, ssh配置文件详解.
官方手册可以通过如下命令查询:
man ssh_config ssh(1) obtains configuration data from the following sources in the following order: 1. command-line options # 命令行参数,如-p 10086, -i /path/to/identity_file 等选项来设置SSH的端口号或认证证书位置 2. user's configuration file (~/.ssh/config) # 针对某个用户的配置文件,所在路径为~/.ssh/config,默认是不存在的,需要手动创建 3. system-wide configuration file (/etc/ssh/ssh_config) # 针对系统所有用户的配置文件,,所在路径为/etc/ssh/ssh_config For each parameter, the first obtained value will be used.
注意看最后一行,对于同一个参数在上面1,2,3多处有不同取值时,第一个获取的参数值为有效。因此上面3个方式的优先级也是 1 > 2 > 3。这里我主要记录通过第2种方式来配置本地的SSH连接,也就是修改本地的~/.ssh/ssh_config文件。打开该文件后,可以发现它里面包含多个Host 代码块,每个Host块就是一个匹配规则。具体格式如下:
Host alias1 # 机器别名 HostName 192.168.1.2 # 主机地址 User root # 用户名 IdentityFile ~/.ssh/id_ecdsa # 认证文件 Port 22 Host alias2 HostName 192.168.1.3 Port 9002 User Jones
上面解释的已经比较清楚了,机器别名特别好用,可以节省好多打字 😃
上面例子中,alias1 代码块里指定了用户名,ip地址,私钥文件地址,因此,一个繁琐的标准命令:
ssh -i ~/.ssh/id_ecdsa root@192.168.1.2
就可以用如下简单命令代替, 是不是很方便?容易区分还不容易出错。
ssh alias1
有了别名,我们就可以通过给不同服务区使用不同别名,或者给同一个服务器的不同用户分配一个不同别名alias,再分别 ssh alias 就可以了。例如
Host LocalGit # 机器别名 HostName 192.168.2.123 # 主机地址 User git # 用户名是git IdentityFile ~/.ssh/id_ecdsa # 认证文件 Port 22 Host LocalUser # 机器别名 HostName 192.168.2.123 # 主机地址 User tom # 用户名tom IdentityFile ~/.ssh/tom_key # 认证文件 Port 22
就可以通过如下两个短命令进行访问。
ssh LocalGit ssh LocalUser
同样的,如果使用了别名,那么上面在添加Git远程仓库的时候,就可以对应地直接使用别名:
# 添加远端Repo git add remote origin ssh://git@192.../home/git/gitrepos/test.git # 添加远端Repo git add remote origin ssh://LocalGit/home/git/gitrepos/test.git