RabbitMQ設定SSL相關操作
阿新 • • 發佈:2018-12-01
相關檔案
openssl.cnf
檔案配置
[ ca ] default_ca = testca [ testca ] dir = . certificate = $dir/cacert.pem database = $dir/index.txt new_certs_dir = $dir/certs private_key = $dir/private/cakey.pem serial = $dir/serial default_crl_days = 7 default_days = 10950 default_md = sha1 policy = testca_policy x509_extensions = certificate_extensions [ testca_policy ] commonName = supplied stateOrProvinceName = optional countryName = optional emailAddress = optional organizationName = optional organizationalUnitName = optional [ certificate_extensions ] basicConstraints = CA:false [ req ] default_bits = 2048 default_keyfile = ./private/cakey.pem default_md = sha1 prompt = yes distinguished_name = root_ca_distinguished_name x509_extensions = root_ca_extensions [ root_ca_distinguished_name ] commonName = hostname [ root_ca_extensions ] basicConstraints = CA:true keyUsage = keyCertSign, cRLSign [ client_ca_extensions ] basicConstraints = CA:false keyUsage = digitalSignature extendedKeyUsage = 1.3.6.1.5.5.7.3.2 [ server_ca_extensions ] basicConstraints = CA:false keyUsage = keyEncipherment extendedKeyUsage = 1.3.6.1.5.5.7.3.1
生成ca檔案,指令碼(setup_ca.sh
)內容如下:
#!/bin/bash
hr="-------------------------------------------"
br=""
strength=2048
valid=10950
message="Usage: sh setup_ca.sh [certificate authority CN]"
if [ $# -ne 1 ];
then
echo $message
exit 2
fi
if [ $1 = "--help" ];
then
echo $message
exit 2
fi
certauthCN= $1
export OPENSSL_CONF=../openssl.cnf
if [ ! -d ./ca/ ];
then
echo "Creating folder: ca/"
mkdir ca
echo "Creating folder: ca/private/"
mkdir ca/private
echo "Creating folder: ca/certs/"
mkdir ca/certs
echo "Creating folder: ca/serial"
echo "01" > ca/serial
echo "Creating file: ca/index.txt"
touch ca/index.txt
fi
cd ca
openssl req -x509 -newkey rsa:$strength -days $valid -out cacert.pem -outform PEM -subj /CN=$certauthCN/ -nodes
openssl x509 -in cacert.pem -out cacert.cer -outform DER
cd ..
生成伺服器證書,指令碼(make_server_cert.sh
)內容如下:
#!/bin/bash
hr="-------------------------------------------"
br=""
strength=2048
valid=10950
message="Usage: sh make_server_cert.sh [server name] [PKCS12 password]"
if [ $# -ne 2 ];
then
echo $message
exit 2
fi
if [ $1 = "--help" ];
then
echo $message
exit 2
fi
sname=$1
password=$2
export OPENSSL_CONF=../openssl.cnf
if [ ! -d ./server/ ];
then
echo "Creating Server folder: server/"
mkdir server
fi
cd server
echo "Generating key.pem"
openssl genrsa -out key.pem $strength
echo "Generating req.pem"
openssl req -new -key key.pem -out req.pem -outform PEM -subj /CN=$sname/O=server/ -nodes
cd ../ca
echo "Generating cert.pem"
openssl ca -in ../server/req.pem -out ../server/cert.pem -notext -batch -extensions server_ca_extensions
cd ../server
echo "Generating keycert.p12"
openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:$password
cd ..
生成客戶端證書,指令碼(create_client_cert.sh
)內容如下:
#!/bin/bash
hr="-------------------------------------------"
br=""
strength=2048
valid=10950
message="Usage: sh create_client_cert.sh [client name] [PKCS12 password]"
if [ $# -ne 2 ];
then
echo $message
exit 2
fi
if [ $1 = "--help" ];
then
echo $message
exit 2
fi
cname=$1
password=$2
export OPENSSL_CONF=../openssl.cnf
if [ ! -d ./client/ ];
then
echo "Creating folder: client/"
mkdir client
fi
cd client
echo "Generating key.pem"
openssl genrsa -out key.pem $strength
echo "Generating req.pem"
openssl req -new -key key.pem -out req.pem -outform PEM -subj /CN=$cname/O=client/ -nodes
cd ../ca
echo "Generating cert.pem"
openssl ca -in ../client/req.pem -out ../client/cert.pem -notext -batch -extensions client_ca_extensions
cd ../client
echo "Generating keycert.p12"
openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:$password
cd ..
步驟:
我這裡以Linux為例,目錄是/usr. 寫一下步驟
首先開啟/usr,建立一個資料夾
mkdir testca
拷貝上面所有shell指令碼,然後分步驟執行:
#引數是證書頒發機構名
sh setup_ca.sh MyRabbitMQSSL
#生成伺服器證書, 第一個引數是伺服器名,第二個引數是密碼
sh make_server_cert.sh rabbit-server rabbit
#生成客戶端證書,第一個引數是客戶端名稱,第二個引數是密碼
sh create_client_cert.sh rabbit-client rabbit
keytool匯入證書
keytool -import -alias rabbit-server -file ./server/cert.pem -keystore trustStore -storepass rabbit
此時會提示是否匯入證書,輸入y
或者是
,然後回車
刪除之前匯入過的證書,別名為 rabbit-server
keytool -delete -alias rabbit-server -keystore trustStore -storepass rabbit
配置rabbitmq
vi $rabbitmq_home/etc/rabbitmq/rabbitmq.config
檔案內容如下:
%% Disable SSLv3.0 and TLSv1.0 support.
[
{ssl, [{versions, ['tlsv1.2', 'tlsv1.1']}]},
{rabbit, [
{tcp_listeners, [5672]},
{ssl_listeners, [5671]},
{ssl_options, [{cacertfile,"/usr/testca/ca/cacert.pem"},
{certfile,"/usr/testca/server/cert.pem"},
{keyfile,"/usr/testca/server/key.pem"},
{verify, verify_peer},
{fail_if_no_peer_cert, true},
{versions, ['tlsv1.2', 'tlsv1.1']}
]}
]}
].
儲存.
重啟rabbitmq.
#關閉服務
rabbitmqctl stop
#啟動服務
rabbitmq-server -detached
#檢視狀態
rabbitmqctl status
編寫java測試類
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.GetResponse;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.security.KeyStore;
public class ValidatingCert{
public static void main(String[] args) throws Exception{
char[] keyPassphrase = "rabbit".toCharArray(); //證書密碼
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream("keycert.p12"), keyPassphrase);//把client目錄keycert.p12拷貝到專案裡面
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keyPassphrase);
char[] trustPassphrase = "rabbit".toCharArray(); //證書密碼
KeyStore tks = KeyStore.getInstance("JKS");
tks.load(new FileInputStream("trustStore"), trustPassphrase);//把/usr/testca/目錄的trustStore拷貝到專案裡面
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(tks);
SSLContext c = SSLContext.getInstance("TLSv1.1");
c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.0.111");//rabbitmq server
factory.setPort(5671);
factory.useSslProtocol(c);
Connection conn = factory.newConnection();
Channel channel = conn.createChannel();
channel.queueDeclare("rabbitmq-queue", false, true, true, null); //rabbitmq-queue是rabbitmq佇列
channel.basicPublish("", "rabbitmq-queue", null, "Test,Test".getBytes());
GetResponse chResponse = channel.basicGet("rabbitmq-queue", false);
if (chResponse == null){
System.out.println("No message retrieved");
}else {
byte[] body = chResponse.getBody();
System.out.println("Recieved: " + new String(body));
}
channel.close();
conn.close();
}
}
參考:
http://vstars.iteye.com/blog/2229409
https://github.com/Berico-Technologies/CMF-AMQP-Configuration/tree/master/ssl