patorashのブログ

方向性はまだない

PaperclipがImageMagickのデフォルト設定の影響で動かなくなったのを直した

昨日、Macのセットアップが終わったという話をしました。

patorash.hatenablog.com

そして、Docker立ち上げて作業後にrspecを流したら、全然関係ないところがエラーで落ちるじゃないですか…😰

pryで止めて、@model.errorsを出力してみると…

@details={:report=>[{:error=>"Paperclip::Errors::NotIdentifiedByImageMagickError"}]}, @messages={:report=>["Paperclip::Errors::NotIdentifiedByImageMagickError"]}>

はて、ImageMagickImageMagickはインストールしてるぞ?と思い、バージョンチェック。

root@67a587ce1af1:/app# convert --version Version: ImageMagick 6.9.10-23 Q16 x86_64 20190101 https://imagemagick.org Copyright: © 1999-2019 ImageMagick Studio LLC License: https://imagemagick.org/script/license.php Features: Cipher DPC Modules OpenMP Delegates (built-in): bzlib djvu fftw fontconfig freetype heic jbig jng jp2 jpeg lcms lqr ltdl lzma openexr pangocairo png tiff webp wmf x xml zlib

やっぱりあるじゃないか…。

調査してみると、Paperclipを使っていても落ちるところと落ちないところがあり、PDFを添付しているところだけが落ちていた。

調査開始

Paperclipというキーワードを起点にググってみると、Paperclip.options[:current_path] = '/usr/bin/'にしてみろというのを見かけたりしたので、convertのパスを確認後に設定してみるも、状況は変わらず。

ImageMagickというキーワードを起点に変更し、ググってみたら、以下のページを発見。

yasuhiroki.hatenablog.com

何かしらのヒントがあるのかなと思って読んでみたところ、脆弱性対応のためにpolicy.xmlを使うように変わったらしいことが判明。 以前のDockerイメージでImageMagickの何のバージョンを使っていたかはもうわからないけれど、今の6.9.10-23では、policy.xmlを使ってそう。

上記の記事では、HTTPSのところをコメントアウトしたとあったが、うちで起きてるのはそもそもそういう話じゃないだろうしなぁ…と思いながらも/etc/ImageMagick-6/policy.xmlの中身を見てみた。 すると…

<policymap>
  <!-- 略 -->
  <!-- disable ghostscript format types -->
  <policy domain="coder" rights="none" pattern="PS" />
  <policy domain="coder" rights="none" pattern="PS2" />
  <policy domain="coder" rights="none" pattern="PS3" />
  <policy domain="coder" rights="none" pattern="EPS" />
  <policy domain="coder" rights="none" pattern="PDF" />
  <policy domain="coder" rights="none" pattern="XPS" />
</policymap>

disable ghostscript format typesの文字があった👻 そして、pattern="PDF"のrights="none"ということで、権限がなさそう…。

policy.xmlの前半のほうに、書き方が書いてありました。

<!--
  Configure ImageMagick policies.

  Domains include system, delegate, coder, filter, path, or resource.

  Rights include none, read, write, execute and all.  Use | to combine them,
  for example: "read | write" to permit read from, or write to, a path.

  Use a glob expression as a pattern.

  サンプルがズラズラと…
-->

解決!

pattern="PDF"のところのrightsをnoneからread|writeに変更すれば動きそうかなと思い、設定してからrspecを実行したところ、見事成功!👊

事なきを得ました。

二度と起きないようにDockerfileを修正する

そうはいっても、現状だとDocker Imageを作り直すたびにnoneに戻ってしまうので、Dockerでビルドするときにsedでを書き換えるようにしておきました。

# ImageMagickのpolicy.xmlを修正してpdfを扱えるようにする
RUN sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml

そして、dockerをビルド後、再びテストを実行して問題ないことを確認!やったぜ!!

まとめ

まだPaperclip使ってるの!?とか言わないでやってください。色々あるんです!