使用 Open62541 在 OPCUA 中初始化安全服务器

问题描述 投票:0回答:1

我正在尝试使用 ACS 和 AES256 证书创建一个最小的服务器。

代码和证书

我已经使用 OpenSSL 构建了证书。

步骤 命令 结果
服务器私钥 openssl genpkey -算法 RSA -out opcua_server.key -aes256 加密密钥
服务器签名请求 openssl req -new -key opcua_server.key -out request.csr 企业社会责任要求
带有 URI 的服务器证书 openssl req -new -keycrypted_opcua_server.key -x509 -days 365 -outcertificate.pem -subj“/C=IT/ST=Campania/L=Roma/O=Senatus Romanum/CN=Opcua Legionis”-addext“subjectAltName =URI:urn:OPCUASecureServerTest" PEM证书
解封至 DER openssl x509 -in 证书.pem -outform der -out 证书.der DER证书
证书数据展示 openssl x509 -in certificate.der -inform der -text -noout

然后我尝试设置服务器。

公用事业

UA_StatusCode myInsecurePasswordCallback(UA_ServerConfig *sc,
                                                UA_ByteString *bytestringPassword) {
    char* sec = (char*)"insecure_password";
    *bytestringPassword = UA_STRING_ALLOC(sec);
    return UA_STATUSCODE_GOOD;
}

void printApplicationUriFromLoadedCertificate(UA_ServerConfig *config) {
    UA_Boolean none = false;
    printf("Verifying certificates on endpoints...\n");
    // Loop through the existing security policies and print certificate info
    for(size_t i = 0; i < config->securityPoliciesSize; i++) {
        UA_EndpointDescription *endpoint = &config->endpoints[0];
        UA_ByteString *certificate = &endpoint->serverCertificate;
        printf("*");
        if(certificate->length > 0) {
            printf("\nLoaded Certificate Application URI: %.*s\n", (int)certificate->length, certificate->data);
            none = true;
        }
    }
    if (!none) printf("\nNo certificate loaded.\n");
}

// Custom permissions and roles functions
UA_UInt32 custom_getUserPermissions(const UA_AccessControl *ac, void *sessionContext, const UA_NodeId *nodeId, UA_UInt32 permissions) {
    return permissions;
}

static UA_Boolean
allowAddNode(UA_Server *server, UA_AccessControl *ac,
             const UA_NodeId *sessionId, void *sessionContext,
             const UA_AddNodesItem *item) {
    printf("Called allowAddNode\n");
    return UA_TRUE;
}

static UA_Boolean
allowAddReference(UA_Server *server, UA_AccessControl *ac,
                  const UA_NodeId *sessionId, void *sessionContext,
                  const UA_AddReferencesItem *item) {
    printf("Called allowAddReference\n");
    return UA_TRUE;
}

static UA_Boolean
allowDeleteNode(UA_Server *server, UA_AccessControl *ac,
                const UA_NodeId *sessionId, void *sessionContext,
                const UA_DeleteNodesItem *item) {
    printf("Called allowDeleteNode\n");
    return UA_FALSE; // Do not allow deletion from client
}

static UA_Boolean
allowDeleteReference(UA_Server *server, UA_AccessControl *ac,
                     const UA_NodeId *sessionId, void *sessionContext,
                     const UA_DeleteReferencesItem *item) {
    printf("Called allowDeleteReference\n");
    return UA_TRUE;
}

static UA_UsernamePasswordLogin userNamePW[2] = {
    {UA_STRING_STATIC("station-client"), UA_STRING_STATIC("operator1")},
    {UA_STRING_STATIC("admin-client"), UA_STRING_STATIC("superSecurePassword1!")}
};

服务器

