Help with idmap & subuid/subgid please

The error i keep getting here seems to be:

Error: Failed to get ID map: Host id is in the range of subids

afaik, this won’t work:

sudo tee /etc/sub{uid,gid} <<EOF
root:1000:65536
user0:100000:65536
user1:100001:65536
user2:100002:65536
user3:100003:65536
EOF

because of overlap, the second example I showed:

sudo tee /etc/sub{uid,gid} <<EOF
root:1000:65536
user0:100000:65536
user1:165536:65536
user2:231072:65536
user3:296608:65536
EOF

is rather nasty because of the odd numbers.

I suppose, deleting user{0…3} rows from the sub{uid,gid} files are enough for idmapping.
Regards.

are you saying for raw.idmap i don’t actually need them in sub{uid,gid}?

It seems so simple yet, this just isn’t working for me.

  • I have a host with 4 users user0, user1, user2, user3 with uids 1000, 1001, 1002, 1003 and a group on my host shared which has a gid of 1004
  • c1 shall have user3 passed in and shared gid
  • c2 shall have user0, user1, user2, user3, shared gid passed in and its own users with those names

Everything I do seems to result in an error of some kind, and I’ve spent about a day trying to get this working ugh.

if someone could show me an example of what needs to go into sub{uid,gid} and id.rawmap for c1 and c2 i’d appreciate it, because I’m just not getting it.

So I tried with that:

tee /etc/sub{uid,gid} <<EOF
lxd:100000:65536
root:100000:65536
EOF
systemctl restart lxd

and inside the container:

 groupadd -g 1003 user3
 groupadd -g 1004 shared
 useradd -u 1003 -g 1003 -G shared user3
printf "both 1003 100003" | sudo lxc config set docker-container raw.idmap -

ERROR conf - …/src/lxc/conf.c:lxc_map_ids:3672 - newuidmap failed to write mapping “newuidmap: uid range [100003-100004) → [1003-1004) not allowed”: newuidmap 275011 0 100000 65536 100003 1003 1

I dunno how to get what I want, seems simple enough but everything I try doesn’t work.

Hi,
What is the host linux distro? Can you post the lxc info | grep -i shiftfs:?
Did you get that error when restart the container, right?
Regards.

The first parameter which is host user id(1003) and the second parameter which is container user id(100003), right?

I have tried your commands without any error, which my host system is Ubuntu 20.04.4 and my lxc version is 5.4.

Okay, well I’m running 5.4 as well on Archlinux.

# lxc info | grep -i shiftfs:
    shiftfs: "false"

Yes.

Yes

Yes.

Here’s how I created the container:

On the host

lxc rm c1
lxc launch images:ubuntu/22.04 c1
lxc config device add c1 home disk source=/home/user3/ path=/home/user3
lxc config device add c1 shared disk source=/mnt/shared path=/mnt/shared

In the container:

lxc exec c1 bash
groupadd -g 1003 user3
groupadd -g 1004 shared
useradd -u 1003 -g 1003 -G shared user3
exit

On the host:

printf "both 1003 100003" | sudo lxc config set c1 raw.idmap -
lxc restart c1

ERROR conf - …/src/lxc/conf.c:lxc_map_ids:3672 - newuidmap failed to write mapping “newuidmap: uid range [100003-100004) → [1003-1004) not allowed”: newuidmap 325627 0 100000 65536 100003 1003 1

For what I described above is my subuid/gid correct?

$ cat /etc/subuid
lxd:100000:65536
root:100000:65536

$ cat /etc/subgid
lxd:100000:65536
root:100000:65536

Can you post the output of the lxc config show c1, I think that looks like an Archlinux issue but not sure.

Here:

