astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

セキュアなトークンの作り方

開発部のにゃんです。主にバックエンドを弄っております。

Webアプリケーションではセキュリティ対策のためにランダムな文字列を使用する場面が多々あります。例えば

  • CSRF対策のトークン
  • OAuthやOpenID Connectで使用するnonce, state, code_verifier
  • メールの到達確認用URLのトークン
  • パスワードをhashする際に使用するsalt
  • セッションID

これらの値は単に衝突しなければOKというものではありません。十分なセキュリティ強度を確保するためには推測不可能なランダム値を使う必要があります。

以下は推測不可能なランダム値ではありません。セキュリティが求められる場面では使ってはいけません。

  • Math.randomなどの疑似乱数
  • 日付やユーザ情報のハッシュ

ではどのような値が適切なのでしょうか?

/dev/random/dev/urandom

Linuxには

  • /dev/random
  • /dev/urandom

という特別なファイルがあり、セキュリティの求められる場面でも利用可能な乱数を取得することができます。

/dev/randomはシステムのノイズを利用した真の乱数を返します。ノイズを貯めたエントロピープールが枯渇するとノイズが溜まるまでブロックされるというデメリットがあります。SSH鍵やTLSサーバ鍵など長期間利用され、高度な保護が求められる場合に使用します。

/dev/urandomは、/dev/randomに品質で劣りますがトークンなどの使い捨ての値には十分な強度があります。またエントロピープールが枯渇してもブロッキングされません。

Webアプリケーションなどのリアルタイム用途ではブロッキングを避けたいのと、大抵の場合、暗号鍵ほどの強度は求められないので /dev/urandomを使うのが良いでしょう。

java.security.SecureRandom

プログラミングでは/dev/random/dev/urandomを直接利用せずライブラリやAPIを通してアクセスします。

Javaではjava.security.SecureRandomというクラスが用意されています。実装はJDKによって異なっていたり、設定によって切り替わるのですが、概ね

  • SecureRandom.getStrongInstance() - /dev/randomに相当する真の乱数生成器を取得、エントロピー枯渇時にブロッキングする。
  • new SecureRandom() - /dev/urandomに相当する暗号論的疑似乱数生成器を取得。ブロッキングしない。

となっているようです。なお、他の言語では

  • PHP: random_bytes
  • Ruby: SecureRandom
  • Python: secrets.SystemRandom
  • Node.JS: crypto.randomBytes
  • Web API: crypto.getRandomValues

といった安全なランダム値を取得するAPIが用意されています。

サンプルコード

アカウント登録時やメールアドレス変更時に以下のような文面のメールを送ることがあると思います。

以下のURLにアクセスしてメールアドレス変更を行ってください

http://exmaple.com/mail/confirm?token=laLg4Whuf0NA27AYLDyigk2i6_X16g6tNBbBSR_eLlugTHMQDptfqbePrPP4lT62

このメール文面にあるtokenを安全に作成するコードを例示します。

import org.apache.commons.codec.binary.Base64;  
import org.apache.commons.codec.binary.Hex;  
import org.apache.commons.codec.digest.DigestUtils;  
  
import java.nio.ByteBuffer;  
import java.security.SecureRandom;  
  
public class Token {  
    public static void main(String[] args) {  
        System.out.println(generateMailVerificationToken("test@example.com"));
    }  
  
    public static String generateMailVerificationToken(String email) {  
        ByteBuffer buf = ByteBuffer.allocate(48);  
  
        // 16byteのランダム文字列
        byte[] randomBytes = new byte[16];  
        SecureRandom secureRandom = new SecureRandom();  
        secureRandom.nextBytes(randomBytes);  
        buf.put(randomBytes);  
 
        // 32byteのemailハッシュ値
        byte[] emailHashBytes = DigestUtils.sha256(
            email + Hex.encodeHexString(randomBytes));
        buf.put(emailHashBytes);  
  
        return Base64.encodeBase64URLSafeString(buf.array());  
    }  
}

ポイントはMath.randomやjava.util.Randomではなく、java.security.SecureRandomを使うことです。トークンとしてはランダム部分の16バイトで十分な長さがあり衝突の心配はありません。今回はメールアドレスのsha256ハッシュ値32バイトを追加していますが、この部分は本質的には不要です

というわけで、今回は地味目な話題でしたがトークンってどう作ればいいのかな?と思った時には参考にしていただけると幸いです

Weave Scopeを使ってみた話

こんにちは。開発部のtorigakiです。

今回はWeave Scopeを簡単に検証した話をさせていただければと思います。

弊社では様々なサービスでDockerを使っています。通常Dockerホストでどのようなコンテナが稼働しているのか確認するためには、サーバーにSSHログインしてDockerコマンドを実行して確認するという流れになるかと思います。 Dockerホストの台数が少ないうちはこの運用でも把握できるかと思いますが、台数が多くなるにつれ、この運用がつらくなってくることが想定されます。 また、1台のホストに多くのコンテナが稼働しているとどのコンテナがどういった連携をしているのか把握していくのも困難になってくるかと思います。

そこで、Dockerコンテナをサーバーにログインすることなく、GUIで簡単に管理することができるツールがないかなと探してみたところ、Weave Scopeという素晴らしいツールがありましたので、さっそく導入してみました。 今回はこのWeave Scopeについて簡単に解説していきたいと思います。

Weave Scopeとは?

Weave Scope は、DockerとKubernetesのための可視化・監視ツールです。アプリだけでなく、インフラ全体を確認することができ、コンテナを直感的かつリアルタイムに把握、制御できます。

インストール方法

インストールは非常に簡単で、scopeファイルをダウンロードして実行するだけで導入できます。

sudo curl -L git.io/scope -o /usr/local/bin/scope
sudo chmod a+x /usr/local/bin/scope
scope launch

Weave Scope画面のアクセス方法

ブラウザから http://サーバーアドレス:4040にアクセスするとコンテナ状況を把握できる画面が表示されます。 4040ポートを使用するので、実行環境によっては、ファイアーウォール等の許可設定を入れる必要があります。

実際に使ってみた

弊社では社内WikiでGrowiを使っているのですが、このGrowiは1台のホストで複数のDockerコンテナが連携して稼働しているので、今回このGrowiサーバーに導入してみることにしました。

Weave Scope画面

コンテナ連携

こちらがブラウザでアクセスしたWeave Scope画面です。 コンテナ同志の連携が視覚的にわかりやすく表示されています。 このサーバーにはGrowiとtogelackが共存しているのですが、それぞれのコンテナが個別に連携していることも一目で把握できます。

f:id:astamuse:20210726135822p:plain

 プロセス連携

画面上部の「processes」をクリックすると、各コンテナのプロセスレベルの連携が表示されます。

f:id:astamuse:20210726135910p:plain

この画面を見ることで、プロセスレベルの連携も把握できるので、より詳細にシステムを把握することができます。

テーブル表示

画面上部の「Table」をクリックすると、コンテナごとの一覧表示をすることができます。

f:id:astamuse:20210726140033p:plain

CPUやメモリでソートすることもできますので、高負荷コンテナをすぐに把握することもできます。 また、「processes」をクリックすることで、プロセスレベルで一覧表示することも可能です。

リソース表示

画面上部の「Resources」をクリックすると、ホスト、コンテナ、プロセスごとのリソース利用状況がどれくらい使用されているのかわかりやすく表示されます。

f:id:astamuse:20210726140128p:plain

画面上部の「CPU」をクリックするとCPUごとの利用状況も把握することができます。

コンテナごとの詳細情報

表示されているコンテナ名をクリックすることで、クリックしたコンテナの詳細情報が表示されます。 コンテキストメトリック、タグ、およびメタデータやCPU、メモリの使用状況を把握することができます。

f:id:astamuse:20210726140202p:plain

コンテナのコンソール出力とコンテナへのログイン

上記で表示した詳細ウィンドウのモニタのアイコンをクリックすると、コンテナのコンソール出力をブラウザ上に表示できます。 そして、「>_」 のアイコンをクリックすると、コンテナにログインしてコマンドを実行することができます。

f:id:astamuse:20210726140238p:plain

わざわざホストサーバーにSSHログインしなくても、このブラウザ画面だけでコンテナの状況を把握することが可能になります。 ターミナルを使わずとも運用できるのは非常にありがたいですね。

 まとめ

今回は、DockerをGUIでわかりやすく管理できるWeave Scopeについて簡単に解説しました。 このツールはDockerだけでなくKubernetesも視覚的に管理できるので、今後はKubernetesでの導入もやっていけたらと思っております。

弊社では引き続きエンジニア・デザイナーを募集中ですので、ご興味のある方は下からご応募いただければと思います。

Stylelint を導入したときのあれこれ

こんにちは、フロントエンドエンジニアの minamo です。

最近は夏映画の公開ラッシュで週2回映画館に通っています。忙しい!

3度目のブログは、最近導入してみた Stylelint についてです。

  • Stylelint を導入するメリット
  • おすすめのプラグイン
  • 導入するときに困ったこと・その解決法

などについて書いていきます。

Stylelint って何?

Stylelint は CSS の 構文チェックツール です。Javascript の ESLint の CSS 版とも言える存在です。

基本的な構文エラーや typo 、たまにやってしまうスタイル指定の重複など、構文チェックツールとしての機能はもちろんのこと、

  • プロパティの順番
  • 一行空けるか、空けないか
  • カラーコードは大文字か小文字か

などなど、個人間で書き方の差が激しい(ともすれば宗教戦争になりかねない)CSS の記述ルールを定め、統一してくれます。

チームでの開発など、複数人で作業する場合でも自動的にルールに則って記述を統一してくれるので、レビュー指摘の手間や無駄な争いがなくなり、開発にあてる時間を増やすことができます。

筆者はこのツールの存在を知ったとき、「ワシの若い頃はプロパティの順番を丸暗記していたもんじゃったがのう」と昭和の昔話おじいさんになってしまいましたが、令和に生きる開発者はそんな苦労をすることなく、プロパティの順番や書き方を気にせずのびのび開発し、あとでポチッと一発 Stylelint にかければいいのです。素晴らしいことだと思います。

インストール

本体と同時にプラグインもインストールしていきます。

npm install stylelint stylelint-config-standard stylelint-config-recess-order stylelint-config-prettier stylelint-scss --save-dev

今回選んだプラグインはこちら。

recommended or standard?

基本的な設定には stylelint-config-recommended もしくは stylelint-config-standard がありますが、 stylelint-config-standard を採用するのにも少し紆余曲折がありました。

まず導入対象のプロダクトでは SCSS を使っていたので、 stylelint-config-standard-scss を使おうとしたのですが、あまりメンテナンスされていないため見送りに。

次は stylelint-config-recommended-scss の使用を検討。しかし、 recommend よりは規則がより厳格な standard の方を使いたい。こちらは規則が少しゆるめの stylelint-config-recommended を extend しているため、standard にしたいのであれば自分でルールを足すしかありません。

結果として、stylelint-config-standard + stylelint-scss を入れて、推奨するルールを設定ファイルに記述しました。

設定ファイル

インストールが完了したら、設定ファイルを作成し、どのプラグインを使うか指定したり、細かいルールを足していったりとカスタマイズしていきます。

touch stylelint.config.js  // 設定ファイルの作成

設定ファイルの書き方も ESLint と似ていますね。ここでは導入したときの設定を転載します。(あまり細かい説明はしません)

extends

extends: ['stylelint-config-standard', 'stylelint-config-recess-order', 'stylelint-config-prettier'],

順番に注意しましょう!

plugins

plugins: ['stylelint-scss'],

ignoreFiles

ignoreFiles: ['**/node_modules/**'],

rules

rules: {
  'at-rule-no-unknown': null,
  'scss/at-rule-no-unknown': true,
  // ↑ここまでは stylelint-scss の推奨ルール。
  // ↓あとはお好みの設定を記述しましょう。
},

選択肢を選んでいくだけで Stylelint の rules を書き出してくれるジェネレーターもあります。便利〜! 例を見ながら回答していくので、ルールの内容の勉強にもなりますね。

maximgatilin.github.io

ただ全部答えていくと結構な量になりますし、 config とかぶっているルールは外してもいいかもしれませんね。 config でどういったルールを設定しているのか、内容に一度目を通しておくといいと思います。

stylelint-config-recommended

github.com

stylelint-config-standard

github.com

使い方

package.json

lint コマンドや fix コマンドで Stylelint が動作するように設定しましょう。

{
  "scripts": {
    "lint:css": "stylelint **/*.{css,scss,sass}"        // エラーを検知する
    “fix:css": "stylelint —fix **/*.{css,scss,sass}"    // エラーを自動的に修正する
  }
}

VSCode

VSCode をお使いであれば、拡張機能を入れるのがよいでしょう。

marketplace.visualstudio.com

ESLint と同じように保存時に動作するように設定すれば、自動的に修正してくれるので開発スピードが上がりますね。

"editor.codeActionsOnSave": {
  "source.fixAll.stylelint": true
}

導入時に困ったルールなど

selector-pseudo-element-no-unknown

導入対象のプロダクトはフレームワークに Vue.js (Nuxt.js) を使っていたので、 ::v-deep がこのルールに引っかかります。 設定ファイルで ::v-deep を対象から外すよう個別に設定しました。

declaration-block-trailing-semicolon

この設定が Prettier の「インラインスタイルで末尾のコロンを削除する」設定とコンフリクトします。これは調べた限り解決方法が見つからなかったです。。

no-descending-specificity

「詳細度の高いセレクタより後に詳細度の低いセレクタを定義することを禁止する」ルールです。これは lint fix でも修正できず、後から修正していこうと思うと結構大変です…!なのでこちらは泣く泣く無効化することに。

大事なこと

Stylelint は最初から導入する のが後で困らないのでおすすめです!!

astamuse ではいつでもエンジニア&デザイナーを募集しています。 もちろんリモートでの面接にも対応していますので、お話だけでもお気軽にどうぞ!

Copyright © astamuse company, ltd. all rights reserved.