よろず環境設定 2

IPv6の無効化

initscripts のバージョンによって処置内容が少々異なる。主には、RedHat のナレッジベース "How do I disable the IPv6 protocol in Red Hat Enterprise Linux?" を参考にした。以下の 3つの処置が必要だ。

1. modprobe.conf への記述追加

/etc/modprobe.d/ ディレクトリの存在するディストリビューションでは、/etc/modprobe.conf に直に書くのではなく、/etc/modprobe.d/ 下に ipv6 といったファイル (ファイル名は任意) を作成し、下記に述べる内容だけをそこに書く方がスマートだ。以下、「modprobe.conf に」という部分はそう解釈していただきたい。

※ FedoraCore 9 には、デフォルトでは /etc/modprobe.conf ファイルが存在しない。これは、デバイスモジュールのロードの役目が modprobe.conf から udev へとシフトし、OS の装備するハードウェアリストも充実してきたためだ。特殊な場合を除いては modprobe.conf へのモジュール記述が不要になりつつあるらしい。こういったディストリビューションではなおさら /etc/modprobe.d/ 配下のファイルに書くべきと思われる。

RedHat Enterprise Linux/CentOS 4の場合

modprobe.conf に以下の記述を加える。

alias net-pf-10 off

net-pf-10 は、デフォルトで ipv6 カーネルモジュールのエイリアスとして定義されている (ハードコードされている?) 名前。見てみたければ、

root# modprobe -c |grep net-pf-10

で確認することができる。

RedHat Enterprise Linux/CentOS 5.1 ~ 5.3 の場合

上記に加えて、下記の一文も記述する。

install ipv6 /bin/true

同様の作用をする記述に、`blacklist ipv6' や `alias ipv6 off' もあるが、blacklist による記述では、起動後に `modprove ipv6' とコマンドすれば、ipv6 モジュールはロードできてしまう。つまり、何か他のプログラムや他のモジュールの要求により意図せず ipv6 カーネルモジュールがロードされる可能性が残るということだ ("How to Disable IPv6 in Fedora and CentOS" より)。また、`ipv6 off' の書き方をしてあるシステム上で `modprobe ipv6' を唱えた場合、`FATAL: Module off not found.' というエラーになってイヤラしい。`install ipv6 /bin/true' なら、何かが ipv6 モジュールをロードしようとした際には必ず /bin/true が実行されるだけ、つまり何も起こらない。

RedHat Enterprise Linux/CentOS 5.4 以降の場合

net-pf-10 の記述と、下記の一文を記述する。

options ipv6 disable=1
RedHat Enterprise Linux/CentOS 6 の場合

上記のどれが正解なのか不明。そういった場合は、とりあえず 3つとも書いておいても害はないようだ(※)。/etc/modprobe.conf に直接書き加えてもいいし /etc/modprobe.d/disable-ipv6.conf (ファイル名は ipv6.conf でも何でも構わない) を新規に作成してそこに書いてもよい。

※ いや、たまに害がある。実際に出会ったのは、CentOS 6.3でLVS (Linux Virtual Server) フレームワークを使ってロードバランサを立てようとした時だ。LVSのカーネルモジュール ip_vs は、ipv6 カーネルモジュールがロードできないと正常にロードされない。そういう場合は、`install ipv6 /bin/true' は書いてはいけない。つまり、「ipv6 モジュールはロードできるけれども実質無効」という状態に手加減してやるわけだ。

RedHat Enterprise Linux/CentOS 7 の場合

