絶対完全無料ツールの紹介

エンジニア目線のブログです

#1 AWSエンジニアの悲劇 ほとんどのエンジニアは気づいていいない闇

www.youtube.com

カッコウという鳥の生存方法はご存知でしょうか?

カッコウは自分の卵を他の鳥の巣に産み付けて、その巣の親は
カッコウだとは気づかずに育てていきその子供は本当の卵・
ひなを落としていきます。

カッコウの子が親よりも倍以上の大きさになっても親の鳥は気づかずに
餌を与え続けていきます。

恐ろしい話ですが、これがAWS、国内ベンダー。
AWSAWSエンジニアの関係に似ているので例えに使わせてもらいました。

AWSのメリットと言われている箇所を1つずつ潰していきます。

1.AWSはリソースを効率よく使えるので、コスト削減につながる
文言だけでは安くなるように聞こえるが、実際はVPSとかの4倍〜10倍。
固定じゃないので、比較がしづらい。
柔軟性という言葉を武器に計算をしづらくして囲い込みを行っている
マーケティング的な手法の部分が多いと思われます。

2.ディスク容量の限界がないので、気にしなくていい
格安専用サーバーで1TBのディスク容量なので、それを超える
ディスク容量を果たして保守できるのでしょうか?
MySQLで大量なデータと思っても100GBぐらいかと思います。
それ以上で運用しているのであれば、ログテーブルを保存している
など、システムに問題があるかと思いますが、限界がないという事で
気にしなくていい事が逆にデメリットになって、ディスク費用が高くなったり、
気づいたときにはアーカイブ化が困難な状態になっているのではと思います。

3.AWSは落ちない
結構落ちてます。「AWS 障害」で検索すれば出てきます。

4.機能が豊富
自分で作りましょう。それがスキルかと思います。
aurora rdsの機能はmysql,postgresで可能です。
cloudfrontはnginxのキャッシュの設定でできます。
dynamodbはmongoDBで代替可能です。
AWSはサポートがあるので、わからなければサポート使う手もあります。
そうすることによってAWS側はユースケースの知識、経験がつくので、
お金もらいながらナレッジがたまり、AWSエンジニアは気づかないうちに
どんどん自前で機能を構築するスキルを失っていく事になります。
なので、はじめのカッコウの生態を例えに上げました。

5.インフラの手間が省ける
にもかかわらずインフラチームが存在していて、インフラ周りの
対応に追われたりしてないでしょうか?
例えばアカウントを例に挙げると、
AWSの機能ではなく全てLinuxにインストールする形をとればLinux
アカウントを与えるだけで担当者に任せられます。
しかし、AWSの機能でインフラ構築してしまうと、Linuxのアカウントだけでなく、
AWSのコンソールアカウントも与えないといけません。
AWSのIAMユーザーの権限設定だけでLinuxのアカウントの権限設定とダブルワークになってしまいます。
redmineを自前で構築するのは工数がかかるので、お金を払ってBacklogなどSaasを使うのはわかりますが、
AWSの場合はお金を払って、さらに工数もかかってしまうという事です。

次からはデメリット3点
A.請求が無限大
2でも説明したように、容量が無限になると例えば、開発中にバグがあって容量が
とてつもなく増えたりとか、またはアクセスしまくるようなバグがあった時は
請求が急激に高くなったりすることなどのデメリットもあります。
そうなってもエンジニアが払うわけではないので、本人のデメリットには
ならないですが、会社のデメリットなのは間違いないです。
実際小松の現場でもあった出来事です。

B.AWSから抜けられない
気づいたら、ELB、aurora、S3などで周りを固められ、AWSから抜け出せなくなってしまいます。
まさにベンダーロック
一度足を入れると抜けにくいのに気づかずにどんどんはまっていくような状態です。
AWSから他のサービスに移行した件を聞いたことがないです。

