surgemq添加ssl
1.MQTT协议
消息发布订阅功能的消息队列协议
报文组成: 固定报头(控制报文类型)+可变报头(协议名称、协议级别、连接标志、保持连接)+有效载荷(clentId+will topic+will message +username + password )
协议级别QoS支持0,1,2
可以基于tcp和udp
2.surgemq
Surgemq采用了mqtt通信协议可以做Server和Client,项目里主要用它做Server
Server每次和新的Client连接会创建一个新的对象叫Service
用来维护整个连接到关闭过程中服务端和这个客户端的通信,处理消息的发布,订阅
3.ssl(两种方式)
利用自己生成的根证书分别给服务端(ca.crt,server.crt,server.key)和客户端的证书签名(ca.crt,client.crt,client.key)
只需要根证书对服务端和客户端进行ssl验证(ca.crt,ca.key)
3.1方式一:
No.1 获取服务器自签名证书
获取ca.crt
openssl genrsa -out ca.key
openssl req -x509 -new -nodes -key ca.key -subj "/CN=*" -days -out ca.crt
获取服务端证书和key
openssl genrsa -out server.key
server表示服务端ip,需要在测试服务器/etc/hosts配置添加 119.23.136.97 server openssl req -new -key server.key -subj "/CN=server" -out server.csr openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
获取客户端证书
openssl genrsa -out client.key
openssl req -new -key client.key -subj "/CN=server" -out client.csr
echo extendedKeyUsage=clientAuth > extfile.cnf
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile extfile.cnf -out client.crt -days
No.2服务端和客户端使用证书双向验证
Surqmq server监听端口方式改为tls.listen,tlsConfig加入服务端的证书和key以及根证书
//read crt and key``
certpool := x509.NewCertPool()
pemCerts, err := ioutil.ReadFile(ca)
if err != nil {
fmt.Println(err)
return err
}
certpool.AppendCertsFromPEM(pemCerts)
//server 端加入 tls
cert, err := tls.LoadX509KeyPair(crt, key)
if err != nil {
fmt.Println(err)
return err
}
config := &tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: certpool,
}
this.ln, err = tls.Listen("tcp", u.Host, config)
Paho.mqtt client支持ssl方式的连接方式,tlsConfig加入客户端的证书和key以及根证书
//初始化tlsConfig
func NewTLSConfig(ca, crt, key string) *tls.Config {
certpool := x509.NewCertPool()
pemCerts, err := ioutil.ReadFile(ca)
if err == nil {
certpool.AppendCertsFromPEM(pemCerts)
}
cert, err := tls.LoadX509KeyPair(crt, key)
if err != nil {
panic(err)
}
return &tls.Config{
RootCAs: certpool,
Certificates: []tls.Certificate{cert},
}
}
//将给client设置tlsConfig
connOpts.AddBroker(uri).SetTLSConfig(NewTLSConfig(ca, crt, key))
mc = MQTT.NewClient(connOpts)
3.2方式二:
No.1只需要获取根证书server.crt和server.key
openssl genrsa -out server.key
openssl req -x509 -new -nodes -key server.key -subj "/CN=server" -days -out server.crt
No.2服务端和客户端使用根证书进行ssl验证
//server 端加入 tls
cert, err := tls.LoadX509KeyPair(crt, key)
if err != nil {
fmt.Println(err)
return err
}
config := &tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tls.NoClientCert, //此处为tls.NoClientCert
}
this.ln, err = tls.Listen("tcp", u.Host, config)
func NewTLSConfig( crt, key string) *tls.Config {
// Import client certificate/key pair
certpool := x509.NewCertPool()
pemCerts, err := ioutil.ReadFile(crt)
if err == nil {
certpool.AppendCertsFromPEM(pemCerts)
}
// Create tls.Config with desired tls properties
return &tls.Config{
RootCAs:certpool,
}
}
//将给client设置tlsConfig
connOpts.AddBroker(uri).SetTLSConfig(NewTLSConfig(ca, crt, key))
mc = MQTT.NewClient(connOpts)