• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 在 centOS 上配置 SSH 密钥认证自动登录

    密钥是一对,有公钥和私钥。公钥对数据进行加密而且只能用于加密,私钥只能对所匹配的公钥加密过的数据进行解密。

    • 服务端密钥(host key):远程服务器端,sshd 启动或者重启的时候,都会重新生成服务端密钥,包含服务端公钥和服务端私钥。
    • 客户端密钥(ssh key):本地客户端当前用户的密钥,需要使用 ssh-keygen 来手工生成。然后把客户端公钥,上传保存在服务上。


    当本机客户端的当前用户,向远程服务器端,发起 ssh 连接的时候。远程服务端 sshd 会把服务器端公钥(host key),发送给本地客户端,进行主机认证。当主机验证通过后,客户端将客户端当前用户的公钥 ID 发送给服务端,服务端在被请求使用的服务器中的用户的~/.ssh/authorized_keys中,查找客户端当前用户的公钥。若查找到一致的公钥内容,产生一个随机数,经过加密,再发送给客户端,客户端解密后,得到随机数。再使用协商密钥加密,返回给远程服务端。服务端经过解密得到的随机数,对比与发送出去的随机数,若一致,则验证身份验证通过,允许登录。


    密钥验证是使用本地当前用户的密钥进行验证,本地当前用户不同,密钥不同。密钥验证与本地当前用户密钥有关,需要远程服务器端被请求使用的用户的中,保存客户端当前用户的公钥,位置:~/.ssh/authorized_keys。不需要远程服务器端用户生成密钥。服务端密钥是有 sshd 进程生成。例如,登录远程服务端,使用服务端用户 git,因为是团队开发,所以客户端存在多人,分别在各自的本机上发起 SSH 连接请求,各自的当前用户不同,分别有 root、developer 等等,那么密钥验证只与本机客户端当前发起请求的用户密钥有关,服务器端用户 git 用户~/.ssh/authorized_keys中保存客户端公钥,服务端用户 git 不需要生成密钥。


    在远程服务器端中,用户种类:

    • root:系统超级用户,属于 root 组。禁止 ssh 登录远程服务器 shell。
    • admin:自定义管理员用户,属于 wheel 组。允许 ssh 登录远程服务器 shell。
    • developer:自定义普通用户,属于 develop 组。允许 ssh 登录远程服务器 shell。对项目程序代码文件,是所有者。scp、sftp 下载上传文件。
    • git:自定义普通用户,属于 develop 组。禁止 ssh 登录远程服务器 shell。对共享的 Git 仓库是所有者。Git 上传下载 Git 远程仓库。

    在本机客户端中,用户种类:

    • root:系统超级用户,属于 root 组。进入本机 ceonOS 时,默认使用的用户。为了个人方面,经常使用。


    配置密钥认证的前提条件:服务端 SSH 服务正常,sshd 进程启动。本地客户端,可以使用密码认证的方式 ssh 登录服务端。


    本地客户端 centOS 中,生成密钥

    使用当前用户来生成密钥。openssh 7.0+,默认使用 RSA 加密的密钥,已弃用 DSA 加密。

    # 若当前用户是 root
    ssh-keygen -t rsa -C "zhangsan_Pc_root"
    
    • -t:表示 ssh 的密钥类型,常用的有:rsa、ed25519、dss。
    • -C:注释或称名称标识,此值随意。是给产生的秘钥对加了一个注释,可当作不同密钥的标识,用来区分不同客户端。zhangsan_Pc_root:是客户端用户名+电脑+用户的格式。意思是,张三在台式电脑上,使用 root 用户登录。zhangsan_Mob_root:张三在笔记本电脑上,使用 root 用户登录。此用户名要与git config --global user.name "Your Name"保持一致,便于查看 git 历史记录。寻找来源。


    # 上面命令输入后出现的对话框:
    Enter file in which to save the key (/root/.ssh/id_rsa): # 直接回车
    Enter passphrase (empty for no passphrase):  # 直接回车
    Enter same passphrase again: # 直接回车
    
    • 第一个对话框,是选择密钥位置以及名称,若同一个用户下,针对不同远程服务器,而需要创建多个密钥的时候,则需要修改密钥名称,避免因重复覆盖掉以前的。
    • 第二给对话框,是让给密钥设置密码。第三个对话框是再次输入密码来确认。为了在以后使用此密钥的时候,不再输入密钥的密码。所以此处密码都留空,即可直接回车。即可生成密钥(ssh key)。


    # 查看生成的密钥。
    ls -al ~/.ssh
    
    • id_rsa:私钥文件,默认名称。
    • id_rsa.pub:公钥文件,默认名称。
    • config:客户端,用户配置文件。
    • known_hosts:客户端,用来储存主机认证的时候,远程服务器端发过来的服务器端公钥(host key)。

    若当前用户是 root,不需要设置权限,默认权限正合适。若当前用户不是 root,需要确保以下目录文件的属主和权限。

    • $HOME:属主是当前用户,目录权限必须为755drwxr-xr-x
    • .ssh:属主是当前用户,目录的权限700drwx------
    • id_rsa:属主是当前用户,文件权限600-rw-------
    • id_rsa.pub:属主是当前用户,文件权限644-rw-r--r--


    # 查看公钥
    cat ~/.ssh/id_rsa.pub
    


    本地客户端 centOS 中,保存主机名(可省略)

    本机客户端当前用户 ssh 配置,常用来配置 ssh 连接的时候,主机名以及密钥位置。便于输入 ssh 连接命令。

    # 在客户端用户配置
    vim ~/.ssh/config
    
    Host developerHost
        HostName 192.168.0.50
        Port 22
        User developer
        IdentityFile ~/.ssh/id_rsa
    

    注意:~/.ssh目录文件,应该属于当前用户自己。若使用 root 用户,修改其下用户的文件,会被改变文件所有者以及所属组,需要修改文件所有者。

    命令行配置,优先级别最高。然后是~/.ssh/config中配置,最后是/etc/ssh/ssh_config


    远程服务器端 centOS 中,保存公钥

    复制本地生成的公钥内容,添加到服务器端的~/.ssh/authorized_keys文件内,如果需要添加多个,则用换行进行隔开。

    ssh-copy-id 复制公钥

    # 给服务器端 lanmper 用户,传送本机 root 用户公钥
    ssh-copy-id -i ~/.ssh/id_rsa.pub lanmper@example.com
    
    # 给服务器端 developer 用户,传送本机 root 用户公钥
    ssh-copy-id -i ~/.ssh/id_rsa.pub developer@example.com
    
    • ssh-copy-id,命令工具,是安装 OpenSSH 的时候,也被自动安装上的。不需要另外安装。它的作用,是将客户端当前用户公钥内容填充到一个远程服务端的被请求使用的用户~/.ssh/authorized_keys文件中。
    • ssh-copy-id,也会给远程主机的用户主目录$HOME~/.ssh~/.ssh/authorized_keys目录文件不存在,会自动创建,会自动设置合适的权限
    • ssh-copy-id,如果不传入-i参数,使用默认公钥~/.ssh/id_rsa.pub
    • ssh-copy-id,会检查重复,若在远程主机中authorized_keys中,已经存在被复制的公钥,则不会重复写入,而且会给与提示信息。
    • ssh-copy-id,使用参数-f,会强制覆盖已经存在的公钥。
    • ssh-copy-id,当被请求使用的用户,在服务器端被禁止 ssh 登录 shell的时候,不能使用此办法。会报错:fatal: unrecognized command
    # 强制覆盖以前的公钥
    ssh-copy-id -f -i ~/.ssh/id_rsa.pub developer@example.com
    


    手工复制公钥

    还可以先手工复制本机客户端公钥字符串内容,然后 ssh 登录远程服务器端,手工写入服务端被请求使用用户的~/.ssh/authorized_keys中。

    # ssh 密码方式登录远程服务器端
    ssh developer@example.com
    

    ~/developer/.ssh目录不存在的时候,需要自己创建。

    cd ~/developer
    ls -al
    
    mkdir .ssh
    
    cd .ssh
    touch authorized_keys
    
    # 设置所有者,所属用户组
    chown -R developer:develop ~/developer
    
    # 添加公钥内容
    vim authorized_keys
    
    # 设置所有者,所属用户组
    chown -R developer:develop ~/developer
    


    权限设置

    手工添加完毕 developer 用户的公钥后,还需要确保响应的正确权限,防止权限错误,而导致 ssh 密钥验证失败。

    # 设置权限
    sudo chmod 700 .ssh
    sudo chmod 600 .ssh/authorized_keys
    

    $HOME,是当前用户主目录。比如 developer 用户,$HOME,即是/home/developer(可用~/developer访问)。

    • $HOME:目录权限必须为755drwxr-xr-x所有者必须是当前用户。一般不会被改变,不需要修改。
    • .ssh:目录的权限700drwx------
    • authorized_keys:文件权限644-rw-------


    从本机客户端远程 SSH 连接远程服务端

    在本机客户端中,使用 SSH 远程连接服务端。

    # 本地当前用户是 developer,那么下面请求方式,则相同。
    ssh -v developer@example.com
    ssh -v developer@192.168.0.50
    ssh -v developerHost
    
    # 强制使用公钥验证
    ssh -v -o PreferredAuthentications=publickey example.com
    
    • developer:以远程服务端上的 developer 用户,进行 SSH 连接。若省略,则使用本地当前用户。
    • example.com是服务端主机名,也可以是 IP 地址192.168.0.50,根据实际情况,自行修改。
    • developerHost:本机客户端的当前用户配置文件~/.ssh/config中,设置的被请求主机别名。推荐使用此简单方式,更方便。
    • -T:禁止为 ssh 分配伪终端。
    • -v:显示连接的详细信息,将输出 debug 消息,可用于调试。
    • -vvv:显示连接的更加详细信息,进入 ssh 调试模式,就可以看到 ssh 在连接过程中的那些步骤。
    • -o:指定额外选项,选项非常多。
    • PreferredAuthentications:配置登录时认证方式。默认值:publickey,gssapi-keyex,gssapi-with-mic,password。
      • publickey:基于公共密钥的安全验证方式,通过生成一组密钥的公钥来实现用户的登录验证。
      • password:通过输入用户名和密码的方式进行远程机器的登录验证。允许使用者储存了密码,那么如果你选择了记忆密码,就可以直接登录而不需要输入密码。
      • keyboard-interactive:基于键盘交互的验证方式,通过服务器向客户端发送提示信息,然后由客户端根据相应的信息通过手工输入的方式发还给服务器端。也就是说你必须要自己输入密码。若客户端保存了密码,以 xshell 为例,客户端会替你完成键盘输入密码的过程。所以键盘交互和密码连接基本无区别。只是服务端 ssh 日志记录上会有不同。此选项,在新版中,已经被遗弃