MarkDown

WordPressの記事をMarkDownで入力できる “WP Githuber MD” が凄く使いやすい

WordPressの記事をMarkDown入力

WordPressでMarkDown入力できるエディタを探していると「WP Githuber MD」というプラグインを見つけた。
htmlからMDへのコンバートが不完全だったりするので、MDから書く人に限定されるかもしれないが、動作が安定していて使いやすいので敷居は低いと思う。

エディタ名 使いやすさ 安定 メモリ消費 プレビュー MarkDown GUI編集 完全OSS
Gutenberg
Elementer
Classic Editor
WP Githuber MD

使用イメージ

※gif画像はgithubから転載

https://github.com/terrylinooo/githuber-md

注意点

  • htmlからの変換"Html to Markdown"は適用しないほうがいい
    • 成功することもあるが、変換に失敗すると文章全体が消える
  • 行間を開けないとMarkDownを認識しない
    • "#表題\n記事" では識別しない "\n#表題\n記事"と書くとよい
    • 他のMarkDownエディタでも行間を空ける仕様が多い
  • リスト表記(li相当)の記号がインラインのプレビューで表示されない場合がある
    • WordPressのエディタ内でリストのdotとかCircle表記が見えない場合がある
    • 全体のプレビューで表示すればリストのdotやCircleを確認できる。
  • 改行がうまく入力できないときはhtmlの改行
    • 本来のMarkDownだと \n(スペース+改行)で改行になるが、githuber-mdでは反映されなかった
    • MarkDown以外にHtmlも反映されるので
      で改行にしたほうが手間が少ない

WordPressのようなエディタで文章を書くと段落が崩れてやる気をなくすことが多いのだけれど、MardDownだときれいに整形できる。

落ちないWebサイト

落ちないWebサイトの構築 【WordPressを静的サイト化する】

落ちないWebサイトの構築

先日、このサイトとは別に運用しているWordPressの1つが不安定になってしまい、不具合の原因を調べたところMySQLのアップグレードが原因でutf8mb4の文字コード指定に異常が発生していた。
復旧のために対象DBの文字コードの異常を修正する必要があったので、一度Dumpしてからリストアを実行し復旧させた。
復旧は軽微な対応で済んだのだけど、今後は手間をかけずに、サーバーレス的な継続的な改善ができるようにしたい。

今回の課題

  • 現行のWordPressサイトの本番環境を手間をかけずに安定運用させる
  • まず最低限の機能で構築
  • 保守コスト優先、WordPressの管理画面をベースにする
  • CloudFrontでホスティングすることでサーバレスな機能を運用する
  • 構築後に検索やSEO対策の機能を実装する
  • WordPressなのでセキュリティリスクが発生しないように注意する

