2011年12月28日水曜日

S3オリジンのCloudFrontでインデックスドキュメントやエラードキュメントを利用できるようにする

スズキです。

CloudFrontには"Default Root Object"という設定項目があり
"http://cloudfront.suz-lab.com/"などでアクセスすると、
上記項目で指定したファイル(ページ)が表示されるようになります。

しかし、"http://cloudfront.suz-lab.com/sub/"などの
サブディレクトリに対するアクセスには対応してません。

また、ステータスコード404などに対するエラードキュメントに関しても、
独自のエラーページを表示させることはできません。

CloudFrontのオリジンをS3にしている場合(S3オリジン)は、
まさに上記の制限が、そのままきいてしまいます。

ちなみにカスタムオリジンの場合はオリジン次第なので、オリジンサーバが
インデックスドキュメントやエラードキュメントを指定できるようにしていれば、
独自のエラードキュメントやアブディレクトリに対するインデックスドキュメントも
可能となります。

しかし、やはりコンテンツは、高い可用性と耐久性を誇るS3に置いておきたいところです。

そもそも、S3には"Web Site Hosting"と呼ばれる機能があり、その機能を有効にすると
サブディレクトリを含めたインデックスドキュメントとエラードキュメントを
独自のファイルに指定することができます。ただし、"Web Site Hosting"用のURLから
アクセスしてはじめて上記の機能を利用することができます。

ここでまた、CloudFrontに戻ります。

CloudFrontを設定するときに、S3オリジンでバケットを指定するのではなく、
カスタムオリジンで上記の"Web Site Hosting"のURLを指定することも、実はできます。

カスタムオリジンにすれば"Web Site Hosting"機能の結果がキャッシュされるため、
サブディレクトリを含めたインデックスドキュメントや独自のエラードキュメントも、
実質、利用できていることになります。

キャッシュ期間には注意です!
--------
http://www.suz-lab.com

2011年12月27日火曜日

VPC上のELBに対するサブネットのCIDRブロックについて

スズキです。

VPC上のELBはサブネットに所属しますが、そもそもELBはスケールするので、
サブネットのIPアドレスレンジはある程度確保しておかなければいけないはずです。

じゃあ、いくつ確保しておけばいいのか?という話ですが、
下記に記載されていました。
How Do I Use Elastic Load Balancing in Amazon VPC?

つまり、次の引用のとおりです。
In order to ensure that your load balancer can scale properly,
the subnet that you attach the load balancer to should be at least a /25 CIDR block
and should have enough free IP addresses to scale.

ELBが適切にスケールできるように、ELBが所属するサブネットのCIDRブロックは
少なくとも"/25"にし、自由に利用できるIPアドレスを確保すべきです。

例えば、下記のようにサブネットを割り振る感じになると思います。
サブネット: 192.168.1.0/25
ネットマスク: 255.255.255.128
ネットワーク: 192.168.1.0
ホストのレンジ: 192.168.1.1 - 192.168.1.126
ブロードキャスト: 192.168.1.127

ちなみにVPCの場合、
192.168.1.1 192.168.1.2 192.168.1.3
の先頭3つのIPアドレスが予約されているので、実際にEC2に割り振れるIPアドレスは
192.168.1.4 - 192.168.1.126
となります。

とりあえずELBのサブネットは"/25"ってことですね。
--------
http://www.suz-lab.com

2011年12月26日月曜日

NagiosのCloudWatchプラグイン(PHP版)

スズキです。

以前、@j3tm0t0さんが公開してくれたNagiosのプラグイン、check_cloudwatch
ほぼ同様のものをCloudWatchとの通信はPHPを使ったもので作ってみました。
(元祖check_cloudwatchはコマンドラインツールを利用しています)

下記のように利用できます。

# ./check_cloudwatch \
> -c 20 \
> -w 10 \
> -f credential.yml \
> -r ap-northeast-1 \
> -n AWS/EC2 \
> -m CPUUtilization \
> -s Average \
> -u Percent \
> -d InstanceId \
> -v i-xxxxxxxx \
CloudWatch CRITICAL - AWS/EC2 CPUUtilization Average InstanceId i-xxxxxxxx: 25.092 Percent;| data=25.092;10;20;0;

コードは下記のようになっています。(エラー処理が甘々ですが...)

require_once("/opt/aws/php/latest/sdk.class.php");

