いますぐ実践! Linuxシステム管理

[バックナンバーのトップへ] [Linux システム管理のトップへ]


いますぐ実践! Linux システム管理 / Vol.137 / 読者数:1339名

こんばんは、うすだです。

本は、図書館で借りるよりも買ったほうがよい、という意見を、 メルマガやブログなどで、よく拝見します。

図書館で借りると、お金がかからなくて経済的です。
しかし、その半面、ゆっくり読めないとか、本に書き込むことができないとか、 身銭を切っていないので真剣に読まない、などというデメリットが考えられます。

基本的には、わたしは、上記の意見に異論はありません。
ただ、分厚い本に限っては、少し事情が異なるように思います。

というのも、自分で購入した本は、いつでも読めると思ってしまうため、 いつまでたっても読み始めないか、途中で挫折してしまうのです。
(例: OS自作入門、パタヘネ本、サスマン本、…い、いつか読みますよ。)

逆に、図書館で借りると、返却期限がありますので、それまでに読まないといけない、 という後向きなモチベーション(?)により、買うよりも真剣に読むことができます。

という過去の前例を考慮して、先日、以下の本を借りてきました。
500ページ強を3週間で読破すべく、真剣にがんばろうと思います。
(ちなみに、Binary Hacksで紹介されていて、読もうと思った次第です。)

セキュリティウォリア - 敵を知り己を知れば百戦危うからず
http://www.amazon.co.jp/exec/obidos/ASIN/4873111986/usupiorg06-22

この調子でうまくいくのであれば、持っている本も、 図書館で借りてきてしまえばよいのではないか、ということになりそうですね。

…間違っていることを薄々感じつつ、今回も、はりきってまいりますよ!

今回のお題 - ユーザ情報を管理する

前回、mkpasswd コマンドを使って、パスワードを自動的に生成しつつ、 たくさんのユーザを一括登録するなどの方法を、ご紹介しました。

Vol.136 - パスワードを自動生成する
http://www.usupi.org/sysad/136.html

このあたりのネタは、大昔にもご紹介していますので、今回は潔く、 別の内容にしようかなと、最初は思いました。
ですが、ちょっと紹介し足りていないところもあり、 このまま新たな内容にしてしまうのは気がひけましたので、 続きをご紹介しようと思います。

というわけで今回は、以下の内容を、お送りしようと思っております。

  1. /etc/passwd や /etc/shadow の内容をまとめて管理する。
  2. mkpasswd コマンドで生成したパスワードを、各ユーザに知らせる。

上記になにも感じなかった貴兄は、宿題の答えへとお進みください…。


ユーザアカウントの情報を確認したいとき、 究極的には /etc/passwd と /etc/shadow ファイルを眺めればよいですが、 いかんせんパッと見て理解しにくい、という問題があります。

そんなときは、双方の内容をあわせて CSV ファイルにして、 某社表計算ソフトなどで眺めれば、わかりやすいのではないでしょうか。

思い立ったが吉日、そんな Perl スクリプトを作成してみました。

#!/usr/bin/perl
use strict;

my %passwd = &read_file("/etc/passwd");
my %shadow = &read_file("/etc/shadow");
foreach (sort keys %passwd) {
    my $p = $passwd{$_};
    my $s = $shadow{$_};
    if(!$ARGV[0] || length($$s[0]) > 4) {
        printf("%s,%s,%d,%d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
            $_, $$s[0], $$p[1], $$p[2], $$p[3], $$p[4],
            $$p[5], $$s[1], $$s[2], $$s[3], $$s[4],
            $$s[5], $$s[6], $$s[7]);
    }
}

sub read_file {
    my ($fname) = @_;
    my %ret;
    open(FILE, $fname) || die "cannot open $fname";
    while(<FILE>) {
        chomp;
        my @array = split(/:/);
        my $user = shift(@array);
        $ret{$user} = \@array;
    }
    close FILE;
    %ret;
}

/etc/passwd と /etc/shadow ファイルの中身を、 read_file という名のサブルーチンで読み込み、 それぞれ連想配列 %passwd と %shadow に情報を格納します。
あとは、foreach 文で、各情報を CSV 形式で出力するだけです。

read_file サブルーチンは、ユーザ名をキーとして、 ユーザ名以外の情報の配列を値とした連想配列を返します。

