トップ > ソフトウェア > Cinwa

[前ページ] [次ページ]


Cinwa - CGIによるリモートファイル操作ツール

Author: Takeshi Fujiyoshi
Last update: 2010/09/05

目次

Cinwa とは

Cinwa は、ウェブサーバ上のファイルを操作したりアップロード、 ダウンロードすることを目的に自作したソフトウェアである。 ウェブサーバ上で動作させる CGI プログラムとクライアントマシン上で 動作させるコマンドラインツールから構成される。 CGI は使っているがウェブアプリケーションではないので、 CGI is not web application = Cinwa と名付けた。

以下の機能を持つ。

このツールは、筆者が HP 公開に使用している「さくらインターネット」の 「さくらのレンタルサーバ・ライト」でウェブドキュメントのファイルを アップロードする目的で開発した。 「さくらのレンタルサーバ・ライト」ではファイルをアップロードするために FTP とウェブファイルマネージャを使用できる。 しかし、FTP は暗号化がされず特にパスワードが平文で流れてしまう問題あり。 一方、標準のウェブファイルマネージャでは SSL で暗号化はされるけど 操作性と応答性が非常に悪く使い物にならない。

さくらでは2010年2月より FTPS (FTP over SSL) がサポートされたため このツールの必要性は薄れたのだが、 サーバ上で任意のコマンドを実行できるため、例えば tar.gz 形式でファイルをアップしておいてサーバ上で tar コマンドを実行して 展開するといった使い方ができて便利なので使い続けている。

なお、同じ「さくらのレンタルサーバ」でも「スタンダード」以上のプランでは SSH が使用できるため、このツールは全く不要である。

配布物

ファイル 内容
cinwa-0.1.gem Cinwa 0.1 のパッケージ (RubyGems 形式)
cmdsosa-0.1.gem Cmdsosa 0.1 のパッケージ (RubyGems 形式)
COPYING ライセンス

インストール方法

本ソフトウェアは Ruby で書かれている。 サーバ、クライアントともに Ruby-1.8.7 がインストールされた UNIX 系の OS なら動く可能性が高い。Ruby-1.8.7 以外のバージョンでは未確認。

サーバでは CGI プログラムで Ruby を使用できなければならない。 クライアントでは readline ライブラリを使用するため別途インストールが 必要かも知れない。 また、クライアントでは Cinwa のインストールに RubyGems を使用するので、 あらかじめインストールされている必要あり。

手順を以下に示す:

  1. クライアントへのインストール

    上記2つの .gem ファイルをダウンロードし、 クライアント上で以下のコマンドを実行する。

    $ gem install cinwa-0.1.gem cmdsosa-0.1.gem

    一般ユーザで実行すると ~/.gem 以下にインストールされるようである。 Ruby 1.8.7 なら ~/.gem/ruby/1.8/bin に実行ファイルが置かれるので、 そこにパスを通しておくこと。

    古いバージョンの RubyGems では一般ユーザではインストールできないかも 知れない。その場合は root 権限でインストールするなど対処する。

  2. アクセス認証に使用する公開鍵ペアの作成:

    クライアント上で cinwa-keygen コマンドを実行すると、 公開鍵証明書ファイル ~/.cinwa/cert.pem と秘密鍵ファイル ~/.cinwa/key.pem が作成される。

    詳しくは後述の cinwa-keygen コマンド の説明を参照。

  3. サーバへのインストール

    クライアント上で cinwa-mkcgi コマンドを実行し、 サーバ側にインストールするファイル群を生成する。:

    $ cinwa-mkcgi tmpdir
    

    tmpdir 以下に生成されたファイルのうち cinwa.cgi をサーバ上の CGI プログラムとして実行可能な場所に置き、 ディレクトリ cinwa を cinwa.cgi と同じディレクトリに置く。

    詳しくは後述の cinwa-mkcgi コマンド の説明を参照。

cinwa-keygen コマンド

cinwa-keygen コマンドは、アクセス認証に使用する公開鍵ペアを生成する。

使い方:

cinwa-keygen

引数は存在しない。

本コマンドを実行すると以下のファイルが生成される。

生成されるファイル 内容
~/.cinwa/cert.pem クライアントの公開鍵証明書ファイル
~/.cinwa/key.pem クライアントの公開鍵証明書に対応する秘密鍵ファイル

cert.pem をサーバ側のディレクトリ cinwa/clients 以下に置くことにより このクライアントからサーバへの cinwa によるアクセスが許可される。 サーバ上での証明書ファイル名は拡張子が .pem であれば何でも良い。

cinwa-mkcgi コマンド

cinwa-mkcgi コマンドは、サーバにインストールする CGI プログラムと 必要なファイル群を生成する。

使い方:

cinwa-mkcgi [-R <ruby_path>] <destdir>

<ruby_path> はサーバにおける Ruby インタプリタのパスを指定する。 これは CGI スクリプトの1行目に #!<ruby_path> の形で挿入される。 デフォルトは "/usr/bin/env ruby"。

<destdir> は生成したファイルの格納先ディレクトリを指定する。 このディレクトリはサーバ側のファイル配置とは無関係なので適当でよい。

cinwa-mkcgi を実行すると、ディレクトリ <destdir> が生成され、 その下に以下のファイルが格納される。

ファイル名 内容
cinwa.cgi CGI プログラムの本体。Ruby スクリプト。
cinwa/common.rb cinwa.cgi からロードされる Ruby スクリプト
cinwa/server.rb cinwa.cgi からロードされる Ruby スクリプト
cinwa/.htaccess アクセス制御ファイル。中身はこのディレクトリ以下の ファイルへの HTTP アクセスを禁止する Deny from all の1行のみ。
cinwa/clients/*.pem 接続許可するクライアントの公開鍵証明書ファイル。 ~/.cinwa/cert.pem がコピーされる。

これらのファイルをウェブサーバ上の適切な場所に安全な方法で アップロードする必要がある。

<destdir> とその下に生成されたファイルは、 サーバへのアップロードが済んだら用無しなので削除すれば良い。

cinwa コマンド

cinwa コマンドは、CGI 経由でウェブサーバのファイルを操作するための ユーザインタフェースを提供する。クライアントマシン上で実行する。

使い方:

cinwa [options] <URL> [<command> [...]]
オプション、引数 機能
-p <proxy_host>:<port> プロキシサーバを使用する。 <proxy_host> にはプロキシサーバのホスト名 or IPアドレス、<port> にはポート番号を指定する。
-w 冗長表示を有効化(デバッグ用)
<URL> ウェブサーバにインストールされた CGI プログラム (cinwa.cgi) の URL を指定する。
<command> ... コマンドインタプリタに入る前に実行させる コマンドを指定する。

cinwa は起動すると最初に引数 <URL> で指定されたサーバへの接続を試みる。 接続に成功すると、引数 <command> で指定されたコマンドを順に実行する。 コマンドが全て成功するかコマンドが未指定のときはコマンドインタプリタに入り、 プロンプトを表示してユーザからのコマンド入力を待つ。 <command> で指定されたコマンドが1つでもエラーになると そこでプログラムは終了する。

サーバへの初回接続時はサーバの証明書を受け入れるか確認されるため、 'y' を入力して受け入れる必要あり。 サーバの証明書を受け入れなければそこでプログラムは終了する。

サーバへの接続に失敗するとそこでプログラムは終了する。 そのときはサーバのログなどから原因を調べて対処すること。

例1: 初回接続:

$ cinwa http://www.myserver.com/cgi-bin/cinwa.cgi
Connecting to server...
This server certificate is not yet accepted.
Do you want to accept it? (y/[n])? y
Success
cinwa>

例2: プロキシ経由で接続:

$ cinwa -p fake.proxy.com:8080 http://www.myserver.com/cgi-bin/cinwa.cgi
Connecting to server...
Success
cinwa>

例3: 先行実行するコマンドを指定:

$ cinwa http://www.myserver.com/cgi-bin/cinwa.cgi 'cd /' 'ls -xF'
Connecting to server...
Success
==> cd /
/
==> ls -xF
COPYRIGHT       bin/            boot/           compat@         dev/
entropy         etc/            home/           lib/            libexec/
media/          mnt/            proc/           rescue/         root/
sbin/           sys@            tmp@            usr/            var/
cinwa>

コマンドインタプリタから入力できるコマンド

cinwa コマンドは、サーバへの接続に成功するとコマンドインタプリタに入る。 コマンドインタプリタでは 'cinwa> ' プロンプトを表示して ユーザからのコマンド入力を待つ。

コマンドインタプリタで入力できるコマンドについて、以下に使い方を説明する。

ls, cat, cp, mv, rm, mkdir, rmdir, chmod, sh, env - サーバ上でそのまま実行

これらのコマンドはそのままサーバ上のシェルに渡されて実行される。 引数は入力したままの形式で渡される。 引数がクォーテーションやワイルドカードなどのメタ文字を含んでいる場合、 サーバ側のシェルで展開してから実行される。

ファイル一覧を表示:

cinwa> ls -xF
app/            common/         config.rb       distrib/        doc/
error/          etc/            fujiyosi/       image/          index.html
old/            photo/          private/        winapp/
cinwa>

ファイルを削除:

cinwa> rm index.html

cinwa> ls -Fx
app/            common/         config.rb       distrib/        doc/
error/          etc/            fujiyosi/       image/
old/            photo/          private/        winapp/
cinwa>

sh または env を使うことでサーバ上の任意のコマンドを実行できる。

サーバの OS を確認:

cinwa> env uname -srm
FreeBSD 7.1-RELEASE-p8 i386
cinwa>

アーカイブファイルをアップロードしてサーバ側で展開:

cinwa> mput mk.tgz
Putting mk.tgz to mk.tgz
.done
cinwa> tar zxvf mk.tgz
** Invalid command: tar
cinwa> env tar zxvf mk.tgz
tar: ustar vol 1, 9 files, 20480 bytes read, 0 bytes written in 1 secs (20480 bytes/sec)
mk
mk/local.ruby.mk
mk/local.www.mk
mk/local.subdir.mk
mk/local.error.mk
mk/local.sh.mk
mk/local.elisp.mk
mk/local.rubygems.mk
mk/local.sys.mk
cinwa>

cd - カレントディレクトリの変更

サーバ上でカレントディレクトリを変更する。 引数には、変更先のディレクトリを絶対パスまたはカレントディレクトリからの 相対パスで指定する。 成功すると指定したディレクトリがカレントディレクトリとなる。

カレントディレクトリは多くのコマンドの動作に影響する。

使用例:

cinwa> cd /usr/local
/usr/local
cinwa> pwd
/usr/local
cinwa> ls -Fx
apache/         bin/            cpanel/         etc/            include/
info/           lib/            libdata/        libexec/        man/
mysql/          php/            sbin/           share/          var/
www/
cinwa>

pwd - カレントディレクトリのパスの表示

サーバ上のカレントディレクトリの絶対パスを表示する。引数はなし。

get - ファイルのダウンロード

サーバ上のファイルをクライアントにダウンロードする。 第1引数にはサーバ上のファイル名、第2引数にはクライアント上に置く際の ファイル名を指定する。 第2引数を省略するとサーバ上のファイルと同じファイル名となる。

各ファイル名は、絶対パスまたはカレントディレクトリからの相対パスで 指定できる。

例:

cinwa> get /etc/passwd
Getting /etc/passwd to ./passwd
.done
cinwa> lls -l
total 22
-rw-r--r--  1 fujiyosi  users  21937 Sep  4 15:39 passwd
cinwa>

mget - 複数のファイルのダウンロード

サーバ上の1つ以上のファイルをまとめてクライアントにダウンロードする。 引数にはサーバ上のファイル名を列挙する。 クライアント上に置く際のファイル名は、サーバ上でのファイル名と同じになる。

各ファイル名は、絶対パスまたはカレントディレクトリからの相対パスで 指定できる。また、ファイル名にはシェルのワイルドカードを使用できる。 存在しないファイル名が指定されたら単に無視される。

例:

cinwa> mget /bin/*sh
Getting /bin/csh to ./csh
.done
Getting /bin/tcsh to ./tcsh
.done
Getting /bin/sh to ./sh
.done
cinwa> lls -l
total 786
-rw-r--r--  1 fujiyosi  users  319436 Sep  4 15:40 csh
-rw-r--r--  1 fujiyosi  users  115292 Sep  4 15:40 sh
-rw-r--r--  1 fujiyosi  users  319436 Sep  4 15:40 tcsh
cinwa>

put - ファイルのアップロード

クライアント上のファイルをサーバにアップロードする。 第1引数にはクライアント上のファイル名、第2引数にはサーバに置く際の ファイル名を指定する。 第2引数を省略するとクライアント上のファイル名と同じファイル名となる。

各ファイル名は、絶対パスまたはカレントディレクトリからの相対パスで 指定できる。

使用例:

cinwa> put README.txt YONDE.txt
Putting README.txt to YONDE.txt
.done
cinwa> put /etc/passwd
Putting /etc/passwd to passwd
.done
cinwa> ls -l
total 40
-rw-r--r--  1 ncl  users  17790 Sep  4 15:43 YONDE.txt
-rw-r--r--  1 ncl  users   1605 Sep  4 15:43 passwd
cinwa>

mput - 複数のファイルのアップロード

クライアント上の1つ以上のファイルをまとめてサーバにアップロードする。 引数にはクライアント上のファイル名を列挙する。 サーバ上に置く際のファイル名はクライアント上でのファイル名と同じになる。

各ファイル名は、絶対パスまたはカレントディレクトリからの相対パスで 指定できる。また、ファイル名にはシェルのワイルドカードを使用できる。 存在しないファイル名が指定されたら単に無視される。

使用例:

cinwa> mput /bin/*sh /etc/rc.conf
Putting /bin/csh to csh
.done
Putting /bin/ksh to ksh
.done
Putting /bin/sh to sh
.done
Putting /etc/rc.conf to rc.conf
.done
cinwa> ls -l
total 1024
-rw-r--r--  1 ncl  users  146626 Sep  4 15:45 csh
-rw-r--r--  1 ncl  users  207921 Sep  4 15:45 ksh
-rw-r--r--  1 ncl  users     711 Sep  4 15:45 rc.conf
-rw-r--r--  1 ncl  users  144345 Sep  4 15:45 sh
cinwa>

ss - アクティブセッション一覧表示 (デバッグ用)

アクティブなセッションの情報を一覧表示する。 ただし、引数に -r を付けて実行すると全てのセッションが消去される。

例: 3つのクライアントからサーバに接続されている状態:

cinwa> ss
session ID                                 count         timeout
6db40156f6bf1e3c4ee45d7e9e760489               1             269
0389d632830773b37a86eb87dd5a8796               2             300
56179bc38470e027f75b6fc24148da43              21             254
Total 3 active sessions

例: セッションクリア:

cinwa> ss -r
session ID                                 count         timeout

例: 以下は ss コマンドが切っ掛けで再びセッションが確立された:

cinwa> ss
session ID                                 count         timeout
1c8ea05cdda15f13bad2c00795ee6de0               1             300
Total 1 active sessions

lcd - クライアント側のカレントディレクトリの変更

クライアント側においてカレントディレクトリを変更する。 引数には変更先のディレクトリのパスを絶対パスまたはカレントディレクトリ からの相対パスで指定する。

lpwd - クライアント側のカレントディレクトリのパスの表示

クライアント側におけるカレントディレクトリのパスを表示する。 引数はなし。

lls - クライアント側のファイル一覧表示

クライアント側においてカレントディレクトリのファイルの一覧を表示する。 このコマンドはクライアント上で ls コマンドを実行するだけである。 引数はそのまま ls コマンドに渡される。

使用例:

cinwa> lcd /usr/src
/home/usr/src
cinwa> lpwd
/home/usr/src
cinwa> lls -Fx
BUILDING        CVS/            Makefile        Makefile.inc    UPDATING
bin/            build.sh*       common/         compat/         crypto/
dist/           distrib/        doc/            etc/            external/
games/          gnu/            include/        lib/            libexec/
regress/        rescue/         sbin/           share/          sys/
tests/          tools/          update.log      usr.bin/        usr.sbin/
x11/
cinwa>

exit - プログラムの終了

cinwa を終了する。

version - バージョンの表示

サーバとクライアントにおける Cinwa のプログラムおよび Cinwa が使用しているプログラムのバージョン情報を表示する。

例:

cinwa> version
Client:
        Cinwa 0.1
        Cmdsosa 0.1
        Ruby 1.8.7 2009-06-12 i486-netbsdelf
        NetBSD 5.99.39 i386
Server:
        Cinwa 0.0.99
        Ruby 1.8.7 2009-12-24 i386-freebsd7
        FreeBSD 7.1-RELEASE-p13 i386
cinwa>

help - ヘルプの表示

引数を指定しなければ、cinwa で使用できるコマンドの一覧を表示する。 引数にコマンド名を指定すると、そのコマンドの詳細を表示する。

例:

cinwa> help
Command list:
  cat             run command cat
  cd              change current directory
  chmod           run command chmod
  cp              run command cp
  env             run command env
  exit            exit
  get             download file
  help            print help
  history         list or control history
  ...

  以下省略

cinwa> help get
get -- download file
usage: get <remote_file> [<local_file>]
cinwa>

リダイレクションとパイプ

コマンドインタプリタでは、シェルと似た形式のリダイレクションを使用できる。

書式 動作
command > file コマンド command の標準出力をクライアント上の ファイル file へ書き出す。 サーバ上のファイルではないことに注意。
command >> file コマンド command の標準出力をクライアント上の ファイル file へ追記する。 サーバ上のファイルではないことに注意。
command | program クライアント上で外部コマンド program を実行し、コマンド command の標準出力を program の標準入力へ接続する。

例: ls -l の出力をファイル xxx.txt に書き出す:

cinwa> ls -l > xxx.txt

例: ls -l の出力を less を使って読む:

cinwa> ls -l | less

Cinwa プロトコルの概要

クライアントで動作する cinwa コマンドとウェブサーバ上で動作する CGI プログラム cinwa.cgi との間で Cinwa プロトコルを用いて通信する。 Cinwa プロトコルはトランスポートとして HTTP の POST メソッドを使用する。

基本的な動作

Cinwa プロトコルにおける基本的な動作は以下の通り。

  1. cinwa コマンドを使ってユーザがコマンドを投入すると、 cinwa コマンドはそのコマンドに対応するリクエストメッセージを HTTP POST リクエストに載せてウェブサーバの cinwa.cgi へ送信する。
  2. cinwa.cgi はリクエストを受信すると、それに従った処理を行ない、 処理結果を格納したレスポンスメッセージを HTTP レスポンスに載せて返信する。
  3. cinwa コマンドは受信したレスポンスメッセージの内容により、 結果を表示したりファイルに書き出したり更にリクエストを発行したりし、 投入されたコマンドに対する処理が終了したらユーザからの入力待ちに戻る。

Cinwa プロトコルで一度に送受信できるデータサイズは 上限 500KB 程度に制限されている(パラメータで変更可能)。 このサイズを越えるファイルをアップロード、ダウンロードするときは、 複数のリクエストに分割して転送される。 一方、サーバ上での実行したコマンドの出力は分割転送することができず、 上限サイズで打ち切られる。

アクセス制御と暗号化

  1. cinwa コマンドは起動すると Cinwa プロトコルの LOGIN リクエストを 用いてクライアントの公開鍵証明書を送信する。
  2. cinwa.cgi は、ディレクトリ cinwa/clients 以下に同じ内容の証明書が 存在すれば、新しくセッションを割り当て、ランダムに生成した セッションIDとパスワードをクライアントの公開鍵で暗号化して返信する。 一方、同じ内容の証明書が存在しなければ、エラーを返信しアクセスを拒否する。
  3. cinwa コマンドは、受信したデータを自身の秘密鍵で復号して セッションIDとパスワードを取得する。
  4. cinwa コマンドと cinwa.cgi は、これ以降のメッセージを パスワードで暗号化し、セッションIDを付加して送受信する。

メッセージ認証とリプレイ攻撃防止

Cinwa プロトコルでやりとりされるメッセージには、 暗号化メッセージとセッションIDに加えて カウンタとメッセージ認証符号が付加される。

カウンタは 1 からスタートし、リクエストごとに増加する。 メッセージ認証符号は、セッションID、カウンタ、暗号化メッセージ、 パスワードを連結したデータのハッシュである。

cinwa コマンドと cinwa.cgi は、メッセージを受信したとき、 以下のいずれかの場合に受信したメッセージを不正であるとみなす。

  • メッセージ認証符号が不一致
  • リクエストのカウンタが前回の値以下
  • レスポンスのカウンタがリクエストのカウンタと異なるとき

これにより、メッセージの改ざんとリプレイ攻撃による不正アクセスを 防止できる(たぶん)。

HTTP の話

HTTP のアクセス認証

Cinwa では独自の認証メカニズムを実装しているが、 HTTP の Basic 認証、Digest 認証にも対応している。 Cinwa クライアントプログラムは、HTTP レベルで認証が要求されると 端末上でユーザ名とパスワードの入力を促す。 Basic 認証はパスワードを平文で転送するので SSL (https) 以外の通信では 使うべきではない。

$ cinwa http://www.xxx.yyy/cgi-bin/cinwa.cgi
[HTTP] Digest authentication for realm "private"
[HTTP] Username: fujiyosi   ★HTTPの認証のユーザ名を入力
[HTTP] Password:            ★HTTPの認証のパスワードを入力
cinwa>

SSL 対応

サーバが SSL をサポートしている場合、 cinwa コマンドの引数の URL を https://... とすれば SSL で接続する。

なお、サーバの証明書の検証は行なっていない。

プロキシ接続

HTTPプロキシサーバ経由でサーバに接続するには -p オプションで プロキシサーバのアドレスとポートを指定する。:

$ cinwa -p proxy.dokoka.com:8888 http://www.xxx.yyy/cgi-bin/cinwa.cgi

トップ > ソフトウェア > Cinwa

[前ページ] [次ページ]