// define status
$ok       = array("code" => 0, "name" => "OK");
$warning  = array("code" => 1, "name" => "WARNING");
$critical = array("code" => 2, "name" => "CRITICAL");
$unknown  = array("code" => 3, "name" => "UNKNOWN");

// set option
$option = getopt("c:w:f:r:n:m:s:u:d:v:");
$critical_size = $option["c"];
$warning_size  = $option["w"];
$credential    = yaml_parse_file($option["f"]);
$region        = $option["r"];
$namespace     = $option["n"];
$metrics       = $option["m"];
$statistics    = $option["s"];
$unit          = $option["u"];
$name          = $option["d"];
$value         = $option["v"];

// init cw
$cw = new AmazonCloudWatch($credential["accessKey"], $credential["secretKey"]);
$cw->set_region($region);
date_default_timezone_set("Asia/Tokyo");

// get metric statistics
$response = $cw->get_metric_statistics(
    $namespace,
    $metrics,
    "-10 minutes",
    "now",
    300,
    $statistics,
    $unit,
    array(
        "Dimensions" => array(
            array("Name" => $name, "Value" => $value)
        )
    )
);
$data = (float)$response->body->GetMetricStatisticsResult->Datapoints->member->$statistics->to_string();

// check status
if($data > $critical_size) {
    $status = $critical["code"];
} elseif($data > $warning_size) {
    $status = $warning["code"];
} elseif($data > 0) {
    $status = $ok["code"];
} else {
    $status = $unknown["code"];
}

// output status
$output = " - ${namespace} ${metrics} ${statistics} ${name} ${value}: ${data} ${unit};| data=${data};${warning_size};${critical_size};0;";
switch($status) {
    case $ok["code"]:
        print("CloudWatch " . $ok["name"]       . $output);
        exit($ok["code"]);
    case $warning["code"]:
        print("CloudWatch " . $warning["name"]  . $output);
        exit($warning["code"]);
    case $critical["code"]:
        print("CloudWatch " . $critical["name"] . $output);
        exit($critical["code"]);
    case $unknown["code"]:
        print("CloudWatch " . $unknown["name"]  . $output);
        exit($unknown["code"]);
}
print("CloudWatch " . $unknown["name"] . $output);
exit($unknown["code"]);

AccessKey、SecretKeyは下記のファイルにまとめています。

accessKey: "XXXXXXXXXXXXXXXXXXXX"
secretKey: "ssssssssssssssssssssssssssssssssssssssss"

もう少しブラッシュアップしたら、また、ちゃんと紹介しようと思います。
--------
http://www.suz-lab.com

2011年12月20日火曜日

PostfixからSESにリレー(stunnel編)

スズキです。

と言っても、下記のAWSドキュメント通りですが...

とりあえず、SESのSMPTポート(465)をたたいてみると、
下記のように何も反応が返って来ません。
# telnet email-smtp.us-east-1.amazonaws.com 465
Trying 107.22.229.233...
Connected to email-smtp.us-east-1.amazonaws.com.
Escape character is '^]'.

これは、SESへの(SMTP)接続はTLSでの暗号化を必要とするので、
当然、直接のtelnetでは接続できなくなります。

ということで、下記のようにstunnelをインストールして、
SESに対するTLSの処理はstunnelでおこない、stunnnelにはTLS無しで
透過的にSESに接続できるようにしてみました。
# yum -y install stunnel

stunnelの設定ファイルは下記のとおりです。
# cat /etc/stunnel/stunnel.conf
[smtp-tls-wrapper]
accept  = 2525
client  = yes
connect = email-smtp.us-east-1.amazonaws.com:465

stunnelの起動は次のとおりですが、起動スクリプトも、
どこかで用意しておきたいところです。
# /usr/bin/stunnel

そして、stunnelに対して接続すると、下記のように今度は無事、
SMTPのレスポンスが返ってくることがわかります。
# telnet localhost 2525
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 email-smtp.amazonaws.com ESMTP SimpleEmailService-194655181

次は実際にPostfixからSESにリレーしてみます。
--------
http://www.suz-lab.com

2011年12月19日月曜日

そろそろCloudFormation(VpcCloudFormation編)

スズキです。

下記で簡単な(EC2一つ立ち上げるだけの)CloudFormationを試しましたが、
そろそろCloudFormation(HelloCloudFormation編)
今回は、これをVPC上で立ち上げてみました。

