sudo権限のないサーバーでapt installをしたい
MMA Advent Calendar 2024 11日目の記事です
はじめに
私の大学では,学生がホームディレクトリ内であれば任意のLinuxコマンドが実行できるサーバーがあります.
しかし,さすがにsudo
グループには入ってないため,sudo
が使えません.
しかし,apt install
をしたい!!
というわけで今回は,proot
を使い,任意のディレクトリに構築したディストリのrootfsで好き勝手出来るようにします.
PRootとは
要は,chroot
のroot権限いらないバージョンです.
Linux Kernelのptrace
というシステムコールで実現しているのだとか.ただし,chroot
と違い,オーバーヘッドが生じるというデメリットがあります.
PRootの導入
PRootのダウンロード
sudoの使えないLinuxサーバーのシェルでディレクトリを作ります.
$ mkdir proot.d
$ cd proot.d
そしてPRootをダウンロードしましょう.
$ curl -LO https://proot.gitlab.io/proot/bin/proot
$ chmod +x ./proot
$ ./proot --version
_____ _____ ___
| __ \ __ \_____ _____| |_
| __/ / _ \/ _ \ _|
|__| |__|__\_____/\_____/\____| v5.3.1-99a84175
built-in accelerators: process_vm = yes, seccomp_filter = yes
Visit https://proot-me.github.io for help, bug reports, suggestions, patches, ...
Copyright (C) 2022 PRoot Developers, licensed under GPL v2 or later.
これでprootコマンドが使えるようになりました.
rootfsのダウンロード
お好みのLinux ディストリビューションのrootfsをダウンロードしてください.
今回はUbuntu 22.04をダウンロードします.
(本当は24.04を入れたかったのですが,このあとのapt installでエラーが出てうまくいかず...)
$ curl -LO https://cdimage.ubuntu.com/ubuntu-base/releases/22.04.5/release/ubuntu-base-22.04.5-base-amd64.tar.gz
$ mkdir ubuntu-jammy
$ tar -C ubuntu-jammy -xvf ubuntu-base-22.04.5-base-amd64.tar.gz
PRootの実行
以下のコマンドを実行するだけです.
$ ./proot -R ubuntu-jammy/ -0
#
ルートシェルが現れると思います.
-R
オプションは,ネットワークの接続などに必要なホスト側のファイルや,ホスト側のホームディレクトリをバインドしてくれる便利なオプションです.
-0
オプションは,rootユーザーになれます.
試しにPRootを実行して,このrootfsに,aptでffmpeg
をインストールしてみます.
shiragi@server:~/proot.d$ ./proot -R ubuntu-jammy/ -0
# bash
root@server:~/proot.d# apt update
Get:1 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
Get:2 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB]
(略)
root@server:~/proot.d# apt install ffmpeg
(略)
root@server:~/proot.d# ffmpeg
ffmpeg version 4.2.7-0ubuntu0.1 Copyright (c) 2000-2022 the FFmpeg developers
ちゃんとffmpeg
がインストールされ,実行できました.
apt
コマンドを実行しても,用意したrootfs内でやるくりするため,ホスト側のファイルには影響ありません.
-R
オプションのおかげでホスト側のホームディレクトリをそのまま使うこともできます.
rootfs内のコマンドをホスト側で実行する
せっかくインストールしたffmpegですが,毎回proot
コマンドを打ってから呼び出すのは面倒です.
そのため,ホストから直接ffmpegコマンドを実行できるようにします.
ffmpeg
の部分を他のコマンドに置きかえることで,ffmpegに限らず様々なコマンドで利用できます.
まず,ホスト側に戻り,踏み台となるシェルスクリプトを配置するためのbin
ディレクトリを作成します.
$ cd ~
$ mkdir bin
次に,binディレクトリ内に,ffmpeg
という名前のファイルを作成し,以下の通りに記述します.
$ cd bin
$ cat <<EOF >ffmpeg
#!/usr/bin/sh
/home/shiragi/proot.d/proot -R /home/shiragi/proot.d/ubuntu-jammy -w ${PWD} /usr/bin/ffmpeg $*
EOF
proot
とrootfsのフルパスは,各自の環境のものに置き換えてください.
-w
オプションで,proot内でもホストと同じカレントディレクトリにできます.
あとは,.bashrc
を変更し,環境変数PATHに~/bin
を追記するようにします.
# (前略)
export PATH=/home/shiragi/bin:${PATH}
これで,ホスト側でもffmpeg
コマンドを実行できるようになりました.
$ ffmpeg -i tmp.png tmp.jpg
ffmpeg version 4.2.7-0ubuntu0.1 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 9 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
configuration: --prefix=/usr --extra-version=0ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, png_pipe, from 'tmp.png':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: png, rgb24(pc), 3840x2160, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
Stream #0:0 -> #0:0 (png (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[swscaler @ 0x5000000c1500] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to 'tmp.jpg':
Metadata:
encoder : Lavf58.29.100
Stream #0:0: Video: mjpeg, yuvj444p(pc), 3840x2160, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
Metadata:
encoder : Lavc58.54.100 mjpeg
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
frame= 1 fps=0.0 q=4.9 Lsize=N/A time=00:00:00.04 bitrate=N/A speed=0.226x
video:350kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
ただし,prootがホームディレクトリしかバインドしていないので,ffmpeg
コマンドでホームディレクトリ以外のファイルを扱うには別途工夫が必要です.
おわりに
これで好きなパッケージをsudo権限なしで使えるようにできました.
特権ポートなどを使うことができなかったり,IOのオーバーヘッドがネックだったりしますが,aptが使えるだけでかなりできることが増えます.
皆様もよいPRootライフを!
Discussion