モヒカンメモ

髪色が定期的に変わることに定評のある(比較的)若者Webエンジニアの備忘録

Redash SaaSからRDSにアクセスするために調べたこと、考えたことまとめ

背景

RDB等にあるデータストアへクエリを投げてデータをチラ見したり、取ってきたデータをいい感じにグラフとかで可視化したり出来るRedashという便利ツールがある。ベース部分はOSSで、self hostingすることもできるし有償でSaaSとして使うこともできる

redash.io

とあるAWS RDS上のデータをパパっと可視化したくなったので、Redash SaaSからRDSへつなげるように出来るんだっけ、とか、どんなリスクがあるんだっけ、みたいなことを調べたのでまとめておく

f:id:pinkumohikan:20200823183745p:plain
redash

ざっくり要点

  • RDSのPublicly Accessibleという設定を有効にすれば、インターネット (VPC外) からRDSへアクセスできる
  • DBをinternet publicにすることで不正アクセスの危険は高まるが、既存の仕組みでリスクはある程度抑えられる

インターネット (VPC外) からRDSへアクセスすることはできる

インターネットからRDSへアクセスする場合、踏み台用のホストを用意してそのホスト経由 (SSHポートフォワーディング) でRDSへアクセスする方法が王道だが、Redash SaaSでは踏み台をサポートしてないのでこの方法は使えない

RDSには Publicly Accessible という設定があり、これを有効にするとVPC外からでもRDSへアクセスできるようになる

aws.amazon.com

dev.classmethod.jp

想定されるリスク

データベースをinternet publicにするリスク

インフラ設計においてデータベースはDMZとかprivate networkなどと呼ばれるような、インターネットから直接アクセス出来ない領域に置くのがベストプラクティスとされてきた。なので、セキュリティに関心のある開発者だと「DBをinternet publicにするのって危険じゃん」って思うと思う

不正アクセスによってDB上のデータが漏洩したり書き換えられたりするリスクが考えられるが、次のような対策を行うことでリスクはだいぶ減らせそう

  • 接続元IPアドレスによるフィルタリングを行う
  • 特に機微な情報は、暗号化した上でDBに乗せる
  • Redash等readのみしかしないDBクライアントには、権限を絞ったreadonlyなDBユーザを用意する

SaaS固有のリスク

SaaSからinternet経由でDBへアクセスする場合、次のようなリスクが考えられる

  1. SaaSそのものが攻撃を受ける可能性
    • SaaSに登録した認証情報を使い、SaaSのIPからDBアクセスされうる
  2. SaaSを踏み台として使われる可能性
    • 攻撃者がSaaSを正規に契約することで、SaaSのIPからDBアクセスされうる (IPアドレスベースのフィルタリングを回避される)

SaaS事業者もそのような攻撃を許せば面目丸つぶれなので何らかの対策を講じていると思うがリスクはゼロではない。「こういうリスクが想定されるけど、対策してる?」とか聞いて、対策が甘いなって感じたらSaaSを使わないことを検討したい

もっと対策するなら

分析専用のDBを用意する

アプリケーション用のDBとは別に分析専用のDBを用意し、想定している分析に必要なデータのみをmigrationする仕組みを作り、Redash SaaSからはそれを使うようにする。そうすれば、仮に不正アクセスされても被害範囲を限定できる

Redash SaaSを使わず、Redashを自前運用する

VPC内に自前のRedashを立ててしまえばDBをinternet publicにする必要がなくRedashを使うことが出来る

redash.io

実際、身近なWeb系企業ではこの方法を取っているところも多い。難点としてはRedashは割とカジュアルにハングするので定期的な復旧作業が生じるのと、バージョンアップに追従する更新w運用コストがちょっと掛かること

その他、細かい話

Publicly Accessibleって後から変更できる?ダウンタイムは?

2020年8月現在、AWS RDS for Aurora (MySQL互換) にて検証した限りでは あとから変更可能 で、変更によるダウンタイムは なし だった

2015年4月時点ではインスタンス作成時のみ設定可能だった模様

http://dev.sukimash.com/aws/rds-publicly-accessible-setting-change/

早速 Publicly Accessible の設定をON にすべく、いろいろと調べてみたところ、どうやらこの設定は後から変更することはできないようです。。。

従って、接続できるようにするには、RDS のスナップショットを取り、別のインスタンスを Publicly Accessible ON で起動し、そちらにつなぎ直す、という手順が必要なようだ、、、ちょっとめんどくさいですね。

mysqlコマンドの実行結果から枠線とカラム名を除いて表示する

mysqlコマンドの実行結果から枠線とカラム名を取り除いて表示する方法を調べたので備忘録がてらまとめておく

やりたいこと

