近日用SSH连接服务器时候遇到一些问题,总结出这篇文章。
SSH介绍
简单说,SSH是一种网络协议,用于计算机之间的加密登录。SSH只是一种协议,存在多种实现,既有商业实现,也有开源实现。这里说的实现是OpenSSH。
SSH之所以能够保证安全,原因在于它采用了公钥加密。
整个过程是这样的:(1)远程主机收到用户的登录请求,把自己的公钥发给用户。(2)用户使用这个公钥,将登录密码加密后,发送回来。(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。
1、公钥是锁,私钥是钥匙,他们互相加密,互相解密(且是成对出现,只能一对一) 2、公钥加密,私钥解密。私钥做数字签名,公钥验证。 例1:A将自己的公钥发给了B,将一条信息用自己的私钥加密后发给B【私钥加密+Hash摘要≈数字签名】, B用A的公钥能够正确解密【解密】,证明这条消息确实是A发出的【认证】, 因为公钥和私钥是一一对应的,公钥正确解密且私钥只有A知道,所以可以认定是A发出的消息。 例2:B将一条信息用A的公钥加密后发给A,A用自己的私钥正确的解密了这条信息, 可以认定这条信息就是B发出的,因为只有A的私钥能解密。
SSH常用命令
1、远程连接主机
ssh user@remoteServer ssh user@remoteServer-p 2222 //p 参数指定端口号
2、远程运行Shell命令
ssh user@remoteServer "cmd1;cmd2" 多条命令间用分号分割
说明:连接到远程主机,并执行远程主机的command命令。例如:查看远程主机的硬盘和内存使用情况。
ssh root@remoteServer "df -h;free -h"
执行远程主机中的脚本,假设有一个脚本/home/user/a.sh,需要在本地操作远程机器执行脚本a.sh,需要执行:
ssh user@remoteServe "/home/test.sh"
注意指定脚本为全路径 如果要传参,则直接在脚本后加上参数即可,即:
ssh user@remoteServe "/home/test.sh hello world"
3、SSH自带的SFTP功能
sftp user@remoteServer //连接 put /localFile/A /remoteFile/B //将本地的A文件传到远程主机的B目录下 get /remoteFile/B /localFile/A //将远程主机的B文件下载到本地的A目录下 cd //切换远程主机目录 lcd //切换本地目录,其他基本命令都是这样,带l的是本地
4、常用的有关SSH命令
# 查询openssl软件 rpm -qa openssh openssl # 查询sshd进程 ps -ef | grep ssh # 查看ssh端口 netstat -lntup | grep ssh ss | grep ssh (效果同上,同下,好用) netstat -a | grep ssh(记住这个) netstat -lnt | grep 22 ==> 查看22端口有没有开/ssh服务有没有开启 技巧: netstat -lnt | grep ssh | wc -l -->只要大于2个就是ssh服务就是好的 # 查看ssh的秘钥目录 ll /root/.ssh/known_hosts # 当前用户家目录的.ssh目录下 # ssh的配置文件 cat /etc/ssh/sshd_config # ssh服务的关闭 service sshd stop # ssh服务的开启: service sshd start # ssh服务的重启 service sshd reload [停止进程后重启] ==> 推荐 service sshd restart [干掉进程后重启] ==> 不推荐 # ssh远程登录 ssh 192.168.1.100 # 默认利用当前宿主用户的用户名登录 ssh omd@192.168.1.100 # 利用远程机的用户登录 ssh omd@192.168.1.100 -o stricthostkeychecking=no # 首次登陆免输yes登录 ssh omd@192.168.1.100 "ls /home/omd" # 当前服务器A远程登录服务器B后执行某个命令 ssh omd@192.168.1.100 -t "sh /home/omd/ftl.sh" # 当前服务器A远程登录服务器B后执行某个脚本 # 本小节代码来源:https://www.cnblogs.com/ftl1012/p/ssh.html
5、SSH免密登录
点击此文:ssh免密码登录
SSH使用过程中常见报错
主要排查方向:防火墙、sshd服务、密码是否正确、是否禁止root用户登录、公钥问题、账户被锁。
1、WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
这种情况常见于服务器系统重装之后,服务器主机密钥发生变更,所以我们更新密钥即可:
ssh-keygen -R remoteServer
2、Permission denied, please try again.
出现这种报错呢,一可能是你输入的密码有误,二也有可能是在SSH安全策略中设置了root用户禁止登陆!改为:PermitRootLogin yes即可。详见此文:SSH连接报错:Permission denied, please try again.的解决方法
3、SSH用户被锁定
例如在Ubuntu上root等用户如果输错3次密码之后会被锁定,这时候就需要用到Pam_Tally2锁定和解锁用户了,详见此篇文章:
使用Pam_Tally2锁定和解锁SSH失败的登录尝试:
https://www.howtoing.com/use-pam_tally2-to-lock-and-unlock-ssh-failed-login-attempts/
4、Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
出现这个报错,一般来说我们的服务器的防火墙和sshd服务都是正常的,我们此时要排查下PubkeyAuthentication和PasswordAuthentication的值是否为yes,即公钥认证和密码认证都要为yes,看你是用什么方式连接的了!用grep命令搜索http://etc/ssh/sshd_config中的配置:
[root@admin]# egrep "PubkeyAuthentication" /etc/ssh/sshd_config #PubkeyAuthentication yes [root@admin]# egrep "PasswordAuthentication" /etc/ssh/sshd_config PasswordAuthentication no
可见,我们密码认证未开放,改为PasswordAuthentication yes即可。
另外,此种错误也有可能是公钥出问题了,我们将公钥放到服务器的~/.ssh/authorized_keys文件中便可。
5、忘记了SSH密码
这种情况很尴尬,如果你还能用root用户登录到SSH,然后passwd命令修改密码即可。
如果实在忘记了SSH密码,可以去服务器厂商的后台页面修改,以阿里云为例,是可以在控制台修改登录密码的: