t.marcusの外部記憶装置

忘備録とかちょっとした考えとかをつらつらと...

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ジョブを実行したところ…

f:id:t_marcus87:20160209193850p:plain

_人人人人人人人人人人人人人人_
> 燦々と輝く「ジョブ失敗」 <
 ̄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

詳しくはこちら

NginxをL7 LBとして使う

名だたるメーカーのLBは数百万してしまうので、個人で使うには高過ぎる。
個人用途だと十分すぎる?のでnginxをアクティブスタンバイ構成のLBとして使う方法

やりたいことをまとめると

  1. /path1もしくは/path2以下のでアクセスが来た場合はweb2にproxyする
  2. 上記以外のリクエストはweb1にproxyする
  3. web1とweb2はそれぞれアクティブスタンバイ(active/passive)構成として、基本的にはactiveが受けるが、activeが応答しなかった場合はpassiveで処理を行う
  4. 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"