ヘルスチェックや定点観測用の即席スクリプトを書くときなど、mysqlコマンドの実行結果をスリムに表示したいことがある

何もオプションを指定せずにmysqlコマンドでクエリを実行すると、下記のように枠線とカラム名がついてくる

$ mysql --host 127.0.0.1 -u root -e 'select "Hello, world" as "greeting"';
+--------------+
| greeting     |
+--------------+
| Hello, world |
+--------------+

ただデータを眺める分にはこれで良いが、別のプログラムに食わせたいときや値だけが欲しいときに枠線やカラム名が邪魔になる

なので、枠線やカラム名を取り除いて表示させたい

実行結果から枠線を消す方法

mysqlコマンドに --silent というオプションがあり、これを使うと枠線をommitして表示することができる

help:

$ mysql --help
...
  -s, --silent        Be more silent. Print results with a tab as separator,
                      each row on new line.
...

before

$ mysql --host 127.0.0.1 -u root -e 'select "Hello, world" as "greeting"';
+--------------+
| greeting     |
+--------------+
| Hello, world |
+--------------+

after

$ mysql --host 127.0.0.1 -u root --silent -e 'select "Hello, world" as "greeting"';
greeting
Hello, world

実行結果からカラム名を消す方法

mysqlコマンドに --skip-column-names というオプションがあり、これを使うとカラム名をommitして実行結果のみを表示することができる

help:

$ mysql --help
...
  -N, --skip-column-names
                      Don't write column names in results.
...

before

$ mysql --host 127.0.0.1 -u root -e 'select "Hello, world" as "greeting"';
+--------------+
| greeting     |
+--------------+
| Hello, world |
+--------------+

after

$ mysql --host 127.0.0.1 -u root --skip-column-names -e 'select "Hello, world" as "greeting"';
+--------------+
| Hello, world |
+--------------+

実行結果から枠線とカラム名を両方消す方法

単純に先の2つのオプションを同時に指定すれば良い

before

$ mysql --host 127.0.0.1 -u root -e 'select "Hello, world" as "greeting"';
+--------------+
| greeting     |
+--------------+
| Hello, world |
+--------------+

after

$ mysql --host 127.0.0.1 -u root --silent --skip-column-names -e 'select "Hello, world" as "greeting"';
Hello, world

余談

mysqlコマンドにパイプで続けてコマンドを書くと、実行結果から枠線は取り除いて渡してくれる

小さなプログラムを組み合わせて大きなプログラムを作るための工夫で、Linux哲学ってやつ

続くコマンドなし

$ mysql --host 127.0.0.1 -u root  -e 'select "Hello, world" as "greeting"'
+--------------+
| greeting     |
+--------------+
| Hello, world |
+--------------+

続くコマンドあり

$ mysql --host 127.0.0.1 -u root  -e 'select "Hello, world" as "greeting"' | cat
greeting
Hello, world

GitHub Activityをグラフで可視化してくれるGitHub Readme StatsでGitHub映えを狙う

こんにちは、可視化大好きお兄さんこと @pinkumohikan です(自称)。

Webエンジニア御用達のソースコード管理ツール "GitHub" でのアクティビティを可視化してくれる GitHub Readme Stats というおもしろツールが、結構映えるグラフを作ってくれていい感じだったのでご紹介します。

f:id:pinkumohikan:20200803022415p:plain

GitHub Readme Stats

github.com

基本的には

https://github-readme-stats.vercel.app/api?username=pinkumohikan

みたいなURLにアクセスすると動的にActivityを集計してグラフ表示してくれます。獲得したスター数や、当年のスター数、作ったPR数、作ったIssue数など。色々カスタマイズも出来るみたい。

自分は下記のようにオプションを設定しており、

https://github-readme-stats.vercel.app/api?username=pinkumohikan&count_private=true&show_icons=true&theme=radical

するとこんなふうなグラフがでます。

https://github-readme-stats.vercel.app/api?username=pinkumohikan&count_private=true&show_icons=true&theme=radical

Special Repositoryに置くのがオススメ

GitHubの自分のアカウント名と同じリポジトリを Special Repository と呼ぶらしいです。例えばアカウント名が pinkumohikan なら pinkumohikan というリポジトリがそれに当たります。

f:id:pinkumohikan:20200804111353p:plain
ひみつだよ!

github.com

そしてなにやら、Special RepositoryのREADMEに書いた文章はプロフィールページにもサマリー表示されるらしい。

github.com

こんな感じ: f:id:pinkumohikan:20200803022125p:plain

GitHub Readme StatsのURLをREADMEに貼っとけば GitHub映えしますね。僕のREADMEにはさっき紹介したGitHub Activityに加えて、良く使う言語のグラフも表示しています。

