CentOS 7でgeoipupdateが動かなくなった
GeoIP-update-1.5.0-11.el7 が4月からエラーを吐くようになった。
/etc/cron.weekly/geoipupdate: Received Error -21 (Sanity check database_info string failed) when attempting to update GeoIP Database Received Error -21 (Sanity check database_info string failed) when attempting to update GeoIP Database
サイトを確認してみると、ライセンス購入をしていないとLegacy Databaseは更新できなくなり、ダウンロードできるのも3月版のみ、しかも2019年1月2日からはウェブからも削除されるらしい。
GeoLite2は使える風なので、別途GeoIP2をインストールしてみる。
データベースのダウンロード
本来であればデータベースをダウンロードするのだが、後述の通り2019年12月下旬より直接のデータのダウンロードはできなくなった。geoipupdateというアップデータで全データをダウンロードすることになる。バージョン2系のアップデータは全データのダウンロードがとても遅かったが、現在のバージョンでは解消されている。
geoipupdate のインストール
更新のためgeoipupdateを入れる。
リリースページにバイナリリリースのtarballがあるのでこれを使用した。
rpmもあるが、これを入れるにはGeoIP1系を消しておく必要がある。
curl -O https://github.com/maxmind/geoipupdate/releases/download/v4.1.5/geoipupdate_4.1.5_linux_386.tar.gz tar xaf geoipupdate_4.1.5_linux_386.tar.gz cd geoipupdate_4.1.5_linux_386 mkdir -p /opt/geoip/{bin,etc} mv geoipupdate /opt/geoip/bin/ mv GeoIP.conf /opt/geoip/etc/
GeoIP.conf の DatabaseDirectory も設定する。
# The directory to store the database files. Defaults to /usr/local/share/GeoIP DatabaseDirectory /opt/geoip/share/GeoIP
geoipupdate をソースからビルドする場合
以下はソースからビルドする場合だが、バージョン2.5の時の例なので現在(4.1)とは手順が異なる可能性が高い。
sudo yum install libcurl-devel git clone --depth=1 https://github.com/maxmind/geoipupdate cd geoipupdate ./bootstrap ./configure --prefix=/opt/geoip make sudo make install
ASN databaseも更新するならばGeoIP.confのEditionIDsにGeoLite2-ASNを追加する必要がある。
ライセンスキーを取得する
2019年12月下旬より、カリフォルニアのプライバシー法(CCPA)準拠のために無料利用でもアカウントが必要になったらしい。
GeoIPの利用者もCCPAに準拠する必要があるが、その辺りはここでは割愛する。
更新をテストする
/opt/geoip/bin/geoipupdate -f /opt/geoip/etc/GeoIP.conf -v | less
rpmインストールや自前でビルドした場合など、デフォルトのパスを使っている場合は-fでconfファイルの場所を指定する必要はない。
ASN databaseは毎週火曜、他は毎月最初の火曜に更新されるらしい。
タイムゾーンが不明なので木曜頃に更新するようにcrontabに書いた。
23 9 1-8 * Thu /opt/geoip/bin/geoipupdate -f /opt/geoip/etc/GeoIP.conf
以上だが…
あとは各アプリケーションでGeoIPではなくGeoIP2を使うようにする必要があり、これが多いと面倒かもしれない。
またDBパスがデフォルトではないので /opt/geoip/share/GeoIP 以下をクライアントでも指定する必要がある。
GNU screenで行の折り返しが変になる
GNU screen内のbashやvimで画面幅に収まらない長い行を表示しても折り返されず、右端の文字が上書きされるだけになってしまう。
症状として、bashで上下キーなどでhistoryを表示していると長い行を表示した後でその分だけカーソルが上に行ってしまう。vimでは長い行の後で階段状に表示され、しかも改行されない分だけ以降の行が実際より上に表示される。
line-wrapが切れているのが原因なので直すには^arや、^a^r、^a:wrap (:wrap on)で+wrap状態にすればよい。何かのはずみにミスタイプして-wrap状態になったのだろう。
これが起きた環境ではscreenの中のあるウインドウでsshしてさらにscreenを起動しており、外側のscreenで-wrapとなっていた。
内側のscreenが原因かと思いそちらで試行錯誤していてなかなか気づかなかった。
そもそも:wrap offを使ったことがないので.screenrcに
bind r bind ^r
としてキーを無効化してみた。
parse_url()の結果が壊れる
parse_url()で日本語URL(IRI状態)を渡すと壊れる。具体的には全角空白が別のUTF-8として無効な文字列になった。(PHP7.1)
調べてみるとphp_replace_controlchars_ex()でiscntrl()を呼び出し、コントロール文字を'_'に置換している。
日本語のWindows環境ではASCIIの\x00-\x1f, \x7fだけでなく\x80も対象になるため、UTF-8の全角空白(U+3000 = \xe3\x80\x80)が壊れたようだ。
バグ報告も昔からされているがUNIX系環境のen_US.UTF8で普段作業するせいか知らなかった。回避するにはlocaleを無難なものに設定すればよい。
普通のウェブプログラムではlocale依存の処理はOSに任せずに文字コード系もmbstringのUTF-8一択なので、余計な作用が出ないほうが望ましい。
そこで冒頭で
<?php setlocale(LC_ALL, 'C');
とした。限定的ならばLC_CTYPE
のみを一時的に変更する。
<?php $oldLocale = setlocale(LC_CTYPE, 0); // Japanese_Japan.932 setlocale(LC_CTYPE, 'C'); parse_url(...); setlocale(LC_CTYPE, $oldLocale);
PHP8以降ではデフォルトでlocaleはCのため不要。
Let's Encryptが落ちていてOCSPリクエストがエラーになる
Service status: Service Disruption
https://letsencrypt.status.io/
アクセスのあるサイトはキャッシュが生きているのだが、運悪く証明書を更新したばかりのサイトがあった。これは困る。
Firefox の security.ssl.enable_ocsp_stapling = true
(デフォルト) クライアント環境で SEC_ERROR_OCSP_TRY_SERVER_LATER が表示されたりする。Apache では SSLStaplingReturnResponderErrors on
(デフォルト)か SSLStaplingFakeTryLater on
(デフォルト)をoff
にすれば回避できる。とりあえず SSLStaplingFakeTryLater
が問題発見の邪魔になるので切る。
また SSLStaplingResponderTimeout 10
(デフォルト)を短くするとトラブル時にクライアントの初回アクセス時間を短縮できる。といってもクライアント側でも検証できない以上keep-aliveでTLS接続が生きている間だけのような雰囲気だし、短くしすぎると正常なレスポンスも受け取れなくなる懸念がある。
今回はOCSPサーバが動いていないことが分かってるので一時的に SSLUseStapling
を切っても何ら問題はない。
診断
$ openssl s_client -connect DOMAIN:443 -status -servername DOMAIN < /dev/null | less ... DONE CONNECTED(00000003) OCSP response: no response sent ...
OCSPが返らない。
OpenSSL: Manually verify a certificate against an OCSPを参考に細かくテストする。詳しくはman ocsp
。
$ openssl x509 -noout -ocsp_uri -in cert.pem http://ocsp.int-x3.letsencrypt.org/ $ openssl ocsp -issuer chain.pem -cert cert.pem -text -url http://ocsp.int-x3.letsencrypt.org/ -header HOST ocsp.int-x3.letsencrypt.org -resp_text ... Error querying OCSP responsder 140014513862560:error:27076072:OCSP routines:PARSE_HTTP_LINE1:server response error:ocsp_ht.c:250:Code=400,Reason=Bad Request
400になってしまった。Hostヘッダを手動で送る。
$ openssl ocsp -issuer chain.pem -cert cert.pem -text -url http://ocsp.int-x3.letsencrypt.org/ -header Host ocsp.int-x3.letsencrypt.org ... Error querying OCSP responsder 140045098887072:error:27076072:OCSP routines:PARSE_HTTP_LINE1:server response error:ocsp_ht.c:250:Code=504,Reason=Gateway Time-out
しばらく待たされてからサーバ側でタイムアウトする。
Apache では SSLStaplingErrorCacheTimeout 600
(デフォルト)があるが、OCSPのレベルのエラーをキャッシュするだけなのか、このHTTPエラーはキャッシュしないようだ。