CloudWatchでメトリクスフィルタの設定でちょこっとだけ苦戦した

皆さん、CloudWatch使ってますか!?
という、どこかで見たようなことがあることを自分も言ってみたくなったごきげんまるです。

今日はCloudWatchのメトリクスフィルタの設定です。

メトリクスフィルタとは何ぞやというのは、ほかの方々にお任せをします。
まぁ、何が出来るかというと、LambdaやECSのログはCloudWatchに出力されますが、そのログの一部(パターン)にマッチしたものをメトリックスにしてグラフで見たり出来るようになります。
監視ツールを入れると、ログ全部を監視ツールに送って、そちら側で絞りこみ等をするかと思いますが、例えば監視ツールを使わずに簡単な監視をさせるとかであればメトリクスフィルタは1つの対応方法になるかと思います。

例えば、メトリクスフィルタでERRORをフィルタし、その結果をSQSに送ってメールで受け取るとか。。。

自分がいる国とは別のリージョンのAWS環境を使っているが、その国の法律でデータの持ち出しが制限されているとか。。。

会社のルールでデータをAWS外に出すことが極端に制限されているので、エラーが出たことだけを通知して実際の内容はAWSにログインして確認しないといけないとか。。。

そんなときに使われる?


ということで、CloudWatchでメトリクスフィルタの設定の仕方です。

CloudWatchでメトリクスフィルタ設定

AWSのマネジメントコンソールからCloudWatchを選びます。

CloudWatchの画面から、「ログ」を選びます。
※ここでメトリクスは選ばないように!

f:id:gokigenmaru:20190708140823p:plain

メトリクスるフィルタを設定したいログを選択してから「メトリクスフィルタの作成」を選びます。

f:id:gokigenmaru:20190708141034p:plain

この画面でフィルタをする文字列を設定します。

f:id:gokigenmaru:20190708141237p:plain

フィルタパターンのところで、ログに対してどのようなフィルタをするかを設定できます。
ログ内でERRORをフィルタしたい場合は、フィルタパターンに"ERROR"を記載すればOK!

フィルタパターンの記載方法は、「例の表示」という箇所をクリックすると、よく使われるフィルタの記載方法が出てきます。
めっちゃ便利やーーん!

f:id:gokigenmaru:20190708141517p:plain

さらに、説明文中の「パターン構文の詳細を確認してください。」や「メトリクスフィルタ構文と例については、CloudWatch ログのヘルプを参照してください。」をクリックするとAWSのサイトに飛んで、詳細な設定方法が見れます。
docs.aws.amazon.com

いやぁ、便利っすね。さすがAWSです。
これを見ながらやればできちゃいます!

設定するフィルタパターンを入力したら、メトリクスの割り当てを選んで、次の画面に。
メトリクス名を決めて入力したらフィルタの作成を選択。これでメトリクスフィルタの作成は完了。簡単でしょ!?

f:id:gokigenmaru:20190708142249p:plain


で、今回自分はJAVAのプログラムで書かれたアプリケーションのログをフィルタすることになっていました。
先方からの要望は、
JAVAで作成したアプリケーションが出力するloglovelのエラーとワーニングをフィルタしてほしい。」

実際に、どのようにログが出てるかを見てみると、JSON形式で出力されていました。
ログにはJSON(1行で出力される)と、なぜかJSON形式の後に適当なメッセージが出ている。
あれ、JSON形式+1ですか?
ログは以下のような感じで出力される。

{"timestamp": "2019-07-07T06:25:19.420Z","log_level": "ERROR","loggername": "ApplicationExceptionHandler.handleCommonException","message": "AABBCCDDEEFFGG"} nazekahitokoto

先ほど紹介したAWSのサイトには、「JSON ログイベントから値を取得するメトリクスフィルターの使用」という項があり、この通りやればJSON形式のログのフィルタは簡単に出来そう。

{ $.log_level = "ERROR" }