C.スキルがつかない
シェフで例えると、自前で調味料からつくるシェフとチェーン店からお弁当を買ってくる
シェフだとどちらがスキルが高い、または、これからどちらのスキルが高くなるでしょうか?
スキルの点でも自前で作ったほうがいいのは明白です。
AWSのサポートがあることでAWS自身のナレッジはたまり、エンジニアはサポート頼みに
陥ります。

これらの理由から
気づかないうちにAWSを使えば使う程アマゾンにナレッジとお金が周り、
使う側のスキルと資産がどんどん削られています。
さらに、AWSしかわからないインフラエンジニアが増えてAWSがマーケットを独占して
国内ベンダーはどんどん縮小しています。
そういった残酷で悲惨な状況なのにもかかわらず気づいていないという悲劇が
続いているのでカッコウの生態を例に挙げました

今まで説明してきたように合理的な理由でAWSを選択する事はないです。
しかし多くのエンジニアを魅了しています。今まで理解できなかったのですが、なんとなく
原因がわかってきたので、「#AWSの洗脳」で紹介していきます。

バックエンド用語のクイズ集
https://programming.quigen.info/category/2/99/

#7 CSRFを言葉でなく意味を理解する、コーディングして実証

youtu.be

今回はCSRFです。

CSRFとは何かしらのデータの投稿する時に意図したページからの投稿なのか
どうかをチェックするセキュリティの仕組みです

step1 投稿ページにトークンをinput type="hidden"などのフォームに設置
step2 同じトークンをセッションに保存
step3 POSTで投稿した時にPOSTのパラメータのトークンとセッションのトークンが
      一致しているか確認
step4 一致したら、処理を続行、しなければ処理を中断
      といった流れになります。

なぜそういった対策をしないといけないかというと

①投稿ボタンを連打されると二重に登録される可能性がある
②別のSNSなどから意図せず投稿されてしてしまう可能性がある

などです。

なのでそういったセキュリティの観点からほとんどのフレームワークでも
用意されています。

Laravelなどのフレームワークでは有効期限が2時間ってなってますが、
それはどういうことかというと確認ページなどを開いたまま
違うことで2時間が過ぎ、POSTすると時間オーバーでリフレッシュからって
事になります。

ユーザビリティがその分下がってしまうので、CSRFトークンの期限は
不要かと思います。

サーバー的にずっとトークンデータをずっと保持するとデータ容量を
いっぱいに使ってしまう可能性があるので、その点で期限を決めてもいいかと
思いますが、1日もしくはそれ以上の日数ぐらいでもいいかと思います。

そこでクイズというか疑問が湧いてきました。
Laravelのセッションの種類には
file,cookie,database,apc,memcached,redis,dynamodb
などがありこの中でCSRFが実現できなくなるセッションの種類があります
どれだと思いますか?

正解はcookieです。
なぜなら、cookieは保存先がサーバーにはなくブラウザにあるため
CSRFの実装をすると一旦ブラウザにレスポンスしないと反映されない分
2重に登録されてしまうという事を防ぎきれないです。

なので論理的に考えるだけではなくて、実際に検証してみました。

まずはじめにfileをセッションにしてPOSTの連打してみました

2回目からCSRFのセキュリティが効いて419エラーが出ている所が確認できました

次にCookieをセッションにしてPOSTするボタンを連打してみました。

4回目から419とCSRFのセキュリティが効いてますが、2,3回目は
POSTできてしまっています。

cookieのレスポンスがブラウザに反映される前にこの3回分のPOSTが
されているからだと思います

今回CSRFの説明しましたが、ただ単にcookieをセッションにすると
CSRFの機能の一部が無効になるという事だけを説明したかったわけではなく
CSRFとは何か?を理解し
セッションとは何か?を理解していればこのような不具合が発生すると
人から教えられなくても気づける事です。

今回このように具体的な例でCSRFの仕組みの理解を説明しましたが、
意外とエンジニア歴何年もあるベテランエンジニアでも基本的な言葉は知っていても
原理的な仕組みの理解をしている人は自分の経験上多くなかったので、
CSRFを一例として取り上げました。

