Настройка непривилегированного 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



increase-uid-gid.pl

Довольно старый скрипт, но всё ещё полезный.
yeupou.wordpress.com/2017/06/23/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 {
    print $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) {
        #chown($newuid, $newgid, $File::Find::name);
        chown($newuid, $newgid, $File::Find::name);
        print " set to UID:$newuid GID:$newgid\n";
    } else {
        print " kept to UID:$originaluid GID:$originalgid\n";
    }

}

# EOF