テンプレートは下記のようになります。

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "Create an Amazon EC2 instance running the SUZ-LAB CentOS AMI.",

  "Parameters" : {
    "KeyName" : {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance",
      "Type"        : "String"
    }
  },

  "Mappings" : {
    "RegionMap" : {
      "ap-northeast-1" : { "AMI" : "ami-de9126df" }
    }
  },

  "Resources" : {
    "Ec2Instance" : {
      "Type"       : "AWS::EC2::Instance",
      "Properties" : {
        "KeyName"          : { "Ref" : "KeyName" },
        "ImageId"          : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]},
        "InstanceType"     : "m1.small",
        "SubnetId"         : "subnet-9bd939f2",
        "PrivateIpAddress" : "10.0.0.100"
      }
    }
  },

  "Outputs" : {
    "InstanceId" : {
      "Description" : "InstanceId of the newly created EC2 instance",
      "Value"       : { "Ref" : "Ec2Instance" }
    }
  }
}

前回同様、下記に示す上記のテンプレートURLを使って
AWS Management Consoleから起動すればOKです。
https://s3-ap-northeast-1.amazonaws.com/www.suz-lab.com/formation/VpcCloudFormation.template


ただし、サブネットやルーティング、Network ACLsなどの設定は、まだ、
できないようなので、VPC(サブネット/ルーティング/Network ACLs)の設定は
事前にしておく必要があるようです。

また、最近VPC上で利用できるようになったELBですが、こちらも、まだ、
対応していないようです。ですので、お金はかかりますがVPC上のELBも、
予め作成しておく必要があるようです。
(そしてインスタンスのぶら下げるのは手動になってしまうと思います)

次は何編にしよう?
--------
http://www.suz-lab.com

そろそろCloudFormation(HelloCloudFormation編)

スズキです。

CloudFormationの用途に、一時的に利用する開発環境や検証環境、バックアップ環境の
起動/停止を一気にまとめて行うというものがあると思います。
(というか、それしか思い浮かばないのですが...)

ということで、そろそろ、そのような要件が出てきたので、
ちゃんと一から試すことにしました。(つまりHelloCloudFormationです)

下記は一番簡単な、AMIからEC2を起動するHelloCloudFormationテンプレートです。
(シンプルなテンプレートなので意味合いは直感的にわかると思います)

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "Create an Amazon EC2 instance running the SUZ-LAB CentOS AMI.",

  "Parameters" : {
    "KeyName" : {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance",
      "Type" : "String"
    }
  },

  "Mappings" : {
    "RegionMap" : {
      "ap-northeast-1" : { "AMI" : "ami-de9126df" }
    }
  },

  "Resources" : {
    "Ec2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "KeyName" : { "Ref" : "KeyName" },
        "ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}
      }
    }
  },

  "Outputs" : {
    "InstanceId" : {
      "Description" : "InstanceId of the newly created EC2 instance",
      "Value" : { "Ref" : "Ec2Instance" }
    }
  }
}

ということで、上記のテンプレートを実際にAWS Management Consoleから利用してみます。

まずは、上記のテンプレートを下記のようにS3に配置します。
https://s3-ap-northeast-1.amazonaws.com/www.suz-lab.com/formation/HelloCloudFormation.template

次に、下記のように"Provide a Template URL"を選択し、テンプレートのURLを入力します。


そして、パラメータを入力します。ここで入力するパラメータは上記のテンプレートで
"Parameters"で定義されたもので、任意に指定することができます。


最後に、情報の確認して問題なければ、構築を開始します。


起動後、"Outputs"タグを確認すると、下記のようにテンプレートの"Outputs"で定義した情報が
出力されていることがわかります。


次は、VPC!
--------
http://www.suz-lab.com

S3にブラウザから直接アップロードするフォーム(HTML)をPHPで生成

スズキです。

S3にブラウザから直接アップロードする方法を下記で紹介しましたが、
JAWS-UG宮崎第3回勉強会LT資料(Browser Uploads to S3 using HTML POST Forms)
そのときは、静的なHTMLフォームを前提として、Base64のpolicyやsignatureは
別プログラム(Ruby)で作成していました。

今回は、そのHTMLフォームをPHPで生成し、有効期限やアップロードファイル名、
リダイレクト先などを動的に変更できるようにしてみました。

