Настройка непривилегированного LXC
Установка и настройка непривилегированного контейнера lxc со смещением uid/gid.
1 | LANG=C SUITE=bookworm MIRROR=https://ftp.debian.org/debian/ lxc-create --name=unprivileged-lxc --template=debian |
Добавим дополнительные подгруппы subuids/subgids для пользователя root.
1 2 3 4 5 | usermod --add-subuids 200000-265535 root usermod --add-subgids 200000-265535 root # для удаления подгрупп # usermod --del-subuids 200000-265535 root # usermod --del-subgids 200000-265535 root |
Для смещения subuids/subgids используем скрипт increase-uid-gid.pl
1 2 | cd /var/lib/lxc/ ./increase-uid-gid.pl --lxc=unprivileged-lxc --increase=200000 |
Файл конфигурации
/var/lib/lxc/unprivileged-lxc/config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | lxc.net.0.type = veth lxc.net.0.hwaddr = 00:11:22:09:a1:21 lxc.net.0.link = kvmbr0 lxc.net.0.flags = up lxc.net.0.name = eth125 lxc.net.0.veth.pair = veth125 lxc.net.0.ipv4.address = 10.1.1.125/32 lxc.net.0.ipv4.gateway = 10.1.1.1 lxc.apparmor.profile = generated lxc.apparmor.allow_nesting = 1 # apparmor inside lxc @ https://discuss.linuxcontainers.org/t/apparmor-inside-debian-container/10332/2 lxc.mount.entry = /sys/kernel/security sys/kernel/security none bind,optional 0 0 lxc.rootfs.path = dir:/var/lib/lxc/unprivileged-lxc/rootfs # Common configuration lxc.include = /usr/share/lxc/config/debian.common.conf lxc.include = /usr/share/lxc/config/debian.userns.conf # specific user map lxc.idmap = u 0 200000 65536 lxc.idmap = g 0 200000 65536 # lxc.prlimit.nice = -15 # lxc.prlimit.nproc = unlimited # Container specific configuration lxc.tty.max = 4 lxc.uts.name = unprivileged-lxc lxc.arch = amd64 lxc.pty.max = 1024 |
lxc-ls -f
1 2 | NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
unprivileged-lxc RUNNING 0 - 10.1.1.125 - true
|
Заодно добавим непривилегированного пользователя в lxc
lxc-attach -n unprivileged-lxc
1 2 3 | # lxc unpriv-user groupadd --gid 5599 unpriv-user adduser --home /home/unpriv-user --ingroup unpriv-user --uid 5599 unpriv-user |
В lxc у пользователя uid/gid = 5599, тогда как для хоста, id процессов этого пользователя будут 205599, соответственно id процессов root будут 200000
shift_sub.sh
Это скрипт, которым пользуюсь я.
Запускать его надо зачрутившись в rootfs выключенного LXC.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #!/bin/bash OPTS=`getopt -o s:h --long shift:,help -n 'parse-options' -- "$@"` ; EC="$?" eval set -- "$OPTS" while true; do case "$1" in -s | --shift) SHIFT=$2; shift 2 ;; -h | --help ) HELP="yes"; shift ;; -- ) shift; break ;; * ) break ;; esac done if [[ "$HELP" == "yes" ]]; then printf '%s\n' "Stop LXC > lxc-stop -n <lxcname>" printf '%s\n' "Copy this script to /var/lib/lxc/<lxcname>/rootfs/" printf '%s\n' "chroot in rootfs > chroot /var/lib/lxc/<lxcname>/rootfs/" printf '%s\n' "Run inside > /shift_sub.sh --shift 500000" exit fi printf '%s\n' "Is this LXC turned off? > lxc-stop -n <lxcname>" printf '%s\n' "Are you already chrooted in LXC? > chroot /var/lib/lxc/<lxcname>/rootfs/" printf '%s' "Type uppercase yes: " read inchroot if [[ "$inchroot" = "YES" ]]; then printf '%s\n' "Run in chroot" if [[ -n "$SHIFT" && "$SHIFT" -ge 100000 ]]; then printf '%s\n' "Start shifting subuids" while read -r FILE; do ORIG_UID=`stat -c %u ${FILE}` ORIG_GID=`stat -c %g ${FILE}` NEW_UID=$ORIG_UID NEW_GID=$ORIG_GID if [[ "$ORIG_UID" -lt "$SHIFT" ]]; then let NEW_UID=$ORIG_UID+SHIFT fi if [[ "$ORIG_GID" -lt "$SHIFT" ]]; then let NEW_GID=$ORIG_GID+SHIFT fi if [[ "$ORIG_UID" -lt "$SHIFT" || "$ORIG_GID" -lt "$SHIFT" ]]; then if [[ -L "$FILE" ]]; then printf '%s\n' "symbolic link $NEW_UID:$NEW_GID ${FILE}" chown -h $NEW_UID:$NEW_GID ${FILE} else printf '%s\n' "chown $NEW_UID:$NEW_GID ${FILE}" chown $NEW_UID:$NEW_GID ${FILE} fi else printf '%s\n' "skip ${FILE}" fi done <<<`find / -name "*"` else printf '%s\n' "You must set the value '--shift' to be greater than or equal to 100000" fi else printf '%s\n' "You must run this script in chroot ONLY!" fi printf '%s\n' "done" |
increase-uid-gid.pl
Это довольно старый скрипт, и в нём есть ошибки в обработке ссылок.
setting up lxc containers with mapped giduid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #!/usr/bin/perl # # Copyright (c) 2017 Mathieu Roy <yeupou--gnu.org> # http://yeupou.wordpress.com # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA # # # usermod --add-subuids 100000-165535 root # usermod --add-subgids 100000-165535 root # # in LXC container config: # lxc.id_map = u 0 100000 65536 # lxc.id_map = g 0 100000 65536 # # that would be with --increase=100000 use strict; use File::Find; use Getopt::Long; ### options my ($getopt, $help, $path, $lxc, $increase, $limit); eval { $getopt = GetOptions("help" => \$help, "lxc=s" => \$lxc, "path=s" => \$path, "increase=i" => \$increase, "limit=i" => \$limit); }; if ($help or !$increase or (!$path and !$lxc)) { # increase is mandatory # either path or lxc also # print help if missing print STDERR " Usage: $0 [OPTIONS] --lxc=name --increase=100000 or $0 [OPTIONS] --path=/directory/ --increase=100000 Will increase all files UID/GID by the value set. --lxc=name LXC container name, will be used to determine path --path=/dir No LXC assumption, just work on a given path --increase=n How much to increment --limit=n Increase limit, by default equal to increase Useful for instance when you add to a LXC container such config: lxc.id_map = u 0 100000 65536 lxc.id_map = g 0 100000 65536 And the host system having the relevant range set: usermod --add-subuids 100000-165535 root usermod --add-subgids 100000-165535 root It would update UID/GID within rootfs to match the proper range. Note that additional configured mount must also be updated accordingly, using --path for instance. By default, limit is set to increase value so you can run it several time on the same container, the increase will be effective only once. You can set the limit to something else, for instance if you want to increase by 100000 a container already within the 100000-165536 range, you would have to use --increase=100000 --limit=200000. This script is primitive: it should work in most case, but if some service fail to work after the LXC container restart, it is probably because one or several files were missed. Author: yeupou\@gnu.org http://yeupou.wordpress.com/ "; exit; } # limit set to increase by default $limit = $increase unless $limit; # if lxc set, use it to define path if ($lxc) { my $lxcpath = `lxc-config lxc.lxcpath`; chomp($lxcpath); $path = "$lxcpath/$lxc/rootfs"; } # in any case, path must be given and found die "path $path: not found, exit" unless -e $path; print "path: $path\n"; ### run find(\&wanted, $path); # if lxc, check main container config if ($lxc) { my $lxcpath = `lxc-config lxc.lxcpath`; chomp($lxcpath); # https://unix.stackexchange.com/questions/177030/what-is-an-unprivileged-lxc-container # directory for the container chown(0,0, "$lxcpath/$lxc"); chmod(0775, "$lxcpath/$lxc"); # container config chown(0,0, "$lxcpath/$lxc/config"); chmod(0644, "$lxcpath/$lxc/config"); # container rootfs - chown will be done during the wanted() chmod(0775, "$lxcpath/$lxc/rootfs"); } exit; sub wanted { my $v = $File::Find::name; # find out current UID/GID my $originaluid = (lstat $File::Find::name)[4]; my $newuid = $originaluid; my $originalgid = (lstat $File::Find::name)[5]; my $newgid = $originalgid; # increment but only if we are below the new range $newuid += $increase if ($originaluid < $increase); $newgid += $increase if ($originalgid < $increase); # update if there is at least one change if ($originaluid ne $newuid or $originalgid ne $newgid) { if ( -l "$File::Find::name" ) { # 😂 Let's not interpret symlinks directly to the host system 😂 print "skip link:\t $v\n"; } else { print "file:\t $v \t set to UID:$newuid GID:$newgid\n"; chown($newuid, $newgid, $File::Find::name); } } else { print "file:\t $v \t kept to UID:$newuid GID:$newgid\n"; } } # EOF |
Оригинальный пост на SecOps.it Blog • Настройка непривилегированного LXC