生成ssl证书
克隆tls-gen库
$ git clone https://github.com/michaelklishin/tls-gen.git
$ cd tls-gen/basic
生成root ca及相关证书
$ PASSWORD=bunnies make (设置证书密码,并生成证书)
$ ls -lha ./result (ca, server, client证书都在里面)
验证证书
$ make verify
默认CN用的是hostname,也可以指定CN
$ CN=secure.mydomain.local PASSWORD=bunnies make
创建rabbitmq flux HelmRelease文件 rabbitmq.yaml
:
---
apiVersion: flux.weave.works/v1beta1
kind: HelmRelease
metadata:
name: rabbitmq
namespace: default
annotations:
flux.weave.works/automated: "true"
spec:
releaseName: rabbitmq
chart:
repository: http://mirror.azure.cn/kubernetes/charts/
name: rabbitmq
version: 6.7.4
values:
rabbitmq:
username: admin
password: admin
extraPlugins: "rabbitmq_shovel rabbitmq_shovel_management rabbitmq_federation rabbitmq_federation_management"
extraConfiguration: |-
ssl_options.versions.1 = tlsv1.2
ssl_options.versions.2 = tlsv1.1
tls:
enabled: true
caCertificate: |-
-----BEGIN CERTIFICATE-----
MIIDRTCCAi2gAwIBAgIJAP5p2dgMPqDOMA0GCSqGSIb3DQEBCwUAMDExIDAeBgNV
BAMMF1RMU0dlblNlbGZTaWduZWR0Um9vdENBMQ0wCwYDVQQHDAQkJCQkMB4XDTE5
MTEyNTAzMzEzNVoXDTI5MTEyMjAzMzEzNVowMTEgMB4GA1UEAwwXVExTR2VuU2Vs
ZlNpZ25lZHRSb290Q0ExDTALBgNVBAcMBCQkJCQwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQDbPzTi/ijn8v22YGIQXNE3YCvfwAxiCMC2gtbO7juHhmkL
63Y2UBmtWw+aFmnqv1DNexS5tMvSmjx0pPs6jm7xRTMWwfM3l4L6gOy2UarQmmev
D0bPDZ8VEegFaJ4tQJ1MjXPlHDgqhqrrD3oS1iPx2JmDsTgHtOaR5FYsAR+WiUlu
djcFuLVISNH6UXcqjL/1UfcqivS/MaBHop3d4usAK6IE3MfyaSSxVFtlrIac0j/T
b/xudv3G3sPJE/OITvoPK/Wieo6x6WX/caeJAF4OU+a+AQbyVTfotYvcaOjAlu2w
01rBnNZtUGGtVmRUCedJUrJxUbtTNgxqxke2bUjFAgMBAAGjYDBeMAsGA1UdDwQE
AwIBBjAdBgNVHQ4EFgQUZLGx4cV7OSSAIXn+c+CNj6SKteIwHwYDVR0jBBgwFoAU
ZLGx4cV7OSSAIXn+c+CNj6SKteIwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
AQsFAAOCAQEAnF9s1eFD/BA4V5EcsBUcFE/igJpYB009Uk0+RIY7u3AzHW1UBrJu
+jLuF803Hi8IlNVqwmTiokwtjIVcHk9bOFk4D73Ix11pviQ5zrM4oIsUTpplToEC
l+KSUAouEyrBeM+MKvHwMxJxNIQ++4O0ThplmpiyD9PLmjsJ3PqsFlbH/YctmSL7
H08bHSx5T0t5FcYPyIiMMCIKl2RglgAY2868nGhokquiMX2Ohu9ChHBbRJR2OA/7
8+xdKegozY5gT8/H8sFBo6+/h5A6Ceq+ek+JiNpgJqUs8CJNMiejACiBLbug6lwb
NrckMtUV+roaKgByMTy/xVUOVJI4nr1YGw==
-----END CERTIFICATE-----
serverCertificate: |-
-----BEGIN CERTIFICATE-----
MIIDgDCCAmigAwIBAgIBATANBgkqhkiG9w0BAQsFADAxMSAwHgYDVQQDDBdUTFNH
ZW5TZWxmU2lnbmVkdFJvb3RDQTENMAsGA1UEBwwEJCQkJDAeFw0xOTExMjUwMzMx
MzZaFw0yOTExMjIwMzMxMzZaMCsxGDAWBgNVBAMMD01BQ0MwMlZXMjA5SFYyUjEP
MA0GA1UECgwGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
58zrAwQlRQtWgeItD7XApDIwXu2hS1JByyo/o4viwIIbC23onMUymZWn4q+NRgjG
jrxo2kLK2zXiyUy8rvfgv3lDnirQpX49kXQzxpvEWqBPePIhBL8yrNMMwv9EDQfR
NVk2yn2YH+i6ywnLVunueSNexLq0qFtI5l+6Fl9AZSF3aTF1BuNtol4qbjaFiLnK
tWnderBBFldlNRrGiwJ1asNMhi2yTd8yFvwLWdmOudSKO9ThX7/6Lf+e86PKGQ0f
mHpES0vcEtmNdseEbWlVLmXqToEY4gR2HLbKCUHRSb2MYFuHvAW5aiaHCEGpge+j
JSlcEIvQe5BFGhtj7VnqywIDAQABo4GoMIGlMAkGA1UdEwQCMAAwCwYDVR0PBAQD
AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMDYGA1UdEQQvMC2CD01BQ0MwMlZXMjA5
SFYyUoIPTUFDQzAyVlcyMDlIVjJSgglsb2NhbGhvc3QwHQYDVR0OBBYEFGYJZwRV
ofLs44nbc7zsGWMoO6CbMB8GA1UdIwQYMBaAFGSxseHFezkkgCF5/nPgjY+kirXi
MA0GCSqGSIb3DQEBCwUAA4IBAQArTaXl8lq03f5HCtB6sqmNpsdfcji57KkPpnOO
Fs0K4PVoyTFNfFkTHom0CM3OoPmDvruaVgGkfxaTUJug9N0aBoe52jcljasFFkAO
41GhKjl8Mg/u7lrbveO/lC1du//PiXI7za6T/CfKZusPzBJnLfVQFSwEXnOROYn+
umhbVUqldq63ZlkUDg7ZqjLe4T6l+Ecbu+2NK9KmsabTMZNLEVC1aCVuQSgoNb1V
d8dYt05LHGmkkmgu435YJe/hJx8DSXcRaVHkX6x8Kopgd3yoR9dY8QbisD4OBWwv
MDCOe2EqAIn6ZH82C7bg4v6A4P82y1qOHkA1ZEK3L+amypcO
-----END CERTIFICATE-----
serverKey: |-
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA58zrAwQlRQtWgeItD7XApDIwXu2hS1JByyo/o4viwIIbC23o
nMUymZWn4q+NRgjGjrxo2kLK2zXiyUy8rvfgv3lDnirQpX49kXQzxpvEWqBPePIh
BL8yrNMMwv9EDQfRNVk2yn2YH+i6ywnLVunueSNexLq0qFtI5l+6Fl9AZSF3aTF1
BuNtol4qbjaFiLnKtWnderBBFldlNRrGiwJ1asNMhi2yTd8yFvwLWdmOudSKO9Th
X7/6Lf+e86PKGQ0fmHpES0vcEtmNdseEbWlVLmXqToEY4gR2HLbKCUHRSb2MYFuH
vAW5aiaHCEGpge+jJSlcEIvQe5BFGhtj7VnqywIDAQABAoIBAQCRJTpfWCAyPKg9
ii+nL6rh5d9uAaRG8snp+pmAwh4JZy6iGH9Ycw59Jz3J7x0qJmKWjBmn2b0GSJaq
b9eSQ/rCSp9xkeO2TPcmdjnZej4YdVtuI0dTnpmPqFPMYmTtN+DjY+qwHra7/FHC
w25FDRRbXC+CRlrLNOXQA08VpS1AZOQibHke2FvAAvdtOpUrGzAxswKhyeEl99YW
vATkM8z/t91F2gC7wJ4zYGicyRPPCgd0cOvJQoKVQYRy7jN/AonU4wDDEH0nMbjH
cETbk47edkzHuACzmhShMG8j73oo0FR2TgVz62sGGfSWQHIzKig4jEGV4Jv6xpKB
BhFQuRA5AoGBAPnSNEhc2knVuH+GboPdvMtoi/6AjYTSWKuLK/9K7F0106o7VXgJ
n4ieAIMi05oQbhyl0xbx8X+TQ+jWmcDINFEYcfCcIPOg+Syr3qaL6i/Ylz+gJmjq
Ja6dlEz6HwZIr3etWR7hWFjI3Q5StR39QbFBsOEjGDug/2qwe4AUoxT1AoGBAO2I
nLick6aWtnodWWl0vO8/+IzOzSvxsY61sPJnw34Jf/TZ97VhZEZT55nTCcUTUIQk
AA4ZwA6Yr7xZUmKdiKVUw9BrCBjZfR1n4gvjmkRe1tmOKoZ5Rac31kxl9mtoMg+9
+sG5mk0Z2q6GhLnCP75OXd+E1AUSWFORkI3iayi/AoGBAJddAUiG2cu6rlq1/Ofw
xZ8I7Sl6gkRjnk3xuOqpXqTrJCAUayibzAlekjjiNQs3wT+iSU+xr/z4IUFGJUpl
Ay3Pfdmm/2AdvFuQlwqZ436x4JIwWpVeqQ4vc9dgBMQt7gK5CTJonrrMmQNAoXRW
KiNYBe+i79/RIHBoFav41QaxAoGARorGuFDPzK5/nL5wmk/v+EGQSAj2h7FsoMw2
s5a7SQf7NzUwSm6VAAnVAyrYgO2egM/MMGPXVL5lmlMQk3bjaO5GhPP0YKTeckgy
qoM6gkmEFvIQkQUc+W8stl2lk/pKu8AY40WCnJksB56tdhlJIvRVDpd8+9CZ6J+X
RXvThTMCgYEAlE1e0fG9fN2DCFpPk1FfOW20XeayRmkOw7YkLYLkn3iBnAbyLpQb
KBnKzmDyV43kJKlm5UYL4nORj+kRp6bEPmwEIEtUGHunM/oIUwl/B7qwEqCDjR4h
RVwaVkTk7se1gItw67b3uNCHdN6Dd5Gjhv54ezhMYnI2rTYv4U1pSqA=
-----END RSA PRIVATE KEY-----
resources:
requests:
cpu: 100m
memory: 256Mi
replicas: 1
metrics:
enabled: true
volumePermissions:
enabled: true
persistence:
enabled: true
ingress:
enabled: true
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
path: /rabbitmq(/|$)(.*)
提交代码到个人的 Flux Repo
手动触发flux同步
$ fluxctl sync --k8s-fwd-ns flux
检查rabbitmq运行状态
$ kubectl get pod rabbitmq-0
NAME READY STATUS RESTARTS AGE
rabbitmq-0 2/2 Running 2 4h10m
创建测试脚本目录
$ mkdir test_scripts
$ cd test_scripts
拷贝ssl证书
$ mkdir ssl
$ cp ./result/{ca_certificate.pem,client_certificate.pem,client_key.pem} ssl/
创建发送端send.go
:
package main
import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
"log"
"github.com/streadway/amqp"
)
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
}
// 只能在安装 rabbitmq 的服务器上操作
func main() {
cfg := new(tls.Config)
cfg.RootCAs = x509.NewCertPool()
if ca, err := ioutil.ReadFile("ssl/ca_certificate.pem"); err == nil {
cfg.RootCAs.AppendCertsFromPEM(ca)
} else {
failOnError(err, "Failed to append ca")
}
if cert, err := tls.LoadX509KeyPair("ssl/client_certificate.pem", "ssl/client_key.pem"); err == nil {
cfg.Certificates = append(cfg.Certificates, cert)
} else {
failOnError(err, "Failed to append client cert")
}
conn, err := amqp.DialTLS("amqps://admin:admin@localhost:5671/", cfg)
failOnError(err, "Failed to connect to RabbitMQ")
defer conn.Close()
ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
defer ch.Close()
q, err := ch.QueueDeclare(
"hello", // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue")
body := "Hello World!"
err = ch.Publish(
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(body),
})
log.Printf(" [x] Sent %s", body)
failOnError(err, "Failed to publish a message")
}
创建接收端recv.go
:
package main
import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
"log"
"github.com/streadway/amqp"
)
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
}
// 只能在安装 rabbitmq 的服务器上操作
func main() {
cfg := new(tls.Config)
cfg.RootCAs = x509.NewCertPool()
if ca, err := ioutil.ReadFile("ssl/ca_certificate.pem"); err == nil {
cfg.RootCAs.AppendCertsFromPEM(ca)
} else {
failOnError(err, "Failed to append ca")
}
if cert, err := tls.LoadX509KeyPair("ssl/client_certificate.pem", "ssl/client_key.pem"); err == nil {
cfg.Certificates = append(cfg.Certificates, cert)
} else {
failOnError(err, "Failed to append client cert")
}
conn, err := amqp.DialTLS("amqps://admin:admin@localhost:5671/", cfg)
failOnError(err, "Failed to connect to RabbitMQ")
defer conn.Close()
ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
defer ch.Close()
q, err := ch.QueueDeclare(
"hello", // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue")
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer")
forever := make(chan bool)
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
}
}()
log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever
}
运行测试脚本
打开一个终端窗口
$ go run send.go
打开另一个终端窗口
$ go run recv.go