2009/06/18

SIGPIPE

  1#!/bin/sh
  2    :
  3if ${any_command} | grep -q "${word}"
  4then
  5    :
    

linux 上で実行しているこの様なシェルスクリプトの ${any_commnand} がたまに異常終了している事がある。
気になって調べてみると SIGPIPE を受信してエラー終了している様だ。
grep (1) のマニュアルを調べてみると

Exit immediately with zero status if any match is found, even if an error was detected.

man grep



と明記してあるので grep (1) が先に終了してしまったので、 ${any_command} に SIGPIPE が送信されているらしい。

スクリプト中で grep -q は割と多用すると思うが、 こんな落とし穴もあるので気をつけなくては。
そもそも grep (1) なんてよく使うコマンドだから かえってマニュアルを熟読しないだろうし、 だからこの様な BUG が潜む原因にもなっていると思う。
というか実は常識的な話だったりする?

2009/05/18

The myth of unix security

Kaspersky 社のブログ によると、 FreeBSD や Linux をターゲットとしたマルウェアが発見されたとの事です。

It’s often argued that *nix systems are secure, and there are’t any viruses or malware for such systems. This hasn’t been true for a long time, as two recently detected malicious programs prove.

Kaspersky 社の Blog より



超適当に翻訳してみると、 『多くの場合、unix システムはセキュリティを確保しているので、 ウィルスやマルウェアはありえないと主張されていた。 これらの事は既に真実ではない事が最近検出された2種類の悪意あるプログラム により証明されている。』 みたいな事が言われている。
今回は通常の perl スクリプトと FreeBSD や Linux 上で実行可能な 暗号化された perl スクリプトの 2 種類のマルウェアが発見されたらしく、 それぞれ迷惑メイルを送信する「ボット」や、 セキュリティソフト風の怪しいソフトウェアを販売するための 詐欺サイトを宣伝・販売するウェブサイトを構築してしまうらしい。

Windows に比較すれば FreeBSD や Linux の方が多少は安全ではあるが、 それはあくまでも相対的な比較においての安全であり 絶対的に安全という訳ではない。 そんな事はちょっと考えてみれば常識だろって位の事だと思うのだが、 一部では「Linux だから安全っ」みたいな事を妄信している人がいる様だ。
自分だけが被害に遭うだけならそれでも全然構わないのだが、 マルウェアに侵入を許してしまうと迷惑メイルの発信源になったり、 他のコンピュータへの攻撃の足掛かりになったりする事で、 他人にも迷惑を及ぼす危険性があるので是非とも心を改めて欲しい。
まぁ、人に迷惑をかけるなって事ですね。
コンピュータである以上「絶対に安全」なんてあり得ない事なので、 ちゃんとセキュリティ情報などには気を配り、 万全の対策をしなくてはならないのはもはや常識の範疇だと思う。

2009/04/09

POSIX.2 標準仕様のシェルによる変数展開

シェルスクリプトを作成する際に シェル変数に値を代入したり参照したりする事は頻繁に発生するが、 シェル変数の展開にも便利な使い方がある。
basename (1) や dirname (1) と同様な動作が シェルの組込みとして利用できるので資源の節約にもつながり、 上手に利用すると可読性の高いスクリプトが作成できる。

機能一覧

