first commit

This commit is contained in:
ssp97 2024-08-22 02:58:23 +08:00
commit 74712b6d5b
19 changed files with 477 additions and 0 deletions

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# 默认忽略的文件
/shelf/
/workspace.xml

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/2024-08-22_mqtt_relay.iml" filepath="$PROJECT_DIR$/.idea/2024-08-22_mqtt_relay.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

19
config/config.go Normal file
View File

@ -0,0 +1,19 @@
package config
// Config represents the configuration structure
type Config struct {
Server struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
EnableTLS bool `yaml:"enable_tls"`
CertFile string `yaml:"cert_file"`
KeyFile string `yaml:"key_file"`
} `yaml:"server"`
Relay struct {
Broker string `yaml:"broker"`
EnableTLS bool `yaml:"enable_tls"`
CertFile string `yaml:"cert_file"`
KeyFile string `yaml:"key_file"`
} `yaml:"relay"`
LogFile string `yaml:"log_file"`
}

16
go.mod Normal file
View File

@ -0,0 +1,16 @@
module github.com/ssp97/mqtt_relay
go 1.21.5
require (
github.com/256dpi/gomqtt v0.14.4
github.com/mochi-mqtt/server/v2 v2.6.5
gopkg.in/yaml.v2 v2.4.0
)
require (
github.com/256dpi/mercury v0.2.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/rs/xid v1.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

52
go.sum Normal file
View File

@ -0,0 +1,52 @@
github.com/256dpi/gomqtt v0.14.4 h1:eO9FjRExQ9G9I3RTzDAEYhuS5KFy5RYudrnCvKSr8Z0=
github.com/256dpi/gomqtt v0.14.4/go.mod h1:s8uMqxWMl93jUyPGNutI1Duy2lxWkcQZ6qky+OPQmfM=
github.com/256dpi/mercury v0.2.0 h1:ImB0JYuZ28kwp2MpqnMdQFSD3z9mgaNYHrSjYuyP0LI=
github.com/256dpi/mercury v0.2.0/go.mod h1:xxgxZSQO7VUwxGLpk8yRVe/WF0MKH7nCIwSh4kUVMy4=
github.com/Pallinder/go-randomdata v1.2.0/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y=
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/jpillora/backoff v0.0.0-20170918002102-8eab2debe79d/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mochi-mqtt/server/v2 v2.6.5 h1:9PiQ6EJt/Dx0ut0Fuuir4F6WinO/5Bpz9szujNwm+q8=
github.com/mochi-mqtt/server/v2 v2.6.5/go.mod h1:TqztjKGO0/ArOjJt9x9idk0kqPT3CVN8Pb+l+PS5Gdo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

8
log/relay.log Normal file
View File

@ -0,0 +1,8 @@
2024/08/22 02:16:04 open : The system cannot find the file specified.
2024/08/22 02:17:00 CreateTLSConfig fail, err= open : The system cannot find the file specified.
2024/08/22 02:17:39 listen tcp :1883: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
2024/08/22 02:18:39 listen tcp 0.0.0.0:1883: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
2024/08/22 02:21:06 listen tcp 0.0.0.0:1883: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
2024/08/22 02:44:59 CreateTLSConfig fail, err= open config/_.tcljd.com.crt: The system cannot find the file specified.
2024/08/22 02:47:05 CreateTLSConfig fail, err= open config/_.tcljd.com.crt: The system cannot find the file specified.
2024/08/22 02:47:08 CreateTLSConfig fail, err= open config/_.tcljd.com.crt: The system cannot find the file specified.

67
main.go Normal file
View File

@ -0,0 +1,67 @@
package main
import (
"os/signal"
"syscall"
//"crypto/x509"
"io/ioutil"
"log"
"os"
"gopkg.in/yaml.v2"
"github.com/ssp97/mqtt_relay/config"
"github.com/ssp97/mqtt_relay/mqtt"
)
// LoadConfig loads configuration from a YAML file
func LoadConfig(filename string) (*config.Config, error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
var cfg config.Config
err = yaml.Unmarshal(data, &cfg)
if err != nil {
return nil, err
}
return &cfg, nil
}
func main() {
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigs
done <- true
}()
// Load configuration
cfg, err := LoadConfig("userdata/config.yml")
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
// Set up logging
logFile, err := os.OpenFile(cfg.LogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatalf("Failed to open log file: %v", err)
}
defer logFile.Close()
log.SetOutput(logFile)
// Create a new MQTT server
server := mqtt.MqttServerStart(cfg)
<-done
server.Log.Warn("caught signal, stopping...")
_ = server.Close()
server.Log.Info("main.go finished")
}

