モヒカンは正義

プログラマー風林火山で言う「風のエンジニア」になりたい(比較的)若者Webエンジニアの備忘録

"[skip ci]" とコミットメッセージに書くと、CIをスキップできる

TravisCIやCircleCIを使ってCI/CDするのはだいぶメジャーになりましたね。

ドキュメントのみの更新時やwipのときなど、「git commitはしておきたいけどCIは走らせなくて良いだよな〜」というときありますよね。

そういうとき [skip ci] とコミットメッセージに含めておくとCIをskip出来て便利です。他にもいくつかバリエーションが有るので、手に馴染むものを使えば良さそう。

参考資料

TravisCI

docs.travis-ci.com

If you don’t want to run a build for a particular commit for any reason, you may instruct Travis CI to skip building this commit via a command in the commit message.

The command should be one of the following forms:

[ skip]

or

[skip ]

where is either ci, travis, travis ci, travis-ci, or travisci. For example,

[skip travis] Update README

CircleCI

circleci.com

By default, CircleCI automatically builds a project whenever you push changes to a version control system (VCS). You can override this behavior by adding a [ci skip] or [skip ci] tag anywhere in a commit’s title or description.

ゆるゆる無限LTというクレイジーイベントへ参加してLT3本やってきた

自分もワイワイしている若者ものづくりコミュニティ Oysters主催、ゆるゆる無限LTというクレイジーイベントへ参加した。

oysters.connpass.com

会場はウィルゲートさん提供。サンクス!

f:id:pinkumohikan:20190513195525j:plain
雰囲気

無限LTとwはwww

他の人の LT を聞きながら、LT の資料を作る。 それを繰り返すことで、1日にたくさん LT の経験をしようという会です。

一言で言うと、LT中毒者の集いですね(雑)

話したこと

自己紹介てきなやつ

  • 我はpinkumohikanだぞ!崇めよ
  • サバゲと、ボウリングと、仮想通貨自動売買はいいぞ!

たくさんメール送るのは大変だぞ

  • まだまだ伝達手段としてメールは無視出来ないぞ
    • 長文送りたいとかエビデンスの観点ではまだ代わりは無い
  • 何も考えずにたくさんメール送ったら、全然届かないぞ (スパムフィルタ)
    • 送信者認証、IP/ドメインレピュテーション、etc...
  • おとなしくSendGridとかSESとかのSaaS使うのがよし
    • SDK使えばOP25Bとかの制約も受けないし!
  • Google Postmaster Toolが便利
    • 迷惑メール通報率や、IP/ドメインレピュテーションの確認ができる

ちゃんとサードパーティ製パッケージのバージョンアップやるんだぞ

f:id:pinkumohikan:20190513195026j:plain
オーディエンスを煽る我

スライドはテンション上がったら上げます(あげないやつ)

もっと様子が気になるぞ?

さとだいさんが写真取ってくれたので見るべし

あとは、タグを追うべし

twitter.com

感想

真面目なネタから、技術ネタ、大根おろしの辛さの研究みたいなぶっ飛んでるネタまで聞けてたのしかった(小学生並みの感想)

MySQL8をバージョンアップしたら起動しなくなった

背景

  • 個人プロダクト用にMySQL8を運用していて定期的にバージョンアップを行っている
  • 8.0.14 から 8.0.16 にマイナーバージョンアップしたところMySQLが起動しなくなった 💀

f:id:pinkumohikan:20190502141209p:plain

調査と対応

おもむろにstartしてみる

$ sudo systemctl start mysql
Job for mysql.service failed because the control process exited with error code.
See "systemctl status mysql.service" and "journalctl -xe" for details.

ですよね〜〜〜

素直にprocessのログを見る

