OpenSSH是SSH协议的开源实现。OpenSSH可进行远程登录、备份、通过scp或sftp进行远程文件传输等等。SSH最完美的确保两个网络和系统之间交换数据的机密性和完整性。其主要的优点是通过使用公共密钥加密进行服务器身份验证。然而,不时有传闻关于OpenSSH零日漏洞。这里我们列出一些重要的事情,你需要作出调整来提高OpenSSH服务器的安全性。
默认配置文件和端口
/etc/ssh/sshd_config-OpenSSH服务器配置文件
/etc/ssh/ssh_config-OpenSSH客户端配置文件
~/.ssh/-用户独立的ssh配置目录
~/.ssh/authorized_keysor
~/.ssh/authorized_keys-公钥(RSAorDSA)
/etc/nologin-如果该文件存在,则只允许root帐号登录
/etc/hosts.allowand
/etc/hosts.deny:访问控制定义
SSH默认端口:TCP22
连接中的SSH会话
#1:禁用OpenSSH服务
一些工作站或者是笔记本是无需OpenSSH服务的,你不需要提供远程登录和文件传输,那么就禁用SSHD服务吧。CentOS/RHEL/FedoraLinux用户可通过yum命令来禁用并删除openssh-server服务:
Debian/UbuntuLinux用户可通过apt-get命令来处理:
1 | #apt-getremoveopenssh-server |
你还需要更新iptables脚本来移除ssh例外规则,在CentOS/RHEL/Fedora下可编辑/etc/sysconfig/iptables和/etc/sysconfig/ip6tables.搞定后重启iptables服务即可:
2 | #serviceip6tablesrestart<code></code> |
#2:只使用SSHProtocol2
SSH协议版本1有很多漏洞和安全问题,应该避免使用SSH-1,可通过在sshd_config文件中配置如下信息来启用SSH-2:
#3:限制用户访问SSH
默认所有系统用户都可以通过SSH登录,只需要用密码或者公钥即可。有时候你创建某个用户只是为了使用邮件或者是FTP,但是这些用户也可以通过ssh登录,登录后就可以访问很多的系统工具,包括编译器和脚本语言,可打开网络端口以及做很多其他的事情。我们可以通过sshd_config文件中的AllowUsers和DenyUsers来设置可访问SSH服务的用户名单。
下面配置只允许root,vivek和jerry三个帐号使用SSH服务
1 | AllowUsersrootvivekjerry |
你也可以设置哪些用户不能访问SSH:
你也可以
配置LinuxPAM来允许或者拒绝通过sshd服务器登录,你也可以对一个分组进行设置是否可以访问ssh(详情)
#4:配置空闲登出的超时间隔
用户通过ssh登录到服务器后,如果长时间没有任何动作的话,可通过设置空闲超时时间来让登录的用户自动登出,以避免一些不必要的ssh会话连接。打开sshd_config文件查看并编辑如下配置:
这里我们设置了300秒(5分钟),一旦用户在5分钟内没有动作则会自动被踢出。请看
如何自动登出BASH/TCSH/SSH以了解更多无活动状态自动登出的详情。
#5:禁用.rhosts文件
不读取用户命令下的~/.rhosts和~/.shosts文件,只需在sshd_config中使用如下设置:
SSH可模拟过时的rsh命令的行为,需要禁用通过RSH的非安全登录。
#6:禁用基于主机的认证
在sshd_config中使用如下配置:
1 | HostbasedAuthenticationno |
#7:禁止root帐号通过SSH登录
没必要让root帐号可通过ssh登录,可通过正常用户登录后然后执行su或者sudo来执行root权限的操作,可在sshd_config中使用如下配置来禁用root帐号登录:
关于这个问题,Bob给出了很棒的说明:
Saying"don'tloginasroot"ish******t.Itstemsfromthedayswhenpeoplesniffedthefirstpacketsofsessionssologginginasyourselfandsu-ingdecreasedthechanceanattackerwouldseetherootpw,anddecreastthechanceyougotspoofedasto
yourtelnethosttarget,You'dgetyourpasswordspoofedbutnotroot'spw.Gimmeabreak.thisis2005-Wehavessh,usedproperlyit'ssecure.usedimproperlynoneofthis1989willmakeadamnbitofdifference.-Bob
#8:启用警告的Banner
可以在sshd_config中通过如下配置来启用通过ssh登录后的警告信息:
下面是/etc/issue文件的示例内容:
----------------------------------------------------------------------------------------------
欢迎访问oschina服务器,请不要乱来!!!
----------------------------------------------------------------------------------------------
#8:防火墙处理SSH端口#22
你需要在防火墙规则中打开22端口,除非你的服务器只允许通过局域网访问:
Netfilter(Iptables)配置
编辑/etc/sysconfig/iptables(红帽系列Linux)以允许来自192.168.1.0/24和202.54.1.5/29两个网段的连接:
1 | -ARH-Firewall-1-INPUT-s192.168.1.0/24-mstate--stateNEW-ptcp--dport22-jACCEPT |
2 | -ARH-Firewall-1-INPUT-s202.54.1.5/29-mstate--stateNEW-ptcp--dport22-jACCEPT |
如果你的系统启用了IPv6,编辑/etc/sysconfig/ip6tables(Redhatandfriendsspecificfile):
1 | -ARH-Firewall-1-INPUT-sipv6network::/ipv6mask-mtcp-ptcp--dport22-jACCEPT |
用实际的IPv6范围替换其中的ipv6network::/ipv6mask
*BSDPF防火墙配置
如果你使用了PF防火墙,可更新/etc/pf.conf配置如下:
1 | pass in on$ext_ifinetprototcpfrom{192.168.1.0/24,202.54.1.5/29}to$ssh_server_ipport ssh
flagsS/SAsynproxystate |
#9:修改SSH端口和限制IP绑定
默认SSH绑定到所有网卡的所有IP,端口号是22,建议只绑定到需要的网卡IP,并修改默认的端口。可通过ssh_config配置文件中使用如下配置信息将端口修改为300:
2 | ListenAddress192.168.1.5 |
还有一个更好的方法是使用积极主动的脚本,诸如fail2ban或者是denyhosts
#10:使用强的SSH密码
使用强而复杂的密码是多么重要的一件事。蛮力攻击之所以有效,是因为你使用基于字典的密码。你可以强制要求用户不能使用基于字典的密码,并通过使用
johntherippertool来找出已有的弱密码,下面是一个随机密码生成器的示例:(放在你的~/.bashrc):
4 | tr - dc
A-Za-z0-9_</dev/urandom| head
-c${l}| xargs |
运行:genpasswd16
输出:uw8CnDVMwC6vOKgW
#11:使用基于公钥的认证
使用公/私钥配对,并对私钥提供密码保护,详情请看使用基于
RSA和
DSAkey的认证。绝对不要使用密码短语免费密钥(密码键更少)登录。
#12:使用Keychain认证
keychain是一个特别的bash脚本,用于方便灵活的生成基于密钥认证,提供多种安全措施,详情请看
keychainsoftware.
#13:ChrootSSHD(将用户锁定在他的主目录下)
默认用户允许浏览服务器上的目录,如/etc、/bin等,我们可使用chroot或者是
specialtoolssuchasrssh来保护ssh。而OpenSSH4.8p1和4.9p1让你不再依赖第三方的工具(如rssh和组合chroot)来将用户锁定在他的主目录下,详情请看blogpost关于如何使用ChrootDirectory指令。
#14:使用TCPWrappers
TCPWrapper是一个基于主机地址的网络ACL系统,用来过滤网络地址访问互联网。OpenSSH支持TCPWrappers。只需要更新你的/etc/hosts.allow文件只允许通过192.168.1.2172.16.23.12访问sshd:
1 | sshd:192.168.1.2172.16.23.12 |
详情请看
FAQaboutsettingandusingTCPwrappers
#15:禁用空密码
你应该禁止帐号使用空密码进行远程登录,在sshd_config使用如下配置即可:
#16:阻止SSH破解(蛮力破解攻击)
蛮力破解是一种试图通过大量使用单一或分布式计算机网络来战胜一个加密方案。为了阻止这种方法,可结合使用如下软件:
DenyHosts是Python语言写的一个程序,它会分析SSHD的日志文件,当发现重复的攻击时就会记录IP到/etc/hosts.deny文件,从而达到自动屏蔽IP的功能。
解释如何在RHEL、Fedora和CentOS系统下安装
DenyHosts
Fail2ban是一个IP自动屏蔽工具
security/sshguard-pf在pf中防止暴力破解
security/sshguard-ipfw在ipfw中防止暴力破解
security/sshguard-ipfilter在ipfilter中防止暴力破解
security/sshblockblockabusiveSSHloginattempts.
security/sshitchecksforSSH/FTPbruteforceandblocksgivenIPs.
BlockHostsAutomaticblockingofabusiveIPhosts.
BlacklistGetridofthosebruteforceattempts.
BruteForceDetectionAmodularshellscriptforparsingapplicationlogsandcheckingforauthenticationfailures.Itdoesthisusingarulessystemwhere
applicationspecificoptionsarestoredincludingregularexpressionsforeachuniqueauthformat.
IPQBDBfilterMaybeconsideredasafail2banlite.
#17:限制22端口连接的速率
netfilter和pf都提供了连接速率限制选项
Iptables示例
下面配置禁止在一分钟内22端口超过5个连接:
4 | $IPT-IINPUT-ptcp--dport${ssh_port}-i${inet_if}-mstate--stateNEW-mrecent-- set |
5 | $IPT-IINPUT-ptcp--dport${ssh_port}-i${inet_if}-mstate--stateNEW-mrecent--update--seconds60--hitcount5-jDROP |
另外的配置选项:
1 | $IPT-AINPUT-i${inet_if}-ptcp--dport${ssh_port}-mstate--stateNEW-mlimit--limit3/min--limit-burst3-jACCEPT |
2 | $IPT-AINPUT-i${inet_if}-ptcp--dport${ssh_port}-mstate--stateESTABLISHED-jACCEPT |
3 | $IPT-AOUTPUT-o${inet_if}-ptcp--sport${ssh_port}-mstate--stateESTABLISHED-jACCEPT |
5 | #$IPT-AINPUT-i${inet_if}-mstate--stateNEW,ESTABLISHED,RELATED-ptcp--dport22-mlimit--limit5/minute--limit-burst5-jACCEPT |
更多的配置详情请看iptables的man页。
*BSDPF示例
以下将限制的最大连接数到20,每个源速率限制连接数,在一个5秒的跨度15。如果有人打破我们的规则将它们添加到我们的阻止的ip表和阻止他们做任何进一步的连接。
1 | sshd_server_ip= "202.54.1.5" |
2 | table<abusive_ips>persist |
3 | block in quickfrom<abusive_ips> |
4 | pass in on$ext_ifprototcpto$sshd_server_ipport ssh flagsS/SAkeepstate(max-src-conn20,max-src-conn-rate15/5,overload<abusive_ips>flush) |
#18:使用端口碰撞技术(PortKnocking)
端口碰撞技术是一个方法的外部开放端口防火墙通过生成一个连接请求在一组预先指定关闭端口。一旦一个正确的顺序连接尝试接收,防火墙规则是动态修改为允许主机将连接尝试连接在特定端口(s)。
使用iptables配置端口碰撞的示例:
02 | $IPT-Astage1-mrecent--remove--nameknock |
03 | $IPT-Astage1-ptcp--dport3456-mrecent-- set --nameknock2 |
06 | $IPT-Astage2-mrecent--remove--nameknock2 |
07 | $IPT-Astage2-ptcp--dport2345-mrecent-- set --nameheaven |
10 | $IPT-Adoor-mrecent--rcheck--seconds5--nameknock2-jstage2 |
11 | $IPT-Adoor-mrecent--rcheck--seconds5--nameknock-jstage1 |
12 | $IPT-Adoor-ptcp--dport1234-mrecent-- set --nameknock |
14 | $IPT-AINPUT-m--stateESTABLISHED,RELATED-jACCEPT |
15 | $IPT-AINPUT-ptcp--dport22-mrecent--rcheck--seconds5--nameheaven-jACCEPT |
16 | $IPT-AINPUT-ptcp--syn-jdoo |
两个软件:
fwknop是一个结合端口碰撞和被动操作系统识别技术的实现
Multiple-portknocking仅限于Netfilter/IPtables的实现
#19:使用日志分析器
可通过
logwatchorlogcheck来阅读日志,这些工具可以让你轻松的浏览日志。通过指定时间来给出日志的报告。首先要确保在sshd_config中将日志级别LogLevel设置为INFO或者DEBUG:
#20:对OpenSSH和操作系统打补丁
推荐你使用诸如
yum,
apt-get,
freebsd-update工具来保持系统的即时获取最新的安全补丁。
其他选项
为了隐藏openssh版本,你可更新源码然后再次编译openssh,并确保在sshd_config中使用如下配置:
01 | #Turnonprivilegeseparation |
02 | UsePrivilegeSeparation yes |
03 | #Preventtheuseofinsecurehomedirectoryandkeyfilepermissions |
05 | #Turnonreversenamechecking |
06 | VerifyReverseMapping yes |
07 | #Doyouneedportforwarding? |
10 | #Specifieswhetherpasswordauthenticationisallowed.Thedefaultisyes. |
11 | PasswordAuthenticationno |
在重启openssh-server之前先用如下命令验证配置是否正确:
使用
two-factor或者
three-factor(ormore)认证来加强OpenSSH的安全。