実現方法の候補

  • StaticPress
    日本人の開発者が作ったWordPressのプラグイン。
    オリジナルは3年以上メンテナンスされていないため脆弱性の懸念がある。古くからあるプラグインのため、脆弱性やバグ対策のソースコードも公開されている。
  • WP2Static
    元はSimpleStaticという名前だったWordPressのプラグイン。完全なOSSで公開されていて自由なカスタマイズが可能。WP CLIにも対応しているので自分でWordpressを管理できる人にはとても都合がよい。CDNに乗せれば高機能かつ安定運用が可能になる。
  • Hugo
    Go言語にHugoというフレームワークがあり、高機能なhtmlテンプレートエンジンとして利用が可能。CDNに乗せれば格安で高機能かつ安定運用が可能になる。ただしWordPressの機能やノウハウを捨てることになる。
  • Shifter(サービス)
    Wordpressを静的サイトで公開するホスティングサービス。価格も良心的。ただしCDN等へ配置してバックエンドをカスタマイズしたい場合は2度手間になってしまう。
  • kusanagi(サービス)
    WordpressをフルカスタマイズしたOSSソリューション。日本のベンダが提供しているためサポートも信頼できるがシステムとして導入すると価格が高い。(1インスタンス15万円)
    レンタルサーバで提供されているkusanagiを利用する場合はホスティング費用だけでよいのでコストパフォーマンスは悪くない。ただ、どの程度サポートされるのか、プラグインやテーマは全て利用可能なのか、自前でWordPressのソースやnginxもカスタマイズ可能なのか、WPとKusanagiの二重運用になりコストが高くなる。
    元がWordPressなのでGPLとしてOSS版も提供されているが、最適化のためにNginxからビルドする前提になっておりWordPressと別のノウハウも必要になるため運用コストがかかる。良くも悪くもWordPressのカスタマイズバージョン。
  • k8s
    WordPressの勉強会でREST-APIでヘッドレス運用してk8sに乗せてCDN配信する話を聞いた。CDN配信のソースをk8sへデプロイしてCIは外部のSaaSへお任せというのは贅沢で良いけど、本番が静的ページでCDNに乗せるならk8sにする意味はあるのか(S3やGCSで良いのでは?)、Pod上で静的ページだけではなくvueでREST-APIと通信しているならWordPressのような記事ベースのコンテンツでは脆弱性が含まれるのではないか。色々と疑問が残る。

WP2Staticを利用する

  • 今回の課題解決はWordPressのサイト全体を静的なhtmlに変換してくれるWP2StaticというWPプラグインを利用する。

  • ■採用の理由

    1. WordPressの機能を引き継げるので、サイトのテンプレートデザインや面倒なSEOの設定を管理しやすい
    2. プラグインのフル機能がOSSで提供されているため問題があれば改修できる
    3. WP管理画面からの操作だけでなく WP CLIにも対応しているためバッチ処理で管理できる
    4. 本番サイトを静的ページで運用できるため大部分のセキュリティリスクを回避できる
    5. AMPやSEO用のメタタグ等、多くのWordPressの便利機能を利用することができる

アーキテクチャ

  • 現在のWordPress環境はSTG環境として運用する
  • 本番サイトはAWS S3に配置してCloudFrontで配信する
  • 自動化を前提にWP CLIで運用できる構成にする
  • クローリングは可能な限りWP2Staticで行う(WP CLIで制御可能なため)
  • WP2Staticではトップページ以外のクローリングができないため、ページネーションのインデックスは独自スクリプトを構築する
  • サイト内検索はいったん排除する(後日にJavascriptのサイト内検索を設置する。検索URLのみ動的サーバへ転送することもできるがセキュリティリスクを避けて本番はサーバレス構成で運用する)
  • Lambda Edgeの処理が可能になるのでnodejsで動的処理をする
  • 汎用的な顧客の問い合わせ機能や予約フォームは、CRMやMA,GoogleForm等で提供することでセキュリティリスクを抑えて機能を提供し、かつ一元管理が可能になる
  • 顧客対応用の恒久的な問い合わせページはMauticを利用する
  • アンケートや不特定多数からの問い合わせ、予約受付等はGoogle Formを利用する
  • マイクロサービス(フロントエンドやバックエンドのAPI連携等)は、Lambda Edgeを利用する

WP2Staticの課題と対策

  • 日本語URLのクローリングとファイル出力

    • 対策
      パーマリンクを記事IDベースに変更
  • ページ分割された過去記事(pagenation)のクローリングが不完全で出力されない

    • 対策
      毎回すべての記事をページングするスクリプトを別途作成しておく
      ※1度に10件以上の投稿をしなければトップページのクロールだけで記事を正しく出力できるが、10件以上登録したときにページングの整合性があわなくなる可能性があるため対策を設計しておく
  • 投稿の属性(カテゴリ、タグ、日付)を含めたURLが出力されない

    • 対策
      前項の対策と同じようにWP CLI等で全ての記事を出力できるスクリプトを作成しておくとよい。
  • サイト内検索の機能が提供できない

    • 対策
      ※aを検討中
    • a. mecab等で検索インデックスを構築して、本番の検索フォームと紐付ける
    • b. STG環境のWordPressのAPIとPOSTで通信させる
    • c. AWS Cloud Serarch等のサイト内検索用のWebサービスを契約する(コストが高い)
  • 投稿記事(single)のAMPが出力されない

    • 対策
      WP2Staticへ明示的に"/amp"もしくは"?amp"のページを登録するとAMP用の静的ページが生成される