int main() {
    signal(SIGINT, stopHandler);
    signal(SIGTERM, stopHandler);

    UA_String applicationUri =  UA_String_fromChars("urn:open62541.OPCUASecureServerTest");

    // Hardcoded paths to the certificate and private key files
    const char* certificatePath =  "./modules/opcua/src/.server_security/certificate.der";
    const char* privateKeyPath =  "./modules/opcua/src/.server_security/privatekey.der";

    // Load server certificates
    const UA_ByteString certificate = loadFile(certificatePath);
    const UA_ByteString privateKey = loadFile(privateKeyPath);

    // Create the server
    UA_Server *server = UA_Server_new();
    UA_ServerConfig *config = UA_Server_getConfig(server);
    
    // Output the Application URI for debugging
    std::cout << "############\n## " << "Application URI: " << std::string((char*)config->applicationDescription.applicationUri.data, applicationUri.length) << "\n############\n" << std::endl;
    UA_StatusCode retval;
    UA_UInt16 portNumber = 4840;
    UA_ByteString trustList[] = { certificate };
    size_t trustListSize = sizeof(trustList) / sizeof(UA_ByteString);
    const UA_ByteString *issuerList = {};
    size_t issuerListSize = 0;
    const UA_ByteString *revocationList = {};
    size_t revocationListSize = 0;

    /// option to start the server without None auth enabled.
    retval = UA_ServerConfig_setDefaultWithSecureSecurityPolicies(
      config, portNumber, 
      &certificate, &privateKey,
      trustList, trustListSize,
      issuerList, issuerListSize, 
      revocationList, revocationListSize);
    config->privateKeyPasswordCallback = myInsecurePasswordCallback;
    config->applicationDescription.applicationUri = applicationUri;
    config->applicationDescription.applicationName = UA_LOCALIZEDTEXT_ALLOC("en-US", "Secure Monkey Server");
    /* Override accessControl functions for nodeManagement */
    config->accessControl.allowAddNode = allowAddNode;
    config->accessControl.allowAddReference = allowAddReference;
    config->accessControl.allowDeleteNode = allowDeleteNode;
    config->accessControl.allowDeleteReference = allowDeleteReference;
    UA_ServerConfig_addSecurityPolicyBasic256Sha256(config, &certificate, &privateKey);

    // Output the Application URI for debugging
    std::cout << "Application URI: " << std::string((char*)config->applicationDescription.applicationUri.data, applicationUri.length) << std::endl;

    // Print the Application URI from the certificate after it has been loaded
    printApplicationUriFromLoadedCertificate(config);

    // [AUDITING](https://reference.opcfoundation.org/Core/Part4/v104/docs/6.5)
    if(retval != UA_STATUSCODE_GOOD)
        goto cleanup;

    if(!running)
        goto cleanup; // received ctrl-c already

    retval = UA_Server_run(server, &running);

 cleanup:
    UA_ByteString_clear((UA_ByteString*)&certificate);
    UA_ByteString_clear((UA_ByteString*)&privateKey);

    UA_Server_delete(server);
    return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

输出

为了便于阅读,我对此进行了稍微编辑。

[2024-09-27 10:05:45.864 (UTC+0200)] warn/server         AccessControl: Unconfigured AccessControl. Users have all permissions.

[2024-09-27 10:05:45.865 (UTC+0200)] info/server

AccessControl: Anonymous login is enabled 

[2024-09-27 10:05:45.866 (UTC+0200)] warn/server      x509 Certificate Authentication configured, but no encrypting SecurityPolicy. This can leak credentials on the network.

############
## Application URI: urn:open62541.server.application²²²
############

[2024-09-27 10:05:46.043 (UTC+0200)] warn/userland      ServerUrls already set. Overriding. 

[2024-09-27 10:05:46.047 (UTC+0200)] warn/server        AccessControl: Unconfigured AccessControl. Users have all permissions.     

[2024-09-27 10:05:46.047 (UTC+0200)] warn/server        x509 Certificate Authentication configured, but no encrypting SecurityPolicy. This can leak credentials on the network.


Application URI: urn:open62541.OPCUASecureServerTest Verifying certificates on endpoints...

***** No certificate loaded. 

[2024-09-27 10:05:46.048 (UTC+0200)] warn/server        The certificate's application URI could not be verified. StatusCode BadCertificateUriInvalid 

[2024-09-27 10:05:46.048 (UTC+0200)] warn/server        The certificate's application URI could not be verified. StatusCode BadCertificateUriInvalid 

[2024-09-27 10:05:46.048 (UTC+0200)] warn/server        The certificate's application URI could not be verified. StatusCode BadCertificateUtificateUriInvalid 

[2024-09-27 10:05:46.048 (UTC+0200)] warn/server        The certificate's application URI could not be verified. StatusCode BadCertificateUriInvalid

问题

1-我是否假设我应该从一个新服务器开始,使用

UA_Server_new
然后使用
UA_ServerConfig_setDefaultWithSecureSecurityPolicies
方法使用默认安全策略设置它,然后依赖
UA_ServerConfig_addSecurityPolicyBasic256Sha256
来设置证书,非常不正确?许多警告似乎表明我做错了什么。

2- 为什么我的证书不起作用?我是在创建步骤、导入状态还是两者都失败了?

3- 我的 ACS 正确吗?我使用项目 example 作为来源。

c++ opc-ua open62541
1个回答
0
投票

我不确定您问题的其他部分,但您当然还需要 subjectAltName 中服务器的主机名或 IP 地址。请参阅 https://reference.opcfoundation.org/Core/Part6/v104/docs/6.2.2 .

© www.soinside.com 2019 - 2024. All rights reserved.