RHEL10の仮想コンソールでsudo su -したときに、LANG=ja_JP.UTF-8になる

こんにちは、tukapiyoです。
RHEL10を導入後、仮想コンソール(TERM=linux
)でsudo su -
をした際に、LANG=ja_JP.UTF-8
になってしまうことが分かりました。
仮想コンソールは標準では日本語が表示できないので、各種メッセージが文字化けしてしまいます。
RHEL9では問題なかったことから原因を調査したところ、原因が特定できたので結果をまとめておきます。
目次
環境
- RHEL 10.0 Coughlan
localectl
の結果$ localectl System Locale: LANG=ja_JP.UTF-8 VC Keymap: jp X11 Layout: jp X11 Model: microsoftpro X11 Options: terminate:ctrl_alt_bksp
発生事象
当該サーバの状況(RHEL10)
- 仮想コンソール(
TERM=linux
)で一般ユーザにログイン
LANG=en_US.UTF-8
(想定通り) - そのまま
sudo su -
でrootにスイッチ
LANG=ja_JP.UTF-8
(想定外)
この状態で例えばnmtuiを実行してみると、たくさん豆腐が見えます。
他サーバの状況(RHEL9)
- 仮想コンソール(
TERM=linux
)で一般ユーザにログイン
LANG=en_US.UTF-8
(想定通り) - そのまま
sudo su -
でrootにスイッチ
LANG=en_US.UTF-8
(想定通り)
そもそもなぜLANG=en_US.UTF-8になっているか
localectl
ではLANG=ja_JP.UTF-8
に設定されているのに、なぜLANG=en_US.UTF-8
になるのでしょうか。
実はSSHで接続した場合はLANG=ja_JP.UTF-8
になります。
この件は過去に調査したことがあり、以下の記事でも説明しています。
記事内のこの部分が該当の説明です。
ログイン時に
/etc/profile
が読み込まれます(詳細は割愛)。
その中でさらに、/etc/profile.d/*
を読み込むようになっていました。
/etc/profile.d/
の中には複数のシェルスクリプトが含まれていますが、そのうちlang.sh
を参照するとLANG=en_US.UTF-8
を設定している行が見つかります。
$TERM
がlinux
(コンソール)の場合に、LANG=en_US.UTF-8
を設定するようになっていますね。
おそらく、コンソールでは日本語等の文字が表示できない(文字化けする)ため、あえて英語ロケールへ変更するようにしているのでしょう。
ということで、仮想コンソールの場合はLANG=en_US.UTF-8
となるのが想定通りなのです。
原因調査
lang.sh
最も怪しいlang.sh
については、RHEL9もRHEL10も差分はありませんでした。
そこで、中身をもう少し見てみることにします。
以下のコードは、lang.sh
の抜粋です。
ちょうどLANG=en_US.UTF-8
に書き換える処理の部分になります。
# The ${LANG} manipulation is necessary only in virtual terminal (a.k.a. console - /dev/tty*): if [ -n "${LANG}" ] && [ "${TERM}" = 'linux' ] && /usr/bin/tty | /usr/bin/grep --quiet -e '/dev/tty'; then if /usr/bin/grep --quiet -E -i -e '^.+\.utf-?8$' <<< "${LANG}"; then case ${LANG} in ja*) LANG=en_US.UTF-8 ;; (..snip..)
2行目を読むと以下の3つの条件でLANG=en_US.UTF-8
に設定されることが分かります。
$LANG
が設定されているTERM=linux
であるtty
コマンドの結果が/dev/tty
を含む
1つめ、2つめは問題ないことがこれまでの結果から判明しています。
3つめがまだ確認できていませんので、確認をしてみます。
tty
tty
コマンドは、今使っている端末が何かを表示します。
仮想コンソールの場合は、/dev/tty0
~が使われます(そのうち、X Window Systemは、/dev/tty7
~を使います)。
端末アプリケーションやSSHなどは、疑似端末(pseudo-terminal)の/dev/pts/0
~が使われます。
つまり、「tty
コマンドの結果が/dev/tty
を含む」というのは仮想コンソールであることを示します。
では実際に仮想コンソールからtty
コマンドの結果を確認してみましょう。
RHEL10のtty
- 仮想コンソール(
TERM=linux
)で一般ユーザにログインし、tty
コマンドを実行
/dev/tty1
- そのまま
sudo su -
でrootにスイッチし、tty
コマンドを実行
/dev/pts/2
- 一般ユーザに戻って、
sudo tty
コマンドを実行
/dev/pts/2
RHEL9のtty
- 仮想コンソール(
TERM=linux
)で一般ユーザにログインし、tty
コマンドを実行
/dev/tty1
- そのまま
sudo su -
でrootにスイッチし、tty
コマンドを実行
/dev/tty1
- 一般ユーザに戻って、
sudo tty
コマンドを実行
/dev/tty1
おや、RHEL10ではsudo
した際のtty
が疑似端末の/dev/pts/2
という扱いになってしまいました。
これが怪しそうです。
そこで次はsudo
について調べてみます。
sudo
RHEL10側のマニュアルを色々と確認していると、sudoers(5)
のマニュアルに気になる記載を見つけました。
use_pty
If set, and sudo is running in a terminal, the command will be run in a new pseudo-terminal. If the sudo process is not attached to a terminal, use_pty has no effect.
A malicious program run under sudo may be capable of injecting commands into the user’s terminal or running a background process that retains access to the user’s terminal device even after the main program has finished executing. By running the command in a separate pseudo-terminal, this attack is no longer possible. This flag is on by default for sudo 1.9.14 and above.
“If set, and sudo is running in a terminal, the command will be run in a new pseudo-terminal.”と書かれています。
意訳するとuse_pty
を使うと、sudo
は疑似端末(pseudo-terminal)で実行されるということです。
挙動を踏まえるに、このオプションは最重要容疑者です。
もっと注目すべき点は、”This flag is on by default for sudo 1.9.14 and above.”という記載。
つまりsudo 1.9.14以上ではデフォルトで設定されるよ、とのこと。
おっとー?バージョンで挙動変わるなんて、より怪しい匂いがプンプンするぜ。
ということで、バージョンを確認してみましょう。
RHEL10のsudo
$ sudo -V Sudo バージョン 1.9.15p5
RHEL9のsudo
$ sudo -V Sudo バージョン 1.9.5p2
はい、RHEL10でバージョンが1.9.15p5(1.9.14以上)になっています。
この違いが、tty
の差、ひいては$LANG
の差に繋がっている可能性が高いですね。
解決
原因の目星は付きました。
sudo
のuse_pty
を無効にして様子を確認してみます。
sudoers
の設定を変更するにあたって、/etc/sudoers
ファイルを編集しても良いですが、今回は/etc/sudoers.d/
配下にファイルを作成する形にします。
以下の様に/etc/sudoers.d/use_pty
を作成しつつ、use_pty
を無効にします。
# visudo -f /etc/sudoers.d/use_pty Defaults !use_pty
この状態で、改めて仮想コンソールから状況を確認してみましょう。
このように、sudo
をしてもtty
が仮想コンソール(/dev/tty1
)になり、LANG=en_US.UTF-8
が設定されるようになりました。
まさしくuse_pty
が原因だったようです。
まとめ
今回の事象は、sudo
のデフォルトの挙動が変わったことが原因でした。
マニュアルにも書かれているとおり、セキュリティの理由でデフォルト値が変わっていることもありますので、セキュリティとのトレードオフを検討した上で設定を変更するようにして下さい。
最近のコメント