📘

sudo権限のないサーバーでapt installをしたい

2024/12/10に公開

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を追記するようにします.

.bashrc
# (前略)
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