まとめ・雑感

  • 「WP2Static」で構築したサイトは「AMP」プラグインのページ出力も正常に機能している
  • 「WordPress ping Optimizer」は残念ながら正常に機能しなかった(元サイトのURLをベースに通知してしまう)
  • CloudFrontへ配置したサイトをLighthouseで計測すると、初回実行Performance98、2回目以降はPerformance100になった。(CDN配信なので2回めから早い)
    元が軽量なページなので高速化していないが静的サイト化で悪化するようなことはなかった。

Ubuntu18.04でのRedmineアップグレードについての備忘録

仕事やプライベートでRedmineを使ってタスク管理・ナレッジ管理をしていて、Ubuntuのパッケージを利用してRedmineを運用している。
最近、Redmineの環境をUbuntu16.04から18.04にアップグレードした際に、Rubyのバージョン依存での不具合や注意点、Passengerのインストールのつまずきがあったので、対策等をメモしておく。

■Rubyの罠

Redmineの構成や利用しているgemパッケージはそれほど変わっていないようだが、aptパッケージとgemパッケージの依存関係が競合してインストールに失敗する場合がある。

上のようにRMagickのパッケージをインストールするときに関連するライブラリ(パッケージ)がインストールされていないと、インストールを失敗したあとで環境の修復にも時間がかかる。
また、rbenvを使ってrubyのバージョン管理をしている場合は、aptパッケージのrubyと競合するので、少なくともroot権限のrbenvは削除してaptパッケージのrubyを参照するようにしておいたほうがいい。(ユーザー権限のrbenvは残っていてもアップグレードできた)

対策:

  • rmagick関連のパッケージをインストールしていないクリーンな環境で、必要なライブラリ関連のパッケージが全てインストールした状態にしてアップグレードする。もしくは、ソースコードから必要なパッケージを1つずつインストールする。
    条件に合わずにインストールエラーが発生するとRedmineのインストールが完走しなくなり、後述の「aptの罠」にもハマってしまう。

  • 具体的な対策は、gemのインストール(bundle insall ~)の前に必要なaptパッケージのライブラリが揃っているとエラーにならないようだ。以下のパッケージ全てインストールすると大丈夫だと思う。

sudo apt install ruby-fastimage ruby-mini-magick ruby-oily-png
sudo apt install imageinfo imagemagick imagemagick-6-common imagemagick-6-doc imagemagick-6.q16 imagemagick-6.q16hdri imagemagick-common imagemagick-doc
sudo apt install libchart-gnuplot-perl libgraphics-magick* libgraphicsmagick* libmagick*
  • 前述の対応でubuntu側のパッケージが揃うはずだが、環境依存でGemfileでインストールするパッケージのバージョンがあわない場合がある。自分の場合はGemfileに記述されたnokogiriのバージョンがbundle installでは解決できなかった。
    同じ不具合にあった場合は"bundle install"の前に個別にバージョン指定してnokogiriをインストールしてから"bundle ~"すれば解決することができた。
gem install nokogiri -v "1.8.1"

■aptの罠

上のRMagick等のgemの依存関係でRedmineをアップグレードするとaptの途中で止まってしまう場合がある。aptのインストールが途中で失敗すると、他のパッケージをインストールしようとするときにもRedmineも再インストールすることになり、全てのパッケージのインストールに失敗する。

対策:

