-
Notifications
You must be signed in to change notification settings - Fork 428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: Secure channel does not automatically reestablish after its lifetime expires. #1732
Comments
Hi @splatch, Thanks a lot for your help—I really appreciate it. I suspected the issue might be the same, so I'm using the 0.13-SNAPSHOT version for everything, but still didn't make any difference. <dependency>
<groupId>org.apache.plc4x</groupId>
<artifactId>plc4j-api</artifactId>
<version>0.13.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.plc4x</groupId>
<artifactId>plc4j-driver-opcua</artifactId>
<version>0.13.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.plc4x</groupId>
<artifactId>plc4j-transport-tcp</artifactId>
<version>0.13.0-SNAPSHOT</version>
</dependency> I have a few other ideas that might be causing the problem, so I’ll share all the information I’ve gathered:
As mentioned earlier, I tried adding
import org.apache.plc4x.java.DefaultPlcDriverManager;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcReadResponse;
import java.util.concurrent.TimeUnit;
public class App {
public static void main(String[] args) {
DefaultPlcDriverManager driverManager = new DefaultPlcDriverManager();
String username = "admin";
String password = "admin";
String securityPolicy = "Basic256Sha256";
String keyStoreFile = "/home/digilab/help/test2/demo_2/test/client/client_cert.p12";
String serverCertificate = "/home/digilab/help/test2/demo_2/test/SimulationServer@Yoshi_2048.der";
String keyStorePassword = "gustavo";
String messageSecurity = "SIGN_ENCRYPT";
String connectionString = String.format(
"opcua:tcp://Yoshi.lab.mtu-digilab.io:53530/OPCUA/SimulationServer?discovery=false"
);
connectionString += !username.isBlank() ? String.format("&username=%s", username) : "";
connectionString += !password.isBlank() ? String.format("&password=%s", password) : "";
connectionString += !securityPolicy.isBlank() ? String.format("&security-policy=%s", securityPolicy) : "";
connectionString += !messageSecurity.isBlank() ? String.format("&message-security=%s", messageSecurity) : "";
connectionString += !serverCertificate.isBlank() ? String.format("&server-certificate-file=%s", serverCertificate) : "";
connectionString += !keyStoreFile.isBlank() ? String.format("&key-store-file=%s", keyStoreFile) : "";
connectionString += !keyStorePassword.isBlank() ? String.format("&key-store-password=%s", keyStorePassword) : "";
connectionString += String.format("&tcp.keep-alive=%b", true);
connectionString += String.format("&channel-lifetime=%d", 50000);
System.out.println("Connection String: " + connectionString);
try (PlcConnection plcConnection = driverManager.getConnection(connectionString)) {
System.out.println("Connected to the server");
System.out.println("Connection metadata: " + plcConnection.getMetadata());
while (true) {
PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
System.out.println("Builder: " + builder);
System.out.println("Builder: " + builder.getClass());
System.out.println("Builder: " + plcConnection);
builder.addTagAddress("constant", "ns=3;i=1002");
PlcReadRequest readRequest = builder.build();
PlcReadResponse response = readRequest.execute().get(5000, TimeUnit.MILLISECONDS);
for (String tagName : response.getTagNames()) {
System.out.println("Value[" + tagName + "]: " + response.getObject(tagName));
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
System.out.println("" + e);
}
}
}
but we can see when it enters the stall mode in here:
That's all. Thank again for your support! I hope we can find a solution together Best, |
Hello Gustavo, |
Hi @splatch, Which security policy you're currently using? If you have any suggestions, I could try them out to help identify the issue. Best, |
I usually test basic128, however you can give a spin to mix of security modes and see if security mode=none and message security=none makes any difference. There are some aspects of nonce management which might be softened by server if you use anonymous authentication with no security. |
Hi @splatch, It is interesting because when I set both Which Prosys version are you using? If my code is correct, I suspect it could be something related to the simulator. Here’s what I did: String messageSecurity = "NONE";
String securityPolicy = "NONE";
String connectionString = String.format("opcua:tcp://Yoshi.lab.mtu-digilab.io:53530/OPCUA/SimulationServer?discovery=false");
connectionString += (securityPolicy.isBlank()) ? "" : String.format("&security-policy=%s", securityPolicy);
connectionString += (messageSecurity.isBlank()) ? "" : String.format("&message-security=%s", messageSecurity);
connectionString += String.format("&channel-lifetime=%d", 20000); |
I'm on v5.4.6-148. Anyhow, will try to test to see what's going on. If session dies around lifetime its definitely related to the token renewal. |
Hi @splatch, I'm also using the same version of Prosys. I also just tried connecting PLC4x to a Python OPC UA server with no security, and it worked well without any channel lifetime issues, even with a channel lifetime set to 10 seconds. I'm curious about how your setup with Prosys is configured. Are you using any security settings? And are you using a short channel lifetime to test the token renewal? Thanks so much for your assistance! |
Hi @splatch, I used Wireshark to intercept the communication between the Client and Server and identified an issue. I may be forgetting to configure something properly. Here's the relevant log:
From the first log, it appears that the communication occurs normally until the final message, where a new channel is attempted, but the process encounters a This issue seems similar to #1213. I had already taken that into consideration and used the Can you identify and issue or a potential solution? Thanks for your help! Best regards, |
The tcp keep alive won't help in this case, transport level communication is fine, so all packets are flying both directions. Issue comes from application protocol and some gap in our implementation of security protocol. Below quote from the the spec:
This means that for initial (issue) call, we send |
Hi @splatch, Exactly, that is the issue. In frame 1539, we can see that the SecureChannel ID is 5. However, when the client tries to renew the SecureChannel in frame 1625, it uses 0 as the SecureChannel ID instead of 5. As I understood, it should be only zero when issuing a new SecureChannel, and that's not the case here. Is there a way to fix this? Thanks for all you support in this! |
You need to have a look inside |
Hi @splatch, It turns out the issue was related to the version of PLC4x. It’s strange because it seemed like the system was caching the old version instead of using the new one, even though the dependency tree showed the correct version. Here’s what I did to resolve the problem:
Thanks so much for all your help! |
@gustavoschewinski You're welcome, glad you got it covered. Tooling we use sometimes make things harder. Enjoy OPC-UA! :-) |
What happened?
I'm experiencing an issue where a secure channel is not reestablished after reaching channel lifetime limit while using PLC4Xj with certificates for both the client and server. The initial connection works perfectly, with a secure channel being established and data being received via OPC UA. However, once the channel's lifetime expires, it closes and is not automatically reestablished.
I've read that simply increasing the channel lifetime indefinitely is not a viable solution. I also attempted to use
tcp.keep-alive=true
, but this did not resolve the issue.Is there a solution or configuration that I might be overlooking to address this problem?
Additional Information:
Here is the connection string I'm using:
Maybe it is related to #1684?
Is there a configuration setting or a different approach that can help with automatically reestablishing the secure channel once it closes?
Thanks!
Best,
Gustavo.
Version
v.0.12.0
Programming Languages
Protocols
The text was updated successfully, but these errors were encountered: