Linuxのファイルシステムの特徴
LinuxのEXT4やBrtfsやEXT3などのファイルシステムは、i-nodeとブロック領域の2つで構成されています。ファイルのデータはブロック領域に格納されます。そのブロックの管理領域には、ファイルの実データが格納されている位置やファイル・サイズ、変更時刻などの管理情報が記録されます。これがi-nodeです。
各ファイルやディレクトリのi-node番号を確認するには、ls -iコマンドを実行します。
$ ls -ali
54980 -rw-r--r-- 1 faust users 1.5G 6月 14 21:20 test.tar.gz
232836 drwxr-xr-x 1 faust users 84 6月 15 01:11 www
また、各パーティションごとに使用されているi-node番号の総数は、df -iコマンドで確認できます。
$ df -i
ファイルシス Iノード I使用 I残り I使用% マウント位置
devtmpfs 4104575 576 4103999 1% /dev
tmpfs 4105569 1 4105568 1% /dev/shm
tmpfs 4105569 555 4105014 1% /run
/dev/sdb2 0 0 0 - /
tmpfs 4105569 13 4105556 1% /sys/fs/cgroup
tmpfs 4105569 555 4105014 1% /var/lock
tmpfs 4105569 555 4105014 1% /var/run
/dev/sda1 0 0 0 - /srv/m4
/dev/sdb1 524288 327 523961 1% /boot
/dev/sdc1 390686272 76318 390609954 1% /srv/hdd
ファイルのタイムスタンプ情報
ファイルブロックには、最終i-node更新時刻(ctime)、最終参照時刻(atime) 、最終ファイル更新時刻(mtime)を示すタイムスタンプが属性データとして埋め込まれています。それぞれ以下のコマンドで確認できます。
最終i-node更新時刻を確認
$ ls -lc
-rw-r----- 1 root root 169K 8月 2 04:51 messages
最終参照時刻を確認
$ ls -lu
-rw-r----- 1 root root 169K 8月 1 19:45 messages
最終ファイル更新時刻を確認
$ ls -l
-rw-r----- 1 root root 169K 8月 2 04:51 messages
touchコマンドを使ってファイルのタイムスタンプを改竄する
touchコマンドを用いると、atime・mtimeは任意の時刻に改竄することが可能です。
$ touch hoge.txt
$ ls -al
-rw-r--r-- 1 faust users 0 8月 2 04:58 hoge.txt
$touch -d "2000/4/1 00:00:00" hoge.file
$ ls -al
-rw-r--r-- 1 faust users 0 4月 1 2000 hoge.txt
これで今日(2013年8月2日)作られたはずのファイルが、2000年4月1日に作成されたことになりました。このようにtouchコマンドを使うと簡単にatime・mtimeのタイムスタンプを改竄することが可能です。しかし、最終i-node更新時を記録しているctimeはtouchコマンドでは日時修正が出来ません。このため、ctimeを見るオプションで見るとi-nodeの更新日時からファイルのi-nodeがいつ更新されているのか判明してしまいます。
$ ls -lc
-rw-r--r-- 1 faust users 0 8月 2 04:58 hoge.txt
ctimeのタイムスタンプを変更するには
では、ctimeを変更するにはどのようにすれば良いのでしょうか。i-nodeを直接書き換える必要があります。CentOSならば、debugfsコマンドでパーティションを書き込み可能にして、modify_inodeによって書き換えることが出来ます。その場合、Creation timeの部分で、UNIXタイムスタンプを入力します(ここでは2000年4月1日00時00分00秒の954514800を指定)。
$ sudo debugfs -w /dev/vda3
debugfs 1.41.12 (17-May-2010)
debugfs: cd /home/faust
debugfs: stat test.txt
Inode: 1177357 Type: regular Mode: 0664 Flags: 0x80000
Generation: 1780830578 Version: 0x00000000:00000001
User: 500 Group: 500 Size: 0
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 0
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x38e4bd70:bd6023b0 -- Sat Apr 1 00:00:00 2000
atime: 0x51fac627:bd6023b0 -- Fri Aug 2 05:33:43 2013
mtime: 0x51fac627:bd6023b0 -- Fri Aug 2 05:33:43 2013
crtime: 0x51fac627:bd6023b0 -- Fri Aug 2 05:33:43 2013
Size of extra inode fields: 28
EXTENTS:
debugfs: modify_inode test.txt
Mode [0100664]
User ID [500]
Group ID [500]
Size [0]
Creation time [954514800] 954514800
Modification time [1375389223] 954514800
Access time [1375389223] 954514800
Deletion time [0]
Link count [1]
Block count high [0]
Block count [0]
File flags [0x80000]
Generation [0x6a255172]
File acl [0]
High 32bits of size [0]
Fragment address [0]
Direct Block #0 [62218]
Direct Block #1 [4]
Direct Block #2 [0]
Direct Block #3 [0]
Direct Block #4 [0]
Direct Block #5 [0]
Direct Block #6 [0]
Direct Block #7 [0]
Direct Block #8 [0]
Direct Block #9 [0]
Direct Block #10 [0]
Direct Block #11 [0]
Indirect Block [0]
Double Indirect Block [0]
Triple Indirect Block [0]
debugfs: stat test.txt
Inode: 1177357 Type: regular Mode: 0664 Flags: 0x80000
Generation: 1780830578 Version: 0x00000000:00000001
User: 500 Group: 500 Size: 0
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 0
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x38e4bd70:bd6023b0 -- Sat Apr 1 00:00:00 2000
atime: 0x38e4bd70:bd6023b0 -- Sat Apr 1 00:00:00 2000
mtime: 0x38e4bd70:bd6023b0 -- Sat Apr 1 00:00:00 2000
crtime: 0x51fac627:bd6023b0 -- Fri Aug 2 05:33:43 2013
Size of extra inode fields: 28
EXTENTS:
debugfs: quit
これでctimeが2000年4月1日になります。EXT3のファイルシステムならば、ls -lcコマンドでもctimeが書き換わっていることが確認できます。しかしEXT4のファイルシステムの場合は、i-nodeにctimeの他にcrtimeという拡張情報が埋め込まれています。これはファイル作成日を示す情報で、この書き換えはdebuginfoのインターフェースではi-nodeを修正できません。
まとめ
mtime、atimeの書き換えならば容易で、これでlsコマンドで通常表示される時刻に関しては改竄が容易ですが、ctimeの書き換えになると若干複雑になります。さらにEXT4のファイルシステムではcrtimeの情報があるため、この書き換えを行うことが出来ません。ということで、セキュリティ的にはmtime、atimeの情報はあまり信用せず、ctimeないしcrtimeの情報を見た方が正確かと思います。