在Ubuntu系统中,/etc/securetty文件是控制哪些终端设备允许root用户直接登录的关键配置文件。当你通过串口(如/dev/ttyS0、/dev/ttyUSB0)连接服务器时,如果串口设备没有被列入/etc/securetty,那么root用户将无法通过该串口登录系统,即使密码正确也会被拒绝。解决方法很简单:将你的串口设备名称添加到/etc/securetty文件中即可。比如你使用的是第一个串口,就在文件末尾加一行"ttyS0",保存后root就能正常通过串口登录了。
这个机制看似简单,但在实际运维中非常重要。很多工程师在配置嵌入式设备、工控机、远程管理卡(如IPMI、iLO、iDRAC的串口重定向)时,经常遇到"明明密码对了却登不进去"的问题,十有八九就是/etc/securetty没有配置正确。下面我会从原理到实操,把这个问题彻底讲透。
什么是/etc/securetty文件/etc/securetty是一个纯文本文件,里面每一行写一个终端设备名称。它的作用是告诉系统的登录程序(如login、sshd、getty等):哪些终端被认为是"安全的",允许root用户在这些终端上直接登录。如果一个终端不在这个列表里,root登录请求就会被拒绝,普通用户不受影响。
在Ubuntu系统中,这个文件通常位于/etc/securetty,默认内容大致如下:
# /etc/securetty: list of terminals on which root is allowed to login. # See securetty(5) and login(1). console tty1 tty2 tty3 tty4 tty5 tty6 tty7 tty8 tty9 tty10 tty11 tty12 tty13 tty14 tty15 tty16 tty17 tty18 tty19 tty20 tty21 tty22 tty23 tty24 tty25 tty26 tty27 tty28 tty29 tty30 tty31 tty32 tty33 tty34 tty35 tty36 tty37 tty38 tty39 tty40 tty41 tty42 tty43 tty44 tty45 tty46 tty47 tty48 tty49 tty50 tty51 tty52 tty53 tty54 tty55 tty56 tty57 tty58 tty59 tty60 tty61 tty62 tty63
你会发现,默认列表里只有console和tty1到tty63这些虚拟控制台,完全没有串口设备。这就是为什么串口登录root会失败的根本原因。
串口设备在Linux中的命名规则在动手修改之前,你需要先搞清楚你的串口设备在系统中叫什么名字。Linux对串口设备有统一的命名规范:
传统的PC串口(COM口)对应的设备名是/dev/ttyS0、/dev/ttyS1、/dev/ttyS2、/dev/ttyS3,依次类推。ttyS0是第一个串口(COM1),ttyS1是第二个(COM2)。
USB转串口设备对应的名称通常是/dev/ttyUSB0、/dev/ttyUSB1、/dev/ttyUSB2等。
PCIe串口卡对应的可能是/dev/ttyS0、/dev/ttyS1,也可能是/dev/ttyP0、/dev/ttyP1,具体取决于驱动。
查看当前系统有哪些串口设备,可以用以下命令:
ls -l /dev/ttyS* /dev/ttyUSB* /dev/ttyACM*
或者用dmesg查看内核识别到的串口信息:
dmesg | grep tty
确认设备名后,记住只需要设备名部分(比如ttyS0),不需要写完整路径/dev/ttyS0。
如何修改/etc/securetty允许串口root登录操作步骤非常直接,用任何文本编辑器打开文件:
sudo nano /etc/securetty
或者用vim:
sudo vim /etc/securetty
在文件末尾添加你的串口设备名。比如你要允许通过第一个串口登录,就加:
ttyS0
如果你有多个串口都需要允许root登录,就逐行添加:
ttyS0 ttyS1 ttyUSB0
保存文件后,修改立即生效,不需要重启任何服务。下次通过串口登录时,root就可以正常输入密码进入系统了。
为什么系统要做这个限制很多人会问,为什么不直接允许所有终端都让root登录?这其实是一个安全设计理念。串口在很多场景下是物理可接触的,比如机房里的服务器后面板、嵌入式设备的调试口、工业现场的控制终端。如果任何人只要接上串口线就能以root身份登录,那安全风险极大。
/etc/securetty的设计思路是:只有系统管理员明确"信任"的终端,才允许root登录。默认只信任本地物理控制台(console和tty1-tty63),因为这些需要有人坐在机器前面才能操作。串口默认不被信任,需要管理员显式添加。
这种"默认拒绝、显式允许"的策略是Linux安全体系中非常经典的白名单思维。同样的逻辑也体现在/etc/hosts.allow、/etc/hosts.deny、PAM配置等多个层面。
串口登录的完整配置链条需要特别注意的是,/etc/securetty只是串口root登录的其中一个环节。要让串口登录完全工作,还需要确保整个登录链条都是通的。很多时候你改了securetty还是登不上,问题出在别的地方。
完整的链条包括以下几个部分:
第一,串口硬件要被系统正确识别,驱动要加载。用ls /dev/ttyS*确认设备存在。
第二,要有getty进程在串口上监听。传统系统用agetty或mingetty,systemd系统用serial-getty@.service。检查串口getty是否启用:
systemctl status serial-getty@ttyS0.service
如果没有启用,需要启用它:
sudo systemctl enable serial-getty@ttyS0.service sudo systemctl start serial-getty@ttyS0.service
第三,/etc/securetty要包含对应的串口设备名。
第四,如果你用的是SSH通过串口转发或者其他间接方式,还要确认sshd的配置没有额外限制。
这四个环节缺一不可,任何一个没配置好,串口root登录都会失败。
安全建议:是否真的需要root串口登录作为安全角度的建议,我要说一句实话:在生产环境中,尽量避免通过串口直接以root身份登录。更好的做法是:
用普通用户通过串口登录,然后用sudo提权执行需要的操作。这样所有操作都有审计日志,而且不会因为误操作直接破坏系统。
如果确实需要root串口登录(比如系统崩溃只有串口能访问的紧急情况),那么建议:
1. 只在必要的串口上添加securetty,不要把所有串口都放开。
2. 设置串口的波特率、流控等参数,防止暴力破解。可以在getty配置中限制登录尝试次数。
3. 物理层面保护串口接口,比如加锁、封堵不用的串口口。
4. 考虑使用串口控制台+带外管理的方式,而不是让串口直接暴露在网络可达的位置。
不同Ubuntu版本的差异在Ubuntu 16.04、18.04、20.04、22.04、24.04等版本中,/etc/securetty的机制基本一致,但有一些细节差异。
较新的Ubuntu版本(20.04以后)更多依赖systemd和PAM来管理登录,/etc/securetty的实际作用范围可能会受到PAM配置的影响。具体来说,PAM模块pam_securetty.so会读取这个文件。如果你的PAM配置中没有加载这个模块,那改securetty也没用。
检查PAM中是否启用了securetty模块,查看/etc/pam.d/login文件:
grep securetty /etc/pam.d/login
正常应该看到类似这样的行:
auth required pam_securetty.so
如果没有这行,说明securetty检查被跳过了,你需要手动添加。
常见问题排查在实际操作中,以下几个问题最常见:
问题一:改了securetty还是登不上。排查方法:先确认getty服务在运行,再确认设备名写对了(注意大小写,ttyS0和ttys0是不同的),最后检查PAM配置。
问题二:不知道自己的串口叫什么。用dmesg | grep -i serial或者ls /dev/tty*来查看,也可以在BIOS/UEFI中查看串口分配。
问题三:串口登录时出现"Login incorrect"但密码明明对。这通常就是securetty没配置的典型症状,root被拒绝了但系统不会明确告诉你原因。
问题四:多串口环境下搞混了设备。建议用udev规则给串口创建固定的符号链接,比如/dev/console_serial,这样不管硬件怎么变,名字都不会乱。
总结/etc/securetty是Ubuntu系统中控制root终端登录权限的核心文件之一,对串口登录的限制是其默认安全策略的体现。解决串口root登录问题的核心操作就是把对应的串口设备名(如ttyS0、ttyUSB0)添加到这个文件中。但要确保完整可用,还需要确认串口getty服务已启用、PAM模块已加载、设备驱动正常。在安全实践中,建议优先使用普通用户+sudo的方式通过串口管理系统,只在紧急维护场景下才开放root串口登录,并做好物理和逻辑层面的双重防护。
