目次
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 を使用するので、 あらかじめインストールされている必要あり。
手順を以下に示す:
クライアントへのインストール
上記2つの .gem ファイルをダウンロードし、 クライアント上で以下のコマンドを実行する。
$ gem install cinwa-0.1.gem cmdsosa-0.1.gem
一般ユーザで実行すると ~/.gem 以下にインストールされるようである。 Ruby 1.8.7 なら ~/.gem/ruby/1.8/bin に実行ファイルが置かれるので、 そこにパスを通しておくこと。
古いバージョンの RubyGems では一般ユーザではインストールできないかも 知れない。その場合は root 権限でインストールするなど対処する。
アクセス認証に使用する公開鍵ペアの作成:
クライアント上で cinwa-keygen コマンドを実行すると、 公開鍵証明書ファイル ~/.cinwa/cert.pem と秘密鍵ファイル ~/.cinwa/key.pem が作成される。
詳しくは後述の cinwa-keygen コマンド の説明を参照。
サーバへのインストール
クライアント上で cinwa-mkcgi コマンドを実行し、 サーバ側にインストールするファイル群を生成する。:
$ cinwa-mkcgi tmpdir
tmpdir 以下に生成されたファイルのうち cinwa.cgi をサーバ上の CGI プログラムとして実行可能な場所に置き、 ディレクトリ cinwa を cinwa.cgi と同じディレクトリに置く。
詳しくは後述の cinwa-mkcgi コマンド の説明を参照。
cinwa-keygen コマンドは、アクセス認証に使用する公開鍵ペアを生成する。
使い方:
cinwa-keygen
引数は存在しない。
本コマンドを実行すると以下のファイルが生成される。
生成されるファイル | 内容 |
---|---|
~/.cinwa/cert.pem | クライアントの公開鍵証明書ファイル |
~/.cinwa/key.pem | クライアントの公開鍵証明書に対応する秘密鍵ファイル |
cert.pem をサーバ側のディレクトリ cinwa/clients 以下に置くことにより このクライアントからサーバへの cinwa によるアクセスが許可される。 サーバ上での証明書ファイル名は拡張子が .pem であれば何でも良い。
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 がコピーされる。 |
これらのファイルをウェブサーバ上の適切な場所に安全な方法で アップロードする必要がある。
cinwa.cgi は、HTTP アクセス可能でかつ CGI プログラムとして実行可能な ディレクトリに置く必要がある。 また、ファイル名とパーミッションを必要に応じて設定しなければならない。
「さくらのレンタルサーバ」の場合:
ディレクトリ cinwa はそのままの構成で cinwa.cgi と同じ ディレクトリに置くことを想定している。
このディレクトリにはセキュリティ上重要なファイルが置かれるため、 このディレクトリ以下のファイルへの HTTP アクセスは禁止すべきである。 ファイル .htaccess にはこのための設定が記述されているが、 この方法で HTTP アクセスを禁止できないシステムでは、このディレクトリを HTTP から見えない場所へ移動させるなどして対処すべきである。 ディレクトリを移動した場合、cinwa.cgi の内容を適切に修正する必要がある。
<destdir> とその下に生成されたファイルは、 サーバへのアップロードが済んだら用無しなので削除すれば良い。
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> ' プロンプトを表示して ユーザからのコマンド入力を待つ。
コマンドインタプリタで入力できるコマンドについて、以下に使い方を説明する。
これらのコマンドはそのままサーバ上のシェルに渡されて実行される。 引数は入力したままの形式で渡される。 引数がクォーテーションやワイルドカードなどのメタ文字を含んでいる場合、 サーバ側のシェルで展開してから実行される。
ファイル一覧を表示:
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>
サーバ上でカレントディレクトリを変更する。 引数には、変更先のディレクトリを絶対パスまたはカレントディレクトリからの 相対パスで指定する。 成功すると指定したディレクトリがカレントディレクトリとなる。
カレントディレクトリは多くのコマンドの動作に影響する。
使用例:
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>
サーバ上のカレントディレクトリの絶対パスを表示する。引数はなし。
サーバ上のファイルをクライアントにダウンロードする。 第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>
サーバ上の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>
クライアント上のファイルをサーバにアップロードする。 第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>
クライアント上の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>
アクティブなセッションの情報を一覧表示する。 ただし、引数に -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
クライアント側においてカレントディレクトリを変更する。 引数には変更先のディレクトリのパスを絶対パスまたはカレントディレクトリ からの相対パスで指定する。
クライアント側におけるカレントディレクトリのパスを表示する。 引数はなし。
クライアント側においてカレントディレクトリのファイルの一覧を表示する。 このコマンドはクライアント上で 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>
cinwa を終了する。
サーバとクライアントにおける 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>
引数を指定しなければ、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 コマンドとウェブサーバ上で動作する CGI プログラム cinwa.cgi との間で Cinwa プロトコルを用いて通信する。 Cinwa プロトコルはトランスポートとして HTTP の POST メソッドを使用する。
Cinwa プロトコルにおける基本的な動作は以下の通り。
Cinwa プロトコルで一度に送受信できるデータサイズは 上限 500KB 程度に制限されている(パラメータで変更可能)。 このサイズを越えるファイルをアップロード、ダウンロードするときは、 複数のリクエストに分割して転送される。 一方、サーバ上での実行したコマンドの出力は分割転送することができず、 上限サイズで打ち切られる。
Cinwa プロトコルでやりとりされるメッセージには、 暗号化メッセージとセッションIDに加えて カウンタとメッセージ認証符号が付加される。
カウンタは 1 からスタートし、リクエストごとに増加する。 メッセージ認証符号は、セッションID、カウンタ、暗号化メッセージ、 パスワードを連結したデータのハッシュである。
cinwa コマンドと cinwa.cgi は、メッセージを受信したとき、 以下のいずれかの場合に受信したメッセージを不正であるとみなす。
これにより、メッセージの改ざんとリプレイ攻撃による不正アクセスを 防止できる(たぶん)。
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 をサポートしている場合、 cinwa コマンドの引数の URL を https://... とすれば SSL で接続する。
なお、サーバの証明書の検証は行なっていない。
HTTPプロキシサーバ経由でサーバに接続するには -p オプションで プロキシサーバのアドレスとポートを指定する。:
$ cinwa -p proxy.dokoka.com:8888 http://www.xxx.yyy/cgi-bin/cinwa.cgi