アイエエー 例外? なんで例外?

C++で未キャッチ例外が発生したときに、スタックトレース(バックトレース)を作成するライブラリです。
https://github.com/rti7743/naichichi2/blob/master/naichichi2/haikuwoyome.h

特徴

ヘッダ単体で使えます。
windows MSVC と Linux gccで動きます。
C++11が使えると、例外の中身も表示されます。
NYSLなので自由に使えます。コピペしてOK。
名前がとてもかっこいい。

遊び方

#include "haikuwoyome.h"

int main()
{
	//これ以降で、未キャッチ例外が発生したら、スタックトレースを生成します.
	HaikuWoYome::KaisyakuShiteYaru(); //ハイクを詠め。介錯してやる。

	f();
	
	return 0;
}
#include "haikuwoyome.h"

void ff()
{
	*(int*)0 = 0;
}


void f()
{
	ff();
}

int main()
{
	//これ以降で、未キャッチ例外が発生したら、スタックトレースを生成します.
	HaikuWoYome::KaisyakuShiteYaru(); //ハイクを詠め。介錯してやる。

	f();

	return 0;
}

コンパイル C++11 が使える場合

g++  -std=c++11  -Wl,--no-as-needed -ldl  a.cpp


出力例

=HAIKU=============================================
backtrace:
HaikuWoYome::BackTrace() ./a.out() [0x402798]
HaikuWoYome::OnSignalFunction(int) ./a.out() [0x402c08]
/lib/x86_64-linux-gnu/libc.so.6(+0x354b0) [0x7fc5dbe484b0]
ff() ./a.out() [0x402ed0]
f() ./a.out() [0x402ee2]
main ./a.out() [0x402ef3]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7fc5dbe33830]
_start ./a.out() [0x401849]

signal: 11 (SIGSEGV)
process_id: 29259 thread_id:29259
===================================================

C++11がない場合でも、同一です。

g++   -Wl,--no-as-needed -ldl  a.cpp
=HAIKU=============================================
backtrace:
HaikuWoYome::BackTrace() ./a.out() [0x40204e]
HaikuWoYome::OnSignalFunction(int) ./a.out() [0x4024be]
/lib/x86_64-linux-gnu/libc.so.6(+0x354b0) [0x7f766a3d84b0]
ff() ./a.out() [0x402786]
f() ./a.out() [0x402798]
main ./a.out() [0x4027a9]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7f766a3c3830]
_start ./a.out() [0x4014c9]

signal: 11 (SIGSEGV)
process_id: 29277 thread_id:29277
===================================================
#include "haikuwoyome.h"

void ff()
{
	throw std::runtime_error("さよならー");
}


void f()
{
	ff();
}

int main()
{
	//これ以降で、未キャッチ例外が発生したら、スタックトレースを生成します.
	HaikuWoYome::KaisyakuShiteYaru(); //ハイクを詠め。介錯してやる。

	f();

	return 0;
}

コンパイル C++11 が使える場合

g++  -std=c++11  -Wl,--no-as-needed -ldl  a.cpp


出力例

=HAIKU=============================================
backtrace:
__cxa_throw ./a.out(__cxa_throw+0x47) [0x402a28]
ff() ./a.out() [0x40306a]
f() ./a.out() [0x403089]
main ./a.out() [0x40309a]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7f4b4ac47830]
_start ./a.out() [0x4019b9]

exception: std::runtime_error さよならー
process_id: 29693 thread_id:29693
===================================================


C++11がない場合は、例外の中身を取得できません.

g++   -Wl,--no-as-needed -ldl  a.cpp
=HAIKU=============================================
backtrace:
__cxa_throw ./a.out(__cxa_throw+0x47) [0x40235e]
ff() ./a.out() [0x4029ee]
f() ./a.out() [0x402a2a]
main ./a.out() [0x402a3b]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7fca4fb5c830]
_start ./a.out() [0x4016b9]

process_id: 29685 thread_id:29685
===================================================

標準は stderrに出力するだけですが、カスタムすこともできます。

#include <stdio.h>

//私のロガーです
void mylogger(const char* msg)
{
        puts("HELLO");
        puts(msg);
        puts("/HELLO");
}