パパっと真似したいかたは

あんまりオプションとか関心なくてとりあえず真似してみたいかたは、僕のREADMEをコピペしてもらえればそれっぽいものがシュッと出来上がります。

Raw README.md: https://raw.githubusercontent.com/pinkumohikan/pinkumohikan/master/README.md

pinkumohikan のところを自分のGitHubアカウント名にreplace、自分のGitHubアカウント名でリポジトリを作り、そこにREADME.mdとして保存すればパパっと試せます。お試しあれ。

useraddコマンドをAmazon Linux2へインストールする

Linuxユーザを追加するときに使うuseraddコマンド。Amazon Linux2のdockerイメージではデフォルトでは入っていなかったのでインストール方法を調べたたときの備忘録。Amazon Linux2に限らず、Linuxのminimal環境にuseraddコマンドを入れるのに使える方法だと思う。

useraddコマンド

 「useradd」は新規ユーザーを作成し、ユーザーごとの設定を決めるコマンドです。作成時のデフォルト値をあらかじめ定めておくこともできます。

www.atmarkit.co.jp

Amazon Linux2 dockerイメージ

Amazon Web ServicesのEC2でインスタンスを立てるときによく使われる Amazon Linux2 のdocker imageがdockerhubに上がっていた。

hub.docker.com

f:id:pinkumohikan:20200704121521p:plain
Amazon Linux2のdocker image

$ docker run --rm -it amazonlinux:2 bash
bash-4.2# cat /etc/os-release | grep PRETTY_NAME
PRETTY_NAME="Amazon Linux 2"

ただ、実際のAmazon Linux2 AMIとはインストールされているパッケージとかが若干の差異があるみたい。sudoとかuseraddとかsystemdとか入ってないし、minimal版みたいな感じっぽい。

デフォルトではuseraddコマンドが入っていない

Amazon Linux2向けのプロビジョニングを書いていて、ユーザの追加とかやりたかったんだけどuseraddコマンドが入っていない。

bash-4.2# useradd
bash: useradd: command not found

適当にググったら shadow-utils っていうパッケージに内包されているらしい。

シャドウパスワードファイルとユーザー/グループアカウントを管理するための ユーティリティ。

penguin.triumf.ca

$ docker run --rm -it amazonlinux:2 bash
bash-4.2# cat /etc/os-release | grep PRETTY_NAME
PRETTY_NAME="Amazon Linux 2"
bash-4.2#
bash-4.2#
bash-4.2# yum list shadow-utils
Loaded plugins: ovl, priorities
amzn2-core                                                         | 3.7 kB  00:00:00
(1/3): amzn2-core/2/x86_64/group_gz                                | 2.5 kB  00:00:00
(2/3): amzn2-core/2/x86_64/updateinfo                              | 223 kB  00:00:00
(3/3): amzn2-core/2/x86_64/primary_db                              |  42 MB  00:00:03
Available Packages
shadow-utils.x86_64                   2:4.1.5.1-24.amzn2.0.2                    amzn2-core

yumリポジトリの追加要らずでシュッとインストールできそう。

shadow-utilsをインストールする

bash-4.2# yum install -y shadow-utils
Loaded plugins: ovl, priorities
amzn2-core                                                         | 3.7 kB  00:00:00
(1/3): amzn2-core/2/x86_64/group_gz                                | 2.5 kB  00:00:00
(2/3): amzn2-core/2/x86_64/updateinfo                              | 223 kB  00:00:00
(3/3): amzn2-core/2/x86_64/primary_db                              |  42 MB  00:00:04
Resolving Dependencies
...
Installed:
  shadow-utils.x86_64 2:4.1.5.1-24.amzn2.0.2

Dependency Installed:
  audit-libs.x86_64 0:2.8.1-3.amzn2.1         libcap-ng.x86_64 0:0.7.5-4.amzn2.0.4
  libsemanage.x86_64 0:2.5-11.amzn2           ustr.x86_64 0:1.0.4-16.amzn2.0.3

Complete!

useraddが使えるようになった🎉

bash-4.2# useradd
Usage: useradd [options] LOGIN
       useradd -D
       useradd -D [options]

Options:
...

めでたしめでたし

80番ポートを使っているプログラムをlsofコマンドで特定する

Linux環境で特定のポートを使いたいけど先に使われていてどのプログラムがそのポートを使っているか知りたいとき、lsofコマンドが便利。

lsofコマンド

 「lsof」はオープンしているファイルを一覧表示するコマンドです。

www.atmarkit.co.jp

lsofコマンドに-iオプションでポート番号をつけて実行すると、そのポートを握っているプログラム (コマンド) がわかる。

80番ポートを使っているのは誰?

