10分钟搭建个人离线小说库:fanqienovel-downloader完全指南
2026/7/14 16:35:36
# 启用userns-remap,需提前配置/etc/subuid与/etc/subgid\ndockerd --userns-remap="default"该配置使容器内root用户在宿主机上以非特权UID运行,即使容器被突破,也无法直接操作宿主机root资源。 典型加固措施包括:USER 1001声明)--cap-drop=ALL --cap-add=NET_BIND_SERVICE)--read-only --tmpfs /run --tmpfs /tmp)| 配置项 | 默认值 | 工业级推荐值 |
|---|---|---|
| 用户命名空间支持 | 禁用 | 启用(--userns-remap=default) |
| 容器PID命名空间 | 共享宿主机PID | 独立(--pid=private) |
| SELinux/AppArmor | 未强制启用 | 启用并加载定制策略 |
/* 允许 read/write/exit,拒绝 openat 及以上编号系统调用 */ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)), BPF_JUMP(BPF_JMP | BPF_JGE, __NR_openat, 0, 1), BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS)该 BPF 程序加载系统调用号,若 ≥__NR_openat则终止进程,否则放行;SECCOMP_RET_KILL_PROCESS触发 SIGSYS 并终止整个线程组。ptrace或userfaultfd绕过命名空间隔离unshare+mount组合调用尝试提权等保三级要求操作系统内核级行为可控,需对容器/沙箱运行时调用的系统调用(syscalls)实施细粒度白名单管控。
基于 Linux seccomp-bpf 规范,结合等保三级“最小授权”原则,剔除非必要 syscall:
openat、read、write等基础 I/O 允许,但限制路径前缀socket、connect仅允许 AF_INET/AF_UNIX,禁用 AF_PACKETexecve严格校验二进制哈希与签名{ "defaultAction": "SCMP_ACT_ERRNO", "syscalls": [ { "names": ["read", "write", "close"], "action": "SCMP_ACT_ALLOW" } ] }该配置默认拒绝所有 syscall,仅显式放行读写关闭操作;SCMP_ACT_ERRNO返回 EPERM 而非崩溃,符合等保审计可追溯性要求。
/etc/docker/daemon.json需由 root 用户拥有,且权限应为644,否则 dockerd 启动时将拒绝加载。{ "default-runtime": "runc", "seccomp-profile": "/etc/docker/seccomp.json" }该配置强制所有容器(除非显式覆盖)使用指定的 seccomp 策略文件;seccomp-profile是 dockerd 20.10+ 引入的全局策略字段,替代旧版default-ulimits类松散控制。sudo systemctl restart dockerdocker inspect nginx | jq '.[0].HostConfig.SecurityOpt'prestart钩子可修改容器配置(如config.json)并注入自定义 seccomp 策略。// inject-seccomp-hook.go func main() { var spec specs.Spec if err := json.NewDecoder(os.Stdin).Decode(&spec); err != nil { os.Exit(1) } spec.Linux.Seccomp = &specs.Seccomp{ // 动态挂载 profile DefaultAction: specs.ActErr, Syscalls: []specs.Syscall{{ Names: []string{"chmod", "chown"}, Action: specs.ActAllow, }}, } json.NewEncoder(os.Stdout).Encode(spec) }该 hook 从 stdin 读取 OCI 配置,覆盖默认 seccomp 策略,仅允许chmod和chown,其余系统调用均拒绝。参数DefaultAction: ActErr强制失败而非静默丢弃,提升安全可观测性。/usr/local/bin/inject-seccompconfig.json的hooks.prestart数组中注册路径与超时{ "timestamp": "2024-06-15T08:23:41Z", "container_id": "a1b2c3d4", "syscall": "openat", "action": "SCMP_ACT_ERRNO", "profile": "restricted-v2" }该JSON格式由auditd+eBPF钩子生成,字段`action`标识拦截动作类型,`profile`标明生效策略版本,便于跨集群关联分析。aa_change_hat()系统调用切换到受限配置文件。内核LSM框架在security_inode_getattr()等钩子中注入策略检查逻辑。/* AppArmor钩子注册示例 */ static struct security_hook_list apparmor_hooks[] = { LSM_HOOK_INIT(inode_getattr, apparmor_inode_getattr), LSM_HOOK_INIT(file_open, apparmor_file_open), };该代码注册了文件访问控制钩子;apparmor_inode_getattr在stat()调用时校验路径是否在profile白名单中,file_open则拦截open()并匹配路径规则。docker-abc123)--security-opt apparmor=xxx显式指定profile名称/etc/apparmor.d/docker-*形式持久化| 策略类型 | 生效时机 | 作用域 |
|---|---|---|
| abstractions | 构建时包含 | 通用能力集(如networking) |
| child profiles | execve时触发 | 嵌套进程隔离 |
在边缘侧设备与PLC/DCS系统深度集成场景中,需基于标准协议定义轻量、安全、可验证的通信Profile。以Modbus/TCP为例,可裁剪非必要功能码并强制启用TCP校验与超时重传:
// Modbus TCP Profile配置片段 type ModbusProfile struct { UnitID uint8 `json:"unit_id"` // 设备逻辑地址,限定1~247 TimeoutMS uint32 `json:"timeout_ms"` // 严格限制为150ms,防长连接阻塞 AllowedFCs []uint8 `json:"allowed_fcs"` // 仅允许0x03(Read Holding)、0x10(Write Multiple) }该结构体约束了协议行为边界,避免非法功能码触发PLC异常。同时,OPC UA Profile需绑定NamespaceIndex与NodeId语义映射表:
| OPC UA NodeId | 语义标签 | 数据类型 | 采样周期(ms) |
|---|---|---|---|
| i=2258 | Motor_RPM | Int32 | 100 |
| i=63 | Tank_Level_Perc | Float | 500 |
# auditd规则:监控容器运行时目录及敏感syscall -a always,exit -F arch=b64 -S execve,openat -F path=/var/lib/docker/ -k container_priv_esc -a always,exit -F arch=b64 -S setuid,setgid,capset -k cap_violation该规则捕获所有尝试在 Docker 根目录下执行或提权的操作,并打上审计键(key),便于后续过滤与聚合。journalctl -k -o json --since "10 seconds ago"实时拉取;Rootless容器依赖/etc/subuid和/etc/subgid定义用户命名空间的ID偏移范围。每个条目格式为:username:start_id:count。
| 用户 | 起始UID | 数量 |
|---|---|---|
| devops | 100000 | 65536 |
| ci | 200000 | 65536 |
# 查看当前用户的subuid映射 $ cat /etc/subuid | grep $USER devops:100000:65536 # 启动rootless容器并显式指定userns $ podman run --userns=keep-id -it alpine id uid=1000(1000) gid=1000(1000) groups=1000(1000)该命令启用--userns=keep-id,将主机用户UID/GID一对一映射至容器内,同时受限于/etc/subuid分配的ID段,实现非特权下的强隔离。
cpu.weight(1–10000)实现细粒度份额分配:echo 8000 | sudo tee /sys/fs/cgroup/rt-app/cpu.weight echo 2000 | sudo tee /sys/fs/cgroup/batch-job/cpu.weight权重非绝对配额,而是相对比例:8000:2000 = 4:1,内核据此计算vruntime偏移,确保低延迟任务获得更高调度优先级。| Group | CPU.weight | io.weight |
|---|---|---|
| rt-app | 8000 | 800 |
| batch-job | 2000 | 200 |
mount -t cgroup2 none /sys/fs/cgroupmkdir /sys/fs/cgroup/rt-app && echo "+cpu +io" > /sys/fs/cgroup/cgroup.subtree_control# 创建带 CPU/内存限制的租户 scope systemd-run \ --scope \ --property=CPUQuota=50% \ --property=MemoryMax=512M \ --property=AllowedCPUs=0-1 \ --unit=tenant-a \ sleep infinity该命令启动一个受控 scope 单元,`CPUQuota` 限制 CPU 时间配额,`MemoryMax` 设定内存上限,`AllowedCPUs` 实现 CPU 绑核;所有子进程自动写入 `/sys/fs/cgroup/tenant-a/cgroup.procs`。| 机制 | 隔离粒度 | 动态重配 |
|---|---|---|
| Docker --cpus/--memory | 运行时抽象层 | 需重启容器 |
| systemd-run + cgroup.procs | 内核 cgroup v2 原语 | 实时写入 cgroup.procs |
# 强制启用cgroup v2并禁用swap echo "vm.swappiness = 0" >> /etc/sysctl.conf sysctl -p # 启动容器时指定内存硬限制与OOM Score调整 docker run --memory=2g --memory-reservation=1.5g --oom-score-adj=800 nginx--memory设置硬限制触发内核OOM Killer;--oom-score-adj(取值-1000~1000)提升该容器被优先终止的概率,确保关键宿主服务不被波及。systemd持久化禁用swap:sudo systemctl mask swap.targetpodman或Kubernetes LimitRange强制注入memory.limit_in_bytes| 参数 | 等保三级合规值 | 作用 |
|---|---|---|
vm.swappiness | 0 | 彻底禁用swap交换 |
memory.oom_control | 1 | 启用OOM事件通知 |
# 检查SSH服务是否禁用root远程登录(等保三级要求:5.2.3.a) grep -E '^\s*PermitRootLogin\s+no' /etc/ssh/sshd_config > /dev/null \ && echo "✅ 符合:PermitRootLogin已禁用" \ || echo "❌ 不符合:需执行 sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config"| 指标类别 | SLA阈值 | 当前达成率 | 数据源 |
|---|---|---|---|
| 日志留存周期 | ≥180天 | 192天 | ELK集群冷热分层策略 |
| 漏洞修复平均时长 | ≤72小时(高危) | 41.2小时 | Jira+OpenVAS联动工单 |