openssh服务
简介
OpenSSH(secure shell)是在远程系统上安全运行的shell。ssh是通常用来远程登录到一个系统的命令(若在远程系统上存在相应账户);除此之外,ssh也可用于在远程系统中运行命令。
常见的远程工具一般有以下三种
- telnet
认证明文;数据传输明文;安全性差
- ssh
通信,认证及传输过程均是加密的
- dropbear
嵌入式系统专用的SSH服务器和客户端工具
SSH版本
- V1:基于CRC-32做MAC,无法防范中间人(man-in-middle)攻击
- V2:双方主机协议选择安全的MAC方式。基于DH算法做密钥交换,基于RSA或DSA算法实现身份认证
认证方式
- 基于口令(密码)认证
- 基于密钥认证
工作模式
openSSH基于C/S(client/server)架构工作
server------sshd,配置文件为/etc/ssh/sshd_config
client------ssh,配置文件为/etc/ssh/ssh_config
SSH应用实例
- 以当前本机用户身份登录指定地址远程系统中(需要本地主机和远程主机上均有同名用户,否则登录会失败)
查看本机IP地址,地址是192.168.43.128
[root@windfantasy ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.43.128 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::79b2:f4ad:870:5ae7 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:fe:fa:45 txqueuelen 1000 (Ethernet)
RX packets 201 bytes 19671 (19.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 106 bytes 11753 (11.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
远程登录到192.168.43.129地址的系统(登录的用户同样是root用户);需要正确输入远程系统root用户的登录密码才可成功登录
[root@windfantasy ~]# ssh 192.168.43.129
The authenticity of host '192.168.43.129 (192.168.43.129)' can't be established.
ECDSA key fingerprint is SHA256:/Vi7ogcocoHje9gh0Y453Y5/+sNRBD3upL5YL/3MLhU.
ECDSA key fingerprint is MD5:27:1a:16:34:ac:71:b8:0a:e5:ea:be:0f:f3:27:83:10.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.43.129' (ECDSA) to the list of known hosts.
[email protected]'s password:
Last login: Mon Jan 7 23:07:24 2019 from 192.168.43.1
再次查询ip地址,发现变为192.168.43.129,说明成功登录到远程系统中,登录用户是root
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.43.129 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::b1e9:ffe4:3818:8d33 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:c8:53:17 txqueuelen 1000 (Ethernet)
RX packets 62 bytes 8878 (8.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 63 bytes 10177 (9.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
退出远程系统,返回本机系统中
[root@localhost ~]# exit
logout
Connection to 192.168.43.129 closed.
查询IP地址,发现是192.168.43.128,成功返回到本地系统
[root@windfantasy ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.43.128 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::79b2:f4ad:870:5ae7 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:fe:fa:45 txqueuelen 1000 (Ethernet)
RX packets 309 bytes 32528 (31.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 226 bytes 28418 (27.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 以指定身份登录到指定远程主机上
查询本机IP地址
[root@windfantasy ~]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.43.128 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::79b2:f4ad:870:5ae7 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:fe:fa:45 txqueuelen 1000 (Ethernet)
RX packets 464 bytes 50434 (49.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 398 bytes 49379 (48.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
以远程系统中的tom用户登录到远程系统上
[root@windfantasy ~]# ssh [email protected]
[email protected]'s password:
查看IP地址及用户名,发现成功登录
[tom@localhost ~]$ ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.43.129 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::b1e9:ffe4:3818:8d33 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:c8:53:17 txqueuelen 1000 (Ethernet)
RX packets 194 bytes 22151 (21.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 167 bytes 23892 (23.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 以远程用户身份在远程主机上执行单次作业,执行完毕后,将结果输出到本地显示器,并自动返回到本机系统上
登录远程系统上的root用户,创建abc文件,并写入123;查看abc文件,将结果显示到本地显示器
[root@windfantasy ~]# ssh [email protected] 'echo 123 >abc;cat abc'
[email protected]'s password:
123
查看IP地址,发现仍在本机系统上
[root@windfantasy ~]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.43.128 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::79b2:f4ad:870:5ae7 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:fe:fa:45 txqueuelen 1000 (Ethernet)
RX packets 673 bytes 71793 (70.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 568 bytes 70796 (69.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
SSH主机密钥
- 原理
ssh通过公钥加密的方式保持通信安全。当某一ssh客户端连接到ssh服务器时,在该客户端登陆之前,服务器会向其发送公钥副本。这可用于为通信渠道设置安全加密,并可验证客户端的服务器。
当用户第一次使用ssh连接到特定服务器时,ssh命令可以在用户的/.ssh/known_hosts文件中存储该服务器的公钥。在此之后每当用户进行连接时,客户端都会通过对比/.ssh/known_hosts文件中的服务器条目和服务器发送的公钥,确保从服务器获得相同的公钥。若公钥不匹配,客户端会假定网络通信已遭劫持或服务器已被入侵,并且中断连接。
这意味着,若服务器的公钥发生更改(比如硬盘出现故障导致公钥丢失,或正常替换公钥后),用户则需要更新其~/.ssh/known_hosts文件并删除旧的条目才能够进行登录。
- 密钥配置
用户可通过使用公钥身份验证进行ssh登录身份证。ssh允许用户使用私钥-公钥方案进行身份验证。这意味着将生成私钥和公钥这两个密钥。私钥文件用作身份验证凭据,像密码一样,需妥善保管。公钥复制到用户希望登录的系统,用于验证私钥。公钥并不需要保密。拥有公钥的ssh服务器可以发布仅持有私钥的系统才可解答的问题。因此,可以根据所持有的密钥进行验证。从而可以不必在每次访问系统时键入密码,且安全性仍可得到保证。
使用ssh-keygen命令即可生成私钥(/.ssh/id_rsa)和公钥(/.ssh/id_rsa.pub)
另外,私钥也可单独设置密码,使安全性进一步提升
生成密钥后,其默认存储在家目录下的.ssh/目录中。私钥和公钥的权限是600和644;.ssh目录权限是700.
- 实例
配置密钥,密钥类型选择rsa;私钥文件名保持默认,且不对其配置密码
[root@windfantasy ~]# ssh-keygen -t rsa
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:y7z/2MmMZDZTxybKfpm4s4Qy9TE2nOGRYYVy+IQHQsM root@windfantasy
The key's randomart image is:
+---[RSA 2048]----+
| o+ .+oo. |
| Eo+.=o |
| *+ |
| o.+ . |
| S O o + |
| + * * + |
| o = @. o |
| o BoO+. |
| ..B** |
+----[SHA256]-----+
查看家目录下的.ssh目录,发现已成功生成公钥和私钥
[root@windfantasy ~]# ls .ssh/
id_rsa id_rsa.pub
将公钥拷贝到远程主机上,输入远程主机密码,已完成认证
[root@windfantasy ~]# ssh-copy-id [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.43.129 (192.168.43.129)' can't be established.
ECDSA key fingerprint is SHA256:/Vi7ogcocoHje9gh0Y453Y5/+sNRBD3upL5YL/3MLhU.
ECDSA key fingerprint is MD5:27:1a:16:34:ac:71:b8:0a:e5:ea:be:0f:f3:27:83:10.
Are you sure you want to continue connecting (yes/no)? 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
[email protected]'s password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
完成后,远程登陆主机,发现无需输入密码,直接登陆,密钥验证成功
[root@windfantasy ~]# ssh [email protected]
Last login: Mon Jan 7 23:08:04 2019 from 192.168.43.128
[root@localhost ~]# ls .ssh/
authorized_keys
- scp命令运用(远程传输文件)
将本地的文件拷贝到远程主机的tmp目录下,且重命名为b
[root@windfantasy ~]# ls
anaconda-ks.cfg
[root@windfantasy ~]# scp anaconda-ks.cfg [email protected]:/tmp/b
anaconda-ks.cfg 100% 1298 9.9KB/s 00:00
登陆远程主机查看其tmp目录下的文件,发现有b,说明拷贝成功
[root@windfantasy ~]# ssh 192.168.43.129
Last login: Tue Jan 8 00:04:22 2019 from 192.168.43.128
[root@localhost ~]# ls /tmp/
a systemd-private-6a9c142f1df54fa185d5b5fa5becd9d4-vgauthd.service-mtmecs
b systemd-private-6a9c142f1df54fa185d5b5fa5becd9d4-vmtoolsd.service-4072tr
ks-script-XR63Er yum.log
将远程主机的家目录中abc文件,拷贝到本机,并重命名为test
[root@localhost ~]# ls
a abc anaconda-ks.cfg
[root@localhost ~]# exit
logout
Connection to 192.168.43.129 closed.
[root@windfantasy ~]# scp [email protected]:/root/abc ./test
abc 100% 4 0.1KB/s 00:00
[root@windfantasy ~]# ls
anaconda-ks.cfg test
自定义SSH服务配置
SSH服务器通常无需修改,但会提供其他安全措施,可以在配置文件/etc/ssh/sshd_config中修改openSSH服务器的各个方面
permitrootlogin {yes|no} //是否允许root用户基于密钥方式远程登录
permitrootlogin without-password //仅允许root用户基于密钥方式远程登录
passwordauthentication {yes|no} //是否启用密码身份验证,默认开启
SSH安全注意事项
- 密码应该经常换且足够复杂
选取30位由字母,数字及下划线组成的随机数
[root@windfantasy ~]# tr -dc A-Za-z0-9_ < /dev/urandom | head -c 30 |xargs
5farZRxd2Lk3igLHP6RT5DP2n6N_i_
- 使用非默认端口
- 限制登录客户端地址
- 仅监听特定的IP地址
- 禁止管理员直接登录
- 仅允许有限制用户登录
- AllowUsers
- AllowGroups
- 使用基于密钥的认证
- 禁止使用空密码
- 禁止使用SSHv1版本
- 设定空闲会话超时时长
- 利用防火墙设置ssh访问策略
- 限制ssh的访问频度和并发在线数
- 做好日志的备份,经常分析(集中于某台服务器)
firewalld防火墙初步应用
分类
在红帽7.0中,一般有三种防火墙服务
- iptables------默认设置下,所有数据均允许通过
- firewalld------默认设置下,所有数据均不允许通过
- ebtables------8.0系统中常用
数据传输到主机的过程
数据→防火墙→tcp wrappers→service→selinux
应用实例
配置firewalld防火墙,使本机只允许IP地址为192.168.43.128的主机远程登陆
停止iptables和ebtables服务且无法自启动,避免对firewalld服务的干扰
[root@wml ~]# systemctl stop iptables
Failed to stop iptables.service: Unit iptables.service not loaded.
[root@wml ~]# systemctl stop ebtables
[root@wml ~]# systemctl mask iptables ebtables
Created symlink from /etc/systemd/system/iptables.service to /dev/null.
Created symlink from /etc/systemd/system/ebtables.service to /dev/null.
启动firewalld防火墙服务,且设为自启动
[root@wml ~]# systemctl enable firewalld
[root@wml ~]# systemctl start firewalld
查看防火墙当前配置,发现其允许ssh服务通过
[root@wml ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
首先关掉ssh服务,使其不允许通过防火墙;规则永久生效
[root@wml ~]# firewall-cmd --remove-service=ssh --permanent
success
然后添加富规则,使IP为192.168.3.128的主机允许使用ssh远程连接到本机,规则永久生效
[root@wml ~]# firewall-cmd --add-rich-rule 'rule family=ipv4 source address=192.168.3.128/32 service name=ssh accept' --permanent
success
重新加载防火墙服务,使刚才的修改生效
[root@wml ~]# firewall-cmd --reload
success
重新查看防火墙的状态,发现刚才的修改成功生效
[root@wml ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="192.168.3.128/32" service name="ssh" accept
更换到IP为192.168.3.128的主机上
[root@windfantasy ~]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.3.128 netmask 255.255.255.0 broadcast 192.168.3.255
inet6 fe80::b1e9:ffe4:3818:8d33 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:c8:53:17 txqueuelen 1000 (Ethernet)
RX packets 4441 bytes 447122 (436.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3082 bytes 509466 (497.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
远程连接刚才配置了防火墙的主机(192.168.3.129);发现成功登陆
[root@windfantasy ~]# ssh 192.168.3.129
Last login: Tue Jan 8 01:23:55 2019 from 192.168.3.128
[root@wml ~]#
退出远程主机,修改本机地址为192.168.3.130,并重新连接远程主机,发现连接失败;说明远程主机上的防火墙设置成功生效
[root@wml ~]# exit
logout
Connection to 192.168.3.129 closed.
[root@windfantasy ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
[root@windfantasy ~]# systemctl restart network
[root@windfantasy ~]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.3.130 netmask 255.255.255.0 broadcast 192.168.3.255
ether 00:0c:29:9c:a4:5a txqueuelen 1000 (Ethernet)
RX packets 589 bytes 63765 (62.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 405 bytes 68929 (67.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@windfantasy ~]# ssh 192.168.3.129
ssh: connect to host 192.168.3.129 port 22: No route to host