112
mqtt/hook.go Normal file
View File

@ -0,0 +1,112 @@
package mqtt
import (
"bytes"
"fmt"
mqttServerV2 "github.com/mochi-mqtt/server/v2"
"github.com/mochi-mqtt/server/v2/packets"
)
type MqttServerHookOptions struct {
Server *mqttServerV2.Server
}
type MqttServerHook struct {
mqttServerV2.HookBase
config *MqttServerHookOptions
}
func (h *MqttServerHook) ID() string {
return "events-example"
}
func (h *MqttServerHook) Provides(b byte) bool {
return bytes.Contains([]byte{
mqttServerV2.OnConnect,
mqttServerV2.OnDisconnect,
mqttServerV2.OnSubscribed,
mqttServerV2.OnUnsubscribed,
mqttServerV2.OnPublished,
mqttServerV2.OnPublish,
mqttServerV2.OnConnectAuthenticate,
mqttServerV2.OnACLCheck,
}, []byte{b})
}
func (h *MqttServerHook) Init(config any) error {
h.Log.Info("initialised")
if _, ok := config.(*MqttServerHookOptions); !ok && config != nil {
return mqttServerV2.ErrInvalidConfigType
}
h.config = config.(*MqttServerHookOptions)
if h.config.Server == nil {
return mqttServerV2.ErrInvalidConfigType
}
return nil
}
// subscribeCallback handles messages for subscribed topics
func (h *MqttServerHook) subscribeCallback(cl *mqttServerV2.Client, sub packets.Subscription, pk packets.Packet) {
h.Log.Info("hook subscribed message", "client", cl.ID, "topic", pk.TopicName)
}
func (h *MqttServerHook) OnConnect(cl *mqttServerV2.Client, pk packets.Packet) error {
h.Log.Info("client connected", "client", cl.ID)
// Example demonstrating how to subscribe to a topic within the hook.
h.config.Server.Subscribe("hook/direct/publish", 1, h.subscribeCallback)
// Example demonstrating how to publish a message within the hook
err := h.config.Server.Publish("hook/direct/publish", []byte("packet hook message"), false, 0)
if err != nil {
h.Log.Error("hook.publish", "error", err)
}
return nil
}
func (h *MqttServerHook) OnDisconnect(cl *mqttServerV2.Client, err error, expire bool) {
if err != nil {
h.Log.Info("client disconnected", "client", cl.ID, "expire", expire, "error", err)
} else {
h.Log.Info("client disconnected", "client", cl.ID, "expire", expire)
}
}
func (h *MqttServerHook) OnSubscribed(cl *mqttServerV2.Client, pk packets.Packet, reasonCodes []byte) {
h.Log.Info(fmt.Sprintf("subscribed qos=%v", reasonCodes), "client", cl.ID, "filters", pk.Filters)
}
func (h *MqttServerHook) OnUnsubscribed(cl *mqttServerV2.Client, pk packets.Packet) {
h.Log.Info("unsubscribed", "client", cl.ID, "filters", pk.Filters)
}
func (h *MqttServerHook) OnPublish(cl *mqttServerV2.Client, pk packets.Packet) (packets.Packet, error) {
h.Log.Info("received from client", "client", cl.ID, "payload", string(pk.Payload))
pkx := pk
if string(pk.Payload) == "hello" {
pkx.Payload = []byte("hello world")
h.Log.Info("received modified packet from client", "client", cl.ID, "payload", string(pkx.Payload))
}
return pkx, nil
}
func (h *MqttServerHook) OnPublished(cl *mqttServerV2.Client, pk packets.Packet) {
h.Log.Info("published to client", "client", cl.ID, "payload", string(pk.Payload))
}
// OnConnectAuthenticate returns true/allowed for all requests.
func (h *MqttServerHook) OnConnectAuthenticate(cl *mqttServerV2.Client, pk packets.Packet) bool {
h.Log.Info("Auth", pk.Connect.Username, pk.Connect.Password)
return true
}
// OnACLCheck returns true/allowed for all checks.
func (h *MqttServerHook) OnACLCheck(cl *mqttServerV2.Client, topic string, write bool) bool {
return true
}

56
mqtt/server.go Normal file
View File