以前の動画でも紹介しましたがプログラミング・エンジニアに必要な知識量は
そこまで多くなく、現場に入って2〜3週間で習得できる場合がほとんどです。

しかし、原理的な仕組みの理解をしなければ、今回のように「Cookieセッション
CSRFは不可能」という結果の知識を大量に覚えていかないといけません。

知識の暗記だけではなく、仕組みの理解をして知識と知識の掛け算ができるエンジニア
になれるように心がけてみてもいいかもしれません

#6 暗号化というそもそもの意味と意義 ssh, httpsを具体的にtcpdumpで実証しました

youtu.be

今回は暗号化がどういうものなのかを説明します。

ssh, https, vpn, ipv6などは暗号化されている技術の一つです。

なんとなく安全なものだとはわかっていても具体的にはイメージが
つかない人も多いと思うので、実際tcpdumpを用いて動画をとりました。

まずは、phpからmysqlに接続してSQLを通信傍受できるかどうかを
確認します。

insert文を実行して、それがtcpdumpで実際のinsert文を確認できました。

この環境ではmysqlの通信は暗号化されていないためSQLが丸見えとなります

この環境ではphplocalhostからmysqllocalhostなので丸見えでも
問題ないですが例えばMySQLサーバーをパブリックな環境として公開して
どこからでもアクセスできるようにした場合はそのデータが通るネットワーク
すべてに通信傍受される危険性があります

なので、一般的には内部ネットワークからのIPのみ許可する設定を
している事が多いです。

他にはSSHでポートフォワーディングして直接接続せず
暗号化してから接続する方法もあります

MySQL Workbenchなどでも TCP/IP over an SSH connection
を選んで暗号化する方法もSSHのポートフォワーディングと
実質的に同じです。

次にHTTP Sの暗号化の確認をしていきたいと思います。

まずはhttpでアカウントとパスワード入力してPOSTします。
そのPOSTのデータをtcpdumpで確認します。

POSTされたアカウントとパスワードが確認できました。

次にhttpsにしてtcpdumpしてみます。
しかしPOSTされたデータが取得できませんでした。

このようにhttpでは容易にパスワードを傍受できてしまいます。

今ではほとんどのWEBページでhttpsになっているので第三者がデータを
傍受できる事はできなくなってきてます。

昔はプロキシサーバーが社内のイントラネットにあって会社に不要な
WEBページをブロックしたり、どういったアクセスや入力しているのかを
管理していましたが、HTTPSが主流になってそういった事も少なくなりました

なぜならプロキシサーバーを立ててもHTTPSで暗号化されていて
データが見れないので管理ができないからです。

アイスマンWiFiからクレジットカードのデータを盗んだ方法も
おそらくhttpで通信傍受をして盗んだのではと思います。

こういったように実際tcpdumpでデータの中身を見れるかどうかを検証
しながら説明するとわかりやすく理解できるのではと思い
ターミナルの画面を録画して説明してみました

#5 oauthの仕組み プロバイダーとクライアントでのやりとりを説明

youtu.be

今回はoauthについて講義したいと思います。

oauthは歴史的経緯でoauth2,oauth2.0と言うこともありますが、
今回はoauthと呼ぶようにします。

oauthを利用すれば違うドメインの違うDBで
同じアカウントで違うサービスを提供できるので大変便利な仕組みです。

かつ少し理解しづらいかと思いますので、今回取り上げました。

以前の開発でメインシステムとは切り離してサブシステムを開発して
そのサブシステムの認証でoauthを利用して全く別のシステム環境でサービスを
提供するといった案件があったのですが、
そのoauthの仕組みを話しても誰もピンとこなくて
Laravelのoauthのライブラリをインストールしてれば大丈夫と担当者が
思い込んでしまいサブシステム連携が全く進まなかった時がありました。

AWSの洗脳」などの動画でも説明していますが、エンジニアの癖で
仕組みの原理を理解せずに機能を覚えたがります。

まさにこのoauthの件は機能を覚えて、原理を理解していなかった典型例です。

原理を理解することがとても重要なので今回oauthを取り上げた理由でもあります。

インスタグラムを例に挙げて説明していきます。
インスタグラムのログインページにいきます。
「Log in with Facebook」をクリックすると
facebookのログインページに飛ばされます。
このfacebookページに飛ばされた時にURIのパラメータで
どこに対しての認証を許可するのかという情報が必ず入っています。
URIを分解してパラメータをわかりやすくしてみます。

分解すると色々パラメータがありますが、一番重要なパラメータは
app_idです。
12から始まる番号がfacebookのDB上でインスタグラムだと登録されています。

そのapp_idのデータを保持しつつfacebookのログインページに遷移して
ユーザーネームとパスワードを入力すると認証されます。

認証された後Facebook側で
ブラウザはFacebookのログイン状態になります。
このユーザーの一時的な(30分程度)トークンを生成してFacebook側のDBに
トークンとユーザーIDを登録します。

その後、そのトークンをパラメータとしてURIに追加して元のアプリつまり
インスタグラムにリダイレクトします。

インスタグラム側ではFacebook側で生成されたトークンを受けて
インスタグラムのサーバーサイド側からそのトークンとapp_idをパラメータに付けて
リクエストします。

リクエストを受けたFacebook側はトークンで合致したデータがあるのかどうかを
チェックして、データがあればuser_idを返して認証が成功したことを示します

トークンでの認証が通ればインスタグラム側でもFacebook側のレスポンスから
facebookのuser_idを取得して登録処理もしくは既に登録されていればログイン処理を行います。

この一連の流れでインスタグラムにはユーザーのパスワード情報を持たずに
ログインさせる事ができました。

セキュリティ的にはトークンの有効期限を決めてトークンの文字列を長くすれば
充分に安全を確保できます。
例えば、小文字大文字と数字で62文字ありその文字数を10文字にすると
兆の上の京の単位の80京というパターンの数があるので、トークンをハッキング
しようとするならば80京分の1の確率となり不可能な数値となります。

そもそもOauthのセキュリティ問題があるのであればGAFAを始めとした多くのIT企業
で使われていません。

oauthを利用することによって他のサービスのデータを借りる事ができるので
データベースを統合する必要がなく柔軟にデータのアクセス権も対応できます。

マイクロサービスや他の会社との連携など色々な局面においてとても便利なので
知っておいて損はないかと思います。

#4 セッションの仕組みや使う目的 意外と経験者でも理解していない部分

youtu.be

今回はセッションの説明です。
Webサイトにログインして、マイページが見れたり
買い物などができるのもセッションのおかげです。

セッションとはCookieとサーバー各々に同じキーのデータを
持ちユーザーを識別する仕組みです。

Cookieを知らないといけないので、Cookieを説明すると

この画像のようにGoogle Developer Toolを開いて
Applicationタブを開くと、左にStorageの欄にCookieのアイコンを
クリックすると各ドメインが見えます。それを選択すると
左からName, Value, Domainと並んでいます。

このName, Valueのデータが毎回アクセスする度にサーバーに渡されます。

このCookieデータの登録、削除の方法は色々ありますが、
基本的にサーバー側(PHPJavaRuby等)で行います。

試しに、PHPでuser_idというNameにkomatsuというValueを設定してみます。
この状態のページにアクセスすると先程のgoogle developer toolに
設定した値がある事が確認できます。

それを踏まえたうえで簡単なログインページとログイン後の
マイページを作ってみましょう。

redisなどでセッション管理するのが一般的ですが、わかりやすく
ファイルにセッションデータを登録する方法で実装してみます。
セッションファイルにCoookieのValueのデータを保存するように開発します。

ランダムの値をCookieのNameのデータにして、セッションファイルの
ファイル名にしています。

ランダム関数がまちがっているようです。

Storage をインポートしないといけないみたいです。

ログインボタンを押すとcookieに値が登録されているのを確認できます。

cookieの値とストレージにあるファイル名が同じ事を確認しています。

ファイルの中身のデータを確認します。

cookieのuser_idのデータを確認します。

DBのt_usrテーブルのkomatsu1がusr_nameでそれをキーに
usr_name_mbのデータseijiroがある事を確認します。

seijiroのデータが確認できました。
seijiroはDBにしかないデータなので、DBからの取得に成功している事
を意味しています。

cookieのuser_idでセッションファイルを取得して、その中身のkomatsu1
というデータからt_usrのusr_nameが該当したデータを取得しています。

このケースでいうuser_idがここではセッションの役割をしています。
アクセスする度にサーバーにこのuser_idの値komatsu1を送る事で
マイページなどの本人にしか見せてはいけないデータなどを見せる事ができます。

別のIDkomatsu111でcookie登録するとまたそのセッションファイルが
作成している事を確認します。

もう一度はじめからkomatsu1のIDを登録からはじめます。

サーバーのセッションファイルを削除しても、Cookieのuser_idを削除しても
どちらかが削除されれば、共通のデータがなくなるので、エラーが表示されます。

セッションの説明でした

DBのt_usrテーブルのkomatsu1がusr_nameでそれをキーに
usr_name_mbのデータseijiroがある事を確認します。

ログインボタンを押すとcookieに値が登録されているのを確認できます。

このケースでいうuser_idがここではセッションの役割をしています。
アクセスする度にサーバーにこのuser_idの値komatsu1を送る事で
マイページなどの本人にしか見せてはいけないデータなどを見せる事ができます。

redisなどでセッション管理するのが一般的ですが、わかりやすく
ファイルにセッションデータを登録する方法で実装してみます。

cookieとストレージに同じデータを保存するプログラミングをします。
cookieの値とストレージにあるファイル名が同じ事を確認しています。

マイページでseijiroと表示されれば成功です。
このデータはt_usrのテーブルに格納されているデータです。
cookieのuser_idでセッションファイルを取得して、その中身のkomatsu1
というデータからt_usrのusr_nameが該当したデータを取得しています。

バックエンド用語のクイズ集
https://programming.quigen.info/category/2/99/

#3 DB DataBaseとは?概念の説明 エンジニアでなくてもDBの構成を理解しておくと便利

youtu.be

DBについて
データベースと言ってもスプレッドシート、エクセルと似たようなものと考えれば簡単かと思います。
1枚のシートがDBでいうところのテーブル
A,B,Cの部分がカラムで、1,2,3の部分が行です。
DBからこの"item A","item B","item C"のデータを取得する時はSELECT文でデータ取得して、
追加の時はINSERT、更新の時はUPDATE文を利用します。
フィルタリングして"item A"だけを取得したい時はWHEREを用いてフィルターします。
SELECT B FROM seat1 WHERE A = 1といったSQLになります。
開発環境ではなく本番のデータでは何百万行ぐらいあるデータも珍しくないです。
実践動画ではphpMyAdminで実際にSQLを実行しながら紹介していきます。

phpMyAdminでテーブルのデータ操作します。

初めにinsert文でデータを追加しています。
次にupdate文でデータを変更しています。
where句がないと全てのデータを変更してしまいますので、
注意する必要があります。

次にselect文です。test_idが2より大きいデータを表示しています。

最後にdelete文です。test_idが2のデータを削除しています。
こういったSQLPHPからでも操作してアプリケーションを作成します。

テーブルにプライマリーキーを追加します。
プライマリーキーを追加すると、phpMyAdmin上で編集、削除などの操作が簡単になります。

バックエンド用語のクイズ集
https://programming.quigen.info/category/2/99/