QUO CARD Digital Innovation Lab Tech Blog

クオカード デジタルイノベーションラボの技術ブログです

AWS WAFをv2へ移行しました

デジタルイノベーションラボのIです。 今回はクオカードペイシステムのAWS WAFをClassicからv2へ移行した件について書こうと思います。

背景

クオカードペイではインフラにAWSを使用しており、外部に公開しているALBにはWAF Classicを適用していました。その名の通りこのWAFは旧世代扱いで、現在ではWAF(v2)の使用が推奨されています。

※ 正確には旧世代のWAFは「AWS WAF Classic」、現世代のWAFは「AWS WAF」という名称なのですが、わかりやすく区別するためにこのエントリでは現世代のWAFをAWSAPIのように「v2」と呼ぶことにします。

botからのアクセスを弾くために、WAF bot controlを使いたいというのが移行を考え始めた直接のきっかけでしたが、更にカスタムレスポンス機能だったり、Log4jの脆弱性に対応したマネージドルールだったり、v2にしかない機能を使いたいというケースが増えてきました。

また今後もWAFの新機能はv2でしか実装されないと思われるため、このままClassicを使用していてはその恩恵も受けられません。

このような経緯でv2への移行を決めました。

移行方法

Classicからv2への移行にはAWS公式の手段が存在します。

—------------------------------------------------------------------------------------------------------------------------

1.自動移行では、既存のウェブ ACL に関連するすべての内容が読み込まれます。AWS WAF Classic で変更または削除される内容はありません。ウェブ ACL とその関連リソースの表現を作成します。この表現は、AWS WAF と互換性があります。新しいウェブ ACLAWS CloudFormation テンプレートを生成し、Amazon S3 バケットに保存します。

2.AWS WAF でウェブ ACL および関連リソースを再作成するために、テンプレートを AWS CloudFormation にデプロイします。

3.ウェブ ACL を確認して手動で移行を完了し、新しいウェブ ACL が最新の AWS WAF の機能を最大限に活用するようにします

4.保護されたリソースを新しいウェブ ACL に手動で切り替えます。

—------------------------------------------------------------------------------------------------------------------------

上記引用の通り、既存のClassic ACLの各種設定をもとに、新規でv2 ACLを作成するCloudFormation stackがデプロイされます。

検証環境で一度実際に試してみた結果、主に以下の理由からこの方法は採用しないことにしました。

  • 結局手動での追加作業が必要な部分が多い
  • 新しく作成されるv2 ACLの名前を指定できない(どうやら、「<移行元Classic ACL名>+<自動で付与されるuuid>」となる様子)
  • そもそもクオカードペイのAWS環境は基本的にTerraformで管理しているため、できるだけCloudFormationでのリソース管理は避けたい

よって、完全に一からv2関連リソースを新規作成することにしました。

ルール設定

移行前のClassicではAWS Marketplaceの「Fortinet Managed Rules for AWS WAF Classic - Complete OWASP Top 10」を利用していました。

v2ではそれに代えて、AWS標準のマネージドルールグループを使うことにしました。WCUを1500以内に収める必要があるため、以下のマネージドルールをACLに追加しました。

—--------------------------------------------------------------------

AWSManagedRulesCommonRuleSet
AWSManagedRulesKnownBadInputsRuleSet
AWSManagedRulesSQLiRuleSet
AWS-AWSManagedRulesLinuxRuleSet
AWS-AWSManagedRulesUnixRuleSet
AWS-AWSManagedRulesAmazonIpReputationList
AWSManagedRulesBotControlRuleSet

計1475WCU

—--------------------------------------------------------------------

また、IPセットも使用してIPアドレスでの制御も実施しました。これはClassicと大差ありません。

チューニング

AWS標準のマネージドルールは特にブラックボックス的なので、実際の動作をみながらのルールのチューニングが必須です。

