モヒカンメモ

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

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

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

ざっくりまとめ

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

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コード書いてたら、衝撃の事実に気づく

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

response event

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

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

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

dev.classmethod.jp

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

じゃあどうすんの?

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

  • 所定のパラメータがついていなかったらオリジンにそのまま問い合わせさせる
  • 所定のパラメータがついていたら自分で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!

PHPUnit 7系が2020年2月でサポート終了するぞ!バージョンアップを急げ!

PHPでデファクトスタンダードなテスティングツール PHPUnit の7系バージョンが2020年2月7日でサポートが終了します。

ざっくりまとめ

  • PHPUnit 7系(あるいはそれ以下)を使っているひとは、PHPUnit 8系へ乗り換えましょう
  • PHPUnit 8系はPHP7.2以上が必須。7.1以下の人は先にPHPのバージョンアップを計画しましょう

f:id:pinkumohikan:20191207174810p:plain
2020年2月でサポート終了

phpunit.de

github.com

PR

この記事は若手ものづくりコミュニティ Oysters のAdvent Calendar 2019にかこつけて書きました。

adventar.org

サポート終了するとどうなる?

PHPUnitはメジャーバージョンのリリースから2年がサポート期限で、既に4, 5, 6はサポート終了済み。現行は7系と8系で、7系はもうじきサポート終了です。

一般的にはサポートが切れるとそれ以降、改善がされなかったり、バグが修正されなかったり、ドキュメントが公式サイトから消去されて行ったり、脆弱性が見つかっても放置されたりします。

なので、サポート期限が来る前に新しいバージョンへ追従していくのが基本です。

え?そんな工数割けない?じゃあ最初からOSSなんて使わなければ良かったのに(真顔で火の玉ストレート攻撃ズドーン)

PHPUnit 7系から8系って何が変わる?

phpunit.de

大きなところでいうと

  • PHP 7.2が最低サポートバージョンになる
    • PHP 7.1以下の環境ではそもそもinstallできなくなる
  • ライフサイクル系メソッド (setUpとかtearDownとか) のreturn typeとして void が明示される
    • テストクラスでそれらを使っている場合、同じように void を明示しないとmethod signatureが合わないぞって怒られる
  • いくつかのアサーションメソッド、アノテーションがdeprecatedに
    • assertArraySubsetは個人的には好きだったのでちょっとショック

どんな流れでバージョンアップすれば良い?

だいたいいつもこんな感じで上げています。

  1. 手元でcomposer updateコマンドでPHPUnitをバージョンアップ
  2. 脳死でテストを走らせる
  3. 出てくるwarningやerrorをissueにまとめ、怒られのパターンを見る
  4. えいやで行けそうな数ならえいやで直す、そうでなければ怒られパターンごとに分割して直す
    • このとき現行バージョンでも動く変更を心がけ、バージョンアップのPRとは切り離して先行リリースしていくと変更の影響範囲を狭められてオススメです
  5. PHPUnitのバージョンアップをリリース (master等へmerge)

最後に

PHPUnitに限らず、OSSを使うならバージョンアップは割けて通れないと考えています。目先の工数削減のために脳死で使うんじゃなくて、OSS採用の際にはバージョンアップへの追従コストも考えましょう。また、バタバタしながらのビッグバン変更にならないよう、こまめに計画的にアップデートしていきましょう。

自分の前職では毎週、OSSのバージョンアップをやっていました。とても良い文化だなと思って自分の周りや今の職場でも普及活動中をしているところです。

techlog.voyagegroup.com

awscliで 'AWSHTTPSConnection' object has no attribute 'server_hostname' って怒られたときにやったこと

ざっくりまとめ

  • awscliをインストールして使おうとしたら何か怒られた
  • よく分からんけど、aptでインストールするのやめてpipで入れ直したら直った

起きたこと

とあるUbuntuサーバへawscliをインストールして、aws configureして、awsコマンドを叩いたところ下記のようなエラーが置きた

$ sudo apt install awscli
...

$ aws s3 ls
fatal error: 'AWSHTTPSConnection' object has no attribute 'server_hostname'

アイヤー、謎のエラー

エラーメッセージ的にはこっちの設定が悪いとかでは無さそうな雰囲気を感じる、良く分からんけど

やったこと

Try 1: 再インストール

エラーメッセージでぐぐったら、再インストールしたら直ったよ記事がいくつかヒットしたので試してみた

$ sudo apt remove awscli
...


$ sudo apt install awscli
...

$ aws s3 ls
fatal error: 'AWSHTTPSConnection' object has no attribute 'server_hostname'

ハイダメー!!!

Try 2: pipで入れ直す

何も考えずにaptでインストールしたけど、そう言えばいつもawscliはpipでインストールしていたのを思い出した

pipで入れ直してみる

$ sudo apt remove awscli
...

$ sudo pip3 install awscli
Traceback (most recent call last):
  File "/usr/bin/pip3", line 9, in <module>
    from pip import main
ImportError: cannot import name 'main'

あらやだ(たまに起こるけど、rootとしてログインしてからなら通るのでそれ以上調べる気にならずなんでこうなるのかちゃんと理解していない人の顔)

$ sudo --login pip3 install awscli
...
Successfully installed awscli-1.16.283

$ aws s3 ls
-bash: /usr/bin/aws: No such file or directory

チッ (aptで入れていたs3コマンドへのpathが通ったままなのでloginしなおす)

$ aws s3 ls
2019-11-16 18:23:14 very-nice-na-bucket

勝った

Laravelのレートリミットミドルウェアについて調べた

ざっくりまとめ

  • Laravelには任意のエンドポイントに対してレートリミットを行うためのミドルウェアが用意されている
  • 1分当たり10リクエストまで、という感じで制限可能
  • ログイン中ならユーザ、そうでなければIPアドレス単位でカウントされる

レートリミットとは

1分間に10回まで実行してよい、みたいな感じで制限を課すこと。Web APIや高負荷な集計/エクスポート機能といった、必要だがむやみに連打されたくない機能で利用することが多い

Laravelには、レートリミット機能を提供するミドルウェアが標準で用意されている

laravel.com

あんまりドキュメントには情報がないのでコードを追った

参考にしたコードは、Laravel 6.5リリース時点のもの

実装的にはこの辺から: https://github.com/laravel/framework/blob/v6.5.0/src/Illuminate/Routing/Middleware/ThrottleRequests.php

制限の単位

何分当たり何リクエストまで、という感じで指定可能

誰がどのぐらいリクエストしてきたかは内部的にはcacheで管理される

制限を超えると、ステータスコード429を返す

ユーザにこの画面を見せるわけにはいかないので、ちゃんと適切なエラーページを用意してあげよう

使い方

throttle:$何回まで,$何分間のうちに みたいな感じでミドルウェアを指定すれば使える

公式ドキュメントに乗っている下記の例だと、1分間に60回までリクエストを許すという設定になる

Route::middleware('auth:api', 'throttle:60,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});

61回目のリクエストからは 429 Too Many Requests というエラーが表示される

f:id:pinkumohikan:20191113140120p:plain
429 Too Many Requests

CircleCIのDocker Layer Cachingが有料 & だいぶ高価になっていた

ざっくりまとめ

  • CircleCIのDocker Layer Caching (DLC) がパフォーマンスプラン (従量課金) の有料機能になっていた
  • DLCが有効だと、ジョブが1回走る度にVMを20分間動かしたのと同じぶんのクレジットを消費する
  • クレジットは減ったら自動チャージで課金されるので、ガンガン課金されてCI破産しないようにご注意を

Docker Layer Caching (DLC) とはなにか

docker build時の中間キャッシュ (Layer cache) を再利用する仕組み。前回のビルドから変更がなかった分の中間キャッシュを再利用できれば、その続きからのビルドのみで済むのでCI時間を短縮できる

過去の使ってみた記事 (2018年): blog.pinkumohikan.com

いつの間にか有料になっていた

自分が先の記事を書いた2018年5月時点では無料プランでも使えたが、2019年頭ぐらいから有料オプションになっていたらしい (詳細な時期は不明)

2019年11月現在では、DLCを使うにはパフォーマンスプラン (従量課金) を契約する必要がある

Docker レイヤー キャッシュを自分の環境で有効化するには?

Docker レイヤー キャッシュを利用するには、Performance プランのアカウントが必要です。

circleci.com

そして利用料はそれなりに高い

パフォーマンスプランは毎月クレジットが割り当てられ、(基本的には) CI実行時のリソース使用量に応じてクレジットが減っていく。クレジット残量は少なくなると自動でチャージされる ( = 課金される)。

DLCの利用料は、1ジョブ実行で200クレジット消費とのこと

f:id:pinkumohikan:20191108134610p:plain

MediumサイズのLinux環境 (2コア 4Gメモリ) を1分間動かすと10クレジット消費らしいので、 1ジョブ実行でVMを20分間動かしたのと同じ分のクレジットが消費されることになる

f:id:pinkumohikan:20191108134633p:plain

金額になおすと25,000クレジット = $15とすると1ジョブ実行 200クレジット = $0.12

CI高速化のためにビルドマトリックスで何ジョブも並列で走る設計にしていたり、開発者数が多かったりしたらチリツモでそれなりの額になるやも

アイヤー

徳丸基礎試験の試験結果が届いた

8月頭にウェブセキュリティ基礎試験(徳丸基礎試験)のベータ試験を受けて、ついに今日、試験結果が届いた。

f:id:pinkumohikan:20191016213017j:plain:w300
職場の先輩にもらったモンスターエナジー。もちろん、本記事には全く関係がない

試験結果

受験直後の記事で私はこう言いました:

blog.pinkumohikan.com

ちなみに今回の試験としては手応え十分なのでまあ受かっているんじゃないかな。もしこれで落ちていたら木の下に埋めてもらっても構わないよ!

そして結果:

f:id:pinkumohikan:20191016210423p:plain
合格だよ

ぱんぱかぱーん、 無事徳丸試験 第一号合格者になりました🎉

早速Wantedlyの資格欄にも反映w

f:id:pinkumohikan:20191023204606p:plain

でも目標としていた正答率には届かず

正直、言うても基礎レベルだし9割は取れるでしょって思ってました。

f:id:pinkumohikan:20191016212116p:plain
9割取る自信発言

が、実際には87.5%。惜しいですが未達は未達ーーーー。悔しい。

カテゴリごとの正答率レポートがついていたので、それを見てだめだったところを復習します。

反省します

P.S.

自転車の前輪と後輪は基本同じなので入れ替えても意味がないらしいです。なんやねん。

徳丸試験(ウェブセキュリティ試験)を受けてきた

セキュリティ界隈で有名な徳丸さん監修のウェブセキュリティ試験(通称: 徳丸試験)を受けてきた。

peatix.com

動機

今回、徳丸試験を受けようと思った動機は下記の通り。

  1. 事業開発会社でWebアプリケーションを設計、実装する仕事をしており、Webアプリケーションの安全性についても責任がある
  2. Webエンジニアとしての強みを増やすため
  3. "徳丸試験 第1号合格者" という響きがかっこいい

試験対策

下記2冊の本を参考書として利用した。

f:id:pinkumohikan:20190804204950j:plain
初代徳丸本、二代目徳丸本、徳丸本コンプリートセット

受験申し込みから試験当日まで1ヶ月も無かったので徳丸本を通読するのは厳しいと思って赤本を先に読んだが、振り返ってみると試験対策としてはそのまま徳丸本を読んだほうが時間効率が良いように感じた。赤本は軽くWebセキュリティを抑えたい人や、PMやお客さんからセキュリティ予算 (工数) をもぎ取るために知識武装したい人にオススメ。

学習法は、軽く参考書を通読して、新たに学びになったところや良く分からなかったところに付箋を貼り、数日後に付箋を貼ったところを重点的に読み返す、というもの。過去問があればまず過去問を解いて苦手なところを見つたりするが、今回はなにせ第一回なので過去問など存在しないw

f:id:pinkumohikan:20190804205609j:plain
付箋貼って数日後に振り返る勉強法

感想

徳丸本は新卒内定者時代に一度読んで、当時はチンプンカンプンでとても苦労した覚えがある。職業エンジニアになって5年ぐらい経った今、改めて読むと概ね「分かる〜」って感じだったので基礎体力はしっかり出来ているようだ、良かった。

巷では不正アクセスや情報漏えいの話を良く聞くので、この業界でご飯食べて生きていくにはセキュリティ知識は欠かせないものになってきたと感じる。でも、一口にセキュリティと言っても幅も深さもあって「どこまで勉強すればええねん」ってなりがち。そういった意味で、試験という形なハッキリと合否がでるので「一旦の目標として、徳丸試験基礎レベルに合格出来るぐらいまで頑張ってみよっか!」って言えるのはとても良さそう。

ちなみに今回の試験としては手応え十分なのでまあ受かっているんじゃないかな。もしこれで落ちていたら木の下に埋めてもらっても構わないよ!結果が分かるのは3ヶ月後。楽しみにしてよう。

今回の学習の成果をいい感じに仕事で発揮して、給料アップにつなげるぞ 💰💰💰💰💰💰

P.S.

予言通り合格して、第一号合格者になりました 🎉

blog.pinkumohikan.com

mysqldumpしたら "unknown option '--show-warnings'" と怒られる問題

概要

f:id:pinkumohikan:20190721203820p:plain

背景

mysqlやmysqldumpなどのコマンドを実行するとき、 .my.cnf という名前の設定ファイルを用意しておくと文字コードやホスト名、パスワードなどのオプションを省略することができる。

dev.mysql.com

自分は下記のように show-warnings というオプションを設定していた。mysqlコマンドでは通常、warningの出るDB操作を行ってもwarningは表示されないが、このオプションを設定しておくとコンソールに警告メッセージを表示してくれるようになる。警告を握りつぶして良いことなど何一つとしてないので、必ず指定しておきたいオプションだ。

.my.cnf

[client]
show-warnings

警告の例

mysql> drop table if exists db.not_found_table;
Query OK, 0 rows affected, 1 warning (0.01 sec)

Note (Code 1051): Unknown table 'db.not_found_table'

だが、この設定をしたままmysqldumpを実行すると下記のように怒られてしまう。

$ mysqldump dump_target_table
mysqldump: [ERROR] unknown option '--show-warnings'.

原因と対策

原因は show-warnings オプションはmysqlコマンドにはあるがmysqldumpにはないため、存在しないオプション指定してんじゃねえぞと怒られているわけである。

解決策としては、 show-warnings オプションを [client] というgroupではなく [mysql] というgroupに記載すれば、mysqlコマンドのときだけオプションを適用することができた。

before

[client]
show-warnings

after

[mysql]
show-warnings

ドキュメントとしてはこの辺り:

dev.mysql.com

If an option group name is the same as a program name, options in the group apply specifically to that program. For example, the [mysqld] and [mysql] groups apply to the mysqld server and the mysql client program, respectively.

The [client] option group is read by all client programs provided in MySQL distributions (but not by mysqld). To understand how third-party client programs that use the C API can use option files, see the C API documentation at Section 28.7.7.50, “mysql_options()”.

これでmysqldumpを実行するときだけ show-warnings をコメントアウトするというつらい運用から開放される!

Ubuntu 18.04.2 LTSへtracerouteコマンドをインストールする

Ubuntu 18環境でネットワーク経路を確認しようとtracerouteコマンドを使おうとしたら入ってなかったのでシュパッとインストールする

f:id:pinkumohikan:20190715172330p:plain
traceroute --version

tracerouteコマンドとは

特定のIPやホストへのネットワーク経路や疎通を確認するためのコマンド

詳しくは:

tech.nikkeibp.co.jp

Ubuntu 18.04.2 LTSにはデフォルトではインストールされていない

インフラ屋か、構築直後しか使わないし、しょうがないね

$ traceroute

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

sudo apt install inetutils-traceroute
sudo apt install traceroute

おや、二個勧められたぞ?

www.gnu.org

inetutils-tracerouteは、GNUのやつなので安心感がありそう

sourceforge.net

tracerouteは、少ない権限で動いたり何かモダンらしい (SOURCEFORGEのdescription読んだだけw)

inetutils-tracerouteとtraceroute、どちらを使うべきか?

ぱっと調べた感じではtracerouteがおすすめっぽい

理由は、それぞれで blog.pinkumohikan.com への経路を調べたところ、 inetutils-traceroute ではオプションいじいじしても目的ホストまでたどり着けなかったが traceroute を使えばすんなりたどり着けたため

この記事も参考にした:

j3iiifn.hatenablog.com

ということでtracerouteのパッケージをインストール

$ sudo apt install traceroute
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  traceroute
0 upgraded, 1 newly installed, 0 to remove and 9 not upgraded.
Need to get 45.4 kB of archives.
After this operation, 152 kB of additional disk space will be used.
Get:1 http://nova.clouds.archive.ubuntu.com/ubuntu bionic/universe amd64 traceroute amd64 1:2.1.0-2 [45.4 kB]
Fetched 45.4 kB in 1s (35.1 kB/s)
Selecting previously unselected package traceroute.
(Reading database ... 175935 files and directories currently installed.)
Preparing to unpack .../traceroute_1%3a2.1.0-2_amd64.deb ...
Unpacking traceroute (1:2.1.0-2) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Setting up traceroute (1:2.1.0-2) ...
update-alternatives: using /usr/bin/traceroute.db to provide /usr/bin/traceroute (traceroute) in auto mode
update-alternatives: using /usr/bin/lft.db to provide /usr/bin/lft (lft) in auto mode
update-alternatives: using /usr/bin/traceproto.db to provide /usr/bin/traceproto (traceproto) in auto mode
update-alternatives: using /usr/sbin/tcptraceroute.db to provide /usr/sbin/tcptraceroute (tcptraceroute) in auto mode

すんなり入った

$ traceroute --version
Modern traceroute for Linux, version 2.1.0
Copyright (c) 2016  Dmitry Butskoy,   License: GPL v2 or any later

お試しで調査してみる

$ traceroute --icmp blog.pinkumohikan.com
You do not have enough privileges to use this traceroute method.
socket: Operation not permitted

おおん!? 少ない権限で動くとは何だったのか

$ sudo traceroute --icmp blog.pinkumohikan.com
traceroute to blog.pinkumohikan.com (13.115.18.61), 30 hops max, 60 byte packets
 1  xxx.g.tyo1.static.cnode.io (xxx.xxx.xxx.xxx)  0.918 ms  0.988 ms  1.096 ms
 2  g-o-4eb-a13-4-v-712.interq.or.jp (157.7.41.129)  6.723 ms  6.833 ms  6.961 ms
 3  unused-133-130-013-013.interq.or.jp (133.130.13.13)  0.754 ms  0.855 ms  0.965 ms
 4  unused-133-130-012-034.interq.or.jp (133.130.12.34)  0.856 ms  0.965 ms  1.029 ms
 5  16509.tyo.equinix.com (203.190.230.53)  0.600 ms  0.604 ms  0.604 ms
 6  * * *
 7  * * *
 8  54.239.52.93 (54.239.52.93)  2.063 ms  1.693 ms  1.560 ms
 9  52.95.30.38 (52.95.30.38)  0.560 ms  0.566 ms  0.651 ms
10  * * *
11  * * *
12  * * *
13  52.95.31.55 (52.95.31.55)  2.160 ms  2.135 ms  2.151 ms
14  52.95.31.173 (52.95.31.173)  1.720 ms  1.692 ms  1.691 ms
15  52.95.31.158 (52.95.31.158)  3.173 ms  3.199 ms  3.215 ms
16  52.95.31.72 (52.95.31.72)  2.948 ms  3.509 ms  3.500 ms
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

失敗しとるやんけw

ICMPだと無理っぽいけど、TCP SYNを使うモードを見つけたので試してみる

$ sudo traceroute --tcp blog.pinkumohikan.com
traceroute to blog.pinkumohikan.com (13.115.18.61), 30 hops max, 60 byte packets
 1  xxx.g.tyo1.static.cnode.io (xxx.xxx.xxx.xxx)  0.910 ms  1.024 ms  1.045 ms
 2  g-o-4eb-a13-4-v-712.interq.or.jp (157.7.41.129)  1.107 ms  1.326 ms  1.527 ms
 3  unused-133-130-013-013.interq.or.jp (133.130.13.13)  0.614 ms  0.630 ms  0.619 ms
 4  unused-133-130-012-034.interq.or.jp (133.130.12.34)  0.774 ms  0.717 ms  0.844 ms
 5  16509.tyo.equinix.com (203.190.230.53)  1.041 ms  1.033 ms  1.030 ms
 6  * * *
 7  * * *
 8  54.239.52.89 (54.239.52.89)  1.954 ms 54.239.52.103 (54.239.52.103)  9.649 ms 54.239.52.107 (54.239.52.107)  1.492 ms
 9  52.95.30.44 (52.95.30.44)  0.988 ms 52.95.30.48 (52.95.30.48)  0.996 ms 52.95.30.60 (52.95.30.60)  0.870 ms
10  * * *
11  * * *
12  * * *
13  52.95.31.19 (52.95.31.19)  2.169 ms 52.95.31.43 (52.95.31.43)  2.507 ms 52.95.31.47 (52.95.31.47)  2.097 ms
14  52.95.31.221 (52.95.31.221)  2.020 ms 52.95.31.183 (52.95.31.183)  2.802 ms 52.95.31.215 (52.95.31.215)  2.092 ms
15  52.95.31.168 (52.95.31.168)  2.189 ms 52.95.31.188 (52.95.31.188)  4.170 ms 52.95.31.172 (52.95.31.172)  3.172 ms
16  52.95.31.86 (52.95.31.86)  2.249 ms 52.95.31.72 (52.95.31.72)  3.035 ms  2.943 ms
17  27.0.0.158 (27.0.0.158)  2.431 ms * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  ec2-13-115-18-61.ap-northeast-1.compute.amazonaws.com (13.115.18.61)  1.688 ms  2.683 ms  2.617 ms
24  ec2-13-115-18-61.ap-northeast-1.compute.amazonaws.com (13.115.18.61)  1.945 ms  2.926 ms  2.171 ms

いけた 🎉