High Performance OPC UA Server SDK
1.5.2.321
|
This section describes how to configure user authentication in the UA Server.
OPC UA currently supports four different ways to authenticate a user during the ActivateSession service call:
This actually performs no authentication at all. Every user which uses an application which is allowed to connect, either because the client is trusted, or because the server also allows to use SecurityPolicy None (no application authentication), is able to connect.
It is recommended to disable this kind of authentication for security reasons.
Also, note, that simply relying on application authentication is not an appropriate solution, because
This allows to authenticate the user using an username and password. The password gets encrypted, even when using a none secure channel, because the UserToken itself get individually encrypted. Technically OPC UA allows transmitting passwords also in clear text, but this option SHALL not be used.
Using the password a server can authenticate users using existing APIs like e.g. Windows LoginUser
or Linux PAM. The High Performance SDK supports to replace the authentication backend with own implementations. By default, it uses its "internal" implementation which is a portable solution using plain text configuration files, which store the passwords as cryptographic hash.
This allows authenticating users using X509 certificates. It is especially useful to integrate smart cards for user authentication, to increase the security level. This requires smart cart support in client side to access the private key information. It is also possible to use file based private keys, but this is not recommended.
On server side there is no difference in using smart cards or file based private keys. The server only needs the X509 certificate, which is transmitted during the ActivateSession call. Using the public key in the certificate the server can verify the cryptographic signature, which proves that the client is in possession of the private key which belongs to the given certificate.
The authentication process consists of the following steps:
This allows delegating user authentication to an external OAuth2 server. This is currently not support by the SDK.
The SDK provides example files for users, groups and passwords to use with the DemoServer and ServerExamples. When making a product do not use these files but create your own.
Adding a user to the configuration can be done by simply adding new entries into the users
file in the server's bin
directory. This file contains a mapping from the internally used numeric user ID (UID) and the username. The UID must be unique. Simply increment this number of each entry.
Example:
# <userid>:<username> 0:anonymous 1:root 2:joe 3:john 4:sue
The user anonymous has a special meaning and is used to map clients authenticating with an AnonymousIdentityToken. To disable anonymous clients, do not add that entry to the users file. For compile time deactivation of anonymous clients, disable the CMake option UA_AUTHENTICATION_SUPPORT_ANONYMOUS.
The next step is to assign this user to groups it needs permissions to. Therefor you edit the file groups
. This file contains a mapping from the group ID (GID) to a group name in the same way as the users
file for users. In addition, there is a third column with a comma separated list of users which belong to this group.
Example:
# <groupid>:<groupname>:<username1>,<username2> 0:operators:root,joe 1:users:john,sue
The passwords are stored in the file unreadable as hashes with salt, however it is still possible to start brute-force attacks against these hashes to retrieve the passwords. Therefore the password file should only be readable by the server process and no other user.
The passwords for each user are configured in the file passwd
. It is possible to add plaintext passwords here, but this is not recommended. Instead, you can use the tool uapasswd
to add cryptographically hashed and salted password here.
./uapasswd -u john Changing password for user 'john'. New password: Retype new password: Successfully wrote file 'passwd'
See UA Password Manager for more information on this tool.
To make X509 user authentication working you need to create a second PKI store, so that the user certificates are independent of the application instance certificates.
This example contains two stores. The first for application instance certificates, the second for user certificates.
[pkistore] pkistores/size = 2 pkistores/0/config = "pki_store_0;50;50;50;50" pkistores/0/import_dir = "import" pkistores/1/config = "pki_store_user;50;50;50;50" pkistores/1/import_dir = "import_user"
The import_dir
parameter defines a folder, where you can place certificates which should be imported into the store when starting the server. Because there are two stores, you need to use also two different import folder.
To trust self-signed certificate you need to save it in the import_user
folder as DER encoded certificate with .der
file extension. When starting the server this gets imported and stored under pki_store_user/trusted/certs
using its thumbprint as filename.
You can also programmatically trust certificates by using the function pki_store_save_cert to import the certificate.
To trust CA-signed certificates you need to import the CA certificate. This way all certificates issued but this CA will be trusted as well. To import the CA certificate you need to store the CA certificate in the import_user
folder as DER encoded with the file extension .der
. An addition you need to store also the CA's certificate revocation list in this folder. This file also needs to be DER encoded with the file extension .crl
.
Example:
rootCA.der (DER encoded certificate) rootCA.crl (DER encoded CRL)
These files get stored in pki_store_user/trusted/certs
and pki_store_user/trusted/crl
using the certificate thumbprint as filename. The CRL needs to be updated on a regular basis, so that revoked certificates are not allowed to connect anymore.
You can also programmatically trust certificates by using the function pki_store_save_cert and pki_store_save_crl to import the certificate and CRL. Note, that CA certificates should always have a CRL, so that it is possible to revoke certificates. The CRL needs to be updated regularly.
A user certificate is a regular X509v3 certificate, where the Common Name
field is mapped to a username. This means you need to create the user
and group
settings in the same way as for password authentication, which is described above in Configuring Users. But instead of a password the user can use his private key to authenticate himself.
The following example shows how to create a self-signed user certificate using OpenSSL command line tool:
$> openssl req -x509 -newkey rsa:4096 -keyout john_key.pem -out john.pem -days 365 Generating a RSA private key ......................................................................................................................................................++++ .....................................................................++++ writing new private key to 'john_key.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:john Email Address []:john@internet.com $> openssl x509 -in john.pem -outform der -out john.der $> ls -l john* -rw-r--r-- 1 john john 1478 Jun 19 15:56 john.der -rw------- 1 john john 3414 Jun 19 15:56 john_key.pem -rw------- 1 john john 2057 Jun 19 15:56 john.pem
The first command creates the files john_key.pem
, which contains a password protected private key, and john.pem
which contains John's certificate. The second command converts the PEM encoded certificate into a DER encoded certificate (john.der
), which is required for OPC UA. Important is the question regarding the Common Name
. This name is later on mapped to the username in the server.
Creating CA signed user certificates is normally handled by the IT department of the company running the OPC UA infrastructure. For testing purpose you can also create your own local CA and issue certificates yourself. The SDK includes some example scripts for testing this feature in the folder bin/CA
. These scripts require GNU Bash and the OpenSSL command line tool. This is available on Linux by default, on Windows you can use the WSL (Windows Subsytem for Linux), Git Bash or Cygwin Bash. See bin/CA/README.md
for detailed instructions on how to use those scripts. For more information on the OpenSSL tools please consult the documentation at https://www.openssl.org/docs/.
For testing this feature you can use UaExpert, which supports password authentication as well as X509 user certificate authentication. See http://documentation.unified-automation.com/uaexpert/1.5.1/html/connect.html#connect_authentication for a step by step guide. Simply select the option "Certificate" instead of "Password" and configure the path to the user certificate file (john.der
) and key file (john_key.pem
). If the key file is password protected, UaExpert will ask you for that password when loading the key.
The server settings.conf
allows configuring multiple user token types. In this example we configured UserNameIdentityToken and X509IdentityToken, but removed the AnonymousIdentityToken.
user_tokens/size = 2 user_tokens/0/name = Username_256_Token user_tokens/0/type = Username user_tokens/0/policy_id = http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256 user_tokens/1/name = X509_Token user_tokens/1/type = Certificate user_tokens/1/policy_id = http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256
Then in every configured endpoint you can select what user tokens are accepted for this endpoint. You select the token by its index. In this example both token types are allowed.
endpoints/size = 1 endpoints/0/endpoint_url = opc.tcp://[hostname]:4840 endpoints/0/bind_address = 0.0.0.0 endpoints/0/bind_port = 4840 endpoints/0/security_policies = 0,1,2 endpoints/0/user_tokens = 0,1
In the section [session]
you can select password file to use for password based user authentication and the PKI store to use for X509 based user authentication.
# location of file to load users and passwords for authentication authentication_passwd_file = passwd # PKI store index for X509 user authentication authentication_store = 1