Ctrl+Alt+Delキーの代替にCtrl+Alt+Upを使う

■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
# This sed script is run across the dumpkeys output to remap keys on the console

# This turns caps lock into control
#s/keycode  58 = Caps_Lock/keycode  58 = Control/;

■当然「/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
    # Allow user to remap keys on the console
    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
#!/bin/sh

$ 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。。。