//私のロガーを使います.
#define HAIKU_WO_YOME_OUTPUT_STDERR(MSG) mylogger(MSG)
#include "haikuwoyome.h"



void ff()
{
        throw std::runtime_error("さよならー");
}

void f()
{
        ff();
}

int main()
{
        //これ以降で、未キャッチ例外が発生したら、スタックトレースを生成します.
        HaikuWoYome::KaisyakuShiteYaru(); //ハイクを詠め。介錯してやる。

        f();

        return 0;
}
HELLO
=HAIKU=============================================
backtrace:
__cxa_throw ./a.out(__cxa_throw+0x47) [0x402a17]
ff() ./a.out() [0x403045]
f() ./a.out() [0x403064]
main ./a.out() [0x403075]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7ff44e551830]
_start ./a.out() [0x401979]

exception: std::runtime_error さよならー
process_id: 28341 thread_id:28341
===================================================

/HELLO


std::exceptionを基底にもたない例外を使いたい場合は、以下のようにします。

#include <stdio.h>
#include <string>

class MyException
{
        std::string msg;
public:
        MyException() {}
        MyException(const std::string& msg) { this->msg = msg; }
        virtual ~MyException(){}

        std::string what() const{ return this->msg; }
        //
        //または、
        //const char* what() const{ return this->msg.c_str() ; }
};

//私のロガーです
void mylogger(const char* msg)
{
        puts(msg);
}

//私のロガーを使います.
#define HAIKU_WO_YOME_OUTPUT_STDERR(MSG) mylogger(MSG)
//私の作った例外を使います.
#define HAIKU_WO_YOME_YOUR_EXECPTION_CLASS MyException
#include "haikuwoyome.h"

void ff()
{
        throw MyException("さよならー");
}


void f()
{
        ff();
}

int main()
{
        //これ以降で、未キャッチ例外が発生したら、スタックトレースを生成します.
        HaikuWoYome::KaisyakuShiteYaru(); //ハイクを詠め。介錯してやる。

        f();

        return 0;
}
=HAIKU=============================================
backtrace:
__cxa_throw ./a.out(__cxa_throw+0x47) [0x402a7f]
ff() ./a.out() [0x4030fb]
f() ./a.out() [0x403137]
main ./a.out() [0x403148]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7f5ca9c6e830]
_start ./a.out() [0x401999]

exception: MyException さよならー
process_id: 28812 thread_id:28812
===================================================

当然ですが、例外をキャッチすると何も表示されません。

#include "haikuwoyome.h"

void ff()
{
	throw std::runtime_error("うぼあー");
}


void f()
{
	ff();
}

int main()
{
	//これ以降で、未キャッチ例外が発生したら、スタックトレースを生成します.
	HaikuWoYome::KaisyakuShiteYaru(); //ハイクを詠め。介錯してやる。

	try
	{
		f();
	}
	catch(std::exception& e)
	{
	}
	return 0;
}

出力例…当然何もでない.


この例外を投げたのは誰だー

この例外を投げたのは誰だーから6年。やっと解決したっぽい。

この例外を投げたのは誰だー
http://d.hatena.ne.jp/rti7743/20110109/1294605380

ヘイトには課税せよ(ヘイトには課金せよ)

ヘイトと表現の自由の両立について。
サッカースタジアムで旭日旗が問題になっているらしい。

そもそも、なぜスポーツ会場で軍旗にも使われている(いた)旗を掲げないといけないのか?というツッコミは置いといて、
大会の規定で軍旗などの政治的な主張とされるものは禁止されるのだから、
掲げるのを禁止されるのは仕方がないところである。

だが、同時に、表現の自由も大切である。
例えクソのような主張であっても、表現の自由で守られるべきだ。
(例えば、この文章のようなクソな主張であってもね。)

表現の自由はとても大切である。
でも、その表現で、苦しむ人もいるだろう。
両方を救ううまい方法はないだろうか。


そこで、提案したいのが、
ヘイト(や場に好ましくない政治的主張やCM)は禁止ではなく、別料金をいただいて、
課金していただいた上でどうどうと掲げていただくというものだ。

