Skip to content

Instantly share code, notes, and snippets.

@wankdanker
Last active December 26, 2023 19:43
Show Gist options
  • Save wankdanker/cbbbe8ed01fa2c0d31835e6d6c49dcc3 to your computer and use it in GitHub Desktop.
Save wankdanker/cbbbe8ed01fa2c0d31835e6d6c49dcc3 to your computer and use it in GitHub Desktop.
A script to make Proxmox LXC Containers unprivileged
#!/bin/bash
##
## Warning: do not use this unless you understand and agree with what it does
##
## Based on: https://forum.proxmox.com/threads/convert-privileged-to-unprivileged-container.31066/#post-261883
##
## NOT HANDLED
## * multiple disks
## * if there are backup/snapshot references in the lxc/$vmid.conf the unprivileged:1 will be added to the end of the file and in a backup config not in the active config, that can break the first boot
## * setuid and setgid permissions are not retained
# CONFIGURE THIS (the pool on which subvol-NNN-disk-1's exist):
vol=pve1-data
vmid=$1
if [ "$vmid" == "" ];
then
echo "Usage is: $0 vmid";
exit 1
fi
echo "stopping vm $vmid"
pct stop $vmid
echo "taking snapshot"
zfs snapshot $vol/subvol-$vmid-disk-1@mkunpriv-$( date +%Y%m%d%H%M%S%N )
echo "chowning files, sockets and pipes"
find /$vol/subvol-$vmid-disk-1/ -type f -or -type s -or -type p | while read S; do U="$(ls -ln "${S}" | awk '{print$3}')"; G="$(ls -ln "${S}" | awk '{print$4}')"; F=100000; chown "${F:0: -${#U}}${U}:${F:0: -${#G}}${G}" "${S}"; done
echo "chowning symlinks"
find /$vol/subvol-$vmid-disk-1/ -type l | while read S; do U="$(ls -ln "${S}" | awk '{print$3}')"; G="$(ls -ln "${S}" | awk '{print$4}')"; F=100000; chown -h "${F:0: -${#U}}${U}:${F:0: -${#G}}${G}" "${S}"; done
echo "chowning directores"
find /$vol/subvol-$vmid-disk-1/ -type d | while read S; do U="$(ls -lnd "${S}" | awk '{print$3}')"; G="$(ls -lnd "${S}" | awk '{print$4}')"; F=100000; chown "${F:0: -${#U}}${U}:${F:0: -${#G}}${G}" "${S}"; done
echo "fixing postfix if necessary"
[ -e /$vol/subvol-$vmid-disk-1/var/spool/postfix/dev/-random ] && rm -ri /$vol/subvol-$vmid-disk-1/var/spool/postfix/dev/-random
[ -e /$vol/subvol-$vmid-disk-1/var/spool/postfix/dev/-urandom ] && rm -ri /$vol/subvol-$vmid-disk-1/var/spool/postfix/dev/-urandom
echo "setting suid on sudo"
[ -e /$vol/subvol-$vmid-disk-1/usr/bin/sudo ] && chmod u+s /$vol/subvol-$vmid-disk-1/usr/bin/sudo
echo "enabling unprivileged setting on vm config"
echo -e "\nunprivileged: 1" >> /etc/pve/lxc/$vmid.conf
echo "starting vm $vmid"
pct start $vmid
@wankdanker
Copy link
Author

@Phlogi I have not worked on one nor searched for one, so I'm not sure.. I know the way the Proxmox team recommends to do it is by backup/restore. I think during the restore process, you have the option to toggle unprivileged or privileged.

@danielehrhardt
Copy link

How long does this process Take?

@wankdanker
Copy link
Author

@danielehrhardt It really depends on the number of files in the volume. It's running find three times at the root of the container. If you have enough memory, then probably a lot of the file metadata would be in ram after the first execution of find. The output of find is piped to a bunch of commands... I don't know how long processing each file takes.

I did this to probably 20 or 30 containers. Some of those containers were barely modified installations of Ubuntu Server with the latest packages and very little user data. Those probably took 15 to 30 minutes each.

Other containers were running Samba or Cyrus IMAP with hundreds of thousands if not millions of files and those took hours.

@elderlabs
Copy link

elderlabs commented Oct 22, 2023