aptのエラーを修復するためにはパッケージをインストールする都度Redmineのパッケージを削除するか、apt-get upgradeからRedmineパッケージを除外して関連パッケージをインストールしてから再度有効化する必要がある。

参考:apt-get upgradeから特定パッケージを除外する
https://qiita.com/strsk/items/c933a661c077a666073a

■Passengerの罠

Passengerをアップグレードするときにautoオプションでインストールしたのだけど、autoオプションではPassenger専用のnginxのソースビルドが導入されてしまい、動作させるための設定に苦労した。
Passenger版のnginxはディストリビューション版とは異なる最低限のコンパイルオプションでビルドされるため、Passengerを含まないApacheやNginxの設定では正常に動作しない。(自動でインストールされたPassengerの設定を確認してから気がついた)

対策:

  • Passenger版のnginxは利用せずにUbuntuのnginxパッケージを再インストールする
sudo apt install nginx-core nginx-full --reinstall
sudo apt-get install -y dirmngr gnupg
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates

■Permissionの調整

前バージョンまでRailsとPassengerの連携を重視してApacheを利用していたが、最近はnginxのほうが慣れて安心できるためnginxへ変更した。このときに各所でpermissionの調整が必要になったので、これもメモしておく。

対策:

  • ・apache2ユーザーの権限 "www-data"をnginxユーザーへchownする
    パッケージでインストールされているディレクトリ("/usr/share/redmine"等)はエイリアスが多用されているので、"chown nginx:nginx -rf"のようなサブディレクトリ一括でのパーミッション変更ができない場合があるので注意が必要。

  • Web公開用のディレクトリだけでなく、起動スクリプト(/etc/init.d/nginx )とデーモン(/etc/systemd/system/multi-user.target.wants/nginx)にもユーザー指定の記述があれば変更する必要がある。

■まとめ

Redmine3.4+nginxへアップグレードしたことによる利点:

  1. パフォーマンスが大幅に向上した
  • Redmine+Apache2+Passengerでは、チケットの投稿に数秒かかる場合があったのだけど、Redmine+nginxに変更してから1秒以内に投稿できるようになった。
    メモリ効率も向上していて、Apacheではメモリ使用量が200MB以上専有されていたのだけどnginxでは100MB以内になった。
  1. 安定した
  • 1のパフォーマンスと同じ原因だと思われるが、Apacheで運用するRedmineではチケットを投稿したときに(数ヶ月に1度程度)原因不明の503エラーが発生していた。エラーが発生したときはApacheの503エラーしかログに残らず再現性がなかったため不具合回避ができずにいたのだけど、アップグレード(nginxに変更)してからは1度も発生しなくなっている。
  1. 古いバージョンのRubyを捨てることができた
  • rubyのパッケージはバージョン依存が強いものが多くて互換性問題が運用リスクとして抱えることになる場合がある。今回アップグレードしたRedmine3.4はrubyを2.5以上に統一することができたので自分にとって大きな利点だった。特にAWSとの連携では、Lambdaがサポートするrubyが2.5以上必須なので運用上なにかと有用である。

Redmine3.4へのアップグレード対応について、反省点と今後のリスク:

  1. 時間の消費
  • Ubuntuで利用するRedmineパッケージのアップグレードは、OS標準のオプションだけで解決できていた為30分~1時間もあれば対応できていたのだが、今回はパッケージの競合等で手作業での調査と対策が必要になり、不具合調査に1日+手順書作成に1日、実施に半日程度かかった。
    振り返りとしては、Dockerや新規のAWSインスタンスを新規で立ち上げて、Redmine18.04用のRedmineを構築してから、旧環境とDBを移行したほうが安全で早く対応できたように思える。
  1. 外部パッケージの導入
  • Ubuntuの標準リポジトリではnginx対応のPassengerが配布されていないため、外部リポジトリからPassengerをインストールしたが、今後の運用管理でリスクになる可能性がある。

Vuls導入メモ IPAテクニカルウォッチ「脆弱性対策の効果的な進め方(ツール活用編)」