$ sudo journalctl -xe
...
Apr 26 00:39:17 $hostname sudo[5013]: $username : TTY=pts/0 ; PWD=/home/$username ; USER=root ; COMMAND=/bin/systemctl start mysql
Apr 26 00:39:17 $hostname sudo[5013]: pam_unix(sudo:session): session opened for user root by $username(uid=0)
Apr 26 00:39:17 $hostname systemd[1]: Starting MySQL Community Server...
-- Subject: Unit mysql.service has begun start-up
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- Unit mysql.service has begun starting up.
Apr 26 00:39:17 $hostname audit[5067]: AVC apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="/usr/sbin/mysqld" pid=5067 comm="apparmor_parser"
Apr 26 00:39:17 $hostname kernel: audit: type=1400 audit(1556206757.959:27): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" profile="unconfined" name="/usr/sbin/mysqld" pid=5067 comm="a
Apr 26 00:39:19 $hostname trace-agent[945]: 2019-04-26 00:39:19 JST | TRACE | INFO | (pkg/trace/agent/service.go:63 in Run) | total number of tracked services: 0
Apr 26 00:39:23 $hostname systemd[1]: mysql.service: Main process exited, code=exited, status=1/FAILURE
Apr 26 00:39:23 $hostname systemd[1]: mysql.service: Failed with result 'exit-code'.
Apr 26 00:39:23 $hostname sudo[5013]: pam_unix(sudo:session): session closed for user root
Apr 26 00:39:23 $hostname systemd[1]: Failed to start MySQL Community Server.
-- Subject: Unit mysql.service has failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- Unit mysql.service has failed.
--
-- The result is RESULT.
...

うーん、何も分からない(キレ気味)

MySQLのログを見る

$ sudo less /var/log/mysql/error.log
...
2019-04-25T15:41:12.267479Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.16) starting as process 6246
2019-04-25T15:41:13.263343Z 4 [System] [MY-013381] [Server] Server upgrade from '80015' to '80016' started.
2019-04-25T15:41:15.448593Z 4 [ERROR] [MY-013384] [Server] Could not create server upgrade info file at '/var/lib/mysql/'.
2019-04-25T15:41:15.454470Z 0 [ERROR] [MY-013380] [Server] Failed to upgrade server.
2019-04-25T15:41:15.455397Z 0 [ERROR] [MY-010119] [Server] Aborting
2019-04-25T15:41:17.137374Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.16)  MySQL Community Server - GPL.

Could not create server upgrade info file at '/var/lib/mysql/'.

このあたりが怪しそう

おもむろにlsしてみる

$ ls -alh /var/lib/mysql/
...
drwxr-x---  2 mysql mysql 4.0K Apr 26 00:41  mysql
-rw-r-----  1 mysql mysql  56M Apr 26 00:41  mysql.ibd
-rw-r--r--  1 root  root     6 Apr 13 00:08  mysql_upgrade_info
drwxr-x---  2 mysql mysql 4.0K Apr 26 00:28  performance_schema
-rw-------  1 mysql mysql 1.7K Sep 30  2018  private_key.pem
...

一個だけroot所有なファイルが有るぞ...!?

mysql_upgrade_infoは本来rootじゃなくてmysql所有であるべきものっぽいので、所有者をmysqlに変えたら直るんじゃね?

$ sudo chown mysql:mysql mysql_upgrade_info
$ sudo systemctl start mysql
$ sudo systemctl status mysql
● mysql.service - MySQL Community Server
   Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2019-04-26 00:51:50 JST; 3s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 11526 ExecStartPre=/usr/share/mysql-8.0/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
 Main PID: 11578 (mysqld)
   Status: "SERVER_OPERATING"
    Tasks: 38 (limit: 1110)
   CGroup: /system.slice/mysql.service
           └─11578 /usr/sbin/mysqld

おかえり

MySQLのログを見ても、バージョンアップ成功してそう

$ sudo less /var/log/mysql/error.log
...
2019-04-25T15:51:39.763174Z 4 [System] [MY-013381] [Server] Server upgrade from '80015' to '80016' started.
2019-04-25T15:51:42.308523Z 4 [System] [MY-013381] [Server] Server upgrade from '80015' to '80016' completed.
...

なぜ mysql_upgrade_info がroot所有になっちゃったのかは謎だけど、原因が2週間前の操作によるものである可能性が高くてもう追えないし、ログを順に辿っていけば解決出来る問題だったのでひとまずこれにて。

Scalaで使うテンプレートエンジンの検討 (Scalate、Twirl、Beard)

