useradd コマンドでユーザのパスワードを指定する方法

スクリプトなどで自動で Linux のユーザを追加して、そのユーザにパスワードまで設定したいということはあると思います。たとえばテスト環境の構築を自動化していてダミーユーザをたくさん作らないといけない場合など、たとえパスワードがバレても特に問題ない場合が当てはまるかと思います。

ちなみに Linuxコマンドラインからユーザを追加したい時に使えるコマンドとして adduser コマンドと useradd コマンドがあってどっちを使ったらいいのか迷ってしまってユーザ泣かせですが、私の認識では両者は基本的に同じことができて、単に adduser コマンドはインタラクティブ、useradd はワンライナー向き、というところで落ち着いています。

adduser コマンドや passwd コマンドなどはユーザのパスワードをコマンドラインオプションから指定できるようになっていません。インタラクティブにプロンプトを表示してエコーなしで(キータイプが表示されない状態で)ユーザに入力させパスワードを設定するようになっています。

コマンドラインからパスワードを指定できるようにしてしまうとパスワードが丸見えになってしまってコマンドの履歴とかターミナルのログとかいろんな所にパスワード文字列が平文で残ってしまってセキュリティ上よろしくないということでこうなっているのだと思います。

というわけでスクリプトでユーザ作成時にパスワードまで指定できるようにするには useradd コマンドを使用します。

といっても useradd コマンドも単純に平文ではパスワードを指定させてくれません。
useradd コマンドの -p オプションには、暗号化(ハッシュ)されたパスワードを指定する必要があります。

さて、そのハッシュの方法ですが、man によると crypt(3) を使って取得した値を指定するようにと書いてあります。

crypt(3) というのは、crypt() という関数のことで、コマンドラインから簡単に呼び出すことができません。C 言語のプログラムを書かないといけません。
Perl の crypt 関数は内部的に crypt(3) を呼んでいるようですのでそれを使って回避するやり方はあるようです。

useraddコマンド | ユーザー管理コマンド | ウナのLinux講座 | ウナのIT資格一問一答
http://una.soragoto.net/lecture/linux/user_cmd/useradd.html

ただ、上記の URL で示されている方法だと、POSIX 準拠ではあるのですがダイジェスト生成に DES が使われていて crack(1) で簡単に破られてしまうというのと、パスワード文字列の長さが 8 文字以上あっても 8 文字までしか使われないという問題があります。

そこで、Glibc2 以降の拡張を使って $id$salt$ というソルト(id は 1, 5, 6 などの数、salt は 16 文字以内の任意のランダムな文字列) を指定すると MD5 や SHA256, SHA512 といった暗号学的ハッシュが使えるので安全性が高まりパスワード文字列の長さの制限もなくなります。

ただ、これでもやはりパスワード文字列がコマンドラインに丸見えなので、それが気持ち悪いという場合はファイルにパスワードを書いておいてそれを読みこませるという方法を取る必要がでてきてだんだんワンライナーの範疇を超えてくる感じです。(Perl ならそれくらい簡単にできるかもしれませんが、、、)

また、適切な salt を選ぶのはなかなか難しい作業です。(ランダムな文字列を生成するワンライナーを書くという手はありますが・・・)


そこで、mkpasswd コマンドが使える環境(Ubuntu 12.04 では whois パッケージに mkpasswd が含まれています)では、perl によるワンライナーの代わりに mkpasswd コマンドを使うことをお勧めします。

mkpasswd コマンドは、標準入力もしくはファイルディスクリプタからパスワードを読み込ませてそれを適切なソルトをつけて -m オプションで指定した方法でハッシュしてくれるというコマンドです。

使い方は以下のようになると思います。

$ cat mypassword.txt | mkpasswd -s -m sha-512

$6$Tqd5rI9..0tS8Af$ZQkNOfrZpdw6tz1bvUZFyjmPmJ4OXhVILyUJCqF1gopahmc8L6xe9hZ62YyKYY1qeWLRqvVXXB97r6OCFlgFq/
という感じの文字列が表示されたら成功です。

mkpasswd コマンドの -s は標準入力からパスワード文字列を読み込むように指定するオプション、-m sha-512 は SHA 512 でハッシュすることを指定するオプションです。

これでパスワードをコマンドラインに晒すことなく、適切なソルトで強いハッシュでパスワードを保護することができました。

あとはこれを useradd コマンドに指定するだけです。

$ sudo useradd -p `cat mypassword.txt | mkpasswd -s -m sha-512` username

useradd の man を見ると、-p でパスワードを指定したアカウントはデフォルトではアクティブでないとされていますが、私の環境ではこれでこのユーザでログインできました。

また、試しに /etc/shadow の中身を見てみると、mkpasswd で生成された文字列が書きこまれているのがわかると思います。