IPAテクニカルウォッチ「脆弱性対策の効果的な進め方(ツール活用編)」

https://www.ipa.go.jp/security/technicalwatch/20190221.html

2019年2月21日にIPAが脆弱性対策についての効果的なツール活用としてVulsが紹介されていた。

ちょうど自前でもVulsを導入したので、手順やつまづいた点を備忘録にブログにまとめておく。

 

vuls reportコマンドの正しいオプション指定

公式サイトの例ではrepotコマンドのオプション指定が下記のようになっているが、公式の例のようにcve情報をsqlite3で構築していると正しく動作しなかった。

 -cvedb-path="...."
 -ovaldb-path="...."
 -gostdb-path="...."
 -exploitdb-path="...."

正しいオプション指定は以下になる

-cvedb-sqlite3-path="...."
-ovaldb-sqlite3-path="...."
-gostdb-sqlite3-path="...."
-exploitdb-sqlite3-path="...."

config.tomlファイルへ記載してオプションを省略する

DB参照のオプションはconfig.tomlへ登録することができる。confに設定すれば何度も同じオプションを指定する必要がなくなる。

公式を参考にvulsユーザーの環境に構築していればconfig.tomlの記述は下記のようになる。

 

https://vuls.io/docs/ja/usage-report.html

[cveDict]
type="sqlite3"
SQLite3Path="/home/vuls/cve.sqlite3"

[ovalDict]
type="sqlite3"
SQLite3Path="/home/vuls/go/src/github.com/kotakanbe/goval-dictionary/oval.sqlite3"

[gost]
type = "sqlite3"
SQLite3Path="/home/vuls/go/src/github.com/knqyf263/gost/gost.sqlite3"

[exploit]
type = "sqlite3"
SQLite3Path ="/home/vuls/go/src/github.com/mozqnet/go-exploitdb/go-exploitdb.sqlite3"

 

Vulsのレポートをhttps(443ポート)で閲覧