Scalaでテンプレートエンジン使いたくなったので調べた。

www.scala-lang.org

探し方

GitHubでホスティングされているホットなものを探す。

github.com

こういうのを探すときは、

  • そこそこstarがついている (= みんなに使われている)
  • 定期的に新バージョンがリリースされている
  • contributorが一人じゃない

辺りを確認しておくのがオススメ。 そうしておけば、突然ライブラリが消滅したり、時代に取り残されて渋々他のライブラリへの移行を余儀なくされる、みたいな悲しいことを回避出来る確率が上がる。

見つけたもの

探し方 で触れた観点を持って良さげだなと思ったは次の3つ。

1. Scalate

github.com

Mustache、Jade、Scaml、SSPと複数の表記方法をサポートしている。 テンプレートエンジンって「こういう風にかけ!」と表記方法をビシッと指定されているものしか使ったことがなかったが、複数の表記方法から手に馴染むものを選べるのは嬉しいんじゃないだろうか。

とは言えいくつかはHTML特化の表記方法なので「メール本文とかPush通知の文面とかもテンプレート管理したいんじゃー」という場合は、選択肢としてはMustacheかSSP表記のいずれかになる。オススメはSSPで、テンプレート変数が未定義だった場合にはランタイムで怒ってくれる。Mustacheはしれっとブランクになってしまうのでそれに気づかず事故りやすそう。

2. Twirl

github.com

有名な モリモリ フルスタック系フレームワークplayのテンプレートエンジン。 SBT Pluginとして追加する感じで、templateをコンパイルしてくれるのでテンプレート変数の過不足が無くなるのが良い。 テンプレート変数が未定義だった場合に Scalate * SSP だとランタイムで気付けるが、Twirlだとコンパイル時点で気づける。

機能的は良いんだけど、コンパイルオプションで fatal-warningswarn-unused-import を有効にしていると、 TwirlKeys.templateImports := Nil を設定するハックをしないと unused import で怒られて使えないのが難点。

github.com

3. Beard

github.com

ScalateとTwirlに比べるとstarが少ないが、表記方法はMustacheベースで手に馴染みやすい印象。 Last releaseが2016/4で、2019/4/5現在新し目なIssueも無いのでメンテは活発では無さそうな感はある。

その他

今回はJava用のテンプレートエンジンは探してないけど、そっちも探せば他にも良さげなものはあるかも。

他にオススメあったら教えて下さい。

CircleCIでdockerを使うときはバージョン指定を忘れないこと

学び

CircleCI上でdockerを動かすとデフォルトではバージョン17.09っていう化石エンジンで動いてしまうので気をつけるべし。

背景

とあるOSSアプリ のCIをCircleCIでしようと思って悪戦苦闘していたら、こういうリプを貰った。

「そんなバナナw 今は2019年だぜJK?w」と思って確認したら、本当だったw

f:id:pinkumohikan:20190321233825p:plain

ログ: https://circleci.com/gh/pinkumohikan/sunfish/21

新しいdocker engineを使う

積極的に新しいバージョンを使っていきましょうね、ということで

circleci.com

を参考に、こんな感じでバージョンを指定する。

f:id:pinkumohikan:20190321234645p:plain

すると、指定したバージョンでdocker engineが動くことが確認できた。

f:id:pinkumohikan:20190321234722p:plain

ログ: https://circleci.com/gh/pinkumohikan/sunfish/24

めでたし、めでたし。

ちなみに

指定可能なdocker engineのバージョンはここから選べる。

download.docker.com

Docker for Macが路頭に迷わないようにたくさんメモリを食べられるようにする

こんにちは。

軽量でポータブルな開発&実行環境としてDockerが人気ですね。 僕は数年前までは開発環境にはもっぱらVagrantを使っていたのですが、最近は仕事でもプライベートでもDockerしか使ってないです。

f:id:pinkumohikan:20190209144001p:plain

Dockerは単純に捨てやすい開発環境という使い方もできるし、うまいこと作ると設定ファイルを差し替えたらすぐ本番で動かせるぞ、という使い方も出来ます。後者だと 12 factor appで言う 開発/本番一致 がしっかり出来て最高ですね。

さて、Dockerにはメモリ使用量の制限設定があり、それがネックになって開発中のプログラムの動きが鈍くなったり応答しなくなったことがあったので、誰かの役にたてばいいなと思ってメモリ使用量の増やし方をメモります。

1. Docker for Macへのメモリ使用量を確認する

まずは現状確認をしましょう。

Docker for MacのPreferencesを開きます。

f:id:pinkumohikan:20190209142106p:plain

f:id:pinkumohikan:20190209142123p:plain

次にAdvancedのタブを開き、Memoryの量を確認します。

f:id:pinkumohikan:20190209142158p:plain

メモリ使用量制限は2GBのようです。

2. 制限に引っかかっていることを確認する

プログラムの動きが鈍いのが本当にメモリ使用量制限のせいであるかを確認しましょう。

アクティビティモニタのメモリタブを開きます。

f:id:pinkumohikan:20190209142526p:plain

1.9Gぐらい使っているようですね。メモリ使用量制限の値が2GBだったので数字だけ見ると若干の余裕はありますが、瞬間的に引っかかって縮退した可能性が高そうです。

3. メモリ使用量制限の値を引き上げる

Docker for MacのPreferencesに戻って、2GBとなっていたところを引き上げます。いくらに引き上げるかは総メモリ量と他にどのぐらい同時作業するかによりますが、僕の場合はメモリ16GBマシンで同時に使うのはSlackとIntelliJぐらいなのでガツッと8GBにしました。

一度しか設定できないものではないので、これでもしほかが逼迫したら引き下げればいいよねぐらいの楽観です。

f:id:pinkumohikan:20190209142901p:plain

Apply & Restart を押して、dockerデーモンが上がってきたらdone。

4. プログラムがスムーズに動くようになったか確認する

すむーーーずになりました。

たまに起きていた動きがめちゃ遅になったり応答しなくなったりすることはなくなりました。やっぱりメモリやったんやな!

あとあと見たらdocker-composeでdb含む環境一式を立ち上げてバリバリ動いている状態だと4.7Gぐらいメモリ食ってたので、8GBっていう割り当ては妥当だった模様。

f:id:pinkumohikan:20190209143449p:plain

30日間brew cleanupしてなかったらbrew upgradeのついでに実行されるようになっていた

僕は仕事でもプライベートでも開発環境としてMacBookを使っているのですが、毎朝 brew upgrade コマンドを叩いています。今日は何が上がったかな?を確かめるのが日課です。これをせずにbrew installをした日にはたくさんのupgradeが走ってめちゃめちゃ待たされますからね・・・。

で、昨日おもむろに brew upgrade を叩いたら、やけに長いログが...。

$ brew upgrade
...
==> Upgrading 1 outdated package:
typescript 3.2.4 -> 3.3.1
==> Upgrading typescript
==> Downloading https://homebrew.bintray.com/bottles/typescript-3.3.1.high_sierr
######################################################################## 100.0%
==> Pouring typescript-3.3.1.high_sierra.bottle.tar.gz
🍺  /usr/local/Cellar/typescript/3.3.1: 86 files, 41.0MB
==> `brew cleanup` has not been run in 30 days, running now...
ずらずらずら.....

_人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人人_

> brew cleanup has not been run in 30 days, running now... <

 ̄YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY^ ̄

どうやら、30日間brew cleanupしてなかったらbrew upgradeをトリガーに実行されるようになったらしい。

brewはinstallやupgradeするたびに以前のバージョンをキャッシュしておいてくれます。そのお蔭で「アッ、バージョンアップしたら動かない...!」というときにコマンド一つでバージョンを戻すことができます。

brew cleanup は、そのキャッシュを削除するコマンドです。ずっと前のバージョンを残していると使わない割にディスク食いますからね。

へーおもしろい変更だなと思って調べてみたら、この仕様になったのは brew v1.9.0 からっぽい。

github.com

このissueで自動的に brew cleanup を実行すべきでは?という議論がなされての結果らしい。

github.com

PRとしてはこれかな

github.com

