openssh服务
1 openssh详解1.1 什么是opensshOpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。SSH协议族可以用来进行远程控制, 或在计算机之间传送文件。而实现此功能的传统方式,如telnet(终端仿真协议)、 rcp ftp、 rlogin、rsh都是极为不安全的,并且会使用明文传送密码。OpenSSH提供了服务端后台程序和客户端工具,用来加密远程控件和文件传输
文章目录
1 openssh详解
1.1 什么是openssh
OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。SSH协议族可以用来进行远程控制, 或在计算机之间传送文件。而实现此功能的传统方式,如telnet(终端仿真协议)、 rcp ftp、 rlogin、rsh都是极为不安全的,并且会使用明文传送密码。OpenSSH提供了服务端后台程序和客户端工具,用来加密远程控件和文件传输过程中的数据,并由此来代替原来的类似服务
- 延伸:
- ssh协议有两个版本:
v1:基于CRC-32 做MAC,不安全; (一般用于实现主机认证)
v2:基于协议协商选择双方都支持的最安全的MAC机制
基于DH做密钥交换,基于RSA或DSA实现身份认证,从而实现无需输入账号面膜
客户端通过检查服务器端的主机秘钥来判断是否能够继续通信; - 认证方式:
1、基于口令的认证
2、基于密钥的认证
- ssh协议有两个版本:
1.2 为什么要使用openssh
由于传统的telnet、rcp ftp等工具是明文传输数据的,对数据安全性存在很大的安全隐患,而OpenSSH可以对传输的数据进行加密从而大大提高了数据的安全性
1.3 openssh工作原理
openSSH是基于C/S架构工作的
服务器端 //sshd,配置文件在/etc/ssh/sshd_config
客户端 //ssh,配置文件在/etc/ssh/ssh_config
ssh-keygen //密钥生成器
ssh-copy-id //将公钥传输至远程服务器
scp //跨主机安全复制工具
- 服务器建立公钥: 每一次启动 sshd 服务时,该服务会主动去找 /etc/ssh/ssh_host* 的文件,若系统刚刚安装完成时,由于没有这些公钥,因此 sshd 会主动去计算出这些需要的公钥,同时也会计算出服务器自己需要的私钥
- 客户端主动联机请求: 若客户端想要联机到 ssh 服务器,则需要使用适当的客户端程序来联机,包括 ssh, putty 等客户端程序连接
- 服务器传送公钥给客户端: 接收到客户端的要求后,服务器便将第一个步骤取得的公钥传送给客户端使用 (此时应是明码传送,反正公钥本来就是给大家使用的)
- 客户端记录并比对服务器的公钥数据及随机计算自己的公私钥: 若客户端第一次连接到此服务器,则会将服务器的公钥记录到客户端的用户家目录内的 ~/.ssh/known_hosts 。若是已经记录过该服务器的公钥,则客户端会去比对此次接收到的与之前的记录是否有差异。若接受此公钥, 则开始计算客户端自己的公私钥
- 回传客户端的公钥到服务器端: 用户将自己的公钥传送给服务器。此时服务器:具有服务器的私钥与客户端的公钥,而客户端则是: 具有服务器的公钥以及客户端自己的私钥,你会看到,在此次联机的服务器与客户端的密钥系统 (公钥+私钥) 并不一样,所以才称为非对称加密系统
- 开始双向加解密: (1)服务器到客户端:服务器传送数据时,拿用户的公钥加密后送出。客户端接收后,用自己的私钥解密 (2)客户端到服务器:客户端传送数据时,拿服务器的公钥加密后送出。服务器接收后,用服务器的私钥解密,这样就能保证通信安全
1.4 OpenSSH程序简介
1.4.1 OpenSSH的分为客户端和服务端两部分
Clients端的配置文件:/etc/ssh/ssh_config
Server端的配置文件:/etc/ssh/sshd_config
Server端服务脚本:/etc/rc.d/init.d/sshd
OpenSSH在Linux系统中默认是安装并启动的
-
openssh 主要的关键包
openssh.x86_64 5.3p1-104.el6 //服务端和客户端的公共组件
openssh-askpass.x86_64 5.3p1-104.el6 //
openssh-clients.x86_64 5.3p1-104.el6 //客户端安装包
openssh-server.x86_64 5.3p1-104.el6 //服务端安装包 -
openssl-clients 几个常用文件
/etc/ssh/ssh_config //客户端配置文件
/usr/bin/scp //远程复制文件
/usr/bin/sftp //远程文件共享
/usr/bin/slogin
/usr/bin/ssh
/usr/bin/ssh-add
/usr/bin/ssh-agent
/usr/bin/ssh-copy-id
/usr/bin/ssh-keyscan -
openssl-server 几个常用文件
/etc/rc.d/init.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd
1.4.2 服务器端配置文件/etc/ssh/sshd_config 主要参数详解
服务端配置文件是让别人登陆时使用的,配置文件中使用“#”注释掉的一般就是使用默认
参数 | 说明 |
---|---|
#Port 22 | 默认端口号,为了其安全一般要更改为其他端口 |
#AddressFamily any | 说明要监听任意地址 |
#ListenAddress 0.0.0.0 | 监听本机所有IPV4的ip |
#ListenAddress :: | 监听本机所有的IPV6的地址 |
#LoginGraceTime 2m | 登陆宽限时长 默认2分钟不登录自动关闭 |
#PermitRootLogin yes | 是否支持管理员直接登陆 |
#MaxAuthTries 6 | 最大尝试次数 (6次以后终端断开) |
#MaxSessions 10 | 最大并发允许链接数 (超过 将拒绝) |
#RSAAuthentication yes | 是否支持RSA密钥认证 |
#PubkeyAuthentication yes | 是否支持公钥认证 |
#AuthorizedKeysFile .ssh/authorized_keys | 默认保存口令的文件 |
#PermitEmptyPasswords no | 是否支持空密码登陆 |
1.4.3 客户端配置文件/etc/ssh/ssh_config 主要参数详解
客户端配置文件时登陆别人的ssh使用的
参数 | 说明 |
---|---|
#Host * | 表示连接所有主机 |
#Port 22 | 默认连接端口 |
#Cipher 3des | 加密时使用的加密机制 |
#StrictHostKeyChecking ask | 严格的主机秘钥检查 即第一次连接时是否询问 |
1.5 口令认证
以服务器中本地系统用户的登录名称、密码进行验证。从客户机的角度看,正在连接的服务器有可能被假冒;从服务器角度来看,当遭遇密码穷举攻击时防御能力较弱
- client端向server端发去连接请求
- server接受请求并向client端发送自己的主机公钥
- client输入密码,并使用server端公钥加密后发送给server(敏感信息安全传输)
- server接受加密的密码,使用私钥解密,匹配认证密码是否合法。合法则登录成功。
1.6 密钥对认证
首先客户端上的用户会在客户端生成一对密钥,并将自己的公钥上传到远程服务器上面(一般在对应用户的home目录下),自己保留私钥信息,之后在我们使用ssh命令远程登录服务器的时候,只需要我们输入远程服务器上面对应的用户名,而不需要再输入密码就可以进行登录
- 客户端生成一对密钥,并将公钥上传至服务端(~/.ssh/authorized_keys)
- 客户端请求连接,包含主机名和当前用户
- 服务端从authorized_keys中查找是否有用户信息,如果有则向客户端发送一段随机字符串,并用客户端的公钥进行加密
- 客户端用自己的私钥对随机字符串进行解密,并返还给服务端
- 服务端将解密后的字符串与之前发送的字符串进行比对,如一致则验证通过
公钥(Public Key)与私钥(Privtae Key)的关系
公钥与私钥是成对生成,这两个密钥互不相同,可以互相加密与解密。
不能根据一个密钥来推算出另一个密钥。
公钥对外公开,私钥只有私钥的持有人才知道。
公钥与私钥要配对使用,如果用公钥对数据进行加密,只有用相对就的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密
1.7 SSH知识总结
1.7.1 SSH的加密技术
加密技术:传输过程,数据加密。
1.SSH1没有对客户端的秘钥进行校验,很容易被植入恶意代码
2.SSH2增加了一个确认联机正确性的Diffe_Hellman机制,每次数据的传输,Server都会检查数据来源的正确性,避免黑客入侵。
SSH2支持RSA和DSA密钥
DSA:digital signature Algorithm 数字签名
RSA:既可以数字签名又可以加密
1.7.2 SSH常识
- SSH是安全的加密协议,用于远程连接Linux服务器
- SSH的默认端口是22,安全协议版本是SSH2
- SSH服务器端主要包含2个服务功能SSH连接和SFTP服务器
- SSH客户端包含ssh连接命令和远程拷贝scp命令等
1.7.3 如何防止SSH登录入侵
- 自定义 SSH 服务配置
[root@node1 ~]# cat /etc/ssh/sshd_config
PermitRootLogin {yes|no} //是否允许root用户远程登录系统
PermitRootLogin without-password //仅允许root用户基于密钥方式远程登录
PasswordAuthentication {yes|no} //是否启用密码身份验证,默认开启
- SSH 安全注意事项
- 密码应该经常换且足够复杂
[root@node1 ~]# tr -dc A-Za-z0-9_ < /dev/urandom | head -c 30 | xargs //生成30位的密码
oTchjzhwEZK5s7XCQ50Fnj9r0vX7gQ
[root@node1 ~]# openssl rand 20 -base64 //生成20位随机密码
Di9ry+dyV40xVvBHirsc3XpBOzg=
-
使用非默认端口,修改默认端口为其他端口)
-
限制登录客户端地址
-
仅监听特定的IP地址
-
禁止管理员直接登录
-
仅允许有限制用户登录
AllowUsers:允许登陆的用户白名单 (多个用户使用空格隔开)
AllowGroups:允许登陆的组的白名单 -
使用基于密钥的认证
-
禁止使用空密码
-
禁止使用SSHv1版本
-
设定空闲会话超时时长
-
利用防火墙设置ssh访问策略
-
限制ssh的访问频度和并发在线数
-
做好日志的备份,经常分析(集中于某台服务器)
2 登录验证方式
1、ssh的基本语法
ssh [OPTIONS] [user]@server [COMMAND]
-l user: 以指定用户身份连接至服务器;默认使用本地用户为远程登录时的用户;
ssh user@server
ssh -l user server
-p PORT:指明要连接的端口
-X 启用X11Forwarding,即转发X界面的请求;
-x: 禁用;
-Y: 启用信任的X11Forwarding
2、ssh 基于秘钥的认证
ssh-keygen语法:
ssh-keygen [OPTIONS]
-t {rsa|dsa} 密钥类型 一般使用rsa
-b # 指明密钥长度
-f /PATH/TO/OUTPUT_KEYFILE 指明密钥文件
-P '' :指明加密密钥的密码,表示使用空密码
2.1 密码验证(口令认证)
2.1.1 准备两台虚拟机,一台作为客户端,一台作为服务端,用客服端远程连接服务端
[root@node1 ~]# ssh root@192.168.25.110 ##root为服务端的用户,##192.168.25.110为服务端地址
The authenticity of host '192.168.25.110 (192.168.25.110)' can't be established.
ECDSA key fingerprint is SHA256:GnK28SJbU4C8Op2rmLAg5lcSBpfM/oeTUSmq0QkfdJY.
ECDSA key fingerprint is MD5:5a:a5:35:49:b5:d0:1d:ce:f0:16:8a:b6:68:f2:d9:3d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.25.110' (ECDSA) to the list of known hosts.
root@192.168.25.110's password: ##输入root用户的密码
[root@node2 ~]$ ##此时由客户端成功连接到服务端
2.1.2 修改服务端ssh服务的配置文件,对客服端远程登录进行限制
[root@node2 ~]# vim /etc/ssh/sshd_config
37 LoginGraceTime 2m
38 PermitRootLogin no ##不允许root用户登录
39 StrictModes yes
40 MaxAuthTries 6 ##最大失败连接次数
41 MaxSessions 10
42 AllowUsers tom ##只允许tom用户远程登录,相当于白名单
[root@node2 ~]# systemctl restart sshd ##修改完配置文件需重启服务
2.1.3 客户端登录权限的验证
[root@node1 ~]# ssh harry@192.168.25.110
harry@192.168.25.110's password:
Permission denied, please try again. ##用harry用户登录,权限被拒
[root@node1 ~]# ssh root@192.168.25.110
root@192.168.25.110's password:
Permission denied, please try again. ##用root用户登录,权限被拒
[root@node1 ~]# ssh tom@192.168.25.110
tom@192.168.25.110's password:
Last login: Thu Jul 9 11:27:11 2020 from 192.168.25.110
[tom@node2 ~]$ ##tom用户成功远程连接
##注意:虽然root用户被禁止远程登录,但可通过tom用户作为中间用户来进行切换,只要知道root用户的密码就可以##
[tom@node2 ~]$ su - root
Password: ##输入root的密码##
Last login: Thu Jul 9 11:42:12 CST 2020 on pts/0
Last failed login: Thu Jul 9 11:54:05 CST 2020 from 192.168.25.110 on ssh:notty
There was 1 failed login attempt since the last successful login.
[root@node2 ~]# ##成功由tom用户切换为root用户
##如要解决此bug需要在服务端开启pam认证,不给tom用户使用su命令切换用户的权限##
[root@node2 ~]# vim /etc/pam.d/su
1 #%PAM-1.0
2 auth sufficient pam_rootok.so
3 # Uncomment the following line to implicitly trust users in the "wheel" group.
4 #auth sufficient pam_wheel.so trust use_uid
5 # Uncomment the following line to require a user to be in the "wheel" group.
6 auth required pam_wheel.so use_uid ##把此行的注释去掉
7 auth substack system-auth
8 auth include postlogin
9 account sufficient pam_succeed_if.so uid = 0 use_uid quiet
10 account include system-auth
11 password include system-auth
12 session include system-auth
13 session include postlogin
14 session optional pam_xauth.so
###修改为后再用tom用户进行切换就没有权限了
[root@node1 ~]# ssh tom@192.168.25.110
tom@192.168.25.110's password:
Last login: Thu Jul 9 11:55:02 2020 from 192.168.25.110
[tom@node2 ~]$ su - root
Password:
su: Permission denied
[tom@node2 ~]$
2.2 密钥对验证
-
用户可通过使用公钥身份验证进行ssh登录身份验证。ssh允许用户使用私钥-公钥方案进行身份验证。这意味着将生成私钥和公钥这两个密钥。私钥文件用作身份验证凭据,像密码一样,必须妥善保管。公钥复制到用户希望登录的系统,用于验证私钥。公钥并不需要保密。拥有公钥的ssh服务器可以发布仅持有您私钥的系统才可解答的问题。因此,可以根据所持有的密钥进行验证。如此一来,就不必在每次访问系统时键入密码,但安全性仍能得到保证。
-
使用ssh-keygen命令生成密码。将会生成私钥/.ssh/id_rsa和公钥/.ssh/id_rsa.pub
-
生成ssh密钥后,密钥将默认存储在家目录下的.ssh/目录中。私钥和公钥的权限就分别为600和644。.ssh目录权限必须是700。
2.2.1 在客户机中创建密钥对
ssh-keygen命令
可用的加密算法:RSA、ECDSA、DSA
[root@node1 ~]# ssh-keygen -t rsa ## -t 指定加密算法类型 ##生成密钥对
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): ##定义保存的密钥文件名
Enter passphrase (empty for no passphrase): ##输入私钥密码##
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa. ##说明已经生成密钥
Your public key has been saved in /root/.ssh/id_rsa.pub. ##说明已经生成公钥
The key fingerprint is:
SHA256:ch19XvS7ehReEWc36P+ViQ3C08fGyvWlnXpIOt5I3WA root@node2
The key's randomart image is:
+---[RSA 3072]----+
| .o*|
| . . +=|
| o + + +|
| . = * O+|
| . S . +E%+O|
| o o=+O=|
| .o.+oo|
| .ooo.o.|
| .o.oo |
+----[SHA256]-----+
2.2.2 将公钥文件上传到服务器中目标用户的公钥库
[root@node1 ~]# ssh-copy-id root@192.168.25.111
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.25.111 (192.168.25.111)' can't be established.
ECDSA key fingerprint is SHA256:hQUryG5gU8B+A5iKi8iBZzTLWRvN1dosOSu7LxPrR5Y.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.25.111's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.25.111'"
and check to make sure that only the key(s) you wanted were added.
2.2.3 客户端使用密钥对验证登录
[root@node1 ~]# ssh root@192.168.25.111
Last login: Sat Sep 25 15:59:31 2021 from 192.168.25.110
3 scp远程复制
使用scp命令可以利用SSH安全连接与远程主机相互复制文件。使用scp命令时,除了必须指定复制源、目标外,还应指定目标主机地址、登录用户,执行后提示验证口令即可
语法:
scp [OPTIONS] SRC…DEST
常用选项:
-r: 递归复制,复制目录及内部文件时使用;
-p: 保存源文件元数据信息中的属主、属组及权限;
-q: 静默模式
-P PORT: 指明远程服务器使用的端口
两种模式:
PUSH: scp [OPTIONS] /PATH/FROM/SOMEFILE … user@server:/PATH/TO/DEST
//复制本地文件至远程主机 (但远程目录一定要有写权限)
PULL: SCP [OPTIONS] user@server:/PATH/FROM/SOMEFILE /PATH/TO/DEST
//远程目标主机文件至本地
//将服务端的test文件传送到远程主机
[root@server ~]# ls
anaconda-ks.cfg test2
[root@server ~]# scp -p /root/test2 root@192.168.58.20:/opt/
test2 100% 0 0.0KB/s 00:00
[root@node1 ~]#
//到node2 查看
[root@client~]# ls /opt/
data test2
//复制远程主机/etc/fstab至服务端当前目录下
//在创建一个testing.txt的文件
[root@client ~]# touch testing.txt
[root@client ~]# ls
anaconda-ks.cfg testing.txt
//在server,将client的testing cp到当前目录中来
[root@server ~]# scp root@192.168.58.20:/root/testing.txt ./
testing.txt 100% 0 0.0KB/s 00:00
[root@server ~]# ls
anaconda-ks.cfg test2 testing.txt
[root@node1 ~]#
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)