93 lines
2.5 KiB
Go
93 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/simonvetter/modbus"
|
|
)
|
|
|
|
/*
|
|
* Modbus client with TLS example.
|
|
*
|
|
* This file is intended to be a demo of the modbus client in TCP+TLS
|
|
* mode. It shows how to load certificates from files and how to
|
|
* configure the client to use them.
|
|
*/
|
|
|
|
func main() {
|
|
var client *modbus.ModbusClient
|
|
var err error
|
|
var clientKeyPair tls.Certificate
|
|
var serverCertPool *x509.CertPool
|
|
var regs []uint16
|
|
|
|
// load the client certificate and its associated private key, which
|
|
// are used to authenticate the client to the server
|
|
clientKeyPair, err = tls.LoadX509KeyPair(
|
|
"certs/client.cert.pem", "certs/client.key.pem")
|
|
if err != nil {
|
|
fmt.Printf("failed to load client key pair: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// load either the server certificate or the certificate of the CA
|
|
// (Certificate Authority) which signed the server certificate
|
|
serverCertPool, err = modbus.LoadCertPool("certs/server.cert.pem")
|
|
if err != nil {
|
|
fmt.Printf("failed to load server certificate/CA: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// create a client targetting host secure-plc on port 802 using
|
|
// modbus TCP over TLS (MBAPS)
|
|
client, err = modbus.NewClient(&modbus.ClientConfiguration{
|
|
// tcp+tls is the moniker for MBAPS (modbus/tcp encapsulated in
|
|
// TLS),
|
|
// 802/tcp is the IANA-registered port for MBAPS.
|
|
URL: "tcp+tls://secure-plc:802",
|
|
// set the client-side cert and key
|
|
TLSClientCert: &clientKeyPair,
|
|
// set the server/CA certificate
|
|
TLSRootCAs: serverCertPool,
|
|
})
|
|
if err != nil {
|
|
fmt.Printf("failed to create modbus client: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// now that the client is created and configured, attempt to connect
|
|
err = client.Open()
|
|
if err != nil {
|
|
fmt.Printf("failed to connect: %v\n", err)
|
|
os.Exit(2)
|
|
}
|
|
|
|
// read two 16-bit holding registers at address 0x4000
|
|
regs, err = client.ReadRegisters(0x4000, 2, modbus.HOLDING_REGISTER)
|
|
if err != nil {
|
|
fmt.Printf("failed to read registers 0x4000 and 0x4001: %v\n", err)
|
|
} else {
|
|
fmt.Printf("register 0x4000: 0x%04x\n", regs[0])
|
|
fmt.Printf("register 0x4001: 0x%04x\n", regs[1])
|
|
}
|
|
|
|
// set register 0x4002 to 500
|
|
err = client.WriteRegister(0x4002, 500)
|
|
if err != nil {
|
|
fmt.Printf("failed to write to register 0x4002: %v\n", err)
|
|
} else {
|
|
fmt.Printf("set register 0x4002 to 500\n")
|
|
}
|
|
|
|
// close the connection
|
|
err = client.Close()
|
|
if err != nil {
|
|
fmt.Printf("failed to close connection: %v\n", err)
|
|
}
|
|
|
|
os.Exit(0)
|
|
}
|