# lxc config show c1
architecture: x86_64
config:
  environment.LANG: en_US.UTF-8
  environment.LC_COLLATE: POSIX
  image.architecture: amd64
  image.description: Ubuntu jammy amd64 (20220801_07:42)
  image.os: Ubuntu
  image.release: jammy
  image.serial: "20220801_07:42"
  image.type: squashfs
  image.variant: default
  raw.idmap: both 1003 100003
  security.nesting: "true"
  security.syscalls.intercept.mknod: "true"
  security.syscalls.intercept.setxattr: "true"
  volatile.base_image: 28a4d7df8557cba690b1cc3f11585bfebe8e904fb7abf9e8eb621894da96fed6
  volatile.cloud-init.instance-id: dca7fac0-c7ae-4c6c-877c-4452c5019722
  volatile.eth0.host_name: veth254162ac
  volatile.eth0.hwaddr: 00:16:3e:6b:4e:56
  volatile.eth0.name: eth0
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":100003,"Maprange":1}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":100003,"Maprange":1}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":100003,"Maprange":1}]'
  volatile.last_state.power: STOPPED
  volatile.uuid: 1b7b6b66-fefc-4709-b1f5-db77aad17034
devices:
  docker:
    path: /var/lib/docker
    pool: docker
    source: c1
    type: disk
  home:
    path: /home/user3
    source: /home/user3/
    type: disk
  shared:
    path: /mnt/shared
    source: /mnt/shared
    type: disk
ephemeral: false
profiles:
- default
stateful: false
description: ""

Have a look at that thread, can give you a hint.
https://github.com/lxc/lxd/issues/7469
Regards.
Here are my configurations.

indiana@lxdserver:~$ more /etc/subuid
indiana:100000:65536
indiana@lxdserver:~$ more /etc/subgid
indiana:100000:65536

Hmm, okay so I tried with:

sudo tee /etc/sub{uid,gid} <<EOF
lxd:100000:65536
root:100000:65536
user0:165536:65536
user1:231072:65536
user2:296608:65536
user3:362144:65536
EOF

I tried with:

printf "both 1003 362144" | sudo lxc config set c1 raw.idmap -

ERROR conf - …/src/lxc/conf.c:lxc_map_ids:3672 - newuidmap failed to write mapping “newuidmap: uid range [362144-362145) → [1003-1004) not allowed”: newuidmap 358529 0 100000 65536 362144 1003 1

So I don’t see why this doesn’t work. I created each user and shifted the uid by 65536 so they don’t overlap

sudo tee /etc/sub{uid,gid} <<EOF
lxd:100000:65536
root:100000:65536
one:165536:65536
two:231072:65536
three:296608:65536
four:362144:65536
EOF

Add shared group:

sudo tee -a /etc/subgid <<EOF
shared:362145:1
EOF
systemctl restart lxd
lxc launch images:ubuntu/22.04 c1
lxc profile add c1 vlan7
lxc config device add c1 docker disk pool=docker source=c1 path=/var/lib/docker
lxc config set c1 security.nesting=true \
                                security.syscalls.intercept.mknod=true \
                                security.syscalls.intercept.setxattr=true
lxc config set c1 environment.LANG en_US.UTF-8
lxc config set c1 environment.LC_COLLATE POSIX
lxc config device add c1 home disk source=/home/four/ path=/home/four
lxc config device add c1 shared disk source=/mnt/shared path=/mnt/shared

lxc exec c1 bash
lxc restart c1
systemctl restart lxd

Now I try to make the custom idmap

printf "both 362144 1003\ngid 362145 1004\n" | sudo lxc config set c1 raw.idmap -

and I get

ERROR conf - …/src/lxc/conf.c:lxc_map_ids:3672 - newuidmap failed to write mapping “newuidmap: uid range [1003-1004) → [362144-362145) not allowed”: newuidmap 427222 0 100000 1003 1003 362144 1 1004 101004 64532

I honestly don’t know if I’m dumb or what, but this doesn’t seem to work.

I wonder if the problem is that I am using linux-hardened. I noticed that kernel.unprivileged_userns_clone is set to 0. Pretty sure that is needed.

I haven’t set any sysctl’s manually, on this system, so maybe using that kernel sets it.

So I found a post, you can check it out link. @stgraber point that out.

So first thing to note is that LXD loads the subuid/subgid values from /etc on startup.
If you modified them but didn’t restart LXD, that could be a problem.

Regards.

I had been restarting the daemon, so that doesn’t seem to be the issue.

I also made sure to set:

sysctl -w kernel.unprivileged_userns_clone=1
systemctl restart lxd

I think the problem is the raw.idmap command, that’s what seems to not work, the container starts if i don’t do that, ie if I set it back to:

printf "" | sudo lxc config set c1 raw.idmap -

So I do that, and i start the container