/etc/sysctl.d/10-ipv6.conf を作る。`sysctl -p /etc/sysctl.d/10-ipv6.conf' で反映。

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

2. network への記述追加

/etc/sysconfig/network ファイルに以下の記述を加える。厳密には initscripts のバージョンに依存するのだろうが、余計な変数を定義たとしても /etc/sysconfig/network-scripts/ifup シェルスクリプトとそこから呼ばれる ifup-eth などで無視されるだけなので、共通と考えていいだろう。もっと調べたければ、initscripts パッケージ付属のドキュメント <share>/doc/initscripts-x.x.x/sysconfig.txt を読むといいだろう。

NETWORKING_IPV6=no
IPV6INIT=no
IPV6_AUTOCONF=no

下の2つは、各インターフェイスファイル (/etc/sysconfig/network-scripts/ifcfg-*) で個別に指定することもできるものだが、sysconfig/network ファイルに書いておくと、全てのネットワークインターフェイスに対するグローバルな指示となる。これを確実にするため、各インターフェイスファイルにこれらを打ち消すような記載がないことも確認しておかなくてはならない。なお、最後の IPV6_AUTOCONF=no は、前出の "How do I disable the IPv6 protocol in Red Hat Enterprise Linux?" では触れられていないが、実際にネットワークinitスクリプトを見てみると IPv6 モジュールをロードするかしないかの重要なトリガーになっている様子なので、念のため記述することにしている。

3. ip6tables の停止

IPv6 版 iptables がスタートアップしないようにする。RHEL/CentOS 7 では不要。

root# chkconfig ip6tables off
root# chkconfig --list ip6tables

手順 1 ~ 3 が全て完了したら、システムをリブートする。起動後、`lsmod |grep ipv6' と `lsmod |grep net-pf-10' をコマンドして何も出力されないことを確認する。

4. その他のサービスの帳尻合わせ

IPv6がリッスンできないと言って、起動の度にエラーを記録する奴が幾つかいる。

Postfix
/etc/postfix/main.cf 内の inet_protocols = allinet_protocols = ipv4 にする。
ntpd, ntpdate
/etc/sysconfig/ntpd 及び ntpdate 内の OPTIONS-4 を加える。
sshd
RHEL/CentOS 7 世代のみ。/etc/ssh/sshd_config でコメントアウトされている "#AddressFamily any" のコメント記号を外し "AddressFamily inet" に書き換えておく。
 

ローカルでしか開かないGUIツールをリモートから使うには

例えば、RedHat系の system-config-* などシステム管理系 GUI ツールの中には、VNCでリモート接続している時や、root 以外の一般ユーザでローカルの X Window にログインしている時には使えないものがある。そういう時には、sshX Forwarding 機能を活用するとたいていのものは動かすことができる。この機能を使うためには、サーバ (接続先) の sshd_configX11Forwardingyes に設定してある必要がある。例えば、

リモートマシンの virt-manager をクライアント端末 (操作端末) から開くには、クライアント端末の X Window 上のターミナルで、下記のようにコマンドする;

ssh -Y root@server virt-manager

リモートマシンへの一般ユーザでのVNC接続中に、リモートマシンの virt-manager を開くには、VNCセッション上のターミナルで、下記のようにコマンドする;

ssh -Y root@localhost virt-manager

これでも開けない場合は、上記コマンドの前に下記のコマンドを発行しておく;

xhost +inet:localhost

SHIFT_JISロケールを使えるようにする

アプリケーションによっては、SHIFT_JIS ロケールが使えないと出力が文字化けしたり動作に支障を来したりする場合がある。しかし、RHEL5 以降のデフォルト状態ではそもそも ja_JP.SJIS ロケール定義ファイルがコンパイルされていないため、使用するには glibc のための定義ファイルを作ってやる必要がある。

root# locale -a |grep ja   <-ja_JP.SJISがコンパイルされglibcに認識されているか確認
ja_JP
ja_JP.eucjp
ja_JP.ujis
ja_JP.utf8
japanese
japanese.euc
root# localedef -v --force -f SHIFT_JIS -i ja_JP /usr/lib/locale/ja_JP.sjis

