2015/10/30

Happy birthday for my dearest.


Dear Princess, may you have a great and happy life ahead. We are always with you. I wish you a very Happy Birthday. Enjoy.

2015/10/01

Shuca (朱夏) - 日本語対応のサマライザ

MOONGIFTで紹介されていた Shuca という日本語に対応したサマライザを試してみた。
サマライザとは文章を解析し重要な部分だけを抜き出してくれる要約エンジンの事で、 この処理が自動で実施できると非常に便利になりそうなので 早速 CentOS 6.6 に Shucha を導入してみる。

Shuca は予め分かち書きや構文解析された文章を入力ソースとして受け付ける。 そのため、別途、形態素解析システムの JUMAN や 日本語構文・格・照応解析システムの KNP が必要となるので それらのツールも同時にインストールする。

Shuca のインストール
Shuca 本体は Python で記述されており GitHub でソースが公開されている。 基本的にインストール作業は不要で GitHub からダウンロードしたファイルを任意のディレクトリに展開すれば良い。
今回は /usr/local 以下に全てのファイルを展開し、 実行可能ファイルは /usr/local/bin 以下に設置した。
$ wget https://github.com/hitoshin/shuca/archive/master.zip
$ unzip master.zip
$ sudo mkdir -p /usr/local/{bin,libexec,dic}
$ sudo cp -p shuca-master/lib/* /usr/local/bin/.
$ sudo cp -p shuca-master/dic/* /usr/local/dic/.
$ sudo cp -p shuca-master/libexec/* /usr/local/libexec/.
            
インストールが終了したら同梱されているサンプルデータで動作を確認する。
$ Shuca.py < shuca-master/dat/sample.knp.txt 
JR東海は4月16日、山梨リニア実験線で同日に行ったL0系の高速有人走行試験において、590キロメートル毎時を記録したと発表した。
2003年12月2日に同社のMLX01形が記録した鉄道の世界最高速度、581キロメートル毎時を11年4ヶ月ぶりに9キロメートル毎時更新する形となった。
JR東海は、「今後も開業に向けさまざまな試験を行っていく」とコメントしている。
            
JUMAN のインストール
JUMAN は京都大学 大学院情報学研究科の黒崎・河原研究室が開発した日本語形態素解析システムで、 日本語の文章を形態素ごとに分かち書きし品詞などの情報を付加している。
$ wget http://nlp.ist.i.kyoto-u.ac.jp/nl-resource/juman/juman-7.01.tar.bz2
$ tar xvf juman-7.01.tar.bz2
$ cd juman-7.01
$ ./configure --prefix=/usr/local
$ make
$ sudo make install
            
KNP のインストール。
KNP も京都大学 大学院情報学研究科の黒崎・河原研究室が開発した日本語構文・格・照応解析システムで、 JUMAN で解析された結果から文節および基本句間の係り受け関係、格関係、照応関係を出力する。
KNP は zlib を利用しているので、予め zlib のインクルードファイル、ライブラリ等をインストールしておく。
$ sudo yum -y install zlib-devel
$ wget http://nlp.ist.i.kyoto-u.ac.jp/nl-resource/knp/knp-4.14.tar.bz2
$ tar xvf knp-4.14.tar.bz2
$ cd knp-4.14
$ ./configure --prefix=/usr/local --with-juman-prefix=/usr/local
$ make
$ sudo make install
            
動作の確認
これらがインストールできたら Shuca に同梱されているデータで動作の検証を実施する。
$ juman < shuca-master/dat/sample.snt.txt | knp 
# S-ID:1 KNP:4.14-CF1.1 DATE:2016/03/04 SCORE:-63.73058
                                JR──┐     
                                      東海は──┐ 
                  4──┐           │ 
                          月──┐       │ 
                                16──┐   │ 
                                        日、──┤ 
        山梨──┐               │ 
              リニア──┐           │ 
                        実験──┐       │ 
                                線で──┐   │ 
      同日に──┐           │   │ 
              行った──┐       │   │ 
        L0──┐   │       │   │ 
                系の──┤       │   │ 
高速──┐       │       │   │ 
        有人──┐   │       │   │ 
                走行──┤       │   │ 
                      試験に──┐   │   │ 
                            おいて、──┤   │ 
                      590──┐   │   │ 
                キロメートル──┤   │   │ 
                              毎時を──┤   │ 
                                  記録したと──┤ 
                                          発表した。
EOS
    :
    :
    :
            
これで必要なツール類のインストールは完了した。

ここまで動作が確認できたら php を利用して簡単な動作検証環境を作成する。
Shcha に附属されていたサンプルデータから KNP の実行時オプションは "-simple -normal" だと推察してみた。
この php スクリプトは入力された URL からコンテンツを取得して jUMAN で形態素解析を実施してKNP で構文解析を実施した上で Shcha を実行して要約を取得する。
下準備として改行コードの統一、HTML タグの除去、空行や空白のサプレス、 更に KNP の制限により半角文字を全角文字に変換している。
あくまでも動作サンプルのためのスクリプトなので、 エラー処理や html entity の処理など実施していない。

  1<html>
  2    <head>
  3        <title>
  4            shuca 要約
  5        </title>
  6    </head>
  7    <body>
  8        <center>
  9<?php
 10    mb_internal_encoding("UTF-8");
 11
 12    define("juman",     "/usr/local/bin/juman");
 13    define("knp",       "/usr/local/bin/knp -simple -normal -cf-cache");
 14    define("shuca",     "/usr/local/bin/Shuca.py -l 500 ");
 15
 16    if(strlen(($url = $_REQUEST["url"]))){
 17        print "$url<br><br>";
 18
 19        $start = gettime();
 20
 21        $content =
 22            mb_convert_kana(                                                            /* 半角文字を全角に変換 */
 23                preg_replace("/ +/", " ",                                               /* 複数のスペースを1個に置換 */
 24                    preg_replace("/^ *\n/m", "",                                        /* 空行を削除 */
 25                        strip_tags(                                                     /* html タグを削除 */
 26                            preg_replace('!<style.*?>.*?</style.*?>!is', '',            /* <style> タグとその内容を削除 */
 27                                preg_replace('!<script.*?>.*?</script.*?>!is', '',      /* <script> タグとその内容を削除 */
 28                                    str_replace("\r", "",                               /* CR を削除 */
 29                                        file_get_contents($url))))))), "ASKV");
 30
 31        $buf = "";
 32        $desc = array(
 33            0 => array("pipe", "rb"),                   /* stdin: pipe */
 34            1 => array("pipe", "wb"),                   /* stdout: pipe */
 35            2 => array("file", "/dev/null", "w"),       /* stderr: /dev/null */
 36        );
 37
 38        if($pp = proc_open(sprintf("%s | %s | %s", juman, knp, shuca), $desc, $pipe)){
 39            fwrite($pipe[0], $content);
 40            fclose($pipe[0]);
 41
 42            while(!feof($pipe[1]))
 43                $buf .= nl2br(fread($pipe[1], 1024));
 44            fclose($pipe[1]);
 45
 46            proc_close($pp);
 47
 48            print <<< EOF
 49                {$buf}
 50EOF
 51            ;
 52            printf("処理時間: %f 秒", gettime() - $start);
 53        }
 54    }
 55    else{
 56        print <<< EOF
 57                <form>
 58                    <input type='text' name='url' size='50'>
 59                    <input type='submit' value='要約'>
 60                </form>
 61EOF
 62        ;
 63    }
 64
 65function    gettime()
 66{
 67
 68    $t = gettimeofday();
 69    return((float)($t["sec"] + $t["usec"] / 1000000.0));
 70
 71}
 72
 73    
 74?>
 75        </center>
 76    </body>
 77</html>
    

