Golang connection error

Hi everyone,

If someone could point me in the right direction that would be amazing. I am trying to build a small Golang OPC client to connect to Ignition's OPC UA server.

For reference, I am using Golang 1.22.5 and Ignition 8.1.44 and I am running a trial license. My server settings are set below :

And I have restarted the OPC UA module, as other posts have stated it is required.

Lastly I am using the GoLang Library GitHub - gopcua/opcua: Native Go OPC-UA library link here -> GitHub - gopcua/opcua: Native Go OPC-UA library

My Golang code looks like this, and I have tried several variations of it, all with no success. I don't believe a certificate is needed, for no security policy connections, but I have tried with certificates, and without. Currently using this code I get a StatusBadIdentityTokenInvalid.

package main

import (
    "context"
    "log"

    "github.com/gopcua/opcua"
    "github.com/gopcua/opcua/ua"
)

func main() {
    endpoint := "opc.tcp://localhost:62541" // opc.tcp://localhost:62541/discovery was attempted too 
    c, _ := opcua.NewClient(
        endpoint,
        opcua.SecurityPolicy(ua.SecurityPolicyURINone),
        opcua.SecurityMode(ua.MessageSecurityModeNone),
        opcua.AuthUsername("opcuauser", "password"), // defaults 
    )
    if err := c.Connect(context.Background()); err != nil {
        log.Fatalf("Failed to connect: %v", err)
    }
    defer c.Close(context.Background())

    log.Println("Connected to OPC UA server!")
}

Thank you in advance for any help!

Maybe a Wireshark capture would help.

Does it work without a username/password?

You actually do need certificates if you're going to authenticate via username/password, even if the secure channel will not use security.

YES! thank you so much,

Well, I figured it would be something very simple. Completely removing the line allows for connection. I was attempting to use this configuration if I didn't use the password. (I set settings to allow anonymous connection). But I'm guessing that it was sending extra data, instead of just not sending a user.

    c, _ := opcua.NewClient(
        endpoint,
        opcua.SecurityPolicy(ua.SecurityPolicyURINone),
        opcua.SecurityMode(ua.MessageSecurityModeNone),
        opcua.AuthAnonymous(), 
    )
}

Okay,
this is good to know, is there a specific format for the Ignition certificates needed. When I went down the route of adding them, I was using OpenSSL to create them, and I believe the Golang library requires x509 and PKCS1 certificates. (Forgive me, certs are not my strong suite) When all that was configured it stated there was no thumbprint for the certificate I had sent. Though the certificate I had uploaded and the one I was sending had the same fingerprint (SHA-1).

Would a Wireshark capture maybe give more insight on this?

The certificate representing your client you would import into Ignition to mark it "trusted" would be a DER-encoded X509 certificate. You don't really even have to worry about this because once your client has tried to connect once, assuming it gets far enough, the certificate would show up in the quarantine section and you could mark it trusted there.

I don't know anything about the library you're using or how to configure it to use security or generate certificates for it though.

Kevin, thank you so much for the quick responses. It means a lot.

This is more than enough information to get me moving.

DER-encoded X509 certificate

If I get a working configuration I will post the answer here for anyone interested. The library appears to be mildly maintained, but the certificate portion feels outdated.

1 Like