-f の引数は読み込むキャラクタマップ定義ファイル名、-i は元にするlocale定義ファイル名、最後にlocale定義の出力ディレクトリ名を指定する。各引数は、絶対パスで書かない限り、既定のパスからの相対指定と解釈される。既定の位置は `localedef --help' で調べられるが、RHEL5.x で見たところ、キャラクタマップは /usr/share/i18n/charmaps/、元ロケール定義は /usr/share/i18n/locales/、出力先は /usr/lib/locale/。最後の「出力パス」だけは絶対パスで指定しないと定義が出力されなかった。RHEL6 でも事情は全く同じだ。

また、SHIFT_JIS は多くの矛盾を抱えたロケールであるため、localedef 実行時に「警告が出されたためファイルに出力されませんでした」というエラーが出てファイル出力が行われない。--force オプションはその対策だ。定義ファイルが出力されなかった場合でも、再度 `locale -a |grep ja' で確認すると一応 ja_JP.sjis が表示されるのだが、マシンを再起動すると元に戻ってしまう。

グラフィカルデスクトップへのrootログインを禁止する

GNOMEデスクトップ環境で root ユーザでのログインを禁止するには、GDM に関する pam の設定を変更する。VNCで接続する際もやはり gdm を介するので、そちらも root ログイン禁止となる。変更はオンザフライでできる。基本的には vsftpd の拒否リストと仕組みは同じだ。変更するのは /etc/pam.d/gdm-password ファイル。RHEL/CentOS 6 では pam_gnome_keyring.so 行の後、RHEL/CentOS 7 では pam_selinux_permit.so 行の後に、pam_succeed_if.so または pam_listfile.so 行を挿入する。

pam_succeed_if.so を使うやり方

単純に「root以外なら成功」となる。rootでいくら正しいパスワードを入力しても常にログインは失敗する。

auth    required    pam_succeed_if.so user != root quiet
pam_listfile.so を使うやり方

rootだけでなく複数のユーザを拒否したり特定のいくつかのユーザだけ許可できたりと、融通が利く。反面、上記よりも整備に一手間掛かる。

auth    required    pam_listfile.so item=user sense=deny file=/etc/gdm/user-list onerr=succeed

"file=" で指す拒否ユーザリストのパスやファイル名は自由。そして、その拒否リストファイルを作る。内容はこれだけだ。

root
/etc/securetty を空にするという昔ながらの方法もあるが、それだとテキストコンソール(Runレベル3) まで root ログイン不可となるばかりか(ただしシングルユーザモードは対象外)、GDMログインは制限できない。グラフィカルログイン主体の現代では、追加的なセキュリティ施策にこそなれ、主対策としては少々時代遅れと言わざるを得ない。

使いようによっては、特定のユーザだけ許可するという方針も採れる。ただしその場合、上記の手法のままだと、新しいアカウント(許可したくない対象)を作る度に拒否リストファイルに書き足さなくてはならない。そこで、sense を逆にしたほうがいいだろう。つまり、

auth    required    pam_listfile.so item=user sense=allow file=/etc/gdm/user-list onerr=fail

として、リストファイルには許可したいユーザだけを並べておくわけだ。ちなみに "onerr=" は pam としてのエラーつまりリストファイルが存在しなかったり読めなかったりした時のための指示であり、fail にすべきか succed にすべきかは緊急時のポリシーやファイルの置き場(例えばNFS上にあるとか) によって変わってくるだろう。

CentOS7 で "カラーマネージメントされたデバイスを作成するには認証が必要です" ダイアログ多発

CentOS 7 でGUIログインする前後に 「カラーマネーマネージメントされたデバイスを作成するには認証が必要です」という認証ダイアログが何度も出て邪魔で邪魔でしょうがない。GNOMEのバグのようだ。Bugzillaここ にとりあえずの回避策が書かれている。そのままでは解決できなかったが、isInGroup 条件を削除することによって対策の効果が得られた。

/etc/polkit-1/rules.d/02-colord.rules というファイルを下記の内容で作る。

polkit.addRule(function(action, subject) {
  if (action.id == "org.freedesktop.color-manager.create-device" ||
       action.id == "org.freedesktop.color-manager.create-profile" ||
       action.id == "org.freedesktop.color-manager.delete-device" ||
       action.id == "org.freedesktop.color-manager.delete-profile" ||
       action.id == "org.freedesktop.color-manager.modify-device" ||
       action.id == "org.freedesktop.color-manager.modify-profile") {
     return polkit.Result.YES;
  }
});