lxc start c1
lxc exec c1 bash
groupadd -g 1003 three
groupadd -g 1004 shared
useradd -u 1003 -g 1003 -G shared three
printf "both 362144 1003\ngid 362145 1004\n" | sudo lxc config set c1 raw.idmap -
# lxc config show c1
architecture: x86_64
config:
  environment.LANG: en_US.UTF-8
  environment.LC_COLLATE: POSIX
  image.architecture: amd64
  image.description: Ubuntu jammy amd64 (20220801_07:42)
  image.os: Ubuntu
  image.release: jammy
  image.serial: "20220801_07:42"
  image.type: squashfs
  image.variant: default
  raw.idmap: |
    both 362144 1003
    gid 362145 1004
  security.nesting: "true"
  security.syscalls.intercept.mknod: "true"
  security.syscalls.intercept.setxattr: "true"
  volatile.base_image: 28a4d7df8557cba690b1cc3f11585bfebe8e904fb7abf9e8eb621894da96fed6
  volatile.cloud-init.instance-id: afd4efc0-1317-455a-b644-220cf975bb71
  volatile.eth0.host_name: veth7a3566a3
  volatile.eth0.hwaddr: 00:16:3e:fd:98:a8
  volatile.eth0.name: eth0
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":362144,"Nsid":1003,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":101004,"Nsid":1004,"Maprange":64532},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":362144,"Nsid":1003,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":362145,"Nsid":1004,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":101005,"Nsid":1005,"Maprange":64531}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.power: RUNNING
  volatile.uuid: ea1abf51-fb19-4bd6-ac06-e5e6e36fb0e6
devices:
  docker:
    path: /var/lib/docker
    pool: docker
    source: c1
    type: disk
  home:
    path: /home/three
    source: /home/three/
    type: disk
  shared:
    path: /mnt/shared
    source: /mnt/shared
    type: disk
ephemeral: false
profiles:
- default
- vlan7
stateful: false
description: ""
systemctl restart lxd

Make sure to restart it again for good measure, start the container:

ERROR conf - …/src/lxc/conf.c:lxc_map_ids:3672 - newuidmap failed to write mapping “newuidmap: uid range [1003-1004) → [362144-362145) not allowed”: newuidmap 448521 0 100000 1003 1003 362144 1 1004 101004 64532

Still not working hmm. If My understanding is correct I’m trying tp map in 296608 to the host as 1003.

Am I even doing it right?

Interestingly, I was able to get this working on an Ubuntu host but not on the Archlinux one, even with the standard linux kernel.

Ubuntu

$ lxc config show c1
architecture: x86_64
config:
  environment.LANG: en_US.UTF-8
  environment.LC_COLLATE: POSIX
  image.architecture: amd64
  image.description: Ubuntu jammy amd64 (20220801_07:42)
  image.os: Ubuntu
  image.release: jammy
  image.serial: "20220801_07:42"
  image.type: squashfs
  image.variant: default
  raw.idmap: |
    both 1003 1003
    gid 1004 1004
  security.nesting: "true"
  security.syscalls.intercept.mknod: "true"
  security.syscalls.intercept.setxattr: "true"
  volatile.base_image: 28a4d7df8557cba690b1cc3f11585bfebe8e904fb7abf9e8eb621894da96fed6
  volatile.cloud-init.instance-id: dbf64754-aaf4-4a43-82a7-b0c1df237479
  volatile.eth0.host_name: veth28601199
  volatile.eth0.hwaddr: 00:16:3e:75:7b:14
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":1001004,"Nsid":1004,"Maprange":999998996},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":1004,"Nsid":1004,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":1001005,"Nsid":1005,"Maprange":999998995}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":1001004,"Nsid":1004,"Maprange":999998996},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":1004,"Nsid":1004,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":1001005,"Nsid":1005,"Maprange":999998995}]'
  volatile.last_state.idmap: '[]'
  volatile.last_state.power: RUNNING
  volatile.uuid: 022d6f84-4f61-423f-b178-5a5c8d9f28c9
devices:
  docker:
    path: /var/lib/docker
    pool: docker
    source: c1
    type: disk
  home:
    path: /home/four
    source: /home/four/
    type: disk
  shared:
    path: /mnt/shared
    source: /mnt/shared
    type: disk
