トップ «前の日(08-06) 最新 次の日(08-08)» 追記

2003-08-07

_ もう一度住基ネットのダメさ加減を思い出して落ち込んでみる

http://www.mainichi.co.jp/digital/network/archive/200308/06/1.html

現場で運用している人間(少なくとも実情がパーフェクトに分かっている人間。管理者とは名ばかりで実態が把握できていないことがこれまで何度も起きてきた問題なので。)と、総務省側の運用担当が本音で語ったうえで内部告発しないとダメなんじゃないかな。これ。

まぁものすごく非現実的ですが。アングラ掲示板とか(それこそ Winny か?)なら可能なんじゃないかな。でもアングラ掲示板が利用できるレベルの人が運用しているなら、そこからちゃんと勉強したと仮定すればそれなりに信用できるかもしれない。

あと、桜井さんはネックワークについてそれほど強くないのが戦術から見てとれるので、喋りが立たなくてもいいから、もっと詳しい人を連れてきた方がいいと思う。繋がっていることは確かに問題だが、運用次第でどうにかなるのは事実。繋がっていることだけ叩き続けてもラチがあかない。いちばんの問題は運用がまったくもって信用できないってことでしょ。

この手の話は喋りのうまい目立つ人同士がやり合ったって、テレビで片山さんががなり立てていたのと大差ないと思うんだな。

  • チェックさせている(自分はチェックしていない)
  • 危険性がある可能性がある。(具体的で詳細な危険を列挙できていない)

これで議論として成り立つわけがない。言い方は悪いが熊さん八っつぁんレベルですよ。知らない人と分からない人の議論は徒労。

振り出しに戻していいのなら、住基ネットのいちばんの問題は、総務省は認めていないがまず嘘をついていたこと。これで国民の信頼を裏切ったわけだから、まず信頼回復を図るのが正しい手順。なのに我々のやっていることは正しく、セキュリティは万全だと言い張っている。

そんなやり方で納得できる大人が居るわけないだろ。

まず謝罪。片山さんは当然クビでしょ。あんな声のでかいだけの人が大臣で居るだけで問題だっての。で、それから国民を納得させるものを出せ。それができないのならそれについても謝罪だ。

あと、現場の運用担当者はセキュリティ関係のオープンな試験を受けるべき。(受験者の名簿から担当者がバレないようにしないといけないけど。)みんなが納得できるレベルであることを示さなければいけない。研修? そんなもの形だけで役に立たないことなんて、みんなが知ってますよ。ばかにするのもたいがいにしなさいっての。

それから、自治体の端末から被害が他に拡大することはないなんて言うけど、そういう問題じゃ……

切りがないのでこの辺で。

Tags: Security