[RHEL/CentOS 7] 一般ユーザによるシャットダウンやリブートを禁止する

RHEL/CentOS 7 では、一般アカウントでも簡単にシステムをシャットダウン/リブートやハイバネートできてしまう。wheel グループに属するユーザに至っては、パスワードの要求もなしに `systemctl poweroff' や `systemctl reboot' が実行できる。GUI デスクトップ、テキストターミナルに関わらずだ。これは危ない。従来通りに sudosu を使わなければならない運用に切り替えるか、それに似た動きに変えたい。

ついでながら、この処置にはありがたい副次的効果がある。GNOMEデスクトップは、ログインユーザに実行権限があるかどうかを polkit に問い合わせて画面の表示アイテムを変えているらしく、以下の手順でシャットダウンやリブートをできなくしたユーザのデスクトップには電源ボタンが表示されなくなる。ログイン画面(gdmグリーター)の電源ボタンも消えて無くなる。ケース 1 と 2 (後述) の場合 wheel グループのユーザのデスクトップにだけは電源ボタンが表示される。それもイヤだという人は次項 GNOMEデスクトップ関連アプリのデフォルト値を変更したい も参照していただくといいだろう。

こうした権限管理は polkit フレームワークで制御されている。アクションの定義 (action id) は /usr/share/polkit-1/actions/org.freedesktop.login1.policy ファイルで、例えば、シャットダウンは org.freedesktop.login1.power-off、他のユーザがログインしている時のそれは org.freedesktop.login1.power-off-multiple-sessions と定義されている。そして、/etc/polkit-1/rules.d/50-default.rules ファイルに下記のようなルールがある。RHEL/CentOS 7 に使われている polkit のバージョンでは、定義ファイルは JavaScript で書かれている。ルールファイルはファイル名の辞書順で評価されていく。

polkit.addAdminRule(function(action, subject) {
    return ["unix-group:wheel"];
});

addAdminRule() は、管理者権限を必要とするアクションが実行されようとした時に polkit に返す管理者アカウントのリストを定義する。この定義により、wheel グループに属するユーザの場合は認証なしに、それ以外のユーザは wheel グループに属するいずれかのアカウントのパスワードが要求される。いずれかのアカウントというのが妙で、テキストターミナルの場合、polkitwheel グループのユーザの一覧を表示し「どのユーザのにするか」と聞いてくるのだ。変な動きだ。

動作を変えるには /etc/polkit-1/rules.d/ 配下にカスタムルールファイルを作成する。/usr/share/polkit-1/ 配下をいじったり、/etc/polkit-1/ 配下にある既定のファイルを編集するのはよろしくない。パッケージのアップデート時にお仕着せのものへリセットされる畏れがあるからだ。

1. sudoのように本人のパスワードを要求するようにする場合

wheel グループに属するユーザだけに許可し、なお且つ本人のパスワードの入力を要求するようにするには、/etc/polkit-1/rules.d/10-restrict-poweraction.rules ファイルを作る。こんな内容だ。

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.login1.power-off" ||
        action.id == "org.freedesktop.login1.power-off-multiple-sessions" ||
        action.id == "org.freedesktop.login1.reboot" ||
        action.id == "org.freedesktop.login1.reboot-multiple-sessions" ||
        action.id == "org.freedesktop.login1.suspend" ||
        action.id == "org.freedesktop.login1.suspend-multiple-sessions" ||
        action.id == "org.freedesktop.login1.hibernate" ||
        action.id == "org.freedesktop.login1.hibernate-multiple-sessions" ||
        action.id == "org.freedesktop.systemd1.manage-units")
    {
        if (subject.isInGroup("wheel")) {
            return polkit.Result.AUTH_SELF;
        } else {
            return polkit.Result.NO;
        }
    }
});

