开机第一件事是什么?输入密码!你可能习以为常,但在这简单的敲击回车背后,Linux 已经悄悄启动了一整套严密的登录体系。今天,我们一起走进这个看似普通却至关重要的流程。
一、前言:从一串密码说起
作为一名程序员,每次打开电脑,首先面对的就是登录界面。Windows 的图形界面大家都熟悉,而 Linux 的终端登录界面,简洁而纯粹,深得我心。
最初我也曾疑惑:这个黑乎乎的界面靠谱吗?登录是怎么运作的?安全性又如何保障?直到深入源码,才发现原来这背后,是一整套严密、模块化的设计。
本篇文章将带你一步步揭开 Linux 登录系统的面纱,从界面启动、用户验证到 shell 启动,全面解析其运行机制和背后的源码实现。
二、第一道门:登录界面的出现
Linux 系统启动后,首先出现的就是我们熟悉的终端登录界面。这一界面,最经典的就是由 mingetty 程序负责。
🎯 mingetty 是什么?
mingetty 是一个轻量级的终端登录管理器,它的核心职责包括:
-
初始化终端设备(如
/dev/tty1、/dev/tty2) -
设置终端属性(比如关闭密码回显)
-
显示登录提示,等待用户输入用户名
📌 示例源码:
int tty_fd = open("/dev/tty1", O_RDWR | O_NOCTTY);
if (tty_fd == -1) {
perror("Failed to open tty");
exit(EXIT_FAILURE);
}
接着,它会设置终端属性,关闭回显功能:
struct termios new_termios;
tcgetattr(tty_fd, &new_termios);
new_termios.c_lflag &= ~(ICANON | ECHO);
tcsetattr(tty_fd, TCSANOW, &new_termios);
此时,你看到的“login:”提示,就来自它!
三、核心大脑:login 程序的验证机制
用户输入用户名之后,系统会将控制权交给 login 程序,它是登录系统的核心组件。
1. 检查用户名有效性
如果是普通用户,而且系统中存在 /etc/nologin 文件,系统会直接拒绝登录,并显示该文件的内容。这通常用于维护期间,防止用户干扰系统操作。
if (strcmp(username, "root") != 0 && access("/etc/nologin", F_OK) == 0) {
FILE *nologin_file = fopen("/etc/nologin", "r");
if (nologin_file) {
char buffer[1024];
while (fgets(buffer, sizeof(buffer), nologin_file) != NULL) {
write(STDOUT_FILENO, buffer, strlen(buffer));
}
fclose(nologin_file);
}
exit(EXIT_FAILURE);
}
2. root 用户登录控制
Linux 对 root 用户的登录限制更严:
-
只有
/etc/securetty文件中列出的终端,root 才能登录; -
如果该文件不存在,root 可在任意终端登录。
判断逻辑如下:
int is_secure_terminal(const char *tty_name) {
FILE *securetty_file = fopen("/etc/securetty", "r");
if (securetty_file) {
char buffer[1024];
while (fgets(buffer, sizeof(buffer), securetty_file) != NULL) {
buffer[strcspn(buffer, "\n")] = 0;
if (strcmp(buffer, tty_name) == 0) {
fclose(securetty_file);
return 1;
}
}
fclose(securetty_file);
}
return 0;
}
四、密码验证:加密算法保障安全
验证用户名之后,下一步是密码验证。Linux 系统通常使用 /etc/shadow 文件存储加密后的密码。
验证流程包括:
-
读取用户密码的哈希值;
-
对用户输入的密码进行加密;
-
比对是否一致。
示例代码:
#include <shadow.h>
#include <crypt.h>
int verify_password(const char *username, const char *password) {
struct spwd *sp = getspnam(username);
if (sp == NULL) return 0;
char *encrypted = crypt(password, sp->sp_pwdp);
if (encrypted != NULL && strcmp(encrypted, sp->sp_pwdp) == 0) {
return 1;
}
return 0;
}
大部分现代系统使用的是 SHA-512 加密方式,兼顾安全性和性能。
五、会话管理与 Shell 启动
通过验证后,login 会为用户创建一个新的会话,并启动用户的默认 shell(如 /bin/bash)。
创建会话:
pid_t pid = setsid();
if (pid == -1) {
perror("Failed to create new session");
exit(EXIT_FAILURE);
}
启动 shell:
struct passwd *pw = getpwnam(username);
if (pw == NULL) {
perror("Failed to get user information");
exit(EXIT_FAILURE);
}
char *shell_path = pw->pw_shell;
char *args[] = {shell_path, NULL};
execve(shell_path, args, environ);
此时,熟悉的命令提示符出现,用户就真正“进入系统”了。
六、高级扩展:用户终端限制(/etc/usertty)
除了 securetty 对 root 的限制,Linux 还支持通过 /etc/usertty 文件,对普通用户进行终端访问限制。虽然这在实际中不常用,但在高安全场景下非常实用。
七、总结:简单背后的极致严谨
Linux 登录系统是一套模块化、严谨、安全性高的体系:
-
mingetty 负责终端初始化;
-
login 负责验证、权限控制;
-
shadow、passwd、securetty 多文件配合实现安全机制;
-
execve 实现 shell 的最终启动。
每一步都至关重要,任何一个环节出错,都可能让系统安全性崩塌。
🎁免费备考资料分享(红帽、甲骨文、华为)
为了帮助更多考生高效备考,我根据自己的学习经验,整理了以下几个核心备考资料:
-
考试大纲:
覆盖HCIE笔试和实验考试的所有重点知识,帮助你精准掌握考试范围,避免盲目学习。 -
培训教材:
详细的理论知识和案例分析,核心技术的深入解析,是夯实基础的不二之选。 -
实验手册:
实验考试配置命令速查手册和模拟实验案例集,涵盖关键场景,助你在实验环节高效应对。
获取方式:
如果你需要这些备考资料,可以在评论区留言或者私信我,我会将资料打包发给你,希望对你的备考有所帮助!
如果你觉得本文有帮助,欢迎点赞、评论或收藏!有任何问题也欢迎留言一起交流~
关注我,一起深入 Linux 内核世界!

1274

被折叠的 条评论
为什么被折叠?



