バグ #1585
openOpenSSL 3.x 環境 (ubuntu 22.04 等) で mikutter が起動しない
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
再現手順
- ubuntu 22.04 をインストールする
- ログインして端末を起動する
- 以下を実行して 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
Updated by ncaq エヌユル about 1 year 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)
と書かれているのが気になりますが、
元々ご指摘の通りあんまりセキュアじゃないので、
そんなに気にしなくても良いような気がします。
と考えますが、
どうでしょうか。
Updated by ncaq エヌユル about 1 year ago
とりあえず動くようにしたので、
パッチを添付します。
これが最良の方法かは分からないですが、
とりあえず動かないのは困ったので。
Updated by ncaq エヌユル about 1 year ago
solargraphを後から入れたら色々と警告されたので、
自分が書いた中で簡単に対処できるやつを対処して追記。
Updated by Izumi Tsutsui 11 months 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 さんもしばらく忙しいみたいなので皆さんの意見も
うかがってみたいです。(放置したあげく丸投げですいません)
Updated by toshi_a 初音 10 months ago
暗号化の狙い¶
アクセストークンなどはもともと設定ファイルに平文で保存されていましたが、 #639 によって設定ファイルのフォーマットがMarshalからYAMLに変更されて簡単に見られるようになってしまったので、設定ファイルをエディタで開いて確認・編集するときにこういった情報が見えてしまうと気分が悪いという理由で、 #640 にて別ファイルへの切り出し・暗号化を行いました。このときの仕組みがWorld pluginの永続化にも転用されています。
情報漏洩からの保護は目的としていません。
もし、 blowfish 以外のものを使うように変える場合に何を使うかという選択ですが、
悪意を持って調べようとする人に対しては key も同じ config file に書いているようなので
強い暗号を持ってきてもあまり意味はなく単に重くなるだけ、かつ、
時が経つとまた使えなくなるリスクが残ってしまうような気がします。
(AES256 が使えなくなる頃まで mikutter が生き残っているかという話はありますが……)難読化する目的は「たまたま目に入ってしまうことを防ぐ」というほかには
botによる検索避けくらいだと思うので、本文に書いているように
消えることのない base64 的なエンコードのほうがいいような気がしています。
OpenSSLなどを使って真面目に暗号化する必要がないのはたしかにそのとおりですね。
自動マイグレーション¶
これも、全てのユーザーが全く意識せずにバージョンアップ(データのマイグレーション)をできるようにすべきです。
- Blowfishが利用可能 :: デコードして新ファイルにコンバート
- Blowfishが利用不可 :: ここが問題
結論から言うと、legacy providerをロードする良い方法がないようなので(費用対効果を考えると実装したくなさすぎる)、切ってしまうのが一番現実的な気がします。そのうえで #1585-4 が回避策として働くのであればそのことを周知してもいいかもしれません。
一度でもコンバートされてしまえばOpenSSL3でも問題なく起動できるようになるため、コンバートされるチャンスを増やすために早めにリリースしたほうが良いです。このままの状態で長期間放置しておくと、影響範囲が大きくなっていきます。(もうすでにかなりの期間放置していますが・すみません)
Updated by Izumi Tsutsui 6 months ago
- File openssl.cnf.diff openssl.cnf.diff added
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でも問題なく起動できるようになるため、コンバートされるチャンスを増やすために早めにリリースしたほうが良いです。このままの状態で長期間放置しておくと、影響範囲が大きくなっていきます。(もうすでにかなりの期間放置していますが・すみません)
Updated by Izumi Tsutsui 6 months 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
等