SSHD服务的搭建与管理

环境的选择就是Centos7.x的环境;准备基础的实验环境;

#关闭防火墙
[root@node0 ~]# systemctl stop firewalld	#停止防火墙
[root@node0 ~]# systemctl disable firewalld		#开机自启动停止防火墙

#关闭selinux
[root@node0 ~]# vim /etc/selinux/config 
.........
SELINUX=disabled	#修改这一栏为disabled
............

[root@node0 ~]# getenforce 			#查看selinux的状态
Disabled

#配置好本机可通信的ip
[root@node0 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens32 
TYPE="Ethernet"
BOOTPROTO="static"
NAME="ens32"
DEVICE="ens32"
ONBOOT="yes"
IPADDR="192.168.75.130"
PREFIX="24"
GATEWAY="192.168.75.2"
DNS1="114.114.114.114"


#关闭NetworkManager服务
[root@node0 ~]# systemctl disable NetworkManager
[root@node0 ~]# systemctl stop NetworkManager

1、sshd服务的介绍

sshd服务简介

ssh协议:安全的外壳协议,Secure Shell的缩写;是建立在应用层和传输层基础之上的安全协议

作用:sshd服务使用ssh协议进行远程控制

ssh的安装包

sshd服务的安装需要安装四个软件包,有服务器端和客户端两种之分,

#查看sshd服务的安装
[root@node0 ~]# rpm -qa | grep openssh*
openssl-libs-1.0.2k-16.el7.x86_64
openssh-7.4p1-16.el7.x86_64
openssl-1.0.2k-16.el7.x86_64
xmlsec1-openssl-1.2.20-7.el7_4.x86_64
openssh-clients-7.4p1-16.el7.x86_64
openssl11-libs-1.1.1k-2.el7.x86_64
openssh-server-7.4p1-16.el7.x86_64

#查看sshd服务的相关文件
[root@node0 ~]# rpm -ql openssh
/etc/ssh
/etc/ssh/moduli
/usr/bin/ssh-keygen
/usr/libexec/openssh
/usr/libexec/openssh/ctr-cavstest
/usr/libexec/openssh/ssh-keysign
..............

问题:服务器源码安装了应该如何查看 哪个是启动脚本?

一般的脚本就会带有chkconfig的开机自启动的基本配置;
可以使用grep命令实现
进入到源码目录列表
grep chkconfig ./* -R --color

openssh的配置文件

/etc/ssh/ssh_config:这个配置文件是给到客户端的配置文件

/etc/ssh/sshd_config :这个是服务器端的配置文件

sshd服务需要开机自启动

[root@node0 ~]# systemctl list-unit-files | grep sshd
sshd-keygen.service                           static  
sshd.service                                  enabled 
sshd@.service                                 static  
sshd.socket                                   disabled

如何使用ssh来远程连接主机

#方法一:
ssh + 远程主机用户名 @ 远程主机名或者是IP

[root@node0 ~]# ssh root@192.168.75.130
The authenticity of host '192.168.75.130 (192.168.75.130)' can't be established.
ECDSA key fingerprint is SHA256:sDTQpWlWc74piDzFUAvC7+zE78wT3+3A/PuuAC9LiNs.
ECDSA key fingerprint is MD5:d1:88:0b:d7:65:9d:a5:c1:7b:9c:b9:37:2a:3b:a1:b8.
Are you sure you want to continue connecting (yes/no)? yes						#第一次连接需要输入yes
Warning: Permanently added '192.168.75.130' (ECDSA) to the list of known hosts.
root@192.168.75.130's password: 										#然后输入密码
Last login: Mon Feb 14 01:18:42 2022 from 192.168.75.1

#第一次连接远程主机的时候,服务器没有保存远程主机的信息,因此确认主机身份会提示用户是否继续,成功登入后远程主机的信息会写入到$HOME/.ssh/know_hosts的文件中
[root@node0 ~]# cat .ssh/known_hosts 
192.168.75.130 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPQ8CuOmCJ06+JT+45zGRrCQxf2WDxXQbKYgem315gYvBUeRcF0KORTT5M7BUL+Owm/ltAVcs9EOe3bhgl9QodA=

#RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
#方法二-->使用参数-l 可以省略@
ssh -l 远程主机的用户名 远程主机的ip
[root@node0 ~]# ssh -l root 192.168.75.130
root@192.168.75.130's password: 
Last login: Mon Feb 14 01:34:41 2022 from node0

2、ssh的配置文件讲解

因为我们工程师都是通过远程连接到主机来进行操作,因此ssh的调优尤为重要;而我们都是针对服务器端来进行调优,因此修改的配置文件就是/etc/ssh/sshd_config

而配置文件中,参数前面有#表示的是默认的配置值;

#空格加参数就是注释;

修改远程主机的默认监听端口

#sshd服务默认的监听端口就是22,因此可以通过修改port这个选项
#操作之前最好就是做好备份的习惯
[root@node0 ~]# cp -a /etc/ssh/sshd_config  /etc/ssh/sshd_config.bak


#修改默认端口
[root@node0 ~]# vim /etc/ssh/sshd_config
.......
 17 #Port 22					#这个默认是带#号的22端口
 
#修改成-->这里添加两个登陆的端口222和555
 17 Port 222
 18 Port 555

#修改好要重新加载配置文件
[root@node0 ~]# systemctl restart sshd
[root@node0 ~]# netstat -ntulp | grep ssh
tcp        0      0 0.0.0.0:555             0.0.0.0:*               LISTEN      7516/sshd           
tcp        0      0 0.0.0.0:222             0.0.0.0:*               LISTEN      7516/sshd           
tcp6       0      0 :::555                  :::*                    LISTEN      7516/sshd           
tcp6       0      0 :::222                  :::*                    LISTEN      7516/sshd  

#然后自己连接尝试查看
[root@node0 ~]# ssh -p 222 root@192.168.75.130
root@192.168.75.130's password: 
Last login: Mon Feb 14 01:37:46 2022 from node0

设置sshd服务器绑定的IP;就是允许哪一个ip可以远程连接

使用到的选项就是ListenAddress这个选项

默认是0.0.0.0;表示监听所有的地址

[root@node0 ~]# vim /etc/ssh/sshd_config
............
 19 ListenAddress 192.168.75.130
..........

#重启服务
[root@node0 ~]# systemctl restart sshd
[root@node0 ~]# netstat -ntulp | grep ssh
tcp        0      0 192.168.75.130:22       0.0.0.0:*               LISTEN      7571/sshd   



#使用另外一台设备连接查看
[root@Node1 ~]# ssh root@192.168.75.130
The authenticity of host '192.168.75.130 (192.168.75.130)' can't be established.
ECDSA key fingerprint is SHA256:sDTQpWlWc74piDzFUAvC7+zE78wT3+3A/PuuAC9LiNs.
ECDSA key fingerprint is MD5:d1:88:0b:d7:65:9d:a5:c1:7b:9c:b9:37:2a:3b:a1:b8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.75.130' (ECDSA) to the list of known hosts.		#这里就有报错

#使用本机登陆就可以
[root@node0 ~]# ssh root@192.168.75.130
root@192.168.75.130's password: 
Last login: Mon Feb 14 01:47:46 2022 from node0

设置protocol协议类型

选择的ssh协议版本,可以是1也可以是2,Centos5.x的系统预设置是支援V2;

因此在ssh服务的配置中应当考虑好安全,选择最行的版本;

#在配置文件中添加新的一行
[root@node0 ~]# vim /etc/ssh/sshd_config

.......
 21 Protocol 1

设置包含计算机私人密钥的文件

这个很少用了;也没有用过;

[root@node0 ~]# vim /etc/ssh/sshd_config
.............
HostKey /etc/ssh/ssh_host_rsa_key		
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

如果有人使用ssh登入的时候,ssh记录的会话信息,然后保存的类型是AUTHPRIV;

而sshd服务日志保存在/var/log/secure这个文件中;

[root@node0 ~]# vim /etc/ssh/sshd_config
............
#SyslogFacility AUTH
SyslogFacility AUTHPRIV


#那么为什么sshd的配置文件中没有指定日志文件,但是日志文件却是存在了/var/log/secure?
	#这里就引入一个文件/etc/rsyslog.conf
[root@node0 ~]# cat /etc/rsyslog.conf 
...........
 56 # The authpriv file has restricted access.
 57 authpriv.*                                              /var/log/secure
......
	#刚好我们刚才能够看到ssh记录的类型是AUTHPRIV,这里就是指定了;

记录日志等级

[root@node0 ~]# vim /etc/ssh/sshd_config
..........
 35 #LogLevel INFO
......

3、ssh的调优重点

LoginGraceTime 2m

当使用者连上 SSH server 之后,会出现输入密码的画面,在该画面中,
在多久时间内没有成功连上 SSH server 就强迫断线!若无单位则默认时间为秒!可以根据实际情况来修改实际

PermitRootLogin yes

这里代表的是是否允许root用户登录,默认是允许的;
建议是设置成no
生产环境中的服务器都是不允许root用户登录的

AuthorizedKeysFile .ssh/authorized_keys

这里是指定了公钥文件的路径

PasswordAuthentication yes

这里代表的就是是否与需要密码认证登录,
有些设置不需要,但是一般是通过认证的密钥来登录服务器

PermitEmptyPasswords no

这里代表的是是否允许空密码登录,一般是no的

PrintMotd yes

这里代表的额是登入服务器后有提示信息给到用户查看,
但是它关联的文件就是/etc/motd文件,把需要提醒登入服务器的工程师写点注意事项

#首先在服务器上写入一段警告信息
[root@node0 ~]# echo "请注意你的操作" >> /etc/motd 
[root@node0 ~]# ssh root@192.168.75.130
root@192.168.75.130's password: 
Last login: Wed Feb 16 20:02:23 2022 from 192.168.75.1
请注意你的操作
[root@node0 ~]# 

PrintLastLog yes

这个选项指定的是显示上次的登陆信息,默认的还是yes

UseDNS yes

一般来说,为了要判断客户端来源是否正常合法的,因此会使用DNS,去反复检查主机名
如果是在内网互联的状态,这个设定是no,会让登陆的速度快一点;

4、sshd服务防止暴力破解

防止暴力破解的方法有三种

第一种方法

配置安全的sshd服务

  • 设置足够复杂的密码,一般是大于8位;密码需要由数字、大写字母、小写字母、特殊符号组成
  • 修改默认的连接端口
  • 不允许root账号直接登陆,添加普通用户、授权root权限;
  • 不允许密码登陆,只能是通过认证的密钥来登陆

实验如下–>使用ssh密钥认证登陆服务器

  • 75.130是服务器、75.131是客户端
  • 在客户端生成密钥文件
  • 然后把公钥发送给到服务器
#去到75.131客户端上输入
[root@Node1 ~]# ssh-keygen 		#这个是生成公钥文件的命令
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):    		#这里就是指定密钥文件的默认路径      
Enter passphrase (empty for no passphrase): 						#这里的passphrase 密码是对生成的私匙文件(/root/.ssh/id_dsa)的保护口令,如果不设置可以回车。
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:IHLZssiRCKWPcqtT+P6xQ6Xp6giKoR1GWbB6PwXK+J4 root@Node1
The key's randomart image is:
+---[RSA 2048]----+
|..o              |
|.o + o           |
|o = B o          |
| B O =..         |
|=.@ .+. S        |
|o=.o+.           |
|oo=o+            |
|*B.oo+           |
|*+Eoo.           |
+----[SHA256]-----+
[root@Node1 ~]# 

#这里查看一下密钥文件
[root@Node1 ~]# ls .ssh/
id_rsa  id_rsa.pub  known_hosts

#使用命令把公钥文件给到服务器端
[root@Node1 ~]# ssh-copy-id -i 192.168.75.130
root@192.168.75.130's password: 
Number of key(s) added: 1
Now try logging into the machine, with:   "ssh '192.168.75.130'"
and check to make sure that only the key(s) you wanted were added.


#这里就能够完成依赖密钥登陆
[root@Node1 ~]# ssh 192.168.75.130
Last login: Wed Feb 16 20:31:54 2022 from node0
请注意你的操作
[root@node0 ~]# 


#那么如果端口号改变了应该如何指定端口号?
[root@Node1 ~]# ssh-copy-id -i "-p 222 root@192.168.75.130"

方法二

使用开源的防护软件来防护安全

  • 这种方法比较简单、灵活、功能强大

实战的背景

	最近公网网站一直被别人暴力破解sshd服务密码。虽然没有成功,但会导致系统负载很高,原因是在暴力破解的时候,系统会不断地认证用户,从而增加了系统资源额外开销,导致访问公司网站速度很慢。
	fail2ban可以监视你的系统日志,然后匹配日志的错误信息(正则式匹配)执行相应的屏蔽动作(一般情况下是防火墙),而且可以发送e-mail通知系统管理员,很好、很实用、很强大!

其实就是防止暴力破解,工作的原理就是通过分析一定时间内的相关服务日志;将满足动作的相关IP,利用iptables加入到drop列表一定时间;

注意:重启iptables服务的话,所有DROP将重置

fail2ban软件的官方地址:http://www.fail2ban.org

自己下载相对应的版本就ok了

服务器端准备好软件包

[root@node0 ~]# cd /usr/local/src/
[root@node0 src]# ls
fail2ban-0.8.14.tar.gz

#解压软件包
[root@node0 src]# tar -xf fail2ban-0.8.14.tar.gz 
[root@node0 src]# ls
fail2ban-0.8.14

#一个陌生的软件包如何安装,-->每个软件包的安装肯定会有readme这类型的文件;
[root@node0 src]# cd fail2ban-0.8.14/
[root@node0 fail2ban-0.8.14]# ls README.md 
README.md
[root@node0 fail2ban-0.8.14]# vim README.md 
.......................
To install, just do:

    tar xvfj fail2ban-0.8.12.tar.bz2
    cd fail2ban-0.8.12
    python setup.py install
...................

#从教程上面可以看到是用python来安装的,-->那么我们python的环境就需要大于2.4的版本
[root@node0 fail2ban-0.8.14]# python -V
Python 2.7.5

#这里就可以进行安装部署了
	#这里一定要注意路径,进入到fail2ban的目录文件里边操作
[root@node0 fail2ban-0.8.14]# python setup.py install
....
#安装好了就要查看一下有没有报错
[root@node0 fail2ban-0.8.14]# echo $?
0

安装好了fail2ban,查看一下配置文件

[root@node0 fail2ban-0.8.14]# ls /etc/fail2ban/
action.d  fail2ban.conf  fail2ban.d  filter.d  jail.conf  jail.d


#这里简单了解一下fail2ban的主要文件
[root@node0 fail2ban-0.8.14]# ll /etc/fail2ban/
总用量 32
drwxr-xr-x 2 root root  4096 216 23:15 action.d		#动作文件,默认的文件,设置iptables以及mail等动作的文件
-rw-rw-r-- 1 root root  1525 820 2014 fail2ban.conf		#这里定义了fail2ban的日志几倍、日志位置以及sock套接字文件
drwxr-xr-x 2 root root     6 216 23:15 fail2ban.d		#条件文件夹,内含默认文件。过滤日志关键内容设置
drwxr-xr-x 2 root root  4096 216 23:15 filter.d
-rw-rw-r-- 1 root root 19316 820 2014 jail.conf			#主要配置文件,模块化。主要设置启用ban动作的服务及动作阀值
drwxr-xr-x 2 root root     6 216 23:15 jail.d			#这里也可以生效的文件夹

安装好了fail2ban的软件,那么我们如何知道启动脚本是哪一个?

  • 源码安装好了之后–>它并没有给我们准备好启动的文件,因此我们需要从源码文件中提取启动的脚本
#在这么多的源码文件中,我们也不知道如何找到启动的脚本,因此有个知识点需要掌握;
#凡是启动的脚本都含有开机自动的指令,就会有chkconfig这类似的选项
[root@node0 fail2ban-0.8.14]# grep chkconfig ./* -R --color
./files/redhat-initd:# chkconfig: - 92 08

#这里能够查找出来,于是我们就可以把源码的启动脚本复制到/etc/init.d/的目录下
[root@node0 fail2ban-0.8.14]# cp ./files/redhat-initd  /etc/init.d/fail2ban
[root@node0 fail2ban-0.8.14]# ll /etc/init.d/fail2ban 
-rwxr-xr-x 1 root root 2141 216 23:25 /etc/init.d/fail2ban

#到这里就代表fail2ban基本完成安装

以下就是一个小小的案例来使用fail2ban这款软件

实战要求:

设置ssh远程登录5分钟内,3次密码验证失败,禁止用户IP访问主机1个小时;
1个小时内限制自动解除,用户可以重新登陆查看;

实战分析:

  • 动作文件/etc/action.d/iptables.conf和日志匹配条件文件filter.d/sshd.conf安装后是默认存在的,因此这两个文件是不用做修改
  • 所有的配置应该在jail.conf文件中;

jail.conf的配置如下

#要养成良好的习惯,修改配置文件最好是备份
[root@node0 ~]# cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.conf.bak

#打开配置文件
[root@node0 ~]# vim /etc/fail2ban/jail.conf 
.............
 27 [DEFAULT]			#这里是全局配置
 32 ignoreip = 127.0.0.1/8		#这里是忽略的ip李彪,不受限制,指定本机环回地址不受限制
 41 bantime  = 600				#这里是屏蔽时间,默认是秒,600s=10分钟
 45 findtime  = 600				#这里代表的是这个时间段内,超过规定的次数就会被ban
 48 maxretry = 3				#这里指的是最多的连接次数
 61 backend = auto				#这里是日志修改的检测机制,有gamin、poling、auto三种
 ...........
 94 [ssh-iptables]				#这里开始就是单个服务的设置,我们要找到ssh这个服务-->或者自己写也行
 96 enabled  =true				#这里是是否激活选项
 97 filter   = sshd				#这里是锅炉规则的filter的名字,这里对应的是filter.d目录下的sshd.conf文件
 98 action   = iptables[name=SSH, port=ssh, protocol=tcp]
 99            sendmail-whois[name=SSH, dest=you@example.com, sender=fail2ban@example.com, sendername="Fail2 Ban"]

	#这里就是动作的设定相关参数,对应的文件也是action.d/iptables.conf文件
	#这里面包含,iptables的规则,针对的服务是ssh,端口也是ssh,也可以改为22端口,protocol协议是tcp
	#邮件设定:设置邮件、等参数


100 logpath  = /var/log/sshd.log		#这里是检测系统的登陆日志文件,fail2ban是监控日志而触发的报警,因此这里要写ssh的日志文件保存的位置/var/log/secure
101 maxretry = 5						#这个是最大的密码验证时效的次数
102 bantime = 3600						#禁止用户1小时访问主机
103 findtime = 300						#这里是5分钟内出现规定次数就开始ban

 

#然后启动服务
[root@node0 ~]# /etc/init.d/fail2ban start
Starting fail2ban (via systemctl):                         [  确定  ]
[root@node0 ~]# 


#然后清空一下日志文件查看
[root@node0 ~]# > /var/log/secure 
	#最后使用75.131登陆查看-->
[root@Node1 ~]# ssh root@192.168.75.130
root@192.168.75.130's password: 
Permission denied, please try again.
root@192.168.75.130's password: 
Permission denied, please try again.
root@192.168.75.130's password: 
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

#再次登陆就不能了
[root@Node1 ~]# ssh root@192.168.75.130
ssh: connect to host 192.168.75.130 port 22: Connection refused

#回到服务器端查看iptables的规则链
[root@node0 ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
fail2ban-SSH  tcp  --  anywhere             anywhere             tcp dpt:ssh

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain fail2ban-SSH (1 references)
target     prot opt source               destination         
REJECT     all  --  192.168.75.131       anywhere             reject-with icmp-port-unreachable
RETURN     all  --  anywhere             anywhere 

#还可以使用fail2ban的客户啊短来查看
	#查看规则链是否生效
[root@node0 ~]# fail2ban-client status
Status
|- Number of jail:	1
`- Jail list:		ssh-iptables

#这里就可以查看一下具体的一条规则链,然后如果看到ban的ip就证明实验成功
[root@node0 ~]# fail2ban-client status ssh-iptables
Status for the jail: ssh-iptables
|- filter
|  |- File list:	/var/log/secure 
|  |- Currently failed:	0
|  `- Total failed:	3
`- action
   |- Currently banned:	1
   |  `- IP list:	192.168.75.131 
   `- Total banned:	1

#最后查看一下fail2ban的日志文件
[root@node0 ~]# tail /var/log/fail2ban.log
........
2022-02-17 00:18:16,349 fail2ban.actions[7655]: WARNING [ssh-iptables] Ban 192.168.75.131

实验过程中需要注意的几个点

  • 注意别设置错了规则链–>指定是ssh-iptables
  • 如果iptables -F 是清空了规则链的话需要重启一下fail2ban服务
  • 如果是修改了端口号的话需要在action的port上指定端口号即可

第三种方法

如果调优过程中是可以使用脚本来实现安全防护的,脚本如下:

[root@node0 ~]# vim ssh_ban.sh
#!/bin/bash
#2022年2月17日
#author by liangjiawei
#used ban ssh_ip
######################
cat /var/log/secure | awk '/Failed/{print $(NF-3)}'|sort|uniq -c | awk '{print $2 "=" $1;}' >> /root/black.tx
t
DEFINE="10"
for i in `cat /root/black.txt`
do
        IP=`echo $i|awk -F= '{print $1}'`
        NUM=`echo $i|awk -F= '{print $2}'`
        if [ $NUM -gt $DEFINE ];then
                grep $IP /etc/hosts.deny >/dev/null
                if [ $? -gt 0 ];then
                        echo "sshd:$IP " >> /dev/null

                fi
        fi
done

第四种方法

也可以通过pam模块来防止暴力破解ssh

#在pam模块上添加
[root@node0 ~]# vim /etc/pam.d/sshd 
.........
	#添加这一行
auth    required        pam_tally2.so   deny=3  unlock_time=600 even_deny_root  root_unlock_time=1200

#这里就是尝试3次登陆失败、普通用户是600s解锁,root用户要1200s来解锁

#查看一下用户错误登陆
[root@node0 ~]# pam_tally2 --user
Login           Failures Latest failure     From
root                6    02/17/22 00:46:16  192.168.75.131
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