在内网运维中,最容易被击穿的往往不是防火墙,而是那套脆弱的密码体系。弱口令、重复密码、哈希传递攻击,这些老生常谈的问题至今仍在困扰着多数企业的数据中心。把内网服务器的SSH或RDP登录从传统的密码验证迁移到Kerberos认证,是目前性价比最高、实施难度最低的安全加固手段之一。它解决的核心问题只有一个:让密码本身不再需要在网络上传输,也不再以可逆形式存储在任何地方。
Kerberos为什么能解决密码传输的致命缺陷传统的密码登录流程存在一个根本性隐患:当你输入密码时,密码或其哈希值必须被发送到目标服务器进行比对。即便使用了TLS加密通道,目标服务器在验证的那一刻依然能拿到你的明文密码或等效凭证。一旦这台服务器被攻陷,攻击者就能直接收集到所有登录过的凭据。Kerberos的聪明之处在于,它引入了一个可信的第三方——密钥分发中心,也就是KDC。整个验证过程变成了票据交换,你的密码自始至终没有离开过你的客户端,目标服务器也从未见过你的密码。
具体流程可以这样理解:客户端先向KDC证明自己的身份,通常是用密码的哈希加密一个时间戳发送过去。KDC验证通过后,返回一个用客户端密钥加密的会话密钥,以及一个用服务器密钥加密的票据。客户端拿到这个票据后,直接发给目标服务器。服务器用自己的密钥解开票据,发现里面包含了客户端的身份信息和一把临时会话密钥,于是双方就完成了双向认证。整个过程中,密码没有在网络上传输,服务器也没有接触到任何长期密钥材料。
搭建Kerberos域环境的硬件和软件准备实施Kerberos认证不需要采购额外的商业软件,Linux生态中的MIT Kerberos就是业界标准实现,完全开源且久经考验。你需要准备一台作为KDC的服务器,建议使用独立的虚拟机或物理机,不要和业务应用混跑。操作系统推荐Rocky Linux 9或Ubuntu 22.04 LTS,这两者对Kerberos包的支持都很完善。内存方面,KDC服务本身占用极低,1GB内存就足够,但考虑到日志和审计需求,建议分配4GB。磁盘空间预留20GB以上,主要是为了存放审计日志。
网络规划上,KDC服务器必须拥有固定的IP地址和完全限定域名,比如kdc.internal.lan。Kerberos对时间同步极其敏感,客户端和KDC之间的时间差默认不能超过5分钟,否则认证会直接拒绝。这意味着你必须在整个域内部署NTP服务,KDC本身作为NTP服务器,所有成员服务器和客户端都从KDC同步时间。这个细节在实际部署中经常被忽略,导致认证失败后排查很久才发现是时钟偏差问题。
KDC服务的安装与基础配置以Rocky Linux 9为例,安装MIT Kerberos只需要一行命令:
dnf install -y krb5-server krb5-libs krb5-workstation
安装完成后,需要编辑两个核心配置文件。首先是/etc/krb5.conf,这个文件定义了域的基本信息和KDC的位置。一个典型的内网域配置如下:
[libdefaults]
default_realm = INTERNAL.LAN
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
[realms]
INTERNAL.LAN = {
kdc = kdc.internal.lan
admin_server = kdc.internal.lan
}
[domain_realm]
.internal.lan = INTERNAL.LAN
internal.lan = INTERNAL.LAN
接下来是/var/kerberos/krb5kdc/kdc.conf,这个文件控制KDC数据库的后端类型和票据策略。推荐使用默认的Berkeley DB后端,密码策略可以根据企业安全基线调整,比如要求密码长度至少12位,包含大小写字母和数字:
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
INTERNAL.LAN = {
master_key_type = aes256-cts-hmac-sha384-192
acl_file = /var/kerberos/krb5kdc/kadm5.acl
dict_file = /usr/share/dict/words
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
supported_enctypes = aes256-cts-hmac-sha384-192:normal aes128-cts-hmac-sha256-128:normal
max_life = 24h 0m 0s
max_renewable_life = 7d 0h 0m 0s
}
配置文件就绪后,使用kdb5_util命令创建Kerberos数据库,这个过程中会要求设置数据库的主密钥,务必妥善保管,它是整个域的根密钥:
kdb5_util create -s -r INTERNAL.LAN
启动KDC和管理服务,并设置开机自启:
systemctl enable --now krb5kdc kadmin创建主体并配置服务端SSH接受Kerberos认证
Kerberos中的主体代表用户或服务。你需要为每个登录用户创建用户主体,为每台目标服务器创建服务主体。服务主体的格式是host/主机名@域,这是SSH服务使用的标准主体名称。先在KDC上使用kadmin.local工具操作:
kadmin.local addprinc user1 addprinc -randkey host/appserver.internal.lan ktadd -k /tmp/appserver.keytab host/appserver.internal.lan
上面的命令创建了一个用户主体user1,以及应用服务器appserver.internal.lan的服务主体。ktadd命令将服务主体的密钥导出到keytab文件中,这个文件相当于服务端的密码本,需要安全地传输到应用服务器上。传输完成后,在应用服务器上把keytab文件移动到/etc/krb5.keytab,并设置权限为600,属主为root。
应用服务器端还需要配置SSH守护进程以接受Kerberos认证。编辑/etc/ssh/sshd_config,确保以下参数设置正确:
KerberosAuthentication yes GSSAPIAuthentication yes GSSAPICleanupCredentials yes UsePAM yes
修改后重启sshd服务。此时,如果你的客户端也配置了相同的Kerberos域信息,并且用户已经通过kinit命令获取了票据,那么SSH登录时就不需要输入密码了。客户端执行kinit user1,输入密码获取票据后,使用ssh user1@appserver.internal.lan即可直接登录。这个过程中,密码只用于在客户端本地解密从KDC获取的票据,从未通过网络发送。
从密码到无密码:票据的生命周期管理很多运维人员刚接触Kerberos时,会对票据的概念感到陌生。可以这样理解:票据是一张有时效性的临时身份证。用户通过密码获取的票据称为TGT,有效期通常设为24小时。在这24小时内,用户访问任何已注册Kerberos服务的服务器时,客户端会自动用TGT向KDC换取针对该服务器的服务票据,整个过程对用户透明。这意味着用户只需要在上班时执行一次kinit,一整天都不需要再输入密码。
这种机制带来了两个安全收益。第一,密码的使用频率大幅降低,被键盘记录器或肩窥的风险随之下降。第二,即使攻击者截获了服务票据,它的有效期通常只有几分钟到几小时,而且只能用于访问特定服务,无法像密码那样长期通用。你还可以通过配置约束委派,限制服务票据的转发范围,防止票据被滥用于横向移动。
强制Kerberos认证并禁用密码回退部署Kerberos的初期,通常会保留密码认证作为备用。但当环境稳定运行后,就应该果断关闭密码登录,否则攻击者依然可以通过暴力破解或凭据填充绕过整个Kerberos体系。在SSH配置中,将PasswordAuthentication设为no,ChallengeResponseAuthentication也设为no,只保留GSSAPI认证。对于需要紧急访问的场景,可以保留基于密钥的认证作为最后手段,但密钥必须严格管理,定期轮换。
这个步骤在实施时往往会遇到阻力,因为运维团队习惯了密码登录的便利性。但必须明确一点:保留密码登录就等于在Kerberos这道钢门上留了一扇没锁的窗户。攻击者不会因为你部署了Kerberos就放弃密码攻击,他们只会更专注于寻找那些仍然开启密码登录的服务器。所以全量关闭密码登录是完成安全闭环的关键一步。
跨平台场景的Kerberos集成内网环境通常不是单一的操作系统。Windows域控制器本身就是Kerberos的完整实现,如果你的内网已经有AD域,那么Linux服务器完全可以加入这个域,使用AD作为KDC。Linux端使用realmd和sssd组合,几条命令就能完成域加入,AD中的用户可以直接用Kerberos票据登录Linux服务器。反过来,如果是纯Linux环境自建的MIT Kerberos域,Windows客户端也可以通过配置krb5.ini文件来参与认证,只是需要手动管理主机主体,没有AD那样的一键加域体验。
对于网络设备,主流的企业级交换机、路由器大多支持通过RADIUS与Kerberos联动,或者直接配置为Kerberos客户端。数据库层面,PostgreSQL和MySQL都支持GSSAPI认证,可以将数据库登录也纳入Kerberos统一管理。这样一来,整个内网的所有核心服务都共享同一套身份认证体系,审计和回收权限都变得极其高效。
常见故障的排查思路Kerberos认证失败时,错误信息往往不够直观。最常见的几种情况:时钟不同步会导致“预认证失败”,检查客户端和KDC的系统时间,确保NTP正常工作。DNS解析错误会导致“找不到KDC”,确认所有参与方都能正确解析KDC的FQDN,正向和反向解析都要检查。keytab文件权限不对会导致服务端无法解密票据,确保keytab文件属主为服务运行用户,权限为600或400。
还有一个容易被忽视的问题是加密类型不匹配。较新的MIT Kerberos版本默认禁用了老旧的DES和3DES加密,如果客户端或服务端使用了过时的配置,协商加密类型时就会失败。统一使用AES256-SHA2系列的加密类型,并在krb5.conf中明确指定supported_enctypes,可以避免这类兼容性问题。
将Kerberos与多因素认证结合Kerberos本身解决的是单因素认证的安全传输问题,但它并不排斥多因素认证。你可以在KDC层面集成OTP模块,要求用户在kinit时除了密码还要提供一次性验证码。MIT Kerberos支持通过PKINIT扩展使用智能卡或证书进行预认证,这样用户就不需要记忆密码,直接使用硬件令牌完成初始认证。对于安全等级要求更高的环境,这种组合方案既保留了Kerberos票据体系的便利性,又弥补了静态密码的固有弱点。
实施PKINIT需要搭建一个内部CA,为每个用户签发客户端证书。KDC配置中启用PKINIT插件,指定信任的CA证书路径。用户端使用kinit -X X509_user_identity=证书路径的方式获取票据。整个过程对后续的服务访问完全透明,票据一旦获取,后续流程与密码方式完全一致。
审计与监控的落地部署Kerberos后,所有认证事件都集中在KDC日志中,这为安全审计提供了极大的便利。krb5kdc服务的日志默认记录在系统日志中,可以通过journalctl或/var/log/krb5kdc.log查看。每一次票据请求、每一次认证失败,都有详细记录,包括请求来源IP、请求的服务主体、时间戳等。将这些日志接入SIEM系统,设置异常告警规则,比如短时间内大量认证失败、非工作时间的管理员登录、从未见过的客户端IP请求票据等,可以及时发现攻击行为。
另外,定期审查keytab文件的分布和使用情况也很重要。每个keytab文件都代表着一个服务身份的凭据,如果某个服务已经下线但keytab没有被回收,这个凭据就可能被滥用。建立keytab的生命周期管理流程,服务的上线和下线都要同步更新KDC中的主体和keytab文件。
内网服务器登录的安全性提升,从来不是靠堆砌安全产品实现的。把密码从登录流程中剔除,用Kerberos票据替代密码在网络上的传输,这个改变直接消除了哈希传递、凭据窃取、暴力破解等一系列攻击面。而且这套方案完全基于开源软件,没有授权费用,实施周期短,对现有业务影响小。对于任何重视内网安全的企业来说,这都应该是优先推进的基础设施改造项目。
