DragonOS/docs/kernel/net/ssh.md

204 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ssh支持
目前我们使用一个轻量级的ssh实现[dropbear](https://matt.ucc.asn.au/dropbear/dropbear.html)。
## 初始化步骤
1. 确保/bin/sh存在(应该已经存在其实是busybox如果不存在可以拷贝sysroot/bin目录下的busybox文件: `cp ./bin/sysroot/bin/busybox ./bin/sysroot/bin/sh`)
2. 确保/root目录存在(应该已经存在)
3. 确保/etc/dropbear目录存在
```shell
mkdir /etc/dropbear
```
4. 确保 /var/log/lastlog文件存在可以是空文件(不存在也行)
5. 修改root用户的密码
```shell
busybox passwd
```
6. 启动系统后启动dropbear服务器
```shell
dropbear -E -F -R -p 12580
```
7. 在本地终端中连接到服务器
```shell
./dbclient -p 12580 root@localhos
```
如果报错:
```shell
./dbclient: Connection to root@localhost:12580 exited:
ssh-ed25519 host key mismatch for localhost !
Fingerprint is SHA256:hK2KR5QQnSHpcHLYzCVe9IyKEw1NwIXx41K/gyv7NKI
Expected SHA256:W8+kSk+aCm2uoc1ZIKU/RQJSKoqWrOKrFf9URhfFaw8
If you know that the host key is correct you can
remove the bad entry from ~/.ssh/known_hosts
```
解决方法:`ssh-keygen -R localhost` 删除已存在的错误host key
8. 输入root用户的密码成功登录后即可使用ssh终端
9. 退出ssh终端
```shell
exit
```
## 其它可用命令
生成ssh密钥对
```shell
# 生成dropbear的ssh密钥对
dropbearkey -t rsa -f ~/.ssh/id_dropbear
```
将公钥添加到授权列表
```shell
# 拷贝公钥到指定目录
cp ~/.ssh/id_dropbear.pub ./bin/sysroot
# 使用私钥连接到服务器
./dbclient -i ~/.ssh/id_dropbear -p 12580 root@localhost
```
## SSH相关的系统文件介绍
### /etc/passwd 的作用
- 存储系统用户信息:它包含了每个用户的基本信息,是系统认证和登录的重要数据来源。
- 用于登录和用户管理:系统和应用程序通过读取该文件来验证用户身份、决定用户权限以及加载相应的设置(如默认 shell、主目录等
- 提供支持:对于一些应用程序和命令(如 useradd、passwd、chown它需要通过 /etc/passwd 来获取用户的相关信息。
```bash
username:password:UID:GID:GECOS:home_directory:shell
```
- username用户名用户的登录名称。例如root、john、guest 等。
- password密码用户的加密密码。现在大多数系统会将密码的哈希值存储在 /etc/shadow 文件中,因此这个字段通常是一个占位符(如 x 或 *)。在较旧的系统中,密码可能直接存储在此字段中,但这种做法已不安全。
- UID用户 ID用户的唯一标识符。每个用户都有一个唯一的 UID系统通过它来区分不同用户。通常
- 0 表示 root 用户(超级用户)。
- 普通用户的 UID 从 1000 开始(在一些 Linux 发行版中,可能从 500 开始)。
- GID组 ID用户所属的主组的 ID。组 ID 是与组名称相关联的数字。通常每个用户都会有一个与其用户名相同的组。例如john 用户可能会有一个主组 john其 GID 可能是 1001。
- GECOS用户全名或备注信息这个字段通常存储用户的全名、电话号码等可选信息。它可以为空或包含一些描述性文字通常是通过 chfn 命令进行设置。
- home_directory主目录用户的登录主目录用户登录后会被自动带到这个目录。例如/home/john、/root。如果用户是 root其主目录通常是 /root。
- shell默认 shell用户登录时所使用的 shell 程序。通常是 /bin/bash、/bin/sh 或其他 shell 程序。对于没有实际登录权限的系统用户,这个字段可能是 /usr/sbin/nologin 或 /bin/false以阻止他们登录系统
### /etc/shadow 文件的作用
- 存储用户的加密密码:/etc/shadow 文件中保存了每个用户的 加密密码,而不是明文密码。这是一个系统的安全机制,防止密码泄漏。
- 账户过期管理:它还包含了与账户过期、密码过期、账户锁定等相关的信息,帮助系统管理员管理用户的登录权限。
- 增强安全性:相比于早期系统中把密码直接存储在 /etc/passwd 中,/etc/shadow 将密码从可公开访问的文件中移除,使得系统更加安全
```bash
username:password:lastchg:min:max:warn:inactive:expire:flag
```
- username用户名与 /etc/passwd 中的用户名一致。
- password密码这是用户的加密密码。如果密码为空通常是 * 或 !,表示禁用该账户。正常情况下,这里存储的是密码的加密哈希值。
- lastchg上次修改日期密码最后一次修改的日期表示自 1970 年 1 月 1 日以来的天数。通常这个值是通过 chage 命令查看和更新的。
- min最小密码年龄密码的最小使用期限。用户修改密码后必须等待多少天才能再次修改密码。通常设置为 0表示没有最小密码年龄限制。
- max最大密码年龄密码的最大使用期限。超过这个期限用户必须修改密码。设置为 99999 表示密码永不过期。
- warn警告期限密码过期前系统会提前多少天开始警告用户密码即将过期。
- inactive非活动期限密码过期后用户仍然有多少天的时间可以继续登录。如果超过该天数账户将被禁用。
- expire账户过期日期账户的过期日期表示自 1970 年 1 月 1 日以来的天数。如果账户过期,用户将无法登录。
- flag账户锁定标志这个字段用于存储账户是否被锁定。如果这个字段是 !! 或 *,表示用户账号被锁定,不能登录
### 不同hash算法生成的密码前缀
- `\$5$` 前缀SHA-256
- `\$6$` 前缀SHA-512
- `\$y$` 前缀Yarrow
### 系统调用支持
- fcntl SETLK https://man7.org/linux/man-pages/man2/fcntl.2.html
- unlink
- fsync
- rename https://man7.org/linux/man-pages/man2/rename.2.html
- ioctl TCFLSH
- renameat2: oldfd: -100, filename_from: /etc/shadow+, newfd: -100, filename_to: /etc/shadow 失败
### 文件系统相关
/proc/self目录:/proc/self 是一个 符号链接,始终指向 访问它的进程自己的 /proc/[pid] 目录
| 路径 | 作用 |
| -------------------- | ---------------------------------------- |
| `/proc/self/cmdline` | 当前进程的命令行参数 |
| `/proc/self/exe` | 当前进程的可执行文件路径(是个符号链接) |
| `/proc/self/fd/` | 当前进程打开的所有文件描述符 |
| `/proc/self/environ` | 当前进程的环境变量 |
| `/proc/self/maps` | 当前进程的内存映射布局 |
| `/proc/self/status` | 当前进程的状态信息(类似于 ps 命令) |
- /proc/fd/{id} 也是一个符号链接,指向进程打开的文件描述符所对应的文件路径。
- /dev/pts/0 这些伪终端需要等待主设备/dev/ptmx被关闭的时候删除
- /root目录必须存在
### linux的setgroups和getgroups的作用和用法是什么
在 Linux 中,一个进程有:
- 真实用户 ID (real UID)、有效用户 ID (effective UID)
- 真实组 ID (real GID)、有效组 ID (effective GID)
- 附加组 ID 列表supplementary groups
附加组 ID 让进程除了主组外,还可以属于其他多个组,从而获得对应组的访问权限
#### 用户 ID (UID) 和 组 ID (GID)
这两个是权限身份标识,用来决定一个进程能做什么。
UIDUser ID表示进程属于哪个用户。
常见种类:
- 真实用户 ID (real UID):启动该进程的用户是谁。
- 有效用户 ID (effective UID):实际用于权限检查的 UID比如 setuid 程序可以让 EUID 暂时变成 root
- 保存的 set-user-ID保存切换前的 EUID用于临时恢复
root 用户的 UID 是 0其它用户一般是从 1000或 500开始分配。
GIDGroup ID 表示进程属于哪个主用户组。同样有 real/effective/saved 三种。
另外还有 附加组列表supplementary groups用来赋予额外的组权限。
作用:
当进程访问文件、socket、IPC 等资源时,内核会根据 EUID/EGID + 附加组列表 来判断能否访问。
## Reference
- Linux TTY/PTS概述 https://liujunming.top/2019/09/03/Linux-TTY-PTS%E6%A6%82%E8%BF%B0/
- 伪终端(pseudo terminal) https://zhuanlan.zhihu.com/p/678170056
- 硬件终端 terminal(TTY)
https://www.cnblogs.com/sparkdev/p/11460821.html