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エラーはキャッシュしないようだ。
CentOS 7のduplicity (paramiko)でホスト鍵検証が通らない
サーバを入れ替えてホスト名に対するホスト鍵が変わったサーバ。事前にknown_hostsを編集して新サーバの鍵を追加してあり、OpenSSHのssh
、sftp
では正常に接続できる。
また前提としてpython2-paramiko-1.16.1-2.el7 時点ではECDSA鍵は使えないっぽいのでRSA鍵になる。
duplicity
でsftp経由でバックアップしようとするとエラーが出る。
BackendException: ssh connection to target.server failed: ('target.server',
, )
検索するとホスト鍵の検証を無効化する対処法が出てくるがセキュリティを完全に損なうので言うまでもなく実環境で真似してはいけない。
挙動を見たところ*1、OpenSSHの実装ではドキュメントの通りに一致する鍵が見つかるまでknown_hostsの各行の検証を続けるが、Paramikoでは最初に一致するホスト名しか検証していない雰囲気だった。
今回の場合、旧サーバを落とすまでの一時的な状態として複数の鍵が同じホスト名に対応する状態になっていた。
[target.server],[old.server],[10.0.0.1] ssh_rsa ... [target.server],[new.server],[10.0.0.2] ssh_rsa ...
target.serverを名前解決すると10.0.0.2(new.server)になりそちらに接続するのだが、old.server側の鍵と比較して不一致のためエラーになっていたようだ。
new.serverという名前で接続するようにしたところ、エラーは出なくなり動作した。
*1:詳細は調べていない
CentOS 7のduplicity-0.7.11-1.el7 の--encrypt-keyが動作しない
GPGがエラーを起こす。
GPGError: GPG Failed, see log below: ===== Begin GnuPG log ===== gpg: invalid option "--pinentry-mode=loopback" ===== End GnuPG log =====
とりあえずオプション指定を外して対応した。
/usr/lib64/python2.7/site-packages/duplicity/gpg.py
の以下をコメントアウト。
elif profile.gpg_major == 2: # This forces gpg2 to ignore the agent. # Necessary to enforce truly non-interactive operation. if platform.platform().startswith('Linux'): gnupg.options.extra_args.append('--pinentry-mode=loopback')
バグレポートされていたので次の更新で直ると期待。
Adventure Land
Adventure LandというMORPG風のゲームがある。数か月前くらいにできて、まだプロトタイプだそうだが、cursors.io, agar.io, diep.ioのようにHTML5ベースのゲームだ。
HTML5ということはJavaScriptで動いているわけで、クライアントサイドでごにょごにょやる層も出てくるわけだが、他と違うのはその仕組みがもともとゲームに備わっていることだ。
試しにスクリプト機能をいろいろといじってみた。ただしプロトタイプ版のため、現時点とは仕様が変わる可能性がある。
続きを読む