一、使用密钥对无密码登录Linux服务器

1. 用ssh-keygen生成密钥对

为了减少文件移动操作,建议在客户端操作。

ssh-keygen -t rsa

建议不要输入密码passphrase, 一直按enter就好了。
如果不指定文件名,会生成 id_rsa(私钥), id_rsa.pub(公钥)两个文件。

Tips:
注意,如果这里指定了密钥文件名,需要使用-i参数指定密钥文件名去登录,不然会出现“Permission denied (publickey)”错误。 也可以使用配置文件 ~/.ssh/config进行配置,见本文后面。

2 将上面生成的公钥追加到主服务器~/.ssh/authorized_keys文件

推荐通过ssh的工具套装ssh-copy-id操作,也可以使用ftp工具/scp命令。

# ssh-copy-id方式,注意-i参数指定的是私钥文件名。
# 会自动生成公钥追加到服务器上的authorized_keys文件中。可能你需要输入服务器的密码。
ssh-copy-id -i ~/.ssh/id_rsa user@serverA

# 也可以用熟悉的scp/ftp等方式,不过需要两个步骤,还要登录服务器,要麻烦很多。
scp id_rsa.pub user@serverA:~/.ssh/id_rsa.pub
cat id_rsa.pub >> ~/.ssh/authorized_keys

复制后id_rsa.pub可删除掉。

3. 设置恰当的文件夹权限

登录主机,如下设置恰当的文件夹权限并用ll命令确认。

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# 设置多个用户时,注意用户的home目录权限不能太高,否则会导致不能登录。最高755,建议700
sudo chmod 755 /home/username

注意:如果不设置正确的文件/文件夹权限,登录时会出现密钥未注册的错误。
如果想探究出错原因,参考Xshell “所选的用户密钥未在远程主机上注册,请再试一次”SSH 登录远程linux服务器(良心整理)

4. 设置密钥登录功能

4.1 修改设置

编辑/etc/ssh/sshd_config 文件,进行如下设置:

# 注意 Ubuntu 20之后,RSAAuthentication和PubkeyAuthentication 即使没有设置,也是默认yes的。
RSAAuthentication yes
PubkeyAuthentication yes
# root 用户需要注意能否通过 SSH 登录:
PermitRootLogin yes

4.2 重启ssh服务

sudo service sshd restart

4.3 验证设置是否正确

ssh user@[服务器A地址]

如果不需要输入密码实现远程ssh登录,说明设置正常完成。

Tips:
以密钥方式登录成功后,建议在/etc/ssh/sshd_config中禁用密码登录,以增强服务器安全性:
PasswordAuthentication no

5. 简化密钥登录–密钥对登录进阶版

如果使用了自定义的密钥文件文件名,或者使用了多个密钥对,或者用了其它SSH端口,还是建议使用配置文件来操作,让主机登录更加方便简单。

5.1 配置文件格式

1)文件名及位置

配置文件位置和文件名是固定的:~/.ssh/config

2)文件内容

格式如下,文件里面可以指定多个登录名。

Host {登录名}
    Hostname {主机名或者IP}
    User {登录用户名}
    Port {端口,不指定的话默认22}
    IdentityFile {不指定的话默认为:~/.ssh/id_rsa}
    ServerAliveInterval  {向对象主机多长时间间隔发送信号以保持持续的连接,默认0,不发信号}

例子

Host devChia
    HostName 192.168.2.9
    User chia
    Port 22
    IdentityFile ~/.ssh/id_rsa_P2_db_2022
    ServerAliveInterval  60
Host xxxserver
  HostName ssh123.xxxserver.jp
  User xxxserver-abcxyz
  Port 2222
  IdentityFile ~/.ssh/id_rsa

5.2 登录方法

# 格式: ssh SSH主机
# 例子:
ssh devChia
# 退出登录主机
exit

6. 问题处理

6.1 用-vT参数输出详细日志

如果不能正常连接到对象主机,使用下列命令查看详细日志,找到问题原因。比如连接时出现了Permission denied (publickey)错误。如下输出详细日志:

# 例子:
ssh -vT devChia
ssh -vT -i ~/.ssh/id_rsa_002 user2@host1

输出例子:

