■Ctrl+Alt+Delで許可されたユーザが居ても再起動せずに、
「Ctrl+Alt+Up」のキーボードシグナルを使って再起動させる。
※Debian固有の方法
■キーボードマップの設定コマンドについて
※kbdの設定方法はディストリビューション毎に異なります。
大抵のディストリビューション固有の設定については、
以下のコマンド名でググればたどれるはずです。
$ dpkg -L kbd | grep bin/ | grep key
/bin/loadkeys
/bin/dumpkeys
/usr/bin/showkey
/usr/bin/getkeycodes
/usr/bin/setkeycodes
/usr/bin/loadkeys
/usr/bin/dumpkeys
■CUIでのコンソールの切り替えのキー割り当て(キーマップとは)
$ sudo dumpkeys | sed s/" *\|\t"/" "/g | \
grep "^ control alt keycode \(59\|6[0-9]\) = " | grep -v "nul"
control alt keycode 59 = Console_1
control alt keycode 60 = Console_2
control alt keycode 61 = Console_3
control alt keycode 62 = Console_4
control alt keycode 63 = Console_5
control alt keycode 64 = Console_6
control alt keycode 65 = Console_7
control alt keycode 66 = Console_8
control alt keycode 67 = Console_9
control alt keycode 68 = Console_10
$ sudo dumpkeys | sed s/" *\|\t"/" "/g | \
grep "^keycode \(59\|6[0-9]\)"
keycode 59 = F1
keycode 60 = F2
keycode 61 = F3
keycode 62 = F4
keycode 63 = F5
keycode 64 = F6
keycode 65 = F7
keycode 66 = F8
keycode 67 = F9
keycode 68 = F10
keycode 69 = Num_Lock
■デフォルトで切り替えられるのは、F1〜F6まで。
※F7は通常、X Windowに割り当てられているので、F8〜F10までの3つが追加できる。
この時点でディストリビューションの考え方が反映されている。
F7をまたいでデフォルトでF8以降でも切り替えられるディストリビューションもあるはずです。
$ ps -ef | grep tty | grep -v grep
root 1803 1 0 Nov16 tty1 00:00:00 /sbin/getty 38400 tty1
root 1804 1 0 Nov16 tty2 00:00:00 /sbin/getty 38400 tty2
root 1805 1 0 Nov16 tty3 00:00:00 /sbin/getty 38400 tty3
root 1806 1 0 Nov16 tty4 00:00:00 /sbin/getty 38400 tty4
root 1807 1 0 Nov16 tty5 00:00:00 /sbin/getty 38400 tty5
root 1808 1 0 Nov16 tty6 00:00:00 /sbin/getty 38400 tty6
■Deleteキーの割り当ては14。
Ctrl+Alt+Delは「Meta_BackSpace」として割り当てられている。
$ sudo dumpkeys | sed s/" *\|\t"/" "/g | grep "^keycode [0-9]* = Del"
keycode 14 = Delete
$ sudo dumpkeys | sed s/" *\|\t"/" "/g | grep "^ control alt keycode 14 ="
control alt keycode 14 = Meta_BackSpace
■「Ctrl+Alt+Del」では再起動する設定になっている。
$ grep ^ca /etc/inittab
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
■ちなみにBackSpaceキーはそれ自体がショートカットである。
また、Ctrl+Alt+BackSpaceはGUIのキーマップ設定でX Windowから抜けるのにも使われる。
よって、ここでは別のキー割り当てを考える。
※上記でX Windowから抜けることが出来ない場合は、X Window起動中にCtrl+Alt+F1等に退避してkillすることも出来る。
$ sudo dumpkeys | sed s/" *\|\t"/" "/g | grep "[0-9]* = Back" | sort -u | wc -l
64
■多くのディストリビューションの説明にあるrunlevelに関係なく無効にする設定があると思う。
ログインユーザを確認するには、いずれかのrunlevelが必要。
更新したら、「syslog」を確認。
$ grep ^ca /etc/inittab
ca:12345:ctrlaltdel:
$ sudo init q
$ sudo tail -1 /var/log/syslog | sed s/".*\(init\:\)"/"\1"/
init: Re-reading inittab
■もちろん、環境によって以下は異なるので、ログの名前はsyslogでは無いかも知れない。
$ ps -ef | grep rsyslog | grep -v grep
root 1085 1 0 Nov16 ? 00:00:01 /usr/sbin/rsyslogd -c4
$ grep "syslog\$" /etc/rsyslog.conf
*.*;auth,authpriv.none -/var/log/syslog
■shutdownコマンドの引数もディストリビューションの考え方が反映される。
※「/etc/shutdown.allow」はデフォルトでは存在しない。
$ man shutdown | grep "\-a.*shutdown.allow"
-a /etc/shutdown.allow を使う。
■許可したユーザかrootがログイン中のみCtrl+Alt+Delで再起動出来るなら、
ログインせずに、またはrunlevelを気にせずにinitにシグナルを送る方法を考える必要があるかも知れない。
$ grep ^ci /etc/inittab
ci::kbrequest:/sbin/shutdown -t1 -a -r now
$ sudo tail -1 /var/log/syslog | sed s/".*\(init\:\)"/"\1"/
init: Re-reading inittab
■当然だが、許可したユーザがログインしているからといって、
そのユーザがroot権限なしにshutdownコマンドを実行することは出来ない。
$ /sbin/shutdown -r now 2>&1 | head -1
shutdown: you must be root to do that!
■少なくともinitがSIGINTに応答し、上記条件以外の時にはコンソールに以下の表示がされる。
shutdown: no authorized users logged in
■inittab自体が文書は不完全な為、「ci::」がデフォルトでは記載されていない理由だと思われる。
$ man inittab 2>&1 | grep -A 10 "kbrequest\$" | sed s/" *"/" "/g
kbrequest
initがキーボードハンドラーから、コンソールキーボード上で特定の組み合わせ
のキー入力が行なわれた、とのシグナルを受け取ったときに実行される。
この機能に関する文書はまだ不完全である; kbd-x.xx パッケージ中を探せばより多くの資料が見つかるだろう
(この文書を書いている時点で最新のものは kbd-0.94 である)。 基本的には、あるキーの組み合わせを"Key‐
boardSignal"という動作に結びつけたい という場合に用いられる。
例えば、Alt-上向き矢印というキーの組み合わせをこの用途に使いたい場合は、 キーマップファイル中に次の様に書いておけばよい:
alt keycode 103 = KeyboardSignal
■Alt+Upは以下のようにキーが割り当てられている。
$ sudo dumpkeys | sed s/" *\|\t"/" "/g | grep "^keycode" | grep "Alt\|Up" | sort -k 4
keycode 100 = Alt
keycode 125 = Alt
keycode 126 = Alt
keycode 56 = Alt
keycode 103 = Up
■「Alt+Up」はデフォルトで「KeyboardSignal」に割り当てられている。
$ sudo dumpkeys | sed s/" *\|\t"/" "/g | grep "^ alt keycode 103 = " | grep -v "nul"
alt keycode 103 = KeyboardSignal
■他には「KeyboardSignal」に以下のキーが割り当てられている。
$ sudo dumpkeys | sed s/" *\|\t"/" "/g | grep "KeyboardSignal"
alt keycode 103 = KeyboardSignal
alt shiftl keycode 103 = KeyboardSignal
alt shiftr keycode 103 = KeyboardSignal
alt shiftl shiftr keycode 103 = KeyboardSignal
alt ctrll keycode 103 = KeyboardSignal
alt shiftl ctrll keycode 103 = KeyboardSignal
alt shiftr ctrll keycode 103 = KeyboardSignal
alt shiftl shiftr ctrll keycode 103 = KeyboardSignal
■CapsLockとControlキーの入れ替えは完全に他のディストリビューションとは異なる方法である。
$ cat /etc/kbd/remap
■当然「/lib/kbd」ディレクトリは存在しないが、
「/lib/kbd/keymaps/i386/qwerty/」「/usr/lib/kbd/keymaps/i386/qwerty/」等、
各「lib」配下の「jp106.map.gz」直接編集するディストリビューションならば、
変更されうる仕様なので、監視を怠ってはならない。
$ dpkg -L kbd | grep "etc/" | grep kbd
/etc/init.d/kbd
/etc/kbd
/etc/kbd/config
/etc/kbd/remap
$ dpkg -L kbd | grep lib || echo "No lib"
No lib
■「Alt+Up」を無効にして、「Alt+Ctrl+Up」を使うようにする。
$ echo "alt keycode 103 = nul" | sudo loadkeys
$ sudo dumpkeys | grep Signal
alt shiftl keycode 103 = KeyboardSignal
alt shiftr keycode 103 = KeyboardSignal
alt shiftl shiftr keycode 103 = KeyboardSignal
alt ctrll keycode 103 = KeyboardSignal
alt shiftl ctrll keycode 103 = KeyboardSignal
alt shiftr ctrll keycode 103 = KeyboardSignal
alt shiftl shiftr ctrll keycode 103 = KeyboardSignal
$ echo "control alt keycode 103 = KeyboardSignal" | sudo loadkeys
$ sudo dumpkeys | grep Signal | head -1
control alt keycode 103 = KeyboardSignal
■以下に見るとおり、「/etc/kbd/remap」には、loadkeysに渡すsedコマンド行を書けばよいのだが。。。
$ sudo grep -A 3 "#.*remap" /etc/init.d/kbd
if [ -z "${HAVE_SETUPCON}" -a -r /etc/$PKG/remap ]; then
dumpkeys < ${DEVICE_PREFIX}1 | sed -f /etc/$PKG/remap | loadkeys --quiet
fi
$ tail -1 /etc/kbd/remap
s/alt keycode 103 = KeyboardSignal/alt keycode 103 = nul/;
■「/bin/sh」で書かれているので、デバッグモードが使える。
※ただし、コンソールで実行した場合のみ。dpkg-reconfigureも同じ。
というかそもそもフラグが立っておらず実行されていない。
$ sudo head -1 /etc/init.d/kbd
$ sudo /bin/sh -x /etc/init.d/kbd restart | grep -v "^\+"
Setting console screen modes.
Skipping font and keymap setup (handled by console-setup).
$ sudo dpkg-reconfigure kbd
Setting console screen modes.
Skipping font and keymap setup (handled by console-setup).
■バグなのか、こちらの設定間違いなのか、スキップされているので、
setup関数とそのチェックのすぐ後ろに記載して強制する。
※読みにくいので、スクリプトを追うのは後日。
$ sudo grep -B 2 -A 1 "103 = nul" /etc/init.d/kbd
setup
[ -z "$HAVE_SETUPCON" ] || log_action_msg "Skipping font and keymap setup (handled by console-setup)"
echo "alt keycode 103 = nul" | loadkeys
echo "control alt keycode 103 = KeyboardSignal" | loadkeys
■以下の通りサービスの再起動で有効になった。
$ echo "alt keycode 103 = KeyboardSignal" | sudo loadkeys
$ sudo dumpkeys | grep "KeyboardSignal" |head -1
alt keycode 103 = KeyboardSignal
$ sudo /etc/init.d/kbd restart
$ sudo dumpkeys | grep "KeyboardSignal" |head -1
control alt keycode 103 = KeyboardSignal
■「Alt+Up」は効かず、「Ctrl+Alt+Up」でコンソールにHelloと表示されることを確認する。
$ sudo grep ^ci /etc/inittab
ci::kbrequest:echo "Hello"
$ sudo init q
$ sudo tail -1 /var/log/syslog | grep init | sed s/".*\(init\:\)"/"\1"/
init: Re-reading inittab
■上記が使えるので、ctrlaltdel時のアクションを次のように変更する。
$ sudo grep ^ca /etc/inittab
ca:12345:ctrlaltdel:echo "Please Ctrl+Alt+Up key to reboot!"
$ sudo init q
$ sudo tail -1 /var/log/syslog | grep init | sed s/".*\(init\:\)"/"\1"/
init: Re-reading inittab
■これで、キーボードからのctrlaltdelのSIGINTにinitが反応するならば、kbrequestで再起動出来る。
また、runlevelが不明、許可されたユーザがログインしていなくても、ショートカットキーを知っている人なら再起動出来る。
※当然、私の環境では別のキーを割り当てたので、あしからずw。。。