前置き
以前、元教え子から PHP を教えてほしいと依頼された時に、何度かもどかしい状態になったので、
「screen コマンドを使ってリモートで指導できたらなぁ」と考えたんだけど、忙しすぎて実現しなかった。
あの時は、VNC でターミナルの操作を奪って…とか、遠回りなことをしていた。
(夜中に VNC を電話でインストールさせてサーバに接続させるとか、ほんと無理。でも教え子の若い情熱に負けちゃったんだよね。もうやんない)
その時調査したのは「screen -x user/session」なんだけど、
よそ様の Web ページを拝見して「セキュリティに問題あるけど chmod u+s screen を実行しろ」のアドバイスを発見した。
(「大きな問題ではない」という意見の記述もあるけど、man に「Multiuser はループになっても検出できないから注意しろ」とも書いてある)
確かに、他人のソケットを覗くにはコマンドを root で実行する必要があるし、
実際に u+s せずに実行するとこう(↓)なる。
$ screen -x user/sessionでも、生徒に u+s したコマンドを使わせて余計なトラブルを招きたくない。訳: マルチユーザを使うには suid (u+s) を実行すべし。
Must run suid root for multiuser support.
例えば、仲良しグループ全員でお互いを覗いたりしたら、あっという間にループができて収拾がつかなくなる。
ならば、u+s したコマンドを生徒に使わせないなら良んじゃね?
覗かれる側に u+s は必要ないじゃろ。
答えは意外に簡単だった。あの時悩んだのは何だったんだろう。
1. 設定要件
種別 内容 備考 スクリーンマネージャ Screen version 4.08.00 (GNU) 05-Feb-20 本稿記述時の最新版 ログインシェル GNU bash, version 5.1.8(1)-release OS AlmaLinux release 9.4 (Seafoam Ocelot)
(Solaris11 でも動作可能)アカウント padawan
ホームディレクトリ: /home/padawan/
screen セッション名: task生徒側 knight 先生側 master
• アカウントは生徒側、先生側ともに予め「ふつうに」使えるように作成しておく。(useradd, passwd 等の作業)
2. 設定
2-1. 生徒側設定
• screen コマンドの設定ファイルを用意する。(screen が起動時に自動的に読み込む)2-2. 先生側設定
$ su• 操作ログの格納先を用意する。
# cat > /home/padawan/.screenrc << EOF
deflog on
logfile ".screenlogs/%H_%Y%m%d_%0c_%p:%n.log"
multiuser on
acladd root
EOF
# cat /home/padawan/.screenrc
*立ち入り属性を変更するときは、screen の中から aclchg root -w "#?" を実行する。
deflog on # 操作ログを記録する。 logfile ".screenlogs/%H_%Y%m%d_%0c_%p:%n.log" # 操作ログのファイル名を指定。 multiuser on # マルチユーザモードにする。 acladd root # 管理者の立ち入りを許可する。(knight が sudo してくるため root で良い) #aclchg root -w "#?"# <-- なぜか最初から閲覧モードにすることができない*。
padawan / knight どちらからでも設定 / 解除が可能。
# mkdir /home/padawan/.screenlogs/• ログイン時に screen コマンドが自動起動するようにする。
# chown padawan:padawan /home/padawan/.screenlogs/
# cat >> /home/padawan/.bash_profile << EOF• exit の確認を仕込む。(これはお好みで)
/usr/bin/screen -d -R -S task
exit
EOF
# cat /home/padawan/.bash_profile | tail
-d -R: 切断されて残っていたセッションがあったら再接続する。なかったら新規作成する。
# User specific environment and startup programs /usr/bin/screen -d -R -S task exit
再接続時は一度デタッチされるため、knight も再接続が必要。
-S: セッション名を指定する。この名前に対して knight から接続する。
最後の exit は screen の終了後、それを呼び出した Bash も終了させる。(→ ログアウトさせる)
knight がミスタイプしたときに効果を発揮する。
# cat >> /home/padawan/.bashrc << EOF
# Prompts for confirmation when "exit" is executed within Screen. export CHILD=\$((\$CHILD + 1)) function exit_yesno() { n=\$1 read -p 'ログアウトします。よろしいですか?(yes/no):' ans if [ "\$ans" = "yes" ] || [ "\$ans" = "y" ] ; then exit \$n ; fi } if [ \$CHILD -ge 2 ] ; then alias exit=exit_yesno export IGNOREEOF=8640000 fiEOF
# cat /home/padawan/.bashrc | tail
.bashrc は Bash を起動するたびに実行される。
# Prompts for confirmation when "exit" is executed within Screen. export CHILD=$(($CHILD + 1)) function exit_yesno() { n=$1 read -p 'ログアウトします。よろしいですか?(yes/no):' ans if [ "$ans" = "yes" ] || [ "$ans" = "y" ] ; then exit $n ; fi } if [ $CHILD -ge 2 ] ; then alias exit=exit_yesno export IGNOREEOF=8640000 fi
# exit
$
• knight に root としての実行を /bin/screen -x padawan/* と /bin/screen -ls に限定して許可する。(ついでに master にも)
$ su
# visudo
ホントはここじゃなくて /etc/sudoers.d/padawan に書いたほうがいい。
## Allow root to run any commands anywhere root ALL=(ALL) ALL knight ALL=(ALL) /bin/screen -x padawan/*, /bin/screen -ls * master ALL=(ALL) /bin/screen -x padawan/*, /bin/screen -ls * ## Allows members of the 'sys' group to run networking, software, ## service management apps and more. # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS ## Allows people in group wheel to run all commands %wheel ALL=(ALL) ALL
# exit
$
3. 実施
共有時は同じ画面になるので分かりにくい。
以下の図は、それぞれ 8 行が共有されている状態。
(padawan の screen -ls の直後に knight が screen -x を実行したと仮定)
実際の画面でもリアルタイムで反映されるため、どちらが打鍵しているか分からない。
3-1. 生徒側の操作
3-2. 先生側の操作「task」「exit」を強調するために下線を引いている。実際は下線が表示されない。
padawan$ exit [screen is terminating]
padawan$ screen -ls # padawan の打鍵 There is a screen on: 5706.task (Multi, attached) 1 Socket in /run/screen/S-padawan. padawan$ # Hello, padawan # knight の打鍵 padawan$ # Please tell me Lord of the Ring. # padawan の打鍵 padawan$ # I can teach Load of the Linux. # knight の打鍵 padawan$ # May the force be with you. # padawan の打鍵
multiuser on の設定があると「Multi」が表示される。
exit の実行で screen が終了すると、前述 2-1 で .bash_profile に記述した exit によってログアウトする。 でも可。
共有の最中は、生徒の画面と全く同じ表示になる。接続できない場合は、接続先 (padawan がマルチユーザになっているかどうかを確認する)
(タイミングが遅くなっても、前の分が遡って表示される)
knight$ sudo screen -x padawan/task
knight$ exit
[sudo] knight のパスワード: **(自分のログインパスワード)**[detached from 5706.task]
padawan$ screen -ls # padawan の打鍵 There is a screen on: 5706.task (Multi, attached) 1 Socket in /run/screen/S-padawan. padawan$ # Hello, padawan # knight の打鍵 padawan$ # Please tell me Lord of the Ring. # padawan の打鍵 padawan$ # I can teach Load of the Linux. # knight の打鍵 padawan$ # May the force be with you. # padawan の打鍵
途中で違う画面の操作をしたいときは、 でスクリーンを追加するか、新たなターミナルからログインする。
(「デタッチしてアタッチすれば…」とか言う人はわかってる人なので勝手にやってください)
knight$ sudo screen -ls padawan/
✓ OK
5706.task (Multi, attached)
✗ NG
5706.task (Private)
✗ NG
No Sockets found in /run/screen/S-padawan.
4. 付録
knight と同じ設定のユーザを複数作成すると、一つの padawan を中心に複数ユーザの立ち入りが可能になる。
このとき、誰がどこに接続しているかを確認するには をタイプする。displays でも可。
この画面が表示されるのは自分だけ。本稿では sudo をしているため、さらに interface の項でユーザを確認する必要がある。
黄色の行が自分の情報
term-type size user interface window Perms ---------- ------- ---------- ----------------- ---------- ----- xterm 80x24 root@/dev/pts/4 0(padawan@55) rwx xterm 80x24 root@/dev/pts/2 0(padawan@55) rwx xterm 80x24 padawan@/dev/pts/1 0(padawan@55) rwx [Press Space to refresh; Return to end.]
で画面更新する。(誰かの接続/切断を反映させる)
で作業中の画面に戻る。
knight$ ps u | grep -v grep | grep pts/4
master 8449 0.0 0.4 224096 5504 pts/4 Ss 20:36 0:00 -bash