まずは検証環境に適用し、また本番環境でもルールのアクションを最初はCount状態にして動作確認・ログ分析をしました。WAFのログ出力先はいくつか選択肢がありますが、今回は直接S3に出力してAthenaで分析することにしました。

確認の大きな観点は以下の2点です。

  • 不正なリクエストをブロックできているか
  • 正常なリクエストをブロックしてしまっていないか

WAFに期待しているのは当然前者の機能ですが、ある意味後者の確認のほうがより重要だと思います。正常なユーザアクセスに影響があっては本末転倒です。(実際、検証が不十分でトラブルを起こしてしまいました...)

ブロックの原因となっていたルールをログから特定し、ルールグループから除外しました。

まとめと今後の展望

以上、大まかではありますがWAFの移行に関して実施したことを記載しました。 そもそも移行元のWAF Classicのほうでも沢山のルール設定はしておらず、移行すべきものは少なかったため、実質一から構築したものの作業量はそれほど大きくはなりませんでした。もし複雑なルールを多数設定していたら移行ももっと大変だったと思います。

今後についてですが、現在は正常なリクエストが引っ掛かったルールはルールグループから単純に除外しているのみですが、特にWAF Bot Controlに関してはより細かい制御ができるので時機を見てチューニングをしていきたいです。

15分ルールを導入しました

デジタルイノベーションラボの齋藤です。

以下を参考に15分ルールを導入しました。

https://www.reddit.com/r/MachineLearning/comments/4w6tsv/comment/d6diast/?utm_source=share&utm_medium=web2x&context=3

内容は簡単にまとめると以下のようなものになります。

・何かわからない事があった時、最初の15分間自分で調べる ・もし15分間自分で調べて解決できなかったときは共有用のSlackチャンネルで状況を共有し、他のメンバーにヘルプを依頼する ・共有された問題に知見のあるメンバーがいたらヘルプする

導入の背景

チームで協力して仕事を進める形を目指していますが、他の人にヘルプを求めるのが苦手な人もおり、知見があるメンバーがいてもフォローすることが出来ない状況がありました。またそれによるスケジュール遅延も発生していました。

チームのルールとすることで、他の人にヘルプを求める敷居を下げ、チームで協力して仕事を進められるような形を目指しています。

現状はほぼフルリモートなので、申告が無いとそれぞれの状況が見えにくくなりがちな状況になっています。そのため、早めにアラートが上がる仕組みとしたいと思いました。

質問の仕方

以下のような情報を記載することでヘルプを受けやすくなると考えています。

・背景、文脈を記載する -> 何を実現したいのでその対応をしようとしているのかを記載する

・今までに何をしたか記載 ->どのような試行錯誤を行いどのような結果となったか、その際出力されたログがあればそれも共有する

デジタルイノベーションラボではチームで協力して開発を進めたいエンジニアを募集しています。

QUOカード Digital Innovation Lab.

リモートワークスタイルチェックをやってみました

デジタルイノベーションラボの齋藤です。

永和システムマネジメント アジャイル事業部さんがリモートワークスタイルチェックをやってみたという記事をアップされていました。ミスマッチを防ぐ為に良い取り組みだと思ったので、クオカード デジタルイノベーションラボでもリモートワークスタイルチェックをやってみました。

永和システムマネジメント アジャイル事業部さんの記事

https://blog.agile.esm.co.jp/entry/remote-work-style-check-esm-2022

@mugi_uno さんのリモートワークスタイルチェック

https://gist.github.com/mugi-uno/a794bc199ce7d663f01a434a6e72504c

クオカードでは現在全社的にリモートワークを導入していますが、デジタルイノベーションラボとは少し状況が異なっている為、今回はデジタルイノベーションラボに限った形でチェックをしています。

リモートワーク比重度

リモートワークの導入期間

どの程度リモートワークを導入しているか (≒ 組織としてのリモートワークへの慣れ)

👉「4: 継続してリモートワークを3年以上導入している」

