maven-release-pluginでReceived fatal alert: bad_record_macが出た話
リリース作業中に問題発生したので、自戒録がてら書き連ねておく。
結果としては、Java7だったので、MAVEN_OPTS="-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2"
を環境変数にぶち込んで走らせれば解決しました。
(Java8は試してませんが、おそらく-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djdk.tls.client.protocols=TLSv1,TLSv1.1,TLSv1.2
を指定すれば、行けるはずです)
事の起こりは、リリース作業中にpomのバージョンをイテレーションして、Sonatype Nexus Repository Manager(以下、Nexus)へ成果物のアップロードを行うJenkinsジョブを実行したところ…
_人人人人人人人人人人人人人人_
> 燦々と輝く「ジョブ失敗」 <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
とりあえず、ログを眺めてみると…
$ mvn -Dresume=false release:prepare release:perform -B : : [INFO] --- maven-release-plugin:2.0:prepare (default-cli) @ hoge-api-server --- : : [INFO] --- maven-release-plugin:2.0:perform (default-cli) @ hoge-api-server --- : : [INFO] [INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ hoge-api-server --- [INFO] Uploading: https://nexus.example.com/content/repositories/releases/com/example/api/hoge-api-server/1.59.0/hoge-api-server-1.59.0.jar [INFO] Uploading: https://nexus.example.com/content/repositories/releases/com/example/api/hoge-api-server/1.59.0/hoge-api-server-1.59.0.pom [INFO] Uploaded: https://nexus.example.com/content/repositories/releases/com/example/api/hoge-api-server/1.59.0/hoge-api-server-1.59.0.pom (9 KB at 28.9 KB/sec) [INFO] [INFO] ------------------------------------------------------------------------ [INFO] [INFO] BUILD FAILURE [INFO] [INFO] ------------------------------------------------------------------------ [INFO] [INFO] Total time: 53.752s [INFO] [INFO] Finished at: Tue Feb 09 13:31:27 JST 2016 [INFO] [INFO] Final Memory: 57M/1313M [INFO] [INFO] ------------------------------------------------------------------------ [INFO] [ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on project hoge-api-server: Failed to deploy artifacts: Could not transfer artifact com.example:hoge-api-server:jar:1.10.0 from/to hoge-releases (https://nexus.hoge.org/content/repositories/releases/): Received fatal alert: bad_record_mac -> [Help 1] [INFO] [ERROR] [INFO] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [INFO] [ERROR] Re-run Maven using the -X switch to enable full debug logging. [INFO] [ERROR] [INFO] [ERROR] For more information about the errors and possible solutions, please read the following articles: [INFO] [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
何やら、Nexusへの登録がbad_record_mac
で失敗してるっぽい。
とりあえず、ググってみる。
検索結果から、SSL周りのエラーっぽい雰囲気が漂ってくる。
とりあえずjenkinsサーバに入って、Nexusと話をしてみる…
$ curl -vs https://nexus.example.com * Rebuilt URL to: https://nexus.example.com/ * Trying 12.34.56.78... * Connected to nexus.example.com (12.34.56.78) port 443 (#0) * TLS 1.2 connection using TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 * Server certificate: *.example.com : : > GET / HTTP/1.1 > Host: nexus.example.com > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: text/html < Content-Length: 8009 < Connection: keep-alive < X-Frame-Options: SAMEORIGIN < X-Content-Type-Options: nosniff < Last-Modified: Tue, 09 Feb 2016 10:47:55 GMT < Pragma: no-cache < Cache-Control: post-check=0, pre-check=0 < Expires: 0 < <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> : :
ちゃんとお話できてるっぽい。
SSLといえば、最近Poodleの関係で、SSLv3がサポート切られてたりしてたはず…ということで、SSLv3でお話してみると…
$ curl -vs --sslv3 https://nexus.example.com * Rebuilt URL to: https://nexus.example.com/ * Trying 12.34.56.78... * Connected to nexus.example.com (12.34.56.78) port 443 (#0) * SSL peer handshake failed, the server most likely requires a client certificate to connect * Closing connection 0 curl: (35) SSL peer handshake failed, the server most likely requires a client certificate to connect
ビンゴ!
ということで、Javaのオプションで、SSLv3をオフって解決
mvn -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Dresume=false release:prepare release:perform -B
詳しくはこちら
Zombie.js試してみた(仮設)
最近Zombie.jsでフロントエンドのテストをすることが多くなってきたので、よく使いそうなところを書き出してみた。
// TODO 主要どころのBrowserのメソッドとかそのうち書きたい
忘備録)IntelliJ Maven Error
IntelliJでmvn clean compileを実行した時に以下のメッセージが出た時の対応方法
-Dmaven.multiModuleProjectDirectory system property is not set.
以下の設定を行う
-Dmaven.multiModuleProjectDirectory=$M2_HOME
NginxをL7 LBとして使う
名だたるメーカーのLBは数百万してしまうので、個人で使うには高過ぎる。
個人用途だと十分すぎる?のでnginxをアクティブスタンバイ構成のLBとして使う方法
やりたいことをまとめると
- /path1もしくは/path2以下のでアクセスが来た場合はweb2にproxyする
- 上記以外のリクエストはweb1にproxyする
- web1とweb2はそれぞれアクティブスタンバイ(active/passive)構成として、基本的にはactiveが受けるが、activeが応答しなかった場合はpassiveで処理を行う
- activeが復旧した場合はactiveが処理を行う
【テスト環境】
# サーバ環境 $ cat /etc/redhat-release CentOS release 6.4 (Final) $ nginx -v nginx version: nginx/1.0.15 # ネットワーク環境 + lb (192.168.56.20) | +- web1-active (192.168.56.30) +- web1-passive (192.168.56.31) | +- web2-active (192.168.56.40) +- web2-passive (192.168.56.41) # LB以外のnginxのドキュメントルート配下の構成 # それぞれのファイルにはどのサーバのホスト名を書く ./ + path1/ | + index.html + path2/ | + index.html + index.html + hoge.html + piyo.html
まずnginxにweb1とweb2のグループを登録してactive/passiveの設定を行う
$ cat /etc/nginx/nginx.conf user nginx; worker_processes 1; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 1; # web1の設定 upstream web1 { server 192.168.56.30:80 fail_timeout=1s max_fails=1; server 192.168.56.31:80 backup; } # web2の設定 upstream web2 { server 192.168.56.40:80 fail_timeout=1s max_fails=1; server 192.168.56.41:80 backup; } include /etc/nginx/conf.d/*.conf; }
そして、rewriteの設定を行う
$ cat /etc/nginx/conf.d/default.conf server { listen 80; location / { proxy_pass http://web1; } location ~ (\/path1|\/path2)(\/.*)? { proxy_pass http://web2; } error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
そしてnginxを再起動すると、アクティブスタンバイ構成のLBとして機能するようになる。
Node.jsでカスタムエラー(メモ)
Node.jsでカスタムエラーをつくろうと思って、
Errorをinheritsしただけでは、error.stackが利用できなかったので、色々試行錯誤した結果をメモ。
ちなみに環境は
Node.js 0.10.29
// lib/error/base.js 'use strict'; var util = require('util'); function BaseError(message, code) { Error.call(this); Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; this.status = code || 500; this.message = message || 'BaseError'; } util.inherits(BaseError, Error); module.exports = BaseError;
// lib/error/extend.js 'use strict'; var util = require('util'), BaseError = require('./base'); function ExtendError(message) { BaseError.call(this, message || 'ExtendErrorMessage'); } util.inherits(ExtendError, BaseError); module.exports = ExtendError;
// lib/sample.js var BaseError = require('./error/base'), ExtendError = require('./error/extend'); var be = new BasicError('msg1'); console.log(be); console.log(be.stack); var ee = new ExtendError('msg2', 503); console.log(ee); console.log(ee.stack);
って感じにすると
{ [BaseError: msg1] name: 'BaseError', status: 500, message: 'msg1' } BaseError: msg1 at /Users/tmarcus/Projects/node-test/lib/sample.js:4:5 : : { [ExtendError: msg2] name: 'ExtendError', status: 503, message: 'msg2' } ExtendError: msg2 at /Users/tmarcus/Projects/node-test/lib/sample.js:7:5 : :
という感じで出力されてるのでいけてるっぽい?
Vagrant VirtualBox NICアダプター追加に関する覚書
VirtualBoxから作ったVagrant BaseBoxにNicを追加する設定を追加するVagrantfileの忘備録
config.vm.provider :virtualbox do |vb| vb.customize ["modifyvm", :id, "--nic2", "hostonly"] vb.customize ["modifyvm", :id, "--nictype2", "82540EM"] vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"] end config.vm.network "private_network", ip: "192.168.56.20"
Xmemcache + TimeUnitの組み合わせでミリ秒を利用して嵌った
実験環境:
xmemcached : 1.3.8
memcached : 1.4.11
作ろうとしていた機能は以下の様なものです。
- キャッシュを探してデータがあればそれを返す。なければ次の処理を実行する。
- 別システムからデイリーで変更されるIDのリストを取得する
- それぞれのデータにプログラム側が持ってるメタ情報をくっつける。
- 組み立てたデータを毎時15時パージするようにキャッシュに放り込む
- 組み立てたデータを返す。
実際に起きた現象はこんなかんじです。
1日目・2日目は正常にデータが更新される。
3日目以降は2日目のデータが残り続ける。
結論からいうと、TimeUnitで時間の単位変換をしようとして、toSeconds(ttl)を利用する際に、粒度の細かい方から粗いほうへ変換した際に値の切り詰めが発生してしまった感じです。
値の切り詰めに関しては、TimeUnit (Java Platform SE 6)を参考にしてください。