$ sudo lsof -i:80
COMMAND   PID     USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
nginx   17287     root   12u  IPv4 47601898      0t0  TCP *:http (LISTEN)
nginx   17287     root   14u  IPv6 47601900      0t0  TCP *:http (LISTEN)
nginx   17292 www-data   12u  IPv4 47601898      0t0  TCP *:http (LISTEN)
nginx   17292 www-data   14u  IPv6 47601900      0t0  TCP *:http (LISTEN)
nginx   17293 www-data   12u  IPv4 47601898      0t0  TCP *:http (LISTEN)
nginx   17293 www-data   14u  IPv6 47601900      0t0  TCP *:http (LISTEN)

この例ではnginxがTCP 80番 (http) を握っていることが読み取れる。

Nginxに "413 Request Entity Too Large" と怒られる原因と対処法

Nginxをリバースプロキシとして使っている環境でファイルアップロードなどを行おうとしたとき "413 Request Entity Too Large" というエラーレスポンスが返ることが有る。

nginx.org

f:id:pinkumohikan:20200526235206j:plain
413 Request Entity Too Large

原因

Nginxへ送信されたコンテンツのサイズが大きすぎて、制限を超えているため。

HTTP Response Status Code 413の定義は下記:

6.5.11. 413 Payload Too Large

The 413 (Payload Too Large) status code indicates that the server is refusing to process a request because the request payload is larger than the server is willing or able to process. The server MAY close the connection to prevent the client from continuing the request.

tools.ietf.org

意訳: 413はリクエストがでかすぎてサーバが拒否ったことを示すステータスコードだよ。

※ RFC的には "Payload Too Large" って定義されているけど、Nginxは "Request Entity Too Large" って返してるの何でだろう?知っている人いたら教えて下さい。

対処法

方法としてはざっくり、制限内で収まるようにリクエストサイズを制限する方法と、Nginxの設定を変更してリクエストサイズの上限を引き上げる方法がある。

1. 制限内で収まるようにリクエストサイズを小さくする方法

レンタルサーバを使っている場合など、Nginxの設定を変更する権限がない場合にはこうするほか無さそう。現状の設定を確認して、それに収まるようにリクエストサイズを小さくする。

例えばファイルアップロード機能で怒られる場合は、アップロードできるファイルサイズをNginxが許容するサイズ以下になるようUI側で制限する。具体的な方法としてはFile APIなどが使えそう。

developer.mozilla.org

2. Nginxの設定を変更してリクエストサイズの上限を引き上げる方法

Nginxの設定を変更する権限がある場合、設定ファイルの client_max_body_size というパラメータを変更することでリクエストサイズの上限を引き上げられる。デフォルトでは1MBと結構タイト。

nginx.org

Syntax: client_max_body_size size;

Default: client_max_body_size 1m;

Context: http, server, location

Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field. If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client. Please be aware that browsers cannot correctly display this error. Setting size to 0 disables checking of client request body size.

意訳: クライアントが送ってくるリクエストボディサイズの上限を設定する。リクエストのContent-Lengthが設定値を超えていたら 413 (Request Entity Too Large) エラーをクライアントへ返すよ。0を指定したらサイズをチェックしないよ。

ただし、設定を変更する前に、現状の設定がどういった意図でされているものかを確認するべし。単にデフォルトのままとかであれば変えて良さそうけど、例えばサーバのスペックと想定同時アクセス数などを勘案してリクエストサイズを制限している場合、むやみに設定を変えるとサーバがトラフィックに耐えられなくなる恐れがある。

f:id:pinkumohikan:20200526234900p:plain
50MBまで許す設定の例

設定を書き換えてNginxをreloadしてあげれば、もう怒られない。

f:id:pinkumohikan:20200526235219j:plain
200 OK。もう大きなファイルを上げても怒られない

FileReader.readAsDataURLで得られるのはData URIであって純粋なbase64文字列じゃないぞ

ファイルをFileReader.readAsDataURLを使って文字列化したものは純粋なbase64文字列だと思っていたけど、decodeしようとしたら出来なくてなんでやねん!と思ったので残しておく。

まとめ

  • 画像とかの添付ファイルをJavaScriptで扱うときにFileReaderを使う
  • FileReader.readAsDataURLのresultで得られるのはData URIであって、純粋なbase64文字列じゃない
  • 先頭のData URI宣言部を取り除いたら純粋なbase64文字列になる

大事なことは全部ドキュメントが教えてくれた

base64 decodeできなくて「おや?」と思ったけど、大事なことは全部ドキュメントに書いてあった。

developer.mozilla.org

メモ: blob の result は、先に Base64 でエンコードされたデータの前にある Data-URL の宣言を削除しておかないと、直接 Base64 としてデコードすることができません。 Base64 でエンコードされた文字列のみを受け取る場合は、先に結果から data:/;base64, を削除しておく必要があります。

resultの文字列をprintしてみたら data:image/jpeg;base64,/9j/2wCEAAgGB... みたいな感じになっていて、たしかにbase64文字列じゃないや。っていうかよくよく考えればメソッド名が readAsDataURL だから、実行結果として得られるものは当然Data URIだよな... 😇

余計な文字列を取り除く

文字列化したものをWeb API等へ送るときは、先頭の余計な文字列を取り除いておこう。

実際に取り出した文字列をみるに data:${mimeType};base64,${base64EncodedFile} という構造になっていそうだけど、ドキュメントに 先に結果から data:*/*;base64, を削除しておく必要があります とあるのでとりあえずそれに従えば良さそう。

こんな感じ:

const dataURI = filereader.result; // "data:image/jpeg;base64,/9j/2wCEAAgGB..." みたいなのが入る
const base64EncodedFile = dataURI.replace(/data:.*\/.*;base64,/, '');

developer.mozilla.org

海外へWebコンテンツを配信する際はアクセシビリティの法律に気をつけるべし

ふとしたtweetをきっかけに、海外向けにWebコンテンツを配信する際には現地のアクセシビリティに関する法律に気をつける必要があることを学んだ。

ざっくりまとめ

  • アメリカ等、国によってはアクセシビリティが権利として法的に認められている
  • 先の法を根拠に年間2000件以上の訴訟が起きている
  • 日本ではアクセシビリティは努力目標だけど、同じ感覚で海外展開すると危険

アクセシビリティとは

情報システムの利用しやすさを表す言葉。パソコンやインターネットが幅広く普及した現在、高齢者や障害者などハンディを持つ人にも健常者と同じように使える環境を整える必要がある。アクセシビリティはその対応度を計る尺度となるもの。具体的には「画像や音声などには代替表現として必ずテキストによる注釈をつける」「マウスの使用が困難な人向けにすべての操作をキーボードで行なえるようにする」ことなどが求められている。

kotobank.jp

ざっくり言うと、みんながみんな同じように画像を認識し、文字が読めるわけではないから、そういう境遇の人でもコンテンツを享受できるように配慮してね、みたいなやつ。マルチデバイス対応とか音声読み上げへの対応が代表例。

日本にも、Webコンテンツのアクセシビリティに関するJIS規格があるらしい。

waic.jp

国によってはアクセシビリティが権利として認められている

webtan.impress.co.jp

今回の学びの大部分は上記記事からのもの。特に学びが有ったところを下記に抜粋。

アメリカには、障害を持つ人がアメリカ社会に完全に参加できることを保証したADA(Americans with Disabilities Act 障害を持つアメリカ人法)という法律があります。このADAに基づいたWebアクセシビリティ提訴の件数が、2017年には814件だったのが2018年には2,285件となり281%も増加しています。

...

弁護士の手配や証拠開示手続き、交渉などを含めると、訴訟1件あたりの費用の試算は356,775ドル(約4,000万円)にものぼるとのことです。

...

アメリカでは、5人に1人(=6,400万人)がなんらかの障害を持っており、障害のある就労年齢の人々の可処分所得合計は約4,900億ドル。アフリカ系アメリカ人は5,010億ドル、ヒスパニック系アメリカ人は5,820億ドルとなっており、他の重要な市場セグメントに匹敵することことも紹介していました。

...

アメリカの場合は法律で「やれ」と定められており、アクセシビリティ対策をしないという選択肢はそもそもないらしい。というよりむしろマーケットとしてそれなりに大きいのでアクセシビリティへの積極投資に経済的合理性があるらしい。

こと日本においてはアクセシビリティ対策は努力目標の位置づけだけど、海外では権利として認められているところもあるので海外展開する際に日本と同じ感覚でいると危ないことは覚えておきたい。

Lambda@Edgeではオリジンのデータを部分的に書き換えて返すことはできない

ちょっと何を言っているか分からないと思うけど、自分も分かりたくなかった!

ざっくりまとめ

  • AWS CloudFrontにはいわゆるエッジコンピューティングを提供する Lambda@Edge がある
  • Lambda@Edgeではオリジンから返ってきたbodyの一部を書き換えて返すことは(パパッとは)できない

f:id:pinkumohikan:20200214001234p:plain
bodyどこーーー

Lambda@Edgeとは

aws.amazon.com

AWSが提供するCDNサービスCloudFrontに付随する、エッジコンピューティングサービス。配信先のユーザに近いサーバでLambdaを実行して結果を返したら速くコンテンツ提供できるよねーというやつ

ESI (Edge Side Includes) やりたいとか、基本静的コンテンツしか返さないんだけどごく一部で動的にしたいんだよねーでもpathは変えたくないしサーバも用意したくないんだよねーみたいなときに使えそうなやつ

やりたかったこと

CloudFront + S3な構成において、特定のリクエストパラメータが指定された場合にコンテンツの一部を書き換えて配信したい

例えば、S3におっきなjson置いといて ?limit=10&page=1 みたいなクエリパラメータがついていたらjsonの一部だけを返す、みたいな感じ

GET /posts

Response:
{
    "posts": [
        // たくさんのPost
    ]
}
GET /posts?limit=10&page=1

Response:
{
    "posts": [
        // id 1 - 10までのPost
    ]
}

Lambda 関数をトリガーできる CloudFront イベント を呼んで、下記の図でいう Origin Response をトリガーにLambda@Edgeを動かせばやりたいことできそうだと思うじゃん?

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/images/cloudfront-events-that-trigger-lambda-functions.png

Lambda@Edge 関数の例 とか見てもRequestとResponseそれぞれいじっているようなコードがポコポコ書かれてるし、テンプレートエンジンのレンダリングとかに使えるんじゃねみたいな記事もどこかで見かけたし、絶対行けそうだと思うじゃん????

オリジンから返ってきたbodyはLambda@Edgeで読めない

雑にPoCコード書いてたら、衝撃の事実に気づく

イベントの構造 レスポンスイベント

f:id:pinkumohikan:20200213233751p:plain
response event

おわかり頂けただろうか?

response headerはしっかり渡ってくるけど、 response bodyは渡ってこない!!! ママ〜!!!!!!!!

いやいやそんなばかなー、と思ってググったら「それ仕様やで」っていうクラメソの記事もヒット

dev.classmethod.jp

やっぱりそういうことらしいですわ。ぐぬぬー

じゃあどうすんの?

オリジンのbody任意のresponse bodyを返すことは出来るので、response bodyが渡って来ないならしょうがないから自分でS3 getするしかない。でも、トリガーが Origin Response のままだとCFがS3 getしたあと自分でもS3 getする感じになって無駄なので、トリガーを Origin Request に変えて、

  • 所定のパラメータがついていなかったらpassthrough(オリジンにそのまま問い合わせさせる)
  • 所定のパラメータがついていたら自分でS3 getしてフィルタリング、オリジンに問い合わせさせずにresponseを返す

って感じにするのがスマートかなあ。

リクエストトリガーでの HTTP レスポンスの生成

もしもっといい方法があったらマジで教えて下さい!

っていうか何でこんな仕様になってるの?教えてエロい人

Amazon Linux 2へPHP7.4をインストールする

Amazon Linux 2へPHP 7.4をインストールしたので備忘録がてら残しておく。

f:id:pinkumohikan:20191228190238p:plain
PHP 7.4.1

前提

  • 2019/12/28 時点の情報
  • Amazon Linux 2 ( ami-068a6cefc24c301d2 )

amazon-linux-extras

Amazon Linux 2には amazon-linux-extras という便利コマンドがある。このコマンドを使うとサードパーティ製パッケージを割と新しめなバージョンでサクッとインストールできる。

aws.amazon.com

だがしかしbut、12/28時点ではPHP 7.4はサポートされておらず、フォーラムを見る限り予定も不明確。

Thread: amazon-linux-extras support for PHP 7.4

なので現時点でAmazon Linux 2でPHP 7.4を使うには、自分で頑張ってインストールする必要がある。

P.S.

この記事を書いた時点では入れられなかったが、2020/09/17 現在はamazon-linux-extrasでPHP 7.4を入れられるようになっている。今からPHP 7.4を入れるならそっちの方法が正攻法だと思われる。

ただし、この記事で紹介している方法は新バージョンのリリースからamazon-linux-extrasで使えるようになるまでラグの間は有用な方法ではあるので記事としては残しておく。

ざっくり手順

  1. EPELリポジトリを使えるようにする
  2. remiリポジトリを使えるようにする
  3. remiリポジトリを使って、PHP 7.4をインストールする

コマンドでいうとこちら

sudo amazon-linux-extras enable epel
sudo yum clean metadata
sudo yum install -y epel-release

sudo rpm -Uvh https://rpms.remirepo.net/enterprise/remi-release-7.rpm

sudo yum install --enablerepo remi -y php74

sudo ln -sf /usr/bin/php74 /usr/bin/php

一つづつ解説していく。

解説

1. EPELリポジトリを使えるようにする

fedoraproject.org

イカしたサードパーティ製ライブラリを提供するyumリポジトリ。有名な先進OS Fedoraのメンテナがメンテしてるので安心。

EPELはamazon-linux-extrasでインストール出来る。

$ sudo amazon-linux-extras enable epel
  0  ansible2                 available    [ =2.4.2  =2.4.6  =2.8 ]
  2  httpd_modules            available    [ =1.0 ]
  3  memcached1.5             available    \
        [ =1.5.1  =1.5.16  =1.5.17 ]
  5  postgresql9.6            available    [ =9.6.6  =9.6.8 ]
  6  postgresql10             available    [ =10 ]
  8  redis4.0                 available    [ =4.0.5  =4.0.10 ]
  9  R3.4                     available    [ =3.4.3 ]
 10  rust1                    available    \
        [ =1.22.1  =1.26.0  =1.26.1  =1.27.2  =1.31.0  =1.38.0 ]
 11  vim                      available    [ =8.0 ]
 13  ruby2.4                  available    [ =2.4.2  =2.4.4  =2.4.7 ]
 15  php7.2                   available    \
        [ =7.2.0  =7.2.4  =7.2.5  =7.2.8  =7.2.11  =7.2.13  =7.2.14
          =7.2.16  =7.2.17  =7.2.19  =7.2.21  =7.2.22  =7.2.23
          =7.2.24 ]
 16  php7.1                   available    \
        [ =7.1.22  =7.1.25  =7.1.27  =7.1.28  =7.1.30  =7.1.31
          =7.1.32  =7.1.33 ]
 17  lamp-mariadb10.2-php7.2  available    \
        [ =10.2.10_7.2.0  =10.2.10_7.2.4  =10.2.10_7.2.5
          =10.2.10_7.2.8  =10.2.10_7.2.11  =10.2.10_7.2.13
          =10.2.10_7.2.14  =10.2.10_7.2.16  =10.2.10_7.2.17
          =10.2.10_7.2.19  =10.2.10_7.2.21  =10.2.10_7.2.22
          =10.2.10_7.2.23  =10.2.10_7.2.24 ]
 18  libreoffice              available    [ =5.0.6.2_15  =5.3.6.1 ]
 19  gimp                     available    [ =2.8.22 ]
 20  docker=latest            enabled      \
        [ =17.12.1  =18.03.1  =18.06.1  =18.09.9 ]
 21  mate-desktop1.x          available    [ =1.19.0  =1.20.0 ]
 22  GraphicsMagick1.3        available    [ =1.3.29  =1.3.32 ]
 23  tomcat8.5                available    \
        [ =8.5.31  =8.5.32  =8.5.38  =8.5.40  =8.5.42 ]
 24  epel=latest              enabled      [ =7.11 ]
 25  testing                  available    [ =1.0 ]
 26  ecs                      available    [ =stable ]
 27  corretto8                available    \
        [ =1.8.0_192  =1.8.0_202  =1.8.0_212  =1.8.0_222  =1.8.0_232 ]
 28  firecracker              available    [ =0.11 ]
 29  golang1.11               available    \
        [ =1.11.3  =1.11.11  =1.11.13 ]
 30  squid4                   available    [ =4 ]
 31  php7.3                   available    \
        [ =7.3.2  =7.3.3  =7.3.4  =7.3.6  =7.3.8  =7.3.9  =7.3.10
          =7.3.11 ]
 32  lustre2.10               available    [ =2.10.5 ]
 33  java-openjdk11           available    [ =11 ]
 34  lynis                    available    [ =stable ]
 35  kernel-ng                available    [ =stable ]
 36  BCC                      available    [ =0.x ]
 37  mono                     available    [ =5.x ]
 38  nginx1                   available    [ =stable ]
 39  ruby2.6                  available    [ =2.6 ]
 40  mock                     available    [ =stable ]
 41  postgresql11             available    [ =11 ]

Now you can install:
 # yum clean metadata
 # yum install epel-release
$ sudo yum clean metadata
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
リポジトリーを清掃しています: amzn2-core amzn2extra-docker amzn2extra-epel
10 個の metadata ファイルを削除しました
4 個の sqlite ファイルを削除しました
0 個の metadata ファイルを削除しました
$ sudo yum install -y epel-release
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                      | 2.4 kB  00:00:00
amzn2extra-docker                                                                                               | 1.3 kB  00:00:00
amzn2extra-epel                                                                                                 | 1.3 kB  00:00:00
(1/5): amzn2-core/2/x86_64/group_gz                                                                             | 2.5 kB  00:00:00
(2/5): amzn2-core/2/x86_64/updateinfo                                                                           | 181 kB  00:00:00
(3/5): amzn2extra-epel/2/x86_64/primary_db                                                                      | 1.8 kB  00:00:00
(4/5): amzn2extra-docker/2/x86_64/primary_db                                                                    |  59 kB  00:00:00
(5/5): amzn2-core/2/x86_64/primary_db                                                                           |  36 MB  00:00:00
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ epel-release.noarch 0:7-11 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

=======================================================================================================================================
 Package                           アーキテクチャー            バージョン                   リポジトリー                          容量
=======================================================================================================================================
インストール中:
 epel-release                      noarch                      7-11                         amzn2extra-epel                       15 k

トランザクションの要約
=======================================================================================================================================
インストール  1 パッケージ

総ダウンロード容量: 15 k
インストール容量: 24 k
Downloading packages:
epel-release-7-11.noarch.rpm                                                                                    |  15 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : epel-release-7-11.noarch                                                                               1/1
  検証中                  : epel-release-7-11.noarch                                                                               1/1

インストール:
  epel-release.noarch 0:7-11

完了しました!

2.remiリポジトリを使えるようにする

rpms.remirepo.net

remiもイカしたサードパーティ製ライブラリを提供するyumリポジトリ。

$ sudo rpm -Uvh https://rpms.remirepo.net/enterprise/remi-release-7.rpm
https://rpms.remirepo.net/enterprise/remi-release-7.rpm を取得中
警告: /var/tmp/rpm-tmp.cwom6N: ヘッダー V4 DSA/SHA1 Signature、鍵 ID 00f97f56: NOKEY
準備しています...              ################################# [100%]
更新中 / インストール中...
   1:remi-release-7.7-1.el7.remi      ################################# [100%]

3. PHP 7.4を入れる

あとはお目当てのものをインストールしていくだけ。

EPELもremiも、既存リポジトリと競合しないように無効化された状態でリポジトリ登録されているので、使うときはyumコマンドに --enablerepo remi のようにオプションを付けて明示的に有効化する必要がある。

$ sudo yum install --enablerepo remi -y php74
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
(1/2): remi/primary_db                                                                                          | 2.6 MB  00:00:02
(2/2): remi-safe/primary_db                                                                                     | 1.7 MB  00:00:03
250 packages excluded due to repository priority protections
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ php74.x86_64 0:1.0-1.el7.remi を インストール

...

インストール:
  php74.x86_64 0:1.0-1.el7.remi

依存性関連をインストールしました:
  audit-libs-python.x86_64 0:2.8.1-3.amzn2.1                             checkpolicy.x86_64 0:2.5-6.amzn2
  environment-modules.x86_64 0:3.2.10-10.amzn2.0.2                       libX11.x86_64 0:1.6.5-2.amzn2.0.2
  libX11-common.noarch 0:1.6.5-2.amzn2.0.2                               libXau.x86_64 0:1.0.8-2.1.amzn2.0.2
  libcgroup.x86_64 0:0.41-21.amzn2                                       libselinux-python.x86_64 0:2.5-12.amzn2.0.2
  libsemanage-python.x86_64 0:2.5-11.amzn2                               libxcb.x86_64 0:1.12-1.amzn2.0.2
  ncurses-compat-libs.x86_64 0:6.0-8.20170212.amzn2.1.3                  php74-php-cli.x86_64 0:7.4.1-1.el7.remi
  php74-php-common.x86_64 0:7.4.1-1.el7.remi                             php74-php-json.x86_64 0:7.4.1-1.el7.remi
  php74-runtime.x86_64 0:1.0-1.el7.remi                                  policycoreutils-python.x86_64 0:2.5-22.amzn2
  python-IPy.noarch 0:0.75-6.amzn2.0.1                                   setools-libs.x86_64 0:3.3.8-2.amzn2.0.2
  tcl.x86_64 1:8.5.13-8.amzn2.0.2

完了しました!

php-mbstring などのPHP拡張を入れたいときは、 php74- というprefixをつける。 php-mbstring の場合は php74-php-mbstring 、といった具合。

$ sudo yum install --enablerepo remi -y php74-php-mbstring
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
250 packages excluded due to repository priority protections
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ php74-php-mbstring.x86_64 0:7.4.1-1.el7.remi を インストール

...

インストール:
  php74-php-mbstring.x86_64 0:7.4.1-1.el7.remi

依存性関連をインストールしました:
  oniguruma5.x86_64 0:6.9.4-1.el7.remi

完了しました!

デフォルトでは php74 というコマンド名でインストールされる。symlinkを貼って php で呼べるようにしておくと便利。

$ php --version
-bash: php: コマンドが見つかりません

$ which php74
/usr/bin/php74

$ sudo ln -sf /usr/bin/php74 /usr/bin/php

$ php --version
PHP 7.4.1 (cli) (built: Dec 17 2019 16:35:58) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies

Happy PHP 7.4 Life!