記事・メモ一覧

default eye-catch image.

AWS常時SSL リダイレクトループしない.htaccessの書き方

HTTPSを強制するために .htaccess に細工をするのは有名。例えば以下のような書き方が王道。 RewriteEngine on RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L] これをそのままElasticBeanstalkにデプロイするとリダイレクトループが発生する。正確に書くとリバースプロキシ(ロードバランサ)が有効になっている場合にリダイレクトループが発生する。 原因 原因についてはココが詳しい。ざっくりまとめると、 ロードバランサが443へのアクセスを80へのアクセスに変換する .htaccess内の RewriteCond ${HTTPS} が永遠に on にならず、リダイレクトの度にRewriteRule が走ってしまう 元々のアクセスが https か http のどちらかが分かれば良いのだが、上記の挙動のせいで、https にリダイレクトしたとしても http からアクセスされたことになり、これが永遠に繰り返されてしまう。 解決策 (記事主さんが)無茶苦茶泥臭く挙動を追跡したところ、ロードバランサに到着した元のアクセスが http のときに限り、X-Forwarded-Proto というヘッダが付与され値が入るらしい。なので、X-Forwarded-Protoヘッダの内容を http か https かの判断基準にすれば良い、というのが基本的なアイデア。本人も言っているが、it\'s just an empiric result... である。 その .htaccess が以下 RewriteEngine On # Force HTTPS RewriteCond %{HTTP:X-Forwarded-Proto} !=https RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R,L] これを ElasticBeanstalkにデプロイすると見事に動作する。 [arst_adsense slotnumber=\"1\"] 開発環境との共存 開発もAWSで行っていればこれで良いのだがそうでない場合も多いと思う。 上記のAWS用.htaccessを非AWSな開発環境に持ってくると今度は RewriteCond %{HTTP:X-Forwarded-Proto} !https が常に真になり、リダイレクトループが発生する。 あっちが立てばこっちが立たない! いろいろ試行錯誤した結果、以下なら両立できた。(2017/7/8訂正) RewriteEngine On # Force HTTPS RewriteCond %{HTTPS} !=on RewriteCond %{HTTP:X-Forwarded-Proto} !=https RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R,L] 根拠となる X-Forwarded-Proto がとっても経験的!なので、いつの日か使えなくなる日が来るかもしれない。 [arst_adsense slotnumber=\"1\"]

default eye-catch image.

無料でSSL/TLC証明書を手に入れる EC2/ElasticBeanstalk編

Certbotを使って Conoha+Kusanagi(nginx/centos7) に無料でSSL/TLC証明書をインストール・自動更新する方法は過去に書いた。\"無料でSSL/TLC証明書を手に入れる\" CertbotサイトにOSとWebサーバの組み合わせを入力すると対応するインストール手順が表示される。メジャーな組み合わせであれば証明書の取得から自動更新まで全自動でやってくれる。 2016年7月現在、AWS(EC2)は未対応のため、Certbotツールを使って試行錯誤する必要がある。Certbotの一次情報をもとに何とかやってみたので記録を残しておく。 AWS(EC2)にCertbotでSSL/TLC証明書をインストールする ElasticBeanstalkのロードバランサに取得した証明書を登録しhttpsでアクセスできるようにする 自動更新のセットアップを行う AWS(EC2)にCertbotを使ってSSL/TLC証明書をインストールする いくつか前提がある。 ドメインは取得済みであること。 ドメインがElasticBeanstalkのIPアドレスを指すようにRoute53を設定済みであること。 EC2インスタンスにSSHでログインできるようにしておく。 Certbot利用時、外部からEC2インスタンスにhttpでアクセスを受ける。ElasticBeanstalkにRoutingを変更するようなアプリがデプロイされているとアクセスが失敗するのでDocumentRootにindex.phpがあるだけという状態にしておく。 SSL/TLC証明書をインストールするだけなら443番を開けておく必要はない。ロードバランサはデフォルトの80番だけ開けていれば良い EC2インスタンスのrootパスワードが設定済みであること AWS CLIがインストール済みであること。 IAMで証明書登録ポリシーを付与済みであること。 さっそくEC2インスタンスにログイン。基本的にec2-userで作業する。 一応下記を実行。 $ sudo yum install epel-release Loaded plugins: priorities, update-motd, upgrade-helper Package epel-release-6-8.9.amzn1.noarch already installed and latest version Nothing to do Certbotをダウンロードする。 $ wget https://dl.eff.org/certbot-auto $ chmod a+x certbot-auto Certbotを実行してみる。その際、--debugオプションを付けないと怒られる。would like to work on improving it と言っておきながら --debug がmust。きっと実行内容がCertbotに送られるのだろう。 $ ./certbot-auto WARNING: Amazon Linux support is very experimental at present... if you would like to work on improving it, please ensure you have backups and then run this script again with the --debug flag! 指示通り、--debugオプションを付けて実行してみる。 $ ./certbot-auto --debug ... Installed: augeas-libs.x86_64 0:1.0.0-5.7.amzn1 dialog.x86_64 0:1.1-9.20080819.1.5.amzn1 libffi-devel.x86_64 0:3.0.13-11.4.amzn1 python27-tools.x86_64 0:2.7.10-4.120.amzn1 system-rpm-config.noarch 0:9.0.3-42.27.amzn1 Complete! Creating virtual environment... Installing Python packages... Installation succeeded. Requesting root privileges to run certbot... /home/ec2-user/.local/share/letsencrypt/bin/letsencrypt --debug Version: 1.1-20080819 Version: 1.1-20080819 No installers are available on your OS yet; try running \"letsencrypt-auto certonly\" to get a cert you can install manually いろいろインストールされる。/home/ec2-user/.local/share/letsencrypt/ 以下にPython27 が入る。今回の試行錯誤では自力でPythonを上げなかった。たぶん、自力でPythonのバージョンを上げなくてもコレが使われるんじゃないか。 肝心のインストーラはインストールされず、\"letsencrypt-auto certonly\"というコマンドを実行せよ、と出る。が、これはtypo。 No installers are available on your OS yet; try running \"letsencrypt-auto certonly\" to get a cert you can install manually ディレクトリを移動する。 $ cd /home/ec2-user/.local/share/letsencrypt/bin ここにある certbot コマンドを叩く。ドメイン名、メールアドレスを指定する。 sudo ./certbot certonly -d hoge.com --agree-tos -m hoge@hoge.com --debug すると、中途半端にグラフィカルな画面が表示される。簡易Webサーバを起動するか、現在のWebサーバのDocumentRootを教えるか、2択となる。簡易Webサーバだとどうしても上手くいかなかった。Webサーバを上げたまま(ElasticBeanstalkのヘルスチェックがOKの状態)、DocumentRootを指定すると上手くいった。 うまくいくと、以下のようなメッセージが表示される。 IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/arst.me/fullchain.pem. Your cert will expire on 2016-09-29. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run \"certbot renew\" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let\'s Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le /etc/letsencrypt/live に証明書が作られている。なお、live には ec2-user でアクセスできない。ここでrootに昇格。 $ su - # cd /etc/letsencrypt/live # ls hoge.com # cd hoge.com # ls cert.pem chain.pem fullchain.pem privkey.pem ElasticBeanstalkのロードバランサに証明書を登録する AWS CLI経由で証明書を登録する。その際、IAMにてポリシーを追加しておく必要がある。過去エントリを参照のこと。成功するとJSONで登録情報が返る。ここでは、HogeCertification という名前で登録を行っている。 $ aws iam upload-server-certificate --server-certificate-name HogeCertification --certificate-body file://cert.pem --private-key file://privkey.pem { \"ServerCertificateMetadata\": { \"ServerCertificateId\": \"ASCAI***********A6F5GI\", \"ServerCertificateName\": \"HogeCertification\", \"Expiration\": \"2016-09-29T01:57:00Z\", \"Path\": \"/\", \"Arn\": \"arn:aws:iam::281631559249:server-certificate/HogeCertification\", \"UploadDate\": \"2016-07-01T03:10:18.440Z\" } } ElasticBeanstalkのロードバランサの設定で、証明書欄から HogeCertification を選べるようになる。選んで 443/HTTPS を通すようにすれば、晴れて https://独自ドメイン/ で ElasticBeanstalk の URL が開く。 証明書の自動更新 更新自体はcertbot renewコマンドで行う。certbot renewコマンドは/var/www/html/.well-known/以下にファイルを置いて外部から開きにくる。困ったことに、CakePHPやLaravelアプリをデプロイしているとフレームワークのルーティング機能により上手くいかない。 以下の戦略で対応する。 certbot renew 時だけ、DocumentRoot を アプリ用からcertbot用に切り替える Laravel等のように DocumentRoot がサブディレクトリにオフセットされている場合に対応する ElasticBeanstalkで自動生成される環境を見ると、/var/www/html が /var/app/current へのシンボリックリンクとなっている。Certbot renew を叩くときだけ、シンボリックリンクを差し替える。 $ cd /var/app $ sudo mkdir -p certbot/project/public $ sudo chown -R webapp:webapp certbot $ cd /var/www $ sudo ln -s -f /var/app/certbot html また、certbot用の.well-knownディレクトリが /var/www/html 直下に作られる仕様になっている。DocumentRootはさらに project/public にオフセットされているため、/var/www/html/project/public/.well-known が /var/www/html/.well-known を指すようにシンボリックリンクを作成する。 $ cd /var/app/certbot/project/public $ sudo ln -s ../../.well-known この状態で certbot renew --dry-run を叩くと無事成功する。 $ pwd /home/ec2-user/.local/share/letsencrypt/bin $ sudo certbot renew --dry-run ** DRY RUN: simulating \'certbot renew\' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/ikuty.com/fullchain.pem (success) ** DRY RUN: simulating \'certbot renew\' close to cert expiry ** (The test certificates above have not been saved.) シンボリックリンクの作成は一度だけで良いが、アプリ用とCertbot用のシンボリックリンク張替は都度必要となる。 以下のシェルスクリプトをcronで叩けば良い。 #!/bin/bash cd /var/www sudo unlink html sudo ln -s -f /var/app/certbot html cd ~ pwd sudo ./.local/share/letsencrypt/bin/certbot renew --debug cd /var/www sudo unlink /var/www/html sudo ln -s -f /var/app/current html 不要な更新は実行されないため、1日2回の頻度で実行してよい旨、ドキュメントに記述がある。 Note: if you’re setting up a cron or systemd job, we recommend running it twice per day (it won’t do anything until your certificates are due for renewal or revoked, but running it regularly would give your site a chance of staying online in case a Let’s Encrypt-initiated revocation happened for some reason). Please select a random minute within the hour for your renewal tasks.