ephemeral: false
profiles:
- default
stateful: false
description: ""

Archlinux

$ sudo lxc config show c1
architecture: x86_64
config:
  environment.LANG: en_US.UTF-8
  environment.LC_COLLATE: POSIX
  image.architecture: amd64
  image.description: Ubuntu jammy amd64 (20220801_07:42)
  image.os: Ubuntu
  image.release: jammy
  image.serial: "20220801_07:42"
  image.type: squashfs
  image.variant: default
  raw.idmap: |
    both 1003 1003
    gid 1004 1004
  security.nesting: "true"
  security.syscalls.intercept.mknod: "true"
  security.syscalls.intercept.setxattr: "true"
  volatile.base_image: 28a4d7df8557cba690b1cc3f11585bfebe8e904fb7abf9e8eb621894da96fed6
  volatile.cloud-init.instance-id: 02fe5c34-5072-4e40-afbb-e835a7de03b1
  volatile.eth0.host_name: vetha0a1f7de
  volatile.eth0.hwaddr: 00:16:3e:b1:1b:90
  volatile.eth0.name: eth0
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":101004,"Nsid":1004,"Maprange":64532},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":1004,"Nsid":1004,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":101005,"Nsid":1005,"Maprange":64531}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":101004,"Nsid":1004,"Maprange":64532},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":1004,"Nsid":1004,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":101005,"Nsid":1005,"Maprange":64531}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":101004,"Nsid":1004,"Maprange":64532},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":1003},{"Isuid":true,"Isgid":true,"Hostid":1003,"Nsid":1003,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":1004,"Nsid":1004,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":101005,"Nsid":1005,"Maprange":64531}]'
  volatile.last_state.power: STOPPED
  volatile.uuid: 4ffa4e66-0ee5-4b8c-a0aa-d15c47ab0bd6
devices:
  docker:
    path: /var/lib/docker
    pool: docker
    source: c1
    type: disk
  home:
    path: /home/four
    source: /home/four/
    type: disk
  shared:
    path: /mnt/shared
    source: /mnt/shared
    type: disk
ephemeral: false
profiles:
- default
stateful: false
description: ""

They were set up the same way For example:

sudo adduser two
sudo adduser three
sudo adduser four

Which resulted in /etc/passwd on host:

one:x:1000:1000:one,,,:/home/one:/bin/bash
two:x:1001:1001:,,,:/home/two:/bin/bash
three:x:1002:1002:,,,:/home/three:/bin/bash
four:x:1003:1003:,,,:/home/four:/bin/bash

Then I added a shared group:

sudo groupadd -g 1004 shared
sudo gpasswd -a one shared
sudo gpasswd -a two shared
sudo gpasswd -a three shared
sudo gpasswd -a four shared

In /etc/groups:

one:x:1000:
two:x:1001:
three:x:1002:
four:x:1003:
shared:x:1004:one,two,three,four

The host sub{uid,gid}:

$ cat /etc/subuid
one:100000:65536
two:165536:65536
three:231072:65536
four:296608:65536

$ cat /etc/subgid
one:100000:65536
two:165536:65536
three:231072:65536
four:296608:65536

Finally i added the extra group

sudo tee -a /etc/subgid <<EOF
shared:362145:1
EOF

Standard setup:

$ lxd init
Would you like to use LXD clustering? (yes/no) [default=no]: no
Do you want to configure a new storage pool? (yes/no) [default=yes]: 
Name of the new storage pool [default=default]: 
Name of the storage backend to use (ceph, btrfs, dir, lvm, zfs) [default=zfs]: btrfs
Create a new BTRFS pool? (yes/no) [default=yes]: yes
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]: 
Size in GB of the new loop device (1GB minimum) [default=5GB]: 
Would you like to connect to a MAAS server? (yes/no) [default=no]: 
Would you like to create a new local network bridge? (yes/no) [default=yes]: 
What should the new bridge be called? [default=lxdbr0]: 
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 
Would you like the LXD server to be available over the network? (yes/no) [default=no]: 
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]: 
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
$ sudo lxc launch images:ubuntu/22.04 c1
$ sudo lxc storage create docker btrfs
$ sudo lxc storage volume create docker c1
$ sudo lxc config device add c1 docker disk pool=docker source=c1 path=/var/lib/docker
$ sudo lxc config set c1 security.nesting=true \
                         security.syscalls.intercept.mknod=true \
                         security.syscalls.intercept.setxattr=true