というわけで試してみることに。
ちなみにですが、以下のように枠の中にテストしたいログを書いて、フィルタパターンにフィルタしたい文字列を記載して「パターンのテスト」をおすとフィルタが出来るかどうか試せます。
AW便利やーん(2回目
f:id:gokigenmaru:20190708143413p:plain

やってみたらフィルタ失敗…。なんでだ…。

f:id:gokigenmaru:20190708143706p:plain

お察しの方もいると思いますが、このログ、さっき言った通り、JSON+1なんです。。。
JSONに余計なものがついているせいで、JSON形式と認められず、結果、「JSON ログイベントから値を取得するメトリクスフィルターの使用」の通りにはいかない。。。

じゃあ、フィルタパターンにログで出るそのままの文字列、"log_level": "ERROR"を入れてみるが、失敗。。。
ダブルコーテーションで囲われている中身を文字列として認識するっぽいですね。まぁ、よくある当たり前の話か。。。

さて困った。。。
どうすればログをフィルタ出来るかもう一度さっきのAWSのサイトを隈なく読んでみる。
が、方法は出ていない。。。

ということで、どうすればフィルタ出来るか考えて…考えて…はっと思いつく。

「ダブルコーテーションをエスケープすればいいんでね?」

ということでやってみる。

フィルタパターンに「"\"log_level\": \"ERROR\""」を記載してテスト。
結果うまくいきました。

今回はERRORとWARNINGをフィルタしたいので、フィルタパターンの設定は以下の通りに。
「?"\"log_level\": \"ERROR\"" ?"\"log_level\": \"WARNING\""」

これでERRORとWARNINGのフィルタが出来ました。
めでたしめでたし。

ってか、JSON+1のログってなんすか???w


じゃあどうやってグラフとかを見てみるかというと、
CloudWatchの画面から、メトリクスを選んで

f:id:gokigenmaru:20190708145001p:plain


カスタム名前空間のLogMetricsを選んで、グラフを見たい対象のメトリクス名にチェックを入れると見れます。
※大人の事情で画面は無いです。


ということで、最後は端折りまくってメトリクスフィルタのお話でした。






教訓:ログはJSONならJSONで出してください。。。

AWSCLIコマンドを利用してDynamoDBのScale設定をしてみた

どうもごきげんまるです。
相変わらずの1か月ぶりのブログです。
前回のAnsible勉強会のブログをアップしたら普段アクセス数が地を這うレベルだったのに突然すごい勢いで上昇し、ビビッて腰が引けてしまいブログを書けなかったと言い訳をしています。

ということで、今日はDynamoDBのScaling設定をAWSCLIでやってみたという内容です。

実はこの内容ですが、仕事でミスしまして。。。実際には設定がされず関係各所に壮大な迷惑をかけてしまった件です。
仕事としてはミスで終了(リカバリは別の方にやっていただくというダメっぷり…)だったのですが、このままでは何にもならないということで、どうすれば良かったのかを調べてブログに書きます。
ちなみにミスったところは、DynamoDBのTableのキャパシティータグでAutoScalingの「読み込みキャパシティー」と「書き込みキャパシティー」にチェックが入ってなかった箇所です。
f:id:gokigenmaru:20190527095017p:plain

チェックを入れると入れた設定が反映されているように見えてしまったことで、チェックが無くても問題ないと判断をしてしまいした。。。
f:id:gokigenmaru:20190527095316p:plain

自分のミスを時間をおいて改めて見直すと、ほんとなんでこんなミスをって…。自分の心が乱れますね。。。ブログ書くって怖いっす><

AWSCLIのDynanoDB Scaling設定コマンド

DynanoDBのScaling設定をするやり方は以下のAWSのサイトに載っています。
docs.aws.amazon.com
ここで書かれている通りにやれば問題は無かった…。

気を付けるのは、Scaling設定の場合は「aws dynamodb ~」や「aws dynamodbstreams ~」ではなく、「aws application-autoscaling register-scalable-target --service-namespace dynamodb ~」となることです。
余談ですが、これはDynaomDBに限らずECSなどでもそうなのですが、AWS CLIでScale系の設定をするときには「aws application-autoscaling ~」となることが多いです。自分は最初の頃Scaling設定が見つけられずにコマンドリファレンスを彷徨いまくったことがあります。
少し分かりにくいところですね。

このブログをみて試される方は、まずは適当なDynamoDBのテーブルを作ってください。
そして、まずはmin-capacityとmax-capacityを設定します。

aws application-autoscaling register-scalable-target \
    --service-namespace dynamodb \
    --resource-id "table/TestTable" \
    --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
    --min-capacity 15 \
    --max-capacity 20

設定をすると、DynamoDBのTableの「プロビジョニングされたキャパシティ」の書き込みキャパシティーユニットの値が「15」になります。
こんな感じ。
f:id:gokigenmaru:20190527100441p:plain

デフォルトは「5」なので、上記コマンドを実行したことで書き込みキャパシティーユニットの値が「5」から「15」に変わったことが分かります。
そして、書き込みキャパシティーのチェックを入れてみると、以下のようになります。
f:id:gokigenmaru:20190527100626p:plain
これを見てもらうとわかりますが、先ほど設定するときに利用したコマンドの

--min-capacity : プロビジョニングされたキャパシティ」の書き込みキャパシティーユニットの値 と 「Auto Scaling」のプロビジョニングされた最小キャパシティーの値
--max-capacity  : 「Auto Scaling」のプロビジョニングされた最小キャパシティーの値

となります。

自分のミスは、これで希望の設定が出来てしまっていたことで、上記サイトでここまでの設定で終わらせてしまい、以降のコマンドを実行しなかった。。。
ターゲット使用率はデフォルトの70%でよかったので、これで設定完了と思い込んでしまった。。。

ということで、皆さんは以降の設定を必ず実施してくださいね。
言われなくてもすると思いますが。

ここでAuto Scaling設定がある程度できています。
次にTargetValueを設定していきます。
まずはjsonファイルを以下の内容で作成します。
ファイル名:scaling-policy.json

{
    "PredefinedMetricSpecification": {
        "PredefinedMetricType": "DynamoDBWriteCapacityUtilization"
    },
    "ScaleOutCooldown": 60,
    "ScaleInCooldown": 60,
    "TargetValue": 50.0
}  

作成後、以下のコマンドで上記jsonの設定を反映させます。

aws application-autoscaling put-scaling-policy \
    --service-namespace dynamodb \
    --resource-id "table/TestTable" \
    --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
    --policy-name "MyScalingPolicy" \
    --policy-type "TargetTrackingScaling" \
    --target-tracking-scaling-policy-configuration file://scaling-policy.json

設定をすると「ターゲット使用率」が「50」になります。
また、書き込みキャパシティーにチェックが入ります。
f:id:gokigenmaru:20190527103038p:plain

ここまでやればDynamoDBのAutoScaling設定が完了です。
読み込みキャパシティーユニットを変更する場合は以下を変更してください。

min-capacityとmax-capacity設定で、

aws application-autoscaling register-scalable-target \
    --service-namespace dynamodb \
    --resource-id "table/TestTable" \
    --scalable-dimension "dynamodb:table:ReadCapacityUnits" \
    --min-capacity 15 \
    --max-capacity 20

jsonファイルで
ファイル名:scaling-policy.json

{
    "PredefinedMetricSpecification": {
        "PredefinedMetricType": "DynamoDBReadCapacityUtilization"
    },
    "ScaleOutCooldown": 60,
    "ScaleInCooldown": 60,
    "TargetValue": 50.0
}  

json設定反映で

aws application-autoscaling put-scaling-policy \
    --service-namespace dynamodb \
    --resource-id "table/TestTable" \
    --scalable-dimension "dynamodb:table:ReadCapacityUnits" \
    --policy-name "MyScalingPolicy" \
    --policy-type "TargetTrackingScaling" \
    --target-tracking-scaling-policy-configuration file://scaling-policy.json





教訓:しっかりと検証・確認してから作業は実施しましょう。(当たり前

Ansible Night in Tokyo 2019.04 に行ってきましたー

どうもごきげんまるです。

2019/4/17(水) 19:00からやっていたAnsible Night in Tokyo 2019.04に行ってきました。
この勉強会?ですが、自分は一般参加枠として参加しました。
一般参加枠の倍率は結構高めの約2倍で、正直無理かなぁと思っていたのですが、当選の連絡が来て一安心。
というのも、2019/3/26(火)にもAnsibleのもくもく会があったのですが、見事落選…。倍率はそんなに高くなかったのに。。。ということがあったので、今回は参加できてよかったです。
当日は家でテレワークをしていたのですが、夕方前に自宅を出発、自社officeに寄ってから人と会ってそれから会場の恵比寿に向かうことにしました。

ちなみにですが、自分のAnsible歴はクラウド(AWS)上のEC2(これはTerraformで構築)に必要なMWや設定をいれるために使っているレベルで、経験的には3か月程度です。
しかも一度Ansibleのコードを作ってしまえばもう作らない…。
Ansibleでplaybookを書いたのは、構築とDD(Datadog)をインストール&設定をするのの2つだけです。

Ansible Night in Tokyo 2019.04会場到着編

会場は恵比寿のレッドハット株式会社 恵比寿ネオナート3階セミナー会場。
駅ほぼ直結だったので余裕だろうといろいろと人と話をしていたら時間がギリギリに(汗
急いで恵比寿駅に行ったのですが、Google Mapだとどの建物か見づらい。。。
Connpassから申し込んでいたのですが、このConnpassのイベントページに行き方が書いてあったので、それを頼りに会場に向かうことに。
建物にはすぐについたのですが、そこからが…。

「行き方:JR恵比寿駅 東口を出て右すぐ。渡り通路を越えの恵比寿ネオナートビル 3階 に直接お越しください。エレベーターホールから右方面にお進みいただくと入り口があります」

という説明があったので、駅からそのまま建物に入ると3階だと思い込み、入り口すぐのエレベーターホールで受付を探すこと数分。
どうしても見つからず、どうすればいいか泣きそうになっていたらほかの人がエレベーターに乗ったのを見て、
「ん?ここ3階じゃないのかな?」
とエレベーターに乗ってみたら3階は1つ上の階でしたwww

受付でConnpassのIDを見せて飲み物(タダ、ありがとうございます!)をいただいて会場に。
ただでさえギリギリの時間だったのに、ここでさらに時間を喰ってしまったため、会場に入ると開始時間を過ぎており、テーブルがある席に空きがないorz
椅子には座れたので、まぁよしということでようやく参加です!

Ansible Night in Tokyo 2019.04オープニング編

すでにブログを書くのが面倒に…。(内緒
会場ついて席に座ると、オープニングの説明が始まっていました。
運営のサポート募集とかの説明がされており、こういうイベントの裏方って機会があまりないし、自分にやれることは大したことは出来ないけど、やったことないしやってみたいなぁと思いながら聞いていました。

Ansible Night in Tokyo 2019.04オープニングセッション〜Ansible Roadmap & Ask me anything〜 by Red Hat Inc, Ansible 編

最初のスピーカーの人、綺麗な女性で英語でした。
英語が分からない人向け(自分も当然そちら側)にオープニングで説明していた人が翻訳してくれました。この人、youtubeへの動画配信とかTwitterとかSlackのチェックをしつつ翻訳。何者ですか?w
でもせっかくだから英語で聞いてみようと思ったけど、半分くらいしかわからなかった…。
英語の女性の人、雰囲気的にとてもおもしろそうな人。
AnsibleTowerの説明をしてくれているが、自分があまりAnsibleTowerのことを理解していないので英語もあいまってよく理解できなかった。。。残念。

説明の中で、AnsibleTowerの新しいバージョンが5月中旬に出るとのこと。
新しいバージョンで使える機能?として気になったのは、
 ・ansible collection コミュニティモジュールを塊にできる。かも?
           でも、コミュニティモジュールあんまり詳しくないけど最新バージョンで動くようにメンテナンスされてるかどうかがなぁというのが気になる。。。
 ・ansibleは誰もplaybookを書かなくても実行できるようにする。管理者は書くがその他の人はguiベースでつなぎ合わせて出来るようになる?
  書くまでは難しいけど、組み合わせてちょこちょこっと修正して動かすということができる人は結構多そうなので、これはいいねって思いました!テストはしっかりやらないとだけど。
 ・Exteral credential credential情報を外部のDBとかに持たせ、AnsibleTowerでは情報を保持しなくてもいいように出来る。これは個人的にはうれしい。

ちなみにExteral credentialの件、質問した人が居てansibletowerをハックした後にcredentialにquery投げたら情報抜けるんじゃね?って質問しててすげーなと思った。確かに。。。

Ansible Night in Tokyo 2019.04 各セッション編

VMwareで作ったIaaSにAnsible Towerを導入した話

このセッションの説明をしてくれた人、資料がとても読みやすかったです。ありがとうございます。
この人は会社で新しい部署でIaaSのサービスを構築するにあたりAnsible Towerを導入しサービスを構築するまでにどのような検討をしたかという内容と、Ansible導入後の話(発生した課題や運用の話)、そして今後Ansibleでこんなことをしようと思っていますとうい話の3本立てで、とても話が分かりやすく聞き入ってしまいました。
自分は立場的にはこのような人が「Ansibleで行くよ!playbook書いてねー」と言われるところからスタートするか、すでにAnsibleで書いているところにjoinするかなので、上位でどのようなことが検討されてどういう判断となって導入となるか知らない(見えない)ことが多いので、どういう経緯でどのようなことを検討してAnsibleで行くのかの背景を少し見えてよかったです。
なんだろう、この人の下で働きたい(笑)というくらい分かりやすい説明でした。ぜひ次回も登壇オナシャス!!!

自社クラウドサービスをAnsibleで作った話

うってかわって、アプリ出身の人がサービスをAnsibleで作った話でした。
自分、アプリケーション開発はほんと触ったことがある程度の人間なので、正直話されている内容が難しかったっす…。
説明の最初のころはAnsibleを導入した理由等、オペミス防止やIaCなどの話だったのでそこらへんは分かったのですが、話が深くなっていくにつれて内容が…すいません><
変数や関数の話を主にされていました。きっとアプリケーション開発寄りの人には面白い話だったんだろうなぁ。
※言っていることの多くは分かりませんが、この話は理解できると楽しそうというふいんき(変換できない)は伝わってきました。なんだろう、資料を読むだけだとさっぱりですが、やっぱりこういう場で説明を聞いているとふいんき(ryだけは少し分かるんですよね。

LT

1人5分という短い時間枠の中で、LT登壇された方の経験を共有いただきました。
特に印象に残っているのは、当日金沢?からわざわざこのために来てLTをされた方の内容で、「レガシーなAnsibleを改善していくための方針」とうい内容でした。
正直、このLTについてはもっと深く説明をしてもらいたいくらいの内容で、5分枠ではなく20分くらいの枠の中でやってほしいと心の底から思いました。
この資料、後で見返してみても本当によく出来ていて、特に最後のまとめなんかはほんとこれで本のタイトルになるレベルです。
金沢行くんで自分のこと雇ってもらえませんか? #40過ぎのおっさんを雇う奇特な人は居ないの知っての発言です。

LT枠ですが、他の方の説明もほんとよく出来ていて、正直5分だと短くて内容の割に頭には入りづらかったです。
後日資料を見返してみて、「あぁ、この人はこんなことが言いたかったんだな」というのを察する感じでした。
出来れば次回はもう少し長い時間で説明がもらえるとうれしいです。
※運営さん、お願いします!

Ansible Night in Tokyo 2019.04 終了編

今回、19:00~21:00の2時間でしたが、登壇していただいた皆さんの話はかなり楽しいので、時間が過ぎるのが早かったです。
資料だけ見るのではなく、このように説明を聞きながら資料も見ながらでやるからこそ、自分の理解度も深まるし楽しい思いも出来るんだなぁというのを実感した時間でした。
このような勉強会がタダで受けられるってのは今の時代の若いエンジニアの人たちは恵まれてるなぁと思いました。
ま、自分も40超えたとはいえまだまだ現役でやろうと思っていますし、勉強会があれば率先して参加していこうと思っていますがw
これだけの人数を纏めるのも大変だったと思います。運営に携わった方々にはほんとありがとうございましたとお伝えしたいと思います。
もくもく会は出たことがないので、次はもくもく会でAnsible勉強していけたらいいなぁと思いました。

次回はAnsibleもくもく会 2019.05(ネットワーク編)in エーピーコミュニケーションズ。今日から受付なのにすでに定員越えw
自分はリモート参加枠で出ようと思っています!
次回も宜しくお願い致します!!!








ブログを書く人は「#ansiblejp」をつけてシェアしてくださいとあるのですが、どうすればいいのかわからないのでブログ本文に書いちゃいます。
自分、ブロガー枠じゃないからいいよね…(ボソッ

awscliのqueryオプションについて

どうもごきげんまるです。
前回のブログから3か月か経過し、もう書く必要がないんじゃないかと思い始めてます。

桜、散っちゃいますね。
ごきげんまるの頭の中からもはてなのブログの書き方がきれいさっぱり散っています(笑)

ということで、今日はawscliのqueryオプションについてです。

AWSCLIのqueryオプション

以前のブログで、show系のコマンド(AWSCLIではdescribeやlistです)を多く使うと書きましたが、このshow系のコマンド実際に実行するとすべての情報が出力されるので結構見づらいことが多いです。
そもそもですが、必要な情報というのはピンポイントでほしかったりするので、大量に出力されても該当の情報を見るのが大変。。。
ということで、出力される情報を制限することが結果として正しいオペレーションにつながったりします。
また、このAWSCLIというコマンドですが、設定変更や起動・停止などをするときに、対象となるインスタンスやfunctionなどの名前だけでは引数としては足らず、IDやARNなど、コマンドによって必要となる情報が違います。
手動実行であれば都度必要な引数に合わせた情報をメモなどに残してということもできますが、スクリプトなどを仕込んで自動化しようとすると都度メモはできないので、show系のコマンドの出力結果を変数に叩き込んで、実際の変更コマンドを実行するなどの工夫が必要です。

その時に必要となるのが--queryというオプション。

使いこなせればかなり便利(決して自分が使いこなしているとは言えないけど。。。)なので、積極的に利用して覚えていくのがいいかと思います。
ということで、実際に使うとどうなるか書いていきます。


よくあるec2で見てみます。
対象のアカウントで作成されているec2インスタンスの設定を見るには"aws ec2 describe-instances"を使います。

$ aws ec2 describe-instances
{
    "Reservations": [
        {
            "Instances": [
                {
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "PublicDnsName": "ec2-1-2-3-4.ap-northeast-1.compute.amazonaws.com",
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    },
                    "EbsOptimized": false,
                    "PublicIpAddress": "1.2.3.4",
                    "PrivateIpAddress": "10.0.0.4",
                    "ProductCodes": [],
                    "VpcId": "vpc-xxxxxxxxxxxxxxxxx",
                    "CpuOptions": {
                        "CoreCount": 1,
                        "ThreadsPerCore": 1
                    },
                    "StateTransitionReason": "",
                    "InstanceId": "i-1234567890",
                    "EnaSupport": true,
                    "ImageId": "ami-123456789",
                    "PrivateDnsName": "ip-10-0-0-4.ap-northeast-1.compute.internal",
                    "KeyName": "MyKeyName",
                    "SecurityGroups": [
                        {
                            "GroupName": "launch-wizard-1",
                            "GroupId": "sg-xxxxxxxxxxxxxxxxx"
                        }
                    ],
                    "ClientToken": "",
                    "SubnetId": "subnet-123456789",
                    "InstanceType": "t2.micro",
                    "CapacityReservationSpecification": {
                        "CapacityReservationPreference": "open"
                    },
                    "NetworkInterfaces": [
                        {
                            "Status": "in-use",
                            "MacAddress": "01:02:03:04:05:06",
                            "SourceDestCheck": true,
                            "VpcId": "vpc-XXXXXXXXXXXXXXXXX",
                            "Description": "Primary network interface",
                            "NetworkInterfaceId": "eni-123456789",
                            "PrivateIpAddresses": [
                                {
                                    "PrivateDnsName": "ip-10-0-0-4.ap-northeast-1.compute.internal",
                                    "PrivateIpAddress": "10.0.0.4",
                                    "Primary": true,
                                    "Association": {
                                        "PublicIp": "1.2.3.4",
                                        "PublicDnsName": "ec2-1-2-3-4.ap-northeast-1.compute.amazonaws.com",
                                        "IpOwnerId": "amazon"
                                    }
                                }
                            ],
                            "PrivateDnsName": "ip-10-0-0-4.ap-northeast-1.compute.internal",
                            "Attachment": {
                                "Status": "attached",
                                "DeviceIndex": 0,
                                "DeleteOnTermination": true,
                                "AttachmentId": "eni-attach-123456789",
                            },
                            "Groups": [
                                {
                                    "GroupName": "launch-wizard-1",
                                    "GroupId": "sg-123456789"
                                }
                            ],
                            "Ipv6Addresses": [],
                            "OwnerId": "xx##$$##XX",
                            "PrivateIpAddress": "10.0.0.4",
                            "SubnetId": "subnet-123456789",
                            "Association": {
                                "PublicIp": "1.2.3.4",
                                "PublicDnsName": "ec2-1-2-3-4.ap-northeast-1.compute.amazonaws.com",
                                "IpOwnerId": "amazon"
                            }
                        }
                    ],
                    "SourceDestCheck": true,
                    "Placement": {
                        "Tenancy": "default",
                        "GroupName": "",
                        "AvailabilityZone": "ap-northeast-1a"
                    },
                    "Hypervisor": "xen",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/xvda",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": true,
                                "VolumeId": "vol-123456789",
                            }
                        }
                    ],
                    "Architecture": "x86_64",
                    "RootDeviceType": "ebs",
                    "RootDeviceName": "/dev/xvda",
                    "VirtualizationType": "hvm",
                    "HibernationOptions": {
                        "Configured": false
                    },
                    "AmiLaunchIndex": 0
                }
            ],
            "ReservationId": "r-xxxxxxxxxxxxxxxx",
            "Groups": [],
            "OwnerId": "xx##$$##XX"
        }
    ]
}

このコマンド、ec2インスタンスの情報が大量に出てくるので、必要な情報を探すのは大変…。
というときにいいのがqueryオプション。
例えばPrivateIpAddressだけ知りたいときとかは以下のようにqueryオプションで絞れます。

$ aws ec2 describe-instances --query 'Reservations[].Instances[].PrivateIpAddress'
[
    "10.0.0.4"
]

こんな感じでqueryオプションを使うとほしい情報だけに出力を絞れます。
これ、結構便利なんですよねー。
EC2だとインスタンスIDとかの情報をよく使ったりするのですが、その場合は以下のようにします。

$ aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId'

[
    "i-1234567890"
]

便利、超便利。
この便利なqueryですが、お作法があります。

・まず、コマンドのオプションは以下のように記載する。
  --query
・検索する情報は'(シングルクォーテーション)で囲う。

aws ec2 describe-instances --query 'ここにqueryの条件を入れる'

となります。
これは覚えてしまってください。

そしてqueryを使うとき、意識するのはjsonファイルの構造。
例えば上で使ってるインスタンスIDを出力させるためのコマンドで説明すると、

aws ec2 describe-instances --query 'Reservations.Instances.InstanceId'
これは
aws ec2 describe-instances で出てくる情報の

Reservations という階層にある
 Instances という階層にある
  InstanceId の情報を出力する
となります。
つまり

{
    "Reservations": [
        {
            "Instances": [
                {
                    "InstanceId": "i-1234567890",  <-ここの情報が取れる
                }
            ]
        }
    ]
}

こんな感じ?
わかるといいんですが…。


ということで、queryオプションが便利という話でした。
ほんと触りだけしか書いてないのですが、これだけでも便利なのが伝わるんじゃないかなと思います。





え、伝わらない?











伝われ(笑)


明日はAnsible Night in Tokyo 2019.04にイッテキマスー

AWSCLIを使ってみる

あけましておめでとうございます。今年もよろしくお願いします。
ごきげんまるです。

ということで、2019年1発目のブログを新年から半年経過した今日書きます。

AWSのアクセスキーとシークレットキー

AWSCLIのインストールが終われば、AWSCLIを使うための設定は1つ。AWSCLIのコマンドを実行するAWS環境の指定です。
この指定はコマンド1つで実行可能ですが、AWS環境を指定するためにはアクセスキーとシークレットキーが必要です。
Terraformなどを利用されている方には馴染みがあると思います。自分は仕事でTerraformで環境構築をしているので、アクセスキーとシークレットキーはすぐにわかりましたが、使ってないと「何それ?」となる人も多いのでは?
ということで、アクセスキーとシークレットキーの作成方法と調べ方を先に記載します。

1. AWSのコンソールからIAMコンソールを開きます。
2. 画面左のツリーから、「ユーザー」を選択。
3. 利用しているユーザ名をクリック。
4. 「認証情報」タブを選択。
5. すでにアクセスキーとシークレットキーがある場合は、ここでアクセスキーの箇所にアクセスキーIDがあります。
  ない場合は作成が必要なので、「アクセスキーの作成」を選択。
6. アクセスキーが自動で作成されるので、アクセスキーIDとシークレットキーをメモ。

ちなみにですが、アクセスキーとシークレットキーが作成済みであれば、コンソール画面の右上、自身のアカウント名が表示されているところをクリックし、「セキュリティ認証情報」から「アクセスキー(アクセスキーIDとシークレットアクセスキー)を選択すれば確認できます。」

アクセスキーとシークレットキーの情報が手に入ったらAWSCLIのコマンドで環境設定をします。

AWS環境設定

環境設定は以下のコマンドを実行すればOKです。

$ aws configure
AWS Access Key ID [None]:     <-先ほど調べたアクセスキー情報を入力
AWS Secret Access Key [None]:   <-先ほど調べたシークレットキー情報を入力
Default region name [None]:    <-デフォルトで利用するリージョン(東京ならap-northeast-1)を入力
Default output format [None]:   <-コマンドの出力形式を選択。(JSON/TEXT/TABLE)

これで設定は完了です。
ちなみにですが、これはDefaultのprofile設定となります。
profileは複数作成可能で、環境ごと(本番、開発など)にprofileを作成することも可能です。
例えば開発のprofileを作成するときは以下のようにオプションに"--profile profile名"を入れることで作成可能です。

$ aws configure --profile testprofilename
AWS Access Key ID [None]:     <-先ほど調べたアクセスキー情報を入力
AWS Secret Access Key [None]:   <-先ほど調べたシークレットキー情報を入力
Default region name [None]:    <-デフォルトで利用するリージョン(東京ならap-northeast-1)を入力
Default output format [None]:   <-コマンドの出力形式を選択。(JSON/TEXT/TABLE)

複数prifileを作成した場合ですが、コマンドを普通に実行すると、Defaultのprofileで環境が指定され実行されます。
コマンド実行時に引数に"--profile profile名"を入れれば、指定したprifileの環境でコマンドが実行されます。
AWSCLIですが、コマンドでAWS環境の構築・変更・削除が可能となる(もちろんIAMで設定されている権限で可能な範囲)ので、注意が必要です。
なので、Defaultのprofileは開発環境とし、本番に対して実行する場合は--profileオプションで実行する等を考慮してもいいと思います。
※自分は面倒なのと、本番運用に入った環境でAWSCLIを実行することが無いので、都度Defaultのprofileをaws configureで変更しています。

aws configureで設定した内容は自身のhome directory配下に「.aws」というディレクトリが作成され、そこに情報が格納されています。
「.aws」に2つのファイルが作成されます。
 config ・・・リージョンとアウトプット形式の情報が記載される
 credentials・・・アクセスキーとシークレットキーの情報が記載される
credentialファイルがあればAWS上に勝手にいろんなインスタンスを作成されてしまいますので、間違っても、.aws配下のファイルをgitなどに上げないようにしましょう!

AWSCLIコマンドを実行してみる

ここまで設定をすればAWSCLIでAWS環境へコマンドを実行できます。
AWSCLIのコマンドリファレンスは以下のサイトで公開されているので、実行したいコマンドを調べて実行してみるといいと思います。

docs.aws.amazon.com

といっても何かれやればいいかわからないという方もいるかと思います。
show系のコマンドであれば実行しても変更は入らないので、設定情報の確認から触ってみるのがいいかもです。
AWS上で何かしらを作っているのであれば必ずあると思うのがVPC系の情報なので、例えば以下のあたりのコマンドを実行してみましょう。

$ aws ec2 describe-vpcs
{
    "Vpcs": [
        {
            "VpcId": "vpc-xxxxxxxxx,
            "InstanceTenancy": "default",
            "CidrBlockAssociationSet": [
                {
                    "AssociationId": "vpc-cidr-assoc-xxxxxxxx",
                    "CidrBlock": "172.31.0.0/16",
                    "CidrBlockState": {
                        "State": "associated"
                    }
                }
            ],
            "State": "available",
            "DhcpOptionsId": "dopt-xxxxxxxx",
            "OwnerId": "xxxxxxxxxx",
            "CidrBlock": "172.31.0.0/16",
            "IsDefault": true
        }
    ]
}

このコマンドはAWS上で設定されているVPCの情報を確認するためのコマンドです。
上記は自分のAWS環境のDefaultのVPC情報ですね。
Default output formatの設定をJSONにしているので、JSONで出力されています。
出力形式は何も指定しない場合はDefault output formatの設定で出力されます。コマンドのオプション(--output )で変更が可能で、text形式で出力させたい場合は"--output text"、table形式で出力させたい場合は"--output table"で変更が可能です。
例えば上記のコマンドに"--output text"オプションを指定するとこんな感じ。

$ aws ec2 describe-vpcs --output text
VPCS    172.31.0.0/16   dopt-xxxxxxxx   default True    xxxxxxxxxx    available       vpc-xxxxxxx
CIDRBLOCKASSOCIATIONSET vpc-cidr-assoc-xxxxxxx 172.31.0.0/16
CIDRBLOCKSTATE  associated

"--output table"にするとこんな感じ。

$ aws ec2 describe-vpcs --output table
-------------------------------------------------------------------------------------------------------------------
|                                                  DescribeVpcs                                                   |
+-----------------------------------------------------------------------------------------------------------------+
||                                                     Vpcs                                                      ||
|+---------------+----------------+------------------+------------+---------------+-------------+----------------+|
||   CidrBlock   | DhcpOptionsId  | InstanceTenancy  | IsDefault  |    OwnerId    |    State    |     VpcId      ||
|+---------------+----------------+------------------+------------+---------------+-------------+----------------+|
||  172.31.0.0/16|  dopt-xxxxxxxx |  default         |  True      |  xxxxxxxxxxxxx |  available  |  vpc-xxxxxxxx  ||
|+---------------+----------------+------------------+------------+---------------+-------------+----------------+|
|||                                           CidrBlockAssociationSet                                           |||
||+------------------------------------------------------------------+------------------------------------------+||
|||                           AssociationId                          |                CidrBlock                 |||
||+------------------------------------------------------------------+------------------------------------------+||
|||  vpc-cidr-assoc-xxxxxxxx                                         |  172.31.0.0/16                           |||
||+------------------------------------------------------------------+------------------------------------------+||
||||                                              CidrBlockState                                               ||||
|||+-----------------------------------------+-----------------------------------------------------------------+|||
||||  State                                  |  associated                                                     ||||
|||+-----------------------------------------+-----------------------------------------------------------------+|||

もちろん、VPCだけではなくS3やEC2などもコマンドが用意されているので、上記で紹介しているリファレンスを見ながらいろいろと試してみるといいかと思います。
自分は「AWS上で構築した環境が正しくパラメータが設定されているかの確認をやれるようにしてほしい。」というお客様からのリクエストを満たすために使っているので、基本的にはshow系のコマンドを多く使います。
実際に環境の構築や変更・削除はAWSCLIではなくTerraformでやっているので…。

Windows10 WSL(Ubuntu18.04)でawscliをインストールしてみた

最初のブログを書いてからだいぶ時間が経ちましたが、技術的なブログは1つだけ。
ブログは気が向いたら書けばいいと、すでに心の中で言い訳をしているごきげんまるです。

自分はWindows10にLinux(Ubuntu18.04)を入れて使っています。
Windows Subsystem for Linuxです。
ファイルシステムとかの制御はwindowsベースなのでいろいろと問題もあったりしますが、Vagrantなどを起動せずにLinuxが使えるのは便利ですね。

今回はそのUbuntuでawscliをインストールして使えるようにした話になります。

AWS CLIとは・・・

AWSCLIで構築したりすることができるツールです。CLIはそのままコマンドラインインターフェスの略ですね。
AWSは基本的にはコンソール画面からGUIでポチポチすればネットワークやサーバなどを構築できますが、それをコマンドでやれると何がいいかというと、Linuxなどのコマンドラインからスクリプトでいろんなことが自動で実行できるようになります。

今回、なぜAWSCLIを使うことになったかというと、お客様から、「AWS上で構築した環境が正しくパラメータが設定されているかの確認をやれるようにしてほしい。」というリクエストがあったからです。
table1個、EC2を1つ、S3のBucket1つというレベルであれば目視確認でいいのですが、作成しているのはtableで数十個という単位なので、目視確認は時間がかかる。。。
じゃあスクリプトで値を取ってきて、エクセルとかで比較できるようになれば簡単だねという話になり、実現するのに何を使おうかという中でAWSCLIならいけるんじゃね?ということで使うことにしてみました。
※terraformingも検討したのですが、一部の値がとってこれないことが机上の調査で分かったので、やめました。


じゃあ使おうとなった時に、いちいちAWS上にEC2をLinuxで構築してというは面倒。簡単に試しつつ使ってみたかったので、WSL上にあるUbuntuでやってみることに。

といっても、Ubuntuリポジトリにawscliの1.14があります。
なので、apt installとかapt updateをすればawscli1.14.44あたりが最新で入るはずです。

~$ apt search awscli
Sorting... Done
Full Text Search... Done
awscli/bionic 1.14.44-1ubuntu1 all
  Universal Command Line Environment for AWS


じゃあブログにならないじゃんという話なのですが、実はawscliの最新は1.16(2018/12/03現在)なので、Ubuntuリポジトリにあるのは古いバージョンです。
まぁ、リポジトリにあるのは古いバージョンというのはよくある話です。
1.14でももちろん使えるのですが、試していたところ1.14では使えないコマンドがあり、どうしてもそのコマンドが使いたいということで最新の1.16を入れることにしました。


Linux環境にpipをインストール

AWSのいいところ、それはだいたいの情報がAWSの公式サイトに上がっていることです。
LinuxにAWSCLIをインストールする方法もググれば上位にAWSの公式サイトの情報が出てきます。AWSがCloudで1番使われる理由もこの辺りがあるんだろうなぁ。と感心します。
たまにわかりづらいですが…。

docs.aws.amazon.com

これを見ながらやればいけるはず。
ということで、サイトに記載されている通りpythonの確認を実施。
Ubuntu18.04はPython3が入っています。

~$ python3 --version
Python 3.6.5

Python 3 バージョン 3.3以上が入っているので、Python3は問題なし。
ということで、pipのインストール確認を実施。

~$ which pip
~$

コマンドないなー。インストールされてないなーということで、pipのインストール実施。
pipのインストールはpypa.ioからスクリプトをダウンロードし、ダウンロードしたスクリプトを実行しPathを通せばOKとのこと。
楽勝っすね。
公式サイトにある通り、

~$ curl -O https://bootstrap.pypa.io/get-pip.py
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1622k  100 1622k    0     0   723k      0  0:00:02  0:00:02 --:--:--  723k
~$ python get-pip.py --user

Command 'python' not found, but can be installed with:

sudo apt install python3
sudo apt install python
sudo apt install python-minimal

You also have python3 installed, you can run 'python3' instead.

何も考えず、サイトにあったコマンドをそのまま実行したら怒られた。
まぁ、当たり前の話でPythonは3です。
なので、python3 get-pip.py --userにすればOK。

~$ python3 get-pip.py --user
Traceback (most recent call last):
  File "get-pip.py", line 20890, in <module>
    main()
  File "get-pip.py", line 197, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip._internal
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/__init__.py", line 40, in <module>
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/cli/autocompletion.py", line 8, in <module>
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/cli/main_parser.py", line 8, in <module>
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/cli/cmdoptions.py", line 17, in <module>
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/locations.py", line 10, in <module>
ImportError: cannot import name 'sysconfig'

えっと。。。最後ImportErrorって書いてあるんすけど。。。
sysconfigがimportできないってことだけど、sysconfigはLinuxの標準ライブラリのはず。それがimport出来ないってことはここにあるはずの何かが足りないってことか。
と思ってググってみると、
Qiitaのブログで2018年5月からget-pip.pyを実行するとImportError: cannot import name 'sysconfig'が出るというブログを発見。
読ませていただいたところ、暫定的な解決策としてPPAを変えたらいけたということで、やってみることに。

~$ sudo add-apt-repository ppa:deadsnakes/ppa
~$ sudo apt-get update
~$ sudo apt-get install python3.6 python3.6-dev
~$ sudo python3.6 get-pip.py
Traceback (most recent call last):
  File "get-pip.py", line 20890, in <module>
    main()
  File "get-pip.py", line 197, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip._internal
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/__init__.py", line 40, in <module>
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/cli/autocompletion.py", line 8, in <module>
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/cli/main_parser.py", line 8, in <module>
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/cli/cmdoptions.py", line 17, in <module>
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/locations.py", line 10, in <module>
ImportError: cannot import name 'sysconfig'

ダメじゃああああああん orz。。
pipインストールできない。詰んだ。
※このブログを書いているときに分かったのですが、pypaのGitサイトでIssueが出ていて、そこを見れば簡単に解決出来たのですが、only英語であったのと、この時は英語読みたくない病が発病していた為、ちゃんと読まなかったのです…。

仕事で入れているんでなければここで諦めてSplatoon2でも始めるのですが、仕事でAWSCLIが必要であったことから、諦めたいけど諦めずに考えることに。
上で試したのは結局python3を入れなおすことで、今やりたいのはpipを入れること。
pipかぁ、pypa.io以外にpipのインストールスクリプトが置いてあるサイトはないのかな。
インストールスクリプト、、、
ん、インストールか。ダメもとでUbuntuリポジトリで探してみるかなぁ。

~$ apt search pip
~~大量出力~~

見るのメンドイ…。
そういえばUbuntuはコマンドうってみて無かった時にaptで入れろとか出るなぁ。

~$ pip --version

Command 'pip' not found, but can be installed with:

sudo apt install python-pip

(゚∀゚)キタコレ!!
Ubuntuリポジトリにpipあるやん!!!

ちょっと待てよ。pythonって書いてあるな。
python3も欲しいな。。。無いかなぁ。

~$ apt search python3-pip
Sorting... Done
Full Text Search... Done
python3-pip/bionic-updates 9.0.1-2.3~ubuntu1 all
  Python package installer


(゚∀゚)キタコレ!!
python3もあるじゃん!
両方インストールしてしまおう。

~$ sudo apt install python-pip python3-pip
~$ which pip
/usr/bin/pip
~$ which pip3
/usr/bin/pip3
pip --version
pip 9.0.1 from /usr/lib/python2.7/dist-packages (python 2.7)
~$ pip3 --version
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)

ということでようやっとAWSCLIインストールに必要となるpipのインストールが完了しました。
無駄に時間喰ったなぁ。。。

Linux環境にAWSCLIをインストール

ようやく本命のAWSCLIのインストールです。
pipを使ってインストール。

~$ pip install awscli --upgrade --user
Collecting awscli
~~中略~~
Successfully installed PyYAML-3.13 awscli-1.16.67 botocore-1.12.61 colorama-0.3.9 docutils-0.14 futures-3.2.0 jmespath-0.9.3 pyasn1-0.4.4 python-dateutil-2.7.5 rsa-3.4.2 s3transfer-0.1.13 six-1.11.0 urllib3-1.24.1

Successfully installedでawscli-1.16.71が出ているので、無事成功。
AWSCLIは簡単に入ったわー。よかったー。
コマンドを実行出来るか確認。

~$ aws --version

Command 'aws' not found, but can be installed with:

sudo apt install awscli

ちょwwwwwww
コマンド見当たらないとか出てるんですけどおおお

冷静にサイトを見ると、AWSCLI実行ファイルのパスを追加しないといけないらしい。

~$ export PATH=~/.local/bin:$PATH
~$ aws --version
aws-cli/1.16.67 Python/2.7.15rc1 Linux/4.4.0-17134-Microsoft botocore/1.12.57
~$ source .profile
~$ cat .profile
~~中略~~
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi

無事インストール完了しました。
ちなみにですが、インストールを実施した12/3頃はバージョンが1.16.67でしたが、今日(12/7)確認してみたら1.16.71になっていました。
AWS関連はupdateが早くて多い。。。

auditでコマンド実行履歴をログに取得してみた

どうも、ごきげんまるです。

 

皆さんは会社のLinuxサーバでログイン者のコマンド実行履歴を管理されていますか?

Linuxではコマンド履歴を取得する方法がいくつかあります。

私の現場では、Snoopy Loggerを使ってLinuxサーバのコマンド履歴を監査用として取得していましたが、AWSでAmazonLinux2でEC2インスタンスを作成した際にSnoopy Loggerがうまくインストールできない問題があったことから、Linux標準で用意されているauditに変更。その内容を書こうと思います。

aujditのログのローテートで少しはまった話についてはまた次回。。。

 

Snoopy Loggerとは

コマンドの実行履歴をsyslogに記録してくれるツールです。

github上に公開されており、いろいろなLinuxディストリビューションに対応しているツールで、インストール実行するとディストリビューションに応じたインストールが走ってくれる便利ツールです。

 

github.com

 

なぜSnoopy Loggerを使わなかったのか。

AmazonLinux2ではインストールがうまく行かなかった…。

gcc等のSnoopy Loggerで必要なパッケージを手動で入れる必要はありましたが、インストールシェルは実行でき、うまくいっているように見えるのですが、ログを見るとerrorを吐いて止まっている。

インストールログ:
~途中省略~

 

SNOOPY INSTALL: Building... make all-recursive
make[1]: Entering directory `/tmp/snoopy-2.4.6'
Making all in etc
make[2]: Entering directory `/tmp/snoopy-2.4.6/etc'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/tmp/snoopy-2.4.6/etc'
Making all in lib
make[2]: Entering directory `/tmp/snoopy-2.4.6/lib'
Making all in inih
make[3]: Entering directory `/tmp/snoopy-2.4.6/lib/inih'
Making all in src
make[4]: Entering directory `/tmp/snoopy-2.4.6/lib/inih/src'
CC ini.lo
CCLD libinih.la
make[4]: Leaving directory `/tmp/snoopy-2.4.6/lib/inih/src'
make[4]: Entering directory `/tmp/snoopy-2.4.6/lib/inih'
make[4]: Nothing to be done for `all-am'.
make[4]: Leaving directory `/tmp/snoopy-2.4.6/lib/inih'
make[3]: Leaving directory `/tmp/snoopy-2.4.6/lib/inih'
make[3]: Entering directory `/tmp/snoopy-2.4.6/lib'
make[3]: Nothing to be done for `all-am'.
make[3]: Leaving directory `/tmp/snoopy-2.4.6/lib'
make[2]: Leaving directory `/tmp/snoopy-2.4.6/lib'
Making all in src
make[2]: Entering directory `/tmp/snoopy-2.4.6/src'
Making all in eventsource
make[3]: Entering directory `/tmp/snoopy-2.4.6/src/eventsource'
CC libsnoopy_eventsource_execve_wrapper_la-execve_wrapper.lo
CCLD libsnoopy_eventsource_execve_wrapper.la
make[3]: Leaving directory `/tmp/snoopy-2.4.6/src/eventsource'
Making all in datasource
make[3]: Entering directory `/tmp/snoopy-2.4.6/src/datasource'
CC noop.lo
CC cmdline.lo
cmdline.c: In function 'snoopy_datasource_cmdline':
cmdline.c:71:79: error: comparison between pointer and zero character constant [-Werror=pointer-compare]
for (cmdLineArgCount=0 ; *(snoopy_inputdatastorage->argv+cmdLineArgCount) != '\0' ; cmdLineArgCount++);
^~
cmdline.c:71:30: note: did you mean to dereference the pointer?
for (cmdLineArgCount=0 ; *(snoopy_inputdatastorage->argv+cmdLineArgCount) != '\0' ; cmdLineArgCount++);
^
cc1: all warnings being treated as errors
make[3]: *** [cmdline.lo] Error 1
make[3]: Leaving directory `/tmp/snoopy-2.4.6/src/datasource'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/tmp/snoopy-2.4.6/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/tmp/snoopy-2.4.6'
make: *** [all] Error 2

 

 

 

おそらくですが、Snoopy LoggerはCentOSなどの一般的なLinuxディストリビューションには対応していますが、AmazonLinux2は対応していないのではないかと推測しています。

※調べる時間がその時は無かった…。

構築期限も差し迫っていたことから、AmazonLinux2でSnoopy Loggerを使うことはあきらめ、Linux標準のauditdを利用することに。

 

auditとは

Linux標準のセキュリティに関する情報を追跡するものらしいです。

今回やりたかったコマンドの実行履歴の取得もこのauditで実施できることから、今回はauditを利用することに。

設定自体は簡単で、AmazonLinux2ではデフォルトでパッケージが導入され、サービスが起動していることから、設定のみで利用可能でした。

 

 auditでコマンド履歴をaudit.logに記録するコマンド

 

auditctl -a exit,always -S execve

 

上記コマンドを実行すると、audit.log(AmazonLinux2では/var/log/audit/audit.log)にコマンドの履歴が記録されます。

可読性は…正直よくありません。1回のコマンド実行で数行のログが出力され、見づらいったらありゃしない。

まぁでも監査用のログなので、可読性は今回は捨てることに。

 

ただ、コマンドで実行した場合、当然ながらrebootなどでサーバが停止したりすれば再度実行が必要。

監査ログということもあり、サーバ起動時からログが取れないのは致命的なので、サーバ再起動等があってもコマンド履歴が取得できるよう、以下の通りauditのrulesに追記。

 

/etc/audit/rules.d/audit.rules 

-a exit,always -S execve

 

 これでauditを再起動すればauditctlコマンドを実行しなくてもコマンド履歴をログに取得できるようになりました。

 とりあえず、監査ログ取得ということであれば上記で対応は可能です。ただ、実際にセキュリティ事故等でコマンドを追うとなると正直読みづらく大変だと思うので、何かしら考えないといけないなぁと思っているところです。

 

 

 

 

まだブログの書き方に慣れておらず、ほかのブログのようにはきれいに書けない。。。

pre記法?とかを学ばないとダメですね。