絵描きのzfs snapshot活用術
あっ、線画レイヤーに色塗ってる!
突然ですが、私、趣味で絵を描きます(NSFWです)
絵描きあるあるが「線画レイヤーに色を直接塗ってしまっており、それに気づくことなく作業をガンガン進めてしまい、気づいたら手遅れなところまで進んでしまっている」という事故です。ご丁寧に保存しちゃってたりするともはや後には戻れません。なんとか、お絵かきソフトを駆使して線画と中の色塗りの部分を分離するみたいなことをするしかないです。とてもとても面倒くさいです。
なので考えました。せっかくzfsのNASを組んだのだから、zfs snapshotで一時間ごとに絵のファイルが保存されてる作業フォルダのスナップショットを取っておけばよいのでは?と。そしたら、ミスに気づいた時点で過去のスナップショットをさかのぼって、そこから色が塗られちゃう前の古い作業データの線画レイヤだけ取り出して現作業ファイルにコピペすればらくらく回復できます。
というわけで、さっそくやってみました。
まず、定期zfs snapshot。cronとかつかって自分でやってもいいですが面倒ですよね。ここはsanoidっていうツールがあるのでこれを使います。
Pythonで書かれてるっぽいです。まあ、Debianだったらapt-getでインストールできますので楽ちん。
$ sudo apt install sanoid
んで、次に設定ファイル。/etc/sanoid/sanoid.conf
に設定ファイルあるので、emacsだかviだかで編集します。私はこんな感じにしました。
[tank/working] use_template = template_daily [template_daily] hourly = 24 daily = 7 monthly = 0 yearly = 0 autosnap = yes autoprune = yes
tank/working
というzfsがイラストのファイルが入ってる領域です。これをsambaで外部に公開して、Windowsからマウントして使ってる感じです。
hourly = 24
で一日に一時間に一回snapshotを取り、daily = 7
で一日一個。保存する感じにしてます。多分これであってる。。。sanoid.conf
を編集したら、sanoidを再起動しときます。
$ sudo systemctl restart sanoid
これで、定期的にsnapshotが取れます。
root@liella:/home/takahashi# zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT tank/working@autosnap_2022-03-13_00:22:35_monthly 0B - 4.81G - tank/working@autosnap_2022-03-13_00:22:35_daily 0B - 4.81G - tank/working@autosnap_2022-03-13_00:22:35_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_01:00:01_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_02:00:24_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_03:00:24_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_04:00:24_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_05:00:24_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_06:00:24_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_07:00:24_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_08:00:01_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_09:00:01_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_10:00:01_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_11:00:24_hourly 0B - 4.81G - tank/working@autosnap_2022-03-13_12:00:24_hourly 0B - 4.81G -
この設定で一時間に一枚snapshot取れてます。
特定の場所だけsnapshot取りたい!
余談ですが、zfsでスナップショットを取る場合は、zfsのファイルシステム(か、zvol)単位になります。つまりzfs内部にある特定のディレクトリだけsnapshotを取る!みたいなことはできないわけです。
root@liella:/home/takahashi# zfs list NAME USED AVAIL REFER MOUNTPOINT tank 1.65T 12.8T 1.64T /tank
例えば、こんなzfsがあったとしましょう。ここで、/tank
ディレクトリの下にoekaki
みたいなディレクトリを作り、このoekaki
ディレクトリ内部だけのsnapshotを取りたい!みたいなことはできないんですね。上の例だとtank
全体でしかsnapshotがとれません。
tank
の下にoekaki
とは別のディレクトリもたくさんあって、そこにデータもたくさんある場合はそこもまとめてスナップショットされてしまいます。すると、スナップショットの容量が大きくなってzfs poolの容量を圧迫します。
スナップショット領域は最も重要なファイルがあるディレクトリだけに限定したいですね。
とはいえ、スナップショット対象領域を別にした構成に新たに作り直すのも面倒です。後付で特定のディレクトリだけ、例えば/tank/samba/public/working
の場所だけsnapshot取りたい場合は一工夫すれば一応それっぽいことが可能です。
まず、tank
の下に新しいzfsを後付します。
root@liella:/home/takahashi# zfs create tank/working root@liella:/home/takahashi# zfs list NAME USED AVAIL REFER MOUNTPOINT tank 1.65T 12.8T 1.64T /tank tank/working 4.81G 12.8T 4.81G /tank/working
これで、tank/working
という新しいzfsが作れました。あとはMOUNTPOINTを変更します。
root@liella:/home/takahashi# zfs set mountpoint=/tank/samba/public/working tank/working root@liella:/home/takahashi# zfs list NAME USED AVAIL REFER MOUNTPOINT tank 1.65T 12.8T 1.64T /tank tank/working 4.81G 12.8T 4.81G /tank/samba/public/working
これで、tank/working
のスナップショットをとれば/tank/samba/public/working
サブディレクトリの中身のみスナップショットを取るみたいなことが事実上できます。あとはtank/working
をマウントすればいいです。
root@liella:/home/takahashi# zfs mount tank/working root@liella:/home/takahashi# df -h Filesystem Size Used Avail Use% Mounted on tank 15T 1.7T 13T 12% /tank tank/working 13T 4.9G 13T 1% /tank/samba/public/working
こんな感じで。もちろん、もともと/tank/samba/public/working
に存在していたファイルはmount時点で見えなくなってしまうので(消えるわけではなくて見えなくなるだけです。mount解除すればまた見えるようになります)もともとあったファイルはどこかに退避しといた上でzfs mount
後に移動し直せばいいです。
もともとあったファイルの移動のひと手間がありますが、zfsを作り直すよりは楽だと思いますので、特定ディレクトリだけスナップショット取りたい場合はこのやり方はおすすめです。
さて、/tank/samba/public/working
のスナップショットを取ったとして、スナップショットもWindowsから楽に参照できればいいですよね?というわけで、このスナップショットをマウントしてSambaで公開します。
まず、スナップショットのマウントから。
root@liella:/home/takahashi# zfs list NAME USED AVAIL REFER MOUNTPOINT tank 1.65T 12.8T 1.64T /tank tank/working 4.81G 12.8T 4.81G /tank/samba/public/working root@liella:/home/takahashi# zfs set snapdir=visible tank/working
さて、zfs set snapdir=visible tank/working
を実行したあとで/tank/samba/public/working
の中身を見てみると。。。
root@liella:/tank/samba/public/working# ls -ahlF total 1.7G drwxrwxrwx 9 101000 101000 10 Mar 13 09:18 ./ drwxrwxr-x 9 101000 101000 13 Mar 13 16:46 ../ drwxr-xr-x 2 101000 101000 55 Mar 13 09:18 0.下描き/ drwxr-xr-x 2 101000 101000 16 Mar 13 09:18 1.ペン入れ/ drwxr-xr-x 2 101000 101000 6 Mar 13 09:21 2.彩色/ drwxr-xr-x 3 101000 101000 10 Mar 13 09:18 3.QA_Review/ drwxr-xr-x 3 101000 101000 42 Mar 13 09:21 4.Done/ drwxr-xr-x 2 101000 101000 19 Mar 13 09:18 done_drawing/ -rw-r--r-- 1 101000 101000 70M Mar 13 01:16 knowhow.pur -rw-r--r-- 1 101000 101000 1.6G Mar 9 22:03 myboard.pur drwxrwxrwx 1 root root 0 Mar 13 17:26 .zfs/
.zfs
という隠しディレクトリができてることがわかります。この中身を見てみると。。。
root@liella:/tank/samba/public/working# cd .zfs/ root@liella:/tank/samba/public/working/.zfs# ls -ahlF total 17K drwxrwxrwx 1 root root 0 Mar 13 17:26 ./ drwxrwxrwx 9 101000 101000 10 Mar 13 09:18 ../ drwxrwxrwx 2 root root 2 Mar 13 17:26 shares/ drwxrwxrwx 2 root root 2 Mar 13 22:00 snapshot/ root@liella:/tank/samba/public/working/.zfs# cd snapshot/ root@liella:/tank/samba/public/working/.zfs/snapshot# ls -ahlF total 264K drwxrwxrwx 2 root root 2 Mar 13 22:00 ./ drwxrwxrwx 1 root root 0 Mar 13 17:26 ../ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_00:22:35_daily/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_00:22:35_hourly/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_00:22:35_monthly/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_01:00:01_hourly/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_02:00:24_hourly/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_03:00:24_hourly/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_04:00:24_hourly/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_05:00:24_hourly/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_06:00:24_hourly/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_07:00:24_hourly/ drwxrwxrwx 8 root root 10 Mar 13 09:18 autosnap_2022-03-13_08:00:01_hourly/ drwxrwxrwx 8 101000 101000 10 Mar 13 09:18 autosnap_2022-03-13_09:00:01_hourly/ drwxrwxrwx 8 101000 101000 10 Mar 13 09:18 autosnap_2022-03-13_10:00:01_hourly/ drwxrwxrwx 8 101000 101000 10 Mar 13 09:18 autosnap_2022-03-13_11:00:24_hourly/ drwxrwxrwx 8 101000 101000 10 Mar 13 09:18 autosnap_2022-03-13_12:00:24_hourly/ drwxrwxrwx 8 101000 101000 10 Mar 13 09:18 autosnap_2022-03-13_13:00:01_hourly/
はい、このように、snapshotが見えます。
なので、この.zfs領域をSambaで公開してそれをWindowsから見ればOKです。こんな感じで見れます。
ここで問題発生
ここで問題発生。なんかスナップショットのファイル名が妙ちくりんな名前になってます。これは、Windowsがファイル名に:
を使えないことに起因します。sanoidが取るスナップショット名に:
が入っちゃってるので、Sambaが変換をかけてこうなっちゃうんですね。
sanoidのほうでsnapshotの名前を:
を使わないなにか別のフォーマットに変えられないのか?と思ったんですが、これは無理です。sanoidにその機能はないとのこと。
なのでsamba側でなんとかする
なので、samba側でなんとかします。sambaにはwindowsでは表示できない記号がファイル名に使われてた場合、それを置き換える機能vfs objects = catia
というものがあって、それを使います。
[snapshot] comment = zfs snapshots vfs objects = catia mangled names = no catia:mappings = 0x22:0xa8,0x2a:0xa4,0x2f:0xf8,0x3a:0xf7,0x3c:0xab,0x3e:0xbb,0x3f:0xbf,0x5c:0xff,0x7c:0xa6 path = /samba/public/working/.zfs writable = no guest ok = no
この0x22:0xa8,0x2a:0xa4,0x2f:0xf8,0x3a:0xf7,0x3c:0xab,0x3e:0xbb,0x3f:0xbf,0x5c:0xff,0x7c:0xa6
ってのが変換テーブルなわけですが、これの内訳はこういう意味です。
0x22:0xa8 = ダブルクオーテーション (") -> ウムラウト(¨) 0x2a:0xa4 = アスタリスク(*) -> 汎用通貨記号(¤) 0x2f:0xf8 = スラッシュ(/) ->スラッシュ付きオー(⊘) 0x3a:0xf7 = コロン(:) ->除算記号(÷) 0x3c:0xab = 山括弧左(<) ->二重山括弧左(《) 0x3e:0xbb = 山括弧右(>) ->二重山括弧右(》) 0x3f:0xbf = クエスチョンマーク(?) ->逆さクエスチョン(¿) 0x5c:0xff = Yenマーク(\) ->Yの分音記号(ÿ) 0x7c:0xa6 = 垂直線(|) ->分割垂直線(¦)
この設定で。いい感じに表示できます。
2つ注意点。
この変換テーブルをいじらないほうがいいです。例えば、÷(除算記号)はいやだから_
(アンダーバー)に変換したい!と思ってもいじっちゃダメです。理由はあらゆるファイルの_
がすべて:に変換されてしまうので、_
を含むファイルやディレクトリをみようとした瞬間全体がおかしくなります。_
はファイルパスとしてわりかし普通に使うので変換先として使うのはやめましょう。また、このvfs objects = catia
をsambaの[global]
セクションに入れるのもやめましょう。理由はsnapshot以外のすべての領域において万が一除算記号(÷)といった記号がファイル名に使われてしまうと、上述した理由でこれまたSamba全体がおかしくなるからです。snapshotの部分は除算記号(÷)などがパスに使われることはないと保証できますので(sanoidはそんな記号使わないから)snapshot領域のみにvfs objects = catia
を適用しましょう。
はい、これで一時間おきに自動的にスナップショットがとられていつでも過去のデータを参照することができるようになります!
これでHappyお絵かきライフが捗るんじゃぁ~
次はバックアップだねぇ。。。
lxcコンテナのI/Oが異様に遅いという話
NASの運用をようやく開始
LXCコンテナのI/Oが遅い気がします。Dockerの話じゃないですLXCです。
1年ちょい前に10GbEのNASを自作したという話をしました。作ったのはいいんですが、OSインストールを終わらせた後ちょっといじってその後完全放置してたんですよね。だってHDDをそれなりの数揃える勇気がなかったのよ。惰性でQNAP使ってました。なんともったいない。
流石にそろそろ真面目に運用するか?と思って+20万円ぐらい追加課金してHDDや追加部品を揃えました。もう「なるべくお安く」なんてのはどこ吹く風で徹底的に課金しています。
OSも入れ直し。ProxmoxっていうDebianベースのOSにしました。なおこのProxmox。コンテナ(LXC)やVMをWebのGUIで管理できるっていうスグレモノです。VMware ESXiみたいなものですね(VMMはKVMなのでType-Iではないですよ。勘違いしてる人いますが違いますよ)
課金しなくても十分使えます。インストールも簡単出しおすすめです。結構使ってる人いますね。
お家で始める仮想化環境 Proxmox VE 環境構築編 | Nishiの独り言
Proxmox VE6.3のインストールと、やっておくと良い初期設定
本題:LXCコンテナのI/Oが遅いって話
そんで、せっかくなのでSambaデーモンはLXCコンテナ上に置き、ホストのZFS領域をそのコンテナ上にマウントしてそこをSambaで公開するというのを取りました。なんかセキュアな感じがするのでそうしました。ちなみに、私はlxcコンテナに今回はじめて触れました。コンテナといえばDockerが有名ですが、Dockerとの違いはフルのLinuxシステムが動くかどうか?というところだと思います。Dockerが一コンテナ一プロセスという哲学で開発されているのに対して、lxcコンテナはフルのLinuxシステム、つまり、systemdやinitとかも動かしてOKのようです。VMにより近いコンテナと言えると思います。
Windowsから早速アクセスしてベンチマークをとってみました。
シーケンシャルはいい、が、ランダムアクセスが遅くないですか????いや、HDD6台でRAIDZ2だとこんなもんじゃない?って思うでしょ?いやいや、このZFSね。SLOGとかL2ARCをSamsung 980 PROのNVMe SSDに置いてるんですよ。見てくださいこれ。あと、メモリだって64GB積んでますからね?
root@liella:~# zpool status pool: tank state: ONLINE config: NAME STATE READ WRITE CKSUM tank ONLINE 0 0 0 raidz2-0 ONLINE 0 0 0 ata-ST4000VN008-2DR166_ZDHAA43Z ONLINE 0 0 0 ata-WDC_WD40EFZX-68AWUN0_WD-WX32D515UU33 ONLINE 0 0 0 ata-ST4000VN008-2DR166_ZDHAAMFM ONLINE 0 0 0 ata-WDC_WD40EFZX-68AWUN0_WD-WX32D514ZD4J ONLINE 0 0 0 ata-ST4000VN008-2DR166_ZDHAA46D ONLINE 0 0 0 ata-WDC_WD40EFZX-68AWUN0_WD-WX32D515UH9R ONLINE 0 0 0 logs nvme0n1p2 ONLINE 0 0 0 cache nvme0n1p1 ONLINE 0 0 0 errors: No known data errors
んで、Samsung 980 PROのランダムアクセスはもっと速いはずなんですよ。。。こんなもんじゃないのですよ。
ほんとにほんとに本題
さて、色々と調べて「これはLXCコンテナのI/Oが遅いのではないか?」という結論に至りました。ベンチマークをとってみます。ホストにあるZFSと、ホスト上で動いてるLXCコンテナ経由でZFS(ホストのZFS領域をコンテナ内へマウントしてます)でそれぞれbonnie++ベンチマークをとってみました。
# bonnie++ -u root -d ./ -n 50:1048576:1048576:1 -s 4096 -r 1024
結果です
Version 2.00 ------Sequential Output------ --Sequential Input- --Random- -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks-- Name:Size etc /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP liella 4G 1898k 99 1.6g 53 1.6g 55 2892k 99 7.4g 99 +++++ +++ Latency 5300us 54us 43us 3030us 29us 95us Version 2.00 ------Sequential Create------ --------Random Create-------- liella -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete-- files:max:min /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP 50:1048576:1048576 51200 68 51200 99 51200 73 51200 69 51200 99 51200 43 Latency 16339us 2735us 7303us 11797us 3517us 1094ms
random craeteでも51200ファイル/sec(であってますよね?)作れてて、なによりレイテンシがcreateで11797us。readで3517usで、deleteが1094msぐらいです。
それでは、このZFS領域をLXCコンテナへマウントして、LXCコンテナ内部から測ってみましょう。なお、LXCコンテナにはCPU4コアとメモリは8GB割り当ててます。
Version 2.00 ------Sequential Output------ --Sequential Input- --Random- -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks-- Name:Size etc /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP fortress 4G 1735k 99 1.6g 55 1.5g 57 2652k 99 7.0g 99 +++++ +++ Latency 4858us 92us 46us 3367us 24us 396us Version 2.00 ------Sequential Create------ --------Random Create-------- fortress -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete-- files:max:min /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP 50:1048576:1048576 0 54 0 71 0 43 0 45 0 31 0 25 Latency 347ms 331ms 2880ms 368ms 326ms 1658ms
うーん。顕著に性能ダウンしてます。特にSequential CreateとRandom Createのあたり。これゼロってことは一秒間に一個も作れてないってことですよね?
なにより、Latencyが文字通り桁違いに遅くなってます。100ms=100000usなので。。。おそすぎです。。。
うーん。この性能差はどこから来るのでしょう???何がボトルネックなのでしょう???謎いです。
pythonのデフォルト引数の挙動は可怪しいという話
Pythonをすごいやりたい!ってわけではないんですが、DiscordのBot作るのにPython便利そうなので使ってます。
で、プログラミング言語にはデフォルト引数っていう機能がありますよね?Pythonにもあるんですが、Pythonのデフォルト引数の仕様は普段私が使ってる言語たち(Ruby, CL, Scala etc)と仕様がちょっと違うのでハマりましたよという話。
import time import datetime class Foo: def bar(self, now = datetime.datetime.now()): print(f"{now}") hoge = Foo() while True: hoge.bar() time.sleep(1)
ここでbar
っていうFooクラスのインスタンスメソッドがあったとして、普通bar
が呼ばれるたびにnow
は更新されると思いませんか?。ところがpythonってそうならないんですよね。。。classがnewされたときのnowが固定で代入されてずーっと呼び出されます。
私このPythonの意味不明仕様をしらなかったもんで、これに1時間ぐらいハマりました。ユニットテストでは通るのに、実際にコードを動かすと思ったように動かない。
他の言語ではどうなんですか?っていう話ですが
例えばRuby
require 'date' class Foo def bar(now = Time.now) puts now end end hoge = Foo.new() while true hoge.bar() sleep(1) end
Rubyの結果
2020-12-29 15:47:16 +0900 2020-12-29 15:47:17 +0900 2020-12-29 15:47:18 +0900 2020-12-29 15:47:19 +0900 2020-12-29 15:47:20 +0900 2020-12-29 15:47:21 +0900 2020-12-29 15:47:22 +0900 2020-12-29 15:47:23 +0900 ^CTraceback (most recent call last): 1: from test.rb:14:in `<main>' test.rb:14:in `sleep': Interrupt
普通はこうですよね!メソッド呼び出しのたびにデフォルト引数内部は更新されますよ!変わりますってば!
Scalaの場合
class Hoge { def _now() { } } class Foo { def bar(now: Hoge = new Hoge()) { println(now) } } val hoge = new Foo() while (true) { Thread.sleep(1000) hoge.bar() }
Main$$anon$1$Hoge@16f65612 Main$$anon$1$Hoge@311d617d Main$$anon$1$Hoge@7c53a9eb Main$$anon$1$Hoge@ed17bee Main$$anon$1$Hoge@2a33fae0 Main$$anon$1$Hoge@707f7052 Main$$anon$1$Hoge@11028347 Main$$anon$1$Hoge@14899482 Main$$anon$1$Hoge@21588809 Main$$anon$1$Hoge@2aae9190 Main$$anon$1$Hoge@2f333739 Main$$anon$1$Hoge@77468bd9 Main$$anon$1$Hoge@12bb4df8
Scalaの場合もそうです。呼び出しごとに更新されます。当たり前です。
Common Lispの場合
(let ((foo ())) (defun bar (&optional (now (random 100))) (print now))) (loop (progn (bar) (sleep 1)))
14 69 6 48 60 73 8 31 43 4 6 71 14 81 78 14
いや普通(世の中に出回ってる言語の多数派)こうだと思いますが。。。はて。。。?
Pythonってこの他にも「なぜこうした?」っていう意味不明な仕様が多くて、例えば、map
やfilter
といった関数もmap object
とかfilter object
とかが返ってきたりしますよね?
いやこういうのって、普通基底クラスなりなんなりにEnumerable
とかTraversable
みたいなのがあって、ArrayとかListとかはそいつを継承させるものなんじゃないんですか?だからmap objectとかfilter objectとか別途用意するんじゃなくて、mapの結果が直接ArrayとかListを出せるようにするべきなんじゃないんですかね?とかとか
最近のディスアセンブラとかデバッガとかの話
ちょっとリバースエンジニアリング(マルウェア解析ではない)をしないといけなくなったのでそこらへんのツールを探してみた。ここらへんの知識が2008年ぐらいで止まってるので、情報更新。
デバッガ
昔、バイナリ解析と言ったらOllyDbgが有名だったと思うんですが2014年を最後に更新が止まってしまっているようです。
じゃあ今の人たちは何を使ってるのかなぁ?って探すとx64dbgってのがいいみたいです。ちなみにx64と命名されてますが32bit版もあります。
コマンド体系は(MS製でWindowsのでバドラ開発とかに使う)WinDbgに似てるかなぁ。という感じ。bp ReadFile
とかでWin32APIにブレークポイントしかけられます。
「いいなぁ」と思ったのは「ユーザーコードまで実行」というコマンドがあることで、これは嬉しいなと思いました。リバースエンジニアリングってのはWin32APIを手がかりにブレークポイント引っ掛けて、そこから解析していくと思うんですが、その時このコマンドを使えば、一気に解析対象のソフトウェアコードまで戻るわけです。
ディスアセンブラ
みんな憧れのIDA Proはまだ現役らしいですね。20年以上この業界でデファクトスタンダードの地位に留まれているのは素晴らしい。
とはいえ、IDA Proは10万円以上する高価なソフトウェアなので、別に本業でマルウェア解析してるわけでもない私みたいな個人が手軽に手を出すのはちょい辛いかなと思います。
ただ、IDA FreewareってのがあってIDA Proの機能限定版がタダで使えます。
ディスアセンブラなんですが、ディスアセンブルしたコードの参照関係のグラフを出してくれるのが嬉しいです。この昨日はIDA Freewareでも省かれてないので嬉しい。
SAIのサムネイルをWindows上のエクスプローラで見れるようにする
ペイントソフトSAIのファイルってWindowsのエクスプローラでサムネイルが見れないですよね。これ地味に不便でなんとかしたい。SAIはものすごく良いソフトでペンが軽快で描いてて気持ち良いソフトなんで愛用してるんですが、このサムネイルが見れないというのにフラストレーションを感じていました。
検索するとSaiThumbsってのがあってこれをインストールするとWindowsのエクスプローラから見れるようになります。
ここからダウンロードできます
https://wunkolo.itch.io/saithumbs
寄付してーって言われますが、一応寄付せずにダウンロードするだけもできます。「No thanks, just take me to the downloads」をクリックすればOK
ダウンロードして解凍して中の「install.bat」を実行すればOKです。エクスプローラからsaiファイルのサムネイルが見れるようになります。
SAI2は残念ながらまだないようです。
余談ですが、内部的にはlibsaiってのを使ってて、saiのファイルはほとんど解析されてるようです。
saiのファイルは暗号化がかかってるというのはバイナリエディタで中をみてぼんやりと感じてたんですが、見事に解析してますね。。。すごいなぁ。。。
VPSのvultrがいいよって話
vultrというVPSサービスがある。最近ちょくちょく聞くので使ってみた。用途はT-potの運営のためのサーバを借りるため。AWS EC2上で運用しようかなと思ったけどEC2はisoイメージからのインストールの際、まずはじめにS3にisoイメージを上げてーとかちょっと面倒なことをしないといけない。ので、ついでにvultr使ってみようかなと思った。VPSで有名所といえば、あとはさくらVPSがあるけど、さくらVPSはもう使っていて何台か借りてる。のでものは試しでvultrにしてみた。
ちょっと使ってみたところ、AWS Lightsailと比べて(VPS単体で見れば)Vultrのほうが機能面で充実しているかなとおもった。S3とかDynamoDBとかRDSとかと組み合わせないのであればVultrのほうが良い気がします。とはいえ、Vultrもブロックストレージ(AWS EBS相当のもの)とオブジェクトストレージ(AWS S3互換のよう)とLoad Balancerはあるみたいです。
以下箇条書き
- isoイメージからの起動ができる。自分で好きなisoイメージをアップロードしてそこからBootしてインストール可能。Lightsailはできない。
- Webコンソールの画面操作はVGAをVNC経由で飛ばしている。LightsailはWebコンソールもSSH経由なのでiptablesとかでしくじると復旧の手段が完全に絶たれるが、vultrはそんなことはない
- セキュリティインシデントあるとメールで警告してくれる。
- いまなら100USDクレジットくれる!
- 支払いにBitcoin (BTC)とBitcoin Cash (BCH)が使える!まあネタだと思うけど、PRQかよw
ただ、課金形体がプリペイド式で独特です。クレジットカードで課金するとVultr内のクレジットにチャージできて、そのクレジットから毎時間の使用量が引き落とされる感じです。この点AWS Lightsailのように1ドル単位で使用した料金をクレカから引き落としてしくれるわけではないみたいです。この点はちょっとLightsailと比べると柔軟性が低いかもしれません。
ところで、この請求の仕方をライバルのさくらVPSと比べると、時間単位請求という点で一見さくらVPSよりは柔軟のように見えるが一長一短あるかなという感じ。プリペイド方式なので「使った金額がそのまま月額課金される」わけではなく「事前にプリペイドでチャージしておかないといけない」わけで、実際の使用量よりも多くチャージしないとクレジットが足りないのでやむなく多めにチャージするけど端数が出てしまうという感じになりそうです。ここで個人使用だとちょっと拒否感が出る人がいるかもです。さくらVPSはたしかに時間単位請求はしてくれませんが、月額のみがクレジットカードから引き落とされますのでプリペイドチャージで使用しきれない端数が出ることはないわけです。
あと、上述しましたが、今だと100USDクレジットただでもらえるので、インスタンスにもよりますが、二ヶ月ぐらいはただで使えますよ。太っ腹!
なお、上のリンクは私へのアフィリンクになってますので踏んでくれると私にクレジットが入りますのでぜひ踏んでください ;-)
AWS Lightsail上でT-potは運用しないほうがいいという話
AWS Lightsail上でDebianのVMインスタンスを借りて、その上でT-potをインストールした。
最初の方はうまく動いていたのだが、1時間ぐらいするとVMが落ちる問題が発生。SSHはもちろんのことpingすら通らなくなる。AWSのWebIFからVMの再起動をかけると再び上がってくるが、また1時間ほど放置するとVMが落ちる。これでは使い物にならない。なお、AWS LightsailのWebIFはSSH経由なのでこうなってしまうとVMにアクセスする方法がなくなるので調査も面倒だった。再起動するしかない。これ使い勝手悪いよね。。。せめてシリアルポート経由にしてもらえないか?と思う。
ログやらなんやらを色々みて何が起こっているかはわかったので、誰かの役に立つかもしれないので一応書き残しておく。
まずAWS LightsailにはNATがある。VMが直接グローバルIPのセグメントにぶら下がってるわけではない。NATの後ろに隠れている。そんで、そのNATの内部のプライベートIPはDHCPで降ってくる。
で、このNAT内部のプライベートIPのリース期間が短い。3000sec前後しかないのである。したがってこのDHCPのIPリース期間が切れるとIPが剥奪されて一切の通信ができなくなるのである。これが落ちてた原因
dhclientのリース期間が切れたときは当然dhclientが再取得するはずだが、T-potインストール後の環境にはこのdhclientが常駐してない。だから再取得も行われるそのまま沈黙してしまう。
他のT-potをインストールしていないLightsailインスタンスには確かにdhclientが常駐している。T-potがインストール時にこの設定を消してしまうのだろう。
ところで、よくわかってないのだが、dhcpのリース期間を無限に設定してある自宅LAN環境のLinuxサーバではdhclientは常駐してない。リース期間が有限だとNetworkManagerあたりが自動的に立ち上げるのかしら?ここらへんは調べてもよくわからなかった。
じゃあdhclient起動すればいいんでしょ!ってんで手動でdhclientを立ち上げてみたらどうか?と思い。以下のコマンドを叩いた。
# dhclient -r -v eth0 && rm /var/lib/dhcp/dhclient.* ; dhclient -v eth0
すると、たしかに1時間たってもVMは落ちなくなった。
しかしまたもや問題発生。1時間ではVMは落ちなくなったが、今度は4時間後ぐらいにまたVMが落ちてしまう問題が発生した。時間が伸びただけでやっぱり落ちるのである。
Jul 01 01:52:45 rapidassistance dhclient[19188]: DHCPREQUEST for 172.26.3.244 on eth0 to 172.26.0.1 port 67 Jul 01 01:52:45 rapidassistance dhclient[19188]: DHCPACK of 172.26.3.244 from 172.26.0.1 Jul 01 02:18:04 rapidassistance dhclient[19188]: DHCPREQUEST for 172.26.3.244 on eth0 to 172.26.0.1 port 67 Jul 01 02:18:04 rapidassistance dhclient[19188]: DHCPACK of 172.26.3.244 from 172.26.0.1 Jul 01 02:44:37 rapidassistance dhclient[19188]: DHCPREQUEST for 172.26.3.244 on eth0 to 172.26.0.1 port 67 Jul 01 02:44:37 rapidassistance dhclient[19188]: DHCPACK of 172.26.3.244 from 172.26.0.1 Jul 01 03:08:46 rapidassistance dhclient[19188]: DHCPREQUEST for 172.26.3.244 on eth0 to 172.26.0.1 port 67 Jul 01 03:08:46 rapidassistance dhclient[19188]: DHCPACK of 172.26.3.244 from 172.26.0.1 Jul 01 03:27:39 rapidassistance dhclient[403]: Internet Systems Consortium DHCP Client 4.4.1 Jul 01 03:27:39 rapidassistance dhclient[403]: For info, please visit https://www.isc.org/software/dhcp/ Jul 01 03:27:39 rapidassistance dhclient[403]: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3 Jul 01 03:27:39 rapidassistance dhclient[403]: DHCPOFFER of 172.26.3.244 from 172.26.0.1 Jul 01 03:27:39 rapidassistance dhclient[403]: DHCPREQUEST for 172.26.3.244 on eth0 to 255.255.255.255 port 67 Jul 01 03:27:39 rapidassistance dhclient[403]: DHCPACK of 172.26.3.244 from 172.26.0.1 Jul 01 03:27:39 rapidassistance dhclient[428]: Internet Systems Consortium DHCP Client 4.4.1 Jul 01 03:27:39 rapidassistance sh[414]: Internet Systems Consortium DHCP Client 4.4.1 Jul 01 03:27:39 rapidassistance sh[414]: For info, please visit https://www.isc.org/software/dhcp/ Jul 01 03:27:39 rapidassistance dhclient[428]: For info, please visit https://www.isc.org/software/dhcp/ Jul 01 03:27:39 rapidassistance sh[414]: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 4 Jul 01 03:27:39 rapidassistance sh[414]: DHCPOFFER of 172.26.3.244 from 172.26.0.1 Jul 01 03:27:39 rapidassistance sh[414]: DHCPREQUEST for 172.26.3.244 on eth0 to 255.255.255.255 port 67 Jul 01 03:27:39 rapidassistance sh[414]: DHCPACK of 172.26.3.244 from 172.26.0.1
ログをみると、Jul 01 03:27:39まではdhclientはご機嫌でIPのリースを更新してくれているようだが、それ以降ログが途切れている。誰かがNetworkManager周りに再起動をかけたのか?このとき、僕が手動で起動したdhclientも殺されてまたDHCPリースが切れたときにIPが消えて落ちているようだ。元の木阿弥である。
じゃあdhclientをsystemdで起動してWatchdogでプロセスが殺されても復活するようにすればいいのでは?とおもってsystemdのconfigを書いてdhclientを起動させた。。。
ところでどうやら何やら不味いことをやってしまったらしく、systemd start dhclient.service
とやった瞬間VMが落ちた。すでにenableにした後だったのでAWSのWebIFから再起動をかけてもSSHにはつながらない。\(^o^)/オワタ
AWSのWebIFはSSH経由での接続しかサポートしてないのでこうなってしまうとどうやってもVMにはアクセスできなくなるのでインスタンスを削除してOS再インストールからやり直しである。
ここで心が折れた。もうAWS Lightsail上でのT-pot運用は諦めることにする。。。これ以上は面倒くさいし不毛だ。。。
T-potはOSごと含めたISOイメージからのインストール手段も提供している。ので、EC2でインスタンスを借りて、ISOイメージからインストールしてみようかなと思う。
というわけでLightsailでT-potの運用は面倒くさいんでやめたほうがいいという結論になりました。