デジタルイノベーションができてからまだ5年経ってないので4になりました。ちなみに設立当初からリモートワークを導入しています。

リモートワークの導入ポリシー

👉「3: 恒久的な導入だが、根本的な制度変更が行われる可能性はある」

設立当初からリモートワーク前提の組織な為おそらく今後リモートワークができなくなる事は無いですが、変更が行われる可能性はゼロではない為3にしました。

リモートワークのマジョリティ度合い

👉「4: 全員が常にリモートワークの可能性がある(出社している可能性もある)」

全員が基本的にリモートワークですが、たまに会社で抽選で配るメロンやチケットなどが当選した場合など、稀に出社することがあります。

申請・許可の必要性

👉「5: 申請や許可は必要ない」

申請は不要です。

リモートワークの適用範囲

👉「5: 業務に関わる全メンバー(正社員以外も含む)がリモートワークを利用できる」

正社員以外も全メンバーリモートワーク利用可能です。

出社義務

👉「4: 年に数回の頻度で出社する必要がある」

入社日はPC等備品受け取りやセットアップの為に出社をお願いしています。

リモートワークで必要なサービス・アプリケーションの取り扱い

👉「4: 業務で利用するサービス・アプリケーションは主にリモートワークを前提としている。一部リモートワークでは利用できないものがあるが、リモートワーク前提のものに移行中・または移行予定がある、あるいは何らかの代替手段によってすべて解決できる。」

基本的にほぼリモートで対応可能ですが、バーコードの精度チェック機など、物理的なデバイスがオフィスにしか無いものも一部あります。

情報のアクセス範囲

👉「5: リモートワーク・非リモートワークでアクセスできる情報に差はない」

差はありません。

その他

✅社内において一定の権限を持つ人物(役員など)がリモートワークを実践している

❎5,000円/月以上のリモートワークに関する手当がある

❎オフィスが存在しない

❎対外的にリモートワークに関する発信・発表を積極的に行なっている

社長も実践しています。またリモートワーク手当は4,000円/月です。

リモートワークの文化

同期・非同期コミュニーションの割合

👉「B: 非同期コミュニケーションが中心だが、一部で同期的なコミュニケーションが必要」 👉「D: 同期的なコミュニケーションが主で、非同期コミュニケーションツールは補助的な利用のみである」 こちらはチームによって状況が違う為、BとDにしました。エンジニアはSlack中心ですが、込み入った話になった場合はMTGも行っています。

テキストコミュニケーションの割合

👉「B: テキストが主で、補助的にビデオ通話・音声通話を用いる」

一つ前の質問と同じですが、Slack中心ですが、込み入った話になった場合はMTGも行っています。

コミュニケーション頻度

👉「B: ミーティングに加え、それ以外でも日々活発にコミュニケーションを取る。雑談もそこそこ。」

毎日朝会を実施しており、それ以外でもSlackでコミュニケーションを取っています。雑談は多くは無いかもしれません。

働く時間

👉「B: 全員働く時間は定まっていないが、コアタイムなどで重なる時間が存在する」

コアタイムはありませんが、チームメンバーで朝会の時間を調整しており、その時間は重なっています。 現在は8:30から9:30の間に業務を開始する人が多いです。

最後に

結構積極的にリモートワークを実施しているのではないかと思います。リモートワークになってから他チームの人たちと雑談する機会がなくなったという声があり、課題になっています。

クオカード デジタルイノベーションラボではソフトウェアエンジニアを募集しています。

OSSへの支援について

クオカードでは様々なOSSを利用していますが、現在は業務として技術的な貢献をする余裕が無い為、寄付という形で支援をすることにしました。

今回は社内の多くのプロジェクトで利用しているJUnit 5に寄付をしました。

https://junit.org/junit5/

今後もJUnit 5に限らず、できるだけ継続的に多くのOSSの支援をしていきたいと考えています。

クオカードではソフトウェアエンジニアを募集しています。

https://quo-digital.jp/

研修体験記:Spring Core(社外)

あけましておめでどうございます、三度のJavaよりメシが好きなデジタルイノベーションラボの山本です。

2022年最初の記事を投稿させていただきます。

年明けにプロダクトグループメンバー数名でSpringFWのハンズオン研修を受講したので今日はそれについて書きたいと思います。

私は、10年以上エンジニア(主にJava)としてシステム開発に携わっており、SpringBootはここ数年よく使うFWとなっております。 基本的なSpringの知識は業務を通じて、中でもわからなかったものに関しては別途本やサイトで調べて補完してきました。 本と言っても、最低限必要そうなところを読むといったスタイルで最初から最後まで通して読んだ本はありませんでした。

弊社でも多くのプロダクトのコア技術としてSpringBootを採用しており、 それぞれバックグラウンドの異なるエンジニアのSpringの知識の平準化を図るべく、社外のハンズオン研修の受講が去年計画されました。 それが実現した、今回受講した研修はこちらとなります。

VMware Tanzu認定 Spring Core: Training https://www.casareal.co.jp/ls/service/openseminar/vmware/v013

研修は、四日間で9:30 - 17:30(昼休憩1時間)で行われました。

1日目:Spring Frameworkの基礎

2日目:アスペクト指向プログラミングに関して

3日目:SpringBoot(MVCトランザクション管理など)

4日目:SpringBoot(REST API作成、Test, SpringSecurityなど)

1〜2日目は、メニュー通りSpringFrameworkやAOPの基本に関して取り扱い、古い記憶をリファインメントしつつ、もちろん中には初めて知ることもある内容でした。 残りの日は、SpringBootを中心に取り扱い、今まさに業務で使用している内容でした。 中でも個人的にはテストケースを書くたためにSpringが提供してくれる機能を一部しか使っていないことを知ることができたのが今回の研修での一番の収穫でした。

私の今までの経験上、とりわけテストケース作成は最初に作成した人のものをベースに右へ倣えで作成していくパターンが多く、 テストケースの書き方を深堀りした記憶も改善しようと考えたこともなく、いかにその状況に「漬かって」いたかを実感しました。

四日間という期間は少し長かったですが、新年のスタートを切るには良い研修経験となりました。 また機会があれば、別の研修にも参加したいと思います。

それでは、メシ行ってきます。

OpenAPI を利用した開発フロー

こんにちは、デジタルイノベーションラボの飯島です。 今回は、OpenAPI を利用した開発とデプロイまでのフローをざっくり紹介します。

アプリケーション構成

バックエンドは Kotlin + SpringBoot, フロントエンドは TypeScript + React になります。 バックエンドが用意した API をフロントエンドが叩く、一般的なアプリケーションです。

フロー

1. OpenAPI 定義出力用の Interface を実装したコントローラーを作成

簡単なサンプルですが、以下のような Interface を作成し、implement してコントローラーを作成します。

@Tag(name = "UserCreate", description = "ユーザーの登録")
interface UserCreateController {

  @Operation(summary = "ユーザー登録")
  @ApiResponses(
      ApiResponse(responseCode = "200", description = "登録成功"),
  )
  fun create(user: User): HttpResponse
}

data class User(val name: String)

実装クラスに直接アノテーションを記載しても良いのですが、API 定義と実装が混在すると可読性が下がるため、Interface を分けています。

アノテーションspringdoc-openapiで提供されているものを使っています。

2. Interface から OpenAPI 定義の yaml ファイルを生成する

openapi-generator gradle plugin を使用し、Interface から OpenAPI 定義の yaml ファイルを生成します。

3. 生成された yaml ファイルから、フロントエンド用のコードを生成する

OpenAPI Generator を利用して、バックエンドの API を呼び出すための TypeScript コードを生成します。 生成されたコードの内部で使用される Http client については、axios や fetch, ajax など複数の中から選択できます。 docker での生成にも対応しているので、バックエンド側で生成した openapi.yml を引数に generator を実行します。

4. 生成された API 呼び出しコードを利用してフロントエンドをコーディングする

React で画面を作り、3 で生成されたコードを使用してバックエンドとやりとりするようにします。 以下のコードでは、UserCreateApi, createConfiguration, ServerConfiguration がそれぞれ自動生成されたコードになります。 先ほどバックエンドの Interface に定義した create メソッドが UserCreateApi に用意されています。

  const api = new UserCreateApi(
    createConfiguration({
      baseServer: new ServerConfiguration(url, {}),
    })
  )

  api.create({
    name: "taro"
  })

生成されたコードも TypeScript なので、型安全に使用することができます。

5. Slack からデプロイする

弊社ではほぼ全てのプロジェクトが Slack からデプロイできるようになっています。 動作確認などで検証環境にデプロイする用にデプロイマン、本番環境にリリースする用にリリースマンという bot を作ってあるので、コマンド一つで GitHub から簡単にデプロイすることができます。

最後に

バックエンドの API 定義箇所とフロントエンドの呼び出し箇所は、受け渡すデータは同じなのに言語が違うことで書き方が変わってくるため、こうして自動化できるとコーディングがかなり楽になります。 open-api generator の具体的な使い方などはまた別の機会に記事にしたいと思います。

チームのコミュニケーションについて

クオカード デジタルイノベーションラボの齋藤です。

今回はチーム内のコミュニケーションについて説明します。

MTG

デジタルイノベーションラボではCOVID‑19の影響で2020年の春頃からフルリモートになっています。 現在はスクラムで進めており、毎日チーム毎にデイリースクラムを実施しています。

Google Meet、Slackのhuddleなどチームによって使うツールは異なっていますが、MTGは全てオンラインで行っています。たまに他部署とMTGを行う事がありますが、そちらも基本的に全てオンラインになっています。

またスプリント毎のスプリントレトロスペクティブの他に、月1でチーム全体での振り返りを行っています。

Slack

デジタルイノベーションラボではできるだけチームで協力して業務を進める形にしようとしており、割と頻繁にコミュニケーションを取っている方ではないかと思います。

仕様の認識合わせや実装中に困っている事などはまずSlackで議論し、込み入った話になってきたらhuddleで話し合うという進め方になっています。

スプリント中のやりとり

フルリモートになる前からできるだけ自分が何をしているか、確認されなくても周囲の人に伝わるようにしようとしていましたが、リモート中心になってからよりそこを意識するようにしています。

周囲が何をしているかわからないと、リリース直前になって問題に気づいてリリース延期になったり、もしくは周囲からのヘルプを得られず嵌ってしまうなどの問題が起きやすいと考えています。

具体的にはGitのpushをまめに行う、Jiraのチケットにまめにコメントする、またプログラムが完成してからドキュメントを書くのではなく、実装中にWIPという形でドキュメントを公開し、随時追記・修正していく等の進め方にしています。

また悩んでいる事やこれからやろうとしている事をSlackのTimesでコメントしたりしています。

このような対応を行う事により、もし進め方や進めている作業に問題があった場合は早めに周囲の人からコメントをもらえたり、困っている内容について知見のあるメンバーからヘルプを受けたりできるようにしています。

Zoom飲み

上記のように、チーム内のコミュニケーションはそれなりにうまくいくようになってきたと思います。ただ他チームのメンバーとやりとりする機会がそれほど多く無い為、新しく入社したメンバーが他チームにどういう人がいるかわからない、また馴染むのに時間がかかるという問題が起きています。

その為希望者でZoom飲みを実施してみましたが、何の準備もしていなかった為か緊張感のある飲み会になってしまいました。

何かやることを決めた方が話しやすくなりそうというアイデアが出たのでゲームをやってみたところ盛り上がったので、今後も色々と試行錯誤していこうと思います。