zoneedit の dynamic DNS の更新に ddclient (pkgsrc/net/ddcleint) を利用していたのだが、エラーが出て更新できなくなってしまった。
zoneedit のアナウンスとかは見当たらなかったが、どうやら HTTPS でのみ更新が可能なように仕様が変更されたっぽい。
pkgsrc-2014Q1 の ddclient-3.6.6 は SSL が使用できないが、最新版では使用できるらしいとの話を聞きつけて、ddclient-3.8.2 を本家から持ってきて試してみたのだがエラーが出てうまくいかない。
syswrite() on closed filehandle GEN1 at ./ddclient line 1902. Use of uninitialized value $result in numeric ne (!=) at ./ddclient line 1904. WARNING: cannot send to dynamic.zoneedit.com:443 (Bad file descriptor).
デバッグ出力を埋め込んで調べてみると、zoneedit の SSL 証明書の検証ができなくて失敗していることがわかった。
WARNING: cannot connect to dynamic.zoneedit.com:443 socket: SSL connect attempt failed with unknown error error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed SSL connect attempt failed with unknown error error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
とはいえ、ブラウザはともかく、NetBSD で SSL ルート証明書の管理などしてない。どうしよう。
結局、検証は行わないように ddclient を修正して対処した。
@@ -1881,8 +1880,9 @@ Proto => 'tcp', MultiHomed => 1, Timeout => opt('timeout'), + SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE(), ); - defined $sd or warning("cannot connect to $peer:$port socket: $@ " . IO::Socket::SSL::errstr()); + fileno($sd) or warning("cannot connect to $peer:$port socket: $@ " . IO::Socket::SSL::errstr()); } else { $sd = IO::Socket::INET->new( PeerAddr => $peer,
SSL_VERYFY_NONE は IO::Socket::SSL 内で定義されている定数だが、他所から明示的に参照したいときはサブルーチンのように記述すれば良いらしい。
あと、IPアドレス取得用の URL も https://dynamic.zoneedit.com/checkip.html のように HTTPS しか受け付けなくなってしまった。上記の修正だけでは HTTP で取得しようとしてしまうのだが、ddclient.conf の web の引数に https:// を付けて記述すればよい。
use=web, web=https://dynamic.zoneedit.com/checkip.html, web-skip='IP Address'