Amazon CloudFront 上 Protected Content 的 URL Sign...

Amazon CloudFront 也可以設定要簽名才能抓檔案,只是 URL Sign 設計的觀念跟 Amazon S3 完全不一樣,這不一致的調調很... 詭異...

大致上有這些差異:

  • Amazon S3 用的是 HMAC-SHA1 的機制簽名 (shared secret,也就是 Amazon S3 與你都有同一把 key),而 Amazon CloudFront 則是用 RSA key 簽名 (public key,也就是 Amazon CloudFront 存放 public key,你自己存放 private key)。
  • 也因為是使用 RSA key,有人會誤解跟 Amazon EC2 用的 RSA key 相同。但實際上需要在 Security Credentials 頁裡設,有專門對 Amazon CloudFront 用的 RSA key 的段落。
  • 自己對 Base64 編碼再處理,避開使用 += 以及 /。但不是有標準可以用嗎,為什麼要自己發明呢...
  • 引入 Policy 的彈性機制,不僅可以對時間控制,也可以對 IP address 控制,但 Policy 這是帶在 URL 裡傳進去的... 你可以看到我的程式碼內產生出 $json_str 後簽完名帶到 URL 內了。

官方的 CloudFront Signed URLs in PHP 這篇的範例程式碼其實很清楚了,要直接拿去用其實也沒麼問題。我自己整理後是這樣:

<?php

$key_pair_id = 'APKA...';
$pem_file = '';
$resource = 'http://test2-cdn.gslin.org/test.txt';

$expires = time() + 3600;

$json_str = json_encode(
    array(
        'Statement' => array(
            array(
                'Resource' => $resource,
                'Condition' => array(
                    'DateLessThan' => array(
                        'AWS:EpochTime' => $expires
                    )
                )
            )
        )
    ),
    JSON_UNESCAPED_SLASHES
);

$buf = file_get_contents($pem_file);
$key = openssl_get_privatekey($buf);

openssl_sign($json_str, $signed_policy, $key, OPENSSL_ALGO_SHA1);

openssl_free_key($key);

$signature = str_replace(
    array('+', '=', '/'),
    array('-', '_', '~'),
    base64_encode($signed_policy)
);

echo "${resource}?",
    "Expires=${expires}&",
    "Signature=${signature}&",
    "Key-Pair-Id=${key_pair_id}\n";

反正你搞不太懂 Amazon 為什麼要這樣設計的... =_=

Amazon S3 上 Protected Content 的 URL Sign...

Amazon S3 可以在上傳時設定為 non-public,這種檔案如果要讓使用者讀取,就必須透過 URL 簽名的方式...

官方的文件是「Authenticating REST Requests」這篇,不過官方文件把所有細節都寫上去,如果第一次接觸的人反而不知道要怎麼辦...

Thomas Riboulet 給了一個 Quickstart 的範例:「Signing Amazon S3 URLs」,裡面雖然是 Ruby code,不過 code 的邏輯很簡單...

以 test.gslin.org 為例,想要產生出從現在開始 3600 秒內有效的 url 可以這樣寫,用過一次後再回去看官方文件,就會發現其實就是官方文件的「REST Authentication Example 3: Query String Authentication Example」這段,如果以 PHP 寫會長這樣:

<?php

$access_key = "";
$secret_key = "";

$timestamp = time() + 3600;
$data = "GET\n\n\n${timestamp}\n/test.gslin.org/test.txt";

$sign = urlencode(
    base64_encode(
        hash_hmac('sha1', $data, $secret_key, true)
    )
);

echo "http://test.gslin.org.s3.amazonaws.com/test.txt?" .
    "AWSAccessKeyId=${access_key}&" .
    "Expires=${timestamp}&" .
    "Signature=${sign}\n";

接下來來研究 CloudFront 的部份...

Amazon CloudFront 支援 Wildcard 了...

