19.8.6 主机与容器安全基线

主机与容器安全基线旨在通过统一配置标准、最小暴露面与可审计机制,降低平台被入侵与横向移动风险。本节给出可落地的基线控制、安装与验证命令、排错思路与练习,确保“可执行、可验证、可持续改进”。

原理草图(主机与容器安全控制面):

文章图片

一、主机安全基线(安装、配置、验证)
1) 关闭不必要服务、限制端口暴露

# 查看当前监听端口
ss -lntup

# 示例:禁用不必要服务(以telnet为例)
systemctl stop telnet.socket
systemctl disable telnet.socket

# 防火墙只开放必要端口
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --remove-service=telnet
firewall-cmd --reload

# 预期效果:telnet端口不再监听,只有SSH开放
ss -lntup | grep -E '(:22|:23)'

2) SSH加固与root限制

# 编辑配置文件
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?ClientAliveInterval.*/ClientAliveInterval 300/' /etc/ssh/sshd_config
sed -i 's/^#\?ClientAliveCountMax.*/ClientAliveCountMax 2/' /etc/ssh/sshd_config

# 重启生效
systemctl restart sshd

# 验证
sshd -T | egrep 'permitrootlogin|passwordauthentication|clientalive'

3) 账号与sudo最小权限

# 创建运维用户并加入sudo(按需)
useradd -m ops
echo 'ops ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/journalctl' \
  > /etc/sudoers.d/ops

# 检查权限文件语法
visudo -c -f /etc/sudoers.d/ops

4) 安装与配置审计(auditd)

# 安装
yum install -y auditd || apt-get install -y auditd

# 记录关键文件改动
cat >/etc/audit/rules.d/hardening.rules <<'EOF'
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/ssh/sshd_config -p wa -k sshcfg
-w /etc/sudoers -p wa -k sudoers
EOF

# 加载规则
augenrules --load
systemctl enable --now auditd

# 验证:修改后查询
touch /etc/ssh/sshd_config
ausearch -k sshcfg | tail

5) 内核参数与资源限制(sysctl与limits)

# 安全内核参数
cat >/etc/sysctl.d/99-security.conf <<'EOF'
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
kernel.kptr_restrict = 2
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
EOF

sysctl --system

# 限制核心转储
echo "* hard core 0" >> /etc/security/limits.conf

二、容器安全基线(Docker/K8s)
1) Docker运行时限制与只读根文件系统

# 安装Docker(以CentOS为例)
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
systemctl enable --now docker

# 运行容器时限制权限
docker run --rm \
  --read-only \
  --cap-drop=ALL \
  --security-opt no-new-privileges \
  -p 8080:80 nginx:1.25

# 预期效果:容器只读、无额外capabilities
docker inspect --format '{{.HostConfig.ReadonlyRootfs}}' <container_id>

2) 禁止特权容器与敏感挂载

# 错误示例(应禁止)
docker run --privileged -v /:/host ubuntu:22.04

# 正确示例(最小挂载、只读)
docker run --rm -v /data/app:/app:ro ubuntu:22.04 ls /app

3) K8s安全上下文与NetworkPolicy示例

# 文件:k8s-secure-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secure-nginx
  labels:
    app: web
spec:
  securityContext:
    runAsUser: 10001
    runAsNonRoot: true
    fsGroup: 2000
  containers:
  - name: nginx
    image: nginx:1.25
    securityContext:
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["ALL"]
    ports:
    - containerPort: 80
# 文件:deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
# 应用并验证
kubectl apply -f k8s-secure-pod.yaml
kubectl apply -f deny-all.yaml
kubectl describe pod secure-nginx | egrep -A3 'Security Context|readOnlyRootFilesystem'

三、镜像与仓库安全(扫描、签名、最小化)
1) 镜像最小化与扫描

# 使用轻量镜像
docker pull nginx:1.25-alpine

# 示例:Trivy漏洞扫描
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh
./trivy image nginx:1.25-alpine

# 预期效果:输出漏洞列表与修复建议

2) 禁止未知来源镜像

# /etc/docker/daemon.json
cat >/etc/docker/daemon.json <<'EOF'
{
  "registry-mirrors": ["https://your-mirror.local"],
  "insecure-registries": [],
  "content-trust": true
}
EOF

systemctl restart docker

四、监控与审计联动(示例)

# rsyslog转发审计与安全日志
cat >/etc/rsyslog.d/60-security.conf <<'EOF'
authpriv.* @@loghost.example.com:514
daemon.*   @@loghost.example.com:514
EOF
systemctl restart rsyslog

五、常见排错
- SSH无法登录
- 检查:sshd -tjournalctl -u sshd -xe
- 可能原因:禁用密码登录但未配置公钥;PermitRootLogin no导致root无法登录。
- auditd规则未生效
- 检查:auditctl -laugenrules --load
- 可能原因:规则文件语法错误或未重启服务。
- Docker容器启动失败(只读根文件系统)
- 检查:docker logs <id>
- 可能原因:应用需要写入 /var/cache/tmp,需挂载可写卷。
- K8s Pod反复CrashLoop
- 检查:kubectl logskubectl describe pod
- 可能原因:runAsNonRoot与镜像用户不匹配。

六、练习(含命令与验证)
1) 练习:为主机启用基线并验证

# 任务:禁用root SSH登录并启用审计
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd
ausearch -k sshcfg | tail

# 验证:root登录应失败;审计应记录配置修改

2) 练习:构建安全容器运行策略

docker run --rm \
  --read-only --cap-drop=ALL --security-opt no-new-privileges \
  -p 8081:80 nginx:1.25-alpine

# 验证容器权限
docker inspect --format '{{.HostConfig.CapDrop}}' <container_id>

3) 练习:K8s安全上下文与网络策略

kubectl apply -f k8s-secure-pod.yaml
kubectl apply -f deny-all.yaml
kubectl exec secure-nginx -- curl -sS http://example.com || echo "egress denied"

# 预期:拒绝对外访问

本节基线建议形成“模板+自动检查+偏离告警+闭环整改”的流程,并在CI/CD中固化镜像扫描与配置验证,形成持续加固闭环。