Shell脚本如何配置容器合规检查

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器合规检查

  1. 基础合规检查脚本框架
  2. CIS Benchmark 合规检查脚本
  3. 配置自动化定时检查
  4. 容器合规性检查清单
  5. 合规检查配置建议
  6. 使用说明
  7. 合规检查参考标准

为容器环境配置合规检查脚本,通常涉及对容器运行时配置镜像安全宿主机安全以及运行时行为的检查,以下是一个完整的 Shell 脚本框架和配置指南。

基础合规检查脚本框架

#!/bin/bash
# container_compliance_check.sh
# 用途:容器环境基础合规检查
set -euo pipefail
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 报告文件
REPORT_FILE="container_compliance_report_$(date +%Y%m%d_%H%M%S).txt"
# 初始化报告
init_report() {
    echo "==========================================" > "$REPORT_FILE"
    echo "容器合规检查报告" >> "$REPORT_FILE"
    echo "检查时间: $(date)" >> "$REPORT_FILE"
    echo "主机名: $(hostname)" >> "$REPORT_FILE"
    echo "==========================================" >> "$REPORT_FILE"
    echo "" >> "$REPORT_FILE"
}
# 记录检查结果
log_result() {
    local check_name="$1"
    local status="$2"
    local detail="$3"
    echo "[$status] $check_name" >> "$REPORT_FILE"
    echo "  └─ $detail" >> "$REPORT_FILE"
    echo "" >> "$REPORT_FILE"
}
# 检查Docker守护进程配置
check_docker_daemon() {
    echo -e "${YELLOW}[检查] Docker守护进程配置...${NC}"
    # 检查是否启用用户命名空间
    if docker info 2>/dev/null | grep -q "userns"; then
        log_result "用户命名空间" "PASS" "用户命名空间已启用"
    else
        log_result "用户命名空间" "FAIL" "建议启用用户命名空间(--userns-remap)"
    fi
    # 检查日志驱动
    local log_driver=$(docker info --format '{{.LoggingDriver}}' 2>/dev/null)
    if [ "$log_driver" == "json-file" ]; then
        log_result "日志驱动" "WARN" "当前使用json-file驱动,建议使用fluentd或syslog"
    else
        log_result "日志驱动" "INFO" "使用日志驱动: $log_driver"
    fi
}
# 检查运行中容器的配置
check_running_containers() {
    echo -e "${YELLOW}[检查] 运行中容器配置...${NC}"
    # 获取所有运行中的容器
    local containers=$(docker ps -q 2>/dev/null)
    if [ -z "$containers" ]; then
        log_result "运行中容器" "INFO" "没有运行中的容器"
        return
    fi
    for container in $containers; do
        local name=$(docker inspect --format='{{.Name}}' "$container" | cut -d'/' -f2)
        # 检查特权模式
        local privileged=$(docker inspect --format='{{.HostConfig.Privileged}}' "$container")
        if [ "$privileged" == "true" ]; then
            log_result "容器: $name" "FAIL" "以特权模式运行,建议避免"
        fi
        # 检查端口映射
        local ports=$(docker inspect --format='{{range $p, $conf := .HostConfig.PortBindings}}{{$p}} {{end}}' "$container")
        if [ -n "$ports" ]; then
            log_result "容器: $name" "INFO" "端口映射: $ports"
        fi
        # 检查挂载的目录
        local mounts=$(docker inspect --format='{{range .Mounts}}{{.Source}}:{{.Destination}} {{end}}' "$container")
        if echo "$mounts" | grep -q "/var/run/docker.sock"; then
            log_result "容器: $name" "CRITICAL" "挂载了Docker Socket,存在严重安全风险"
        fi
    done
}
# 检查镜像安全配置
check_image_security() {
    echo -e "${YELLOW}[检查] 镜像安全配置...${NC}"
    # 获取所有镜像
    local images=$(docker images -q 2>/dev/null)
    if [ -z "$images" ]; then
        log_result "Docker镜像" "INFO" "没有本地镜像"
        return
    fi
    for image in $images; do
        local repo_tag=$(docker images --format='{{.Repository}}:{{.Tag}}' | head -1)
        # 检查镜像标签
        if echo "$repo_tag" | grep -q ":latest"; then
            log_result "镜像: $repo_tag" "WARN" "使用latest标签,建议使用具体版本"
        fi
        # 检查镜像年龄
        local created=$(docker inspect --format='{{.Created}}' "$image")
        local created_epoch=$(date -d "$created" +%s)
        local current_epoch=$(date +%s)
        local days_old=$(( (current_epoch - created_epoch) / 86400 ))
        if [ $days_old -gt 30 ]; then
            log_result "镜像: $repo_tag" "WARN" "镜像已创建 $days_old 天,建议更新"
        fi
    done
}
# 检查容器运行时安全
check_runtime_security() {
    echo -e "${YELLOW}[检查] 容器运行时安全...${NC}"
    # 检查是否使用只读文件系统
    for container in $(docker ps -q 2>/dev/null); do
        local name=$(docker inspect --format='{{.Name}}' "$container" | cut -d'/' -f2)
        local readonly=$(docker inspect --format='{{.HostConfig.ReadonlyRootfs}}' "$container")
        if [ "$readonly" != "true" ]; then
            log_result "容器: $name" "WARN" "未启用只读文件系统,建议设置 --read-only"
        fi
        # 检查资源限制
        local memory=$(docker inspect --format='{{.HostConfig.Memory}}' "$container")
        local cpu=$(docker inspect --format='{{.HostConfig.NanoCpus}}' "$container")
        if [ "$memory" -eq 0 ]; then
            log_result "容器: $name" "FAIL" "未设置内存限制,建议使用 --memory"
        fi
        if [ "$cpu" -eq 0 ]; then
            log_result "容器: $name" "FAIL" "未设置CPU限制,建议使用 --cpus"
        fi
    done
}
# 检查网络配置
check_network_config() {
    echo -e "${YELLOW}[检查] 网络配置...${NC}"
    # 检查是否使用默认bridge网络
    local default_network=$(docker network ls --filter driver=bridge --format "{{.Name}}" | grep "^bridge$")
    if [ -n "$default_network" ]; then
        log_result "默认bridge网络" "WARN" "建议创建自定义网络,默认bridge网络安全性较差"
    fi
    # 检查端口暴露情况
    for container in $(docker ps -q 2>/dev/null); do
        local exposed_ports=$(docker inspect --format='{{range $p, $conf := .Config.ExposedPorts}}{{$p}} {{end}}' "$container")
        local bound_ports=$(docker inspect --format='{{range $p, $conf := .HostConfig.PortBindings}}{{$p}} {{end}}' "$container")
        if [ -n "$exposed_ports" ] && [ -z "$bound_ports" ]; then
            log_result "容器: $(docker inspect --format='{{.Name}}' "$container")" "WARN" "暴露端口但未绑定映射,可能需要关注"
        fi
    done
}
# 生成最终报告
generate_report() {
    echo "" >> "$REPORT_FILE"
    echo "==========================================" >> "$REPORT_FILE"
    echo "检查完成汇总" >> "$REPORT_FILE"
    echo "==========================================" >> "$REPORT_FILE"
    local pass_count=$(grep -c "\[PASS\]" "$REPORT_FILE" 2>/dev/null || echo 0)
    local fail_count=$(grep -c "\[FAIL\]" "$REPORT_FILE" 2>/dev/null || echo 0)
    local warn_count=$(grep -c "\[WARN\]" "$REPORT_FILE" 2>/dev/null || echo 0)
    local critical_count=$(grep -c "\[CRITICAL\]" "$REPORT_FILE" 2>/dev/null || echo 0)
    echo "PASS: $pass_count" >> "$REPORT_FILE"
    echo "FAIL: $fail_count" >> "$REPORT_FILE"
    echo "WARN: $warn_count" >> "$REPORT_FILE"
    echo "CRITICAL: $critical_count" >> "$REPORT_FILE"
}
# 主函数
main() {
    echo -e "${GREEN}开始容器合规检查...${NC}"
    init_report
    # 检查Docker是否运行
    if ! command -v docker &> /dev/null; then
        echo -e "${RED}错误: Docker未安装${NC}"
        log_result "Docker" "ERROR" "Docker未安装"
        exit 1
    fi
    if ! docker info &> /dev/null; then
        echo -e "${RED}错误: Docker守护进程未运行${NC}"
        log_result "Docker" "ERROR" "Docker守护进程未运行"
        exit 1
    fi
    # 执行各项检查
    check_docker_daemon
    check_running_containers
    check_image_security
    check_runtime_security
    check_network_config
    # 生成最终报告
    generate_report
    echo -e "${GREEN}检查完成!报告已保存到: $REPORT_FILE${NC}"
}
# 执行
main