Amazon CloudFront 在 CNAME 的地方可以填 *.example.com 表示這個 distribution 要吃所有 domain:「CNAME Wildcard Support for Amazon CloudFront」。

這用在 asset 類的服務很好用,可以設定 *.asset.example.com,然後就可以用 {1,2,3,4}.asset.example.com 打散掉。以往則是要手動設多個 domain,沒辦法隨便調整...

Amazon 官方推出 Python 版本的 AWS CLI 工具...

幾天前 Amazon 官方推出 Python 版本的 AWS CLI 工具:「New AWS Command Line Interface (CLI)」,官方網站則是在「AWS Command Line Interface」,程式碼則是公開在 GitHub 上:「aws/aws-cli

FreeBSD ports 裡面有,在 devel/awscli 這裡。

記得一開始作者 Mitch Garnaat 先發展 boto,然後被 Amazon 挖走,沈寂了好幾年,開發出這東西...

常用的服務都可以透過這隻程式操作...

Amazon RDS 可以直接產生 Read Replica Replication 了...

以往要在 Amazon RDS 產生 Read Replica Replication 需要複雜的 snapshot 處理,但現在 AWS 直接提供這個功能了,而且可以同時生很多台:「New Read Replica Capabilities for Amazon RDS」。

這有多重要呢?以前因應流量瞬間爆增時的方式是增加 web server,並且利用 cache (可能是 memcached) 降低對後端的 query 數量。但因為引入 cache,平常就得處理 cache invalidate 的問題。

而這個方式平常只要處理讀寫分離就可以了。當量爆增時除了 web server 增加,直接增加後端的 RDS server (Read Replica Replication),甚至可以分層:

以目前的步調來看,之後有可能會推出 Master-Master 的 HA 架構?

Update:照 comment 提到的,Multi-AZ 本身就是 HA 架構了...

Amazon S3 調降 request 本身的收費...

Amazon S3 的 request 費用大幅調降:「Announcing New Lower Request Pricing for Amazon S3」。

PUT/LIST/COPY/POST 的部份調降 50%,本來每千個是 USD$0.01 調降到 USD$0.005。而 GET 調降 60%,本來 USD$0.01 調降到 USD$0.004。

本來 CloudFront 可以降低 request 費用 (美國區每千個 GET 是 USD$0.0075),現在相比反而變貴... 還是過陣子 CloudFront 有機會再調降 request 費用?

AWS 又降價...

剛剛才開個小會,出來就被 jnlin 提醒,AWS 宣佈降價:「AWS Announces New Data Transfer Pricing」。

自 7/1 開始,從 Internet 流入 AWS 的費用全免,另外美國與歐洲區的頻寬費再降。美國本來是 10TB 以下 USD$0.15/GB,到 50TB 以下的是 USD$0.11/GB,現在改成 10TB 以下都是 USD$0.12/GB,50TB 以下則是 USD$0.09/GB。除了普通的 data transfer 以外,CloudFront 也有對應的調整。

對於自己的機器混搭 AWS 的公司來說,光是 inbound bandwidth 不算錢就可以省下一筆可觀的金額...

Amazon Web Services Console 加強 CloudFront 設定...

之前在 AWS Console 上一直沒辦法設定 AWS CloudFront 的 Custom Origin,必須透過 3rd-party 軟體設定,而現在總算是把這個功能補上去了:「Improved CloudFront Support in the AWS Management Console」。

直接拿 Demo 的圖,最重要的 Custom Origin 功能的畫面:

AWS CloudFront Custom Origin

不過好像還是沒看到 Purge...

AWS 東京第二個 AZ (Availability Zone) 今天啟用...

開張不到一個月的 AWS Japan 今天宣佈啟用第二個 Availability Zone:「Adding a Second AWS Availability Zone in Tokyo」,第一個 AZ 是在 2011/03/02 宣佈啟用:「Amazon Web Services 東京!」。

好快的速度... 是因為全世界對亞洲的需求嗎?