たとえば、上記スクリプトを、showuser.pl というファイル名で保存し、 実行しますと、以下のようになります。

  # chmod +x showuser.pl
  # ./showuser.pl
  adm,*,3,4,adm,/var/adm,/sbin/nologin,13257,0,99999,7,,,
  apache,!!,48,48,Apache,/home/httpd,/bin/false,13257,0,99999,7,,,
  avahi,!!,70,70,Avahi daemon,/,/sbin/nologin,13476,,,,,,
  bin,*,1,1,bin,/bin,/sbin/nologin,13257,0,99999,7,,,
  ...後略...

ただ、全部のユーザの情報を出力しますと、bin や ftp など、 特に確認する必要のないユーザも、わんさか得られてしまいます。
ですので、引数になにか指定すると、パスワードが4文字以下 (* とか NP とか *LK* など)のユーザを出力しないようにしておきました。

  # ./showuser.pl hoge
  root,$1$秘密,0,0,root,/root,/bin/bash,13257,0,99999,7,,,
  test,$1$教えない,10001,100,,/home/test,/bin/bash,13996,0,99999,7,,,
  usu,$1$明かさない,628,4,,/home/usu,/bin/bash,13671,0,99999,7,,,
  ...後略...

ちなみに、出力される CSV ファイルの内容は、以下の通りです。

- ユーザ名
+ 暗号化されたパスワード
- ユーザID
- グループID
- ユーザ情報(GECOS)
- ホームディレクトリ
- シェル
+ 最後にパスワードが変更された日(1970年1月1日からの日数)
+ パスワードが変更可能となるまでの日数
+ パスワードを変更しなくてはならなくなるまでの日数
+ パスワードの有効期限が来る前に、警告を発する日数
+ パスワードの有効期限が過ぎてから使用不能になるまでの日数
+ アカウントが使用不能になるまでの日数(1970年1月1日からの日数)
+ 予約フィールド

先頭が + の項目は、/etc/shadow の情報です。
これらは、すでにご紹介済ですので、詳しくは以下をご覧ください。

Vol.098 - パスワード変更していない日数をチェックする
http://www.usupi.org/sysad/098.html

で、リダイレクトしてファイルに保存したら、 表計算ソフトなどで開いてお好きなように処理してください。

  # ./showuser.pl hoge > user_20080518.csv

ただし、暗号化されているとはいえ、パスワードの情報を含みますので、 取扱いには十分ご注意ください。


さて、前回、mkpasswd コマンドを用いてユーザを作成しましたが、 生成したパスワードをお知らせしないと、使っていただくことができません。

もし、作成したユーザと同じユーザ名で、メールを受け取れる環境があるのでしたら、 そこへメールを送ればよいですよね。

そんな素敵なシチュエーションがあるだろうという前提で、 スクリプトを作成してみました。

#!/usr/bin/perl
use strict;
my $CONVERT = "/usr/bin/iconv -f EUC-JP -t ISO-2022-JP ";
my $SENDMAIL = "/usr/sbin/sendmail -oi ";
my $MAIL_FROM = "postmaster\@new.usupi.org";
my $TO_DOMAIN = "old.usupi.org";
while(<>) {
    chomp;
    my @array = split(/,/);
    if(open(MAIL, "|$CONVERT|$SENDMAIL $array[0]\@$TO_DOMAIN")) {
        print MAIL "From: $MAIL_FROM\nTo: $array[0]\@$TO_DOMAIN\n";
        print MAIL "Subject: $array[0] created\n";
        print MAIL "Mime-Version: 1.0\n";
        print MAIL "Content-type: text/plain;charset=iso-2022-jp\n\n";
        if($array[4]) {
            print MAIL "$array[4] さんへ\n\n";
        } else {
            print MAIL "$array[0] さんへ\n\n";
        }
        print MAIL "あなたのパスワードは $array[1] です。\n";
        print MAIL "すぐパスワードを変更してくださいねー。\n";
        close MAIL;
    } else {
        print STDERR "cannot send mail.\n";
    }
}

$MAIL_FROM にメールの送信元アドレスを、 $TO_DOMAIN に送信先アドレスのドメインの部分を指定してください。
また、日本語は EUC だという前提です。異なる場合は、 iconv の引数を適時変更してください。
そして、引数には、前回の一括ユーザ登録! で使用した CSV ファイルを指定します。

  # cat user001-100.csv
  user001,5ia4fAQk,501,500,User 001,/home/user001,/bin/bash
  user002,qi8clZC5,502,500,User 002,/home/user002,/bin/bash
  ...中略...
  user100,0Vkyu1Ow,600,500,User 100,/home/user100,/bin/bash

