Table of Contents
- Linuxでのアカウント情報管理について
- /etc/passwdについて
- /etc/shadowについて
- パスワードのハッシュ化について
- Shadowの項目について
- Hash方式について
- ハッシュ化とは?
- Saltについて
- 参考文献
1 Linuxでのアカウント情報管理について
Linuxでユーザのアカウント情報を保管しているファイルといえば、
以下では、パスワードの情報などは /etc/shadow に保管されている状況で、それぞれどんな情報が格納されているかまとめてみました。
( /etc/passwdにパスワードを保管しないのは、/etc/passwdが他のユーザからRead可能なファイルだからです。 そしてRead権限がないと困ります。/etc/passwdをRead可能にしなければ、たとえば
------------------------------------------------------------------------------------------------------------------------------
以下で、
#から始まるコマンドは管理者権限で実行、
$から始まるコマンドはユーザ権限で実行していることにします。
Ubuntu11.10で実験しています。
システムユーザ,root,testユーザの例で話を進めます。 実際の値とは一部変更してあることがあります。
-------------------------------------------------------------------------------------------------------------------------------
- /etc/passed
- /etc/shadow
以下では、パスワードの情報などは /etc/shadow に保管されている状況で、それぞれどんな情報が格納されているかまとめてみました。
( /etc/passwdにパスワードを保管しないのは、/etc/passwdが他のユーザからRead可能なファイルだからです。 そしてRead権限がないと困ります。/etc/passwdをRead可能にしなければ、たとえば
$ id (他のユーザ) $ ls -l hogeなどが正しく動作しないことになります。後者についてはuid,gid番号から、ユーザーが誰か判別できないので。。。)
------------------------------------------------------------------------------------------------------------------------------
以下で、
#から始まるコマンドは管理者権限で実行、
$から始まるコマンドはユーザ権限で実行していることにします。
Ubuntu11.10で実験しています。
# useradd -c TEST -d /home/test -e 2011/12/10 -f 1 -m -e /bin/bash testというコマンドでユーザを追加して、
# passwd test testとして、パスワードを"test"としていることにします。 オプションの意味については、
$ man useraddを参照するか、後の記述から推測してください。
システムユーザ,root,testユーザの例で話を進めます。 実際の値とは一部変更してあることがあります。
-------------------------------------------------------------------------------------------------------------------------------
2 /etc/passwdについて
まずはじめに、/etc/passwdが誰から読めるか確認しておきます。
では、実際に/etc/passwdの一部を抜き出してみます。
見て面白そうなところは、
$ ls -l /etc/passwd誰からでも読めるようになっていることと思います。
では、実際に/etc/passwdの一部を抜き出してみます。
root:x:0:0:root:/root:/bin/bash sshd:x:114:65534::/var/run/sshd/usr/sbin/nologin test:x:1001:1001:TEST:/home/test:/bin/bashこの見方は、次のとおりです。
- :(コロン)が区切り
- 各区切られた区間は次の順番で見る。
ログイン名:暗号化パスワード:ユーザID:グループID:コメントorユーザ名:ホームディレクトリ:ログイン時に実行するコマンド
詳しくは、
$ man 5 passwd (man passwdとは内容が違う。man manを読むなどすれば良い。)
ログイン名 | パスワード | uid | gid | コメント | ホームディレクトリ | ログイン時実行するコマンド |
---|---|---|---|---|---|---|
root | x | 0 | 0 | root | /root | /bin/bash |
sshd | x | 114 | 5534 | /var/run/sshd | /usr/sbin/nologin | |
test | x | 1001 | 1001 | TEST | /home/test | /bin/bash |
見て面白そうなところは、
- 暗号化パスワードがxになっているのは、ディストリビューションによって違うかもしれない。とりあえず、空になっている。
- rootはuid,gidとも0である。
- sshdはシステムユーザで、uidが999以下。
- コメントはあってもなくても良い。
- ホームディレクトリはログイン時に、どこがカレントディレクトリになるかや、 環境変数$HOMEなどに関係する(詳しくはman usrmodを参照)。
- 最後のログイン時に実行するコマンドについて、これは$SHELLを定める。 この欄が空の場合、デフォルトでは/bin/shを実行する。
- /usr/sbin/nologinは実行できるので、試しに実行すると何をするやつかわかる気になる。 (コマンド名通りsshdではログインできない。)
- ついでに、一度、sshdの/usr/sbin/nologinを削除して空欄にして、sudo su sshdとかしてみると ログインできることがわかる。(試したら戻しておくこと。)
3 /etc/shadowについて
/etc/shadowは誰から読めるのでしょうか。
「誰から読めるか」を分けることによって、パスワードを一般のユーザが直接見ることができないようにしています。
shadowの中を見てみましょう。
$ ls -l /etc/shadow-rw-r-----で所有者root,所有グループshadowとなっていると思います。 このように、一般ユーザからは読めないことがわかります。
「誰から読めるか」を分けることによって、パスワードを一般のユーザが直接見ることができないようにしています。
shadowの中を見てみましょう。
test:\$6$eIaYHAqm$y/.5CEj/m2RDrubIh...(省略):15316:0:99999:7:1:15318:のようになっています。先ほどと同様
- :(コロン)で区切られている
- 各区切られた区間は以下の順番。($ man 5 shadowの一部改変)
パスワードが変更できるまでの日数:パスワードを変更しないといけなくなるまでの日数 :
パスワードが有効な期限の前にユーザが警告を受ける日数 : パスワードが無効になってからアカウントが使えなくなるまでの日数 : 1970/1/1からアカウントが使えなくなるまでの日数 : 予約フィールド
ほとんどのフィールドは全く使わないと思うので、必要にならない限り無視してよいと思うけど、 こんなものも設定できる、ということで。
- ログイン名: test
- 暗号化パスワード: $6$eIaYHAqm$y/.5CEj/m2RDrubIh...(省略)
- 1970/1/1から最後にパスワードが変更された日までの日数: 15316
- パスワードが変更できるまでの日数: 0
- パスワードを変更しないといけなくなるまでの日数: 99999
- パスワードが有効な期限の前にユーザが警告を受ける日数: 7
- パスワードが無効になってからアカウントが使えなくなるまでの日数: 1
- 1970/1/1からアカウントが使えなくなるまでの日数: 15318
- 予約フィールド:
$ man 5 shadowを参照して欲しいでし。
ほとんどのフィールドは全く使わないと思うので、必要にならない限り無視してよいと思うけど、 こんなものも設定できる、ということで。
4 パスワードのハッシュ化について
4.1 Shadowの項目について
ここでは、特に上記の暗号化パスワードについて考えていきます。
そもそもパスワードは``test``だったわけで、これが非常に長い文字列になっています。
これは、パスワードをハッシュ(Hash)して格納しているからですが、暗号化パスワードの部分は、 実際には次のように分かれています。
これは、パスワードをハッシュ(Hash)して格納しているからですが、暗号化パスワードの部分は、 実際には次のように分かれています。
Hash方式 | Salt | $ | Hash化されたパスワード |
---|---|---|---|
$6$ | eIaYHAqm | $ | y/.5CEj/m2RDrubIh...(省略) |
4.2 Hash方式について
Hash方式として、DES,MD5,SHA256,SHA512などがあります。
(DESは使うべきでないので、ここでは除外します。/etc/Shadowの暗号化パスワードの項が$から始まっていれば良いです。)
それぞれについてはここでは詳しく述べません。
linuxjm.sourceforge.jp/html/LDP_man-pages/man3/crypt.3.html
など、他の多くの方が書かれている文献を参考にしてください。 ここでは、現状はSHA512のままで良いのではないか、ということだけ述べておきます。
Hash方式 | 実際のHash方式 |
---|---|
$1$ | MD5 |
$5$ | SHA-256 |
$6$ | SHA-512 |
など、他の多くの方が書かれている文献を参考にしてください。 ここでは、現状はSHA512のままで良いのではないか、ということだけ述べておきます。
4.3 ハッシュ化とは?
まず、ハッシュ化とは大雑把に言って
という一連の流れのことと言ってよいと思います。
ユーザがログイン時など認証する際には、
を計算して、B'と上記のHash化されたパスワードが一致するかどうかをチェックします。
今パスワードを保管するために、この複雑な変換が持つべき性質として、
文字列 | --------------> | 文字列 |
A | 複雑な変換 | B |
ユーザがログイン時など認証する際には、
入力 | ---------------> | Hash化 |
A' | 複雑な変換 | B' |
今パスワードを保管するために、この複雑な変換が持つべき性質として、
- AからBへの変換の過程にかかる時間はそんなに長くかからない
- Aが違えば、Hash化後のBもほぼ間違いなく違う。
– 例えば、上記のtestユーザでログインしようとして、パスワードをhogehogeと打って、認証に成功すると困る。
- BからAを類推しづらい。
– Hash後の値は常に読まれてしまう可能性があります。 通信路上や、特に/etc/shadowは管理者に読まれます。
– 元々のAが自分以外にバレると、"その事実に気づいて"(!!)パスワードを変更するくらいしか対策がしづらいです。
特に2つ目と3つ目は'ほとんど'相反しています。 『A->Bが一意に決まる』ならば、『B->Aを決まる』はずです。(Bになるやつが1つしかないんだから。)
重要な部分は、『しづらい』とか『ほぼ』とかで、 例えば、『B->A』を求めるのに多くの場合30日かかるなら、パスワードの有効期限を例えば15日などにしておけば、多くの場合大丈夫なのかもしれません。
(多くの場合、という言葉は非常に悩ましい部分ですが。。。)
特に2つ目と3つ目は'ほとんど'相反しています。 『A->Bが一意に決まる』ならば、『B->Aを決まる』はずです。(Bになるやつが1つしかないんだから。)
重要な部分は、『しづらい』とか『ほぼ』とかで、 例えば、『B->A』を求めるのに多くの場合30日かかるなら、パスワードの有効期限を例えば15日などにしておけば、多くの場合大丈夫なのかもしれません。
(多くの場合、という言葉は非常に悩ましい部分ですが。。。)
4.4 Saltについて
ところで、上記の表でSaltという部分がありました。
これは一体何をするのでしょうか?これについて、詳しい話は他の場所に譲りますが、
Hash化の際に"複雑な変換"の部分をSaltを使うことで、各パスワードごとに微妙に変えていくわけです。
(簡単な例として、数字に対してHash化は「Saltを掛けてから、各桁を足す」、というものだったとします。 単純にやれば、12->3ですが、Saltが7の場合、12=>12*7=84->12となります。 Saltが11なら、12=>12*11->6となって、Hash化後には違うものになります。)
これが何故必要か考えてみます。 Hash化の条件として、『B->A』を計算するのが難しい、時間が膨大にかかる、というものがありました。
しかし、予め『AとBの対応表』を時間をかけて作っておけば、どうでしょうか? Hash化の方式はいくつかありますが、もし、みんなが本当に同じ変換を使ってしまっている場合、 1種類の対応表を作られてしまった瞬間に、Hash化する意味の多くが失われます。
一方で、Saltを使うことで、そのような対応表をつくる方法がなくなります。 (Saltごとに対応表をつくる必要があり、1つの対応表をつくるために膨大な時間がかかるのです。)
(簡単な例として、数字に対してHash化は「Saltを掛けてから、各桁を足す」、というものだったとします。 単純にやれば、12->3ですが、Saltが7の場合、12=>12*7=84->12となります。 Saltが11なら、12=>12*11->6となって、Hash化後には違うものになります。)
これが何故必要か考えてみます。 Hash化の条件として、『B->A』を計算するのが難しい、時間が膨大にかかる、というものがありました。
しかし、予め『AとBの対応表』を時間をかけて作っておけば、どうでしょうか? Hash化の方式はいくつかありますが、もし、みんなが本当に同じ変換を使ってしまっている場合、 1種類の対応表を作られてしまった瞬間に、Hash化する意味の多くが失われます。
一方で、Saltを使うことで、そのような対応表をつくる方法がなくなります。 (Saltごとに対応表をつくる必要があり、1つの対応表をつくるために膨大な時間がかかるのです。)
5 参考文献
以下は参考になりそうなサイトです。
自分は特に読んでないので、内容については保証できませんが、このサイトの文章より確からしいと思います。
第1回神泉セキュリティ勉強会資料
linuxjm.sourceforge.jp/html/LDP_man-pages/man3/crypt.3.html
第1回神泉セキュリティ勉強会資料
linuxjm.sourceforge.jp/html/LDP_man-pages/man3/crypt.3.html
0 件のコメント:
コメントを投稿