HOMEBREW_NO_INSTALL_CLEANUPという環境変数でオプトアウトもできるらしい。

travis encrypt-fileに気をつけろ!2回コマンド叩くと復号に失敗する!?

なんか釣りっぽいタイトルになってしまいましたが、そんな意図はありませんw

CI/CDツールとして良くTravis CIを使っています。CDの際などにアプリ設定やDB接続情報と言った機微情報を扱うとき、travis-cliの travis encrypt-file というコマンドを使うとTravis CIだけが複合可能な形で暗号化することができ、とても便利です。

github.com

ですが、その travis encrypt-file というコマンドにはトラップが有って、最近そのトラップを盛大に踏み抜いて爆死したので注意喚起とワークアラウンドをまとめます。

f:id:pinkumohikan:20190124201752p:plain
やっちまったらすぐ共有!

“travis encrypt-file” を同じディレクトリで2回叩くと、以前暗号化したものが復号できなくなる

これは仕様らしいです。

例:

  1. travis encrypt-file aaa.json叩く -> aaa.json.encが出来る -> aaa.json.encは復号可能
  2. travis encrypt-file bbb.json叩く -> bbb.json.encが出来る -> aaa.json.encは復号できない、 bbb.json.encは復号可能

qiita.com

ところで、travis encrypt-fileで複数ファイルを暗号化すると、最後に暗号化したファイルしか復号できません。このことはTravis CIのマニュアルにも記載があり、必要ファイルをtarに固めて1ファイルにするというワークアラウンドが紹介されています。

本当にドキュメントにもしれっと書かれていた。 まあでもドキュメントって細部まではあんまり読みませんよね。

docs.travis-ci.com

The Command Line Client overrides encrypted entries if you use it to encrypt multiple files. If you need to encrypt multiple files, first create an archive of sensitive files, then decrypt and expand it during the build.

元issueはこれっぽい

github.com

ワークアラウンド1: tarで固めて1個だけ travis encrypt-file する

まずは公式に乗っている正攻法から。

手順:

  1. 必要なアレコレをtarで固める
  2. travis encrypt-file コマンドを叩く
  3. .encファイルをcommit
  4. before_install hookとかで復号
  5. tarを展開
  6. 必要な場所に配置して使う

この方法のデメリットは、tarで固めるべきファイルが何かを誰でも分かる状態にするのが難しいこと。

自分だけが暗号化するならあまり問題にはならないかもですが、誰か別の人が暗号化しうるなら気にすべき。一度暗号化したものはTravisCIしか復号できないので、何がtarに入っているべきかをtarで固める人は知っていないといけない。必要なファイルが1個2個ぐらいならREADMEとかに書くでどうにかなりそうだけど、5個とか6個とかになってくると手動では抜け漏れが起きそう。

ワークアラウンド2: ディレクトリユニークであれば良いことを利用したハック

下記記事の 1つのディレクトリで1つのファイルしか使えない? で知った、ディレクトリユニークであれば復号できるという振る舞いを利用したハック。

rcmdnk.com

手順:

  1. ランダムな名前のディレクトリをつくる
  2. 今回暗号化したいファイルをそのディレクトリへコピー
  3. そのディレクトリで travis encrypt-file コマンドを叩く
  4. .encファイルをcommit
  5. before_install hookとかで復号
  6. 必要な場所に配置して使う

この方法のメリットは、暗号化する人はそのとき暗号化したいファイルのことだけ気にすれば良くなること。

この方法のデメリットは、もしディレクトリ名がかぶったら先に暗号化したものが復号できなくなること。

個人的な一押しは、ディレクトリユニークを利用したハック

名前がかぶったらダメっていうのはそれはハッシュにおける衝突と似たような問題なので、ディレクトリ名を長く複雑にすればリスクとしては低減できそう。仕組みさえ用意できれば、都度必要なファイルを全部用意するよりも楽そう。

そして、ここに便利Makefileを用意しました。