最初のユーザ名を送信先アドレスに使用して、 2つ目の生のパスワードをメールでお知らせします。
上記スクリプトを、sendpasswd.pl という名前で保存し、実行しますと、 各ユーザに、それぞれのパスワードをメールで知らせます。

  # chmod +x sendpasswd.pl
  # ./sendpasswd.pl user001-100.csv

ちなみに、以下のようなメールが届きます。

  From: postmaster@new.usupi.org
  To: user001@old.usupi.org
  Subject: user001 created

  User 001 さんへ

  あなたのパスワードは Xdjg04uU です。
  すぐパスワードを変更してくださいねー。

…とはいえ、そんな都合のいいシチュエーションがあるとは限りません。
あったとしても、メールにパスワードを直接記述するのは、 あまりお勧めできることではありません。(社内などのポリシーによりますが。)

それでは、テキストファイルを作成し、印刷して、みなさんにひっそりと配る、 というのではいかがでしょうか。
メールで送るのではなく、 テキストファイルを大量生成するスクリプトを書いてみました。

#!/usr/bin/perl
use strict;
my $CONVERT = "/usr/bin/iconv -f EUC-JP -t UTF-16 ";
while(<>) {
    chomp;
    my @array = split(/,/);
    if(open(TXT, "|$CONVERT > $array[0].txt")) {
        if($array[4]) {
            print TXT "$array[4] 殿\r\n\r\n";
        } else {
            print TXT "$array[0] 殿\r\n\r\n";
        }
        print TXT "あなたのパスワードは $array[1] です。\r\n";
        print TXT "すぐパスワードを変更してくださいねー。\r\n";
        print TXT "\r\n以上\r\n";
        close TXT;
    } else {
        print STDERR "cannot create.\n";
    }
}

引数に、先ほどと同じ CSV ファイルを指定します。
上記スクリプトを、mkpasswdtxt.pl という名で保存し、実行しますと、 ユーザ名.txt というテキストファイルを、大量に生成します。

  # chmod +x mkpasswdtxt.pl
  # ./mkpasswdtxt.pl user001-100.csv
  # ls -1 user*.txt
  user001.txt
  user002.txt
  ...中略...
  user100.txt
  # cat user001.txt
  User 001 殿

  あなたのパスワードは 5ia4fAQk です。
  すぐパスワードを変更してくださいねー。

  以上

日本語は、スクリプトが EUC、 出力するテキストファイルが UTF-16 だと仮定しています。異なる場合は、 先ほどと同様、iconv の引数を適時変更してください。

実際に印刷する手順は、環境によると思いますので、 申し訳ありませんが割愛させていただきます。Windows で行うなら、 VBScript などで自動化できてしまうかもしれませんですね。


以上、ユーザ情報を一括管理したり、パスワードをお知らせする方法などを、 お知らせしました。

前回同様、さまざまなシチュエーションが想定されますので、 そのままで使えないかもしれませんが、 叩き台として参考にすることはできると思います。

また、いずれも、パスワードなど大切な情報を扱いますので、 各ファイルのパーミッションには、ものすごくご注意くださいませ。
(極力、root か同等のユーザしか読み書きできないようにしましょう。)

宿題の答え

前回の宿題は、

  複数のユーザを一括で削除するスクリプトを作成しましょう。

でした。

自由度を考えず、ごそっと一括で消すなら、こんな感じでしょうか。

