会社のブログに記事を書いた 3

developers.bookwalker.jp

タイトル入れるだけでイイカンジになるサムネイルテンプレートを作ったので、これでサムネイルに悩まなくて済む。

このOpenID Connectの話自体は本当に

が最速でtwitterで話題になってた当初から気になってはいたのだけれど、これを仕事のterraformのリポジトリに反映させられたのは2022年1月下旬くらい。

これで新しいコンポーネントに対する継続的デプロイの設定がかなり楽になったのでこういう楽さをもっと高めていきたい。

有料のウイルス対策ソフトを買う必要はあるのか、ないのか

最近友人たちとの間で、マルウェアのEmotetが最近流行している、という話から有料のウイルス対策ソフトを買う必要はあるのか、ないのか、という話に発展したのでその時に話した内容のメモというか再整理。

有料ウイルス対策ソフトは「コンピューターウイルスに感染するかもしれない」という不安からお金を取っている

と書くと表現が意地悪すぎるかもしれないが、要は保険と同じである。

平時はほとんど1役に立たないが、何かあったときに被害の増大を防いでくれる、あるいは何かが起こりそうなときに止めてくれる。
要するにユーザーのリスクを減らしてあげることによって売り上げを立てている。

極論、コンピューターウイルスの被害に遭いたくなければそもそもコンピューターを使わなければいい

しかし、それはコンピューターとインターネットから得られる全ての利便性、メリットを享受できないということでもある。

例えるなら「詐欺師が怖いので訪問者に対して家のドアは一切開けません」と言ってるようなものだ。

「消防署の方から来ました」と言う詐欺師もコンピューターウイルスも、家のドアを開ける( = 拡張子を隠したexeファイルやExcelのマクロといった形で実行してしまう)まではあらゆる手段を使って騙そうとしてくる。

どうにかしてウイルスを実行させようとする以上、どうしても手段には一定の特徴2がでざるを得ず、それを頭の片隅に置いておけば実行する前に気付けることもある。

なんにせよ、そういった注意、確認でも減らせるようなリスクを怖がるあまり、そもそもコンピューターを使わないという選択は、インターネットが普及しきったこの現代ではあまりにもデメリットが大きすぎる。

ウイルス対策ソフトはどのようにしてウイルスを検知、防御しているのか

既知のウイルス

既知のウイルスは既知なので、実行する前に検出するのもファイルのビット列としての特徴3をスキャン対象と見比べるだけでよく、それなりに簡単である。
検出率を高めるためには、未知だったウイルスの特徴をいかに素早く反映するかが問われるということになる。

例えるなら指名手配犯の顔写真と見比べて止めているようなもので、Windows Updateでたまに見かける「Microsoft Defender Antivirusのセキュリティインテリジェンス更新プログラム」というのはこの"指名手配犯の顔写真集"の更新である。

未知のウイルス

未知のウイルスはというと当然だが"指名手配犯の顔写真集"には載っていないので、事前に検出して全て止めるのは無理4である。

ではどうするかというと、ウイルスにありがちな動作を検知して防御する5
例えるなら泥棒にありがちな動き、建物の裏に回ろうとする、とかを見つけて止めるようなものである。 ただしあくまで動きを見て止めるものであるため、稀に誤検知して問題ないプログラムまで止めてしまう場合がある。

また、動きを見て止めるということはプログラムの一挙手一投足を監視するということであって、CPUをその監視に使う分、本来やりたかったソフトの処理は時間がかかることになる。 もっとも、Microsoft Defenderでもこういったプログラムの動きの監視はしているので、有料のウイルス対策ソフトを入れたときだけ殊更に遅くなるというわけでもない。

では実際、無料のMicrosoft Defenderでどの程度コンピュータウイルスを防げるかというと

既知のウイルスに関する検出率、防御率についてのレポートがこれなのだが、この表の各列は左から順にオフライン時の検出率、オンライン時の検出率と防御率、誤検知数である。

オフライン時の検出率については今はそもそもオンライン時の話をしているので対象外として、"顔写真"で実行前に検出できたものを検出率、検出できなかったが実行されてから止めることができたものを防御率と呼んでいるものと思われる。

オンライン時の検出率の時点で既にかなり優秀だが、他の専業の有料ウイルス対策ソフトのいくつかはMicrosoft Defenderを上回っている。さすが専業である。

防御率はというとこちらはもはや専業の有料ウイルス対策ソフトと比べても誤差と言える。誤検知もわずか1。 こういう検査というのは普通、検知漏れ(偽陰性)を減らそうとして敏感にすればするほど誤検知(偽陽性)も増える6ものなのだが、これほどにまで検知漏れも誤検知も少ないというのはかなり優秀だと言える。

ここまで優秀だと無料なのに防御率が高すぎて逆に少し怪しく思えてきてしまうが、単にWindowsでコンピューターウイルス被害に遭う人が増えるとWindowsを使う人が減って商売あがったりなのでそうならないための投資 & 社会貢献という扱いなのだろう。

結局、有料のウイルス対策ソフトを買って得られるメリットとは

安心感と、守ってくれなかったときに文句を言う権利が買える。

文句を言う権利が買える、なんてふざけているのかと言われるかもしれないが、僕個人としては結構重要だと思う。

無料でサービスを享受しているあいだは、サービスに要望を出す権利はともかく、サービスに文句を言う権利まではないと思う。
稀によく見るあのラーメンの漫画の、「『金を払う』とは仕事に責任を負わせること、『金を貰う』とは仕事に責任を負うということだ」7である。
当該の作品では「金の介在しない仕事は絶対に無責任なものになる」と続く。Microsoftの場合、前述の通りWindowsでコンピューターウイルス被害に遭う人が増えるとWindowsを使う人が減るだろうということで間接的に利益を得ているので無責任な仕事はしないだろうとは思いつつも、無料である以上、やはりその仕事に責任を負わせることはできない。

サービスを無料で享受している以上、無料の"サービス"の範囲を超える、ここではすなわちMicrosoft Defenderが防御しきれずマルウェアの被害にあってしまった場合のことだが、文句を言う権利はなく、自己責任と言われても仕方ない。

ほとんどの有料ウイルス対策ソフトは1年あたりに換算すると高くても5000円程度である。
さて、この「安心感と、守ってくれなかったときに文句を言う権利」に対してお金を払うか?払わないか?

このメリットと対価のどちらを大きく見るかは人によって異なるので、僕はどちらがいいと断定的には語らないことにする。


  1. 既知のウイルスに感染していないことを確認できる程度の役には立つ

  2. 「ゲームを作ってみたという友人(がウイルスを実行してしまっており、その友人になりすましてメッセージを送ったウイルス)からゲームのテストプレイをお願いされる」とか「懸賞に当たりました!とか言われてカウントダウンを表示され焦らされる」とか「仕事で使うzipファイルに見せかけて『パスワードは〇〇です』などの文言と一緒に送られてくる」とか

  3. ウイルス定義ファイル(パターンファイル)とは - IT用語辞典 e-Words

  4. ちょっと改変しただけだったりすると部分的に一致して事前検出できたりもする

  5. ヒューリスティック検知(heuristic scan)とは - IT用語辞典 e-Words

  6. ウイルス対策ソフトに限らず、新型コロナウイルスの検査であるとか、Googleをはじめとした情報検索システムのような、真か偽か判定するもの全般に言える。情報検索システムの分野においては"検索性能"をF値またはF尺度という値で評価されることがある。F値についてはこのブログ記事がわかりやすい。新型コロナウイルスの検査では偽陰性の数がわからないのでF値は計算できない。

  7. 引用するだけでお金を落とさないのは筋が通らないというのと単に気になるというのもあってとりあえず、第一巻を電子書籍で買った。このセリフが何巻に出てくるのかは知らないが。

会社のブログに記事を書いた 2

またしても書きました。

developers.bookwalker.jp

会社でやっていることを書けるのは会社ブログだけ。 それを引用しつつ自分がやった範囲を書けるのは自分のブログだけ。

読書メーターは僕が当時のトリスタに入って最初に関わったサービスでした。 そのためまずトリスタの文化に慣れながら、開発サイクルに慣れながら、読メのインフラ構成やアプリケーションコードの構造を把握しながらという感じだったため、ニコニコ漫画ほどかかわった範囲は大きくありません。

スプリントに積まれた、すなわち仕事としてやるべきタスクとしては主にweb frontendで特設ページ1を組んで公開したりするのがほとんどでした。

その一方で、スプリントには積まれていない、個人研究として下記のことをやりました。

  • 手動で作られていたAWSリソースを全部Terraformに書き起こした
    • Elastic Beanstalkは書き起こしが困難だったので、ELBなどはECS(Fargate)への移設時にTerraform管理下になった
  • web frontendにReact + Typescript + CSS module + Webpackを導入した
    • SP表示の一部をReactで再実装した
  • manageとsub backendをElastic BeanstalkからECS(Fargate)へ移設した

これらはいずれも、スプリントに積まれたタスクを実装する際に、その効率があまりにも悪すぎたり、構造の再現や把握があまりにも難しかったために我慢しきれなくなってやったものです。

Terraformへの書き起こしについては過去に書いた記事が存在します。 developers.bookwalker.jp

もっとも、Reactでの書き直しについては途中でニコニコ漫画のAWS移設と新バックエンドに注力することになった結果として、 ある程度の書き方は確立したものの総量としては道半ばにも達せていない段階で現在も担当しているエンジニアに託すことになってしまっているのが少々心残りではありますが…

ニコニコ漫画や一迅ブラスでの経験を読書メーターにもフィードバックしていきたい気持ちはある。

会社のブログに記事を書いた

書いてました。

developers.bookwalker.jp

会社でやっていることを書けるのは会社ブログだけ。
それを引用しつつ自分がやった範囲を書けるのは自分のブログだけ。

この記事のうち僕が直接関わったのは

  • TerraformによるAWSリソースの構築
    • 現行PHPについてのEC2インスタンス群、ELB群
    • React用BFFについてのIAMロール、ELB
    • 新バックエンドについてのIAMロール、ELB
    • 課金サブシステムについてのIAMロール、ELB
    • Elasticache
    • 現行PHPと新バックエンドが使うAurora
    • それらの間のセキュリティグループ
    • S3バケット
  • 現行PHP
    • ドワンゴデータセンターからAWSへリフトするにあたっての計画概要の立案
  • React用BFF
    • ecspressoの設定およびECSのサービス定義、タスク定義
  • 新バックエンド
    • ecspressoの設定およびECSのサービス定義、タスク定義
    • 初期構築から2020年末ごろまでのアプリケーションコード
  • 課金サブシステム
    • 小規模な機能追加
    • Elastic BeanstalkからFargateへの移設
      • ecspressoの設定およびECSのサービス定義、タスク定義

あたりです。もちろん全部ひとりでやったわけではありませんが。

関わっていない部分は

  • TerraformによるAWSリソースの構築
    • 現行PHPのジョブキューとして使われているSQS
    • 新バックエンドが使うDynamoDB
    • 新バックエンドのオートスケーリングの具体的閾値調整
    • 課金サブシステムが使うAurora
    • それらの間のセキュリティグループ
  • 現行PHP
    • アプリケーションコード全般
  • React用BFF
    • アプリケーションコード全般
  • 新バックエンド
    • 2021年以降のアプリケーションコード
  • 課金サブシステム
    • アプリケーションコードの大部分

あたり。

こうやって書き出してみるとむちゃくちゃ色々やったなぁ、という気分になるんですがそれでもまだ課題はたくさんあるんですよねー

ニコニコ漫画の旅は続く。

マルチDBでリードレプリカを有効にしたAPIモードのRails7において書き込み系リクエストが失敗する事象の対処方法と原因

掲題の通り、

  • APIモードのRails7
  • セッションストアは未設定
  • ActiveRecord::Middleware::DatabaseSelector::Resolver を使ってマルチDBでプライマリとリードレプリカの自動切換えをしている
  • POST, PATCH, PUT, DELETEリクエストにおいて500エラーが返る
  • ログには ActionDispatch::Request::Session::DisabledSessionError が出力されている

ような事象の対処方法と原因です。

この記事は2022/01/16時点で最新であるRails 7.0.1に基づいて書いています。

まず最初に手っ取り早く動く対処方法だけ述べます。このような挙動になる理由と関係箇所のソースコード読解、考えうる対処方針は記事の続きにて。

手っ取り早く動く対処方法

/config/application.rb または /config/environments/ 以下の該当環境の設定に

  config.session_store :cookie_store
  config.middleware.insert_before ActiveRecord::Middleware::DatabaseSelector, ActionDispatch::Cookies
  config.middleware.insert_before ActiveRecord::Middleware::DatabaseSelector, ActionDispatch::Session::CookieStore

と書くとひとまず動作するようにはなる。

続きを読む

開発者でない普通の人たちがコードを書く、プログラミングの民主化

Win10の記憶域は論理セクタサイズが異なるHDDを追加できない

内容としてはもうタイトルでオチてるんですが。

僕は自分のPCのデータ領域を4台のHDDを束ねたWin10の記憶域(StoragePool)の双方向ミラーで構築しています。

先日、そのうちの1台に回復不能セクタが出たので外して交換用HDDを通販で注文しました。

交換用HDDが届いて、PowerShellのAdd-PhysicalDiskでStoragePoolに追加しようとしたところ、エラーが出る。

PS C:\WINDOWS\system32> Get-PhysicalDisk

Number FriendlyName              SerialNumber         MediaType CanPool OperationalStatus HealthStatus Usage            Size
------ ------------              ------------         --------- ------- ----------------- ------------ -----            ----
7      Msft Virtual Disk                              SSD       False   OK                Healthy      Auto-Select      8 GB
3      TOSHIBA MD04ACA600        497WK0ZXFFQC         HDD       False   OK                Healthy      Auto-Select   5.46 TB
5      TOSHIBA MN05ACA800        70U4K0G0F7QE         HDD       False   OK                Healthy      Auto-Select   7.28 TB
2      TOSHIBA MD04ACA300        86IEK46IFSFA         HDD       False   OK                Healthy      Auto-Select   2.73 TB
0      Samsung SSD 860 EVO 500GB S3YANB0K154546K      SSD       False   OK                Healthy      Auto-Select 465.76 GB
4      SPCC Solid State Disk     DC11076307EE02638634 SSD       False   OK                Healthy      Auto-Select 223.57 GB
1      TOSHIBA MG04ACA500A       44PEK07VFK7A         HDD       True    OK                Healthy      Auto-Select   4.55 TB



PS C:\WINDOWS\system32> $NEWDISK = Get-PhysicalDisk -SerialNumber "44PEK07VFK7A"

PS C:\WINDOWS\system32> Get-StoragePool

FriendlyName OperationalStatus HealthStatus IsPrimordial IsReadOnly     Size AllocatedSize
------------ ----------------- ------------ ------------ ----------     ---- -------------
Primordial   OK                Healthy      True         False      20.69 TB      15.46 TB
StoragePool  OK                Healthy      False        False      15.46 TB       9.49 TB



PS C:\WINDOWS\system32> $STORAGEPOOL = Get-StoragePool -FriendlyName "StoragePool"

PS C:\WINDOWS\system32> Add-PhysicalDisk -StoragePool  $STORAGEPOOL -PhysicalDisks $NEWDISK
Add-PhysicalDisk : One or more physical disks are not supported by this operation.
 
Extended information:
One or more physical disks encountered an error during addition to the storage pool.
 
Physical Disks:
{fefdad8d-7f77-7424-5cc4-c8269ebbef94}: この要求はサポートされていません。
 
Activity ID: {3c5c65d6-8a83-0004-cf66-5c3c838ad701}
発生場所 行:1 文字:1
+ Add-PhysicalDisk -StoragePool  $STORAGEPOOL -PhysicalDisks $NEWDISK
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (StorageWMI:ROOT/Microsoft/..._StorageCmdlets) [Add-PhysicalDisk], CimException
    + FullyQualifiedErrorId : StorageWMI 51000,Add-PhysicalDisk
 

PS C:\WINDOWS\system32>

CanPool Trueなのに、と思ってReset-PhysicalDiskしたりUpdate-StorageProviderCache -DiscoveryLevel Fullしたりししていた途中、操作ミスで新しいHDDだけのStoragePoolを誤って作って、作れてしまいました。 つまりこのHDD単独では問題ないということ。

であるならば、このHDDが問題なわけではなく、StoragePool側、あるいはHDDとStoragePoolの間に問題があるに違いないと調べた結果。

はい。

ちなみに新HDDのみでStoragePoolを作ると、作られたStoragePoolもLogicalSectorSizeが4kになっていました。 つまりこちらはこちらで4kセクタネイティブのHDDしか追加できなさそう。

PS C:\WINDOWS\system32> Get-StoragePool | select FriendlyName, LogicalSectorSize

FriendlyName LogicalSectorSize
------------ -----------------
記憶域プール                    4096
Primordial                    
StoragePool                512

記憶域を組んでる皆様は新しいHDDを追加するとき、論理セクタサイズにも気を付けましょう。