この記事はLinux Advent Calendar 2020の7日目の記事です。
外部からの接続を許し、かつ内部でほかのデータを触れないようにするためにchrootを用いて環境構築をしたので、なにを行ったかを紹介します。ツッコミどころがありましたら教えていただければと思います。
また、最後にできなかったことを書いておきます。主にGPU。
#やりたいこと
- ユーザーは踏み台サーバを経由して、計算用サーバにsshでアクセスする
- 踏み台サーバ・計算用サーバともにそのユーザのディレクトリ以外のデータにはアクセスできないようにしたい
- そのためにchrootを使う。踏み台サーバ・計算用サーバともに。
- けどいろんなコマンドとかは使いたいよね!
#やること
- 各サーバでユーザ・ホームディレクトリを作成
- 基本的なコマンドが使えるようにchroot配下にいろいろコピーする
- そのユーザをchroot配下におきつつ、sshをできるようにする
- 種々のコマンドを使えるようにする。これがしんどい。
順番にとりあげていきます!
なお、めんどくさいので、以下各サーバのホームディレクトリを下記のようにします。
HOMEDIR=/path/to/homedir
PARENTDIR=(HOMEDIRの親ディレクトリ)
USERNAME=(ユーザ名)
また、踏み台サーバと計算用サーバの話が入り混じりますが、ともにユーザ名・ホームディレクトリへのパスは同じものとします。
#各サーバでユーザ・ホームディレクトリを作成する
まず最初にユーザやホームディレクトリがないと始まらないので、ユーザを作成します。
useradd -b ${PARENTDIR} -m -N -s /bin/bash ${USERNAME}
一応パスワードも設定しておきました。
passwd ${USERNAME}
また、書き込み可能なディレクトリを作成するため、こんなこともしました。
mkdir ${HOMEDIR}/home
chown ${USERNAME}:users ${HOMEDIR}/home
#基本的なコマンドが使えるようにchroot配下にいろいろコピーする
chrootを用いてSSHユーザのディレクトリを制限するを参考にしました。いろいろなものをパーミッションや所有者情報をそのままにコピーしていきます。ポイントはchownやchmodを忘れないことでしょうか。
cd ${HOMEDIR}
cp -p -r /bin ${HOMEDIR}/bin
cp -p -r /lib ${HOMEDIR}/lib
cp -p -r /lib64 ${HOMEDIR}/lib64
mkdir ${HOMEDIR}/usr
cp -p -r /usr/bin ${HOMEDIR}/usr/bin
cp -p -r /usr/lib ${HOMEDIR}/usr/lib
cp -p -r /usr/lib64 ${HOMEDIR}/usr/lib64
chown root:root ${HOMEDIR}
chmod 755 ${HOMEDIR}
cd ${HOMEDIR}
chown ${USERNAME}:users *
これでここにアクセスできればそのユーザは多少のことはできるようになります。できないことのほうが多いですが…。
#ユーザをchroot配下におきつつ、sshをできるようにする
##sshの設定
sshができるようにします。
cd ${HOMEDIR}
mkdir .ssh
vi .ssh/authorized_keys
chmod 700 .ssh
chmod 600 .ssh/authorized_keys
chown -R ${USERNAME}:users ${HOMEDIR}
##chrootの設定
他の領域に入れないように設定します。
必要であれば、sshのAllowUsers
にも${USERNAME}
を入れます。sshd_config
の中の${USERNAME}
や${HOMEDIR}
は展開したものを書いて下さい。
vi /etc/ssh/sshd_config
######################
# 末尾に以下を追記
Match User ${USERNAME}
ChrootDirectory ${HOMEDIR}
X11Forwarding no
AllowTcpForwarding no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
#####################
# service sshd restart や systemctl sshd restartでもいいとは思います
/etc/init.d/ssh reload
ただし、踏み台サーバを経由して多段sshしたい場合には、踏み台サーバ側のAllowTcpForwarding
はyes
にする必要があります。ご注意ください。
#いろいろなコマンドを使うための設定(その1)
vimコマンドなど多くのコマンドは互換性維持などのため、/usr/bin/vim
がシンボリックリンクになっています。例えば筆者の環境では、/usr/bin
にパスが通っているため、/usr/bin/vim
にアクセスするとこれがシンボリックリンクのために/etc/alternatives/vim
を介し、さらにこれもシンボリックリンクのため/usr/bin/vim.basic
にアクセスすることで実行されます。つまり、
vim -> /usr/bin/vim -> /etc/alternatives/vim -> /usr/bin/vim.basic(これが実体)
のように伝わっていきます。というわけで必要なディレクトリをコピーします。
cd ${HOMEDIR}
mkdir ${HOMEDIR}/etc
cp -p -r /etc/alternatives ${HOMEDIR}/etc/alternatives
#踏み台サーバの設定
##sshのための設定
###${HOMEDIR}/etc/passwdが必要
踏み台サーバ->計算用サーバのsshのために/etc/passwd
が必要でした。
-bash-4.3$ ssh ${USERNAME}@(計算用サーバ)
No user exists for uid (${USERNAME}のuid)
そのため、etc/passwd
を作ってやります。${USERNAME}
は展開してください。
mkdir ${HOMEDIR}/etc
vi ${HOMEDIR}/etc/passwd
#========
${USERNAME}:x:(踏み台サーバの${USERNAME}のuid):100::/:/bin/bash
#========
###/dev/random等が必要
/dev/random
と/dev/urandom
が必要です。
mknod ${HOMEDIR}/dev/random c 1 9
mknod ${HOMEDIR}/dev/urandom c 1 9
で作成可能ですが、/dev/ttyをマウントする方法でも問題ないです。
##sshに/dev/ttyが必要
踏み台サーバ経由で計算用サーバにsshする必要があるのですが、sshの際に仮想コンソールを作成するために、debug1: read_passphrase: can't open /dev/tty: No such device or address
となってしまうため、/dev/tty
が必要になります。これの対処には2つ方法があるのを見つけています。
###/dev/ttyをマウントする
ある程度脆弱性が生まれるのは覚悟の上です。chroot環境のユーザ用にdev,procをmountするを参考にしました。
mkdir ${HOMEDIR}/dev
mount --bind /dev ${HOMEDIR}/dev
マウントだと再起動したらだめじゃん!というツッコミは甘んじて受け入れます。fstab使って下さい。
###がんばって/dev/ttyを作成する
LinuxでchrootによるJail環境を構築2によるとこんな方法もあるらしいです。
mkdir ${HOMEDIR}/dev
mknod -m 666 ${HOMEDIR}/dev/tty c 5 0
mknod -m 660 ${HOMEDIR}/dev/tty0 c 4 0
mknod -m 600 ${HOMEDIR}/dev/tty1 c 4 1
踏み台サーバはsshができればいいのでこんなもんです。
#計算用サーバの設定
こちらはもっといろいろ設定しました。htop
は使いたいしgitも使いたいしCやPythonも使いたいし…。というわけで順番に解決していきます。
##webへのアクセスで名前解決したい
wget
などがそもそも使えませんでした。名前解決できていなかったのです。
cp -p /etc/resolv.conf ${HOMEDIR}/etc/
##/dev内にいろいろほしい
下記でscreen
コマンドが使いたいのでいろいろやりました。あとnullが必要なことも。踏み台サーバと同様に2つの方法があります
###/devをマウント
マウントするのは手っ取り早いです。
mkdir ${HOMEDIR}/dev
mount --bind /dev ${HOMEDIR}/dev
###がんばっていろいろつくる
これでもできます
mkdir ${HOMEDIR}/dev
mknod -m 666 ${HOMEDIR}/dev/null c 1 3
mknod -m 666 ${HOMEDIR}/dev/zero c 1 5
mknod -m 644 ${HOMEDIR}/dev/random c 1 8
mknod -m 644 ${HOMEDIR}/dev/urandom c 1 9
mknod -m 666 ${HOMEDIR}/dev/tty c 5 0
mknod -m 660 ${HOMEDIR}/dev/tty0 c 4 0
mknod -m 600 ${HOMEDIR}/dev/tty1 c 4 1
##scpで受信するのにpasswdが必要
ssh叩けるようになったのに受信できませんでした。passwdが必要そうです。${USERNAME}
は展開してください
mkdir ${HOMEDIR}/etc
vi ${HOMEDIR}/etc/passwd
#========
${USERNAME}:x:(踏み台サーバの${USERNAME}のuid):100::/:/bin/bash
#========
##top/htopなどが見たいよね
わざわざ計算用サーバと言っているように、計算用なのでhtopなどが見たいです。こればかりは/proc
を参照できないといけません。仕方ないのでマウントします。
mkdir ${HOMEDIR}/proc
mount --bind /proc ${HOMEDIR}/proc
#git系やwgetでssl証明書の確認をしたい
近年はhttps化が進んでいますね。ちゃんとhttps通信するために、ssl証明書の確認が必要です。
mkdir ${HOMEDIR}/etc/ssl
mkdir ${HOMEDIR}/etc/ssl/certs
mount --bind /etc/ssl/certs ${HOMEDIR}/etc/ssl/certs
#Cの標準ライブラリが使いたいこともある
cp -p -r /usr/include ${HOMEDIR}/usr/include
#Pythonのビルドがしたい
そのままではPythonのビルドができませんでした。tmp
が必要なんですね。作ります。
mkdir ${HOMEDIR}/tmp
chmod 777 mkdir ${HOMEDIR}/tmp
#lsb_releaseが通らない対策
存在しないので通らなかった。
cp -R /usr/share/ ${HOMEDIR}/usr/share
Pythonで必要かも
これがなかったら動かなかったので。
mount --bind /dev/shm ${HOMEDIR}/dev/shm
#screenコマンドを使いたい
計算用にscreen
をよく使っています。How do I use the terminal SCREEN when chrooted?を参考にしました。
mkdir ${HOMEDIR}/run
mkdir ${HOMEDIR}/run/screen
chmod 755 ${HOMEDIR}/run
chmod 777 ${HOMEDIR}/run/screen
mkdir ${HOMEDIR}/dev/pts
mount -t devpts none ${HOMEDIR}/dev/pts/ -o ptmxmode=0666,newinstance
ln -fs /dev/pts/ptmx ${HOMEDIR}/dev/ptmx
#できなかったこと
-
nvidia-smi
が通っていません。NVIDIAドライバを用いたGPUの計算ができない…。 - dockerも素直に使えなかった。