@ -0,0 +1,56 @@
package mqtt
import (
"crypto/tls"
"fmt"
"log"
mqttServerV2 "github.com/mochi-mqtt/server/v2"
"github.com/mochi-mqtt/server/v2/listeners"
"github.com/ssp97/mqtt_relay/config"
)
func MqttServerStart(cfg *config.Config) *mqttServerV2.Server {
server := mqttServerV2.New(nil)
// _ = server.AddHook(new(auth.AllowHook), nil)
var tlsConfig *tls.Config
var err error
if cfg.Server.EnableTLS {
tlsConfig, err = CreateTLSConfig(cfg.Server.CertFile, cfg.Server.KeyFile)
if err != nil {
log.Fatalf("CreateTLSConfig fail, err= %v\r\n", err)
}
} else {
tlsConfig = nil
}
tcp := listeners.NewTCP(listeners.Config{
ID: "TCP TLS",
Address: fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port),
TLSConfig: tlsConfig,
})
err = server.AddListener(tcp)
if err != nil {
log.Fatal(err)
}
err = server.AddHook(new(MqttServerHook), &MqttServerHookOptions{
Server: server,
})
if err != nil {
log.Fatal(err)
}
go func() {
err := server.Serve()
if err != nil {
log.Fatal(err)
}
}()
return server
}

6
mqtt/session.go Normal file
View File

@ -0,0 +1,6 @@
package mqtt
type Session struct {
Username string
Password string
}

16
mqtt/utils.go Normal file
View File

@ -0,0 +1,16 @@
package mqtt
import "crypto/tls"
// CreateTLSConfig creates a TLS configuration for the server
func CreateTLSConfig(certFile, keyFile string) (*tls.Config, error) {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
return tlsConfig, nil
}

BIN
mqtt_relay.exe Normal file

Binary file not shown.

View File

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEJTCCAw2gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBzDELMAkGA1UEBhMCQ04x
CzAJBgNVBAgTAkdEMQswCQYDVQQHEwJTVDEoMCYGA1UEChMfSG9zaGltaXlhIElu
dGVybmV0IEF1dGhvcml0eSBDQTEoMCYGA1UECxMfSG9zaGltaXlhIEludGVybmV0
IEF1dGhvcml0eSBDQTEoMCYGA1UEAxMfSG9zaGltaXlhIEludGVybmV0IEF1dGhv
cml0eSBDQTElMCMGCSqGSIb3DQEJARYWQURNSU5ASE9TSElNSVlBLlVOS09OVzAe
Fw0xODExMzAxNTM4MDBaFw0yODExMzAxNTM4MDBaMIHMMQswCQYDVQQGEwJDTjEL
MAkGA1UECBMCR0QxCzAJBgNVBAcTAlNUMSgwJgYDVQQKEx9Ib3NoaW1peWEgSW50
ZXJuZXQgQXV0aG9yaXR5IENBMSgwJgYDVQQLEx9Ib3NoaW1peWEgSW50ZXJuZXQg
QXV0aG9yaXR5IENBMSgwJgYDVQQDEx9Ib3NoaW1peWEgSW50ZXJuZXQgQXV0aG9y
aXR5IENBMSUwIwYJKoZIhvcNAQkBFhZBRE1JTkBIT1NISU1JWUEuVU5LT05XMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApVEpdzh84q0vcKYgkHwPIkQN
rHi1tp5fIVVa0hEHmScDYiwVcUul0FPZJ71+V5AmVKvDEYna2R/k1cKe8tAmkshq
e6Day05TEZ1VwSbIjPiLweUR2u7EjDL0UkzLsgfwIz7AeAnRvSum72DC3nGu3hon
1Vo5qbHBDYh2V90FkMNiUrWirMqpoqX/pdoD/RDYiuB6waL/xsW7tgF9Ig4llZKi
2e2KZLiCz8c9FxQejYJKch5YHvROThSo9Dq3Y2kwk017nEHKpafdqgqfyhZBp0MM
t0/rGLUU281ZSvgbPyUNDraJv1Z9WJOtmfCYZKhBhFhIJ6RXFCjK+Kt4x+rCiQID
AQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQApH4g6X7br
jAXagdYbQmxQ/g+RWYUTGQDlKzHf4b36hWfST95WeV+PjywS92BI+cGSbeanjhpf
2U8s3JHAWTudMTMgWyH2ZaZnK6ab/6Sau4ByOY1nZWouWOD/v7yjiDY8oeaZYlKG
y/zK/Dz/yuvwfKHWQKF4BRvRIzcqvL4hzjAJ3lO/7KC928l5y3Dv5Eij7xrSS/Bw
Jxrs1qfSXwfbEh/vgbQL7AvIJQHoWLybCh/BssKeudUvUqHMt3xncorXbQZczHMF
ONWRW7YTgMWEf0L30GNBSX+U27+frxHecCCBf7YT/nQEs2CEHBXY7UwVVHmvF2es
UYKxafIygrNt
-----END CERTIFICATE-----