CIS Benchmark 合规检查脚本

#!/bin/bash
# cis_docker_benchmark.sh
# Docker CIS Benchmark 合规检查
CIS_VERSION="1.6.0"
check_cis_1_1_1() {
    echo "检查 1.1.1: Docker单独分区"
    if mount | grep -q "/var/lib/docker"; then
        echo "[PASS] /var/lib/docker 在单独分区"
    else
        echo "[FAIL] /var/lib/docker 不在单独分区"
    fi
}
check_cis_2_1() {
    echo "检查 2.1: 限制容器间网络通信"
    local icc=$(docker info --format '{{.SecurityOptions}}')
    if echo "$icc" | grep -q "name=no-new-privileges"; then
        echo "[PASS] 容器间网络通信受限"
    else
        echo "[FAIL] 建议在daemon.json中设置icc=false"
    fi
}
check_cis_5_1() {
    echo "检查 5.1: 容器只读文件系统"
    for container in $(docker ps -q); do
        local readonly=$(docker inspect --format='{{.HostConfig.ReadonlyRootfs}}' "$container")
        if [ "$readonly" != "true" ]; then
            echo "[WARN] 容器 $(docker inspect --format='{{.Name}}' "$container") 未使用只读文件系统"
        fi
    done
}

配置自动化定时检查