default eye-catch image.

VPC内にElastic Beanstalk + RDS の環境を構築して Laravel アプリをデプロイする [Laravel5アプリデプロイ編]

今後も何度か同じことを調べそうなので忘備録としてまとめておく。手順をstep by stepで記述するが、それぞれ分量が多いので以下の通り章立てを行ってエントリを分割する。 VPC構築編 VPCの作成 VPC、NetworkACL、SecurityGroupの確認、タグ付け VPCのDNSホスト名を有効にする サブネットの作成、タグ付け インターネットゲートウェイの作成、タグ付け、VPCにアタッチ パブリックサブネット用RoutingTableの作成 パブリックサブネット用RoutingTableにインターネットゲートウェイの関連付け 作成したサブネットをパブリックサブネット用RoutingTableに繋ぎかえる RDS構築編 MySQLの設定変更(DBパラメータグループの作成) DBサブネットグループを作成 RDS用セキュリティグループの作成 RDSインスタンスの作成 エンドポイントの確認、疎通確認 Elastic Beanstalk構築編 環境の構築 .ebextensionsによるカスタマイズ Laravel5アプリデプロイ編(本エントリ) gitリポジトリからclone .envの編集 アプリで使うDBのダンプファイルをRDSにコピー Laravelインストーラの準備 Laravel本体のインストール ビルトインサーバでの疎通確認 Elastic Beanstalkへのデプロイ gitリポジトリからclone 通常 Laravel5 にはデフォルトの .gitignore が作られており、Laravel本体は.gitignoreに登録されている。まず、アプリをcloneし、そのあとでLaravel本体をインストールする。 どこか、Laravel5の要件を満たすところでgitリポジトリからcloneする。 $ pwd /home/ikuty/www/ $ git clone ssh://servername/var/git/project.git project .envの編集 アプリケーションの設定を変更する。/config 内に各種設定ファイルが配置されているが、laravelでは.envを変更することで /config内のenv()関数に展開される仕組みになっている。だから、/config 内の各種ファイルを直接変更する必要はない。/config 内も git の構成管理に含めても良い。 cloneした先でenvを編集する。.env_example をリネームすると楽。 APP_KEY= *** 次項で示すようにキーを生成する DB_HOST : RDS編で設定したRDSエンドポイントを指定する DB_DATABASE, USERNAME, PASSWORD : RDS編で設定した各種設定を指定する APP_ENV=local APP_DEBUG=true APP_KEY=**** APP_URL=http://hoge.com/ DB_CONNECTION=mysql DB_HOST=rds-endpoint DB_PORT=3306 DB_DATABASE=hogedb DB_USERNAME=hoge DB_PASSWORD=fuga CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=sync キーを生成する。以下のコマンドで .env の APP_KEY が差し替わる。 $ php artisan key:generate アプリで使うDBのダンプファイルをRDSにコピー 本来は Migration を使うべきだが...。Migration を利用しないでDBを作ってしまった場合は泥臭くやる...;;まず、ダンプ。 $ mysqldump -u hoge -p appdb > appdb.sql RDS側にDBを作成し権限を付与しておく。 $ mysql -h [rds-endpoint] -u hoge -p $ > CREATE DATABSE appdb; $ > GRANT ALL ON appdb.* to hoge@localhost; $ > FLUSH PRIVILEGES; $ > SHOW DATABSES; $ > ... RDS上のDBにダンプしたsqlを流し込む。 $ mysql -h [rds-endpoint] -u hoge -p -D appdb < appdb.sql Laravelインストーラの準備 composerを利用する。パスを通す。本エントリ作成時の最新は version1.3.3。 $ composer global require \"laravel/installer=~1.1\" $ echo \'export PATH=~/.composer/vendor/laravel/installer:$PATH\' >> ~/.bash_profile $ source .bash_profile $ laravel Laravel Installer version 1.3.3 Laravel本体のインストール composerが準備できたらcomposer installでLaravel本体をインストールする。 $ cd project $ composer install ビルトインサーバでの疎通確認 この状態でビルトインサーバを立ち上げ、疎通確認を行う。 $ cd project php artisan serve --host hoge.com Laravel development server started on http://hoge.com:8000/ Elastic Beanstalkへのデプロイ Elastic Beanstalk構築編にて、環境の準備が出来ているものとする。 eb deploy コマンドにより、カレントディレクトリ以下のファイルをデプロイする。また、.ebextension に DocumentRoot を設定する。カレントディレクトリと DocumentRoot の組み合わせを正しく設定する必要がある。 まず、DocumentRootを設定するため、.ebextensionディレクトリを作成し、設定ファイルを作成する。 $ pwd /home/ikuty/www/ $ mkdir .ebextensions $ cd .ebextensions $ vi 01_documentroot.config 01.documentroot_config は以下の通り。YAMLとして記述する必要がある。空白とタブの扱いがシビアなので、タブが入らないように注意する。ファイルの先頭の\"01\" は、ファイルが解釈される順番を表す。.ebextensions 内に、01,02,... のように設定を複数配置できる。 option_settings: - namespace: aws:elasticbeanstalk:container:php:phpini option_name: document_root value: /project/public DocumentRoot を /project/public と設定した場合に正しい構成になるように、カレントディレクトリを移動し、eb deployを実行する。~/www に移動して、/project 以下をデプロイすれば良い。 $ cd ~/www/ $ eb deploy Creating application version archive \"app-160630_130423\". Uploading: [##################################################] 100% Done... INFO: Environment update is starting. INFO: Deploying new version to instance(s). INFO: New application version was deployed to running EC2 instances. INFO: Environment update completed successfully. 設定が正しければ2分弱で完了する。