28
userdata/_.tcljd.com.crt Normal file
View File

@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIIE0DCCA7igAwIBAgIIYB+yBTg2V5owDQYJKoZIhvcNAQELBQAwgcwxCzAJBgNV
BAYTAkNOMQswCQYDVQQIEwJHRDELMAkGA1UEBxMCU1QxKDAmBgNVBAoTH0hvc2hp
bWl5YSBJbnRlcm5ldCBBdXRob3JpdHkgQ0ExKDAmBgNVBAsTH0hvc2hpbWl5YSBJ
bnRlcm5ldCBBdXRob3JpdHkgQ0ExKDAmBgNVBAMTH0hvc2hpbWl5YSBJbnRlcm5l
dCBBdXRob3JpdHkgQ0ExJTAjBgkqhkiG9w0BCQEWFkFETUlOQEhPU0hJTUlZQS5V
TktPTlcwHhcNMjQwODIxMDAwMDAwWhcNMjUwODIwMjM1OTU5WjAWMRQwEgYDVQQD
DAsqLnRjbGpkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMZA
J9HLG4YiFbXs9o/dk1iqCSRPGm3K6iYgl5I11zWv/e6wqWOu8Q8nBhKmejzgvdS9
6CVisRYoJzsCQcudunMYZc/804tX+Pl83pmTJCjd9zwpRzEq7ACSSjm7SMsH1LaX
EFZi78391sGBDJUIbAp1wJk0uWd7nqrzzRCAVDNYORTtqZFJa2pEeN6fSipsUlq1
2G2+m5+rIhBEEggCUypGuwX/Z3OPiRUrs4RzWyuSYIcmAZBaNpqLxvDh3t5UPndd
6w2Q3GeOCW83TtCGdrgJQRkc27N/5QgcVh6t7HzHTO3vN7OcT0fRB3vpzGU+kk5O
+Fldl9PduXfFr8rOB1cCAwEAAaOCAWkwggFlMAwGA1UdEwEB/wQCMAAwHQYDVR0O
BBYEFPhOyaOcSESNSJyUEqEmhEUU/qyGMIHjBgNVHSMEgdswgdihgdKkgc8wgcwx
CzAJBgNVBAYTAkNOMQswCQYDVQQIEwJHRDELMAkGA1UEBxMCU1QxKDAmBgNVBAoT
H0hvc2hpbWl5YSBJbnRlcm5ldCBBdXRob3JpdHkgQ0ExKDAmBgNVBAsTH0hvc2hp
bWl5YSBJbnRlcm5ldCBBdXRob3JpdHkgQ0ExKDAmBgNVBAMTH0hvc2hpbWl5YSBJ
bnRlcm5ldCBBdXRob3JpdHkgQ0ExJTAjBgkqhkiG9w0BCQEWFkFETUlOQEhPU0hJ
TUlZQS5VTktPTleCAQEwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
BwMBBggrBgEFBQcDAjAhBgNVHREEGjAYggsqLnRjbGpkLmNvbYIJdGNsamQuY29t
MA0GCSqGSIb3DQEBCwUAA4IBAQBRjMBhcvjKZK/Og/5FCyHwvu5koqTIBxppP+nr
tzarpyBPdnze0RvKExIc57gOzaXFRhMiJiwsbx68AOAiHb5BoIw09dpgU8UEZbuF
KU9YmRpR5otUf7Vqi5gV1+ki+iwLvURtofGiVqWifpkcESVYj2w6eT/dk33ILwOW
5Otd4Xo531S7Fb0yk8TtUPof3jilWMvexnIGs0goolyjT8+eixWvRkksis9wVukM
2g2aI2IX/D7yngTMCNyYeOaxeulewqkIr9WUKijT9oql1fOFhOe4VfTNDCQLHSpU
W1qThOSjCRqlfL9Dpt4tIgBC1x80bfu/T2hHVUzdaf5jgaWc
-----END CERTIFICATE-----