コードは下記のとおりです。

<?php
$id         = "00000000";
$expiration = gmdate("Y-m-d\TH:i:s\Z",strtotime("1 minute"));
$redirect   = "http://www.suz-lab.com/index.html?id=$id";
$policy = <<<EOS
{
    "expiration": "$expiration",
    "conditions": [
        {"bucket": "www.suz-lab.com"},
        ["starts-with", "\$key", ""],
        {"acl": "private"},
        {"success_action_redirect": "$redirect"},
        ["starts-with", "\$Content-Type", ""],
        ["content-length-range", 0, 1048576]
    ]
}
EOS;
$signature = hash_hmac("sha1", base64_encode($policy), "SECRET_KEY", true);
?>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  </head>
  <body>
    <form action="http://www.suz-lab.com.s3.amazonaws.com/"
          method="post" enctype="multipart/form-data">
      <input type="hidden" name="key"
             value="<?php print("${id}.txt"); ?>"/>
      <input type="hidden" name="AWSAccessKeyId"
             value="ACCESS_KEY"/>
      <input type="hidden" name="acl"
             value="private"/>
      <input type="hidden" name="success_action_redirect"
             value="<?php print($redirect); ?>"/>
      <input type="hidden" name="policy"
             value="<?php print(base64_encode($policy)); ?>"/>
      <input type="hidden" name="signature"
             value="<?php print(base64_encode($signature)); ?>"/>
      <input type="hidden" name="Content-Type"
             value="text/plain"/>
      <input type="file"   name="file"/>
      <input type="submit" name="button" value="Upload"/>
    </form>
  </body>
</html>

上記は有効期限をHTMLフォームが作成されてから1分以内とし、アップロードファイル名や
リダイレクトURLにid(ユーザーIDなど)が反映されるようにしています。

S3へのアップロードが成功すると、下記にリダイレクトされ、リダイレクトURLに
事前につけておいたパラメータ(id=00000000)も引き継がれていることがわかります。

http://www.suz-lab.com/index.html?id=00000000&bucket=www.suz-lab.com&key=00000000.txt&etag=%22...%22

さらに、HTMLフォームが生成された後、1分後にアップロードすると、
次のように、ちゃんとエラーになりました。


これで、いつでも使えます!
--------
http://www.suz-lab.com/

2011年12月17日土曜日

JAWS-UG宮崎第3回勉強会LT資料(Browser Uploads to S3 using HTML POST Forms)

スズキです。

第3回 AWS User Group - Japan【宮崎】 勉強会
でLTします。

LTの内容は下記の資料の通り、
HTMLフォームからS3に直接ファイルをアップロードする方法についてです。


それでは、宮崎の皆さん、よろしくお願いします。
--------
http://www.suz-lab.com

2011年12月9日金曜日

Varnishで"www.suz-lab.com"を"suz-lab.com"にリダイレクト

スズキです。

以前下記で、Varnishによる"suz-lab.com"を"www.suz-lab.com"に
リダイレクトする方法を紹介しましたが、
Varnishでリダイレクト専用Webサーバの構築
今回は、その逆の"www.suz-lab.com"を"suz-lab.com"にリダイレクトする方法です。

上記の設定は、設定ファイル"default.vcl"の"vcl_error"で行い、
具体的には下記のようになります。

sub vcl_error {
    if(req.http.host == "www.suz-lab.com") {
      set obj.http.Location = "http://" regsub(req.http.host, "www\.(.*)", "\1") req.url;
      set obj.status = 301;
    }
    return(deliver);
}

近頃、S3への小細工は、全部Varnishでやってます...
--------
http://www.suz-lab.com

2011年12月7日水曜日

オレゴンリージョン(us-west-2)のAKI(pv-grub-hd0/00)

スズキです。

下記AMIの作成にて、
SUZ-LAB謹製 CentOS AMI (6.0.5 64bit us-west-2)
"User Provided Kernel"で使うAKI(pv-grub-hd0/00)を調査したのでまとめておきます。

▼aki-c2e26ff2
ec2-public-images-us-west-2/pv-grub-hd0_1.02-i386.gz.manifest.xml

▼aki-c0e26ff0
ec2-public-images-us-west-2/pv-grub-hd00_1.02-i386.gz.manifest.xml

