安全特性#
Rootless安全模型#
用户命名空间(User Namespace)原理#
Rootless Podman 利用 Linux User Namespace 将容器内的 root (UID 0) 映射为宿主机上的普通用户,实现无特权运行容器。容器内进程以为自己是 root,但在宿主机上实际以非特权 UID 运行。
subuid/subgid 映射配置#
# /etc/subuid
user1:100000:65536
# /etc/subgid
user1:100000:65536
格式:
用户名:起始UID:数量每个用户分配独立的 UID/GID 范围
容器内 UID 0 映射为宿主机上的起始 UID
Rootless vs Root 安全边界对比#
特性 |
Rootless |
Root |
|---|---|---|
宿主机权限 |
普通用户 |
root |
容器逃逸影响 |
仅限当前用户 |
完全接管宿主机 |
端口绑定 |
>1024(或配置 net.ipv4.ip_unprivileged_port_start) |
任意端口 |
文件系统访问 |
受限于用户权限 |
无限制 |
网络模式 |
slirp4netns / pasta |
完整 CNI/netavark |
攻击面分析#
无daemon = 无SPOF:每个容器独立进程,不存在单一故障点
无root = 最小权限:即使容器被攻破,攻击者仅获得普通用户权限
无长驻进程:减少攻击窗口,降低被利用的可能性
SELinux容器策略#
卷标签#
:Z标签(专用)— 只有此容器可以访问卷内容podman run -v /data:/app:Z nginx
:z标签(共享)— 多个容器可以共享访问podman run -v /shared:/app:z nginx
容器SELinux类型#
container_t:容器进程运行的默认类型container_file_t:容器可访问文件的默认标签
特殊配置#
禁用SELinux(不推荐):
--security-opt label=disable自定义标签:
--security-opt label=type:my_container_t
Capabilities管理#
Podman默认capabilities#
Podman 默认授予容器以下 14 个 capabilities:
AUDIT_WRITE
CHOWN
DAC_OVERRIDE
FOWNER
FSETID
KILL
MKNOD
NET_BIND_SERVICE
NET_RAW
SETFCAP
SETGID
SETPCAP
SETUID
SYS_CHROOT
最小权限实践#
# 删除所有capabilities
podman run --cap-drop=ALL nginx
# 仅添加必需
podman run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
特殊capabilities说明#
Capability |
用途 |
风险 |
|---|---|---|
SYS_ADMIN |
挂载文件系统、配置命名空间等 |
极高,几乎等同root |
NET_ADMIN |
网络配置、防火墙规则等 |
高,可修改网络栈 |
SYS_PTRACE |
调试进程、读取其他进程内存 |
高,可窥探其他容器 |
Seccomp配置#
默认seccomp profile位置#
系统级:
/usr/share/containers/seccomp.json用户级:
~/.config/containers/seccomp.json
自定义seccomp profile#
podman run --security-opt seccomp=/path/to/profile.json nginx
Profile结构#
{
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": ["SCMP_ARCH_X86_64", "SCMP_ARCH_X86"],
"syscalls": [
{
"names": ["read", "write", "open", "close"],
"action": "SCMP_ACT_ALLOW"
}
]
}
defaultAction:未匹配系统调用的默认行为syscalls:允许或拒绝的系统调用列表architectures:适用的CPU架构
禁用seccomp(不推荐)#
podman run --security-opt seccomp=unconfined nginx
只读容器#
# 只读根文件系统
podman run --read-only nginx
# 只读 + tmpfs(可写临时目录)
podman run --read-only --tmpfs /tmp --tmpfs /run nginx
# no-new-privileges(防止提权)
podman run --security-opt no-new-privileges nginx
镜像签名与验证#
Policy.json 配置#
{
"default": [{"type": "insecureAcceptAnything"}],
"transports": {
"docker": {
"registry.example.com": [
{"type": "sigstoreSigned", "keyPath": "/path/to/cosign.pub"}
]
}
}
}
Cosign签名工作流#
cosign generate-key-pair
cosign sign --key cosign.key registry/image:tag
cosign verify --key cosign.pub registry/image:tag
无密钥签名(Sigstore OIDC)#
利用 Sigstore 的 Fulcio CA 和 Rekor 透明日志,通过 OIDC 身份验证实现无需管理密钥的签名:
cosign sign registry/image:tag # 自动触发OIDC认证
Registries安全配置#
# /etc/containers/registries.conf
unqualified-search-registries = ["docker.io", "quay.io"]
[[registry]]
prefix = "docker.io"
location = "docker.io"
[[registry.mirror]]
location = "mirror.example.com"
insecure = false
# 阻止不安全的仓库
[[registry]]
prefix = "untrusted-registry.com"
blocked = true
安全最佳实践清单#
使用rootless模式
删除所有capabilities,仅添加必需
启用no-new-privileges
使用只读根文件系统
启用镜像签名验证
配置seccomp profile
使用SELinux标签保护卷
定期扫描漏洞(Trivy/Grype)
使用最小基础镜像(distroless/scratch)
限制资源(cgroups)