#!/bin/bash
# setup_compliance_cron.sh
# 设置定时检查任务
# 创建日志目录
mkdir -p /var/log/container_compliance
# 添加cron任务 - 每天凌晨2点执行检查
(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/container_compliance_check.sh >> /var/log/container_compliance/check_\$(date +\%Y\%m\%d).log 2>&1") | crontab -
echo "定时检查已配置完成"

容器合规性检查清单

#!/bin/bash
# quick_compliance_check.sh
# 快速合规检查清单
echo "=== 容器合规快速检查清单 ==="
# 1. 基础配置检查
echo -e "\n1. Docker版本检查:"
docker version
# 2. 安全配置检查
echo -e "\n2. 安全配置:"
docker info | grep -E "Security|UserNamespace|RootDir|LoggingDriver"
# 3. 运行容器检查
echo -e "\n3. 运行中容器:"
docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
# 4. 资源使用检查
echo -e "\n4. 资源使用:"
docker stats --no-stream
# 5. 网络配置检查
echo -e "\n5. 网络配置:"
docker network ls

合规检查配置建议

1 Docker daemon.json 安全配置

{
  "icc": false,
  "userns-remap": "default",
  "live-restore": true,
  "userland-proxy": false,
  "no-new-privileges": true,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 64000,
      "Soft": 64000
    }
  }
}

2 容器运行安全参数

# 推荐的安全运行参数
docker run -d \
  --security-opt=no-new-privileges:true \
  --security-opt seccomp=/path/to/seccomp-profile.json \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=65536k \
  --tmpfs /var/run:rw,noexec,nosuid,size=65536k \
  --user 1001:1001 \
  --memory 512m \
  --cpus 0.5 \
  --pids-limit 100 \
  --restart unless-stopped \
  nginx:alpine

使用说明

# 1. 赋予执行权限
chmod +x container_compliance_check.sh
# 2. 执行检查
./container_compliance_check.sh
# 3. 查看报告
cat container_compliance_report_*.txt
# 4. 配置定时检查
./setup_compliance_cron.sh

合规检查参考标准

  • CIS Docker Benchmark - 最权威的Docker安全基准
  • NIST SP 800-190 - 容器安全指南
  • OWASP Docker Security - 应用安全指南
  • PCI DSS - 支付卡行业数据安全标准
  • HIPAA - 医疗行业合规要求

这个脚本框架可以根据你的具体合规需求(如PCI-DSS、HIPAA等)进行扩展和定制,建议定期运行此脚本并记录结果,作为合规审计的一部分。

上一篇Shell脚本如何配置容器审计日志

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!