#!/bin/sh
[ $# -eq 1 ] && TOTAL=$1 || TOTAL=100
num=1
while [ $num -le $TOTAL ]; do
    user=`printf "user%03d" $num`
    `userdel -r $user` && echo "$user deleted"
    num=`expr $num + 1`
done

引数なしで実行しますと、user001〜user100 を、一括削除します。
引数に数字を指定すると、user001 から、指定した番号のユーザまで削除します。

あるいは、引数で指定したユーザを削除するなら、以下の通りです。

#!/bin/sh
while [ $# -gt 0 ]; do
    `userdel -r $1` && echo "$1 deleted"
    shift
done

引数を、そのまま userdel コマンドに渡しているだけ、ですね。

さらにあるいは、一括登録で使用した CSV ファイルを使って、一括削除を行うなら、 以下のようになります。

#!/bin/sh
IFS=','
while read acct pass uid gid gcos hdir shell; do
    `userdel -r $acct` && echo "$acct deleted"
done

実行時に CSV ファイルをリダイレクトすると、ごそっと読み出し、 先頭のユーザ名だけを userdel コマンドに渡します。それだけです。

以上、簡単ではありますが、いろんな解答例を、ご紹介しました。
上記を踏み台にして、いろいろカスタマイズしてみてくださいませ。

今回の宿題

今回の宿題は、

  CSV ファイルから、ユーザを復元するスクリプトを作りましょう。

です。

うっかり userdel してしまったのだけれど元に戻したいとか、 丁稚奉公に行っていたあのひとが帰ってきたのでとか、 いくつかシチュエーションは考えられると思います。

手元に情報が残っていれば、 useradd コマンドなどで復元することも可能ではないかと思います。そんなものを、 考えてみてくださいませ。

あとがき

おもむろに Open Tech Press を眺めていたところ、 Web Console とやらの紹介記事を見つけました。

Open Tech Press | Web Consoleで行うリモート操作でのサーバ管理
http://opentechpress.jp/opensource/08/05/12/0150242.shtml

Web Console
http://www.web-console.org/

Ajax を使って、ブラウザ上でサーバのシェルを使ってしまおうという、 なんとも豪儀なコンセプトをお持ちのソフトのようです。

基本的には、単体の CGI だけで動きますので、設定手順は簡単です。

上記のページから ZIP ファイルを得て(あるいは subversion で入手)、 httpd が読み書きできて、CGI が動作して、 かつ .htaccess を解釈してくれるディレクトリの下に展開します。

そしてあとは、CGI にアクセスして、簡単な設定を行えば、 ブラウザ上でシェルがさくさく動作するようになります。

CGI ですので、Web Console でできることは、httpd ができることに限定されます。 ですが、sudo コマンドを使えば、その壁をとっぱらうことが可能です。
(Web Console 上ではパスワードが入力できないため、 パスワードなしで sudo できる設定にする必要があります。 お試しならよいと思いますが、実運用で設定される際には、 ものすごく熟考してくださいまし。)

なにはともあれ、設定は比較的艦単ですので、さくっとシェルが動くさまを、 実際に見てみてくださいませ。

 

いまどき、VNC などもブラウザ上で動いてしまいますので、 それほど驚愕ではないかもしれませんが、 やりとりするデータが文字だけで済みますので、 他よりもさくさくと快適に動作するというメリットはありそうです。
しかし、それよりも、動く様子を体験しているうちに、なにか自分でも、 かゆいところに手が届く的なものが作れるのではなかろうか、 という気分にさせられたことのほうが、私的には収穫だったと思います。

ここのところ、仕事以外ではなにも作っていませんでしたので、 ぼちぼちなにか作りたいなあと、いい感じに創作意欲をかきたてられました。

 

それはさておき、Debian の OpenSSL の脆弱性の問題が、 あちこちに波及しているようですね。

Debian そのものだけでなく、Debian 上で生成した SSH の鍵や、 SSL の証明書も問題になります。
(つまり、Debian から SSH などでログインされたことのあるサーバも、 問題になる可能性があります。)
ですので、少しでも関連すると思われる貴兄は、下記の情報をよく読み、 対策を施してくださいませ。

OpenSSL パッケージの脆弱性とその影響について (SSH鍵、SSL証明書等)
http://www.debian.or.jp/blog/openssl_package_and_its_vulnerability.html

試しに、手元のノート(Vine)で確認したところ、なんと見つかりました。

  % ./dowkd.pl file .ssh/known_hosts 
  .ssh/known_hosts:50: weak key
  .ssh/known_hosts:54: weak key
  summary: keys found: 56, weak keys: 2

とはいえ、いずれも今はなきマシンでしたので、 問題の行をさくさくっと削除するだけで済みました。
…とまあ、関係なさそうなマシンでも、意外と見つかります。心当たりがなくても、 念のため確認してみるとよろしいのではないでしょうか。

 

今回も、ここまで読んでいただき、ありがとうございました。
それでは、次回は 6月1日(日) 頃に、お会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」− グッズを作って広めたい病にかかったかもしれません…。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本