$ sudo lxc config set c1 environment.LANG en_US.UTF-8
$ sudo lxc config set c1 environment.LC_COLLATE POSIX
$ sudo mkdir -p /mnt/shared && sudo chown -R root:shared /mnt/shared
$ sudo chmod g+s /mnt/shared
$ sudo lxc config device add c1 home disk source=/home/four/ path=/home/four
$ sudo lxc config device add c1 shared disk source=/mnt/shared path=/mnt/shared
$ lxc exec c1 bash
# groupadd -g 1003 four
# groupadd -g 1004 shared
# useradd -u 1003 -g 1003 -G shared four
exit

Finally add the idmap.raw and restart:

printf "both 1003 1003\ngid 1004 1004\n" | sudo lxc config set c1 raw.idmap -
systemctl reload snap.lxd.daemon

I looked at these two threads:

However didn’t really spot anything there that helped. My Arch linux system is using 5.18.14-arch1-1 #1 SMP PREEMPT_DYNAMIC

I’ve spent two days trying to figure this out and gotten no closer.

I made sure these were set

kernel.unprivileged_userns_clone = 1
user.max_user_namespaces = 256484

and I added:

sudo tee -a /etc/lxc/default.conf <<EOF
lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536
EOF

Restarted LXD, still giving me that error.

I tried with:

printf "both 1000 1000" | sudo lxc config set docker-container raw.idmap -

ERROR conf - …/src/lxc/conf.c:lxc_map_ids:3672 - newuidmap failed to write mapping “newuidmap: uid range [1000-1001) → [1000-1001) not allowed”: newuidmap 82353 0 100000 1000 1000 1000 1 1001 101001 64535

# cat /etc/subuid
root:100000:65536
lxd:100000:65536
one:165536:65536
two:231072:65536
three:296608:65536
four:362144:65536

# cat /etc/subgid
root:100000:65536
lxd:100000:65536
one:165536:65536
two:231072:65536
three:296608:65536
four:362144:65536
shared:362145:1

So I think the issue is this Newuidmap failed to write mapping "newuidmap: uid range [1000-1001) -> [1000-1001) not allowed"

Using this configuration:

lxc.idmap = u 0 100000 1000
lxc.idmap = u 1000 1000 1
lxc.idmap = u 1001 101001 64535
lxc.idmap = g 0 100000 1000
lxc.idmap = g 1000 1000 1
lxc.idmap = g 1001 101001 64535

I was able to pass in the “one” user to “ubuntu”.

I also made my subuid and subgid

root:1000:1
root:100000:65536
lxd:100000:65536

Now what I’m not sure about is users two, three and four and that shared group.

So after days of pain i finally figured it out. I came across this tool https://github.com/ddimick/proxmox-lxc-idmapper

For multiple users and the shared group I needed:

$ cat /etc/subuid
root:1000:1
root:1001:1
root:1002:1
root:1003:1
root:100000:65536
lxd:100000:65536
root:1000:1
root:1001:1
root:1002:1
root:1003:1
root:1004:1
root:100000:65536
lxd:100000:65536

Then in /etc/lxc/default.conf I needed:

lxc.idmap = u 0 100000 1000
lxc.idmap = g 0 100000 1000
lxc.idmap = u 1000 1000 1
lxc.idmap = g 1000 1000 1
lxc.idmap = u 1001 101001 0
lxc.idmap = g 1001 101001 0
lxc.idmap = u 1001 1001 1
lxc.idmap = g 1001 1001 1
lxc.idmap = u 1002 101002 0
lxc.idmap = g 1002 101002 0
lxc.idmap = u 1002 1002 1
lxc.idmap = g 1002 1002 1
lxc.idmap = u 1003 101003 0
lxc.idmap = g 1003 101003 0
lxc.idmap = u 1003 1003 1
lxc.idmap = g 1003 1003 1
lxc.idmap = u 1004 101004 64532
lxc.idmap = g 1004 1004 1
lxc.idmap = g 1005 101005 64532

And finally:

printf "both 1003 1003\ngid 1004 1004\n" | sudo lxc config set c1 raw.idmap -