Shell脚本如何配置容器用户命名空间

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器用户命名空间

  1. 基础配置脚本
  2. Docker容器配置示例
  3. Podman容器配置
  4. 脚本创建带用户命名空间的容器
  5. LXC/LXD配置
  6. 自动化配置脚本
  7. 验证脚本
  8. 使用说明

在Shell脚本中配置容器用户命名空间(User Namespace)主要涉及以下几个方面:

基础配置脚本

#!/bin/bash
# 用户命名空间配置脚本
# 设置映射范围
UID_MAP_START=1000
UID_MAP_COUNT=65536
GID_MAP_START=1000
GID_MAP_COUNT=65536
# 创建命名空间子UID/GID映射
setup_user_namespace() {
    local container_name=$1
    # 配置/etc/subuid(如果不存在)
    if ! grep -q "$(whoami)" /etc/subuid 2>/dev/null; then
        echo "$(whoami):$UID_MAP_START:$UID_MAP_COUNT" | sudo tee -a /etc/subuid
    fi
    # 配置/etc/subgid
    if ! grep -q "$(whoami)" /etc/subgid 2>/dev/null; then
        echo "$(whoami):$GID_MAP_START:$GID_MAP_COUNT" | sudo tee -a /etc/subgid
    fi
}

Docker容器配置示例

#!/bin/bash
# 为Docker容器启用用户命名空间
configure_docker_userns() {
    # 创建Docker配置目录
    mkdir -p /etc/docker
    # 配置daemon.json
    cat > /etc/docker/daemon.json <<EOF
{
    "userns-remap": "default",
    "live-restore": true,
    "userland-proxy": false
}
EOF
    # 重启Docker服务
    systemctl restart docker
    # 验证配置
    docker info --format '{{.SecurityOptions}}' | grep -q "name=userns" && \
        echo "用户命名空间已启用" || \
        echo "用户命名空间配置失败"
}

Podman容器配置

#!/bin/bash
# Podman用户命名空间配置
configure_podman_userns() {
    # 配置用户命名空间映射
    cat >> ~/.config/containers/containers.conf <<EOF
[containers]
userns = "auto"
EOF
    # 创建映射文件
    cat > /etc/containers/containers.conf <<EOF
[engine]
userns = "auto"
EOF
    # 配置子UID范围
    sudo usermod --add-subuids 100000-165535 $USER
    sudo usermod --add-subgids 100000-165535 $USER
}

脚本创建带用户命名空间的容器

#!/bin/bash
create_userns_container() {
    local container_image=$1
    local container_name=$2
    # Docker示例
    case "$CONTAINER_RUNTIME" in
        docker)
            docker run -d \
                --name "$container_name" \
                --userns=host \
                --security-opt seccomp=unconfined \
                "$container_image"
            ;;
        podman)
            podman run -d \
                --name "$container_name" \
                --userns-remap \
                "$container_image"
            ;;
        containerd)
            ctr run \
                --uidmap 0:1000:65536 \
                --gidmap 0:1000:65536 \
                "$container_image" \
                "$container_name"
            ;;
    esac
}

LXC/LXD配置

#!/bin/bash
# LXC用户命名空间配置
configure_lxc_userns() {
    local container_name=$1
    # 编辑LXC容器配置
    lxc config set "$container_name" security.privileged false
    lxc config set "$container_name" security.nesting true
    lxc config set "$container_name" security.syscalls.allow all
    lxc config set "$container_name" raw.idmap "both $UID_MAP_START $GID_MAP_COUNT"
    # 重启容器
    lxc restart "$container_name"
}

自动化配置脚本

#!/bin/bash
# 完整的自动化配置脚本
auto_configure_userns() {
    # 检测容器运行时
    detect_runtime() {
        if command -v docker &> /dev/null; then
            echo "docker"
        elif command -v podman &> /dev/null; then
            echo "podman"
        elif command -v lxc &> /dev/null; then
            echo "lxc"
        else
            echo "unknown"
        fi
    }
    RUNTIME=$(detect_runtime)
    case "$RUNTIME" in
        docker)
            configure_docker_userns
            ;;
        podman)
            configure_podman_userns
            ;;
        lxc)
            for container in $(lxc list --format csv -c n); do
                configure_lxc_userns "$container"
            done
            ;;
        *)
            echo "不支持的容器运行时"
            exit 1
            ;;
    esac
}
# 执行配置
main() {
    if [ "$(id -u)" -ne 0 ]; then
        echo "请以root用户运行此脚本"
        exit 1
    }
    echo "开始配置用户命名空间..."
    auto_configure_userns
    echo "配置完成"
}
main "$@"

验证脚本

#!/bin/bash
# 验证用户命名空间配置
verify_userns() {
    echo "=== 用户命名空间配置验证 ==="
    # 检查内核支持
    if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then
        echo "用户命名空间支持: $(cat /proc/sys/kernel/unprivileged_userns_clone)"
    else
        echo "警告: 用户命名空间支持未启用"
    fi
    # 检查映射文件
    echo "子UID映射:"
    cat /etc/subuid 2>/dev/null || echo "文件不存在"
    echo "子GID映射:"
    cat /etc/subgid 2>/dev/null || echo "文件不存在"
    # 检查容器运行时配置
    if command -v docker &> /dev/null; then
        echo "Docker用户命名空间状态:"
        docker info --format '{{json .SecurityOptions}}' | python3 -m json.tool 2>/dev/null || \
            docker info | grep -i "userns"
    fi
    if command -v podman &> /dev/null; then
        echo "Podman用户命名空间配置:"
        podman info --format '{{.Host.Security.Rootless}}'
    fi
}
verify_userns

使用说明

#!/bin/bash
# 使用方法
usage() {
    cat <<EOF
用法: $0 [选项]
选项:
  -c, --configure    配置用户命名空间
  -v, --verify       验证配置
  -r, --run          运行容器实例
  -h, --help         显示帮助信息
示例:
  $0 -c              # 配置用户命名空间
  $0 -v              # 验证当前配置
  $0 -r ubuntu:latest mycontainer  # 运行容器
EOF
}
# 主函数
case "${1:-}" in
    -c|--configure)
        auto_configure_userns
        ;;
    -v|--verify)
        verify_userns
        ;;
    -r|--run)
        shift
        create_userns_container "$@"
        ;;
    -h|--help|*)
        usage
        ;;
esac

使用这些脚本可以灵活配置和管理容器的用户命名空间,实现更好的安全隔离,根据具体的容器运行时(Docker、Podman、LXC等)选择对应的配置方法。

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