0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Linuxでユーザー追加と公開鍵設置を行うスクリプト

Posted at

公開鍵認証でのユーザー追加

クラウド上のサーバなどを設置した際に、ユーザー認証は公開鍵認証のみを許可している場合も多いと思います。というかそうした方がよいです。
ただ、多人数が使う場合に公開鍵設置は結構面倒な作業になるのでスクリプト作りたいなぁと思っていました。で、作りました。
本当にちゃんと運用する場合はLDAPとかを考えた方が良いです。

仕組み

Ubuntuだとユーザ追加のコマンドとしてadduserが用意されていて対話形式で追加できますが、この場合だと公開鍵を手動で置く必要があります。
一方でLinuxで用意されているuseraddコマンドであればオプションを組み合わせていろいろできます。
ぶっちゃけadduserコマンドでもいろいろできそうですけど、useraddで作ったのでadduserのことは忘れてください。

公開鍵の設置

基本的な話ですが、公開鍵(id_rsa.pub)を置く場所は~/.ssh/authorized_keysです。
新しいユーザを作ったら、ホームディレクトリの下に.sshディレクトリを作って、その下にauthorized_keysの名前でid_rsa.pubをコピーすれば良いです。面倒ですね。
useraddコマンドにはskellという機能があります。

skell機能を使う

skell機能は、簡単に言うと新ユーザのホームディレクトリをコピーして作ってくれる機能です。
-kでディレクトリを指定します。そうするとそのディレクトリのファイルをコピーしてくれるのです。
つまり、useraddする前に公開鍵をskellディレクトリへコピーしておいてuseraddすればいいのです。
結局コピーするなら、useraddした後にシェルスクリプトで追加しても一緒って思いがちですが、ファイルの権限とか所有者とか考えるとskell使った方が良いです。

スクリプト第一弾

てことでまずはこんなシェルスクリプトを考えてみました。

# !/bin/sh

if [ $# != 2 ]; then
  echo Usage: $0 username pubkey
  exit 1
fi

cp $2 skell/.ssh/authorized_keys || exit 1
sudo useradd -m -k skell $1

使い方は第一引数がユーザー名、第二引数が公開鍵ファイルパスになります。
実行する場所のskell/.sshディレクトリが作られていることが前提です。
ファイルが無いなどのエラーの場合は末尾の|| exit 1が働いて強制終了します。
この書き方便利なので重宝します。

これで目的の8割は達成しましたが、もうちょっと運用考えます。

ユーザー追加フロー

このスクリプトだとユーザー名と公開鍵を貰って、スクリプトを叩く必要がありますが、容易に想像できるのがみんなid_rsa.pubのファイルを送ってきて、それを取り違えてユーザー作ってしまうという運用ミスです。
ファイルを間違えて上書きする危険もあれば、コマンドを叩くときに間違える可能性もあります。
この危険性をなくすためにやることは1つです。

  • 公開鍵は希望するユーザー名で送って貰う

hogeというユーザ名を希望するなら、公開鍵をhogeという名前に変えてから送って貰います。
hogeというファイルはpubsとかのディレクトリに格納して、それを指定することでユーザ追加するようにしましょう。

スクリプト第2弾

さて、こんな感じになります。

# !/bin/sh
if [ $# != 1 ];then
  echo Usage: $0 username_pubkey_path
  exit 1
fi

username=`basename $1`
cp $1 skell/.ssh/authorized_keys || exit 1
sudo useradd -m -k skell ${username}

使うときは./add.sh pubs/hogeといった形で指定します。
basenameでファイル名を取得できるのでそれをそのままユーザー名にします。

もうちょっとだけ

もうほぼ目的は達成しましたが、この方法で追加したユーザーにはパスワードが設定されていません。
公開鍵でssh認証のみを指定している場合はパスワードを使う場面がない・・・と思いきや、例えばchshするときとか、権限を貰ってsudoするときとかに困ります。
useraddにはパスワードを引数で指定できますが、cryptのハッシュ値を入れないといけないのでちょっと面倒です。

パスワードを作る

平文のパスワードを、ハッシュ化された文字列に変換しましょう。
ハッシュ化に必要なのは元の平文と、ソルトの値になります。
ソルトを指定しないでみんながハッシュ値を使っていると、ハッシュ値を比較しただけで「こいつ、ここのパスワードとここのパスワード一緒やん!」ってなるのでソルトが必要です。
ただ、ランダムでいいのでランダム文字列を生成します。

salt=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -1`

これでソルトが作れます。
パスワードは下記のようにして作れます。

cmd="perl -e 'print crypt(\"${username}\", \"\\\$6\\\$${salt}\");'"
pass=`eval ${cmd}`

コマンド内に引数埋め込むのどうすんだっけ?っていうのを忘れたのでevalしました。1行で書けると思います。そのうち直します。
これをuseradd-pオプションで指定すれば完成です。

シェルスクリプト:最終形態

ということで下記のようになります。

# !/bin/sh
if [ $# != 1 ];then
  echo Usage: $0 username_pubkey_path
  exit 1
fi

username=`basename $1`
salt=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -1`
cmd="perl -e 'print crypt(\"${username}\", \"\\\$6\\\$${salt}\");'"
pass=`eval ${cmd}`

cp $1 skell/.ssh/authorized_keys || exit 1
sudo useradd -m -k skell -p ${pass} ${username}

他にも最初から設置したいファイルがあればskellの下に置けば良いので、適宜アレンジしてみてください。

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?