▼aki-98e26fa8
ec2-public-images-us-west-2/pv-grub-hd0_1.02-x86_64.gz.manifest.xml

▼aki-94e26fa4
ec2-public-images-us-west-2/pv-grub-hd00_1.02-x86_64.gz.manifest.xml

他のリージョンに関しては、下記でまとめてあります。
"User Provided Kernel"で使う"pv-grub-hd0/00"が1.02になってた

久しぶりにAMIのリージョン移行した...
--------
http://www.suz-lab.com

SUZ-LAB謹製 CentOS AMI (6.0.5 64bit us-west-2)

スズキです。

オレゴンリージョン(us-west-2)にリリースしました。

AMIを「suz」で検索してもらえれば、
811118151095/suz-lab_ebs_centos-core-i386-6.0.5
として見つかるはずです。

AMIの内容は、下記と同様となります。
SUZ-LAB謹製 CentOS AMI (6.0.5 64bit ap-northeast-1)

ただし利用しているAKIは下記となります。
▼aki-98e26fa8
ec2-public-images-us-west-2/pv-grub-hd0_1.02-x86_64.gz.manifest.xml
Enjoy!
--------
http://www.suz-lab.com

SUZ-LAB謹製 CentOS AMI (6.0.5 64bit ap-northeast-1)

スズキです。

下記をアップデートしました。
SUZ-LAB謹製 CentOS AMI (6.0.2 64bit ap-northeast-1)
AMIを「suz」で検索してもらえれば、
811118151095/suz-lab_ebs_centos-core-x86_64-6.0.5
として見つかるはずです。

アップデート内容は下記の32bitのものと同じになります。
SUZ-LAB謹製 CentOS AMI (6.0.3 32bit ap-northeast-1)

SUZ-LAB謹製 CentOS AMI (6.0.4 32bit ap-northeast-1)

SUZ-LAB謹製 CentOS AMI (6.0.5 32bit ap-northeast-1)

Enjoy!
--------
http://www.suz-lab.com

2011年12月6日火曜日

SUZ-LAB謹製 CentOS AMI (6.0.5 32bit ap-northeast-1)

スズキです。

下記をアップデートしました。
SUZ-LAB謹製 CentOS AMI (6.0.4 32bit ap-northeast-1)
AMIを「suz」で検索してもらえれば、
811118151095/suz-lab_ebs_centos-core-i386-6.0.5
として見つかるはずです。

アップデート内容は下記となります。

パッケージのアップデート
# yum -y update

よく要求されるセキュリティ要件を反映

まず、"/etc/pam.d/password-auth"を下記のように修正しています。

▼6回以上の失敗アクセスがあった場合、システム管理者がリセットするまで無効とする。
auth        required      pam_tally2.so deny=6

▼過去4回のパスワードを回転使用できないようにする。
password    sufficient    pam_unix.so try_first_pass use_authtok nullok sha512 shadow remember=4

最終的に"/etc/pam.d/password-auth"は下記のようになっています。
auth        required      pam_env.so
auth        required      pam_tally2.so deny=6
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

account     required      pam_unix.so

password    requisite     pam_cracklib.so try_first_pass retry=3 type=
password    sufficient    pam_unix.so try_first_pass use_authtok nullok sha512 shadow remember=4
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

次に、監査ログ(/var/log/audit/audit.log)へのアクセス情報も記録するように、
"/etc/audit/audit.rules"に下記を追加しておきます。
-w /var/log/audit/audit.log

"audit.log"にアクセス(tail)すると、下記のように記録されます。
type=SYSCALL msg=audit(1323176229.195:36): arch=40000003 syscall=5 success=yes exit=3 a0=bf9b27d8 a1=8000 a2=0 a3=bf9b1050 items=1 ppid=875 pid=902 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="tail" exe="/usr/bin/tail" key=(null)
type=CWD msg=audit(1323176229.195:36):  cwd="/var/log/audit"
type=PATH msg=audit(1323176229.195:36): item=0 name="/var/log/audit/audit.log" inode=7132 dev=ca:01 mode=0100600 ouid=0 ogid=0 rdev=00:00

Enjoy!
--------
http://www.suz-lab.com

2011年12月5日月曜日

#サンタクラウド のデータ

スズキです。

#サンタクラウドのページですが、下記のJSONデータをJavaScriptで読み込んで
表示しています。
http://www.suz-lab.com/santacloud/tweet.json

