概要
golang の MQTT クライアントを使って test.mosquitto.org に対して TLS での接続を試します。
認証を使う場合は TLS は必須なので、最低限の確認をしておきます。
準備
- 証明書を用意します。
- http://test.mosquitto.org/ にダウンロードする URL が書いてあります。
$ curl -O http://test.mosquitto.org/ssl/mosquitto.org.crt
$ cat mosquitto.org.crt
-----BEGIN CERTIFICATE-----
MIIC8DCCAlmgAwIBAgIJAOD63PlXjJi8MA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD
VQQGEwJHQjEXMBUGA1UECAwOVW5pdGVkIEtpbmdkb20xDjAMBgNVBAcMBURlcmJ5
MRIwEAYDVQQKDAlNb3NxdWl0dG8xCzAJBgNVBAsMAkNBMRYwFAYDVQQDDA1tb3Nx
dWl0dG8ub3JnMR8wHQYJKoZIhvcNAQkBFhByb2dlckBhdGNob28ub3JnMB4XDTEy
MDYyOTIyMTE1OVoXDTIyMDYyNzIyMTE1OVowgZAxCzAJBgNVBAYTAkdCMRcwFQYD
VQQIDA5Vbml0ZWQgS2luZ2RvbTEOMAwGA1UEBwwFRGVyYnkxEjAQBgNVBAoMCU1v
c3F1aXR0bzELMAkGA1UECwwCQ0ExFjAUBgNVBAMMDW1vc3F1aXR0by5vcmcxHzAd
BgkqhkiG9w0BCQEWEHJvZ2VyQGF0Y2hvby5vcmcwgZ8wDQYJKoZIhvcNAQEBBQAD
gY0AMIGJAoGBAMYkLmX7SqOT/jJCZoQ1NWdCrr/pq47m3xxyXcI+FLEmwbE3R9vM
rE6sRbP2S89pfrCt7iuITXPKycpUcIU0mtcT1OqxGBV2lb6RaOT2gC5pxyGaFJ+h
A+GIbdYKO3JprPxSBoRponZJvDGEZuM3N7p3S/lRoi7G5wG5mvUmaE5RAgMBAAGj
UDBOMB0GA1UdDgQWBBTad2QneVztIPQzRRGj6ZHKqJTv5jAfBgNVHSMEGDAWgBTa
d2QneVztIPQzRRGj6ZHKqJTv5jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA
A4GBAAqw1rK4NlRUCUBLhEFUQasjP7xfFqlVbE2cRy0Rs4o3KS0JwzQVBwG85xge
REyPOFdGdhBY2P1FNRy0MDr6xr+D2ZOwxs63dG1nnAnWZg7qwoLgpZ4fESPD3PkA
1ZgKJc2zbSQ9fCPxt2W3mdVav66c6fsb7els2W2Iz7gERJSX
-----END CERTIFICATE-----
インストール
go getすればいいので特に必要ありません。
コード
package main
import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
"log"
MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
)
func GetCertPool(pemPath string) (*x509.CertPool, error) {
certs := x509.NewCertPool()
pemData, err := ioutil.ReadFile(pemPath)
if err != nil {
return nil, err
}
certs.AppendCertsFromPEM(pemData)
return certs, nil
}
// Connect connects MQTT broker with tls
func Connect(brokerUri string, clientId string, crtFile string) (*MQTT.MqttClient, error) {
opts := MQTT.NewClientOptions()
opts.AddBroker(brokerUri)
opts.SetClientId(clientId)
certPool, err := GetCertPool(crtFile)
if err != nil {
return nil, err
}
tlsConfig := &tls.Config{
RootCAs: certPool,
}
opts.SetTlsConfig(tlsConfig)
client := MQTT.NewClient(opts)
_, err = client.Start()
if err != nil {
return nil, err
}
return client, nil
}
// Publish publish message
func Publish(client *MQTT.MqttClient, topic string, payload []byte){
mqttmsg := MQTT.NewMessage(payload)
receipt := client.PublishMessage(topic, mqttmsg)
<-receipt
}
func main() {
cli, err := Connect("ssl://test.mosquitto.org:8883", "tlstest", "mosquitto.org.crt")
if err != nil{
log.Fatal(err)
}
Publish(cli, "/test/tls", []byte("test"))
}
解説
- Connectの時に"ssl://"を指定する
- SetTlsConfigでtlsConfigを設定する。
- tsl.Configはgolangの標準なのでHTTPSなどと同じように使えます。