default eye-catch image.

VPC内にElastic Beanstalk + RDS の環境を構築して Laravel アプリをデプロイする [ElasticBeanstalk構築編]

今後も何度か同じことを調べそうなので忘備録としてまとめておく。手順をstep by stepで記述するが、それぞれ分量が多いので以下の通り章立てを行ってエントリを分割する。 VPC構築編 VPCの作成 VPC、NetworkACL、SecurityGroupの確認、タグ付け VPCのDNSホスト名を有効にする サブネットの作成、タグ付け インターネットゲートウェイの作成、タグ付け、VPCにアタッチ パブリックサブネット用RoutingTableの作成 パブリックサブネット用RoutingTableにインターネットゲートウェイの関連付け 作成したサブネットをパブリックサブネット用RoutingTableに繋ぎかえる RDS構築編 MySQLの設定変更(DBパラメータグループの作成) DBサブネットグループを作成 RDS用セキュリティグループの作成 RDSインスタンスの作成 エンドポイントの確認、疎通確認 Elastic Beanstalk構築編(本エントリ) 環境の構築 .ebextensionsによるカスタマイズ Laravel5アプリデプロイ編 gitリポジトリからclone .envの編集 アプリで使うDBのダンプファイルをRDSにコピー Laravelインストーラの準備 Laravel本体のインストール ビルトインサーバでの疎通確認 Elastic Beanstalkへのデプロイ 環境の構築 Elastic Beanstalk の各インスタンスを収める「環境」を作成する。この「環境」の中に、これまで作ってきたVPCの要素を追加する。 $ eb create hoge-production --sample # アプリケーションのデプロイは後で行う。今はSampleアプリケーションをデプロイ --cname com-sample-production --instance_type t2.micro --region ap-northeast-1 --tier webserver --vpc.ec2subnets subnet-b71eeac1 #VPCに作成したパブリックサブネット --vpc.elbsubnets subnet-b71eeac1 #VPCに作成したパブリックサブネット(同じにする) --vpc.id vpc-cc2b11a9 --vpc.securitygroups sg-23fe8447 #デフォルトセキュリティグループ --vpc.publicip --vpc.elbpublic 3分から5分程度時間を要する。 作成した環境のURLを開く $eb open http://com-sample-production.ap-northeast-1.elasticbeanstalk.com/ .ebextensionsによるカスタマイズ Laravel5アプリケーションをデプロイするにあたって、環境をカスタマイズする。(qiitaを参考にした) $ pwd /home/ikuty/www $ mkdir .ebextensions $ cd .ebextensions # timezoneを変更する vi 01_settimezone.config 各ファイルは以下の通り。なお、各ファイルは yaml形式であり、空白とタブの扱いがシビア。タブでインデントすると簡単に謎のエラーに悩まされる。空文字はタブではなく半角スペース。 01_settimezone.config command: 01-set_timezone: command: cp /usr/share/zoneinfo/Japan /etc/localtime

default eye-catch image.

VPC内にElastic Beanstalk + RDS の環境を構築して Laravel アプリをデプロイする [RDS構築編]

今後も何度か同じことを調べそうなので忘備録としてまとめておく。手順をstep by stepで記述するが、それぞれ分量が多いので以下の通り章立てを行ってエントリを分割する。 VPC構築編 VPCの作成 VPC、NetworkACL、SecurityGroupの確認、タグ付け VPCのDNSホスト名を有効にする サブネットの作成、タグ付け インターネットゲートウェイの作成、タグ付け、VPCにアタッチ パブリックサブネット用RoutingTableの作成 パブリックサブネット用RoutingTableにインターネットゲートウェイの関連付け 作成したサブネットをパブリックサブネット用RoutingTableに繋ぎかえる RDS構築編(本エントリ) MySQLの設定変更(DBパラメータグループの作成) DBサブネットグループを作成 RDS用セキュリティグループの作成 RDSインスタンスの作成 エンドポイントの確認、疎通確認 Elastic Beanstalk構築編 環境の構築 .ebextensionsによるカスタマイズ Laravel5アプリデプロイ編 gitリポジトリからclone .envの編集 アプリで使うDBのダンプファイルをRDSにコピー Laravelインストーラの準備 Laravel本体のインストール ビルトインサーバでの疎通確認 Elastic Beanstalkへのデプロイ MySQLの設定変更 my.cnf等のコンフィグファイルに記述していた内容をRDS風に記述する。RDSでは「DBパラメータ」に設定を記述していく。まず、DBパラメータを作成する。 $ aws rds create-db-parameter-group --db-parameter-group-name mydbparamgroup --db-parameter-group-family mysql5.6 --description \"public rds\" { \"DBParameterGroup\": { \"DBParameterGroupName\": \"mydbparamgroup\", \"DBParameterGroupFamily\": \"mysql5.6\", \"Description\": \"public rds\" } } 文字コード関連の設定 $ aws rds modify-db-parameter-group --db-parameter-group-name --parameters ParameterName=character_set_client,ParameterValue=utf8mb4,ApplyMethod=immediate ParameterName=character_set_connection,ParameterValue=utf8mb4,ApplyMethod=immediate ParameterName=character_set_database,ParameterValue=utf8mb4,ApplyMethod=immediate ParameterName=character_set_results,ParameterValue=utf8mb4,ApplyMethod=immediate ParameterName=character_set_server,ParameterValue=utf8mb4,ApplyMethod=immediate ParameterName=collation_connection,ParameterValue=utf8mb4_general_ci,ApplyMethod=immediate ParameterName=collation_server,ParameterValue=utf8mb4_general_ci,ApplyMethod=immediate ParameterName=skip-character-set-client-handshake,ParameterValue=0,ApplyMethod=pending-reboot init_connectパラメータの設定。デフォルトの設定をファイルに落とし、ファイルを変更する。 $ aws rds modify-db-parameter-group --generate-cli-skeleton > init_connect.json # 変更後 $ cat init_connect.json { \"DBParameterGroupName\": \"\", \"Parameters\": [ { \"ParameterName\": \"\", \"ParameterValue\": \"\", \"Description\": \"\", \"Source\": \"\", \"ApplyType\": \"\", \"DataType\": \"\", \"AllowedValues\": \"\", \"IsModifiable\": true, \"MinimumEngineVersion\": \"\", \"ApplyMethod\": \"\" } ] } # 出力された設定ファイルを変更する $ vi init_connect.json # 変更内容は以下の通り $ cat init_connect.json { \"DBParameterGroupName\": \"mydbparamgroup\", \"Parameters\": [ { \"ParameterName\": \"init_connect\", \"ParameterValue\": \"SET SESSION time_zone = CASE WHEN POSITION(\'rds\' IN CURRENT_USER()) = 1 THEN \'UTC\' ELSE \'Asia/Tokyo\' END;\", \"Description\": \"\", \"Source\": \"\", \"ApplyType\": \"\", \"DataType\": \"\", \"AllowedValues\": \"\", \"IsModifiable\": true, \"MinimumEngineVersion\": \"\", \"ApplyMethod\": \"immediate\" } ] } # 設定ファイルを読み込む $ aws rds modify-db-parameter-group --cli-input-json file://init_connect.json { \"DBParameterGroupName\": \"mydbparamgroup\" } DBサブネットグループを作成 DB構築編にてAvailabilityZoneが異なるDB用サブネットを2個作成した。それぞれID/tagは\"subnet-131feb65\"/\"subnet public db1\"、\"subnet-d6d2d38f\"/\"subnet public db2\"であった。 DB サブネットグループmydbsubnetgroupを作成する。 aws rds create-db-subnet-group --db-subnet-group-name mydbsubnetgroup --db-subnet-group-description \"DB SubnetGroup for RDS Instance\" --subnet-ids subnet-131feb65 subnet-d6d2d38f { \"DBSubnetGroup\": { \"Subnets\": [ { \"SubnetStatus\": \"Active\", \"SubnetIdentifier\": \"subnet-131feb65\", \"SubnetAvailabilityZone\": { \"Name\": \"ap-northeast-1a\" } }, { \"SubnetStatus\": \"Active\", \"SubnetIdentifier\": \"subnet-d6d2d38f\", \"SubnetAvailabilityZone\": { \"Name\": \"ap-northeast-1c\" } } ], \"DBSubnetGroupName\": \"mydbsubnetgroup\", \"VpcId\": \"vpc-cc2b11a9\", \"DBSubnetGroupDescription\": \"DB SubnetGroup for RDS Instance\", \"SubnetGroupStatus\": \"Complete\" } } RDS用セキュリティグループの作成 RDS用セキュリティグループ myrds を作成する。 $ aws ec2 create-security-group --group-name myrds --description \"RDS security group\" --vpc-id vpc-cc2b11a9 { \"GroupId\": \"sg-b50742d1\" } #タグ付け $ aws ec2 create-tags --resources sg-b50742d1 --tags Key=Name,Value=\"sg rds\" RDS MySQLにVPCから接続するために、RDS用セキュリティグループに3306からのInbound許可設定を行う。(作成済のVPCセキュリティグループのIDはsg-73490c17。) $ aws ec2 authorize-security-group-ingress --group-id sg-b50742d1 --protocol tcp --port 3306 --source-group sg-73490c17 [参考] 下記のようにCIDR標記のアドレスを指定するとVPCの外部からも接続可能になる。 $ aws ec2 authorize-security-group-ingress --group-id sg-b50742d1 --protocol tcp --port 3306 --cidr 0.0.0.0/0 RDSインスタンスの作成 DBパラメータグループ、デフォルトセキュリティグループ、RDS用セキュリティグループを指定する。 外部からの接続を許可する場合 -- publicly-accessible を指定する必要がある。 $ aws rds create-db-instance --db-instance-identifier hogedb --allocated-storage 5 --db-instance-class db.t2.micro --engine MySQL --engine-version 5.6.22 --master-username hoge --master-user-password fuga --db-name hogedb --db-parameter-group-name mydbparamgroup --db-subnet-group-name mydbsubnetgroup --vpc-security-group-ids sg-23fe8447 sg-b50742d1 --storage-type standard --availability-zone ap-northeast-1a --no-multi-az --region ap-northeast-1 --publicly-accessible --no-auto-minor-version-upgrade 疎通確認 エンドポイントを確認する。予めjqコマンドを利用可能にしておくこと。 # jqがない場合 $ sudo yum install jq $ aws rds describe-db-instances --db-instance-identifier hogedb | jq \'.DBInstances[].Endpoint\' { \"Address\": \"hogedb.c3w6*******5990.ap-northeast-1.rds.amazonaws.com\", \"Port\": 3306 } PublicIp、PublicDnsName を確認する。 $ aws ec2 describe-network-interfaces --filters \"Name=description,Values=RDSNetworkInterface\" { .. \"Description\": \"RDSNetworkInterface\", \"Association\": { \"PublicIp\": \"54.95.100.249\", \"PublicDnsName\": \"ec2-54-92-100-249.ap-northeast-1.compute.amazonaws.com\", \"IpOwnerId\": \"amazon-rds\" }, .. } mysql コマンドでエンドポイントに接続してみる。 $ mysql -h 54.95.100.249 -P 3306 -u hoge -p -D hogedb Enter password: fuga Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 9 Server version: 5.6.22-log MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. ...

default eye-catch image.

VPC内にElastic Beanstalk + RDS の環境を構築して Laravel アプリをデプロイする [VPC作成編]

今後も何度か同じことを調べそうなので忘備録としてまとめておく。手順をstep by stepで記述するが、それぞれ分量が多いので以下の通り章立てを行ってエントリを分割する。 VPC構築編(本エントリ) VPCの作成 VPC、NetworkACL、SecurityGroupの確認、タグ付け VPCのDNSホスト名を有効にする サブネットの作成、タグ付け インターネットゲートウェイの作成、タグ付け、VPCにアタッチ パブリックサブネット用RoutingTableの作成 パブリックサブネット用RoutingTableにインターネットゲートウェイの関連付け 作成したサブネットをパブリックサブネット用RoutingTableに繋ぎかえる RDS構築編 MySQLの設定変更(DBパラメータグループの作成) DBサブネットグループを作成 RDS用セキュリティグループの作成 RDSインスタンスの作成 エンドポイントの確認、疎通確認 Elastic Beanstalk構築編 環境の構築 .ebextensionsによるカスタマイズ Laravel5アプリデプロイ編 gitリポジトリからclone .envの編集 アプリで使うDBのダンプファイルをRDSにコピー Laravelインストーラの準備 Laravel本体のインストール ビルトインサーバでの疎通確認 Elastic Beanstalkへのデプロイ 前提 aws cli, eb-cli をインストールしておくこと。 $ pwd /home/ikuty $ aws --version aws-cli/1.10.37 Python/2.6.6 Linux/2.6.32-573.22.1.el6.x86_64 botocore/1.4.27 $ eb --version EB CLI 3.7.6 (Python 2.7.9) Administrator AccessポリシーをもつユーザをIAMで作成し、aws-cli から該当ユーザの権限で操作できるようにしておくこと。 $ aws configure AWS Access Key ID [****************] AWS Secret Key [***********************] Default region name [ap-northeast-1] Default output format [json] VPCの環境構築 VPCを作成する。アドレスの範囲をCIDR標記で記述する。ネットワーク部を16bit取る。 vpc-cc2b11a9というIDのVPCが作成されたという報告がjsonで戻る。 $ aws ec2 create-vpc --cidr-block 10.0.0.0/16 { \"Vpc\": { \"VpcId\": \"vpc-cc2b11a9\", \"InstanceTenancy\": \"default\", \"State\": \"pending\", \"DhcpOptionsId\": \"dopt-fec65c9b\", \"CidrBlock\": \"10.0.0.0/16\", \"IsDefault\": false } } vpc-cc2b11a9というVPCにNameタグを付与する。 $ aws ec2 create-tags --resources vpc-cc2b11a9 --tags Key=Name,Value=\"vpc\" VPCとは、クラウド上に閉じたネットワークを構築する機能であり、VPC作成時に、閉じたネットワークを構成する要素が同時に生成される。構成要素は以下の通り。 Routing Table Subnet Network ACL Security group なお、Network ACL、Security group について AWS のドキュメントでは以下の通り説明している。 Amazon VPCのネットワークACL(アクセスコントロールリスト)は、サブネット内外のトラフィックを制御するファイアウォールとして任意のセキュリティを提供します。セキュリティグループの設定と同じようにACLのルールを適応することによって、VPCに追加のセキュリティ層を提供します。EC2はサブネット指定ができませんのでネットワークACLを利用することはできません。 なんのこっちゃ、だが、図を見ると一目瞭然である。NetworkACLを使ってサブネット毎にファイアウォールを定義できる! NetworkACL、SecurityGroupいずれもファイアウォールのように見えるが、以下のような違いがある。 セキュリティグループ ネットワーク ACL インスタンスレベルで動作します(第 1 保護レイヤー) サブネットレベルで動作します(第 2 保護レイヤー) ルールの許可のみがサポートされます ルールの許可と拒否がサポートされます ステートフル: ルールに関係なく、返されたトラフィックが自動的に許可されます ステートレス: 返されたトラフィックがルールによって明示的に許可されます トラフィックを許可するかどうかを決める前に、すべてのルールを評価します トラフィックを許可するかどうかを決めるときに、順番にルールを処理します インスタンスの起動時に誰かがセキュリティグループを指定した場合、または後でセキュリティグループをインスタンスに関連付けた場合にのみ、インスタンスに適用されます。 関連付けられたサブネット内のすべてのインスタンスに自動的に適用されます(バックアップの保護レイヤーなので、セキュリティグループを指定する人物に依存する必要はありません) Routing tableにタグをつける vpc-cc2b11a9というIDを持ったVPCのRouting tableを確認する。rtb-964da5f2というIDを持ったRouting tableを確認できる。 $ aws ec2 describe-route-tables --filters \"Name=vpc-id,Values=vpc-cc2b11a9\" { \"RouteTables\": [ { \"Associations\": [ { \"RouteTableAssociationId\": \"rtbassoc-b2fd42d6\", \"Main\": true, \"RouteTableId\": \"rtb-964da5f2\" } ], \"RouteTableId\": \"rtb-964da5f2\", \"VpcId\": \"vpc-cc2b11a9\", \"PropagatingVgws\": [], \"Tags\": [], \"Routes\": [ { \"GatewayId\": \"local\", \"DestinationCidrBlock\": \"10.0.0.0/16\", \"State\": \"active\", \"Origin\": \"CreateRouteTable\" } ] } ] } $ aws ec2 create-tags --resources rtb-964da5f2 --tags Key=Name,Value=\"rtb main\" NetworkACLにタグをつける $ aws ec2 describe-network-acls --filters \"Name=vpc-id,Values=vpc-cc2b11a9\" { \"NetworkAcls\": [ { \"Associations\": [], \"NetworkAclId\": \"acl-25fb1a41\", \"VpcId\": \"vpc-cc2b11a9\", \"Tags\": [], \"Entries\": [ { \"CidrBlock\": \"0.0.0.0/0\", \"RuleNumber\": 100, \"Protocol\": \"-1\", \"Egress\": true, \"RuleAction\": \"allow\" }, { \"CidrBlock\": \"0.0.0.0/0\", \"RuleNumber\": 32767, \"Protocol\": \"-1\", \"Egress\": true, \"RuleAction\": \"deny\" }, { \"CidrBlock\": \"0.0.0.0/0\", \"RuleNumber\": 100, \"Protocol\": \"-1\", \"Egress\": false, \"RuleAction\": \"allow\" }, { \"CidrBlock\": \"0.0.0.0/0\", \"RuleNumber\": 32767, \"Protocol\": \"-1\", \"Egress\": false, \"RuleAction\": \"deny\" } ], \"IsDefault\": true } ] } $ aws ec2 create-tags --resources acl-25fb1a41 --tags Key=Name,Value=\"acl main\" SecurityGroupにタグをつける SecurityGroupを確認する。ID=sg-23fe8447というSecurityGroupが存在することがわかる。 $ aws ec2 describe-security-groups --filters \"Name=vpc-id,Values=vpc-cc2b11a9\" { \"SecurityGroups\": [ { \"IpPermissionsEgress\": [ { \"IpProtocol\": \"-1\", \"IpRanges\": [ { \"CidrIp\": \"0.0.0.0/0\" } ], \"UserIdGroupPairs\": [], \"PrefixListIds\": [] } ], \"Description\": \"default VPC security group\", \"IpPermissions\": [ { \"IpProtocol\": \"-1\", \"IpRanges\": [], \"UserIdGroupPairs\": [ { \"UserId\": \"281631559249\", \"GroupId\": \"sg-23fe8447\" } ], \"PrefixListIds\": [] } ], \"GroupName\": \"default\", \"VpcId\": \"vpc-cc2b11a9\", \"OwnerId\": \"281631559249\", \"GroupId\": \"sg-23fe8447\" } ] } $ aws ec2 create-tags --resources sg-23fe8447 --tags Key=Name,Value=\"sg main\" VPCのDNSホスト名を有効にする VPC内のRDSに外部から接続できるようにDNSホスト名を有効にする。 #有効にする $ aws ec2 modify-vpc-attribute --vpc-id vpc-cc2b11a9 --enable-dns-hostnames #確認する $ aws ec2 describe-vpc-attribute --vpc-id vpc-cc2b11a9 --attribute enableDnsHostnames { \"VpcId\": \"vpc-cc2b11a9\", \"EnableDnsHostnames\": { \"Value\": true } } サブネットを作成する 最初のVPC作成時に、16ビットをネットワーク部として使う意図で、CIDR標記で/16を設定した。さらに、8ビットをサブネットとして利用するため、CIDR標記で/24を設定する。8ビット分(第3オクテット分)がサブネットとして利用でき、そのうち .0、.1、.2 のサブネットを作成する。第4オクテットがホスト部となるが、8ビット全て利用することはできず、利用できる最大数がそれぞれ\"AvailableIpAddressCount\"に書かれてる。なお、各サブネットにそれぞれIDが振られる。 RDSをMultiAZで運用しない場合でもDBサブネットグループを作成する際に2つのAvailabilityZoneが必要なので異なるAvailabilityZoneに対応するサブネットを作成する。 $ aws ec2 create-subnet --vpc-id vpc-cc2b11a9 --cidr-block 10.0.0.0/24 --availability-zone ap-northeast-1a { \"Subnet\": { \"VpcId\": \"vpc-cc2b11a9\", \"CidrBlock\": \"10.0.0.0/24\", \"State\": \"pending\", \"AvailabilityZone\": \"ap-northeast-1a\", \"SubnetId\": \"subnet-b71eeac1\", \"AvailableIpAddressCount\": 251 } } # ap-northeast-1a AvailabilityZone $ aws ec2 create-subnet --vpc-id vpc-cc2b11a9 --cidr-block 10.0.1.0/24 --availability-zone ap-northeast-1a { \"Subnet\": { \"VpcId\": \"vpc-cc2b11a9\", \"CidrBlock\": \"10.0.1.0/24\", \"State\": \"pending\", \"AvailabilityZone\": \"ap-northeast-1a\", \"SubnetId\": \"subnet-131feb65\", \"AvailableIpAddressCount\": 251 } } # ap-northeast-1c AvailabitliyZone $ aws ec2 create-subnet --vpc-id vpc-cc2b11a9 --cidr-block 10.0.2.0/24 --availability-zone ap-northeast-1c { \"Subnet\": { \"VpcId\": \"vpc-cc2b11a9\", \"CidrBlock\": \"10.0.2.0/24\", \"State\": \"pending\", \"AvailabilityZone\": \"ap-northeast-1c\", \"SubnetId\": \"subnet-d6d2d38f\", \"AvailableIpAddressCount\": 251 } } サブネットにタグを付与する 作成したサブネットには、それぞれ、subnet-b71eeac1、subnet-131feb65、subnet-d6d2d38f というIDが振られている。それぞれにタグを付与する。 $ aws ec2 create-tags --resources subnet-b71eeac1 --tags Key=Name,Value=\"subnet public web\" $ aws ec2 create-tags --resources subnet-131feb65 --tags Key=Name,Value=\"subnet public db1\" $ aws ec2 create-tags --resources subnet-d6d2d38f --tags Key=Name,Value=\"subnet public db2\" インターネットゲートウェイの作成 インターネットゲートウェイを作成し、タグを付与する。 $ aws ec2 create-internet-gateway { \"InternetGateway\": { \"Tags\": [], \"InternetGatewayId\": \"igw-5bb8203e\", \"Attachments\": [] } } $ aws ec2 create-tags --resources igw-5bb8203e --tags Key=Name,Value=\"igw main\" インターネットゲートウェイをVPCにアタッチする。 #アタッチ $ aws ec2 attach-internet-gateway --internet-gateway-id igw-5bb8203e --vpc-id vpc-cc2b11a9 #確認 $ aws ec2 describe-internet-gateways --internet-gateway-id igw-5bb8203e { \"InternetGateways\": [ { \"Tags\": [ { \"Value\": \"igw main\", \"Key\": \"Name\" } ], \"InternetGatewayId\": \"igw-5bb8203e\", \"Attachments\": [ { \"State\": \"available\", \"VpcId\": \"vpc-cc2b11a9\" } ] } ] } パブリックサブネット用のRoutingTableを作成する VPC作成時に\"rtb-964da5f2\"というIDを持つRoutingTableが作成されていることを確認した。\"rtb-964da5f2\"にはVPC作成時に自動生成されたデフォルトサブネットが紐付いている。 今回、オリジナルのサブネット、インターネットゲートウェイを新たに作成するのに合わせて、RoutingTableを新規作成する。 # RoutingTable の作成 $ aws ec2 create-route-table --vpc-id vpc-cc2b11a9 { \"RouteTable\": { \"Associations\": [], \"RouteTableId\": \"rtb-fe5cb49a\", \"VpcId\": \"vpc-cc2b11a9\", \"PropagatingVgws\": [], \"Tags\": [], \"Routes\": [ { \"GatewayId\": \"local\", \"DestinationCidrBlock\": \"10.0.0.0/16\", \"State\": \"active\", \"Origin\": \"CreateRouteTable\" } ] } } # タグ付け $ aws ec2 create-tags --resources rtb-fe5cb49a --tags Key=Name,Value=\"rtb public\" パブリックサブネット用RoutingTableにインターネットゲートウェイを関連付ける $ aws ec2 create-route --route-table-id rtb-fe5cb49a --destination-cidr-block 0.0.0.0/0 --gateway-id igw-5bb8203e { \"Return\": true } 新たに作成したサブネットをパブリックサブネット用RoutingTableに繋ぎかえる $ aws ec2 associate-route-table --route-table-id rtb-fe5cb49a --subnet-id subnet-b71eeac1 { \"AssociationId\": \"rtbassoc-0ce55a68\" } $ aws ec2 associate-route-table --route-table-id rtb-fe5cb49a --subnet-id subnet-131feb65 { \"AssociationId\": \"rtbassoc-c1e45ba5\" } $ aws ec2 associate-route-table --route-table-id rtb-fe5cb49a --subnet-id subnet-d6d2d38f { \"AssociationId\": \"rtbassoc-76c97612\" }

default eye-catch image.

FitbitAPI long range restingHeartRate plot as health index .

If the sympathetic nervous system is stimulated, the points of restingHeartRate rise directly.I think \"restingHeartRate\" will reveal the index of relaxing myself. Long term observation of restingHeartRate may specify mental or physical rhythms. So, I scracthced the script to retrieve the long term \"restingHeartRate\" from the Fitbit Heartrate API to plot its trend. The restingHeartRate itself may not be userful, but relatively useful The point of restingHeartRate itself (75,82,..) may not be useful to observe the trend of individulas. The uptrend of restingHeartRate will warn that sympathetic nervous system is continuously stimulated, and show the necessity of resting, then avoid from streath. So it\'s important the standard of restingHeartRate and it\'s important to relate the point and physical or mental conditions. Index for rest Vice versa, if this index get the uptrend, agressively rest. Plot example As below, the x axis show the date, between 2015/08 and 2016/06, about 10months. the y axis show the point of the restingHeartRate retrieved from Fitbit Heartrate api.

default eye-catch image.

OAuth2 implicit grant flow で FitbitAPI の認証をパスするサンプル

これまで、OAuth2 Authenticate code grant flow で FitbitAPI の認証をパスしてデータを取得する事例を書いてきた。implicit grant flow では認証をパスできないのか調べてみた。 Fitbit API の認証を implicit grant flowでパスする際の特徴は以下の通り。 implicit grant flow でFitbitAPI の認証をパスするには、アプリケーションタイプを Client として登録する必要がある。 access tokenの消費期限はユーザが決定する。 refresh tokenを使ってaccess tokenを更新する場合、ユーザの承認が必要となる。 本エントリにて、implicit grant flow で FitbitAPI の認証する方法を step by step で追ってみる。 Authenticate code grant flow と implicit grant flow の違いについて、↓が参考になりました。What is the difference between the 2 workflows? When to use Authorization Code flow? Authenticate code grant flow Authenticate code grant flow は以下の流れだった。 ClientID, ClientSecret から認可コードを取得する 認可コードと accessToken を交換する accessTokenを取得するためには ClientID, ClientSecret を保持しておく必要があった。 本家から図を転載する。 implicit grant flow 対して、implicit grant flow は以下のような流れとなる。 まず、本家からの図の転載。 まとめると次の通り。 ClientIDを使って accessToken を取得する https://www.fitbit.com/oauth2/authorize?state=fx2D6zGcbNVltC15sQlxh4wP8U8HH53%2B &scope=activity+heartrate+location+profile+settings+sleep+social+weight &response_type=token &client_id=xxxxxx &redirect_uri=http%3A%2F%2Fhoge.com%3A8002%2Ftest.php ブラウザ上で認証画面が表示される。この画面はブラウザである必要があり埋め込んでスルーしたりすることはできない。 許可すると、指定したコールバックURLがパラメータ付きで呼び出される。(当然伏字です) http://hoge.com:8002/test.php#scope=weight+location+social+settings+heartrate+sleep+activity+profile &state=fx2D6zGcbNVltC15sQlxh4wP8U8HH53%252B &user_id=xxxxx &token_type=Bearer &expires_in=69483 &access_token=eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NjY5MzMyMzcsInNjb3BlcyI6InJ3ZWkgc nBybyByaHIgcmxvYyByc2xlIHJzZXQgcmFjdCByc29jIiwic3ViIjoiM1FaVllYIiwiYXVkIjoiMjI3V EZKIiwiaXNzIjoiRml0Yml0IiwidHlwIjoiYWNjZXNzX3Rva2VuIiwiaWF0IjoxNDY2ODYzNzU0fQ.oy 0Px-mEauh5Jgw1yS8PF94U37tUW2Q35fbCHKcDFHU ここで得られたaccess_tokenを使って、データアクセスAPIを呼び出す。その際、クエリに含まれるaccess_tokenをAPIにアクセスする度に利用する。クエリに付けるのではなくBASIC認証のヘッダとして付与する。 URLのクエリからaccess_tokenを取得しBASIC認証で利用する。 GET https://api.fitbit.com/1/user/-/profile.json Authorization: Bearer eyJhbGciOiJIUz******************************* ******BybyByaHIgcmxvYyByc2xlIHJzZXQgcmFjdCByc29jIiwic3ViIjoiM1FaVll YIiwiYXVkIjoiMjI3VEZKIiwiaXNzIjoiRml0Yml0IiwidHlwIjoiYWNjZXNzX3Rva2 V**************************************eLtCF0V6IISPinTxy_ZgCLQl1tB0 rEMeqVk4 access_token を使いまわしていると、いずれ access_token の消費期限に到達する。 消費期限に到達した access_token を使ってデータ取得を行うと、以下のようなレスポンスが返ってくる。 { \"errors\": [ { \"errorType\": \"expired_token\", \"message\": \"Access token expired: eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0MzAzNDM3MzUsInNjb3BlcyI6Indwcm8gd2xvYyB3bnV0IHdzbGUgd3NldCB3aHIgd3dlaSB3YWN0IHdzb2MiLCJzdWIiOiJBQkNERUYiLCJhdWQiOiJJSktMTU4iLCJpc3MiOiJGaXRiaXQiLCJ0eXAiOiJhY2Nlc3NfdG9rZW4iLCJpYXQiOjE0MzAzNDAxMzV9.z0VHrIEzjsBnjiNMBey6wtu26yHTnSWz_qlqoEpUlpc\" } ] } ここで、Authenticate code grant flow と同様に refresh_token を使って access_token を更新する必要があるのだが、ドキュメントに記述があるように、implicit grant flow では refresh_token を取得するために client_id を使って再度認証する必要がある。 client_id はアプリケーションにストアすべきデータではなく、ユーザによる操作が必要。 Unlike the Authorization Code Grant Flow, the refresh tokens are not issued with the Implicit Grant flow. Refreshing a token requires use of the client secret, which cannot safely be stored in distributed application code. When the access token expires, users will need to re-authorize your app. また、以下に記述があるように、implicit grant flow における access_token の消費期限は Authenticate code grant flow のそれよりも長めに設定される。アプリケーション側で予め消費期限を設定できるが、最終的には認証画面においてユーザが消費機嫌を決めること値が決まる。 Access tokens from the Implicit Grant Flow are longer lived than tokens from the Authorization Code Grant flow. Users may specify the lifetime of the access token from the authorization page when an application uses the Implicit Grant flow. The access token lifetime options are 1 day, 1 week, and 30 days. Applications can pre-select a token lifetime option, but the user ultimately decides.

default eye-catch image.

FitbitAPI 1分毎の歩数を24時間、1ヶ月分 3次元プロットしてみる

前回、1分毎の消費カロリーを24時間 1ヶ月分 3次元プロットしてみた。 データを眺めていてもイメージがわかないので、前回と同様に歩数データもプロットしてみる。 Rawデータの3次元プロット X軸が日にち、Y軸が00:00:00からの経過時間(分)、Z軸が歩数である。 データはFitbitのtrackerが計測したもので、心拍数と同様に、1分あたり小数点のデータが入っている。 あくまでセンサーが出力した数値がそのまま出てくるのだろうと推測される。 (積分すると、ちゃんと1日の歩数になる。サンプリンク周期の方を1分に固定したために歩数の方が小数点になっているんだろう) 値が0から170-180までのレンジにあることが興味深い。 ジムのマシンでガンガン飛ばしているとき、マシンの数値は75回転/分から80回転/分程度。 1回転するのに2歩必要なのだから、150歩から160歩ということになる。 ちょっと多いような気もするが、だいたいそんなもん。 消費カロリーの3次元プロットと比べると、カロリーを消費していない時間帯にも割と歩いていることがわかる。 消費カロリーがフラットだが、歩数が立ち上がっている領域は、心拍数が低い領域である。 心拍数を上げずに歩いてもカロリーは消費されないことがわかる。 積分値の3次元プロット trackerが出力したRawデータを積分して、累積値を3次元プロットしてみる。 消費カロリーの積分プロットは、基礎代謝のおかげて傾きがゼロになることはないのだが、 座り仕事が続くと、歩数に関しては傾きがゼロになり、上記の図のように階段状になる。 気をぬくと、24時間フラットな図になるだろう。 基礎代謝の分を除けば、概ね、消費カロリーと歩数は相関がありそう(計算してないけど)。 万歩計はとても安くて揃えやすいから、歩数を健康の目標にすることが多いのだろうね。

default eye-catch image.

OAuth2 Implicit Grant Flow とセキュリティ

Implicit Grant Flow を「認証」のための方法として使ってはならない、というが、ちょっと不勉強で理解が曖昧だったので、少し深く理解してみることにした。 参考にしたソースは下記記事 The problem with OAuth for Authentication. 単なる OAuth 2.0 を認証に使うと、車が通れるほどのどでかいセキュリティー・ホールができる OAuth2 implicit grant flow 自分が所有する情報に対してアクセスを認めることを認可と呼ぶ。 自分が所有する情報と自分の間に第三者が入らない場合 その鍵を自分が管理することに問題はない アクセスするための鍵を自分自身が管理し、安全が保障されている通信の中で直接鍵を利用できる。 自分が所有する情報と自分の間に第三者(Webシステムやアプリ)が入る場合 Webシステムやアプリに対して自分自身の情報に対するアクセス権を移譲する。 鍵をWebシステムやアプリに渡してしまうと、Webシステムやアプリの脆弱性により鍵そのものが危険にさらされてしまう。 代わりに合鍵(accessToken)を作成し、Webシステムやアプリは合鍵を使って自分自身の情報にアクセスするようにする。 以後、第三者は大元のアクセス権に触れずに、accessToken/refreshTokenを使う。 第三者システムを仮に実装してみると、accessToken/refreshTokenを該当システムのIDに紐付けて保存することで、そのシステム上のログインユーザにリソースオーナーへのアクセス権を付与できる implicit grant flow を認証に使う implicit grant flow を認証に使う、というのは、第三者システムが、リソースオーナーから取得したIDをそのまま第三者システムのIDとして使うことを指す。例えば、GoogleやYahooに保存されたID(emailなど)に対してアクセスを許可するだけで、第三者システムのログインそのものを許可してしまうようなものを指す。 だいたいどんなサービスを作るにしても、最初は知名度が低くて、ユーザ登録などしてくれないことがほとんど。 サービス提供者が考えるのは、GoogleやYahooなどのログインを自システムへのログインに代替できないか、ということ。 自分自身の情報へのアクセスを認めただけなのに、勝手に自分自身のログインであることの証明に使われてしまう、というのが問題。 問題は 第三者システムに悪意はなくて、ただ借りパクしたいだけなら被害はない。 第三者システムが悪い奴で、取得したaccessToken/refreshTokenを使って、本人になりすまして、別の第三者システムにログインしてしまったら...。 別の第三者システム的には、本人からのアクセスなのか、本人になりすましたシステムからのアクセスなのか、区別することができないから、CSRF対策を行って防げる攻撃ではない。