レポートが生成されるとWebブラウザで結果を表示することができるのだが、デフォルトだとvuls repotサーバに接続するためには5111ポートを開放しなければならない。(例:http://example.com:5111/)脆弱対策のレポート閲覧にポートの追加開放が必要というのはスマートではないし本末転倒。

Webサーバ構築に慣れている人はすぐに気づくと思いますが、nginxやapacheをプロキシとして設定すれば外部からのレポート参照はhttpから閲覧できる。私の場合はnginxでproxy設定したのだが一般的なconfの記述でSSL設定(https)とBasic認証の設定が可能だった。

(vulsのマニュアルでは5111ポートにvuls用のSSLとvuls用の認証設定が記載されている)

 

リモートスキャン設定

方法1.http経由のスキャンでは5515ポートを開放してスキャンサーバを実行させて、かつクライアントからhttpを実行、ログはクライアント側に出力される。

方法2.ssh経由のスキャンではスキャン対象のssh鍵が必要。fast scan以外の実行にはsudo権限が必要になる。(実質的にいくつかOSファイルをインストールが必要になる場合がある)

どちらも試したのだが、1の方法は5515のポート開放が必須でログがリモート側に保存されて管理が煩雑になるため5515ポートを閉じて利用しない事にした。現在は2の方法でssh経由のスキャンを運用している。

基本的にバッチ処理の組み合わせなのでcronで定期実行を設定しておけばレポート画面を自動更新することができる。慣れてくるとレポート画面の確認をサボってしまうので、出力結果をメールやslack, mattermost等に飛ばしておくと忘れることがなくなる。

 

※システム連携のサンプル

出典:

https://github.com/future-architect/vuls/

vulsのgithubから引用

感想

ディストリビューションが提供する最新パッケージを適用していても修正されていない脆弱性が大量にあるため、セキュリティリスクを把握して対策できるものは対策する、対策する必要がない場合はそのリスクを把握する判断が必要とされる。

 

◇Vuls導入の利点・長所、個人的に良いと思うところ:

・Vulsのリモートスキャンはエージェントレスなので、対象のサーバに追加アプリケーションのインストールが不要(※yumのパッケージ管理の場合は1つだけパッケージインストールが必要)

・一般的なCVEの脆弱性情報を利用するため、標準的なLinux/Windowsシステムであればプラットフォームに依存しない、AWSやVPS環境でも利用可能

・全てのCVE情報を対象とするため診断精度が高い。システムの脆弱性診断としてはAWSのInspectorよりも詳細なレポートが得られる

・スキャン設定が選択可能でFastでは高速に検査できる。Deep設定では追加の権限設定が必要だが詳細情報を取得可能。

・基本的にバッチ処理とレポート生成だけなので、サーバーリソースが少なくても快適に動作する

・OSS版だけでもセキュリティリスクの現状把握として十分に有用だが、OSS版に対応できるエンジニアがいなくて予算に余裕があるならクラウド版を導入するとよさそう。(1台あたり4000円かかる)

◇Vulsではたりなさそうな短所、個人的にイマイチだと思えるところ:

・SSHでスキャンする場合、スキャン元から接続できるSSHポートが必要、かつSSH鍵のパスフレーズを削除する必要があり、鍵が漏洩したときに第三者の攻撃の懸念になる。(iptablesやsshd_configで接続元を制限することで対策可能)

・CVSS情報にない脆弱性(例えばAWSの固有設定についての脆弱性、AWSだとTrustedadvisor相当の情報)は検査できない。version 007からWordPress特有のセキュリティリスクは内部的にWPScanと同等の検査が行われるようになったらしい。
※version 007にアップデートして検査したがWordPres関連と見られる検査結果は見当たらなかった。。。

・Vuls商用版がメインで提供されているため、OSS版の構築や運用手順、検出したCVSSの情報が少ない。Windowsの脆弱性スキャンは有料版のみ対応。

・有料版の案内が不明瞭。vulsをGoogle検索しても有料版のURLが10位内に表示されない。クラウド版は1台のスキャン設定あたり4,000円(税抜き)とあるがVMやクラウドでも台数があるとそれなりの金額になる。固定のGIPが必要なのかSSH接続ができないオンプレは対応しているのか等がわからない。新規契約者には初期導入や運用について「コンサルティングサービス」オプションの別費用で提供するらしいが相応に費用がかかりそう。

 

OpenCVでWebカメラの解像度を変更すると落ちる不具合の対処方法

所有しているPCを買い替えたところ、OpenCVを利用したアプリが動かなくなった。

 

■アプリ(OpenCV)から見た症状

・動作環境はWindows10、OpenCVのバージョンは3.4.5
・RealSense D435カメラだとOpenCVの機能は正常に稼働する
・新しいPCに内蔵されたWebカメラだと、OpenCVからカメラを呼び出した瞬間に例外終了する
・Webカメラ単体であれば問題なく動作する(OpenCVから呼び出さなければ正常動作)
・OpenCVは最新版3.4.5をリファレンス通りにビルドして利用している

 

■原因の推測

OpenCVからWebカメラを呼び出すときに、カメラ解像度を設定変更するためにWITH_V4Lを参照するが、WITH_V4Lを参照できずに落ちてしまう。

 

■対策

ビルドオプションのWITH_V4LをONにすればカメラ解像度の変更でWITH_V4Lを参照したときの不具合が解消するらしい。
該当するOpenCVのソースコード、platforms/js/build_js.py 107行に定義されている値を変更。

変更前
"-DWITH_V4L=OFF",

変更後
"-DWITH_V4L=ON",

 

■結果

WITH_V4Lオプションを変更してcmakeを実行し、VisualStudioでリビルド、OpenCVライブラリを差し替えると新しいWebカメラでも正常にOpenCVが作動した。

 

the notebook PC