例えば、規定上好ましくないものについて、お1人樣1回 300万円+消費税を請求する。

テレビや新聞とかのメディアに注目される大会なんだろうから、
そこで特別な主張をしたいと言うならば、
選挙の供託金の額と同じ300万円ぐらいは最低でも払っていただきたいところである。

横断幕やノボリなどのようなでかいものについては、別途割増をいただく。
それはヘイト(や規定で禁止されている政治的な主張等 以下:ヘイト)であると注意しても、
やめない場合は、上記料金を請求する。

そして、
頂いた300万円の半分を、その主張で被害を受けるであろう人たちの団体等に寄付する。
もう半分は、スタジアム運営者や、スポーツチーム等で分配する。


禁止ではなく、ここでそれをするには課金してくださいというのは、表現の自由に反しない。
例えば、サイトにバナー広告を乗せるのにはお金が必要である。
テレビCMを流すのにはお金が必要である。
これらと同じくまったく問題がないわけだ。

酒やたばこなどの好ましくないとされるものには、税金を多めに取って認めるようなものである。


この案の面白いのは、
頂いたお金の半分を、その主張で被害を受けるであろう人たちの団体に寄付するところである。

つまり、ヘイトをすればするほど、ヘイトされる人たちが潤うという仕組みである。

もし、3人が年10回ほどヘイトしていただくと、
300万円*10回*3人=9000万円 の半分で、4500万円ほどのお金がヘイトで被害を受けるであろう団体に行く。

ヘイトされる側の人々は、我々の心の傷はそんなものではないといわれるかもしれないが、
タダでヘイトされている現状よりはマシだろう。


そして、何より、ヘイトすればするほど、ヘイトされる側が儲かるならば、馬鹿らしくなってヘイトをやめてくれるかもしれない。
もし、馬鹿らしくなって、ヘイトをやめていただければ、これほどいいことはない。

さらに、残りの半分の4500万円は、スタジアムとスポーツチームに行く。
運営費のタシにでもしていただければ良いだろう。

さらにおまけで、消費税8%が別途入る。9000万円の8%は 9000万円*8%=720万円 である。
このお金が国や自治体に納付されることになる。
福祉や教育にでも回してほしいものである。

スタジアムやスポーツチームが、利益を上げれば、所得税法人税でもお金が入るので、さらに国庫が潤うことが期待される。

つまり、ヘイトに課金をすると、
表現の自由が守られ、(お金を払えば)好きな表現を好きなだけでき、
一方それによって、ヘイトされ傷つく人々が潤い、スタジアムやスポーツチームが潤い、税金で国庫も潤う。
誰も困らない、みんなハッピーになれるのではないだろうか。

AOK ぐるぐる陣形


新AIの非常に難しいで 1vs7 バトルをして勝ちたい。
でも、多方面作戦なんて無理。
深い森で引きこもっても押し負けてしまう・・・・
もっと地の利があって、敵が前からしか来ないマップがあればいいのに・・・という人のために、敵が前からしか来ないしたマップを用意しました。

ダウンロードはこちらか、steamのワークショップから
http://rtilabs.rti-giken.jp/files/2017_02_13/guru2.7z
http://steamcommunity.com/sharedfiles/filedetails/?id=903937994

なんじゃーこのグルグルした陣形はー!?
ぐるぐる陣形じゃー

敵が前からのみやってくるグルグル回るマップです。
It is a map that enemies come around only from the front and go round.


シナリオモードで起動してください。
Please start up in scenario mode.

