Sequel作者のブログで、不用意にrespond_to?,const_defined?などのメソッドを使っているとDoSされる可能性があると書かれてます。
RubyのSymbolはGCされない→外部から任意のSymbolを生成されればメモリがどんどん食われていく→respond_to?などのメソッドは内部的にSymbolを生成している→その手のメソッドにユーザー入力値渡してたらまずいんじゃね?
という話で、具体的にはActiveRecordでattr_accessibleを使ってないときに該当するらしいです。
Sequelはrespond_to?('any_method')をpublic_methods.map{|x| x.to_s}.include?('any_method')のように書き換えることで対応したとのこと。Sequelはmap(&:to_s)した値をキャッシュで保持してるのでこんな書き方になってますが、一般的にはpublic_methods.find{|x| x.to_s == 'any_method'}かな。スコープやrespond_to?の使われ方によって対策は変わってきますので自分の環境に合わせて修正しましょう。
ユーザー入力値の取り扱いに限らず、全体のSymbol数が無限に増えていくような実装をしてるとセルフで死ぬのでそのへんもあれば書き換えましょう。
前職を辞めたのが3月初め、そのすぐあとに地震があって色々あって6月2日からシドニーに居ます。
現地で知り合った人にiPhone買うのを手伝ってもらったり英語教えてもらったり、プログラマだと言ったら「ハッキングとかできるんすか!」って言われたのでjQuery Mobile公式サイトのXSSで遊んだりHacker Typerで遊んだりしてます。
あと変な看板とか。
GNU Parallelがすごすぎて生きるのがつらい
GNU Parallel いいかもね
xargsでもできるよ!
$ yes | head -n10 | sed 's/.*/localhost/g' > server.list
$ xargs -P0 -t -a server.list -I% ssh % "vmstat 1 2|tail -1"
ssh localhost vmstat 1 2|tail -1
ssh localhost vmstat 1 2|tail -1
ssh localhost vmstat 1 2|tail -1
ssh localhost vmstat 1 2|tail -1
ssh localhost vmstat 1 2|tail -1
ssh localhost vmstat 1 2|tail -1
ssh localhost vmstat 1 2|tail -1
ssh localhost vmstat 1 2|tail -1
ssh localhost vmstat 1 2|tail -1
ssh localhost vmstat 1 2|tail -1
2 0 401076 84588 24092 412008 0 0 0 100 7011 16057 8 5 87 0
2 0 401076 86820 24092 412008 0 0 0 100 7045 15172 8 4 89 0
4 0 401076 86820 24092 412008 0 0 0 100 7048 15185 8 4 89 0
2 0 401076 91936 24092 412008 0 0 0 100 7122 14943 8 3 89 0
4 0 401076 93280 24092 412008 0 0 0 100 7230 14676 8 3 89 0
5 0 401076 93280 24092 412008 0 0 0 100 7228 14680 8 3 90 0
5 0 401076 98052 24092 412008 0 0 0 100 7231 14522 8 2 90 0
2 0 401076 100712 24092 412008 0 0 0 100 7283 14499 8 2 90 0
3 0 401076 103272 24092 412008 0 0 0 100 7398 14547 8 2 90 0
3 0 401076 106156 24092 412008 0 0 0 100 7480 14606 7 3 90 0
--max-procs=max-procs
-P max-procs
Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many
processes as possible at a time. Use the -n option with -P; otherwise chances are that only one exec
will be done.
-P0でとにかくいっぱい並行処理される。-P8だと8プロセスが並行して走る感じ。makeの-jと同じかな。
xargsが実行したコマンドの内容。上の処理結果のssh localhost vmstat 1 2|tail -1の部分。別になくてもいいけど確認したいとき便利。
find .. | xargsだとfindの結果をSTDINから受け取って処理するけど、-a fileオプションはfileの内容を受け取って処理する。
xargsが後続するコマンドに渡す引数の部分を%で指定する変数みたいなもの。ssh %はssh localhostに展開される。
DotCloudのベータ招待権が届いたので適当に触って遊んでいました。DotCloudは簡単にいえば、Rubyサーバ、PHPサーバ、MySQLサーバなどを簡単なコマンド(たとえばdotcloud deploy -t ruby mynamespace.ruby)でセットアップできるサービスです。SSHで直接サーバにログインしたりもできます。
PostgreSQLサーバをセットアップして、別に立てたRubyサーバから接続しようとしたときにふと「postgresqlってデフォルト設定では外部からの接続を拒否してたよな」と思い至り、/etc/postgresql/9.0/main/pg_hba.confを見てみると以下のような行がありました。
# Allow access from any host to any databse with anyuser using a password :
# TYPE DATABASE USER CIDR-ADDRESS METHOD
host all all 0.0.0.0/0 md5
# *************************
## ↑これ
# *************************
# "local" is for Unix domain socket connections only
local all all ident
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
最初のところですべてのデータベースに対してすべてのホストからの接続を許可(all all 0.0.0.0/0)しています。これは少なくともUbuntuのaptにあるpostgresqlにはない設定で、DotCloudが追加したものだと思います。そのあとで127.0.0.1/32とあるように、aptからインストールした直後の設定では、接続元が自分自身であるアクセスのみ許可されています(ちなみにこの127.0.0.1/32の設定は0.0.0.0/0の完全なサブセットとなるため無用です)。実際、自分が立てたPostgreSQLサーバに手元からpsql -U foo -p 3333 -h pg.mynamespace.dotcloud.com postgresのようなコマンドでpostgresデータベースに接続できました(ポート番号はランダムに割り振られます)。
この設定はDotCloudの仕様上しかたないことです。PostgreSQLサーバと他の、例えばRubyサーバは別のAmazon EC2インスタンスであり同一LAN内にあるわけではなく、IPアドレスが特定のセグメントにまとまってる保証もないため、接続元の制限は事実上使えません。またDotCloudに限らずクラウドを使うときすべてにいえるでしょう。
クラウド以前の古式ゆかしい構成では、DBサーバなど外部に公開する必要のないサーバは外部からの接続をいったん全拒否し、特定のホスト/IPアドレスからのみ許可といった感じで、L4レベルで接続を規制してたと思います。
postgresユーザー(MySQLでいうroot)のパスワードを簡単なものに変更したり、ブルートフォースに弱そうなスーパーユーザーを作ると、外部からシステムデータベースに接続されて好き勝手される可能性があります。ポート番号はいちおうサーバごとにランダムになりますし、pg.mynamespace.dotcloud.comのようなホスト名も秘匿されてはいますが気休めでしょう。
またdotcloudサーバ同士の接続だと10.*.*.*のようなVPNっぽいアドレスになるように見えますが、DotCloudが0.0.0.0/0とわざわざ設定してることから、特にそういう仕様ではなくたまたまそうだっただけかもしれません。
以上を踏まえて、DotCloudのデフォルトから少しだけ制限を厳しくします。
# 削除して追加
host redmine red 0.0.0.0/0 md5
# "local" is for Unix domain socket connections only
local all all ident
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
これでredmineデータベースにredユーザーが接続する場合のみ外部からの接続が許可されます。運用においてはRubyサーバのIPアドレスを把握して0.0.0.0/0をそのアドレスにするとよりベターです。
もちろんGRANTをきっちり管理するとかわかりやすいパスワードを使わないとか、そもそもここに書いたことは常識すぎて今さら何を言ってるんだお前はレベルの内容ですが、ファイアウォールの下で好き勝手やってたゆとり世代なので油断しがちなのです。試してませんがドキュメントを見るかぎりPostgreSQLに限らずMySQLも同様の状態だと思います。MySQLをskip-grant-tablesすると愉快な事態になるので絶対にやめましょう。あなたは素っ裸です。
どうでもいいけど「cloud」って書こうとするとかなり高確率で「clound」と入力してしまうのでcloudって単語は好きじゃないです。