27
userdata/_.tcljd.com.key Normal file
View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAxkAn0csbhiIVtez2j92TWKoJJE8abcrqJiCXkjXXNa/97rCp
Y67xDycGEqZ6POC91L3oJWKxFignOwJBy526cxhlz/zTi1f4+XzemZMkKN33PClH
MSrsAJJKObtIywfUtpcQVmLvzf3WwYEMlQhsCnXAmTS5Z3ueqvPNEIBUM1g5FO2p
kUlrakR43p9KKmxSWrXYbb6bn6siEEQSCAJTKka7Bf9nc4+JFSuzhHNbK5JghyYB
kFo2movG8OHe3lQ+d13rDZDcZ44JbzdO0IZ2uAlBGRzbs3/lCBxWHq3sfMdM7e83
s5xPR9EHe+nMZT6STk74WV2X0925d8Wvys4HVwIDAQABAoIBAFS6r6oMxd8uaxv9
QiWbe/F9fnm7qx54hlk0PcN56lgiNwOQEl0ttA4XThOjfgPNw6QMZA6yXuAK2jVw
kgE9kKXHLCBXvGvF9f1e/l4hkmc68oMOW0RqxUG7RCjnX8WSO7mr14osL7RYxDOg
fWmml1JjICT6cTEGlvoWR7LBPftQ/Ah2fjQVGBaeJVuwVIvM2T4mZLGJjB5mhN+d
kGM+BLk0ygJBRhf/gi9kDsnRApu7KvSKm3yoSChoNEO3/y+A1NRUMWYy7EJAjjux
3dK0dPbHfbR+r2KrrGe9Yd4txlq8OSrWXMhOFTavWuKPfbJT3eCIFqthmlGERi3V
YzI/5RkCgYEA/GYXwPsieogpbtHqHcYGSHlkqfyoWLVSQFOvrQD529CGUynAUVf3
9bDnF/Yaperf0z69WCHgSEiqe30xf9zqThfMkiHcgmmI1rVMuQ+zrpvTTJ3gSuUi
IrMOf9yOPPAwBZAVnaNo4tPeo4sH3qI5M3cCoe9fJU9zIJHdSAilEjkCgYEAyRRI
NXSszzSzD6Bb1ttI8RkDd63jEXTDUiUwdw/eFLZYqbY9oURoyHjC/ZTBXQ1HfLE5
Facpxbun3Q7drFZFkHM6KBQvpIVTsxwvo+ahyVZbuaYfDx1ClNOBKCZjS/ncTsPC
DViX8nP4FEnrKYFmyg0gibq+6kGQE94xejXZpg8CgYEArYxpkulbqNNNYgT2rOhH
07eczwGKpAxxdQfWCOhd5ZZ5dl+D/Kq3NfogvKodYq6gnrlKKnqIpEtK5kSML7Yw
aegVYvnjjMySKchZ6/nu/AXrgYgg/H6XPTLPqn12VFJ3QqvzIQSGj0lNkjh7/cqf
+FJBviVAz//UUrXZaLmA/4kCgYAiKtAaRTkX/Fxwy07Ps3MxhI6SR3nN/Yky7B7Q
HGIgItvt+ol+XaFwbxSzAhPZO+hpx7NrenwenURoy53fKsmnQe0f4k42JnGSfbea
ohXboFD1usSMTOyDXW0U5XD59/r3Z0wR+HvZNttwlx7ebp6ItrJQtOq742gX+Clw
GrZhAQKBgBOezHDmdwcLFXwBeMSbFP6E/Sg9HKoKK3opURQ34Lb8880WR2SWMCq9
vfkiybdx9xJ8J6sb4dOTjYoE8ixYYsxPzxYcJOuvjdI+K+3Qgzf8eQtblYdn9uSC
/87Qf8KXWfUa6GK7DvgfqogHPEFO0Pwa2xK5u6JypCZ9oukPgpzE
-----END RSA PRIVATE KEY-----

13
userdata/config.yml Normal file
View File

@ -0,0 +1,13 @@
server:
host: "0.0.0.0"
enable_tls: true
port: 1883
cert_file: "userdata/_.tcljd.com.crt"
key_file: "userdata/_.tcljd.com.key"
relay:
broker: "tcp://39.108.92.71:1883"
enable_tls: true
log_file: "log/relay.log"