Is there version to undo this? Changing a unprivileged to a privileged container?

Yes, I modified this script to do that a few years ago and entirely forgot to share it:

#!/bin/bash
##
## Warning: do not use this unless you understand and agree with what it does
##
## Based on: https://forum.proxmox.com/threads/convert-privileged-to-unprivileged-container.31066/#post-261883
##
## NOT HANDLED
## * multiple disks
## * if there are backup/snapshot references in the lxc/$vmid.conf the unprivileged:1 will be added to the end of the file and in a backup config not in the active config, that can break the first boot
## * setuid and setgid permissions are not retained

# CONFIGURE THIS (the pool on which subvol-NNN-disk-1's exist):
vol=pve1-data
vmid=$1

if [ "$vmid" == "" ];
then
        echo "Usage is: $0 vmid";
        exit 1
fi

echo "stopping container $vmid"
pct stop $vmid

echo "taking snapshot"
zfs snapshot $vol/subvol-$vmid-disk-0@mkpriv-$( date +%Y%m%d%H%M%S%N )

echo "chowning files, sockets and pipes"
find /$vol/subvol-$vmid-disk-0/ -type f -or -type s -or -type p | while read S; do U="$(ls -ln "${S}" | awk '{print$3}')"; G="$(ls -ln "${S}" | awk '{print$4}')"; chown "${U:3}:${G:3}" "${S}"; done

echo "chowning symlinks"
find /$vol/subvol-$vmid-disk-0/ -type l | while read S; do U="$(ls -ln "${S}" | awk '{print$3}')"; G="$(ls -ln "${S}" | awk '{print$4}')"; chown -h "${U:3}:${G:3}" "${S}"; done

echo "chowning directores"
find /$vol/subvol-$vmid-disk-0/ -type d | while read S; do U="$(ls -lnd "${S}" | awk '{print$3}')"; G="$(ls -lnd "${S}" | awk '{print$4}')"; chown "${U:3}:${G:3}" "${S}"; done

#echo "fixing postfix if necessary"
#[ -e /$vol/subvol-$vmid-disk-0/var/spool/postfix/dev/-random ] && rm -ri /$vol/subvol-$vmid-disk-0/var/spool/postfix/dev/-random
#[ -e /$vol/subvol-$vmid-disk-0/var/spool/postfix/dev/-urandom ] && rm -ri /$vol/subvol-$vmid-disk-0/var/spool/postfix/dev/-urandom

#echo "setting suid on sudo"
#[ -e /$vol/subvol-$vmid-disk-0/usr/bin/sudo ] && chmod u+s /$vol/subvol-$vmid-disk-0/usr/bin/sudo

echo "disabling unprivileged setting in lxc config"
sed -i 's/unprivileged: 1/# unprivileged: 1/g' /etc/pve/lxc/$vmid.conf

echo "starting container $vmid"
pct start $vmid

I'm not certain whether sudo or postfix need to be modified when converting to privledged, though mine didn't, so ymmv. This script assumes your system uses ZFS. If it doesn't, comment out the zfs snapshot line and/or replace it with an equivalent.

Standard disclaimer that while this script worked for me, it may not work for thee (it may not work for you the way it did for me, or as intended), thus take a backup, restore it, and test it on the restored instance.

Should @wankdanker choose to do so, they could modify their gist here with an extra arg that converts unprivileged to privileged and vice-versa so that the script does everything in an all-in-one fashion. I could do it myself, time permitting, but as I've benefitted from their work, I'll share what I've done here and leave it open to them whether they'd like to do so.

Regards to all.

@dgarner-cg
Copy link

fyi, you two that wrote the priv and unpriv script are heroes.

@elderlabs
Copy link

I got around to merging the two scripts into one, but in testing, ran into a weird issue. I'll share it once I'm a bit more confident in its functionality. I believe my issue may have been umask related, but haven't had the time to verify.

@dgarner-cg
Copy link

I can't wait, if you would, ping me when you do.

@dgarner-cg
Copy link

I got around to merging the two scripts into one, but in testing, ran into a weird issue. I'll share it once I'm a bit more confident in its functionality. I believe my issue may have been umask related, but haven't had the time to verify.

I've been working on a bit of an update, but running into a little speed bump and out of time for the day, if you want to take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment