Project

General

Profile

Actions

バグ #1585

closed

OpenSSL 3.x 環境 (ubuntu 22.04 等) で mikutter が起動しない

Added by Izumi Tsutsui about 2 years ago. Updated 2 months ago.

Status:
終了
Priority:
通常
Assignee:
Target version:
プラグイン名:
world
ブランチ:
クラッシュする:
Yes

Description

概要

ubuntu 22.04 LTS で mikutter 5.0.4 が起動しない。
OpenSSL 3.x で deprecated とされた blowfish が使われていることが原因と思われる。

現象

bundler を設定して mikutter を起動すると以下の "unsupported" の OpenSSL のエラーが出力されて起動に失敗する。

notice: {MIKUTTER_DIR}/core/miquire_plugin.rb:154:in `block in load': plugin loaded: {MIKUTTER_DIR}/plugin/world/world.rb
/home/tsutsui/mikutter/plugin/world/keep.rb:131:in `initialize': unsupported (OpenSSL::Cipher::CipherError)
    from /home/tsutsui/mikutter/plugin/world/keep.rb:131:in `new'
    from /home/tsutsui/mikutter/plugin/world/keep.rb:131:in `decrypt'
    from /home/tsutsui/mikutter/plugin/world/keep.rb:37:in `block in accounts'
    from /home/tsutsui/mikutter/plugin/world/keep.rb:34:in `synchronize'
    from /home/tsutsui/mikutter/plugin/world/keep.rb:34:in `accounts'
    from /home/tsutsui/mikutter/plugin/world/world.rb:39:in `load_world'
    from /home/tsutsui/mikutter/plugin/world/world.rb:80:in `block (3 levels) in <top (required)>'

原因

world plugin の decrypt で使用している encrypt(), decrypt() で使用している blowfish の bf-ecb
OpenSSL 3.x で deprecated とされていて(少なくともデフォルトの状態では)使えなくなっていることが原因と思われる。
source:plugin/world/keep.rb@a94158ee#L131

参考:
https://www.openssl.org/docs/manmaster/man7/migration_guide.html#Deprecated-low-level-encryption-functions
https://wiki.openssl.org/index.php/OpenSSL_3.0#Providers

対応案

暗号化というか情報秘匿ではなく難読化が目的であれば、暗号アルゴリズムを使う必然性は薄くて
base64 とかでも同じという気はする。(key も乱数生成で config に保管しているようなので)

ただ、変更すると migration 処理の実装が必要になってそれはそれで大変?


Files

0001-added-OpenSSL-ver3.patch (5.27 KB) 0001-added-OpenSSL-ver3.patch git format-patch developで生成したpatch ncaq エヌユル, 2022-05-25 19:40
0001-added-OpenSSL-ver3.patch (5.28 KB) 0001-added-OpenSSL-ver3.patch ncaq エヌユル, 2022-05-25 21:30
osc-mikutter-compatibility.png (52.9 KB) osc-mikutter-compatibility.png Izumi Tsutsui, 2022-07-17 02:14
openssl.cnf.diff (662 Bytes) openssl.cnf.diff Izumi Tsutsui, 2022-12-07 01:02
1585-use-own-blowfish-impl.patch (40.7 KB) 1585-use-own-blowfish-impl.patch Osamu Koga, 2023-10-05 20:56
0001-README-blowfish-OpenSSL.patch (1.79 KB) 0001-README-blowfish-OpenSSL.patch Izumi Tsutsui, 2023-11-25 15:37

再現手順

  1. ubuntu 22.04 をインストールする
  2. ログインして端末を起動する
  3. 以下を実行して mikutter を入れて起動
    sudo apt install make gcc git ruby bundler libcairo-dev
    git clone git://mikutter.hachune.net/mikutter.git
    cd mikutter
    bundle config set --local path vendor/bundle
    bundle install
    ruby mikutter.rb
    
Actions #1

Updated by ncaq エヌユル almost 2 years ago

一応外部ファイルで難読化していることを前提とした設定ファイルの取り扱いをしているpluginがあるかもしれないので、
とりあえず適当に、
[class OpenSSL::Cipher::AES256 (Ruby 3.1 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/class/OpenSSL=3a=3aCipher=3a=3aAES256.html)
あたりを使うように書き換えれば良さそうな気もします。
現状マイグレーションは無理なのでユーザにはファイルを削除する手間をかけてもらう必要がありますが。

将来的にまた暗号ロジックが非推奨になった時のことを考えると、
マイグレーションするために、
使っている暗号ロジック名、
例えば "aes-256-cbc"
とかを別のフィールドで持っておけば、
Betaの段階で察知していればStableで変換が可能になりそうですね。

基本的にこのクラスを直接使ってデータを暗号化することは避けてください。通常はより高水準なインターフェースが利用可能なはずです。必要なのは暗号アルゴリズムを指定するため OpenSSL::Cipher.new で暗号オブジェクトを生成することだけでしょう。

[class OpenSSL::Cipher (Ruby 3.1 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/class/OpenSSL=3a=3aCipher.html)

と書かれているのが気になりますが、
元々ご指摘の通りあんまりセキュアじゃないので、
そんなに気にしなくても良いような気がします。

と考えますが、
どうでしょうか。

Actions #2

Updated by ncaq エヌユル almost 2 years ago

とりあえず動くようにしたので、
パッチを添付します。

これが最良の方法かは分からないですが、
とりあえず動かないのは困ったので。

Actions #3

Updated by ncaq エヌユル almost 2 years ago

solargraphを後から入れたら色々と警告されたので、
自分が書いた中で簡単に対処できるやつを対処して追記。

Actions #4

Updated by Izumi Tsutsui almost 2 years ago

ずっと返信を書くのをサボっててすいません。

いろいろと考えていたのですが、ざっくり以下を考える必要があるかなと思っています。
  • マイグレーションの要否
  • 難読化の仕様
  • blowfishの使用可否

マイグレーションの要否

mikutter の歴史からすると、従来から互換性を重視するという姿勢があると思います。
実際、 source:plugin/world/keep.rb@a94158ee#L139 にもすでに
migrate_older_account_data という実装がありますし、
toshi_a さんの OSC京都のスライドでも「使ってもらうための互換性」には
こだわりがあるように見えます。
https://docs.google.com/presentation/d/1xqn2vqqUi6CGIn0WZlqMU07F4XIo4GzUIzErIfWaijY/preview?pli=1#slide=id.g38e48d30b_0188

難読化の仕様

もし、 blowfish 以外のものを使うように変える場合に何を使うかという選択ですが、
悪意を持って調べようとする人に対しては key も同じ config file に書いているようなので
強い暗号を持ってきてもあまり意味はなく単に重くなるだけ、かつ、
時が経つとまた使えなくなるリスクが残ってしまうような気がします。
(AES256 が使えなくなる頃まで mikutter が生き残っているかという話はありますが……)

難読化する目的は「たまたま目に入ってしまうことを防ぐ」というほかには
botによる検索避けくらいだと思うので、本文に書いているように
消えることのない base64 的なエンコードのほうがいいような気がしています。

が、ここは各人の好みの問題もありますし、世間の攻撃の傾向分析が必要なところかとも
思っています。

blowfishの使用可否

今さらながら OpenSSL 3.0 についていくつか調べてみましたが、
古い暗号アルゴリズムについては完全に削除されたわけではなく、
デフォルトで無効化されているだけで、"legacy provider" と呼ばれる
古い実装を有効にすることも可能なようです。

具体的には openssl.cnf で以下のような記述をすればいいようです。

# ...
[provider_sect]
default = default_sect
legacy = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1

なお、いろいろ調べていたところ、本家 ruby openssl の GitHub repository でも
https://github.com/ruby/openssl/issues/500
で同様の問題が挙がっており、いまや ruby コミッタとして活躍中のレニウム氏のコメントで
ruby の openssl 実装で legacy provider をロードできるようなしくみが必要
という提案もあるようです。

とりあえずシステム共通の openssl.cnf ではなくユーザー固有設定で legacy provider を
有効にできるようならドキュメントによる回避が早そうかなと思ったのですが、
すぐには出てきませんでした。


というわけで、実装よりも仕様検討から必要かなという気がするので、
チケットステータスとしては「toshi_aの判断待ち」みたいな雰囲気です。
が、 toshi_a さんもしばらく忙しいみたいなので皆さんの意見も
うかがってみたいです。(放置したあげく丸投げですいません)

Actions #5

Updated by ncaq エヌユル almost 2 years ago

私も出来れば自動マイグレーションしたかったのですが、古い暗号読み込めないならどうやっても無理じゃんと思って諦めてしまったという経緯がありました。
legacy providerで読み込めるようになればそれを使って変換してやるのが正しい道だと思います。
base64にするのは別に何でも良いと思いますが、一つだけ気になる点があるとすると、クラッシュレポートとかで送ってないだろうかということぐらいですが、見た感じ送ってないので大丈夫っぽいですかね。

Actions #6

Updated by toshi_a 初音 almost 2 years ago

暗号化の狙い

アクセストークンなどはもともと設定ファイルに平文で保存されていましたが、 #639 によって設定ファイルのフォーマットがMarshalからYAMLに変更されて簡単に見られるようになってしまったので、設定ファイルをエディタで開いて確認・編集するときにこういった情報が見えてしまうと気分が悪いという理由で、 #640 にて別ファイルへの切り出し・暗号化を行いました。このときの仕組みがWorld pluginの永続化にも転用されています。

情報漏洩からの保護は目的としていません。

もし、 blowfish 以外のものを使うように変える場合に何を使うかという選択ですが、
悪意を持って調べようとする人に対しては key も同じ config file に書いているようなので
強い暗号を持ってきてもあまり意味はなく単に重くなるだけ、かつ、
時が経つとまた使えなくなるリスクが残ってしまうような気がします。
(AES256 が使えなくなる頃まで mikutter が生き残っているかという話はありますが……)

難読化する目的は「たまたま目に入ってしまうことを防ぐ」というほかには
botによる検索避けくらいだと思うので、本文に書いているように
消えることのない base64 的なエンコードのほうがいいような気がしています。

OpenSSLなどを使って真面目に暗号化する必要がないのはたしかにそのとおりですね。

自動マイグレーション

これも、全てのユーザーが全く意識せずにバージョンアップ(データのマイグレーション)をできるようにすべきです。

- Blowfishが利用可能 :: デコードして新ファイルにコンバート
- Blowfishが利用不可 :: ここが問題

結論から言うと、legacy providerをロードする良い方法がないようなので(費用対効果を考えると実装したくなさすぎる)、切ってしまうのが一番現実的な気がします。そのうえで #1585-4 が回避策として働くのであればそのことを周知してもいいかもしれません。

一度でもコンバートされてしまえばOpenSSL3でも問題なく起動できるようになるため、コンバートされるチャンスを増やすために早めにリリースしたほうが良いです。このままの状態で長期間放置しておくと、影響範囲が大きくなっていきます。(もうすでにかなりの期間放置していますが・すみません)

Actions #7

Updated by Izumi Tsutsui over 1 year ago

toshi_a 初音 さんは #note-6 で書きました:

結論から言うと、legacy providerをロードする良い方法がないようなので(費用対効果を考えると実装したくなさすぎる)、切ってしまうのが一番現実的な気がします。そのうえで #1585-4 が回避策として働くのであればそのことを周知してもいいかもしれません。

超いまさらながら WSL ubuntu 22.04.1 LTS で試してみましたが、
/etc/ssl/openssl.cnf#note-4 の通り以下のように修正すれば blowfish 使えて mikutter も起動するようです。
openssl.cnf.diff

--- /etc/ssl/openssl.cnf.orig    2022-07-04 20:20:23.000000000 +0900
+++ /etc/ssl/openssl.cnf    2022-12-07 00:53:41.171961600 +0900
@@ -57,6 +57,7 @@
 # List of providers to load
 [provider_sect]
 default = default_sect
+legacy = legacy_sect
 # The fips section name should match the section name inside the
 # included fipsmodule.cnf.
 # fips = fips_sect
@@ -70,8 +71,9 @@
 # OpenSSL may not work correctly which could lead to significant system
 # problems including inability to remotely access the system.
 [default_sect]
-# activate = 1
-
+activate = 1
+[legacy_sect]
+activate = 1

 ####################################################################
 [ ca ]

一度でもコンバートされてしまえばOpenSSL3でも問題なく起動できるようになるため、コンバートされるチャンスを増やすために早めにリリースしたほうが良いです。このままの状態で長期間放置しておくと、影響範囲が大きくなっていきます。(もうすでにかなりの期間放置していますが・すみません)

https://akkiesoft.hatenablog.jp/entry/20221207/1670371200

Actions #8

Updated by Izumi Tsutsui over 1 year ago

Izumi Tsutsui さんは #note-7 で書きました:

超いまさらながら WSL ubuntu 22.04.1 LTS で試してみましたが、
/etc/ssl/openssl.cnf#note-4 の通り以下のように修正すれば blowfish 使えて mikutter も起動するようです。
openssl.cnf.diff

「システムの /etc/ssl/openssl.cnf を書き換えられない(もしくは見つからない)」という場合は以下でよいようです
  • openssl version -d で OpenSSL の設定ファイルディレクトリを確認
  • OpenSSL 設定ファイルディレクトリから openssl.cnf~/mikutter/openssl.cnf 等にコピー
  • openssl.cnf.diff と同等の差分を当てる
  • 環境変数 OPENSSL_CONF に上記でコピー修正した ~/mikutter/openssl.cnf を指定して mikutter を起動する
    OPENSSL_CONF=~/mikutter/openssl.cnf ruby mikutter.rb
Actions #9

Updated by Izumi Tsutsui 11 months ago

https://github.com/ruby/openssl/pull/635
add OpenSSL Provider support
として Ruby 側に legacy provider を使えるしくみが入っているような感じです。

また元気のあるときに見てみます

Actions #10

Updated by Osamu Koga 8 months ago

対策版Rubyのリリースも秒読みという雰囲気になってきましたが、それはそれとしてBlowfishを自前実装したものでOpenSSLを置き換えてみました。OpenSSLのコードをそのまま移植した感じなのでApache Licenseを入れてます。

そもそも難読化したいだけなのにBlowfishはオーバーキルでは?という話は強く同意しますが、いっぺんに色々やると収集がつかなくなりそうなので既存実装の置き換えだけにしてます。

一応手元で動くことは確認しましたが、あまり自信がないので取り込むにしてもその前に何人か人柱になってもらいたいです。

Actions #11

Updated by Izumi Tsutsui 8 months ago

  • Status changed from 分類待ち to パッチ適用待ち

Osamu Koga さんは #note-10 で書きました:

対策版Rubyのリリースも秒読みという雰囲気になってきましたが、それはそれとしてBlowfishを自前実装したものでOpenSSLを置き換えてみました。

神おさけー!

とりあえず ubuntu 22.04.2 LTS では動いているっぽいです
https://social.mikutter.hachune.net/@tsutsuii/111183131980584635

Actions #12

Updated by toshi_a 初音 6 months ago

  • Status changed from パッチ適用待ち to レビュー待ち
  • Assignee set to Izumi Tsutsui
  • ブランチ set to topic/1585-bf

pushしました。内容の確認お願いします

Actions #13

Updated by Izumi Tsutsui 6 months ago

topic/1585-bf で動作確認して既存の config での起動もOKです。

先走って pkgsrc にパッチを取り込んで思ったのですが、
blowfishの実装がOpenSSLベースでLICENSE.txtファイルも入っているのでそれについてREADMEで言及したほうがいいのだろうか、
というのが気になっているポイントです。

一応「mikutter上で動作するプラグインは適応対象外」との記載はありますが、
パッケージメンテナからすると
対象となるライセンスは一か所に一通り書いてあったほうが誤解は少ない、
みたいなポイントはあります。
https://github.com/NetBSD/pkgsrc/blob/5933bd5/net/mikutter/Makefile#L17
(既存のバンドルプラグインのライセンスがすべてMITであるという確認がされているか、という問題はありますが……)

とりあえずのREADME修正案は添付しておきます。

Actions #14

Updated by Osamu Koga 5 months ago

ちゃんとREADME読んだことなかったんですが

mikutter上で動作するプラグイン及び添付されている外部ライブラリ(vendor以下の全て)については、このライセンスの適応対象外です。

こういう文言あったんですね。現時点ではvendorディレクトリがないので過去のなんかの関係っぽいですが、blowfish実装だけvendor/に移してもいいかもしれません。

(gemとして公開するのが一番シンプルな気もしますが、同じようなgemがすでに存在する(が微妙にバグっている)、mikutterで必要なとこしか実装してない、これ以上メンテする気がないなどの理由で消極的です……。)

Actions #15

Updated by Izumi Tsutsui 3 months ago

  • Assignee changed from Izumi Tsutsui to Osamu Koga

Osamu Koga さんは #note-14 で書きました:

ちゃんとREADME読んだことなかったんですが

mikutter上で動作するプラグイン及び添付されている外部ライブラリ(vendor以下の全て)については、このライセンスの適応対象外です。

こういう文言あったんですね。現時点ではvendorディレクトリがないので過去のなんかの関係っぽいですが、blowfish実装だけvendor/に移してもいいかもしれません。

としぁさんとこの件で話をしたのですが、
「vendorディレクトリはまだbundlerが無い頃にgemを入れていたところなので、今はプラグインはそのままplugin以下に入れれば良い」
ということでした。なので、としぁさん的には今のパッチの構成のままでよいそうです。

あとは、(私自身を含む)パッケージ管理者目線で「どのようなライセンスのコードが含まれるのか」がどこかに書いてあったほうがわかりやすい、
というくらいなので #note-130001-README-blowfish-OpenSSL.patch のようにREADMEに一文書いておけば十分かと思います。

ざっくりこんな感じでよければおさけーさんでコミットしちゃってください、という感じですが、どうでしょう

Actions #16

Updated by Osamu Koga 2 months ago

  • Status changed from レビュー待ち to 終了

topic/1585-bfにつついさんの提案したREADMEの文言を加えてdevelopにマージしました。

Actions

Also available in: Atom PDF