Running glibc programs: Difference between revisions

From Alpine Linux
m (→‎Gentoo Linux: add userspec to chroot as normal user (e.g. current person logged on host) not as root)
m (Undo revision 27139 by Manoel (talk) remove self-promotion because people are complaining.)
Tag: Undo
 
(40 intermediate revisions by 15 users not shown)
Line 1: Line 1:
{{Draft}}
If you want to run [https://www.gnu.org/software/libc/ glibc] programs in Alpine Linux, there are a few ways of doing so. You can install the [https://git.adelielinux.org/adelie/gcompat gcompat] compatibility layer, you can install glibc alongside [https://musl.libc.org/ musl] (manually, as it isn't packaged), or you could do it the easy way and use either Flatpak (the easiest), containers or a chroot.<br>
 
If you want to run [https://www.gnu.org/software/libc/ glibc] programs in Alpine Linux, there are a few ways of doing so. You could install glibc as additional to [https://uclibc.org/about.html uclibc] (you would have to do this manually), or you could do it the easy way and use a chroot.<br>
 
Because there are different use cases, this is just a slight overview about what's possible and what's intelligent.<br>


Because there are different use cases, this is just a slight overview about what's possible and what's sensible.<br>


= Your options =
= Your options =


== Using BusyBox ==
== gcompat ==


First, the most simple approach for setting up a chroot is by using a glibc build of [https://www.busybox.net/about.html BusyBox].
gcompat is the go-to compatibility layer for Alpine users.


This approach has just a few downsides:-
{{cmd|apk add {{pkg|gcompat}}}}
* You have to link most <code>/bin/</code> and <code>/usr/bin</code> programs against <code>/bin/busybox</code>, and some BusyBox builds break if you don't configure them correctly.
* You have to manually download every library you need for your program manually.


However, if you want a small environment for one simple use case, then this is the solution you want.
After that you run your binaries as normal.


== Using a live CD ==
== Flatpak ==


If you prefer using any special distro, you can always download and extract a live CD and use it as a chroot enviroment.
Flatpak is by far the easiest method of running any graphical glibc program on Alpine.
Firstly install it.


== Using an image ==
{{cmd|apk add {{pkg|flatpak}}}}


For Gentoo, it is the slowest approach especially on slow machines since it is not binary distribution and can be indecisive, but you have the advantage of controlling the package version of whichever library you will install. A drawback would be a big build. You have to install a Portage tree, which uses up a lot of space.  (It's not 100% necessary if you don't have to install any additional content that you won't need.)  Sometimes the package will fail on compilation phase of emerge.  You either end up patching it yourself or waiting for a fix to appear on their Bugzilla from an experienced user.
Then you can run any Flatpak application:


For Arch or Debian, it is recommended since packages are precompiled and better at unattended package installation. This approach isn't as easily executed as the other alternatives, but this may be the cleanest and most recommended one for the every day user.
  {{cmd|flatpak run <flatpak name>}}


= How to do it =
It is recommended to enable [https://flathub.org Flathub] using its instructions [https://flatpak.org/setup/Alpine/ here], as most glibc programs you might need will be packaged there.


This is just a quick draft, so here it comes.
You can then install applications from it, for example:


== Using BusyBox ==
{{cmd|flatpak install com.valvesoftware.Steam}}


First, we need to download BusyBox.  You can choose any of your favourite distros to download a prebuilt version.  For instance, you could use Arch Linux [https://www.archlinux.org/packages/?q=busybox packages], as follows:
== Chroot ==


wget http://www.archlinux.org/packages/community/i686/busybox/download/ -O busybox.pkg.tar.xz
An option that's easier to generalize to other glibc applications is installing a glibc-based distribution into a chroot. You can then either chroot into it, or use a symlink and some configuration to make its glibc (and associated libraries) usable from Alpine.
wget http://www.archlinux.org/packages/core/i686/glibc/download/ -O glibc.pkg.tar.xz
mkdir -p ~/chroot/usr/bin/ ~/chroot/{dev,proc,root,etc}
for i in *.pkg.tar.xz;do
bsdtar xfJ $i -C ~/chroot
done
cp /etc/resolv.conf ~/chroot/etc/
ln -s /bin/busybox ~/chroot/bin/sh
ln -s /bin/busybox ~/chroot/bin/ln
sudo chroot ~/chroot/ /bin/sh


This creates a simple chroot enviroment, which we will expand through all the commands included in BusyBox:
After setting up a chroot using any of the methods described below, the loader can be set up in Alpine like so (these instructions are for a Debian chroot in /var/chroots/debian, on x86_64, but can be adapted to other systems by using the appropriate paths):


for i in $(busybox --list);do ln -s /bin/busybox /usr/bin/$i;done
{{cmd|mkdir -p /lib64
 
ln -s /var/chroots/debian/lib/x86_64-linux-gnu/ld-2.33.so /lib64
 
printf '/var/chroots/debian/lib/x86_64-linux-gnu\n/var/chroots/debian/usr/lib/x86_64-linux-gnu\n' > /etc/ld.so.conf
== Using a live CD ==
/var/chroots/debian/sbin/ldconfig}}
{{Draft|Contributions welcome}}
 
 
== Using an image ==


=== Gentoo Linux ===
=== Gentoo Linux ===
Line 64: Line 47:
First,
First,


sudo apk add xz
{{cmd|doas apk add {{pkg|xz}}}}
 
You also may need the vanilla kernel.  If any time Gentoo decides to update PAM, you need it for it to emerge successfully without problems.
 
sudo apk add kernel-vanilla
 
Add the kernel-vanilla to Grub and reboot with the vanilla kernel if you are going to pull in both git and layman which they use to download user community supported packages.


Enter the chroot:
Enter the chroot:
mkdir ~/chroot
{{cmd|mkdir ~/chroot
cd ~/chroot
cd ~/chroot
tar -xvf stage3-*.tar.xz
tar -xvf stage3-*.tar.xz
tar -xvf portage-latest.tar.xz
tar -xvf portage-latest.tar.xz
mv portage usr
mv portage usr
sudo mount --bind /dev dev
doas mount --bind /dev dev
sudo mount --bind /sys sys
doas mount --bind /sys sys
sudo mount -t proc proc proc
doas mount -t proc proc proc
cp /etc/resolv.conf etc
cp /etc/resolv.conf etc
sudo chroot . /bin/bash
doas chroot . /bin/bash}}


And voilà, you have your working Gentoo chroot!<br>
And voilà, you have your working Gentoo chroot!<br>
Line 90: Line 67:
Here is a wrapper script that is similar to <code>arch-chroot</code> when you frequently reuse this chroot:
Here is a wrapper script that is similar to <code>arch-chroot</code> when you frequently reuse this chroot:


Also add your user name to the chroot or make changes to the userspec option to chroot line.
Also, create an account with the same user name as host current user to the chroot or make changes to the userspec option to chroot line.


{{Cat|gentoo-chroot.sh|<nowiki>!/bin/bash
{{Cat|gentoo-chroot.sh|<nowiki>!/bin/bash
CHROOT_PATH="/home/$USER/chroot"
CHROOT_PATH="/home/$USER/chroot"
cd $CHROOT_PATH
cd $CHROOT_PATH
mount | grep $CHROOT_PATH/dev || sudo mount --bind /dev dev
mount | grep $CHROOT_PATH/dev || doas mount --bind /dev dev
mount | grep $CHROOT_PATH/sys || sudo mount --bind /sys sys
mount | grep $CHROOT_PATH/sys || doas mount --bind /sys sys
mount | grep $CHROOT_PATH/proc || sudo mount -t proc proc proc
mount | grep $CHROOT_PATH/proc || doas mount -t proc proc proc
cp /etc/resolv.conf etc
cp /etc/resolv.conf etc
sudo chroot --userspec=$USER:users . /bin/bash
doas chroot --userspec=$USER:users . /bin/bash
echo "You must manually unmount $CHROOT_PATH/dev, $CHROOT_PATH/sys, $CHROOT_PATH/proc."
echo "You must manually unmount $CHROOT_PATH/dev, $CHROOT_PATH/sys, $CHROOT_PATH/proc."
</nowiki>
</nowiki>
Line 108: Line 85:
=== Arch Linux ===
=== Arch Linux ===


Although '''pacstrap''' is included with the arch-install-scripts package, it will not work unless the target directory is a mountpoint, so the Arch bootstrap image must be used instead (the image is updated every month, so change the date in the link as required):
Either use '''pacstrap''' (included with the arch-install-scripts package) or an Arch bootstrap image:


  sudo apk add arch-install-scripts
{{cmd|doas apk add {{pkg|arch-install-scripts}}
  mkdir ~/chroot && cd ~/chroot
mkdir ~/chroot && cd ~/chroot
  curl -O https://mirrors.kernel.org/archlinux/iso/latest/archlinux-bootstrap-2018.01.01-x86_64.tar.gz
curl -O https://mirrors.edge.kernel.org/archlinux/iso/latest/archlinux-bootstrap-x86_64.tar.gz
  tar xzf archlinux-bootstrap-2018.01.01-x86_64.tar.gz && rm archlinux-bootstrap-2018.01.01-x86_64.tar.gz
doas tar xzf archlinux-bootstrap-x86_64.tar.gz && rm archlinux-bootstrap-x86_64.tar.gz
  sed -i '/evowise/s/^#//' root.x86_64/etc/pacman.d/mirrorlist
doas sed -i '/evowise/s/^#//' root.x86_64/etc/pacman.d/mirrorlist
  sudo arch-chroot root.x86_64
doas sed -i '/CheckSpace/s/^/#/' root.x86_64/etc/pacman.conf
  [chroot]# pacman-key --init
doas arch-chroot root.x86_64
  [chroot]# pacman-key --populate archlinux
[chroot]# pacman-key --init
[chroot]# pacman-key --populate archlinux}}


Once that is done, update the system and install the desired package(s) (denoted by ''"foo"'' in this example):
Once that is done, update the system and install the desired package(s) (denoted by ''"foo"'' in this example):
    
    
  [chroot]# pacman -Syu ''foo''
{{cmd|[chroot]# pacman -Syu ''foo''}}


=== Debian ===
=== Debian ===
 
{{todo|gresec referencs need to be cleanly removed from this section.}}
Use the provided debootstrap package to create the Debian chroot. <code>--arch</code> is optional, depending of your needs.
Use the provided debootstrap package to create the Debian chroot. <code>--arch</code> is optional, depending of your needs.


Line 132: Line 110:
   for i in /proc/sys/kernel/grsecurity/chroot_*; do echo 0 | sudo tee $i; done
   for i in /proc/sys/kernel/grsecurity/chroot_*; do echo 0 | sudo tee $i; done
   mkdir ~/chroot
   mkdir ~/chroot
   sudo debootstrap --arch=i386 wheezy ~/chroot http://http.debian.net/debian/
   sudo debootstrap --arch=i386 wheezy ~/chroot https://deb.debian.org/debian/
   for i in /proc/sys/kernel/grsecurity/chroot_*; do echo 1 | sudo tee $i; done
   for i in /proc/sys/kernel/grsecurity/chroot_*; do echo 1 | sudo tee $i; done
   sudo chroot ~/chroot /bin/bash
   sudo chroot ~/chroot /bin/bash
Line 138: Line 116:
You can now use <code>apt-get</code> to install needed packages.
You can now use <code>apt-get</code> to install needed packages.


== Examples ==
== Containers ==
 
=== Source dedicated server ===
 
Here is an easy example of how you can run [http://www.srcds.com srcds] in a simple BusyBox chroot.
 
For this server, you will only need the basic chroot and an advanced tar version (the BusyBox version is not sufficient because of the missing -U command):
 
wget http://www.archlinux.org/packages/community/i686/busybox/download/ -O busybox.pkg.tar.xz
wget http://www.archlinux.org/packages/core/i686/glibc/download/ -O glibc.pkg.tar.xz
wget http://www.archlinux.org/packages/core/i686/tar/download/ -O tar.pkg.tar.xz
mkdir -p ~/chroot/usr/bin/ ~/chroot/{dev,proc,root,etc}
for i in *.pkg.tar.xz;do
bsdtar xfJ $i -C ~/chroot
done
cp /etc/resolv.conf ~/chroot/etc/
ln -s /bin/busybox ~/chroot/bin/sh
ln -s /bin/busybox ~/chroot/bin/ln
sudo chroot ~/chroot/ /bin/sh
 
Now that you are in a working chroot, you can download the server and install it.  You just have to execute the following self-explaining commands...
 
mkdir ~/work
cd ~/work
busybox wget http://www.steampowered.com/download/hldsupdatetool.bin
chmod +x hldsupdatetool.bin
ln -s /bin/busybox ./uncompress
cp /bin/tar . #right now executing programs from $PATH is buggy, soon to be fixed (no bug in BusyBox, but in my script)
./hdsupdatetool.bin #you can accept it or not ;)
./steam
./steam
 
...and you should have a working chroot with '''srcds''' installed in it.
 
If you think you are clever or elegant, you can use the server with a bash script:
 
#!/bin/bash
chroot ~/chroot /root/work/steam $@
 
Just save it (in your Alpine installation) under <code>/usr/bin/steam</code>, do a <code>chmod +x /usr/bin/steam</code> and have fun!
 
{{Warning|This script would let '''Steam''' run with root priviliges.  This is not recommended.}}
 
=== MegaCli ===
 
So let's run [https://wikitech.wikimedia.org/wiki/MegaCli MegaCli] in a chroot too, shall we? ;)
 
First we set up a uclibc chroot :)
 
'''MegaCli''' needs more than just glibc.  It needs [https://www.gnu.org/software/ncurses/ ncurses] and the gcc-libs:
 
wget http://www.archlinux.org/packages/community/i686/busybox/download/ -O busybox.pkg.tar.xz
wget http://www.archlinux.org/packages/core/i686/glibc/download/ -O glibc.pkg.tar.xz
wget http://www.archlinux.org/packages/core/i686/ncurses/download/ -O ncurses.pkg.tar.xz
wget http://www.archlinux.org/packages/core/i686/gcc-libs/download/ -O gcc-libs.pkg.tar.xz
mkdir -p ~/chroot/usr/bin/ ~/chroot/{dev,proc,root,etc,sys}
cp /etc/resolv.conf ~/chroot/etc/
for i in *.pkg.tar.xz;do
bsdtar xfJ $i -C ~/chroot
done
ln -s /bin/busybox ~/chroot/bin/sh
ln -s /bin/busybox ~/chroot/bin/ln
 
After this, we visit [http://www.lsi.com/downloads/Public/MegaRAID%20Common%20Files/8.02.16_MegaCLI.zip this] site and download '''8.02.16_MegaCLI.zip'''.


mkdir tmp
It's also possible to use Docker or Podman containers with a helper like Distrobox. This allows using graphical programs easily and doesn't require root privileges once set up.
cd tmp
unzip ../8.02.16_MegaCLI.zip
cd LINUX
unzip MegaCliLin.zip
#Now comes code stolen from rpm2cpio
o=`expr 96 + 8`
set `od -j $o -N 8 -t u1 MegaCli-8.02.16-1.i386.rpm`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
sigsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $sigsize + \( 8 - \( $sigsize \% 8 \) \) \% 8 + 8`
set `od -j $o -N 8 -t u1 MegaCli-8.02.16-1.i386.rpm`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
hdrsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $hdrsize`
dd if=MegaCli-8.02.16-1.i386.rpm ibs=$o skip=1 2>/dev/null |bsdtar -xf -
#wow ...
rm opt/MegaRAID/MegaCli/MegaCli64 # who needs 64bit?
cp -r opt/ ~/chroot/


Now we have a working '''MegaCli''' client in our chroot.
{{cmd|# apk add {{pkg|distrobox}}}}


As with '''srcds''', we do not want to operate from inside the chroot, so here is a little script that should ease you up (use at your own risk):
=== Distrobox + Podman ===


#!/bin/bash
{{cmd|# apk add {{pkg|podman}}}}
user=$(whoami)
if [ "$user" != "root" ];then
echo "This script needs root access"
exit
fi
mount -t proc proc ~/chroot/proc/
mount --bind /dev/ ~/chroot/dev/
mount --bind /sys/ ~/chroot/sys/
#we may need dev and maybe proc too to use this program
chroot ~/chroot /opt/MegaRAID/MegaCli/MegaCli $@
umount ~/chroot/proc
umount ~/chroot/dev
umount ~/chroot/sys


Save it under <code>/usr/bin/MegaCli</code>. Do a <code>chmod +x /usr/bin/MegaCli</code> and good luck.
Then set up rootless Podman, following [[Podman|these steps]].
You'll need to mount your root as shared for Distrobox to function.


Note:  This method takes around 50mb. If you need something smaller, then you can strip a few files from glibc (not recommended), or work on a squashfs.
Fill in {{path|/etc/local.d/mount-rshared.start}} like so:


With the following, you can create a squashfs that is around 15mb small:
{{cmd|#!/bin/sh
mksquashfs ~/chroot/ /chroot.sfs -b 65536
mount --make-rshared /}}


When you add a [https://en.wikipedia.org/wiki/UnionFS unionfs] layer, you can even use it with write access, or you can bind some directories to the writeable directories before you chroot into it.
Mark it as executable.


I will look into it later on.
{{cmd|# chmod +x /etc/local.d/mount-rshared.start}}


You can save the chroot in another directory than your home directory, and you can even install a chroot through an APKBUILD (after someone wrote it).
Then autostart its service.


With this, you could use many glibc-dependent programs through one chroot, but be aware that running programs like this should not be standard.  This should only be used in extreme situations, as in _closed source_ tools linked against glibc.
{{cmd|# rc-update add local default
&#35; rc-service local start}}


=== Skype on Debian chroot ===
Finally you can create a container using your chosen image.


{{Draft|Not yet validated}}
{{cmd|$ distrobox create --image debian --name debian
$ distrobox enter debian}}


This is an example on how to run '''Skype''' from a Debian 32b chroot.
It may also be necessary to allow X authorization for GUI programs to work.


  sudo chroot ~/chroot
{{cmd|$ xhost +si:localuser:$USER}}
  wget http://www.skype.com/go/getskype-linux-deb
  dpkg -i getskype-linux-deb


To fix missing dependencies, you will want to use:
== Chroot + Bubblewrap ==


  apt-get -f install
It's also possible to use a Debian system chroot with Bubblewrap. This allows running programs without root.


Then, exit the chroot:
{{cmd|# apk add bubblewrap debootstrap
&#35; mkdir -p /var/chroots/debian
&#35; debootstrap --arch amd64 stable /var/chroots/debian/ https://deb.debian.org/debian}}


  exit
Finally we can make an alias for bwrap.


Fix PAX flags on Skype binary - '''linux-grsec''' only.
{{cmd|$ alias glibc{{=}}"LANG{{=}}en_US.UTF-8 bwrap --bind /var/chroots/debian / --dev-bind /dev /dev --proc /proc --bind /sys /sys --bind /run /run --bind /home /home --ro-bind /etc/resolv.conf /etc/resolv.conf --ro-bind /etc/passwd /etc/passwd --ro-bind /etc/group /etc/group"}}


ELF marking with paxctl cannot be used because Skype binary refuses to run if modified.
To run programs that use X11/Xorg you can use:
{{cmd|$ alias glibcX11{{=}}"LANG{{=}}en_US.UTF-8 bwrap --bind /var/chroots/debian / --dev-bind /dev /dev --proc /proc --bind /sys /sys --bind /run /run --bind /home /home --ro-bind /etc/resolv.conf /etc/resolv.conf --ro-bind /etc/passwd /etc/passwd --ro-bind /etc/group /etc/group --bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 --setenv DISPLAY :0"}}


<code>CONFIG_PAX_XATTR_PAX_FLAGS</code> is NOT yet available in '''linux-grsec'''.
In this case you might need to use xhost to allow local connections, e.g.:
{{cmd|# xhost + local:}}


  sudo apk add attr
Now we can invoke glibc-built binaries like so:
  sudo setfattr -n user.pax.flags -v "em" ~/chroot/usr/bin/skype
{{cmd|$ glibc ./binary}} or {{cmd|$ glibcX11 ./binary}}  
 
Mount needed directories in the chroot read-only to limit access to the system devices.
 
Give write access to <code>/dev/v4l</code> and to <code>/dev/snd</code> in order to let Skype use the webcam device:  Skype is not compatible with Alsa anymore and requires Pulseaudio to be running.
 
  sudo mount -o bind /proc ~/chroot/proc
  sudo mount -o bind,ro,remount /proc ~/chroot/proc
  sudo mount -o bind /sys ~/chroot/sys
  sudo mount -o bind,ro,remount /sys ~/chroot/sys
  sudo mount -o bind /dev ~/chroot/dev
  sudo mount -o bind,ro,remount /dev ~/chroot/dev
  sudo mount -o bind /dev/v4l ~/chroot/dev/v4l
  sudo mount -t tmpfs -o nodev,nosuid,noexec shm $CHROOT_PATH/dev/shm
 
Enter the chroot and create a user:
 
  sudo chroot ~/chroot
  useradd -G audio,video <username>
  exit
 
Then run Skype as your newly created user:
 
  sudo chroot ~/chroot /bin/su - <username> -c /usr/bin/skype
 
 
=== Dungeon Crawl (Stone Soup) on Arch ===
 
Once the Arch system is laid down (to <code>~/chroot/root.x86_64</code> in this example), install the game:
 
  sudo arch-chroot ~/chroot/root.x86_64
  [chroot]# pacman -Syu crawl-tiles
 
Then exit the chroot and run it with this command:
 
  sudo arch-chroot ~/chroot/root.x86_64 /bin/su -c 'DISPLAY=:0 crawl-tiles'
 
A separate user can also be created to run the game, if preferred.
 
 
=== Spotify ===
 
==== Docker method ====
 
Read the [[Docker]] page to install it.  Then clone the repository, as shown below.  It will automate the process of pulling all the dependencies, and '''PaX''' marks it for the hardened kernel.  The advantage of this container is that it is ready-to-use and has stripped down many of the <code>/usr/bin</code> executables.  The downside is that is unstable.
 
git clone https://github.com/orsonteodoro/docker-arch-spotify-PaXmarked
 
Follow the instructions in the <code>README.md</code>
 
==== Chroot method ====
 
The Chroot method the preferred method;  it doesn't have the black screen bug and is more stable.  Just translate the [https://github.com/orsonteodoro/docker-arch-spotify-PaXmarked/blob/master/Dockerfile Dockerfile instructions] into native '''sh''' (Bourne shell).  The trick again is to run Spotify as root with sudo inside the chroot – not as regular user. 
 
Use <code>sudo aplay -l</code> to verify that the soundcard is detected.  When you use either this or the Docker method, which relies on ALSA, there could be a conflict depending on who grabs the sound card.  Stop all browsers or programs using the sound device outside of the chroot or the docker image so that Spotify can use it.
 
I did some translation.  You may need to make changes.
 
To update, just delete it and call <code>alpine-spotify-installer.sh</code> again.  You will still need the Arch Linux bootstrap image.  Extract the image.  Next, copy and paste the code shown below into root.x86_64;  <code>chmod +x alpine-spotify-installer.sh</code>. Then, run <code>sudo arch-chroot root.x86_64</code>.  Then, run <code>./alpine-spotify-installer.sh</code>.
 
{{Cat|alpine-spotify-installer.sh|<nowiki>
# Copyright (c) 2018 Orson Teodoro <orsonteodoro@hotmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
 
pacman --noconfirm -Syu
 
pacman --noconfirm -S base-devel
pacman --noconfirm -S xorg-server
pacman --noconfirm -S shadow
pacman --noconfirm -S sudo
pacman --noconfirm -S git
chmod 0660 /etc/sudoers
sed -i -e 's|# %wheel ALL=(ALL) NOPASSWD: ALL|%wheel ALL=(ALL) NOPASSWD: ALL\nspotify ALL=(ALL:ALL) NOPASSWD:ALL\n|g' /etc/sudoers || return 1
chmod 0440 /etc/sudoers
 
echo "Creating user spotify"
useradd -m spotify
echo "Deleting password for spotify"
passwd -d spotify
 
gpasswd -a spotify users
gpasswd -a spotify audio
gpasswd -a spotify video
gpasswd -a spotify wheel
 
echo "switching to spotify nix account"
su spotify
 
cd /home/spotify
mkdir aur
cd aur
 
cd /home/spotify/aur
git clone https://aur.archlinux.org/spotify.git
cd /home/spotify/aur/spotify
sudo -u spotify makepkg --noconfirm -si
 
cd /home/spotify/aur/
git clone https://aur.archlinux.org/paxctl.git
cd /home/spotify/aur/paxctl
sudo -u spotify makepkg --noconfirm -si
#for grsecurity kernels like Alpine
sudo paxctl -C /usr/share/spotify/spotify
sudo paxctl -z /usr/share/spotify/spotify
sudo paxctl -m /usr/share/spotify/spotify
 
sudo pacman --noconfirm -S alsa-lib
sudo pacman --noconfirm -S alsa-utils
 
#confirm that the sound card(s) shows up
sudo aplay -l
 
sudo spotify
</nowiki>
}}
 
To make this easier, create a launcher script:
 
{{Cat|run.sh|<nowiki>!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
sudo arch-chroot root.x86_64 /bin/sh -c "su spotify -c 'sudo spotify'"
</nowiki>
}}


For updating the Chroot or installing dependencies we can mount it and then login as root:
{{cmd|# mount --bind /dev /var/chroots/debian/dev
&#35; mount --bind /proc /var/chroots/debian/proc
&#35; chroot /var/chroots/debian /bin/bash
&#35; apt update && apt upgrade}}


You may want to look at [https://github.com/orsonteodoro/docker-arch-spotify-PaXmarked/blob/master/deflate.sh this script] to learn how to lock it down by removing the unnecessary cruft in your chroot collections that may be abused.
After installing what you might want to umount the binds for dev and proc to avoid issues.
{{cmd|# umount /var/chroots/debian/dev}}
{{cmd|# umount /var/chroots/debian/proc}}


[[Category:Development]]
[[Category:Development]]
[[Category:Installation]]
[[Category:Installation]]

Latest revision as of 14:11, 30 October 2024

If you want to run glibc programs in Alpine Linux, there are a few ways of doing so. You can install the gcompat compatibility layer, you can install glibc alongside musl (manually, as it isn't packaged), or you could do it the easy way and use either Flatpak (the easiest), containers or a chroot.

Because there are different use cases, this is just a slight overview about what's possible and what's sensible.

Your options

gcompat

gcompat is the go-to compatibility layer for Alpine users.

apk add gcompat

After that you run your binaries as normal.

Flatpak

Flatpak is by far the easiest method of running any graphical glibc program on Alpine. Firstly install it.

apk add flatpak

Then you can run any Flatpak application:

flatpak run <flatpak name>

It is recommended to enable Flathub using its instructions here, as most glibc programs you might need will be packaged there.

You can then install applications from it, for example:

flatpak install com.valvesoftware.Steam

Chroot

An option that's easier to generalize to other glibc applications is installing a glibc-based distribution into a chroot. You can then either chroot into it, or use a symlink and some configuration to make its glibc (and associated libraries) usable from Alpine.

After setting up a chroot using any of the methods described below, the loader can be set up in Alpine like so (these instructions are for a Debian chroot in /var/chroots/debian, on x86_64, but can be adapted to other systems by using the appropriate paths):

mkdir -p /lib64 ln -s /var/chroots/debian/lib/x86_64-linux-gnu/ld-2.33.so /lib64 printf '/var/chroots/debian/lib/x86_64-linux-gnu\n/var/chroots/debian/usr/lib/x86_64-linux-gnu\n' > /etc/ld.so.conf /var/chroots/debian/sbin/ldconfig

Gentoo Linux

Select a stage3 from here and portage latest from here at gentoo/snapshots/portage-latest.tar.xz.

First,

doas apk add xz

Enter the chroot:

mkdir ~/chroot cd ~/chroot tar -xvf stage3-*.tar.xz tar -xvf portage-latest.tar.xz mv portage usr doas mount --bind /dev dev doas mount --bind /sys sys doas mount -t proc proc proc cp /etc/resolv.conf etc doas chroot . /bin/bash

And voilà, you have your working Gentoo chroot!

You can now take a look at Gentoo's Handbook to find out how you can configure and install your system, or simply extract/copy the program you need to run in your chroot enviroment and execute it.

Here is a wrapper script that is similar to arch-chroot when you frequently reuse this chroot:

Also, create an account with the same user name as host current user to the chroot or make changes to the userspec option to chroot line.

Contents of gentoo-chroot.sh

!/bin/bash CHROOT_PATH="/home/$USER/chroot" cd $CHROOT_PATH mount | grep $CHROOT_PATH/dev || doas mount --bind /dev dev mount | grep $CHROOT_PATH/sys || doas mount --bind /sys sys mount | grep $CHROOT_PATH/proc || doas mount -t proc proc proc cp /etc/resolv.conf etc doas chroot --userspec=$USER:users . /bin/bash echo "You must manually unmount $CHROOT_PATH/dev, $CHROOT_PATH/sys, $CHROOT_PATH/proc."

Do at chmod +x gentoo-chroot.sh to get it to work.

Arch Linux

Either use pacstrap (included with the arch-install-scripts package) or an Arch bootstrap image:

doas apk add arch-install-scripts mkdir ~/chroot && cd ~/chroot curl -O https://mirrors.edge.kernel.org/archlinux/iso/latest/archlinux-bootstrap-x86_64.tar.gz doas tar xzf archlinux-bootstrap-x86_64.tar.gz && rm archlinux-bootstrap-x86_64.tar.gz doas sed -i '/evowise/s/^#//' root.x86_64/etc/pacman.d/mirrorlist doas sed -i '/CheckSpace/s/^/#/' root.x86_64/etc/pacman.conf doas arch-chroot root.x86_64 [chroot]# pacman-key --init [chroot]# pacman-key --populate archlinux

Once that is done, update the system and install the desired package(s) (denoted by "foo" in this example):

[chroot]# pacman -Syu foo

Debian

Todo: gresec referencs need to be cleanly removed from this section.


Use the provided debootstrap package to create the Debian chroot. --arch is optional, depending of your needs.

On the linux-grsec kernel, you will need to relax chroot limitations:

 sudo apk add debootstrap
 for i in /proc/sys/kernel/grsecurity/chroot_*; do echo 0 | sudo tee $i; done
 mkdir ~/chroot
 sudo debootstrap --arch=i386 wheezy ~/chroot https://deb.debian.org/debian/
 for i in /proc/sys/kernel/grsecurity/chroot_*; do echo 1 | sudo tee $i; done
 sudo chroot ~/chroot /bin/bash

You can now use apt-get to install needed packages.

Containers

It's also possible to use Docker or Podman containers with a helper like Distrobox. This allows using graphical programs easily and doesn't require root privileges once set up.

# apk add distrobox

Distrobox + Podman

# apk add podman

Then set up rootless Podman, following these steps. You'll need to mount your root as shared for Distrobox to function.

Fill in /etc/local.d/mount-rshared.start like so:

#!/bin/sh mount --make-rshared /

Mark it as executable.

# chmod +x /etc/local.d/mount-rshared.start

Then autostart its service.

# rc-update add local default # rc-service local start

Finally you can create a container using your chosen image.

$ distrobox create --image debian --name debian $ distrobox enter debian

It may also be necessary to allow X authorization for GUI programs to work.

$ xhost +si:localuser:$USER

Chroot + Bubblewrap

It's also possible to use a Debian system chroot with Bubblewrap. This allows running programs without root.

# apk add bubblewrap debootstrap # mkdir -p /var/chroots/debian # debootstrap --arch amd64 stable /var/chroots/debian/ https://deb.debian.org/debian

Finally we can make an alias for bwrap.

$ alias glibc="LANG=en_US.UTF-8 bwrap --bind /var/chroots/debian / --dev-bind /dev /dev --proc /proc --bind /sys /sys --bind /run /run --bind /home /home --ro-bind /etc/resolv.conf /etc/resolv.conf --ro-bind /etc/passwd /etc/passwd --ro-bind /etc/group /etc/group"

To run programs that use X11/Xorg you can use:

$ alias glibcX11="LANG=en_US.UTF-8 bwrap --bind /var/chroots/debian / --dev-bind /dev /dev --proc /proc --bind /sys /sys --bind /run /run --bind /home /home --ro-bind /etc/resolv.conf /etc/resolv.conf --ro-bind /etc/passwd /etc/passwd --ro-bind /etc/group /etc/group --bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 --setenv DISPLAY :0"

In this case you might need to use xhost to allow local connections, e.g.:

# xhost + local:

Now we can invoke glibc-built binaries like so:

$ glibc ./binary

or

$ glibcX11 ./binary

For updating the Chroot or installing dependencies we can mount it and then login as root:

# mount --bind /dev /var/chroots/debian/dev # mount --bind /proc /var/chroots/debian/proc # chroot /var/chroots/debian /bin/bash # apt update && apt upgrade

After installing what you might want to umount the binds for dev and proc to avoid issues.

# umount /var/chroots/debian/dev

# umount /var/chroots/debian/proc