_ へぇへぇへぇ(違

http://slashdot.jp/journal.pl?op=display&uid=277&id=145638

ZWiki Trakcer ですか。

試す時間がちょっとないけど。

Tags: Tool

_ make world キタ━━━━━(゜∀゜)━━━━━!!!!

http://www.zdnet.co.jp/enterprise/0308/07/epn11.html

へいへい。

Tags: Unix Security

2004-08-07

_ 動き始める

FreeBSD 4.10R を入れて3時間ほどでどうにか ssh は繋がるようになる。sshd_config の設定をバックアップしていたものに戻したつもりだったが、なぜか上書きできていなくて password 認証が始まったときにはちょっと焦ったが、それも今は大丈夫。

もっと早いかと思っていたが、これくらいのスペックのマシンだとどうしても細かい ports の build に時間を取られる。最初にハマったのは cvsup. 長いよこれ。実際に長いのは cvsup じゃなくて ezm3 や周辺ツールだけどさすがに長いと感じる。しかもこれを make してるときの手元の ports ツリーは最新じゃないんだから、わざわざ ports であるメリットはなかったのかも。まぁ「待っているだけでいい」っていう気楽さはあるんだけど。

で、初回の cvsup 完了までがまた長い。FreeBSD は最初に必要なバイナリをすべて CD-ROM 1枚で入れることができるのでインストールは速いが、それ以降のセットアップはバイナリで芋づるインストールできる Debian の方が早いな、こりゃ。

今ハマっているのは ircd. 前回も ircd はしばらく悩んだが、今回は今まで使っていた ircd-hybrid のバージョンが上がって設定ファイルの書き方が完全に別物になってしまった。うげーと思って他のものを試すがうまく動かず。なんでだーと思ってあちこち調べると、どうも ircd の設定ファイルは IP v6 絡みで解釈に失敗するみたいだ。: でデータを区切るなと。つーことで諦めて新しい ircd-hybrid の設定ファイルを攻略しますか。慣れればこの書き方の方がはるかに人間にやさしい。

Tags: Unix 日々

_ ircd の次は PHP と Zebedee

ircd はこれを書いてほどなくして動いたんだけど、そのあとハマっているのは

  • PHP
  • Zebedee

PHP はなんか ports の build 方法が変わっちゃったのでまだまともな状態で動かせてない。

Zebedee は ports で入れたら 2.5.2 が入ったんだけど、どうも 2.5.1 以前と互換性がなくなったらしい。互換性のためのオプションを有効にしてみても 2.4.1 と繋がらない。2.4.1 を野良 build するかなぁ。と思いながら思案中。幸い面倒な依存関係はないしな。

Tags: 日々

2005-08-07

_ 高音質とPC

Re:この高音質 (オンキョーがCD以上の高品質で音楽配信に参入 /.-j)

PC の劣悪な環境でノイズを減らし、クリアな音を楽しむための機器をオンキョーが扱っていると。音楽配信として見ると?だけど、製品のアピールにはなるのか。なるほどなぁ。毛色の違う iTunes Music Store + iPod 戦略か。

Tags: Music

_ 今さら SW EPISODE III

見た。

威張って言うことではないが、実は今年までスターウォーズは一つもまともに見たことがなかった。テレビでデジタルリマスターを何回もやるので 4, 5 を見た。吹き替え。先が気になったのでビデオを借りて 6 を見た。これも吹き替え。

ファンの人には大変申し訳ないが、感想としては「なんだこのショボイ設定の映画は」であった。正直、この映画が世界中で大ヒットしている理由がさっぱり分からない。どういうことだ、自分の感性はそんなにも鈍いのか。いやいやいや、だってダースヴェイダーはどう考えても単に部下を恐怖で縛ったうえに見殺しにするダメ中間管理職だし、フォースを侮ったやつにはすぐ手を出すし、組織の中に居るべき人間じゃない。

フォースはフォースで、できることはライトセイバーを使うこととサイコキネシスと、意識の低いものの気をそらせるくらいで、思ったほどすごい能力のように見えない。まぁ身体能力の補助に使うことで超人的な活躍はできるみたいだけど、ラスボスの最終攻撃がなんか電撃みたいなやつで「うわー」って。え、これがダークサイドの必殺技?って。

おまけに後だし後だしで実は父ちゃんとか実は双子とか、そんなんありかと。明らかに最初は年齢差のある設定じゃなかったか、おいと。双子ってどないやねんと。

ところが。

ところがだね。

EPISODE III は面白かったんだな、これが。

そこで思った。まず自分は映画には映像美を求めていると。自分の中では SF ものの古い映像はどうもまったくおいしくないらしい。映像のアラに目がいくのと同時に設定のアラがどんどん気になってきてしまう。いやー CG 万歳。

あと、ハリウッド映画にありがちな「いがみあってた5秒後にチュー」のような男女の絡め方がきらいなので、そういう意味でも 4, 5, 6 はダメなんだなぁ。

ただ、最初っから全部字幕で見てたら、あるいはまだマシだったかもしれないと少しだけ思う。というのも、今回 EPISODE III は劇場で字幕版を見たわけだけど、これがセリフ回しに Web 上というか IT 系の人が好んで使うネタがゴロゴロしてて「あぁ、これが元ネタか」という発見があったり、ヨーダの喋りはオリジナルの語順じゃないと雰囲気が出ないと感じたりしたから。

最後に一つだけ。ダースヴェイダーだろうがアナキンだろうが、彼は力がずば抜けているだけでバカだと思うんだがどうか? いや面白かったんですよ、今回は。悲劇はきらいじゃないし。(SEVEN とか好き。)でもね。やっぱこいつはバカだなと。

ちなみに、1 と 2 は見ていない。見る必要ないなーって思ったんでたぶんこの先も見ない。

Tags: 日々 Movie

2006-08-07

_ ploticus FAQ 日本語訳

Ploticus FAQ

前からやろうやろうとは思っていながら放置になっていた ploticus ドキュメントの和訳なんだけど、とりあえず FAQ については見つけた。助かる。

ploticus は非対話的に二次元グラフを作成するツール。まぁ簡単に言うと Excel とか OOo とか使わなくてもサーバ上のログなんかからグラフを生成できるものだと自分は解釈している。

サーバ上のデータを使ってグラフを作るっていうのは mrtg, Webalizer なんかを見れば分かるように今のところプログラムがそれぞれ別個にグラフ作成をやっちゃってて、独自のグラフを起こすことができない。いやまぁ独自に GD とかとお喋りすればいいわけですけど。

そんなわけでこれは割と使えるんじゃないかなーと以前から目をつけてはいるんだけど、ちっともブレイクする気配がないのでそういう需要ってないのかなーとまたいつものように「どうせオレの趣味はマイナーだよ、いじいじ」モードになっていたところ、ふと FAQ の日本語訳を見つけたので少し機嫌がよくなりましたまる。

http://ploticus.sourceforge.net/

Tags: Tool

2010-08-07

_ tarアーカイブにファイルを追加する

あるいは保管目的のログファイルの整理ポリシーを変えましたの話。

結論

.tar.gz -> .gzs.tar

にします。

before
複数のログファイルを tar でまとめて gzip などで固める
after
それぞれのログファイルを gzip などで縮めて tar で固める

背景

保管するログファイルの扱いに困っていました。いや、実際には困っていたというよりはなんとなくあんまりうまくないなぁという程度の感覚でやっていたわけですが。

複数のファイルを保管目的でバックアップする場合、多くはディスク容量の節約をするため tar + gzip などの方法で圧縮していると思います。しかし

この方法はけっこう贅沢なディスクの使い方だ

ということに気がつきました。

問題

多くの、そして古い Un*x の教科書的なドキュメントにはバックアップに tar + gzip を利用する方法が書かれています。しかしこの方法では

tar + gzip を実行するタイミングまではログは生のサイズのまま

なのです。

例えば「月1回ログをまとめて圧縮する」というスケジュールにすると1ヶ月間はログは生のサイズのままです。けっこうな大きさになります。

しかしこの1ヶ月という期間の設定はよくあるパターンかなと思います。あとで DVD などに退避させる際にはこれくらいの期間で置いてあると何かと使い勝手がよいです。

個人では 1TB がヨユーで買えてしまうこのご時世ですが、お仕事的には経費が掛けられないものすごく厳しい状況が続いていますので、生ログのサイズのままハードディスクに置いておくのはできるだけやりたくありません。

試行

そこで

tar.gz のアーカイブにログファイルを append できたら便利じゃね?

と思いつきました。でも結論から言うとどうもこれはできないらしい。まぁ普通に考えてかなり無駄というか無茶な処理ですよね。tar はなぜ失敗したのか分からないけど失敗、cpio の場合は圧縮と append は同時にできねーよ、とはっきり怒ってくれます。

そこで、

rotate と同じ要領で先に gzip しといて tar にまとめりゃいいのか

と気づきました。

解決

何を言ってるか分からないかもしれないのでテストスクリプトを書きました。

  1. まずダミーのファイルを作って途中までをそれぞれgzipで圧縮してtarアーカイブを作る
  2. その段階でのアーカイブの中身を表示
  3. 残りのファイルをgzip圧縮してtarballにappend
  4. アーカイブの中身を表示

しています。ちゃんと追加されている様子が分かります。

これで、

  1. アーカイブファイルの名前を年月などから自動決定する
  2. そのファイルがすでにあればそこに append なければ新規作成

するスクリプトに仕立て上げれば全自動でディスクを節約するアーカイブのできあがりでしょうか。

これなら時期を見て DVD などに退避させる際にも対象のファイルはすでに圧縮してアーカイブ済みなので、えっちらおっちら圧縮する手間と時間も削減できます。

一石二鳥。

Tags: Sysadmin

2011-08-07

_ JavaScriptとCSSの構文チェッカ2011

まとめ

npm に便利ツールが揃ってきてる。

果たして JavaScript という言語が構文チェッカに向いているのか自分には分からないんだけど*1、昔と違って全部 JavaScript で済むという環境が本当に揃ってきていて、かつては Perl などで書かれていたツールが今は JavaScript に集約されつつあるみたい。

とりあえず jshint, csslint をうまく使えるようにしていきたい。

背景

ここ数年は Firebug などのブラウザ上の強力なデバッガ、チェッカが活躍する機会が多かったけれども、とは言え

いちいち目的のページを手で開いてチェッカのレポート、あるいは警告やエラーの出ないことをを目視確認するのはバカバカしい

とずっと思っていた。また手動&目視は作業者のレベルに大きく左右されてしまうのも問題。「ちゃんとチェックしてよ」と言わずに済むならその方が嬉しい。言う手間も含めて省力化できるし、漏れも防げる。

手作りの HTML についてはだいぶ前に

簡単なWeb作り向けRakefile作った

なんてものを作って

  • HTML tidy
  • linkchecker

を利用していた*2んだけど、やはり

  • JavaScript
  • CSS

も対象にしたい。もちろん

The W3C Markup Validation Service

はあるんだけど、

  • ローカルだけで
  • できるだけサクっと利用できる

ものが欲しい。ということで改めて探してみると最近は JavaScript 製で揃ってきているみたい。

リスト

JSLint

最初に JavaScript 製のツールがキテるっぽいと思ったのはこの名前を聞いてから。

もちろんサイトが有名なんだけど、

npm install -g jslint

するとコマンドがインストールできる(もちろん今のところ Un*x 系の環境が必要)。

最近 Emacs 22 + js2-mode から Emacs 23 + js-mode に移行したので以前よりチェックが甘くなってしまって IE のバグを踏んで苦しんだのもこれを使おうと思ったきっかけ。

ただし jslint はちょっと不評な面もあるらしい。

JSHint

ということで fork したのがこれ。

同じく

npm install -g jshint

でインストールでき、実行ファイルが入る。これについては

jshint4rというものを作りました

Rubygems で入れられるバージョンを作ってみたので Windows の人も試してみてね。

JavaScript Lint

JavaScript Lint

Win, Mac, Linux 用バイナリがあるんだけど、止まってるっぽいなぁ、これ。

csslint

npm search すればイロイロ出てくるんだなと試して見つけたのがコレ。

あ、今見ると IDEA*IDEA で紹介されてるのか。知らなかった。

動かしてみると selector に ID 使うんじゃないとか言われる。ん? 最近はそういう常識なの? メンテナンス性の項目に入ってるみたい。なるほど…。

JS[LH]int ほどにはこうやって使ってみてる、みたいな日本語記事を見かけないけど、評判はそれなりにいいみたい。   CSSTidy ってのもあって最適化もしてくれるんだけど、今後は期待できそうにないかなぁ。

*1 少なくとも Ecma レベルだと全然機能が足りないと思うんだけど、node.js 環境なら十分便利なのかも。

*2 と言っても実際の利用機会は作った時期から半年程度で今はほとんどないんだけど


2016-08-07

_ SinatraとOmniAuthで学ぶRack middleware

なんかどうも OmniAuth を使おうと思ったらまず Session を有効にしろやと言われたり言われなかったりするので久しぶりにがっつりコードリーディングしてみた。

以下のバージョンで確認した。

  • Sinatra 1.4.7
  • Rack 1.6.4
  • OmniAuth 1.3.1

まとめ

  1. rack middlewareは記述順に依存する
    • 具体的には OmniAuth の前に Rack::Session を use しておかないとダメ
    • なぜなら OmniAuth は session を利用できる前提で書かれているから
  2. rack middlewareの組み立てられ方
    • より正確にはアプリケーション本体をいちばん内側に包むたまねぎ構造
  3. sinatraのset :sessions, trueはどこに書いてもよい
    • set :sessions, true は書く位置を自由にできるが、use Rack::Session::Cookie は明らかに上の方に書かないとダメな理由

1. rack middlewareは記述順に依存する

具体的には OmniAuth の前に Rack::Session を use しておかないとダメ。やっておかないと以下のようなエラーになる。

OmniAuth::NoSessionError at /
You must provide a session to use OmniAuth.

エラーを吐いてるのはここ。

def call!(env)
  unless env['rack.session']
    error = OmniAuth::NoSessionError.new('You must provide a session to use OmniAuth.')
    fail(error)
  end

なぜなら OmniAuth は session を利用できる前提で書かれているから。まぁそりゃそうかという気がするけど、そもそも rack middleware の順番てどういうことなのか?

2. rack middlewareの組み立てられ方

rack middleware の組み立て方の正解は Rack 付属のサンプルアプリである Lobster の中身を見てみるとよく分かる。

lobster.ru

require 'rack/lobster'

use Rack::ShowExceptions
run Rack::Lobster.new

この rack/lobster の中身はどうでもよく、いちばん最後、

if $0 == __FILE__
  require 'rack'
  require 'rack/showexceptions'
  Rack::Server.start(
    :app  => Rack::ShowExceptions.new(Rack::Lint.new(Rack::Lobster.new)),
    :Port => 9292
  )
end

こういう記述がある。lobster.ru の

use Rack::ShowExceptions
run Rack::Lobster.new

Rack::ShowExceptions.new(Rack::Lobster.new)

と等価であることが分かる。つまり、middleware がアプリケーション本体をくるんでいる状態。

分かる。って書いたけど、じゃあ実際に自分で書いたアプリがどう解釈されるのかも見ておこう。ちょっと長いけど、良い子は我慢してつきあってくれ。本当は別にそれっぽい知識はすでにあるのでまったく読み込む必要はなかったんだけど、改めて追いかけてみようかなと

Rack のソースコード読んでる - 大学生からの Web 開発

を見て「そういや読もうと思えば読めるじゃん」と思ったので、use と run がどのように処理されるかを辿ってみた。

実際にはこの辺りは Rack::Server#start の中の wrapped_app から build_app app を呼んでる辺り、

def wrapped_app
  @wrapped_app ||= build_app app
end
def build_app(app)
  middleware[options[:environment]].reverse_each do |middleware|
    middleware = middleware.call(self) if middleware.respond_to?(:call)
    next unless middleware
    klass, *args = middleware
    app = klass.new(app, *args)
  end
  app
end

この app が実引数の名前もメソッドの名前も同じなのが混乱してしまうが、

def app
  @app ||= options[:builder] ? build_app_from_string : build_app_and_options_from_config
end

で、rackup 起動時に何も与えなかった場合はこっちが呼ばれる。

def build_app_and_options_from_config
  if !::File.exist? options[:config]
    abort "configuration #{options[:config]} not found"
  end

  app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
  self.options.merge! options
  app
end

Rack::Builder.parse_file は最後

def self.new_from_string(builder_script, file="(rackup)")
 eval "Rack::Builder.new {\n" + builder_script + "\n}.to_app",
   TOPLEVEL_BINDING, file, 0
end

を呼んで、豪快に eval の結果を Rack::Builder.new

def initialize(default_app = nil,&block)
  @use, @map, @run, @warmup = [], nil, default_app, nil
  instance_eval(&block) if block_given?
end

に渡す手法を見せ、ここで Rack::Builder#use, Rack::Builder#run が呼ばれる。

def use(middleware, *args, &block)
  if @map
    mapping, @map = @map, nil
    @use << proc { |app| generate_map app, mapping }
  end
  @use << proc { |app| middleware.new(app, *args, &block) }
end

use の中では先ほどの initialize で初期化した @use という Array に middleware が順番に突っ込まれているのが分かる。run はこれだけ。

def run(app)
  @run = app
end

さて、Rack の仕様で、 とにかく実行時には call が呼ばれる のは知ってるよね? call を見てみよう。

def call(env)
  to_app.call(env)
end

to_app はこう。

def to_app
  app = @map ? generate_map(@run, @map) : @run
  fail "missing run or map statement" unless app
  app = @use.reverse.inject(app) { |a,e| e[a] }
  @warmup.call(app) if @warmup
  app
end

ここに先ほどの @use も @run も出てくる。ポイントは実にあっさり書かれてるここ。

app = @use.reverse.inject(app) { |a,e| e[a] }

ここで use したものが逆順に wrap されていってる。わーあっさり。

確認していこう。

  • e は use のところで proc {} で生成されている Proc オブジェクト
  • a は予想通り middleware オブジェクト
e[a]

で Proc オブジェクトが実行される*1んだけど、最初の app は run されるもの、例えば Sinatra の classic style なら Sinatra::Application で、inject なので e に渡るのはすべて実行結果の app になる。つまり

2回目の e[a] は最後に use された middleware に本体の app を与えた結果のアプリ

であり、順番に遡っていくので、結果

Rack::ShowExceptions.new(Rack::Lobster.new)

こういうことになる。

これで call というメソッドを持つ middleware オブジェクトで wrap されるたまねぎ構造が実現される。

実に面倒な処理だが、これは先ほども見たように Rack::Server の app にメモ化されているので、最初の一回だけ実行される。

3. Sinatraのset :sessions, trueは記述順を緩和してくれる

Sinatra::Baseの中にこんな記述があって、

def build(app)
  builder = Rack::Builder.new
  setup_default_middleware builder
  setup_middleware builder
  builder.run app
  builder
end
  • setup_default_middleware
  • setup_middleware

の順番がキモっぽいなというのが分かる。

def setup_default_middleware(builder)
  builder.use ExtendedRack
  builder.use ShowExceptions       if show_exceptions?
  builder.use Rack::MethodOverride if method_override?
  builder.use Rack::Head
  setup_logging    builder
  setup_sessions   builder
  setup_protection builder
end
def setup_middleware(builder)
  middleware.each { |c,a,b| builder.use(c, *a, &b) }
end

setup_middleware の方は中で use を呼んでいるので例のアレ。

setup_default_middleware の中の setup_sessions がそれっぽいので読むと

def setup_sessions(builder)
  return unless sessions?
  options = {}
  options[:secret] = session_secret if session_secret?
  options.merge! sessions.to_hash if sessions.respond_to? :to_hash
  builder.use Rack::Session::Cookie, options
end

まさにここで use OmniAuth の前に use Rack::Session::Cookie が呼ばれている。

ちなみに sessions? って何?って感じだけど、これは set :sessions, true に関係している。

def set(option, value = (not_set = true), ignore_setter = false, &block)
  (snip)

  define_singleton("#{option}=", setter) if setter
  define_singleton(option, getter) if getter
  define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
  self
end

どうもここで sessions? っていうメソッドが定義されてるっぽい? define_singleton を読むと、

def define_singleton(name, content = Proc.new)
  # replace with call to singleton_class once we're 1.9 only
  (class << self; self; end).class_eval do
    undef_method(name) if method_defined? name
    String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
  end
end

わーい黒い黒ーい。値を返すメソッドが定義されてる。つまり

set :sessions, true

def sessions
  true
end
def sessions?
  true
end

が定義される。 setup_sessions にもう一度戻ると set :sessions, true が実行されていれば use Rack::Session::Cookie が OmniAuth など通常の middleware よりも先に実行される。なぜなら default middleware だから。

です。

なるほどね!

おまけ - OmniAuthのproviderをuseしてないのでは?

ちなみに

Sinatra Recipes - Middleware - Twitter Authentication With Omniauth

にある

use OmniAuth::Builder do
  provider :twitter, ENV['CONSUMER_KEY'], ENV['CONSUMER_SECRET']
end

この書き方って OmniAuth::Builder は use してるけど provider は use してなくね? って気がしたんだけど、

def provider(klass, *args, &block)
  if klass.is_a?(Class)
    middleware = klass
  else
    begin
      middleware = OmniAuth::Strategies.const_get("#{OmniAuth::Utils.camelize(klass.to_s)}")
    rescue NameError
      raise(LoadError.new("Could not find matching strategy for #{klass.inspect}. You may need to install an additional gem (such as omniauth-#{klass})."))
    end
  end

  args.last.is_a?(Hash) ? args.push(options.merge(args.pop)) : args.push(options)
  use middleware, *args, &block
end

てことでちゃんと最後に OmniAuth::Strategies::Twitter を普通に use してました。名前空間を提供しつつ use するだけの人は楽をできる DSL ステキ。ステキだけど、分からないとこわい。そんな感じ。

ただ、読んでみて思ったけど Sinatra も Rack も面倒な処理してて遅そうだなーという気がするね…。

参考

*1 これは Rack の機能ではなく単に Ruby の Proc オブジェクトの [] メソッドを呼んでるだけ