Image: img_20151001.png

実行結果
KNP の実行に結構時間がかかっている様だが、 入力ソースを適切に編集する事で実用的な要約が取得できる様だ。

2015/09/03

国別フィルタの自動生成ツール (CentOS 版)

以前 FreeBSD 版の 国別フィルタの自動生成ツール を紹介したのだが、 最近 CentOS でもサーバを運用しているので CentOS 版を作成したので公開する事にした。 機能は FreeBSD 版同様 APNIC から IPアドレスの割当リストを取得して、 IPアドレスを CIDR 型式に修正した上で iptables (8) のコマンドラインパラメタを自動生成している。
今回は /etc/init.d/iptables を実行してフィルタを初期化した上で、 state RELATED,ESTABLISHED が含まれる行の次の行にルールの追加までを実行する。

  1#!/usr/bin/perl
  2# KRフィルタ
  3use Socket;
  4
  5# 拒否する国コード
  6@country = ('KR', 'CN');
  7# IPアドレス一覧取得URL
  8$url = "http://ftp.apnic.net/stats/apnic/delegated-apnic-latest";
  9
 10# iptables 初期化
 11system("/etc/init.d/iptables restart");
 12
 13# 挿入位置を取得 (接続済みパケットは許可する設定の次に挿入)
 14if(open(IN, "iptables -L INPUT --line-number|")){
 15    while(<IN>){
 16        if(/^(\d+).*RELATED,ESTABLISHED.*/){
 17            $rule = $1 + 1;
 18            last;
 19        }
 20    }
 21    close(IN);
 22}
 23
 24# 初期処理
 25foreach $i (@country){
 26    $country{$i} = 1;
 27}
 28
 29if(open(IN, "wget -q -O - $url|")){
 30    while(<IN>){
 31        if(/^apnic\|(..)\|ipv4\|(\d+.\d+.\d+.\d)\|(\d+)/){
 32            if($country{$1}){
 33                $table{inet_aton($2)} = $3;
 34            }
 35        }
 36    }
 37    close(IN);
 38
 39    # IPアドレス一覧を CIDR 型式に変換
 40    foreach $net (sort keys %table){
 41        $addr = unpack('N', $net);
 42        $num = $table{$net};
 43        while($num == $num[0] && ($addr ^ $addr[0]) == $num){
 44            shift @addr;
 45            shift @num;
 46            $addr &= ~$num;
 47            $num <<= 1;
 48        }
 49        unshift(@addr, $addr);
 50        unshift(@num, $num);
 51    }
 52
 53    # iptables 実行
 54    while (@addr){
 55        for($num = pop(@num), $mask = 32; $num > 1; $num >>= 1, $mask--){}
 56        $filt = inet_ntoa(pack('N', pop(@addr))) . "/$mask";
 57        system("iptables -I INPUT $rule -s $filt -j DROP");
 58        $rule++;
 59    }
 60}
 61
 620;
    

2015/08/27

Coleman Exponent Fyrestorm Ti Stove

eBay で Coleman Exponent Fyrestorm Ti Stove を落札。

Image: fyrestorm1.jpg

Fyrestorm Ti Stove
日本では発売されなかったマルチフューエルタイプのストーブで、 一般的なホワイトガソリンは勿論、自動車用の無鉛ガソリン、 更にはアウトドアカートリッジのガス缶も燃料として利用できる優れもの。

10年ほど前に既に製造中止されてしまった製品なのだが、 今回 eBay に「新品未使用、付属品もほぼ完備」という、 いわゆるミントコンディションで出品されていたので迷わず落札。
現在 eBay ではキャンプ用のストーブなどは日本に発送していないとの事なので、 既に何度かお世話になっている スピアネット の転送サービスを利用して取り寄せ。

Image: fyrestorm2.jpg

Fyrestorm Ti Stove
米国内の送料は無料だったので日本への転送費用のみが落札代金に加算されてしまうが、 それでも当時の定価 ($199.99) よりも格安にて入手できた。

自宅に届いた商品を早速開梱してみると説明通りに新品未使用のストーブでした。
この製品は名前の通りバーナーや五徳にチタンを利用しているので、 一度でも着火するとチタン特有の青系の色に焼けてしまうのだが、 本当に未使用・未着火の状態で届いて大満足。
この辺はアメリカ人は大げさに表現する傾向なので実はあまり信頼していなかった…
サービスパーツとして附属されていたOリングやチェックバルブ用のゴムボール、 風よけやヒートシールドなど付属品も殆ど全て揃っていて大満足。

Image: fyrestorm3.jpg

Fyrestorm Ti Stove

今年のキャンプの強力な武器になりそう…と思っていたのですが、 あまりにも綺麗な状態だったので使うのが勿体ないという…困った(笑

Image: fyrestorm4.jpg

Fyrestorm Ti Stove

2015/08/26

CentOS 6 に rssh を導入する

rsshssh (1) を利用したアクセスのうち scp (1) や sftp (1) といった 特定のコマンドのみの実行を許可したり chroot 環境を提供するログインシェルで、 セキュアなファイル転送は提供したいがシェルアカウントへの ログインを拒否したい場合などに非常に有効なログインシェルだ。
scp (1) や sftp (1) のみの実行を許可する場合は アカウントのログインシェルを rssh に変更して 設定ファイルで実行を許可するコマンドを指定するだけで設定は完了する。
しかし chroot 環境を提供する場合はそのための環境設定が必要である。

rssh のインストール
CentOS 6 では yum (1) から導入可能
$ sudo yum -y install rssh
    :
    :
    :
インストール:
  rssh.x86_64 0:2.3.4-1.el6

完了しました!
            
設定ファイルの編集
ssp (1)、sftp (1) のアクセスを許可し、 chroot するディレクトリを指定する。
# This is the default rssh config file

# set the log facility.  "LOG_USER" and "user" are equivalent.
logfacility = LOG_USER

# Leave these all commented out to make the default action for rssh to lock
# users out completely...

allowscp                                # scpを許可
allowsftp                               # sftpを許可
#allowcvs
#allowrdist
#allowrsync

# set the default umask
umask = 022

# If you want to chroot users, use this to set the directory where the root of
# the chroot jail will be located.
#
# if you DO NOT want to chroot users, LEAVE THIS COMMENTED OUT.
chrootpath = /opt/chroot                 # chroot先ディレクトリ

# You can quote anywhere, but quotes not required unless the path contains a
# space... as in this example.
#chrootpath = "/usr/local/my chroot"

##########################################
# EXAMPLES of configuring per-user options
    :
    :
    :
            
chroot 環境の初期設定
rssh に附属のスクリプトで chrrot 環境の初期構築を行う。
いくつかエラーが表示されるがここでは気にしなくても大丈夫
$ sudo sh /usr/share/doc/rssh-2.3.4/mkchroot.sh /opt/chroot
NOT changing owner of root jail. 
NOT changing perms of root jail. 
setting up /opt/chroot/usr/bin
setting up /opt/chroot/usr/libexec/openssh
setting up /opt/chroot/usr/libexec
Copying libraries for /usr/bin/scp.
    (0x00007fff541ff000)
cp: cannot stat `(0x00007fff541ff000)': そのようなファイルやディレクトリはありません
    /usr/lib64/libcrypto.so.10
    /lib64/libutil.so.1
    /lib64/libz.so.1
    /lib64/libnsl.so.1
    /lib64/libcrypt.so.1
    /lib64/libresolv.so.2
    /lib64/libgssapi_krb5.so.2
    /lib64/libkrb5.so.3
    /lib64/libk5crypto.so.3
    /lib64/libcom_err.so.2
    /usr/lib64/libnss3.so
    /lib64/libc.so.6
    /lib64/libdl.so.2
    /lib64/libfreebl3.so
    /lib64/libkrb5support.so.0
    /lib64/libkeyutils.so.1
    /lib64/libpthread.so.0
    /usr/lib64/libnssutil3.so
    /lib64/libplc4.so
    /lib64/libplds4.so
    /lib64/libnspr4.so
    /lib64/libselinux.so.1
    /lib64/librt.so.1
Copying libraries for /usr/libexec/openssh/sftp-server.
    (0x00007fff577f1000)
cp: cannot stat `(0x00007fff577f1000)': そのようなファイルやディレクトリはありません
    /usr/lib64/libcrypto.so.10
    /lib64/libutil.so.1
    /lib64/libz.so.1
    /lib64/libnsl.so.1
    /lib64/libcrypt.so.1
    /lib64/libresolv.so.2
    /lib64/libgssapi_krb5.so.2
    /lib64/libkrb5.so.3
    /lib64/libk5crypto.so.3
    /lib64/libcom_err.so.2
    /usr/lib64/libnss3.so
    /lib64/libc.so.6
    /lib64/libdl.so.2
    /lib64/libfreebl3.so
    /lib64/libkrb5support.so.0
    /lib64/libkeyutils.so.1
    /lib64/libpthread.so.0
    /usr/lib64/libnssutil3.so
    /lib64/libplc4.so
    /lib64/libplds4.so
    /lib64/libnspr4.so
    /lib64/libselinux.so.1
    /lib64/librt.so.1
Copying libraries for /usr/bin/rssh.
    (0x00007fff00bff000)
cp: cannot stat `(0x00007fff00bff000)': そのようなファイルやディレクトリはありません
    /lib64/libc.so.6
Copying libraries for /usr/libexec/rssh_chroot_helper.
    (0x00007fff3e152000)
cp: cannot stat `(0x00007fff3e152000)': そのようなファイルやディレクトリはありません
    /lib64/libc.so.6
copying name service resolution libraries...
tar: メンバ名から先頭の `/' を取り除きます
tar: /lib/libnss_files*: stat 不能: そのようなファイルやディレクトリはありません
tar: /lib/libnss1_files*: stat 不能: そのようなファイルやディレクトリはありません
tar: 前のエラーにより失敗ステータスで終了します
Setting up /etc in the chroot jail
cp: omitting directory `/etc/ld.so.conf.d'
Chroot jail configuration completed.

NOTE: if you are not using the passwd file for authentication,
you may need to copy some of the /lib/libnss_* files into the jail.

NOTE: you must MANUALLY edit your syslog rc script to start syslogd
with appropriate options to log to /opt/chroot/dev/log.  In most cases,
you will need to start syslog as:

   /sbin/syslogd -a /opt/chroot/dev/log

NOTE: we make no guarantee that ANY of this will work for you... if it
doesn't, you're on your own.  Sorry!
            
/dev/null の作成
附属のスクリプトでメッセージに表示されている処理、 エラーで完結できなかった処理などを実行して環境を構築する。
まず chroot 環境に /dev/null を作成する。
$ ls -l /dev/null
crw-rw-rw-. 1 root root 1, 3  8月 26 10:58 2015 /dev/null
$ sudo mknod /opt/chroot/dev/null c 1 3
$ sudo chmod 666 /opt/chroot/dev/null
$ ls -l /opt/chroot/dev/null
crw-rw-rw-. 1 root root 1, 3  8月 26 11:59 2015 /opt/chroot/dev/null
            
ライブラリのコピー
次に エラーメッセージから ldd (1) で参照されたライブラリのうち いくつかがコピーできていない事が確認できる。
chroot 環境にコピーされるのは以下のコマンドなので、 それぞれのコマンドの ldd の結果を参照して 不足しているライブラリをコピーする。
  • /usr/bin/scp
  • /usr/libexec/openssh/sftp-server
  • /usr/bin/rssh
  • /usr/libexec/rssh_chroot_helper
ldd の出力結果からコピーが必要なライブラリを決定しているのだが linux-vdso.so.1ld-linux-x86-64.so.2 は 表示形式が通常と異なっているためにコピーできていない様。
$ ldd /usr/bin/scp
        linux-vdso.so.1 =>  (0x00007ffef53f0000)
        libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007fbd8e06a000)
        libutil.so.1 => /lib64/libutil.so.1 (0x00007fbd8de67000)
        libz.so.1 => /lib64/libz.so.1 (0x00007fbd8dc50000)
        libnsl.so.1 => /lib64/libnsl.so.1 (0x00007fbd8da37000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fbd8d800000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fbd8d5e5000)
        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fbd8d3a1000)
        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fbd8d0ba000)
        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fbd8ce8d000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fbd8cc89000)
        libnss3.so => /usr/lib64/libnss3.so (0x00007fbd8c94a000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fbd8c5b5000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fbd8c3b1000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007fbd8c1ae000)
        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fbd8bfa2000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fbd8bd9f000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fbd8bb82000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fbd8e662000)
        libnssutil3.so => /usr/lib64/libnssutil3.so (0x00007fbd8b955000)
        libplc4.so => /lib64/libplc4.so (0x00007fbd8b750000)
        libplds4.so => /lib64/libplds4.so (0x00007fbd8b54c000)
        libnspr4.so => /lib64/libnspr4.so (0x00007fbd8b30d000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fbd8b0ee000)
        librt.so.1 => /lib64/librt.so.1 (0x00007fbd8aee5000)
$ ldd /usr/libexec/openssh/sftp-server
        linux-vdso.so.1 =>  (0x00007ffe2abcf000)
        libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007fbca7520000)
        libutil.so.1 => /lib64/libutil.so.1 (0x00007fbca731d000)
        libz.so.1 => /lib64/libz.so.1 (0x00007fbca7106000)
        libnsl.so.1 => /lib64/libnsl.so.1 (0x00007fbca6eed000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fbca6cb6000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fbca6a9b000)
        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fbca6857000)
        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fbca6570000)
        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fbca6343000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fbca613f000)
        libnss3.so => /usr/lib64/libnss3.so (0x00007fbca5e00000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fbca5a6b000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fbca5867000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007fbca5664000)
        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fbca5458000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fbca5255000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fbca5038000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fbca7b18000)
        libnssutil3.so => /usr/lib64/libnssutil3.so (0x00007fbca4e0b000)
        libplc4.so => /lib64/libplc4.so (0x00007fbca4c06000)
        libplds4.so => /lib64/libplds4.so (0x00007fbca4a02000)
        libnspr4.so => /lib64/libnspr4.so (0x00007fbca47c3000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fbca45a4000)
        librt.so.1 => /lib64/librt.so.1 (0x00007fbca439b000)
$ ldd /usr/bin/rssh
        linux-vdso.so.1 =>  (0x00007ffffe781000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f823c297000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f823c630000)
$ ldd /usr/libexec/rssh_chroot_helper
        linux-vdso.so.1 =>  (0x00007fffb99e9000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fde8f0ff000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fde8f498000)
$ ls -1 /opt/chroot/lib64
libc.so.6
libcom_err.so.2
libcrypt.so.1
libdl.so.2
libfreebl3.so
libgssapi_krb5.so.2
libk5crypto.so.3
libkeyutils.so.1
libkrb5.so.3
libkrb5support.so.0
libnsl.so.1
libnspr4.so
libplc4.so
libplds4.so
libpthread.so.0
libresolv.so.2
librt.so.1
libselinux.so.1
libutil.so.1
libz.so.1
            
linux-vdso.so.1 は各プログラムのアドレス空間のみに常駐する Virtual Dynamic Shared Object なので実体は存在しなくて問題ない。 それ以外に不足しているライブラリ(今回はld-linux-x86-64.so.2) を chroot 環境にコピーする。
検証のための chroot 環境の構築
この後の作業は実際に chroot 環境で作業するとエラー内容が分かりやすいので chroot して解析作業ができる様最低限の環境を構築する。
なおここで設定したファイルは後に削除する事。
# 不足しているライブラリをコピー
$ sudo cp -p /lib64/ld-linux-x86-64.so.2 /opt/chroot/lib64
# /bin/bash の実行を可能に
$ sudo mkdir /opt/chroot/bin
$ sudo cp -p /bin/bash /opt/chroot/bin/
$ sudo cp -p /lib64/libtinfo.so.5 /opt/chroot/lib64
# /usr/bin/ldd の実行を可能に
$ sudo cp -p /usr/bin/ldd /opt/chroot/usr/bin
$ sudo cp -p /bin/cat /opt/chroot/bin
# /usr/bin/strace の実行を可能に
$ sudo cp -p /usr/bin/strace /opt/chroot/usr/bin
            
chroot 環境での動作確認
構築した chroot 環境で動作を確認する。
scp (1) でアカウント情報を正しく取得できていない事が確認できる。
strace (1) で動作を確認してみると /lib64/libnss_files.so.2open (2)エラーになっている事が判る。
# chroot /opt/chroot /bin/sh
# 必要なライブラリーを確認
# ldd /usr/bin/scp
        linux-vdso.so.1 =>  (0x00007fff00345000)
        libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007f2b2ca5b000)
        libutil.so.1 => /lib64/libutil.so.1 (0x00007f2b2c858000)
        libz.so.1 => /lib64/libz.so.1 (0x00007f2b2c641000)
        libnsl.so.1 => /lib64/libnsl.so.1 (0x00007f2b2c428000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f2b2c1f1000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f2b2bfd6000)
        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f2b2bd92000)
        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f2b2baab000)
        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f2b2b87e000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f2b2b67a000)
        libnss3.so => /usr/lib64/libnss3.so (0x00007f2b2b33b000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f2b2afa6000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f2b2ada2000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007f2b2ab9f000)
        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f2b2a993000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f2b2a790000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f2b2a573000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f2b2d053000)
        libnssutil3.so => /usr/lib64/libnssutil3.so (0x00007f2b2a346000)
        libplc4.so => /lib64/libplc4.so (0x00007f2b2a141000)
        libplds4.so => /lib64/libplds4.so (0x00007f2b29f3d000)
        libnspr4.so => /lib64/libnspr4.so (0x00007f2b29cfe000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f2b29adf000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f2b298d6000)
# /usr/bin/scp -t .
unknown user 0
# strace  /usr/bin/scp -t .
    :
    :
    :
open("/lib64/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib64/tls/x86_64/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib64/tls/x86_64", 0x7ffc3cabffb0) = -1 ENOENT (No such file or directory)
open("/lib64/tls/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib64/tls", 0x7ffc3cabffb0)      = -1 ENOENT (No such file or directory)
open("/lib64/x86_64/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib64/x86_64", 0x7ffc3cabffb0)   = -1 ENOENT (No such file or directory)
open("/lib64/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib64", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/usr/lib64/tls/x86_64/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/tls/x86_64", 0x7ffc3cabffb0) = -1 ENOENT (No such file or directory)
open("/usr/lib64/tls/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/tls", 0x7ffc3cabffb0)  = -1 ENOENT (No such file or directory)
open("/usr/lib64/x86_64/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/x86_64", 0x7ffc3cabffb0) = -1 ENOENT (No such file or directory)
open("/usr/lib64/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib64", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
munmap(0x7f86d27d9000, 13667)           = 0
write(2, "unknown user 0\r\n", 16unknown user 0
)      = 16
exit_group(255)                         = ?
+++ exited with 255 +++
            
附属のスクリプトでメッセージに表示されてる様に 必要な libnss_* をコピーする。
$ sudo cp -p /lib64/libnss_files.so.2 /opt/chroot/lib64
            

これで chroot された環境に scp (1)、sftp (1) での アクセスが可能となる。

正常な動作が確認できたら検証のためのコマンドを削除する。

$ sudo rm /opt/chroot/bin/bash
$ sudo rm /opt/chroot/lib64/libtinfo.so.5
$ sudo rm /opt/chroot/usr/bin/ldd
$ sudo rm /opt/chroot/bin/cat
$ sudo rm /opt/chroot/usr/bin/strace
    

2015/06/03

ランダムなパスワード生成

標準的なコマンドを使用してランダムなパスワードを生成する方法を検討。
自分で考えたのは以下のコマンド

$ cat /dev/random | strings | dd bs=11 count=1 2> /dev/null| tr -d '\n'
    
これでも一応ランダムなパスワード的な文字列が取得できる。

対して 上田会長のアイデアはこちら。

$ cat /dev/urandom | tr -dc 'a-z0-9A-Z' | fold -b10
    
tr (1) コマンドの -c オプションは思い浮かばなかった。 まさに目から鱗な気分です。
さすがシェル芸の家元だけあって目の付け所がシャープ

ちなみに Mac だと tr (1) や fold (1) の挙動が異なるので以下になります。

$ cat /dev/urandom | LC_CTYPE=C tr -dc 'a-z0-9A-Z' | fold -w 10
    

2015/05/28

GW-9400 RANGEMAN ニコイチ

ちょっとした事情で入手した CASIO G-SHOCK GW-9400JK-8JR
MASTER of G シリーズでトリプルセンサーを搭載した RANGEMAN の Love The Sea And The Earth バージョン。
G-SHOCK で初めてのトリプルセンサー搭載モデルなので これからの季節はキャンプなどに最適な時計なのだが、 生息地の減退のためワシントン条約で絶滅危惧種に指定されている、 アジアアロワナをイメージしたというグレーのカラーリングは微妙な色味。

Image: RangemanBefore.jpg

そこでベゼルとバンドを通常モデルの黒と交換する事を思いついたのだが、 ベゼルは日本では既に在庫切れとなっていて入手が困難だった。 色々と探し求めた結果、アメリカの大手オークションサイト eBay で 黒のベゼルをみつけたのではるばるアメリカからベゼルを個人輸入。 国内で入手できたバンドと合わせて交換する事で落ち着いた色合いに。

Image: RangemanAfter.jpg

通常モデルとは異なり盤面にオレンジの差し色が入ってカッコ良くなったと自己満足。

2014/12/19

子供の写真をバックアップ

今回は 「子供」×「ネット」 Advent Calendar 2014 の 19日目の記事として書きました。

難しい話題が続いた様ですので、ここらでちょっと気分転換に軽いお話を…

子供が産まれたら皆さん写真を一杯撮影しますよね?
『え?そうでもない?』…そ、そうですか(笑
私は写真を一杯いっぱい撮影しちゃいました。
我が子のために為にコンパクトデジタルカメラを買い換え、 それでは物足りずにデジタル一眼レフカメラを購入し、 明るいレンズ…望遠レンズ…とすっかり泥沼にはまり込んでいます。 特にお勧めは F値が 1.4 の単焦点レンズで……っと、今回はそういう話ではなくて 撮影したデータを保存するというお話です。

一般的に言ってデジタルカメラで撮影した画像は お手持ちのパソコンのハードディスクに転送して保存していると思います。 その中でお気に入りの何枚かは印刷して保存しているでしょうが、 かつての銀塩カメラと違って全てを印刷する事は少ないのではないでしょうか?
そうなると我が子の写真データはパソコンの中だけに保存されているという事は割とよくある事だと思います。
でも、ちょっと待って下さい。(通販番組風)
そのパソコン本当に大丈夫でしょうか?
ある日パソコンが起動しなくなってしまうのは割と良くある事です。 コンピュータに詳しければパソコンが起動しなくてもお子様の写真を取り出す事はできますが、 普通はそんな事なかなか出来ないと思います。
それに実はパソコンのハードディスクというのは意外と信頼性が低く、 ちょっとした衝撃や場合によっては近所の落雷などでデータが消える危険性があります。
消えてしまって悲しい思いをするまえにちょっとした手間でバックアップを是非!
そんな大切な写真のバックアップにはこちらの商品をぜひ……じゃなくて
今回は我が家でのデータ保全をご紹介致します。

我が家 (というか私) は自宅では MacBook PRO をメインに愛用しています。 写真などのデータも基本はこの中ですのでこのマシンの中身がマスターデータとなります。
ですので全ての基本は MacBook PRO のデータ (画像データの場合は Picture フォルダ) のバックアップになります。

TimeCapsule

OS X と言えば標準で搭載されるバックアップツールの TimeMachine が有名です。
ご多分に漏れず我が家にも TimeCapsule があるので (但し内蔵 HDD は何度か交換済み)、 OS の機能を利用して TimeCapsule にバックアップしています。
MacBook PRO が起動している間は自動でバックアップをしてくれるので便利です。
問題点は若干信頼性が低い所でしょうか。 ですので TimeMachine だけではなく他のバックアップ手段と併用しています。

MacBook Air

普段持ち歩き用に MacBook Air を使っていますので、 重要なデータ (というか殆どの個人データ) はメインの MacBook PRO と同期しています。
同期は OS X に標準のユーティリティ rsync コマンドを利用しています。
rsync は unix で古くから利用されている同期のためのユーティリティで、 ターミナル画面上から利用します。
ターミナルからの利用なので少々ハードルが高く感じますが、 基本は『どこのデータ』を『どこに』同期するか指定して実行するだけです。 例えば以下の様に実行すると Picture フォルダをホスト macbookairPicture フォルダに同期します。 通信は ssh を利用していますが ssh-keygen で生成した鍵認証を利用していますので、 接続時にパスフレーズを聞かれる事なく接続できるので便利ですし自動処理に向いています。

$ for i in Documents Pictures Movies Musics
> do
>  rsync -avz -e ssh ${i} macbookair.example.com:.
> done
                
自宅の LAN 内で MacBook PRO と MacBook Air が同時に起動されている状態では、 上記の処理を自動で定期的に実行する事で MacBook Air のデータを最新の状態に更新し 同時にデータのバックアップ (単なる二重化) としても役立てています。

NAS

正確には NAS ではなくサーバのストレージです。
自宅には FreeBSD で構築したサーバが設置してあるのですが、 そのサーバに大容量の HDD を増設してバックアップ用の NAS としています。 前述した rsync を利用してこちらも自動で定期的にストレージにデータを転送しています。

$ for i in Documents Pictures Movies Musics
> do
>  rsync -avz -e ssh ${i} storage.example.com:/var/backup/
> done
                

VPS

他の用途で利用している VPS (さくらの一番安いタイプですが十分です)のストレージに、 前述した自宅サーバに増設した HDD のデータを定期的に同期しています。
自宅サーバは FreeBSD ですので unix の強力なツールが利用できるので、 この同期処理も勿論 rsync を利用しています。

$ rsync -avz -e ssh /var/backup vps.example.com:/var/backup
                
このさくらの VPS は親戚向けに娘の写真を公開する Web サーバとしても利用しています。 公開には WS-Slideshow という flash のアルバムを利用していますが、 自作のシェルスクリプト を利用して WS-Slideshow の設定ファイル (xml) やサムネイルファイルを作成しています (宣伝乙)。
バックアップしたデータはスクリプトで html などを自動生成して公開しています。
余談ですが、この VPS は 娘の名前の漢字ドメインで運用しています。
娘には unix によるサーバ管理の基礎知識をしっかりと教えて、 娘が成人する時にドメインの権限を委譲するのが今から楽しみです。 (「そんなの要らないよ」と言われるのが今から怖い…)

DVD

年に1回娘の誕生日の翌日に前年の1年分の写真や動画データを DVD に保存しています。
正と副の2枚を焼いて保存していますが、 実は光媒体はデータの保存期間が割と短いので気休め程度です。

Amazon S3

データ保存の本命 Amazon S3 です。
ご存じの方も多いと思いますが、通信販売で有名な Amazon は Amazon Web Service (通称 AWS) という いわゆるクラウドコンピューティングのサービスも提供しています。 この AWS の中で S3 というクラウトストレージ (インターネット上のハードディスクの様なモノです)は お手軽、安心、そこそこ安価なのでこれをバックアップに利用しない手はありません。

AWS の画面は日本語化を進めているそうなのですが、一部(殆ど)英語ですので 若干ハードルが高いのですが、実は簡単な英語ですし機能も単純ですのでそれほど難しくないと思います。
AWS S3 ではデータを「バケット」と呼ばれるコンテナに格納します。
バケットはパソコンのフォルダーの様なものと考えて下さい。 ですので写真を入れるためのバケットを好きな名前で作成します。
ちなみにこのバケットの名前は全世界でユニークにする必要がある様なので、 「pictures」など単純な名前は多分利用できないと思います。

バケットが出来たら早速写真を転送してみます。
ブラウザを経由した Amazon S3 の管理画面からでもアップロードは可能ですが、 Amazon S3 用に色々なツールが公開されているのでそれらを利用するのが良いでしょう。 私はサーバに s3cmd というツールを導入して定期的に同期処理を実行しています。

$ s3cmd sync -rr /var/backup s3://my-picture-backet/Picture
                
ちなみに我が家では娘が産まれてから 8 年分の写真データを全てバックアップしていますが、 容量は 100GB (枚数で言うと 200,000枚) 程度で費用は大体毎月 $ 4.00 (500円) 程度です。

AWS の他の機能 (Cloud Front) を利用すればアップロードした写真を公開したり、 色々とできる事は沢山あるのですが長くなってしまうので今回は残念ながら割愛します。

こうやって列挙すると私は 6重でデータをバックアップしています。 若干やり過ぎ?という気がしなくもありませんが、 お子供の写真は 2 度と撮影できないとても貴重なデータです。 消えてしまったデータを復活するのは非常に困難で不可能な場合も多いですので、 日頃のバックアップで大切なデータが消えてしまうといった事故をお防ぎ下さい。

追記

rsync は OS X 標準ではありませんでした。
Mac Ports を利用して後から導入したコマンドです。

2014/10/30

Happy birthday for my dearest.


You are a gracious person, with a good heart. You care, not because you need to, but because you want to. May God bless you. Happy Birthday.

2014/08/31

PCH Coffee

知り合いが鵠沼海岸にパンケーキのお店を開店したとの事で 早速家族で遊びに行って来ました。

Image: img_1906.jpg

素敵な入り口に駐車スペースも

こぢんまりした店内の内装はとってもセンスが良くまとまっていて、 いつまでもゆっくりしていたくなります。
Image: img_1908.jpg

素敵な店内の様子

娘はフルーツが盛りだくさんの「季節のフルーツパンケーキ」、 私はラズベリーとバナナがトッピングされた「チョコチップパンケーキを頂きました」。

Image: img_1904.jpg

季節のフルーツパンケーキ

Image: img_1905.jpg

チョコチップパンケーキ

ちなみに奥さんは「エッグベネディクトパンケーキ」を頂いたのですが、 写真を撮り忘れました(普段食事を撮影する習慣がないので…つい(汗
ちなみに甘くない具のパンケーキは初めてだったのですが とっても美味しかったです♪

とってもフワフワで美味しいパンケーキを堪能しました。


Copyright © 2008-2020 Mitzyuki IMAIZUMI. All rights reserved.