本文目录导读:

在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等)选择对应的配置方法。