$ ssh -vT user1@192.168.2.17
OpenSSH_8.2p1 Ubuntu-4ubuntu0.5, OpenSSL 1.1.1f  31 Mar 2020
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files
debug1: /etc/ssh/ssh_config line 21: Applying options for *
debug1: Connecting to 192.168.2.17 [192.168.2.17] port 22.
debug1: Connection established.
debug1: identity file /home/chia/.ssh/id_rsa type 0
debug1: identity file /home/chia/.ssh/id_rsa-cert type -1
debug1: identity file /home/chia/.ssh/id_dsa type -1
debug1: identity file /home/chia/.ssh/id_dsa-cert type -1
debug1: identity file /home/chia/.ssh/id_ecdsa type -1
debug1: identity file /home/chia/.ssh/id_ecdsa-cert type -1
debug1: identity file /home/chia/.ssh/id_ecdsa_sk type -1
debug1: identity file /home/chia/.ssh/id_ecdsa_sk-cert type -1
debug1: identity file /home/chia/.ssh/id_ed25519 type -1
debug1: identity file /home/chia/.ssh/id_ed25519-cert type -1
debug1: identity file /home/chia/.ssh/id_ed25519_sk type -1
debug1: identity file /home/chia/.ssh/id_ed25519_sk-cert type -1
debug1: identity file /home/chia/.ssh/id_xmss type -1
debug1: identity file /home/chia/.ssh/id_xmss-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5
debug1: Remote protocol version 2.0, remote software version OpenSSH_8.2p1 Ubuntu-4ubuntu0.5
debug1: match: OpenSSH_8.2p1 Ubuntu-4ubuntu0.5 pat OpenSSH* compat 0x04000000
debug1: Authenticating to 192.168.2.17:22 as 'nftdigger'
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: ecdsa-sha2-nistp256
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ecdsa-sha2-nistp256 SHA256:w6NV9hj/avlBdUFUJYeE7q/OzN6UAP5khoUgFJFTV+M
debug1: Host '192.168.2.17' is known and matches the ECDSA host key.
debug1: Found key in /home/chia/.ssh/known_hosts:8
debug1: rekey out after 134217728 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey in after 134217728 blocks
debug1: Will attempt key: /home/chia/.ssh/id_rsa RSA SHA256:GbYXlP1n9XOue+8ublJwr7gmYnjHtEuQ/k71roOxl/I
debug1: Will attempt key: /home/chia/.ssh/id_dsa 
debug1: Will attempt key: /home/chia/.ssh/id_ecdsa 
debug1: Will attempt key: /home/chia/.ssh/id_ecdsa_sk 
debug1: Will attempt key: /home/chia/.ssh/id_ed25519 
debug1: Will attempt key: /home/chia/.ssh/id_ed25519_sk 
debug1: Will attempt key: /home/chia/.ssh/id_xmss 
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,sk-ssh-ed25519@openssh.com,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,ecsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ecdsa-sha2-nistp256@openssh.com>
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering public key: /home/chia/.ssh/id_rsa RSA SHA256:GbYXlP1n9XOue+8ublJwr7gmYnjHtEuQ/k71roOxl/I
debug1: Authentications that can continue: publickey
debug1: Trying private key: /home/chia/.ssh/id_dsa
debug1: Trying private key: /home/chia/.ssh/id_ecdsa
debug1: Trying private key: /home/chia/.ssh/id_ecdsa_sk
debug1: Trying private key: /home/chia/.ssh/id_ed25519
debug1: Trying private key: /home/chia/.ssh/id_ed25519_sk
debug1: Trying private key: /home/chia/.ssh/id_xmss
debug1: No more authentication methods to try.
nftdigger@192.168.2.17: Permission denied (publickey).

看上述详细日志倒数第二行,No more authentication methods to try.说明当前密钥文件在对象主机没有匹配的公钥文件。

6.2 验证密钥文件对应的公钥内容

使用-y 参数,可以输出私钥文件对应的公钥内容。-f选项指定私钥文件名。本选项可以验证密钥对公私钥是否配对。
格式:ssh-keygen -y -f {私钥文件名}

# 例子:
ssh-keygen -y -f id_rsa_P2_db_2022

查看 jks的公钥 和md5_文件名

二、SCP无密码拷贝服务器文件

一旦按照第一节完成密钥对登录服务器操作之后,就可以方便使用scp命令无密码存取操作主服务器的文件了。

scp @[host]:/source_path/source_file /local_path/
# 或者
scp [登录名]:/source_path/source_file /local_path/

附录:通过脚本自动升级程序

#!/bin/sh
# 杀死所有正运行程序
pid=`ps -ef | grep need_upgrade_process | grep -v 'grep' | awk '{print $2}'`
echo $pid

for id in $pid
do
    kill -9 $id
    echo "killed $id"
done
echo '杀死了所有相关程序'
# 从主服务器复制最新版程序到本地指定目录
scp [host]:/source_path/source_file /local_path/
cd /local_path
# 后台启动
nohup ./need_upgrade_process &
echo '启动完成'
ps -ef|grep need_upgrade_process

参考:

  1. ssh 免密码登录 实现scp跨服务器拷贝文件
  2. ssh-keygen之后,生成的密码都叫id_rsa.pub,我想改名不行吗?
  3. ssh官网文档–ssh-keygen
  4. ssh官网帮助–config文件