OpenSSLのHeartbleed問題については以下でご案内しております。
アナウンス
https://access.redhat.com/site/announcements/791943
問題有無の確認方法および対策
https://access.redhat.com/site/ja/solutions/785993
またこの問題に限らずCVE番号が付与された脆弱性については、
影響有無と対応する修正のアドバイザリについてまとめて公開しております。
本件では以下が該当します。
https://access.redhat.com/security/cve/CVE-2014-0160
2014年5月28日
2014年5月25日
systemd-udevdによるNIC命名とbiosdevnameがまざって混乱する件
最近のsystemd-udevdはlinuxのネットワークインタフェース名を設定します。それにともない特にRHEL界隈でNIC命名規則が複雑になってきたので紹介します。。
問題: linuxカーネルはNICの名前をドライバ初期化順につけるので名前とNICの対応が安定しない。再起動毎に順序がかわる可能性もある。
これに対して過去から最近までいろいろな手法で対策がとられています。
命名規則: デバイスの種類(Ethernetならen, wirelesslanならwl) + ファームウェアでの場所情報(スロット番号またはPCIバスの番号) [+VF番号など]
例: ens0
http://linux.dell.com/biosdevname/
SMBIOSというファームウェアの規格で「オンボードの1番」や「拡張カードスロットの2番」のような場所情報を提供し、これを元にNICの名前を作ります。
例: em1
これは一旦linuxカーネルに適当な名前づけをされたあとに(これが物理的な配置とは無関係になっていることには目をつぶり)、次回の起動からは同じNICに同じ名前をつけるようにするため、MACアドレスとインタフェース名の対応づけをudevのルールとして永続化する仕組みです。
この対応づけは/etc/udev/rules.d/70-persistent-net.rules に保存されます。
RHEL7や最近のFedoraでpersistent-netのルール作成はされませんがRHEL6までで作成されたものをアップグレードした場合はひきつづき有効です。
こんがらがるので以下にまとめます。優先順位自体は最近のFedoraのものと同じですが、デフォルトでの有効無効が環境によってバラバラです。
最近のFedora: ユーザの指定 > persistent-net > biosdevname > systemd > 古典的な名前づけ
RHEL6 on Dell: ユーザの指定 > persistent-net > biosdevname > 古典的な名前づけ
RHEL6 on not Dell: ユーザの指定 > persistent-net > 古典的な名前づけ
RHEL7 on Dell: ユーザの指定 > persistent-net > biosdevname > systemd > 古典的な名前づけ
RHEL7 on not Dell: ユーザの指定 > persistent-net > systemd > 古典的な名前づけ
NIC名前例:
systemd: eno1(ethernetでオンボード1番)
biosdevname: em1 (ethernetでオンボード1番)
古典的な名前づけ: eth0 (最初にeth%d って名前で命名されたNIC)
各自動設定の止め方
systemdのNIC命名: カーネルのコマンドラインに net.ifnames=0
biosdevname: カーネルのコマンドラインに biosdevname=0
persistent-net: /etc/udev/rules.d/70-persistent-net.rulesから該当する行を消す
udevのルールの比較
# 以下RHEL7betaをためした人むけ
RHEL7 public betaを確認するとベンダにかかわらず on Dellのようになっているのですが、RHEL7RCでは上記のように動作が修正されています
問題: linuxカーネルはNICの名前をドライバ初期化順につけるので名前とNICの対応が安定しない。再起動毎に順序がかわる可能性もある。
これに対して過去から最近までいろいろな手法で対策がとられています。
ユーザが明示的に指定する
MAC アドレスなどの識別子とインタフェース名を設定ファイルで明示して指定する。こんなかんじ。DEVICE=eth1 HWADDR=D4:85:64:01:46:9E ONBOOT=yes
Predictable Network Interface Name
くわしくはsystemd本家のwikiにみっちり書いてますが、ざっくりまとめるとハードウェアの物理的な位置やバス上のアドレスを根拠にした、安定した名前をつけます。命名規則: デバイスの種類(Ethernetならen, wirelesslanならwl) + ファームウェアでの場所情報(スロット番号またはPCIバスの番号) [+VF番号など]
例: ens0
Consistent Device Naming by biosdevname
安定した名前づけの仕組みとしては、biosdevnameという別の実装があります。これは最近のFedoraや、RHEL6, 7でDell製ハードウェアの場合に利用されます。http://linux.dell.com/biosdevname/
SMBIOSというファームウェアの規格で「オンボードの1番」や「拡張カードスロットの2番」のような場所情報を提供し、これを元にNICの名前を作ります。
例: em1
Persistent Net
これらの物理的な位置を利用する命名方法が登場する前から利用されているpersistent-netとよばれる仕組みがあります。これは一旦linuxカーネルに適当な名前づけをされたあとに(これが物理的な配置とは無関係になっていることには目をつぶり)、次回の起動からは同じNICに同じ名前をつけるようにするため、MACアドレスとインタフェース名の対応づけをudevのルールとして永続化する仕組みです。
この対応づけは/etc/udev/rules.d/70-persistent-net.rules に保存されます。
RHEL7や最近のFedoraでpersistent-netのルール作成はされませんがRHEL6までで作成されたものをアップグレードした場合はひきつづき有効です。
こんがらがるので以下にまとめます。優先順位自体は最近のFedoraのものと同じですが、デフォルトでの有効無効が環境によってバラバラです。
最近のFedora: ユーザの指定 > persistent-net > biosdevname > systemd > 古典的な名前づけ
RHEL6 on Dell: ユーザの指定 > persistent-net > biosdevname > 古典的な名前づけ
RHEL6 on not Dell: ユーザの指定 > persistent-net > 古典的な名前づけ
RHEL7 on Dell: ユーザの指定 > persistent-net > biosdevname > systemd > 古典的な名前づけ
RHEL7 on not Dell: ユーザの指定 > persistent-net > systemd > 古典的な名前づけ
NIC名前例:
systemd: eno1(ethernetでオンボード1番)
biosdevname: em1 (ethernetでオンボード1番)
古典的な名前づけ: eth0 (最初にeth%d って名前で命名されたNIC)
各自動設定の止め方
systemdのNIC命名: カーネルのコマンドラインに net.ifnames=0
biosdevname: カーネルのコマンドラインに biosdevname=0
persistent-net: /etc/udev/rules.d/70-persistent-net.rulesから該当する行を消す
udevのルールの比較
# 以下RHEL7betaをためした人むけ
RHEL7 public betaを確認するとベンダにかかわらず on Dellのようになっているのですが、RHEL7RCでは上記のように動作が修正されています
2014年5月3日
なぜ cdromグループに入っていないユーザーがCD, DVDを焼けるか、あるいははじめてのsystemd-logind
このあいだ「今度買うハードウェアはDVDマルチライタがついているんだけど、読み込みは許可しつつ焼けないように制限かけたい」って質問されたら、意外に奥が深かったので再現風にまとめ。
自分のデスクトップにLinuxを使いはじめてから15年くらいです。
昔CD-R焼けなくて対応したときの記憶をたどると、たしかこんなかんじだったんじゃないかなと:
自分のマシン(debian testingでinitはsystemdにしてます)でチェックするとこんなかんじ
しかしいずれの環境でも、普段からCD読み書きできています。気になります。
「ファイルシステムとしてmountするのはudisksあたりが頑張ってくれてるはずだから、直接デバイス読んでみよう」 less -f /dev/sr0 すると CD/DVDの内容が読めました。
という状態のデバイスをrootでもcdromグループでもない一般ユーザがアクセスできるのです。
一瞬頭に「???」が浮かびましたが「brw-rw----+」の最後に+があります。確認するとユーザにアクセスを許可するACLが設定されていました。
このACLを設定したプログラムに心あたりがないわけです。自分で明示的に指定したこともありません。自分のマシンで自分の知らない権限設定がされているとかいやですね。しらべましょう。誰がこんな設定してるんでしょうか。ちょっと予想します。
やはりACLが設定されています。GNOMEは排除できました。
pamをうたがって別のvirtual terminal(VT)でrootでログインします。ACLの状態がかわりました。これでインストーラも排除できました。
VTきりかえてkankunアカウントでもういっぺん確認します。
ls -l /dev して同じように+がついているものをみると kvm, rfkill, video0 でも同様のACLが設定されていました。今デスクトップを目の前でつかっているアカウントがデスクトップ用途で使いやすいようにACLを変更する、という意図でやっていそうです。
こういうのたしかsystemdに含まれているlogindってひとが、ConsoleKitから引きついでました。
コンソール切り替えの情報とか監視してないかなー と、lsof -n |grep ttyとかしてみます。
logindが何やってるか知りませんが、こいつかこいつ経由で情報もらった誰かがACLいじっているはず。logindはsystemdのリポジトリにはいってます。
systemdのリポジトリでaclをgrepします。。。./src/login/logind-acl.c ってのがいました。
logind-acl.hで定義されている関数は、 devnode_acl、devnode_acl_all で、デバイスファイルからold_uidとして指定されたuidへの許可ACLを削除して、new_uidとして指定されたuidへの許可ACLを設定します。
devnode_acl_all関数の中で以下のディレクトリを探索してACL設定する対象となるデバイスを決定していました。udevによるタグで絞り込まれています。
dir = opendir("/run/udev/static_node-tags/uaccess");
このタグづけ対象デバイスは、logindのソースと同じディレクトリにある70-uaccess.rulesの中で定義されていて、たとえばCD/DVDについては以下のようなルールがありました。
systemd-logindがACL設定をuaccessタグがついているデバイスにおこなっていそうなことはわかりましたが、どういう契機で行われるかという疑問が残っています。もうひといきです。
systemd-logindがこの依頼を受けてセッション作成し、必要に応じてACL設定の変更をおこなっています。
manager_dispatch_console()
-> seat_read_active_vt()
-> seat_active_vt_changed()
-> seat_set_active()
-> seat_apply_acls()
-> devnode_acl_all()
-> devnode_acl()
まとめると以下のようになっていて、ログインしたとき、画面切り替えした時、既にログイン済みでデバイスをUSBなどで追加したときにちゃんとACLが設定できるようになっていました。
/lib/udev/rules.d/70-uaccess.rules を/etc/udev/rules.d にコピーしてCD用のエントリを消すと、uaccessタグが付与されなくなるのでまずは一般ユーザからCD, DVD焼けなくなる。 でも読む分にはudisks2がユーザ権限でmountしてくれるのでこれでOK。
この方法の問題点としては、70-uaccess.rules に将来の変更で対象となるデバイスが追加された場合にうまく反映されない点があるので手放しでおすすめはしづらいところ。アップデート時には注意が必要です。
systemd以前の世代だと類似のしくみがhal+ConsoleKitだったりudev+ConsoleKitで別途実装されているのでこの方法とちょっとかわります。「一般的にこのコマンド叩けばOK」という美しい方法はないのでした。なやましい……。
事前の予想
自分のデスクトップにLinuxを使いはじめてから15年くらいです。
昔CD-R焼けなくて対応したときの記憶をたどると、たしかこんなかんじだったんじゃないかなと:
- /dev/cdrom あたりはrootユーザ、cdromグループになっている
- 使えるユーザはcdromグループに入っているから使える
確認と謎
自分のマシン(debian testingでinitはsystemdにしてます)でチェックするとこんなかんじ
dragon:~$ ls -l /dev/cdrom
lrwxrwxrwx 1 root root 3 May 2 03:07 /dev/cdrom -> sr0
dragon:~$ ls -l /dev/sr0
brw-rw----+ 1 root cdrom 11, 0 May 2 03:07 /dev/sr0
dragon:~$ idああcdromグループに入ってるわ…… ということでちょっと安心しましたが、長期間使っている環境なので油断できません。Fedoraマシンでみると
uid=1000(kankun) gid=1000(kankun) groups=1000(kankun),24(cdrom),25(floppy),29(audio),30(dip),44(video),
46(plugdev),105(scanner),109(bluetooth),111(netdev)
[kankun@snake ~]$ id uid=1000(kankun) gid=1000(kankun) groups=1000(kankun),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023cdromグループは別にあるもののユーザはcdromグループに入っていません。RHEL5,6,7betaもご同様。
しかしいずれの環境でも、普段からCD読み書きできています。気になります。
「ファイルシステムとしてmountするのはudisksあたりが頑張ってくれてるはずだから、直接デバイス読んでみよう」 less -f /dev/sr0 すると CD/DVDの内容が読めました。
brw-rw----+ 1 root cdrom 11, 0 May 2 03:07 /dev/sr0
という状態のデバイスをrootでもcdromグループでもない一般ユーザがアクセスできるのです。
一瞬頭に「???」が浮かびましたが「brw-rw----+」の最後に+があります。確認するとユーザにアクセスを許可するACLが設定されていました。
dragon:~$ getfacl /dev/sr0
getfacl: Removing leading '/' from absolute path names
# file: dev/sr0
# owner: root
# group: cdrom
user::rw-
user:kankun:rw-
group::rw-
mask::rw-
other::---
誰がこのACLを設定しているの?(タイトルでネタバレ)
# ここからの調査は最初RHEL6でやったんですが、より実装がためになるのでFedora20で調べなおして再現してます。なのでちょいフィクションです。このACLを設定したプログラムに心あたりがないわけです。自分で明示的に指定したこともありません。自分のマシンで自分の知らない権限設定がされているとかいやですね。しらべましょう。誰がこんな設定してるんでしょうか。ちょっと予想します。
- 今のログインユーザだから(pam?)
- インストーラで作成したアカウントだから何か特別に設定が書かれている(どこぞの設定ファイルがudevのルールから参照されてる?)
- GNOMEデスクトップユーザむけのなにかが動いている(udisksとか??)
やはりACLが設定されています。GNOMEは排除できました。
pamをうたがって別のvirtual terminal(VT)でrootでログインします。ACLの状態がかわりました。これでインストーラも排除できました。
getfacl: Removing leading '/' from absolute path names今ログインしてるユーザ全員に許可をだしているわけではなさそうです。一般ユーザのアカウントへの許可は消えてしまいました。最後にログインしたユーザーかな??
# file: dev/sr0
# owner: root
# group: cdrom
user::rw-
group::rw-
mask::rw-
other::---
VTきりかえてkankunアカウントでもういっぺん確認します。
getfacl: Removing leading '/' from absolute path namesやばい…… VT切り替えしかしてないのにACLが書き変わってる……。pamだけじゃこの動きはできません。予想が全滅してポルナレフごっことかやりたくなります。やっても話が進まないのでぐっと堪えます。
# file: dev/sr0
# owner: root
# group: cdrom
user::rw-
user:kankun:rw-
group::rw-
mask::rw-
other::---
ls -l /dev して同じように+がついているものをみると kvm, rfkill, video0 でも同様のACLが設定されていました。今デスクトップを目の前でつかっているアカウントがデスクトップ用途で使いやすいようにACLを変更する、という意図でやっていそうです。
こういうのたしかsystemdに含まれているlogindってひとが、ConsoleKitから引きついでました。
コンソール切り替えの情報とか監視してないかなー と、lsof -n |grep ttyとかしてみます。
systemd-l 683 root 5r REG 0,15 4096 4386 /sys/devices/virtual/tty/tty0/activeあった!
systemd-logindによるACL設定
logindが何やってるか知りませんが、こいつかこいつ経由で情報もらった誰かがACLいじっているはず。logindはsystemdのリポジトリにはいってます。
systemdのリポジトリでaclをgrepします。。。./src/login/logind-acl.c ってのがいました。
logind-acl.hで定義されている関数は、 devnode_acl、devnode_acl_all で、デバイスファイルからold_uidとして指定されたuidへの許可ACLを削除して、new_uidとして指定されたuidへの許可ACLを設定します。
devnode_acl_all関数の中で以下のディレクトリを探索してACL設定する対象となるデバイスを決定していました。udevによるタグで絞り込まれています。
dir = opendir("/run/udev/static_node-tags/uaccess");
このタグづけ対象デバイスは、logindのソースと同じディレクトリにある70-uaccess.rulesの中で定義されていて、たとえばCD/DVDについては以下のようなルールがありました。
# optical drivesこれでさっきのディレクトリに登場しそうです。
SUBSYSTEM=="block", ENV{ID_CDROM}=="1", TAG+="uaccess"
SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", TAG+="uaccess"
$ ls /run/udev/tags/uaccessしてました。b11:0 です。ブロックデバイスのmajor 11, minor 0ですね。
b11:0 c10:232 c116:1 c116:10 c116:11 c116:12 c116:2 c116:3 c116:33 c116:4 c116:5 c116:6 c116:7 c116:8 c116:9 c189:257 c189:258 c189:259 c189:260 c189:385 c21:2 c226:0 c81:0
systemd-logindがACL設定をuaccessタグがついているデバイスにおこなっていそうなことはわかりましたが、どういう契機で行われるかという疑問が残っています。もうひといきです。
1. ログイン時のACL設定
systemd-logindのソースと同じところにpam-module.cといういかにもあやしいのがいます。これをビルドするとpam_systemd.so というモジュールができてセッション作成時に systemd-logindへセッション作成依頼をdbus経由で投げつけます。systemd-logindがこの依頼を受けてセッション作成し、必要に応じてACL設定の変更をおこなっています。
2. VTの状態によるACL設定
systemd-logind内での関数呼び出し元をおいかけると、以下のようになっていて、VTの状態を反映したACL設定をおこなっていました。VT切り替え監視そのものもsystemd-logindが見ていてmanager_dispatch_console() がハンドラになっています。manager_dispatch_console()
-> seat_read_active_vt()
-> seat_active_vt_changed()
-> seat_set_active()
-> seat_apply_acls()
-> devnode_acl_all()
-> devnode_acl()
3. udevdによるACL設定
さらにlogindのソースとおなじディレクトリに追いてある73-seat-late.rules.in をみるとTAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess"という記載があって、uaccessタグがついているデバイスがつながるとudev組み込みのuaccessという処理が走るように設定されています。これは systemdのsrc/udev/udev-builtin-uaccess.cで定義されていて、既にseatとユーザがひもづいている状態でデバイスを接続した時に、そのデバイスについてdevnode_acl()関数を呼びだしてACL設定をおこなうものでした。
まとめると以下のようになっていて、ログインしたとき、画面切り替えした時、既にログイン済みでデバイスをUSBなどで追加したときにちゃんとACLが設定できるようになっていました。
はじめの疑問にもどる
そして結局一般ユーザにCD, DVDを焼けないように設定したいという当初の質問がどうなったかというと……/lib/udev/rules.d/70-uaccess.rules を/etc/udev/rules.d にコピーしてCD用のエントリを消すと、uaccessタグが付与されなくなるのでまずは一般ユーザからCD, DVD焼けなくなる。 でも読む分にはudisks2がユーザ権限でmountしてくれるのでこれでOK。
この方法の問題点としては、70-uaccess.rules に将来の変更で対象となるデバイスが追加された場合にうまく反映されない点があるので手放しでおすすめはしづらいところ。アップデート時には注意が必要です。
systemd以前の世代だと類似のしくみがhal+ConsoleKitだったりudev+ConsoleKitで別途実装されているのでこの方法とちょっとかわります。「一般的にこのコマンド叩けばOK」という美しい方法はないのでした。なやましい……。
登録:
投稿 (Atom)