JSONの内容は下記の通りです。
[
    {
        "tweet_id":"0000000000000000",
        "tweet_text":"VPC上でRDSが利用できるようになりますように!",
        "tweet_user_name":"suz_lab",
        "tweet_user_image":"ツイートしたユーザーの画像のURL",
        "retweet_users":[
            {
                "retweet_user_name":"kaz_goto",
                "retweet_user_image":"リツイートしたユーザーの画像のURL"
            },
            ...
        ]
    },
    ...
]

@tottokugさん、面白い結果、期待してます。!
--------
http://www.suz-lab.com

2011年12月1日木曜日

S3のファイルサイズをチェックするNagiosプラグイン(PHP)

スズキです。

下記でS3(バケット)のファイルサイズが取得できるようになったので
S3で利用されているバケットのファイルサイズの取得
S3で利用されているファイルサイズ(全バケット)の取得
今回はS3のファイルサイズをチェックするNagiosプラグインを作ってみました。

まずは下記のようなAWSのAPIを利用するためのキーを保存したファイルを用意します。

▼ credential.yml
accessKey: "AAAAAAAAAAAAAAAAAAAA"
secretKey: "ssssssssssssssssssssssssssssssssssssssss"

次に下記のスクリプト(PHP)を用意します。

▼ check_s3size
require_once("/opt/aws/php/latest/sdk.class.php");

// define status
$ok       = array("code" => 0, "name" => "OK");
$warning  = array("code" => 1, "name" => "WARNING");
$critical = array("code" => 2, "name" => "CRITICAL");
$unknown  = array("code" => 3, "name" => "UNKNOWN");

// set option
$option = getopt("c:w:f:b:");
$critical_size = $option["c"];
$warning_size  = $option["w"];
$credential    = yaml_parse_file($option["f"]);
if(isset($option["b"])) {
    $bucket = $option["b"];
}

// init s3
$s3 = new AmazonS3($credential["accessKey"], $credential["secretKey"]);
$s3->use_ssl = false;

// get s3 size
if(isset($bucket)) {
    $total_filesize = $s3->get_bucket_filesize($bucket, false);
} else {
    $bucket_list = $s3->get_bucket_list();
    $total_filesize = 0;
    foreach($bucket_list as $bucket) {
        $total_filesize += $s3->get_bucket_filesize($bucket, false);
    }
}

// check status
if($total_filesize > $critical_size) {
    $status = $critical["code"];
} elseif($total_filesize > $warning_size) {
    $status = $warning["code"];
} elseif($total_filesize > 0) {
    $status = $ok["code"];
} else {
    $status = $unknown["code"];
}

// output status
switch($status) {
    case $ok["code"]:
        print($ok["name"]       . " - s3 size: " . $total_filesize . "|size=" . $total_filesize . ";");
        exit($ok["code"]);
    case $warning["code"]:
        print($warning["name"]  . " - s3 size: " . $total_filesize . "|size=" . $total_filesize . ";");
        exit($warning["code"]);
    case $critical["code"]:
        print($critical["name"] . " - s3 size: " . $total_filesize . "|size=" . $total_filesize . ";");
        exit($critical["code"]);
    case $unknown["code"]:
        print($unknown["name"]  . " - s3 size: " . $total_filesize . "|size=" . $total_filesize . ";");
        exit($unknown["code"]);
}
print($unknown["name"]);
exit($unknown["code"]);

実行オプションは下記の通りです。
-c: CRITICALの閾値
-w: WARNINGの閾値
-f: キーファイル
-b: バケット(指定しない場合はすべてのバケットが対象)

オプションを指定して実行すると下記のような結果になります。

# ./check_s3_size -c 1000 -w 100 -f credential.yml -b cdn.cloudpack.jp
CRITICAL - s3 size: 238725|size=238725;

バケット指定(-b)をしないで実行すると、
下記のようにすべてのバケットのファイルサイズを合計したものが対象となります。

./check_s3_size -c 1000 -w 100 -f credential.yml
CRITICAL - s3 size: 31145892|size=31145892;

次はこのプラグインを実際にNagiosで利用してみます。
--------
http://www.suz-lab.com

S3で利用されているファイルサイズ(全バケット)の取得

スズキです。