${parameter:-word} デフォルト値への置換
${parameter:=word} デフォルト値の代入
${parameter:?[word]} 値の検査とエラー
${parameter:+word} 代替値の使用
${#parameter} 文字列長の取得
${parameter%word} 最短後置パターンの削除
${parameter%%word} 最長後置パターンの削除
${parameter#word} 最短前置パターンの削除
${parameter##word} 最長前置パターンの削除

デフォルト値への置換

  • ${parameter:-word}
  • ${parameter} が NULL の場合 word に置換される。

    $ echo ${foo}
    
    $ echo ${foo:-FOO}
    FOO
    $ echo ${foo}
    
    $ foo=BAR
    $ echo ${foo:-FOO}
    BAR
    

デフォルト値の代入

  • ${parameter:=word}
  • ${parameter} が NULL の場合 word に置換され、 かつ parameter に代入される。

    $ echo ${foo}
    
    $ echo ${foo:=FOO}
    FOO
    $ echo ${foo}
    FOO
    $ echo ${foo:=BAR}
    FOO
    

値の検査とエラー

  • ${parameter:?[word]}
  • ${parameter} が NULL の場合 word が指定されていればその値を、 指定されていない場合はデフォルトの値を表示し、 非対話実行されているシェルをエラー終了させる。

    $ echo ${foo}
    
    $ echo ${foo:?value not set}
    value not set
    

代替値の使用

  • ${parameter:+word}
  • ${parameter} が NULL 以外の場合 word に置換される

    $ echo ${foo:+FOO}
    
    $ echo ${foo}
    
    $ foo=BAR
    $ echo ${foo}
    BAR
    $ echo ${foo:+FOO}
    FOO
    

文字列長の取得

  • ${#parameter}
  • ${parameter} の文字列としての長さに置換される

    $ echo ${foo}
    
    $ echo ${#foo}
    0
    $ foo=FOO
    $ echo ${foo}
    FOO
    $ echo ${#foo}
    3
    

最短後置パターンの削除

  • ${parameter%word}
  • ${parameter} の右から word で示されるパターンの最短部分を削除する

    $ foo=/foo/bar/baz
    $ echo ${foo%/*}
    /foo/bar
    $ foo=foo.c
    $ echo ${foo%.*}
    foo
    $ foo=foo
    $ echo ${foo%.*}
    foo
    

最長後置パターンの削除

  • ${parameter%%word}
  • ${parameter} の右から word で示されるパターンの最長部分を削除する

    $ foo=foo.example.com
    $ echo ${foo%%.*}
    foo
    $ foo=http://www.example.com:8888/
    $ echo ${foo%%:*}
    http
    $ foo=foo
    $ echo ${foo%%.*}
    foo
    

最短前置パターンの削除

  • ${parameter#word}
  • ${parameter} の左から word で示されるパターンの最短部分を削除する

    $ foo=foo.c
    $ echo ${foo#*.}
    c
    $ foo=foo.example.com
    $ echo ${foo#*.}
    example.com
    $ foo=foo
    $ echo ${foo#*.}
    foo
    

最長前置パターンの削除

  • ${parameter##word}
  • ${parameter} の左から word で示されるパターンの最長部分を削除する

    $ foo=foo.example.com
    $ echo ${foo##*.}
    com
    $ foo=/foo/bar/baz
    $ echo ${foo##*/}
    baz
    $ foo=foo
    $ echo ${foo##*.}
    foo
    

2009/03/31

Dual Head + KVM Switch + Synergy その3

ATEN の CS-1734A を入手したのでデスクトップ環境を変更してみた。

メインの生活環境となる FreeBSD マシンはビデオカードに nVidia の GeForce 7300 を使用しているので、 Dual Head を活用して画面を VGA と DVI に出力している。
VGA 出力は CS-1734A 経由で正面の BENQ 24 インチメインディスプレイに繋がり、

  • 生活環境としての FreeBSD
  • あまり使う機会は少ないが何となく必要な Windows Xp Professional
  • 使いやすさと美しさが最高な Mac OS X 10.5 Leopard
  • 検証や Linux 独自の作業に必要な ubuntu
の4台を接続し切替ながら使用している。

DVI 出力は メインディスプレイの右隣に設置してある 19 インチのサブディスプレイに直接接続しており、 常時 FreeBSD の画面を表示している。
コンソール使用時は双方に同じ内容が出力されているが、 X Window を起動するとそれぞれ独立した別のスクリーンとして動作できるので、 メインディスプレイに FreeBSD の画面以外が表示されている場合でも サブディスプレイには FreeBSD の画面が表示されていて便利である。
勿論キーボードとマウスはそれぞれのスクリーンを透過的にアクセスできるので、 メインディスプレイにも FreeBSD の X Window が表示されている場合、 マウスカーソルはメインディスプレイの右側からサブディスプレイの左側にかけて 連続して移動する。

CS-1734A 経由で接続されているメインキーボード/マウス以外に、 FreeBSD マシンには BlueTooth 経由でサブキーボード/マウスも接続されているので、 メインディスプレイに FreeBSD が表示されていない (メインのキーボード/マウスが他の OS で利用されている)場合でも、 サブキーボード/マウスを利用してサブディスプレイ上に表示されている FreeBSD を操作する事が可能である。

更にサブディスプレイ上に表示されている X Window のスクリーンでは synergy サーバが動作しており、 Windows Xp、Mac OS X、ubuntu がそれぞれ synergy クライアントとなっているので 各 OS 上でのコピー & ペーストが可能になっている。
ちなみにサブディスプレイ側でマウスカーソルを画面上部に移動すると Mac OS X、 画面下部に移動すると Windows Xp、画面右に移動すると ubuntu に キーボードとマウスの対話権が移動する。
例えばメインディスプレイに Mac OS X が表示されている場合、 メインキーボード/マウスを操作するとメインディスプレイ上で Mac OS X の操作ができ、 サブキーボード/マウスを操作するとサブディスプレイ上で FreeBSD の操作ができるのだが、 サブディスプレイ上でサブマウスのカーソルを画面上部に移動すると、 メインディスプレイ上の Mac OS X の操作を synergy 経由のサブキーボード/マウスでできてしまう。

文章で説明するのが困難な程複雑な仕組みになってしまった気がする。


複雑な仕組みになってしまったのでたまに混乱してしまう…

2009/03/30

ATEN CS-1734A + Logicool V450 Nano

職場で利用しているマウスが 10 年以上前に購入した有線マウスなので、 ワイヤレスで快適な環境を目指し Logicool の V450 Nano を購入した。
本日届いたので早速 CS-1734A の CONSOLE ポートに接続してみると… マウスカーソルが縦方向にしか移動しない。
それぞれの OS が動作するハードウェアの USB ポートに V450 Nano の レシーバを直接差し込むと当然ながら正常に動作しており、 CS-1734A につながっている FreBSD、Windows Xp、Leopard、Linux の 全てで同じ動作なので OS の問題ではなく KVM Switch の問題らしい。
USB マウスは CS-1734A(というか KVM Switch)との相性があるんですね…がっかり。

とりあえず CONSOLE ポートではなく裏面の USB HUB に接続したら動作した。
裏面の USB HUB は前面のスイッチを短くタッチした場合は ディスプレイと連動しないので前面のスイッチを長押するか ホットキーで切替える必要がある。
普段からホットキーのみで切替ているので良しとするか

追記

ディスプレイの切替のたびに USB マウスの挿抜が検出されてしまい、 FreeBSD は USB デバイスのエラーが発生してしまった。
なので当面は V450 Nano は使用できない。

2009/03/29

Mac OS X で CS-1734A 経由の HHK(PD-KB02)を利用する

ATEN の KVM Switch CS-1734A は Mac 対応をうたっているが、 PS/2 接続の Happy Hacking Keyboard(PD-KB02) を CS-1734A に付属する PS/2 -> USB 変換ケーブルを利用して Mac OS X Leopard に接続する様な使い方の場合、 キーボード手前の左右 Meta キー ('◇' )が何故か 'a' になってしまう。

市販の PS/2-USB 変換アダプタを利用して PS/2 接続の Happy Hacking Keyboard を Mac OS X で利用するための デバイスドライバ HHKPS2USBDriver をみつけたので、 リストにない変換アダプタでの動作を確認する方法を参考に CS-1734A の Vendor ID と Product ID を登録したところ、 キーボード手前の左右 Meta キー ('◇') が Command キーとして正しく動作する様になった。

ちなみに ATEN の Vendor ID は 1367(10)、 Product ID は 8723(10) なので、

  1<key>HHK via ATEN CS-1734A</key>
  2<dict>
  3    <key>CFBundleIdentifier</key>
  4    <string>org.nnip.driver.HHKPS2USBDriver</string>
  5    <key>HIDDefaultBehavior</key>
  6    <string></string>
  7    <key>IOClass</key>
  8    <string>HHKPS2USBDriver</string>
  9    <key>IOProviderClass</key>
 10    <string>IOUSBInterface</string>
 11    <key>bConfigurationValue</key>
 12    <integer>1</integer>
 13    <key>bInterfaceNumber</key>
 14    <integer>0</integer>
 15    <key>idProduct</key>
 16    <integer>8723</integer>             <!-- Product ID -->
 17    <key>idVendor</key>
 18    <integer>1367</integer>             <!-- Vendor ID -->
 19</dict>
    
の記述を追加した。

2009/02/18

wget でファイル送信

wget (1) でファイルを送信する必要が生じたので、 ブラウザでファイルを送信する際のパケットをキャプチャして 通信内容を調べてみる。

想定しているのは input type='file'enctype='multipart/form-data' を指定した フォームによるファイル送信処理。
通常の http ヘッダ以外に "Content-Type""boundary"wget (1) の --header オプションで指定し、 multipart/form-data 形式に整形した送信するファイルの内容を --post-data オプションで指定するだけで送信できる。
Content-Type'multipart/form-data'boundary は送信するデータの中に含まれない 任意の文字列を指定すれば問題ない。

multipart/form-data 形式は以下の形式に整形する。

--任意の文字列
Content-Disposition: form-data; name="フォーム名"; filename="ファイル名"
Content-Type: text/plain
(空行)
ファイルの中身
(空行)
--任意の文字列

実際にコマンドライン形式に記述するとこの様になる。

wget --header="Content-Type: multipart/form-data; boundary=バウンダリ" \
	--post-data='
--バウンダリ
Content-Disposition: form-data; name="フォーム名"; filename="ファイル名"
Content-Type: text/plain

ファイルの中身
         :

--バウンダリ
	' 送信先URL

スクリプトの場合などはシェル変数などを利用すると、 もう少し見やすいスクリプトになるだろう。

	:
	:
# バウンダリ文字列は世界標準時基準時点からの秒数とする
boundary="boundary-`date '+%s'`"
# 受信する cgi の <input type="file" name="..."> で指定されるフォーム名
formname="フォーム名"
# 送信するファイル
filename="ファイル名"
# 送信するファイルのデータ
contents="`cat ${filename}`"

# multipart/form-data 形式のデータ生成
data="
--${boundary}
Content-Disposition: form-data; name='${formname}'; filename='${filename}'
Content-Type: text/plain

${contents}

--${boundary}
"

# ファイルの送信処理
wget --header="Content-Type: multipart/form-data; boundary=${boundary}" \
    --post-data="$data" 送信先 URL
	:
	:

2009/02/01

DNS DDoS

詐称された IP address から `. IN NS' という query を投げる DNS DDoS 攻撃が最近流行っているらしい。
この query に対して root servers のリストを応答すると、 わずか数バイトの問い合わせに対して数百バイトの応答が発生してしまうので、 詐称された IP address に膨大なトラヒックが集中してしまい、 結果として DDoS攻撃 分散型サービス拒否攻撃 Distributed Denial of Service attack となってしまうらしい。

bind は既に対策が実施されており、 `. IN NS' query に `refused' と応答する様になったので、 対策されていない DNS の管理者は早急に対策するした方が良いと思う。

2008/12/10

GNU Bourne-Again Shell を便利に使う

対話シェルとして使用する bash (1) の コマンドライン履歴機能の便利な使い方。
bash (1) のコマンドライン履歴機能のうち イベント指示子、単語指示子、修飾指示子は オンラインマニュアルにも情報が少ないが、 慣れると非常に便利でキータイプ量も減るので是非マスターしておきたい。
以下の文中で nm は任意の整数、 foobarbaz などは任意の文字列を示す。

機能一覧

イベント指示子
!! 直前に実行したコマンドを実行する
!-n n 回前に実行したコマンドを実行する
^foo^bar
!:s/foo/bar
直前に実行したコマンドの foobar に変更して実行する
!:gs/foo/bar 直前に実行したコマンドの全ての foobar に変更して実行する
!foo foo で開始されるコマンドを実行する
!n
n 番目に実行されたコマンドを実行する
単語指示子
!:n 直前に実行したコマンドの n 番目の引数を取得する
!^ 直前に実行したコマンドの 1 番目の引数を取得する
!$ 直前に実行したコマンドの最後の引数を取得する
!* 直前に実行したコマンドの全ての引数を取得する
!:n* 直前に実行したコマンドの n 番目から最後までの引数を取得する
!:n-m 直前に実行したコマンドの n 番目から m 番目までの引数を取得する
!:-n 直前に実行したコマンドの最初から n 番目までの引数を取得する
!:n- 直前に実行したコマンドの n 番目から最後の 1 個前までの引数を取得する
修飾指示子
:p コマンドを表示のみして実行しない
:h パスのファイル名部分を取り除きディレクトリ名を取得する
:t パスのディレクトリ名部分を取り除きファイル名を取得する
:r ファイル名の拡張子を取り除き "." の前を取得する
:e ファイル名の拡張子を "." 付きで取得する

イベント指示子

  • !!
  • 直前に実行したコマンドを実行する
    $ echo foo bar baz
    foo bar baz
    $ !!
    echo foo bar baz
    foo bar baz
    

  • !-n
  • n 回前に実行したコマンドを実行する (複数のコマンドを繰り返して実行する場合に便利)
    $ echo foo bar baz
    foo bar baz
    $ echo FOO BAR BAZ
    FOO BAR BAZ
    $ !-2
    echo foo bar baz
    foo bar baz
    $ !-2
    echo FOO BAR BAZ
    FOO BAR BAZ
    

  • ^foo^bar
    !:s/foo/bar
  • 直前に実行したコマンドの foobar に変更して実行する (下のパターンの場合 "/" は任意の文字に変更が可能)
    $ echo foo foo foo
    foo foo foo
    $ ^foo^bar
    echo bar foo foo
    bar foo foo
    $ echo foo foo foo
    foo foo foo
    $ !:s/foo/bar
    echo bar foo foo
    bar foo foo
    

  • !:gs/foo/bar
  • 直前に実行したコマンドの全ての foobar に変更して実行する ("/" は任意の文字に変更が可能)
    $ echo foo foo foo
    foo foo foo
    $ !:gs/foo/bar
    echo bar bar bar
    bar bar bar
    

  • !foo
  • foo で開始されるコマンドを実行する
    $ echo foo bar baz
    foo bar baz
    $ touch foo bar baz
    $ !ec
    echo foo bar baz
    foo bar baz
    

  • !n
  • n 番目に実行されたコマンドを実行する
    $ echo foo bar baz
    foo bar baz
    $ echo FOO BAR BAZ
    FOO BAR BAZ
    $ !1
    echo foo bar baz
    foo bar baz
    

単語指示子

  • !:n
  • 直前に実行したコマンドの n 番目の引数を取得する
    $ echo foo bar baz
    foo bar baz
    $ echo !:0
    echo echo
    echo
    $ echo foo bar baz
    foo bar baz
    $ echo !:2
    echo bar
    bar
    

  • !^
  • 直前に実行したコマンドの 1 番目の引数を取得する
    $ echo foo bar baz
    foo bar baz
    $ echo !^
    echo foo
    foo
    

  • !$
  • 直前に実行したコマンドの最後の引数を取得する
    $ echo foo bar baz
    foo bar baz
    $ echo !$
    echo baz
    foo
    

  • !*
  • 直前に実行したコマンドの全ての引数を取得する
    $ echo foo bar baz
    foo bar baz
    $ echo !*
    echo foo bar baz
    foo bar baz
    

  • !:n*
  • 直前に実行したコマンドの n 番目から最後までの引数を取得する
    $ echo foo bar baz
    foo bar baz
    $ echo !:2*
    echo bar baz
    bar baz
    

  • !:n-m
  • 直前に実行したコマンドの n 番目から m 番目までの引数を取得する
    $ echo foo bar baz FOO BAR BAZ
    foo bar baz FOO BAR BAZ
    $ echo !:3-5
    echo baz FOO BAR
    baz FOO BAR

  • !:-n
  • 直前に実行したコマンドの最初から n 番目までの引数を取得する
    $ echo foo bar baz FOO BAR BAZ
    foo bar baz FOO BAR BAZ
    $ echo !:-4
    echo foo bar baz FOO
    foo bar baz FOO
    

  • n-
  • 直前に実行したコマンドの n 番目から 最後の 1 個前までの引数を取得する
    $ echo foo bar baz
    foo bar baz
    $ echo !:1-
    echo foo bar
    foo bar
    

修飾指示子

  • :p
  • コマンドを表示のみして実行しない
    $ echo foo bar baz
    foo bar baz
    $ touch foo bar baz
    $ !e:p
    echo foo bar baz
    

  • :h
  • パスのファイル名部分を取り除きディレクトリ名を取得する
    $ echo /foo/bar/baz
    /foo/bar/baz
    $ echo !$:h
    echo /foo/bar
    /foo/bar
    

  • :t
  • パスのディレクトリ名部分を取り除きファイル名を取得する
    $ echo /foo/bar/baz
    /foo/bar/baz
    $ echo !$:t
    echo baz
    baz
    

  • :r
  • ファイル名の拡張子を取り除き "." の前を取得する
    $ echo foo.c
    foo.c
    $ echo !$:r
    echo foo
    foo
    

  • :e
  • ファイル名の拡張子を "." 付きで取得する
    $ echo foo.c
    foo.c
    $ echo !$:e
    echo .c
    .c
    

2008/11/25

Catalyst

ひかりoneではCISCOは使えないらしい
これはネタですか?ネタですよね?ネタって言ってください…

Catalyst が良いハードか悪いハードかはともかく、 KDDI のサポセンならせめて CISCO Catalyst 位は知っていて欲しい気がする。


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