(そうしないとAIがあまり強くないので面白くありません。)
(If you do not do that, AI is not very interesting, so it's not fun.)


コンセプト
Concept

1vs7で総力戦がしたい。
I want to make a total battle at 1vs7.

でも、2正面作戦は無理。
But 2 front strategy is impossible.

それなら、敵は前からやってくるマップだったらいいよね。
In that case, the enemy should be a map coming from the front.

1vs7で、戦います。
I will fight at 1vs7.

資源は豊富にあります。
Resources are abundant.

敵は前からのみやってきます。
Enemies only come from the front.

勝利条件は制圧だけです。
Victory conditions are only control.

激戦を繰り返し、敵に勝利しましょう。
Repeat fierce battle, let 's win enemies.

AOK 代理戦争を復旧


昔作った AOKの代理戦争を復旧させた。
http://d.hatena.ne.jp/rti7743/20140725/1406275415

ダウンロードはこちらか、steamのワークショップから
http://rtilabs.rti-giken.jp/files/2017_02_13/dairi-sensou.7z
http://steamcommunity.com/sharedfiles/filedetails/?id=917216334

基本的に、自分は交戦しないで、友軍を支援して戦わせるというとても簡単なマップです。
ただし、後半は・・・

代理戦争 ver3
Proxy war

シングルモードのシナリオです。
It is a single mode scenario.


自陣と、支援先(赤)は、山で完全に分離されています。
My team and the Partner(red) are completely separated in the mountains.

森や山があり、上下を行き来することは出来ません。
There are forests and mountains, you can not go up and down.


自陣には、同盟している交易先(緑)と大量の資源が大量にあります。
There are a large number of Trader(green) and large amounts of resources allied to their own team.

支援先(赤)がいる砂漠地帯には、ほぼ木しかありません。
There are almost trees in the desert area where there is a Partner(red).

支援先に、資源を融通して助けてあげる必要があります。
We need to help resources by Partner.


自陣の豊かな資源をひたすら採掘して、支援先に融資しまくりましょう。
Let's loan our own resources richly and loan it to the Partner.

支援先は、そのカネで軍隊を強化し、ライバルの3カ国を滅ぼしてくれるでしょう。
Partner will strengthen the army with that money and destroy the rival three countries.




なお、ライバルすべてを滅ぼした後には、おまけがありますのでお楽しみに。
In addition, after you destroy all the rivals, there is a bonus so please look forward to it.

このマップは結構初見殺しです。
This map is, You will die the first time.

セーブしながら進みましょう。
Let's proceed while saving.

FAQ
Q:
支援先が敵を倒してくれません。
The Partner will not defeat the enemy.

A:
資源をたくさん送って、ゲームスピードを早いにしてしばらく放置してください。
Please send lots of resources, speed up the game speed and leave it for a while.

攻撃はAIまかせなので、なんとも言えませんが、そのうち彼は敵を攻撃してくれます。
Since the attack is AI, I can not say it at all, but he will attack the enemy in a while.

Q:
文明の選択が気に入らない。
I do not like the choice of civilization.

A:
ご自由に改変して、遊んでください。
Please freely change it, please play.

シングルプレーのシナリオで読み込むと変えられますね。
You can change it by reading in a single play scenario.


Q:
中盤にゲームがクラッシュした
The game crashed in the middle stage

A:
中盤の演出で、まれにゲームが落ちる時があります。
In the production of the middle stage, there are times when the game falls rarely.

セーブしながら進めてください。
Please proceed while saving.


関係図
Relationship diagram

自陣(You)<-同盟(allies)->支援先(Partner)
自陣(You)<-同盟(allies)->取引先(Trader)

支援先(Partner)<-敵対(enemy)->敵A,敵B,敵C(Enemy a,b,c)
取引先(Trader)<-同盟(allies)->敵A,敵B,敵C(Enemy a,b,c)


自陣と取引先は、表面上仲がいい。
My team and Trader are on good terms.
しかし、砂漠ではそれぞれ異なる勢力を応援している。
However, in the desert, they support different forces.
冷戦時代のように。
Like the Cold War era.

仲良く握手しながら、砂漠で代理戦争を行おう。
Let's make a proxy war in the desert while sharing hands with each other.

更新 UPDATE
砂漠での戦闘が発生しやすくしました。
Battle in the desert is easy to occur.

20分後に敵BCが同盟を組むようにしました。
Enemy BC made an alliance after 20 minutes.

1時間後に、金50000と引き換えに、同盟を崩壊させられるようにしました。
After 1 hour, in exchange for 50000 gold, I made it possible to collapse the alliance.

膠着状態を避けるため、
2時間後に、敵Aが生き残っていた場合、支援先に転向し、消滅するようにしました。
In order to avoid the stalemate situation, 
if enemy A survived after 2 hours, we turned to support destination and disappeared.

3時間後に、敵Bが生き残っていた場合、支援先に転向し、消滅するようにしました。
After 3 hours, if enemy B survived, we turned to support and made it to disappear.

4時間後に、敵Cが生き残っていた場合、支援先に転向し、消滅するようにしました。
After 4 hours, if enemy C survived, we turned to a support destination and disappeared.

嫌いから好きを除いた本当に嫌われてそうなプログラム言語トップ31

開発者に嫌われているプログラミング言語トップ25という記事があった。
http://news.mynavi.jp/news/2017/03/30/133/

ただ、嫌われているといっても、それを好きという人たちもいるだろう。
だから、嫌いから好きを除けば本当に嫌われているプログラム言語がわかるというものだろうということで、さっそくなので集計してみた。

嫌いと好きを合算した結果、最も嫌われているランキング順

ランク 名前 嫌い 好き 差分
嫌われ1位 Visual Basic 6 -25 3 -22点
嫌われ2位 CoffeeScript -23 4 -19点
嫌われ3位 Hack -16 0 -16点
4位 VBA -24 9 -15点
4位 Lua -17 2 -15点
6位 Common Lisp -14 0 -14点
7位 Matlab -21 8 -13点
7位 Dart -13 0 -13点
9位 Erland -12 0 -12点
10位 Groovy -15 5 -10点
11位 VB.NET -22 13 -9点
12位 Perl -18 10 -8点
13位 Assembly -19 12 -7点
14位 Objective-C -20 14 -6点
14位 Julia -6 0 -6点
16位 Haskell -3 1 -2点
16位 F# -2 0 -2点
18位 R -8 11 3点
19位 Scala 0 6 6点
20位 Ruby -9 16 7点
20位 Go 0 7 7点
22位 C -10 18 8点
23位 PHP -11 20 9点
24位 C++ -5 19 14点
25位 Swift 0 15 15点
26位 Java -7 23 16点
27位 TypeScript 0 17 17点
28位 SQL -4 24 20点
29位 Python 0 21 21点
30位 C# 0 22 22点
31位 JavaScript -1 25 24点

逆から見れば、最も好かれていて、アンチが少ない順番でもある。

集計方法としては、嫌われている言語トップ25と、よく使われている言語トップ25(好きな言語と仮定する)のデータをもってきて、
嫌われているならマイナス点をつける。嫌われ1位は-25点、2位は-24点、3位は-23点...25位は-1点とする。
よく使われている言語トップ25では、プラス点をつける。1位は25点、2位は24点、3位は23点...25位は1点とする。
これらの差を計算して、昇順に並べたものが、上の表である。
本当に嫌われている順番といえるだろう。
逆からみれば好かれている順番ともいえる。

本当は、生存バイアスとかもあるから、そこら辺も加味したい所でもある。
なぜなら、誕生して使われまくられればそれだけアンチも増えるというものだからな。

集計過程 嫌われている言語

開発者に嫌われているプログラミング言語トップ25
http://news.mynavi.jp/news/2017/03/30/133/
https://fossbytes.com/most-loved-and-most-hated-programming-languages/

1位 Visual Basic 6 1位なので-25点
2位 VBA 2位なので-24点
3位 CoffeeScript 3位なので-23点
4位 VB.NET -22点
5位 Matlab -21点
6位 Objective-C -20点
7位 Assembly -19点
8位 Perl -18点
9位 Lua -17点
10位 Hack -16点
11位 Groovy -15点
12位 Common Lisp -14点
13位 Dart -13点
14位 Erland -12点
15位 PHP -11点
16位 C -10点
17位 Ruby -9点
18位 R -8点
19位 Java -7点
20位 Julia -6点
21位 C++ -5点
22位 SQL -4点
23位 Haskell -3点
24位 F# -2点
25位 JavaScript -1点

集計過程 人気のプログラム言語2017

2017年、最も人気のプログラミング言語フレームワーク・データベースは?
http://news.mynavi.jp/news/2017/03/25/208/
https://stackoverflow.com/insights/survey/2017

1位 JavaScript 1位なので25点
2位 SQL 2位なので24点
3位 Java 3位なので23点
4位 C# 22点
5位 Python 21点
6位 PHP 20点
7位 C++ 19点
8位 C 18点
9位 TypeScript 17点
10位 Ruby 16点
11位 Swift 15点
12位 Objective-C 14点
13位 VB.NET 13点
14位 Assembly 12点
15位 R 11点
16位 Perl 10点
17位 VBA 9点
18位 Matlab 8点
19位 Go 7点
20位 Scala 6点
21位 Groovy 5点
22位 CoffeeScript 4点
23位 Visual Basic 6 3点
24位 Lua 2点
25位 Haskell 1点

生存バイアス

せっかくなので、生存バイアスも加味してみた。
生存バアイスは、 =ROUNDDOWN((2017-B2)/10,0) として、2017年から見て10年で1点とした。
年数がたっていれば、好きに加点して補正するという仕組みだ。

名前 誕生 生存バイアス補正
Visual Basic 6 1991年産まれ 2点
CoffeeScript 2009年産まれ 0点
Hack 2014年産まれ 0点
VBA 1993年産まれ 2点
Lua 1993年産まれ 2点
Common Lisp 1984年産まれ 3点
Matlab 1984年産まれ 3点
Dart 2011年産まれ 0点
Erland 1986年産まれ 3点
Groovy 2003年産まれ 1点
VB.NET 2001年産まれ 1点
Perl 2017年産まれ 0点
Assembly 1940年産まれ 7点
Objective-C 1984年産まれ 3点
Julia 2012年産まれ 0点
Haskell 1990年産まれ 2点
F# 2005年産まれ 1点
R 1996年産まれ 2点
Scala 2003年産まれ 1点
Ruby 1995年産まれ 2点
Go 2009年産まれ 0点
C 1972年産まれ 4点
PHP 1995年産まれ 2点
C++ 1983年産まれ 3点
Swift 2014年産まれ 0点
Java 1995年産まれ 2点
TypeScript 2012年産まれ 0点
SQL 1974年産まれ 4点
Python 1991年産まれ 2点
C# 2000年産まれ 1点
JavaScript 1995年産まれ 2点

wikipediaに掲載されていた日付をもとにした。
アセンブラは、それぞれのCPUごとに違うので、とりあえず一番古いコンピュータ(古代ギリシアのアレではない)の1940年としました。

生存バイアスを加味した、ガチで嫌われているランキング順

ランク 名前 嫌い 好き 生存バイアス 差分
嫌われ1位 Visual Basic 6 -25 3 2 -20点
嫌われ2位 CoffeeScript -23 4 0 -19点
嫌われ3位 Hack -16 0 0 -16点
4位 Dart -13 0 0 -13点
4位 VBA -24 9 2 -13点
4位 Lua -17 2 2 -13点
7位 Common Lisp -14 0 3 -11点
8位 Matlab -21 8 3 -10点
9位 Groovy -15 5 1 -9点
9位 Erland -12 0 3 -9点
11位 Perl -18 10 0 -8点
11位 VB.NET -22 13 1 -8点
13位 Julia -6 0 0 -6点
14位 Objective-C -20 14 3 -3点
15位 F# -2 0 1 -1点
16位 Haskell -3 1 2 0点
16位 Assembly -19 12 7 0点
18位 R -8 11 2 5点
19位 Scala 0 6 1 7点
19位 Go 0 7 0 7点
21位 Ruby -9 16 2 9点
22位 PHP -11 20 2 11点
23位 C -10 18 4 12点
24位 Swift 0 15 0 15点
25位 TypeScript 0 17 0 17点
25位 C++ -5 19 3 17点
27位 Java -7 23 2 18点
28位 C# 0 22 1 23点
28位 Python 0 21 2 23点
30位 SQL -4 24 4 24点
31位 JavaScript -1 25 2 26点

集計に使ったexcel表はここからどーぞ。
http://rtilabs.rti-giken.jp/files/2017_03_31/a.xlsx

間違いがあったら、許してヒヤシンス。

ソース管理等を使った改ざん検知

最近、サイトに侵入して、
クレカのフォームを改ざんし、自サイトにカード番号を送信するといういたずらが流行っているようです。

一見正しく動いているプログラムが、実は改ざんされていることになかなか気が付きにくいものです。
運営されている会社も、クレジットカード会社から連絡があったりして発覚しているようです。

一方で、最近の開発環境はソース管理が導入されています。
デプロイツールも導入されているところがあるでしょう。

正しいソースコードがあるならば、それと比較して改ざんを簡単に検知できるのではないだろうか?
と、いうことで、ソース管理等を使った改ざん検知システムを作ってみた。

案1 ソース管理そのものを使った diff(ただしあまり安全ではない)

とても簡単な改ざん検知
例えば、SVN とかのソース管理で、サーバを管理している場合
(たぶん GITでも同じことができるはず)

#!/bin/sh
DIRGET_DIRECTORY="/var/www/vhost/example.com"
MAIL_TO="alert@example.com"
SUBJECT="[DIFF ERROR!]"
SCS_PROGRAM="svn"

#IS_ALIVE=`ps aux | grep "${SCS_PROGRAM} " | grep -v grep  | wc -l`
#if [ $IS_ALIVE -ge 1 ]; then
#	exit 1
#fi

cd $DIRGET_DIRECTORY
DF=`${SCS_PROGRAM} diff | wc -l`
if [ $DF -eq 0 ] ; then
	exit 0
fi

MAILTEMPFILE=`mktemp`
echo "To: ${MAIL_TO}"  >> $MAILTEMPFILE
echo "Subject: ${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "" >> $MAILTEMPFILE
echo "${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "-------------------------------------------" >> $MAILTEMPFILE
${SCS_PROGRAM} diff >> $MAILTEMPFILE

sendmail $MAIL_TO < $MAILTEMPFILE

/bin/rm $MAILTEMPFILE
exit 100

これで、改ざん者がサイトを改ざんしたら、
変更点が発生し、メールで通知を投げることが出来ます。

ただし、この方法では、本番のwebディレクトリにソース管理機能があるので、あまりよくありません。
まずは、apacheの設定等で、 .svn や .git などへのアクセスを遮断しないと危険です。
次に、逆流して侵入者に commitされないように、ユーザ権限を振らないといけないでしょう。

案2 deployツールを使った場合

deployツールをつかった場合はどうか?
1日1回ならともかく、10分に1回などの場合は、
毎回デプロイツールがチェックに行くのは現実的ではありません。

別のディレクトリにも同一内容をデプロイして、
そこと比較することが考えられます。
ただ、別のディレクトリにもデプロイできるか?というデプロイツールの制約の壁があります。

例えば、

本番
/var/www/vhost/example.com

デプロイしたときについでに取ったコピー
/var/backup/example.com

だったとすれば、以下のようなシェルスクリプトで、diffを使って比較できます。

#!/bin/sh
DIRGET_DIRECTORY="/var/www/vhost/example.com"
COPY_DIRECTORY="/var/backup/example.com"
MAIL_TO="alert@example.com"
SUBJECT="[DIFF ERROR!]"

#Ignore when deploying.
#IS_ALIVE=`ps aux | grep "rsync " | grep -v grep  | wc -l`
#if [ $IS_ALIVE -ge 1 ]; then
#	exit 1
#fi

LANG=C
DF=`diff -rq ${COPY_DIRECTORY} ${DIRGET_DIRECTORY} | grep '^Files' | wc -l`
if [ $DF -eq 0 ] ; then
	exit 0
fi

MAILTEMPFILE=`mktemp`
echo "To: ${MAIL_TO}"  >> $MAILTEMPFILE
echo "Subject: ${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "" >> $MAILTEMPFILE
echo "${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "-------------------------------------------" >> $MAILTEMPFILE
diff -rq ${COPY_DIRECTORY} ${DIRGET_DIRECTORY} | grep '^Files' >> $MAILTEMPFILE

sendmail $MAIL_TO < $MAILTEMPFILE

/bin/rm $MAILTEMPFILE
exit 100

diff | grep '^Files' と、しているのは、
webroot以下に本番にしか無いデータファイルがある場合を考慮してです。
アップロードされた画像とかがおいてあると、片方にしかないよという暴発がありえるので、このようにしています。

あとはcronで定期実行するようにすると、
改ざん検知ができるようになると思います。

どれくらいの頻度でチェックするべきかは、
負荷と相談してやるべきですね。


これで、万が一にもサイトが改ざんされたとしても、早期に気がつけるようになります。
早期に気がつけるということは、被害が拡大する前に即サイトを修正することもできるでしょう。
場合によって、改ざんした人が改ざんをしていろいろ試している時に、止められて被害ゼロということもあるかもしれません。

フューチャーホームコントローラー(FHC)の複数台構成の実装の裏側

フューチャーホームコントローラー(FHC)の複数台構成について、裏側の実装をあまりに語っていないのでちょっと解説したいと思います。
https://rti-giken.jp/fhc/help/howto/multiroom.html


目指したのは、それぞれの部屋に置かれた端末がP2Pな関係で寄り添い通信して家全体のホームネットワークを自動で構築するというものです。

FHCには、webapiという機能があり、いわゆる共有キーのフレーズを使ってAPIを呼び出すことができます。
webapiは、 HTTP GETで要求を送り、返信は jsonで返ってくるシンプルなものです。
これを使えば自由に好きなアプリと連携できます。
https://rti-giken.jp/fhc/help/ref/setting_webapi.html

また、弊社サーバとhttps通信することで、リモートからでもWebAPIを呼び出せるようになっており、
外部webサービスと家の連携も可能になっています。

FHCの複数台連携は、このwebapiを利用する形で作られています。
具体的には、最初に相手を追加する時(信頼関係を結ばせる時)に、端末間でwebapiキーを交換します。

以後は、相手のwebapiキーを使ってそれぞれがそれぞれの機能を呼び出すというものです。
sshのキー認証みたいなものですね。
ただ、これは共有鍵なのでRSAとかに比べては弱いですが、ホームネットワークはLAN内限定なのでまあ信頼しています。

もし、何か理由でキーを記録しているファイルが流出した場合、
webapiキーをリセットすれば問題ありません。
流失キーは即時無効になります。
そしてキーの変更はホームネットワークで自動適応されます。
ユーザは何も考えずにキーをリセットしてOKです。

機能としても、いろいろ頑張っていて、
1:Nの複数台とリンクできるし、
複数の部屋に置かれたFHC群へのアクセスもとても容易です。
信頼端末の信頼端末(友達の友達)とも一度にコネクションできます。

自分<-->信頼端末(友達)<--->信頼端末の信頼端末(友達の友達)
自分<-->信頼端末(友達)で信頼関係を結ぶと、
自分<-->信頼端末の信頼端末(友達の友達)
友達の友達とも信頼関係を自動で結べます。

つまり、新しく部屋にFHCを設置したとしても、どこかの部屋においたFHCと信頼関係を結べば、新しく部屋に設置したFHCは、すべての部屋にアクセスできるというものです。
いちいち、すべての部屋へ信頼関係を手動で結ばせるのは手間ですからね。

信頼関係を結ぶには、自端末にログインでき、信頼関係を結びたい相手端末のIDとパスワードが必要です。
当然ながら、これらがわからないと信頼関係は結べません。
いたずらで侵入しようとしても無駄です。
正規に使うのは簡単でもイタズラは難しいを目指しています。

さらには、
DHCPで相手のIPが変わったとしても自動追従してネットワークを維持します。
webapiキーが変わっても同様です。
同時にすべての端末の電源が同時に切れて、相手のIPが変動しない限り追跡でき、
FHCのホームネットワークはそう簡単には破綻しません。

相手のIPが一度に全部変動しても追跡する機能も理論上は可能です。
ただ少し面倒なのでそこまでは作っていません。

以上が、フューチャーホームコントローラーの複数台対応です。
それぞれの部屋に置かれた端末がP2Pな関係で寄り添い通信して家全体のホームネットワークを自動で構築するというのを実現しました。
また、侵入者によるイタヅラもはねのける防御機能と、
ユーザの利便性を上げる裏方の機能があります。

あなたも、複数の部屋にFHCを置いて、家全体のホームネットワークを作ってみましょう。
https://rti-giken.jp/fhc/help/howto/multiroom.html

これが21世紀の新しい家の姿です。