下記は指定した単一バケットに対するファイルサイズの取得でしたが、
S3で利用されているバケットのファイルサイズの取得
今回はすべてのバケットのファイルサイズの合計を出力するものです。

require_once("/opt/aws/php/latest/sdk.class.php");
$s3 = new AmazonS3(
    "AAAAAAAAAAAAAAAAAAAA",
    "ssssssssssssssssssssssssssssssssssssssss"
);
$s3->use_ssl = false;
$bucket_list = $s3->get_bucket_list();
$total_filesize = 0;
foreach($bucket_list as $bucket) {
  $total_filesize += $s3->get_bucket_filesize($bucket, false);
}
var_dump($total_filesize);

次はこれをNagiosプラグイン化します。
--------
http://www.suz-lab.com

S3で利用されているバケットのファイルサイズの取得

スズキです。

下記スクリプト(PHP)で可能です。

require_once("/opt/aws/php/latest/sdk.class.php");
$s3 = new AmazonS3(
    "AAAAAAAAAAAAAAAAAAAA",
    "ssssssssssssssssssssssssssssssssssssssss"
);
$s3->use_ssl = false;
$response = $s3->get_bucket_filesize("cdn.cloudpack.jp", false);
print($response);

結果は次のようになります。

# ./get-bucket-filesize 
238725

"get_bucket_filesize"の第二引数を"true"にすると、

...
$response = $s3->get_bucket_filesize("cdn.cloudpack.jp", true);
...

単位付きの読みやすい結果になります。

# ./get-bucket-filesize 
233.13 kB

次は、全バケットの容量チェックできるようにして、Nagiosのプラグインにして...
--------
http://www.suz-lab.com

"AWS SDK for PHP"のS3関係のメソッドで証明書関係のエラー対策

スズキです。

とりあえず、下記で紹介はしたのですが、
"AWS SDK for PHP"でS3にファイルアップロードしようとしたら証明書関係のエラー
メソッドによっては対策方法の、次のオプションが指定できないものもあるので、
"curlopts" => array(CURLOPT_SSL_VERIFYPEER => false)
そのようなメソッドを利用する場合の対策方法です。

まず、下記のようなスクリプトを実行すると、

require_once("/opt/aws/php/latest/sdk.class.php");
$s3 = new AmazonS3(
    "AAAAAAAAAAAAAAAAAAAA",
    "ssssssssssssssssssssssssssssssssssssssss"
);
$response = $s3->get_bucket_filesize("cdn.cloudpack.jp", true);
print($response);

次のようなエラーになってしまいます。
("cdn.cloudpack.jp.s3.amazonaws.com"は"*.s3.amazonaws.com"の証明書でもエラー!)

PHP Fatal error:  Uncaught exception 'RequestCore_Exception' with message 'cURL resource: Resource id #9; cURL error: SSL: certificate subject name '*.s3.amazonaws.com' does not match target host name 'cdn.cloudpack.jp.s3.amazonaws.com' (51)' in /opt/aws/php/1.4.7/lib/requestcore/requestcore.class.php:824
Stack trace:
#0 /opt/aws/php/1.4.7/services/s3.class.php(728): RequestCore->send_request()
#1 /opt/aws/php/1.4.7/services/s3.class.php(1397): AmazonS3->authenticate('cdn.cloudpack.j...', Array)
#2 /opt/aws/php/1.4.7/services/s3.class.php(1950): AmazonS3->list_objects('cdn.cloudpack.j...')
#3 /opt/suzuki/bin/get-bucket-filesize(9): AmazonS3->get_bucket_filesize('cdn.cloudpack.j...', true)
#4 {main}
  thrown in /opt/aws/php/1.4.7/lib/requestcore/requestcore.class.php on line 824

下記対策が使えないメソッドは、そもそもSSLの通信をしないようにして対策できます。
"curlopts" => array(CURLOPT_SSL_VERIFYPEER => false)
SSLの通信をしない方法は次のように"$s3->use_ssl = false;"で実現できます。

require_once("/opt/aws/php/latest/sdk.class.php");
$s3 = new AmazonS3(
    "AAAAAAAAAAAAAAAAAAAA",
    "ssssssssssssssssssssssssssssssssssssssss"
);
$s3->use_ssl = false;
$response = $s3->get_bucket_filesize("cdn.cloudpack.jp", true);
print($response);

HTTPSの通信にはならないけど...
--------
http://www.suz-lab.com