encrypt: FILE_NAME=
encrypt:
    test -n "$(FILE_NAME)" && ls $(FILE_NAME) >/dev/null
    $(eval TEMP_DIR=$(shell mktemp -d tmp-XXXXXXXXXX))
    cp $(FILE_NAME) $(TEMP_DIR)
    cd $(TEMP_DIR) && travis encrypt-file $(FILE_NAME)
    cp $(TEMP_DIR)/*.enc .
    rm -rf $(TEMP_DIR)

使い方は $ make encrypt FILE_NAME=sensitive-data.json みたいな感じ。これをTravis CI用のファイルをまとめているディレクトリにボンっと置いて使っています。

やっていることは、ランダムな名前で一時ディレクトリを作り、そこに指定されたファイルをコピーしてtravis encrypt-fileコマンドを叩き、作られた.encファイルをコピーしたのち一時ディレクトリを削除する、といったことです。

実行例はこんな感じ

$ make encrypt FILE_NAME=sensitive-data.json
test -n "sensitive-data.json" && ls sensitive-data.json >/dev/null
cp sensitive-data.json tmp-1pBHxolDaS
cd tmp-1pBHxolDaS && travis encrypt-file sensitive-data.json
encrypting sensitive-data.json for pinkumohikan/some-repository
storing result as sensitive-data.json.enc
storing secure env variables for decryption

Please add the following to your build script (before_install stage in your .travis.yml, for instance):

    openssl aes-256-cbc -K $encrypted_xxx_key -iv $encrypted_xxx_iv -in sensitive-data.json.enc -out sensitive-data.json -d

Pro Tip: You can add it automatically by running with --add.

Make sure to add sensitive-data.json.enc to the git repository.
Make sure not to add sensitive-data.json to the git repository.
Commit all changes to your .travis.yml.
cp tmp-1pBHxolDaS/*.enc .
rm -rf tmp-1pBHxolDaS

ちなみに、travis encrypt-fileコマンドを叩くときのディレクトリがgitリポジトリ外だと「このリポジトリどこやねん?」って聞かれてうざいので注意。

MySQL5.7以降でユーザ作成時にパスワードポリシーで怒られるときの回避策

MySQL5.7.8以降でゆるいパスワードでユーザを作成しようとした際、下記のようなエラーが表示される

mysql> create user "user_name"@"localhost" identified by "some_weak_password";
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

MySQL :: MySQL 5.7 Release Notes :: Changes in MySQL 5.7.8 (2015-08-03, Release Candidate)

5.7.8以降では validate_password プラグインがデフォルトでインストールされるようになっており、その影響で脆弱なパスワードはプラグインによって怒られるようになっている

現状確認

MySQL :: MySQL 5.7 Reference Manual :: 6.5.3 The Password Validation Plugin

MySQL [java_sparrow]> show global variables like '%validate%';
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password.check_user_name    | ON     |
| validate_password.dictionary_file    |        |
| validate_password.length             | 8      |
| validate_password.mixed_case_count   | 1      |
| validate_password.number_count       | 1      |
| validate_password.policy             | MEDIUM |
| validate_password.special_char_count | 1      |
+--------------------------------------+--------+
7 rows in set (0.01 sec)

ドキュメントと上記設定を見る限り、デフォルトでは

  • パスワード長 8文字以上
  • 大文字小文字 1文字以上
  • 数字 1文字以上
  • 記号 1文字以上

でないと怒られるらしい

回避策

1. validate_password.policyをLOWに下げる

MySQL :: MySQL 5.7 Reference Manual :: 6.5.3.2 Password Validation Plugin Options and Variables

によると validate_password.policyMEDIUM のときは、長さ、数字、大文字小文字、記号の4項目で制約がかかるが、 LOW にすると長さのみの制約になるようだ

f:id:pinkumohikan:20181222193801p:plain

オンラインで実行する場合のクエリ

mysql> set global validate_password_policy = LOW;
Query OK, 0 rows affected (0.01 sec)

2. 各種制約文字数を下げる

*_count 系の設定値を変更することで、最低文字数の条件を緩和することができる

例えば「記号は必須にしたくないなー」というときは validate_password.special_char_count0 にしてやれば、パスワードに記号が含まれていなくてもエラーにはならなくなる

オンラインで実行する場合のクエリ

mysql> set global validate_password.special_char_count = 0;
Query OK, 0 rows affected (0.01 sec)

注意

文中で紹介したオンラインで実行する場合のクエリを実行してもDBサーバが再起動するとデフォルトに戻るので、永久的な設定としたい場合は my.cnf の mysqld ディレクティブとかに設定を書いておく必要がある

おまけ

参考にした資料、記事等

yoku0825.blogspot.com

MySQL :: MySQL 5.7 Release Notes :: Changes in MySQL 5.7.8 (2015-08-03, Release Candidate)

MySQL :: MySQL 5.7 Reference Manual :: 6.5.3 The Password Validation Plugin

MySQL :: MySQL 5.7 Reference Manual :: 6.5.3.2 Password Validation Plugin Options and Variables

ワイルドカード証明書はサブドメインでなくても利用できるのかどうかを調べた

背景

*.pinkumohikan.com 用のワイルドカード証明書が pinkumohikan.com ドメインでも使えるのかどうかが気になった。

これまでは pinkumohikan.com はドメインの階層(深さ)が違うので使えないと考えていたが、あるとき pinkumohikan.com でも使えるという話を聞いて気になったので調べた。

ワイルドカード証明書とは?

1枚あればサブドメインでSSLを運用できるSSLサーバ証明書。

ワイルドカードSSLサーバ証明書とは、同一のドメイン配下にある複数の異なるサブドメイン(FQDN)を1枚のSSLサーバ証明書でまとめて保護できるタイプのSSLサーバ証明書です。サブドメインごとに証明書を複数取得する負荷や証明書コストを抑えることができます。

www.geotrust.co.jp

*.pinkumohikan.com 用のワイルドカード証明書を用意すれば、下記のようなドメインを1枚の証明書でSSL運用できる。

  • www.pinkumohikan.com
  • api.pinkumohikan.com
  • cdn.pinkumohikan.com

余談: ワイルドカード証明書を使う理由

証明書の管理は地味に面倒だ。秘密鍵と証明書(場合によっては中間証明書も)を消失しないように、かつそれでいて関係のない開発者には見えないように保管しつづける必要がある。また、証明書には有効期限があるので、いつまでに更新するべきかも気にする必要がある。

当然、証明書が増えるとその分管理コストが増える。証明書の有効期限がバラバラだったら?証明書の更新手続きや差し替えなどを頻繁にやるのは面倒だ。

なので、可能な限り利用する証明書は少なくしたい。そういうときにワイルドカード証明書がとても便利なのだ。

調べた結果

*.pinkumohikan.com 用のワイルドカード証明書が pinkumohikan.com ドメインでも使えるかどうかの技術的な回答は、digicertの資料に答えがあった。

dc.cybertrust.co.jp

従来のワイルドカード証明書では「support.example.com」のように「*」で指定した階層と同じ階層の FQDN でしか利用できませんでした。 DigiCert のワイルドカード証明書はコモンネームと同じドメインであれば、Subject Alternative Names(サブジェクトの別名)を使用して、コモンネームと異なる階層の FQDN を追加可能なため、「example.com」というドメイン名そのものや、「support.mail.example.com」のような別の階層の FQDN も 1 枚で利用可能です。

技術的に一言でいうと、Common Nameが *.pinkumohikan.com となっているだけだと pinkumohikan.com は階層が違うので使えないが、 Subject Alternative Names というプロパティで pinkumohikan.com が明記されている場合は利用可能ということだ。

SANs (Subject Alternative Names)

www.geotrust.co.jp

ようは、証明書のプロパティで「このドメインでも使っていい」という情報を持たせられるらしい。

f:id:pinkumohikan:20181027214643p:plain

Google Chromeの証明書ビューアでは「サブジェクト代替名」と表現されていた。

f:id:pinkumohikan:20181027214745p:plain

Let's Encryptで発行したこのワイルドカード証明書は pinkumohikan.com ドメインでは使え無さそうだ。

結論

*.pinkumohikan.com 用のワイルドカード証明書が pinkumohikan.com ドメインでも使えるかどうかは、発行元が証明書発行時にSANsプロパティに pinkumohikan.com ドメインを明記するかどうか次第である。