※ なぜかパワー関係のアクションだけをaction条件に書いたのではダメで、systemd1.manage-units を加えないと意図通りに動かない。`systemctl enable xxxx' コマンドなども制御されてしまうが、とりあえず、まあよしとしておこう。

2. wheel に属していてもいなくても常に拒否したい場合

sudosu を使うから polkit に許可なんかしてほしくない、というなら、上記の 10-restrict-poweraction.rules ファイルの polkit.Result.AUTH_SELFpolkit.Result.NO にすればよい。

GNOMEデスクトップ関連アプリのデフォルト値を変更したい

システムアカウントを何人も用意しておかなければならない場合、例えば nautilus ファイルブラウザのアイコン表示でいちいち画像系ファイルのサムネイルを表示させたくないといった時、fooでログインしては nautilus の設定を変更し、また bar でログインして変更し、などと面倒くさいことをやっていないだろうか。システムグローバルな既定値を変更することができる。

RHEL/CentOS 5/6 の場合

yum 等で gconf-editor パッケージをインストールし、root でグラフィカルログインして アプリケーション -> システムツール -> 設定エディタ で起動する (※)設定エディタ(gconf-editor) の ファイル メニューから 新しいデフォルトの設定 を選択すると別の画面が開くので、元の画面は閉じ、新しい画面の方で目的の項目を変更する。例えばファイルブラウザのイメージサムネール表示を無効にするなら /apps/nautilus/preferences/show_image_thumbnailsnever にする。RHEL/CentOS 5 の場合は、ここでいちいち、変更した項目を右クリックして デフォルトに戻す (変な日本語訳だ) を選択しなければならない (RHEL/CentOS 6ではやらなくてよい)。全ての項目を好みに変更したら、ファイル メニュー -> 終了

rootでのGUIログインを不許可 にしてある場合は、X のフォワード機能を使って ssh -Y root@localhost gconf-editor とやってもいい。

RHEL/CentOS 7 の場合

RHEL/CentOS 7 では gconfdconf に代わり、gconf-editor でなく dconf-editor をインストールすることになる。ただし、これは補助ツールだ。グローバル既定値を変えるには設定ファイル編集+コマンドでしかできない。とはいえ、RHEL6 までのようにちまちまと gconf-editor で項目を変更していくのとは違い、変更する項目だけをファイルとして用意しておけるので、「これだ」という定型ができてしまえば量産が可能というメリットがある。また、RHEL/CentOS 6 までよりもデフォルト値がまともになってきており、あまりたくさんの項目を変更しなくてよくなったのもありがたいことだ。

まず、変更すべき項目を特定するために、アプリケーション -> システムツール -> dconfエディター を起動する。見るだけなので、root 権限で起動する必要はない。それと並行して、root 権限で /usr/share/glib-2.0/schemas/my_schema.gschema.override というファイルを新規に作り編集を開始する。ファイル名の "my_schema" の部分は何でも構わない。dconfエディタで目的の設定ツリー (スキーマという) を選択した状態で右ペイン下部の スキーマ に表示される文字列、例えば org.gnome.nautilus.preferences を、ファイルにヘッダとして書き、その下に設定項目と値を連ねる。こんな塩梅だ:

[org.gnome.login-screen]
disable-user-list=true
[org.gnome.nautilus.preferences]
show-image-thumbnails='never'
show-hidden-files=true
[org.gnome.settings-daemon.plugins.power]
active=false

ちなみに、サンプル設定の最後に添えた 2行は、GNOMEの電源管理プラグインを無効化する。ユーザのデスクトップに電源ボタンは表示されるが、実質無効となり、再起動/電源オフのどちらを選んでも何も起こらなくなる。前項 一般ユーザによるシャットダウンやリブートを禁止する と併せて実施してもらうとさらにセキュリティが増し誤操作防止にもなる。

my_schema.gschema.override ファイルが完成したら、root 権限のターミナルで下記コマンドを発行してスキーマファイルをコンパイルし直す。

# glib-compile-schemas /usr/share/glib-2.0/schemas/