opendkim lua programming(2)

前回のエントリに引き続きopendkimにluaによるフックを仕掛ける。
前回はAUTH LOGINでログインしてきたユーザ名をluaの中で取得した。
今回はodkim.sign関数を使い、DKIMの署名をしてみる。
http://www.opendkim.org/opendkim-lua.3.html

ちなみにluaを使わなくても当然ながら、署名は可能である。
ただのテストである。(もちろんその先にはちゃんと目的がある)

前提知識

以下のように設定した場合、
example.comをメッセージボディーのFROMに指定すると署名が付与される。

/etc/opendkim.conf
KeyTable    refile:/etc/opendkim/KeyTable
SigningTable    refile:/etc/opendkim/SigningTable
/etc/opendkim/SigningTable
*@example.com default._domainkey.example.com
/etc/opendkim/KeyTable
default._domainkey.example.com example.com:default:/etc/opendkim/keys/example.com/default.private
秘密鍵を生成する
$ cd /etc/opendkim/keys/example.com
$ sudo opendkim-genkey -t -s default -d example.com
$ sudo chown opendkim:opendkim /etc/opendkim/keys/* 

luaの中で署名を指定する。

設定等は前回のエントリを参考に。
前回のtest.luaに対して以下のように追記した。

test.lua

local author = odkim.get_mtasymbol(ctx, "{auth_authen}")
print ("name" .. author )
odkim.log(ctx, "name" .. author )
odkim.sign(ctx, "notdefault._domainkey.example.com")

設定ファイルも変更

/etc/opendkim/KeyTable

notdefault._domainkey.example.com example.com:notdefault:/etc/opendkim/keys/example.com/notdefault.private

default→notdefault

/etc/opendkim/SigningTable

(空)

SigningTableを空にすることでFromを判定して自動的に署名できなくなる。

秘密鍵を生成する

$ cd /etc/opendkim/keys/example.com
$ sudo opendkim-genkey -t -s notdefault -d example.com
$ sudo chown opendkim:opendkim /etc/opendkim/keys/* 

notdefaultに対応する秘密鍵を生成。

以上で準備が整った。

結果を確認する

telnetでメールを送る。
$ telnet localhost smtp
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 ESMTP Postfix
AUTH LOGIN
******
******
MAIL FROM: test@example.com
RCPT TO: test@localhost
DATA
FROM: test@example.com
Subject: hogehoge
hogehoge
.
quit
334 VXNlcm5hbWU6
334 UGFzc3dvcmQ6
235 2.7.0 Authentication successful
250 2.1.0 Ok
250 2.1.5 Ok
354 End data with <CR><LF>.<CR><LF>
250 2.0.0 Ok: queued as 6260E161C6D
221 2.0.0 Bye
Connection closed by foreign host.
メールの中身を確認する。
From test@example.com  Wed Sep 18 14:38:20 2013
Return-Path: <test@example.com>
X-Original-To: test@localhost
Delivered-To: test@localhost
Received: from localhost (localhost [127.0.0.1])
        by localhost (Postfix) with SMTP id 6260E161C6D
        for <test@localhost>; Wed, 18 Sep 2013 14:38:20 +0900 (JST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=example.com;
        s=notdefault; t=1379482700;
        bh=U84RQJxCYmPtDKg95URE0hTFEfcj3DCpcZm8uGc/KJg=;
        h=FROM:Subject:Date:From;
        b=jGAlfdVmSMU3hFd2M8K0blAcXOqHXeUkHKmAPKHbQoWyVTwFmeX39IWaeMHqN0jGx
         UHxsQL4UzWHbwMJ1079Yk7UxIhMdyFTSjGpOz2sAOeLdaWrRMjopvHnN2vg4LzXnKP
         UC/aLayB/GXBJ/DRG2BN9YT6cTH8Xu6F21A8pGeo=
FROM: test@example.com
Subject: hogehoge
Message-Id: <20130918053820.6260E161C6D@localhost>
Date: Wed, 18 Sep 2013 14:38:20 +0900 (JST)

hogehoge

「s=notdefault」などの文字列から署名が実行されたことがわかる。
次回はAUTH LOGINでログインしてきたユーザ別に署名をつけられるようにtest.luaに実装をする予定。

opendkim lua programming

opendkimのluaによるプログラミングについて備忘ログを残す。

luaプログラミング?

DKIM署名(検証)時の処理にluaで記述された処理をフックできる。

フックできる箇所は4箇所
http://www.opendkim.org/opendkim-lua.3.html

  • setup opendkimの本処理が始まる前
  • screen 検証コンテキストが始動した直後(直訳)
  • statistics 全DKIM処理が終了したが、最終的なメッセージハンドリングがおおなわれる前
  • final 全部終わった後

フックの方法
http://manpages.ubuntu.com/manpages/lucid/man5/opendkim.conf.5.html

  • FinalPolicyScript (string)
  • ScreenPolicyScript (string)
  • SetupPolicyScript (string)
  • Statisticsは無い??

目的

postfixがAUTH LOGINで受け付けたユーザのIDをopendkimで利用できるか」ということを調べる。

以下のようにmta macroを利用するとpostfixの持っている情報の一部を利用できると説明されている。
http://www.postfix.org/MILTER_README.html

設定

setupにフックしたい場合は以下のようにする。

# /etc/opendkim.conf
SetupPolicyScript /home/user/lua/test.lua

SMTP認証で認証済みのユーザ名を取得するためにauth_authenマクロを利用する。
auth_authenをログに出力してみる。

-- /home/user/lua/test.lua
local author = odkim.get_mtasymbol(ctx, "{auth_authen}")
odkim.log(ctx, "name " .. author )


Telnetで上記のスクリプトが動くか試してみる。

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 ochimina ESMTP Postfix (Ubuntu)
AUTH LOGIN
334 VXNlcm5hbWU6   
YXV0aGVu                   ☆ユーザのIDはauthen
334 ************
************
235 2.7.0 Authentication successful
MAIL FROM: ******@********
250 2.1.0 Ok
RCPT TO: ******@********
250 2.1.5 Ok
DATA 
354 End data with <CR><LF>.<CR><LF>
TITLE: test
FROM: test
data

postfixのログ(/var/log/syslog)を確認する。

# /var/log/syslog
Sep 14 03:32:23 ochimina opendkim[23645]: name authen@localhost

authen@localhostがユーザ名として出力されていることがわかる。
以上で動作確認完了。

luaプログラミングは簡単そうだ。

inodeの枯渇実験

以下の記事が面白かった。inodeが枯渇するとどうなるのかということなんだが。
http://d.hatena.ne.jp/elf/20111113/1321177077
Ext2/3/4はディスクをフォーマットした時点でinode最大数が固定されてしまう。
一方でbtrfsはinodeを動的に確保できるのでフォーマットした時点では固定されない。
ではどの程度の違いがでるのかが気になるところ。
上記の記事をもとに実験をしてみた。

実験のために10MBの空ファイルをext4/btrfsでフォーマットし、ループバックを利用してマウントする。これで10MBのディスクを仮想的に実現できる。

root@ochimina:~# dd if=/dev/zero of=$PWD/dummy.ext4 bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00525249 s, 2.0 GB/s
root@ochimina:~# dd if=/dev/zero of=$PWD/dummy.btrfs bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00943231 s, 1.1 GB/s
root@ochimina:~# mkfs.ext4 dummy.ext4 
mke2fs 1.42.5 (29-Jul-2012)
dummy.ext4 is not a block special device.
Proceed anyway? (y,n) y
Discarding device blocks: done                            
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
2560 inodes, 10240 blocks
512 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=10485760
2 block groups
8192 blocks per group, 8192 fragments per group
1280 inodes per group
Superblock backups stored on blocks: 
	8193

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
root@ochimina:~# mkfs.btrfs dummy.btrfs 

WARNING! - Btrfs v0.20-rc1 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using

SMALL VOLUME: forcing mixed metadata/data groups
Created a data/metadata chunk of size 1048576
fs created label (null) on dummy.btrfs
	nodesize 4096 leafsize 4096 sectorsize 4096 size 10.00MB
Btrfs v0.20-rc1
root@ochimina:~# mount -t ext4 -o loop dummy.ext4  /mnt/ext4/
root@ochimina:~# mount -t btrfs -o loop dummy.btrfs /mnt/btrfs/

ここで一度それぞれ(ext4/btrfs)のinodeに関する情報を見る。
ext4は最大で2560個作成できるようにフォーマットされたようだ。しかも11個なぜかすでに使用されている。
一方、btrfsは全く作られていない。(後で述べるが、もしかしたらinodeはカウントできない?)

root@ochimina:~# df -i
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/sda2      6283264 294449 5988815    5% /
none           2040855      1 2040854    1% /sys/fs/cgroup
udev           2038453    549 2037904    1% /dev
tmpfs          2040855    511 2040344    1% /run
none           2040855      3 2040852    1% /run/lock
none           2040855     10 2040845    1% /run/shm
none           2040855     18 2040837    1% /run/user
/dev/sda1            0      0       0     - /boot/efi
/dev/loop2           0      0       0     - /mnt/btrfs
/dev/loop0        2560     11    2549    1% /mnt/ext4

そしてinodeを枯渇させてみる。

root@ochimina:~# for i in $(seq 1 10000); do touch /mnt/ext4/$i; done
(省略)
touch: cannot touch ‘/mnt/ext4/2737’: No space left on device
touch: cannot touch ‘/mnt/ext4/2738’: No space left on device
touch: cannot touch ‘/mnt/ext4/2739’: No space left on device
touch: cannot touch ‘/mnt/ext4/2740’: No space left on device
touch: cannot touch ‘/mnt/ext4/2741’: No space left on device
touch: cannot touch ‘/mnt/ext4/2742’: No space left on device
touch: cannot touch ‘/mnt/ext4/2743’: No space left on device
touch: cannot touch ‘/mnt/ext4/2744’: No space left on device
(省略)
root@ochimina:~# for i in $(seq 1 10000); do touch /mnt/btrfs/$i; done
(省略)
touch: cannot touch ‘/mnt/btrfs/4867’: No space left on device
touch: cannot touch ‘/mnt/btrfs/4868’: No space left on device
touch: cannot touch ‘/mnt/btrfs/4869’: No space left on device
touch: cannot touch ‘/mnt/btrfs/4870’: No space left on device
touch: cannot touch ‘/mnt/btrfs/4871’: No space left on device
touch: cannot touch ‘/mnt/btrfs/4872’: No space left on device
touch: cannot touch ‘/mnt/btrfs/4873’: No space left on device
touch: cannot touch ‘/mnt/btrfs/4874’: No space left on device
(省略)

それぞれ(ext4/btrfs)のinodeが枯渇したところで再度inodeの状況を見る。
ext4はinodeを使い切ったことがわかるが、
btrfsは全く作られていないように見えてしまう。

root@ochimina:~# df -i
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/sda2      6283264 294461 5988803    5% /
none           2040855      1 2040854    1% /sys/fs/cgroup
udev           2038453    549 2037904    1% /dev
tmpfs          2040855    511 2040344    1% /run
none           2040855      3 2040852    1% /run/lock
none           2040855     10 2040845    1% /run/shm
none           2040855     18 2040837    1% /run/user
/dev/sda1            0      0       0     - /boot/efi
/dev/loop2           0      0       0     - /mnt/btrfs
/dev/loop0        2560   2560       0  100% /mnt/ext4

btrfsで何個ファイルが作らているのか確認できないので以下の方法で調べる。

root@ochimina:~# echo $(ls /mnt/ext4/*) | wc -w
2550
root@ochimina:~# echo $(ls /mnt/btrfs/*) | wc -w
4186

btrfsのほうが多くのinodeをつくりだしたことがわかる。
多く作れることがすごいというわけではなく、はじめに最大値をきめずに動的に確保できるという点だけが大事なのだ。


ただ追加で実験した内容で少し驚きの結果を得た。

root@ochimina:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        95G  6.8G   83G   8% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            7.8G  4.0K  7.8G   1% /dev
tmpfs           1.6G  892K  1.6G   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            7.8G  1.3M  7.8G   1% /run/shm
none            100M   20K  100M   1% /run/user
/dev/sda1        93M  121K   93M   1% /boot/efi
/dev/loop2       10M  1.6M  4.5M  26% /mnt/btrfs
/dev/loop0      8.7M  134K  8.1M   2% /mnt/ext4

作られたファイル数がbtrfsのほうが多いとしても、このディスク使用量の差には驚かされた。
Ext4のほうが空ファイルを使ったときのディスク使用量が極めて少ない。
ただしext4はSizeが8.7ということで1.3はどこかではじめから使用されていると考えられるのでそれを鑑みるとあんまり変わらない気がする。
というかよくわからんし眠たいから寝る。

以上。

ディレクトリ内のソースコードの行数を再帰的にカウントする

ふと自分が書いたソースコードが今何行か知りたい時ってある。
ちょっと自己満足に浸りたい。そんな時だ。

ひとつのファイルの行数をカウントするのは簡単。
wcコマンドを実行すればいいだけだ。

$ wc -l testfs.py 
130 testfs.py

ところがwcには再帰的にディレクトリ内のファイルを調べる機能がない。
Googleで「wc 再帰」と検索すると以下のようなエントリも見つかるが・・・
チーズバーガー中毒: wcで再帰的にディレクトリを辿ってファイルの行数を数える
クールじゃない・・・

ということで少し考えて以下のようなものを考えてみた。
(とりあえずpythonバージョンで考えてみた。)

$ for file in $(find . -name "*.py"); do wc -l $file; done

これだと各ファイルの行数はわかるが、全体で何行かわからない。

$ wc -l $(find . -name  "*.py")

これだと全体で何行かわかる。
wcが複数のファイルを渡した時に合計を出してくれるおかげだ。
もし複数のファイルを渡せないとしたら、もう少し面倒だろう。

面倒な場合で書いてみたけど、こんな感じ

for file in $(find . -name "*.py"); do lines=$(wc -l $file | awk '{ print $1 }'); sum=$(expr $sum + $lines); done; echo $sum
||<<

PythonFuseを使ってみた。

Fuseって面白いツールだと思う。簡単にファイルシステムに機能を追加できるのだから。
そしてこのライブラリはCは当然だけど、RubyやらPythonからも使える。

今回はPythonを使ってFuseを使ってみた。
OS: Ubuntu 13.04

インストールするもの

python-fuse

使い方

適当なディレクトリに適当なマウントポイントを作る
$ mkdir mnt

マウントポイントに今回のFUSEファイルシステムをマウントする。
$ ./testfs.py mnt

$ ls mnt
hoge readme.txt

$ ls mnt/hoge
test.txt

まとめ

大体こんな感じ。
ちょっと誤解していたことがあった。
get_attrでファイルの属性を返すようにしても、パーミッションチェックは自動で行われないこと。
Permissionのチェックはopenの中で書いて置かないといけない。
アクセス権限がないときは
return -errno.EACCESとするべき。

Amazon SESを(ちょっとだけ)使ってみた。

Amazon SESというサービスがあると聞いたので、どんなサービスか調べてみた。
大量メール送信サービスの一つらしい。
実際に使ってみた。

使い方

  • まずはAWS Management Consoleにアクセス。

https://console.aws.amazon.com/console/home

  • そしてSESへアクセス。

f:id:KYudy:20130514214136p:plain

  • 「Request Production Access」を実行すると使えるらしいが、申請が許可されるのに一日かかるらしいのでとりあえずパス。下記の方法でお試し的に使うことができる。
  • 「Verify a New Sender」で特別に許可するメールアドレスを追加する。今回は2つのアドレスを追加した。(送信用と受信用)
  • 確認のメッセージが登録したメールアドレス宛に届くので、メッセージ中のURLにアクセスする。
  • URLにアクセスすると晴れてメールアドレスが使用可能になる。

f:id:KYudy:20130514214223p:plain

  • 左側のVerified Senderに移動すると2つのアドレスが登録済みであることがわかる。

https://console.aws.amazon.com/ses/home?#verified-senders:email

  • 「Send a Test Email」を押すとテストメールを送ることができる。

今回の場合、2つのメールアドレスのうち、片方から送信し、もう片方で受信した。

以上。

所感

簡単に使えて、超安い。あとはどのぐらい性能が出るか(一時間あたりの流量とか)調べたいな。
あとはAPIはどんなものが提供されているか確認したい。
 

「脳のなかの幽霊」

脳のなかの幽霊(V.S. ラマチャンドラン)を読みきった。知識欲も満たされたし、読み物としても面白かった。
Amazon CAPTCHA

概要

筆者が脳の一部に欠陥をもつ患者に様々な実験を行い、その結果から得られる事実にもとづいて人間の脳の機能について明らかにしていく。
例えばその実験の対象の一つにファントムリム(幻肢)と呼ばれる、存在しない手足が存在するように錯覚するという現象がある。ファントムリムに対して筆者は左右の手を鏡で仕切る装置を用意し、存在しない片手をあたかも存在するように見せることで「幻肢の切断」に成功している。

面白かったトピック

  • ファントムリム
  • 身体と心が一対一で不変であるという思い込みの脆さ
  • シャルルボネシンドローム
  • 否認
  • 面白い話に共通する特徴
  • サッカリンとクロスファミドのマウスへの同時投与
  • クオリア問題

所感

無意識的な脳の活動を本書では「ゾンビ」と呼んでいる。そのゾンビの活動が脳の活動の90%を占めるらしい。本書で出てくる症例の多くが、ゾンビがうまく機能しない場合は日常生活に大きな支障を及ぼすことを示している。
またゾンビが意識に対して及ぼす影響も大きいことがわかる。例えば「否認」と呼ばれる症状においては、自己防衛のために記憶まで改ざんされることがわかる。
私達の日頃の言動や認識は実はゾンビに大きく左右されているのだ。これは少し怖い気もする。自分たちの意識が実は無意識の影かもしれないのだ。
「我思う故に我あり」とか言っている自意識が実は無意識の影だとしたらなんとも滑稽だ。
もっと無意識について多くのことを把握し、その特性や自意識との関わりを理解したい。
理解がすすめば、「自己実現」が用意になったり、うつ病の治療方法が分かる日が来るのかもしれない。
続編がでているのでそちらも読みたい。http://www.amazon.co.jp/%E8%84%B3%E3%81%AE%E3%81%AA%E3%81%8B%E3%81%AE%E5%B9%BD%E9%9C%8A%E3%80%81%E3%81%B5%E3%81%9F%E3%81%9F%E3%81%B3-%E8%A7%92%E5%B7%9D%E6%96%87%E5%BA%AB-%EF%BC%B6%E3%83%BB%EF%BC%B3%E3%83%BB%E3%83%A9%E3%83%9E%E3%83%81%E3%83%A3%E3%83%B3%E3%83%89%E3%83%A9%E3%83%B3/dp/4042982166/ref=pd_bxgy_b_img_y/378-8288823-7720935