getty(get tty)是Linux系统中用于管理终端登录的程序,负责在终端上显示登录提示,验证用户身份,并启动用户会话。它是系统初始化进程的重要组成部分,管理虚拟控制台和串行终端的登录界面。
getty实现包括agetty、mingetty、mgetty等,它们各有特点,适用于不同的场景。
# 基本格式
getty [选项] 波特率 终端类型 [终端设备]
# 常用格式
getty 38400 tty1
getty -L 115200 ttyS0 vt100
getty -I "欢迎登录" tty2
agetty [选项] 端口 终端类型
agetty -l /bin/login tty1 linux
agetty --noclear tty2
mingetty [选项] tty
mingetty --autologin root tty1
mingetty tty2
| 类型 | 描述 | 特点 | 适用场景 |
|---|---|---|---|
agetty |
GNU getty实现,功能最全 | 支持串行和虚拟终端,可配置性强 | 通用Linux系统,需要丰富功能 |
mingetty |
最小化getty,轻量级 | 只支持虚拟终端,功能简单 | 嵌入式系统,资源有限环境 |
mgetty |
专门用于调制解调器 | 支持传真和数据通信 | 调制解调器拨入系统 |
uugetty |
UUCIP getty | 文件传输和邮件处理 | 老式UUCP系统 |
fbgetty |
FrameBuffer getty | 支持图形控制台 | 图形化启动环境 |
配置虚拟控制台(tty1-tty6):
# 查看当前活动的虚拟控制台
who
# 输出示例:
# root tty1 2023-10-01 10:00
# user1 tty2 2023-10-01 10:05
# 查看所有tty设备
ls -la /dev/tty*
# 虚拟控制台:/dev/tty1, /dev/tty2, ...
# 在tty1上启动getty(手动启动)
sudo agetty tty1 linux
# 或
sudo getty 38400 tty1
# 配置自动登录(agetty)
# 在systemd服务文件中添加:--autologin root
# 或通过编辑/etc/inittab(sysvinit系统)
# 禁用虚拟控制台
# 编辑systemd服务文件,注释或删除对应配置
# 或运行:
sudo systemctl stop getty@tty3.service
sudo systemctl disable getty@tty3.service
# 启用虚拟控制台
sudo systemctl start getty@tty3.service
sudo systemctl enable getty@tty3.service
# 查看getty服务状态
sudo systemctl status getty@tty1.service
sudo systemctl status getty@tty2.service
# 重启getty服务
sudo systemctl restart getty@tty1.service
# 查看所有tty的getty进程
ps aux | grep getty
# 输出示例:
# root 1234 0.0 0.1 12345 6789 tty1 Ss+ 10:00 0:00 /sbin/agetty --noclear tty1 linux
配置串行端口作为登录终端:
# 查看串行端口
ls -la /dev/ttyS*
# 输出示例:/dev/ttyS0, /dev/ttyS1, /dev/ttyUSB0
# 设置串行端口权限
sudo chmod 666 /dev/ttyS0
# 或添加用户到dialout组
sudo usermod -a -G dialout $USER
# 在ttyS0上启动getty(波特率115200)
sudo agetty -L 115200 ttyS0 vt100
# 传统getty
sudo getty -L ttyS0 115200 vt100
# 配置自动登录串行终端
sudo agetty -L 115200 --autologin root ttyS0 vt100
# 在系统启动时启用串行终端
# 对于systemd系统,创建服务文件:
sudo nano /etc/systemd/system/serial-getty@ttyS0.service
# 内容:
[Unit]
Description=Serial Getty on %I
BindTo=dev-%i.device
After=dev-%i.device systemd-user-sessions.service
[Service]
ExecStart=-/sbin/agetty -L 115200 %I $TERM
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
KillMode=process
[Install]
WantedBy=multi-user.target
# 启用服务
sudo systemctl enable serial-getty@ttyS0.service
sudo systemctl start serial-getty@ttyS0.service
# 查看串行终端状态
sudo systemctl status serial-getty@ttyS0.service
# 测试串行终端连接
# 使用minicom或screen连接
sudo minicom -D /dev/ttyS0
# 或
screen /dev/ttyS0 115200
自定义登录提示和信息:
# 编辑issue文件(显示在登录提示前)
sudo nano /etc/issue
# 添加自定义信息,例如:
# 欢迎使用 MyLinux 系统
# 内核版本: \n
# 系统时间: \t
# 特殊字符:
# \d - 当前日期
# \l - 当前终端
# \m - 机器架构
# \n - 主机名
# \o - 域名
# \r - 内核版本
# \t - 当前时间
# \s - 操作系统名称
# \v - 内核版本
# 编辑issue.net文件(网络登录显示)
sudo nano /etc/issue.net
# 网络登录时显示的信息
# 测试issue文件
sudo agetty --issue-file /etc/issue tty1 linux
# 创建每个tty不同的issue文件
sudo nano /etc/issue.tty1
# 内容:这是tty1控制台
sudo agetty --issue-file /etc/issue.tty1 tty1 linux
# 在agetty中使用自定义欢迎信息
sudo agetty -I "欢迎登录生产服务器" tty1 linux
# 禁用issue文件显示
sudo agetty --noissue tty1 linux
# 修改登录提示文字
# 编辑/etc/login.defs
sudo nano /etc/login.defs
# 修改:
# LOGIN_STRING "MyLinux Login: "
# 或通过agetty参数
sudo agetty --login-options "-h MyServer" tty1 linux
# 使用自定义登录程序
sudo agetty --login-program /bin/mylogin tty1 linux
# 创建自定义登录脚本
sudo nano /usr/local/bin/mylogin
#!/bin/bash
echo "自定义登录程序"
echo -n "用户名: "
read username
echo -n "密码: "
read -s password
echo
# 这里添加认证逻辑
# 成功后启动shell
exec /bin/bash
# 设置权限
sudo chmod +x /usr/local/bin/mylogin
# 使用自定义登录程序
sudo agetty --login-program /usr/local/bin/mylogin tty2 linux
在systemd系统中配置getty:
# 查看所有getty服务
systemctl list-units --type=service | grep getty
# 输出示例:
# getty@tty1.service loaded active running Getty on tty1
# getty@tty2.service loaded active running Getty on tty2
# 查看特定getty服务文件
systemctl cat getty@tty1.service
# 或
cat /usr/lib/systemd/system/getty@.service
# 创建自定义getty配置
sudo mkdir -p /etc/systemd/system/getty@tty1.service.d/
sudo nano /etc/systemd/system/getty@tty1.service.d/override.conf
# 内容:
[Service]
# 自动登录
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear %I $TERM
# 或自定义选项
# ExecStart=-/sbin/agetty -I "生产服务器" --noissue %I $TERM
# 重新加载systemd配置
sudo systemctl daemon-reload
sudo systemctl restart getty@tty1.service
# 创建新的getty实例
sudo cp /usr/lib/systemd/system/getty@.service /etc/systemd/system/getty-special@.service
sudo nano /etc/systemd/system/getty-special@.service
# 修改ExecStart行
# 启用新的getty实例
sudo systemctl enable getty-special@tty3.service
sudo systemctl start getty-special@tty3.service
# 修改默认的getty参数
# 编辑/etc/systemd/logind.conf
sudo nano /etc/systemd/logind.conf
# 修改:
# NAutoVTs=6 # 自动创建的虚拟终端数量
# ReserveVT=6 # 为显示管理器保留的VT
# KillUserProcesses=yes # 用户注销时杀死其进程
# 重新启动logind服务
sudo systemctl restart systemd-logind
# 查看当前活动的虚拟终端
loginctl list-sessions
# 或
loginctl
# 强制注销特定tty的用户
sudo loginctl terminate-session 会话ID
# 或
sudo pkill -9 -t tty2
高级getty配置和自动化脚本:
#!/bin/bash
# 文件名: configure-getty.sh
# 自动配置getty脚本
# 定义颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# 函数:检查命令是否存在
check_command() {
if ! command -v $1 &> /dev/null; then
echo -e "${RED}错误: $1 命令未找到${NC}"
exit 1
fi
}
# 检查必要命令
check_command agetty
check_command systemctl
# 配置虚拟终端数量
configure_vt_count() {
echo "配置虚拟终端数量..."
# 当前VT数量
CURRENT_VT=$(grep -i "^NAutoVTs" /etc/systemd/logind.conf 2>/dev/null | cut -d= -f2 | tr -d ' ')
if [ -z "$CURRENT_VT" ]; then
CURRENT_VT=6
fi
read -p "当前虚拟终端数量: $CURRENT_VT,请输入新的数量 (1-12): " NEW_VT
if [[ $NEW_VT =~ ^[0-9]+$ ]] && [ $NEW_VT -ge 1 ] && [ $NEW_VT -le 12 ]; then
# 备份原文件
sudo cp /etc/systemd/logind.conf /etc/systemd/logind.conf.backup.$(date +%Y%m%d)
# 更新配置
if grep -q "^NAutoVTs" /etc/systemd/logind.conf; then
sudo sed -i "s/^NAutoVTs=.*/NAutoVTs=$NEW_VT/" /etc/systemd/logind.conf
else
echo "NAutoVTs=$NEW_VT" | sudo tee -a /etc/systemd/logind.conf
fi
# 重启服务
sudo systemctl restart systemd-logind
echo -e "${GREEN}虚拟终端数量已设置为 $NEW_VT${NC}"
else
echo -e "${RED}无效的虚拟终端数量${NC}"
fi
}
# 配置自动登录
configure_autologin() {
echo "配置自动登录..."
read -p "要自动登录的tty编号 (如1,2,3): " TTY_NUM
read -p "自动登录的用户名: " USERNAME
if id "$USERNAME" &>/dev/null; then
# 创建覆盖配置文件
OVERRIDE_DIR="/etc/systemd/system/getty@tty${TTY_NUM}.service.d"
sudo mkdir -p $OVERRIDE_DIR
cat << EOF | sudo tee $OVERRIDE_DIR/autologin.conf
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin $USERNAME --noclear %I \$TERM
EOF
# 重新加载配置
sudo systemctl daemon-reload
sudo systemctl restart getty@tty${TTY_NUM}.service
echo -e "${GREEN}tty${TTY_NUM} 已配置为自动登录用户 $USERNAME${NC}"
else
echo -e "${RED}用户 $USERNAME 不存在${NC}"
fi
}
# 配置串行终端
configure_serial() {
echo "配置串行终端..."
read -p "串行端口 (如ttyS0, ttyUSB0): " SERIAL_PORT
read -p "波特率 (如115200, 9600): " BAUD_RATE
# 检查串行端口是否存在
if [ ! -c "/dev/$SERIAL_PORT" ]; then
echo -e "${RED}串行端口 /dev/$SERIAL_PORT 不存在${NC}"
return
fi
# 创建串行getty服务
cat << EOF | sudo tee /etc/systemd/system/serial-getty@${SERIAL_PORT}.service
[Unit]
Description=Serial Getty on %I
BindTo=dev-%i.device
After=dev-%i.device systemd-user-sessions.service
[Service]
ExecStart=-/sbin/agetty -L $BAUD_RATE %I \$TERM
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
KillMode=process
[Install]
WantedBy=multi-user.target
EOF
# 启用服务
sudo systemctl daemon-reload
sudo systemctl enable serial-getty@${SERIAL_PORT}.service
sudo systemctl start serial-getty@${SERIAL_PORT}.service
echo -e "${GREEN}串行终端 $SERIAL_PORT 已配置,波特率 $BAUD_RATE${NC}"
}
# 主菜单
main_menu() {
while true; do
echo ""
echo "=== Getty配置菜单 ==="
echo "1. 配置虚拟终端数量"
echo "2. 配置自动登录"
echo "3. 配置串行终端"
echo "4. 查看当前配置"
echo "5. 重启所有getty服务"
echo "6. 退出"
echo ""
read -p "请选择操作 (1-6): " choice
case $choice in
1)
configure_vt_count
;;
2)
configure_autologin
;;
3)
configure_serial
;;
4)
echo "=== 当前getty配置 ==="
echo "虚拟终端:"
systemctl list-units --type=service | grep getty@tty
echo ""
echo "串行终端:"
systemctl list-units --type=service | grep serial-getty
echo ""
echo "logind配置:"
grep -E "^(NAutoVTs|ReserveVT)" /etc/systemd/logind.conf 2>/dev/null || echo "使用默认配置"
;;
5)
echo "重启所有getty服务..."
sudo systemctl restart getty@tty*.service
sudo systemctl restart serial-getty@*.service 2>/dev/null
echo -e "${GREEN}所有getty服务已重启${NC}"
;;
6)
echo "退出配置脚本"
exit 0
;;
*)
echo -e "${RED}无效的选择${NC}"
;;
esac
done
}
# 运行主菜单
main_menu
getty故障排查和安全增强:
# 1. 检查getty是否运行
ps aux | grep getty
# 应该看到agetty或getty进程
# 2. 检查tty设备权限
ls -la /dev/tty*
# 确保用户有访问权限
# 3. 查看系统日志
sudo journalctl -u getty@tty1.service
sudo journalctl -u getty@tty1.service -f # 实时查看
sudo dmesg | grep tty
# 4. 手动测试getty
sudo pkill -9 -t tty1
sudo agetty tty1 linux
# 然后切换到tty1查看效果
# 5. 检查登录问题
# 查看/etc/login.defs配置
# 检查PAM配置
cat /etc/pam.d/login
cat /etc/pam.d/system-auth
# 6. 安全增强:限制root登录
# 编辑/etc/securetty
sudo nano /etc/securetty
# 注释掉允许root登录的tty
# 例如,只允许tty1
# tty1
# 其他行注释掉
# 7. 安全增强:禁用特定tty
sudo systemctl mask getty@tty6.service
# 或删除/etc/systemd/system/getty.target.wants/中的链接
# 8. 安全增强:设置登录超时
# 修改agetty参数
sudo nano /etc/systemd/system/getty@tty1.service.d/timeout.conf
[Service]
ExecStart=
ExecStart=-/sbin/agetty -t 60 --noclear %I $TERM # 60秒超时
# 9. 安全增强:限制登录尝试次数
# 配置PAM
sudo nano /etc/pam.d/login
# 添加或修改:
# auth required pam_tally2.so deny=3 unlock_time=300
# 3次失败后锁定5分钟
# 10. 检查登录记录
last
lastb # 失败的登录尝试
who
w
# 11. 查看utmp/wtmp记录
# utmp: 当前登录用户
# wtmp: 历史登录记录
# 查看二进制文件
sudo utmpdump /var/run/utmp
sudo utmpdump /var/log/wtmp
# 12. 重置tty
sudo stty sane < /dev/tty1
sudo reset
# 13. 检查终端类型
echo $TERM
# 应为linux, xterm, vt100等
# 14. 测试终端功能
tput lines
tput cols
# 显示终端行列数
# 15. 修复损坏的tty
# 如果tty无响应,尝试:
sudo chvt 2 # 切换到tty2
sudo chvt 1 # 切换回tty1
# 或
sudo systemctl restart getty@tty1.service
# 16. 启用串行终端安全
# 只允许特定用户通过串行登录
# 在PAM配置中添加串行终端检查
sudo nano /etc/pam.d/login
# 添加:
# auth [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so
# 然后配置/etc/securetty包含串行终端
现代Linux系统(systemd)中的getty配置:
/usr/lib/systemd/system/getty@.service/etc/systemd/system/getty@tty1.service.d//etc/systemd/logind.confsystemctl, loginctl传统SysV init系统中的getty配置:
/etc/inittabinit, telinit/etc/rc.d/rc*.d//etc/init.d/# 传统inittab配置
# 格式:id:runlevels:action:process
# 虚拟控制台
1:2345:respawn:/sbin/getty 38400 tty1
2:2345:respawn:/sbin/getty 38400 tty2
3:2345:respawn:/sbin/getty 38400 tty3
4:2345:respawn:/sbin/getty 38400 tty4
5:2345:respawn:/sbin/getty 38400 tty5
6:2345:respawn:/sbin/getty 38400 tty6
# 串行终端
S0:2345:respawn:/sbin/getty -L ttyS0 115200 vt100
S1:2345:respawn:/sbin/getty -L ttyS1 9600 vt100
# 自动登录
A1:2345:respawn:/sbin/getty -n -l /bin/autologin 38400 tty1
# 特殊配置
# 单用户模式
~:S:wait:/sbin/sulogin
# 重启init
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
# 应用配置
sudo init q
# 或
sudo telinit q
systemd系统:
# 编辑/etc/systemd/logind.conf
sudo nano /etc/systemd/logind.conf
# 修改:
NAutoVTs=8
ReserveVT=8
# 重启服务
sudo systemctl restart systemd-logind
# 立即生效(无需重启)
sudo systemctl start getty@tty7.service
sudo systemctl start getty@tty8.service
sudo systemctl enable getty@tty7.service
sudo systemctl enable getty@tty8.service
SysV init系统:
# 编辑/etc/inittab
sudo nano /etc/inittab
# 添加:
7:2345:respawn:/sbin/getty 38400 tty7
8:2345:respawn:/sbin/getty 38400 tty8
# 重新读取配置
sudo init q
# 或
sudo telinit q
注意:Linux内核通常支持最多63个虚拟控制台,但一般配置6-12个。
排查步骤:
ps aux | grep tty1
# 如果没有agetty进程,重启服务
sudo systemctl restart getty@tty1.service
ls -la /dev/tty1
# 应该显示 crw--w----
# 如果没有,创建设备文件
sudo mknod /dev/tty1 c 4 1
sudo chmod 620 /dev/tty1
sudo chown root:tty /dev/tty1
# 从其他tty切换
sudo chvt 2
sudo chvt 1
# 或使用快捷键 Ctrl+Alt+F1, Ctrl+Alt+F2
sudo stty sane < /dev/tty1
sudo reset
# 或发送重置序列
echo -e "\033c" > /dev/tty1
sudo journalctl -u getty@tty1.service
sudo dmesg | grep tty
sudo pkill -9 -t tty1
sudo systemctl restart getty@tty1.service
方法1:通过/etc/securetty限制root登录
# 编辑/etc/securetty
sudo nano /etc/securetty
# 只允许特定tty
tty1
tty2
# 注释掉其他行
# 不允许root通过串行登录
# ttyS0
# ttyS1
方法2:通过PAM限制用户
# 编辑/etc/pam.d/login
sudo nano /etc/pam.d/login
# 添加:
auth required pam_listfile.so onerr=fail item=user sense=deny file=/etc/login.deny
# 然后创建拒绝列表
sudo nano /etc/login.deny
# 添加要拒绝的用户名,每行一个
baduser1
baduser2
方法3:通过shell限制
# 修改用户的shell为/sbin/nologin
sudo usermod -s /sbin/nologin username
# 或
sudo chsh -s /sbin/nologin username
# 创建自定义nologin消息
sudo nano /etc/nologin.txt
# 添加拒绝登录消息
# 然后设置用户shell
sudo usermod -s /sbin/nologin username
方法4:通过/etc/security/access.conf
# 编辑/etc/security/access.conf
sudo nano /etc/security/access.conf
# 添加:
-:baduser1:ALL
-:baduser2:tty1 tty2
# 格式:权限:用户:来源
# - 表示拒绝,+ 表示允许
| 特性 | agetty |
mingetty |
|---|---|---|
| 功能完整性 | 功能完整,支持丰富选项 | 最小化实现,功能有限 |
| 终端支持 | 虚拟终端和串行终端 | 仅虚拟终端 |
| 配置选项 | 丰富的命令行选项 | 很少的选项 |
| 发行版默认 | 多数现代发行版 | 某些最小化发行版 |
| 资源占用 | 较高 | 极低 |
| 自动登录 | 支持 | 支持(Red Hat系) |
| issue文件 | 支持 | 不支持 |
选择建议: