OpenSSH是SSH协议的一个实现。一般通过scp或sftp用于远程登录、备份、远程文件传输等功能。SSH能够完美保障两个网络或系统间数据传输的保密性和完整性。尽管如此,它最大的优势是使用公匙加密来进行服务器验证。时不时会出现关于OpenSSH零日漏洞的传言。本文将描述如何设置你的Linux或类Unix系统以提高sshd的安全性。
OpenSSH默认设置
TCP端口-22
OpenSSH服务配置文件-sshd_config(位于/etc/ssh/)
1、基于公匙的登录
OpenSSH服务支持各种验证方式。推荐使用公匙加密验证。首先,使用以下ssh-keygen命令在本地电脑上创建密匙对:
1024位或低于它的DSA和RSA加密是很弱的,请不要使用。当考虑ssh客户端向后兼容性的时候,请使用RSA密匙代替ECDSA密匙。所有的ssh密钥要么使用ED25519,要么使用RSA,不要使用其它类型。
$ssh-keygen-tkey_type-bbits-C"comment"
示例:
$ssh-keygen-ted25519-C"Logintoproductionclusteratxyzcorp"
或
$ssh-keygen-trsa-b4096-f~/.ssh/id_rsa_aws_$(date+%Y-%m-%d)-C"AWSkeyforabccorpclients"
下一步,使用ssh-copy-id命令安装公匙:
$ssh-copy-id-i/path/to/public-key-fileuser@host
或
$ssh-copy-iduser@remote-server-ip-or-dns-name
示例:
$ssh-copy-idvivek@rhel7-aws-server
提示输入用户名和密码的时候,确认基于ssh公匙的登录是否工作:
$sshvivek@rhel7-aws-server
2、禁用root用户登录
禁用root用户登录前,确认普通用户可以以root身份登录。例如,允许用户vivek使用sudo命令以root身份登录。
在Debian/Ubuntu系统中如何将用户vivek添加到sudo组中
允许sudo组中的用户执行任何命令。将用户vivek添加到sudo组中:
$sudoadduserviveksudo
使用id命令验证用户组。
$idvivek
在CentOS/RHEL系统中如何将用户vivek添加到sudo组中
在CentOS/RHEL和Fedora系统中允许wheel组中的用户执行所有的命令。使用usermod命令将用户vivek添加到wheel组中:
$sudousermod-aGwheelvivek
$idvivek
测试sudo权限并禁用sshroot登录
测试并确保用户vivek可以以root身份登录执行以下命令:
$sudo-i
$sudo/etc/init.d/sshdstatus
$sudosystemctlstatushttpd
添加以下内容到sshd_config文件中来禁用root登录:
PermitRootLoginno
ChallengeResponseAuthenticationno
PasswordAuthenticationno
UsePAMno
3、禁用密码登录
所有的密码登录都应该禁用,仅留下公匙登录。添加以下内容到sshd_config文件中:
AuthenticationMethodspublickey
PubkeyAuthenticationyes
CentOS6.x/RHEL6.x系统中老版本的sshd用户可以使用以下设置:
PubkeyAuthenticationyes
4、限制用户的ssh访问
默认状态下,所有的系统用户都可以使用密码或公匙登录。但是有些时候需要为FTP或者email服务创建UNIX/Linux用户。然而,这些用户也可以使用ssh登录系统。他们将获得访问系统工具的完整权限,包括编译器和诸如Perl、Python(可以打开网络端口干很多疯狂的事情)等的脚本语言。通过添加以下内容到sshd_config文件中来仅允许用户root、vivek和jerry通过SSH登录系统:
AllowUsersvivekjerry
当然,你也可以添加以下内容到sshd_config文件中来达到仅拒绝一部分用户通过SSH登录系统的效果。
DenyUsersrootsarojanjalifoo
你也可以通过配置LinuxPAM来禁用或允许用户通过sshd登录。也可以允许或禁止一个用户组列表通过ssh登录系统。
5、禁用空密码
你需要明确禁止空密码账户远程登录系统,更新sshd_config文件的以下内容:
PermitEmptyPasswordsno
6、为ssh用户或者密匙使用强密码
为密匙使用强密码和短语的重要性再怎么强调都不过分。暴力破解可以起作用就是因为用户使用了基于字典的密码。你可以强制用户避开字典密码并使用约翰的开膛手工具来检测弱密码。以下是一个随机密码生成器(放到你的~/.bashrc下):
genpasswd(){
locall=$1
["$l"==""]&&l=20
tr-dcA-Za-z0-9_</dev/urandom|head-c${l}|xargs
}
运行:
genpasswd16
输出:
uw8CnDVMwC6vOKgW
使用mkpasswd/makepasswd/pwgen生成随机密码
Linux/UNIX:生成密码
Linux随机密码生成命令
7、为SSH的22端口配置防火墙
你需要更新iptables/ufw/firewall-cmd或pf防火墙配置来为ssh的TCP端口22配置防火墙。一般来说,OpenSSH服务应该仅允许本地或者其他的远端地址访问。
Netfilter(Iptables)配置
更新/etc/sysconfig/iptables(Redhat和其派生系统特有文件)实现仅接受来自于192.168.1.0/24和202.54.1.5/29的连接,输入:
-ARH-Firewall-1-INPUT-s192.168.1.0/24-mstate--stateNEW-ptcp--dport22-jACCEPT
-ARH-Firewall-1-INPUT-s202.54.1.5/29-mstate--stateNEW-ptcp--dport22-jACCEPT
如果同时使用IPv6的话,可以编辑/etc/sysconfig/ip6tables(Redhat和其派生系统特有文件),输入:
-ARH-Firewall-1-INPUT-sipv6network::/ipv6mask-mtcp-ptcp--dport22-jACCEPT
将ipv6network::/ipv6mask替换为实际的IPv6网段。
Debian/UbuntuLinux下的UFW
UFW是UncomplicatedFireWall的首字母缩写,主要用来管理Linux防火墙,目的是提供一种用户友好的界面。输入以下命令使得系统仅允许网段202.54.1.5/29接入端口22:
$sudoufwallowfrom202.54.1.5/29toanyport22
*BSDPF防火墙配置
如果使用PF防火墙/etc/pf.conf配置如下:
passinon$ext_ifinetprototcpfrom{192.168.1.0/24,202.54.1.5/29}to$ssh_server_ipportsshflagsS/SAsynproxystate
8、修改SSH端口和绑定IP
ssh默认监听系统中所有可用的网卡。修改并绑定ssh端口有助于避免暴力脚本的连接(许多暴力脚本只尝试端口22)。更新文件sshd_config的以下内容来绑定端口300到IP192.168.1.5和202.54.1.5:
Port300
ListenAddress192.168.1.5
ListenAddress202.54.1.5
当需要接受动态广域网地址的连接时,使用主动脚本是个不错的选择,比如fail2ban或denyhosts。
9、使用TCPwrappers(可选的)
TCPwrapper是一个基于主机的访问控制系统,用来过滤来自互联网的网络访问。OpenSSH支持TCPwrappers。只需要更新文件/etc/hosts.allow中的以下内容就可以使得SSH只接受来自于192.168.1.2和172.16.23.12的连接:
sshd:192.168.1.2172.16.23.12
在Linux/MacOSX和类UNIX系统中参见TCPwrappers设置和使用的常见问题。
10、阻止SSH破解或暴力攻击
暴力破解是一种在单一或者分布式网络中使用大量(用户名和密码的)组合来尝试连接一个加密系统的方法。可以使用以下软件来应对暴力攻击:
DenyHosts是一个基于PythonSSH安全工具。该工具通过监控授权日志中的非法登录日志并封禁原始IP的方式来应对暴力攻击。
RHEL/Fedora和CentOSLinux下如何设置DenyHosts。
Fail2ban是另一个类似的用来预防针对SSH攻击的工具。
sshguard是一个使用pf来预防针对SSH和其他服务攻击的工具。
security/sshblock阻止滥用SSH尝试登录。
IPQBDBfilter可以看做是fail2ban的一个简化版。
11、限制TCP端口22的传入速率(可选的)
netfilter和pf都提供速率限制选项可以对端口22的传入速率进行简单的限制。
Iptables示例
以下脚本将会阻止60秒内尝试登录5次以上的客户端的连入。
#!/bin/bash
inet_if=eth1
ssh_port=22
$IPT-IINPUT-ptcp--dport${ssh_port}-i${inet_if}-mstate--stateNEW-mrecent--set
$IPT-IINPUT-ptcp--dport${ssh_port}-i${inet_if}-mstate--stateNEW-mrecent--update--seconds60--hitcount5
在你的iptables脚本中调用以上脚本。其他配置选项:
$IPT-AINPUT-i${inet_if}-ptcp--dport${ssh_port}-mstate--stateNEW-mlimit--limit3/min--limit-burst3-jACCEPT
$IPT-AINPUT-i${inet_if}-ptcp--dport${ssh_port}-mstate--stateESTABLISHED-jACCEPT
$IPT-AOUTPUT-o${inet_if}-ptcp--sport${ssh_port}-mstate--stateESTABLISHED-jACCEPT
#anotheronelineexample
#$IPT-AINPUT-i${inet_if}-mstate--stateNEW,ESTABLISHED,RELATED-ptcp--dport22-mlimit--limit5/minute--limit-burst5-jACCEPT
*BSDPF示例
以下脚本将限制每个客户端的连入数量为20,并且5秒内的连接不超过15个。如果客户端触发此规则,则将其加入abusive_ips表并限制该客户端连入。最后flush关键词杀死所有触发规则的客户端的连接。
sshd_server_ip="202.54.1.5"
table<abusive_ips>persist
blockinquickfrom<abusive_ips>
passinon$ext_ifprototcpto$sshd_server_ipportsshflagsS/SAkeepstate(max-src-conn20,max-src-conn-rate15/5,overload<abusive_ips>flush)
12、使用端口敲门(可选的)
端口敲门是通过在一组预先指定的封闭端口上生成连接尝试,以便从外部打开防火墙上的端口的方法。一旦指定的端口连接顺序被触发,防火墙规则就被动态修改以允许发送连接的主机连入指定的端口。以下是一个使用iptables实现的端口敲门的示例:
$IPT-Nstage1
$IPT-Astage1-mrecent--remove--nameknock
$IPT-Astage1-ptcp--dport3456-mrecent--set--nameknock2
$IPT-Nstage2
$IPT-Astage2-mrecent--remove--nameknock2
$IPT-Astage2-ptcp--dport2345-mrecent--set--nameheaven
$IPT-Ndoor
$IPT-Adoor-mrecent--rcheck--seconds5--nameknock2-jstage2
$IPT-Adoor-mrecent--rcheck--seconds5--nameknock-jstage1
$IPT-Adoor-ptcp--dport1234-mrecent--set--nameknock
$IPT-AINPUT-m--stateESTABLISHED,RELATED-jACCEPT
$IPT-AINPUT-ptcp--dport22-mrecent--rcheck--seconds5--nameheaven-jACCEPT
$IPT-AINPUT-ptcp--syn-jdoor
13、配置空闲超时注销时长
用户可以通过ssh连入服务器,可以配置一个超时时间间隔来避免无人值守的ssh会话。打开sshd_config并确保配置以下值:
ClientAliveInterval300
ClientAliveCountMax0
以秒为单位设置一个空闲超时时间(300秒=5分钟)。一旦空闲时间超过这个值,空闲用户就会被踢出会话。更多细节参见如何自动注销空闲超时的BASH/TCSH/SSH用户。
14、为ssh用户启用警示标语
Banner/etc/issue
`/etc/issue示例文件:
----------------------------------------------------------------------------------------------
YouareaccessingaXYZGovernment(XYZG)InformationSystem(IS)thatisprovidedforauthorizeduseonly.
ByusingthisIS(whichincludesanydeviceattachedtothisIS),youconsenttothefollowingconditions:
+TheXYZGroutinelyinterceptsandmonitorscommunicationsonthisISforpurposesincluding,butnotlimitedto,
penetrationtesting,COMSECmonitoring,networkoperationsanddefense,personnelmisconduct(PM),
lawenforcement(LE),andcounterintelligence(CI)investigations.
+Atanytime,theXYZGmayinspectandseizedatastoredonthisIS.
+Communicationsusing,ordatastoredon,thisISarenotprivate,aresubjecttoroutinemonitoring,
interception,andsearch,andmaybedisclosedorusedforanyXYZGauthorizedpurpose.
+ThisISincludessecuritymeasures(e.g.,authenticationandaccesscontrols)toprotectXYZGinterests--not
foryourpersonalbenefitorprivacy.
+Notwithstandingtheabove,usingthisISdoesnotconstituteconsenttoPM,LEorCIinvestigativesearching
ormonitoringofthecontentofprivilegedcommunications,orworkproduct,relatedtopersonalrepresentation
orservicesbyattorneys,psychotherapists,orclergy,andtheirassistants.Suchcommunicationsandwork
productareprivateandconfidential.SeeUserAgreementfordetails.
----------------------------------------------------------------------------------------------
以上是一个标准的示例,更多的用户协议和法律细节请咨询你的律师团队。
15、禁用.rhosts文件(需核实)
禁止读取用户的~/.rhosts和~/.shosts文件。更新sshd_config文件中的以下内容:
IgnoreRhostsyes
SSH可以模拟过时的rsh命令,所以应该禁用不安全的RSH连接。
16、禁用基于主机的授权(需核实)
禁用基于主机的授权,更新sshd_config文件的以下选项:
HostbasedAuthenticationno
17、为OpenSSH和操作系统打补丁
推荐你使用类似yum、apt-get和freebsd-update等工具保持系统安装了最新的安全补丁。
18、ChrootOpenSSH(将用户锁定在主目录)
默认设置下用户可以浏览诸如/etc、/bin等目录。可以使用chroot或者其他专有工具如rssh来保护ssh连接。从版本4.8p1或4.9p1起,OpenSSH不再需要依赖诸如rssh或复杂的chroot(1)等第三方工具来将用户锁定在主目录中。可以使用新的ChrootDirectory指令将用户锁定在其主目录,参见这篇博文。
19.禁用客户端的OpenSSH服务
工作站和笔记本不需要OpenSSH服务。如果不需要提供ssh远程登录和文件传输功能的话,可以禁用sshd服务。CentOS/RHEL用户可以使用yum命令禁用或删除openssh-server:
$sudoyumeraseopenssh-server
Debian/Ubuntu用户可以使用apt命令/apt-get命令删除openssh-server:
$sudoapt-getremoveopenssh-server
有可能需要更新iptables脚本来移除ssh的例外规则。CentOS/RHEL/Fedora系统可以编辑文件/etc/sysconfig/iptables和/etc/sysconfig/ip6tables。最后重启iptables服务:
#serviceiptablesrestart
#serviceip6tablesrestart
20.来自Mozilla的额外提示
如果使用6.7+版本的OpenSSH,可以尝试下以下设置:
#################[WARNING]########################
#Donotuseanysettingblindly.Readsshd_config#
#manpage.Youmustunderstandcryptographyto#
#tweakfollowingsettings.Otherwiseusedefaults#
####################################################
#SupportedHostKeyalgorithmsbyorderofpreference.
HostKey/etc/ssh/ssh_host_ed25519_key
HostKey/etc/ssh/ssh_host_rsa_key
HostKey/etc/ssh/ssh_host_ecdsa_key
#SpecifiestheavailableKEX(KeyExchange)algorithms.
KexAlgorithmscurve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
#Specifiestheciphersallowed
Cipherschacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
#SpecifiestheavailableMAC(messageauthenticationcode)algorithms
MACshmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
#LogLevelVERBOSElogsuser'skeyfingerprintonlogin.Neededtohaveaclearaudittrackofwhichkeywasusingtologin.
LogLevelVERBOSE
#Logsftplevelfileaccess(read/write/etc.)thatwouldnotbeeasilyloggedotherwise.
Subsystemsftp/usr/lib/ssh/sftp-server-fAUTHPRIV-lINFO
使用以下命令获取OpenSSH支持的加密方法:
$ssh-Qcipher
$ssh-Qcipher-auth
$ssh-Qmac
$ssh-Qkex
$ssh-Qkey
最后想要了解更多关于Linux发展前景趋势,请关注扣丁学堂Linux培训官网、微信等平台,扣丁学堂IT职业在线学习教育平台为您提供权威的Linux培训视频教程系统,通过千锋扣丁学堂金牌讲师在线录制的Linux视频教程课程,让你快速掌握Linux从入门到精通开发实战技能。扣丁学堂Linux技术交流群:659974587。