Я подключаюсь от клиента Eclipse Milo к серверу Eclipse Milo. Все работает нормально, но как только я пытаюсь подключиться к любой SecurityPolicy, кроме «None», я получаю следующую ошибку:
17:28:18.365 [main] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - connect(), currentState=NotConnected
17:28:18.365 [main] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - connect() while NotConnected
java.lang.Exception: null
at org.eclipse.milo.opcua.stack.client.ClientChannelManager.connect(ClientChannelManager.java:67) [stack-client-0.2.3.jar:0.2.3]
at org.eclipse.milo.opcua.stack.client.UaTcpStackClient.connect(UaTcpStackClient.java:127) [stack-client-0.2.3.jar:0.2.3]
at org.eclipse.milo.opcua.sdk.client.OpcUaClient.connect(OpcUaClient.java:312) [sdk-client-0.2.3.jar:0.2.3]
at de.dlh.lht.ticc.esa.opcua.client.lib.LhtOpcUaClient.connect(LhtOpcUaClient.java:86) [classes/:?]
at de.dlh.lht.ticc.esa.opcua.client.lib.TestTools.runWithCredentials(TestTools.java:41) [test-classes/:?]
at de.dlh.lht.ticc.esa.opcua.client.lib.ConnectAgainstMiloServerTest.credentialsTest(ConnectAgainstMiloServerTest.java:48) [test-classes/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_101]
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) [junit-4.12.jar:4.12]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) [junit-4.12.jar:4.12]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) [junit-4.12.jar:4.12]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) [junit-4.12.jar:4.12]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12]
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) [junit-rt.jar:?]
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) [junit-rt.jar:?]
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) [junit-rt.jar:?]
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) [junit-rt.jar:?]
17:28:18.367 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - Channel bootstrap failed: null
java.nio.channels.ClosedChannelException: null
de.dlh.lht.ticc.esa.opcua.client.lib.exceptions.ClientExecutionException: java.util.concurrent.ExecutionException: java.nio.channels.ClosedChannelException
at de.dlh.lht.ticc.esa.opcua.client.lib.LhtOpcUaClient.connect(LhtOpcUaClient.java:88)
at de.dlh.lht.ticc.esa.opcua.client.lib.TestTools.runWithCredentials(TestTools.java:41)
at de.dlh.lht.ticc.esa.opcua.client.lib.ConnectAgainstMiloServerTest.credentialsTest(ConnectAgainstMiloServerTest.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.util.concurrent.ExecutionException: java.nio.channels.ClosedChannelException
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
at de.dlh.lht.ticc.esa.opcua.client.lib.LhtOpcUaClient.connect(LhtOpcUaClient.java:86)
... 24 more
Caused by: java.nio.channels.ClosedChannelException
Любая идея?
Это происходит, когда я использую сертификат с закрытым ключом, а также с учетными данными имени пользователя и пароля. Журналы на стороне сервера
DEBUG o.e.m.o.s.s.h.UaTcpServerAsymmetricHandler - Received CloseSecureChannelRequest
поэтому я думаю, что проблема здесь в клиенте. Та же проблема возникает и с другими серверами opc-ua.
Обновлено: Я создал минимальный пример, в котором возникает ошибка
package de.dlh.lht.ticc.esa.opcua.client.lib;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder;
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
import org.eclipse.milo.opcua.stack.client.UaTcpStackClient;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
public class SmokeTest {
private static final Logger log = LoggerFactory.getLogger(SmokeTest.class);
private static EndpointDescription getEndpointDescriptions(String endpoint, SecurityPolicy securityPolicy) throws Exception {
EndpointDescription[] endpoints;
try {
endpoints = UaTcpStackClient
.getEndpoints(endpoint)
.get();
} catch (Exception ex) {
log.warn("failed to get endpoints", ex);
log.warn("will try to explicitly discover endpoints");
String discoveryUrl = endpoint + "/discovery";
log.info("Trying explicit discovery URL: {}", discoveryUrl);
endpoints = UaTcpStackClient
.getEndpoints(discoveryUrl)
.get();
}
EndpointDescription endpointDescription = Arrays.stream(endpoints)
.filter(e -> e.getSecurityPolicyUri().equals(securityPolicy.getSecurityPolicyUri()))
.findFirst().orElseThrow(() -> new Exception("no valid endpoint found for '" + endpoint + "'"));
return endpointDescription;
}
@Test
public void runTest() throws Exception {
OpcUaClientConfigBuilder builder = OpcUaClientConfig.builder();
EndpointDescription endpointDescription =
getEndpointDescriptions("opc.tcp://127.0.0.1:12686/example", SecurityPolicy.Basic128Rsa15);
builder
.setEndpoint(endpointDescription);
builder.setIdentityProvider(new UsernameProvider(
"user",
"password1"
));
OpcUaClient client = new OpcUaClient(builder.build());
client.connect().get();
Thread.sleep(1000 * 10);
client.disconnect().get();
}
}
Этот тест выполняется на примере сервера eclipse milo: https://github.com/eclipse/milo/blob/master/milo-examples/server-examples/src/main/java/org/eclipse/milo/examples/server/ExampleServer.java
Еще одно обновление: что меня больше всего раздражает, так это следующее поведение
09:19:09.040 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.handlers.UaTcpClientMessageHandler - Received OpenSecureChannelResponse.
09:19:09.040 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.handlers.UaTcpClientMessageHandler - SecureChannel id=4, currentTokenId=4, previousTokenId=-1, lifetime=3600000ms, createdAt=DateTime{utcTime=131860523490250000, javaDate=Wed Nov 07 09:19:09 CET 2018}
09:19:09.040 [ua-netty-event-loop-0] DEBUG org.eclipse.milo.opcua.stack.client.handlers.UaTcpClientMessageHandler - 0 message(s) queued before handshake completed; sending now.
09:19:09.040 [ua-shared-pool-1] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - Channel bootstrap succeeded: localAddress=/127.0.0.1:50437, remoteAddress=/127.0.0.1:12686
09:19:09.134 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - disconnect(), currentState=Connected
09:19:09.134 [ua-shared-pool-1] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - Sending CloseSecureChannelRequest...
Кажется, что клиентское соединение установлено успешно, но затем клиент из описанного выше дымового теста немедленно отключается сам, чего не происходит при отсутствии SecurityPolicy.
Что еще более странно, после этого журнал продолжается:
09:28:12.283 [ua-netty-event-loop-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - channelInactive(), disconnect complete
09:28:12.283 [ua-netty-event-loop-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - disconnect complete, state set to Idle
09:28:12.299 [main] INFO org.eclipse.milo.opcua.sdk.client.OpcUaClient - Eclipse Milo OPC UA Stack version: 0.2.4
09:28:12.299 [main] INFO org.eclipse.milo.opcua.sdk.client.OpcUaClient - Eclipse Milo OPC UA Client SDK version: 0.2.4
09:28:12.315 [main] DEBUG org.eclipse.milo.opcua.sdk.client.OpcUaClient - Added ServiceFaultListener: org.eclipse.milo.opcua.sdk.client.session.SessionFsm$FaultListener@333d4a8c
09:28:12.330 [main] DEBUG org.eclipse.milo.opcua.sdk.client.OpcUaClient - Added SessionActivityListener: org.eclipse.milo.opcua.sdk.client.subscriptions.OpcUaSubscriptionManager$1@71687585
09:28:12.440 [main] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - connect(), currentState=NotConnected
09:28:12.440 [main] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - connect() while NotConnected
java.lang.Exception: null
at org.eclipse.milo.opcua.stack.client.ClientChannelManager.connect(ClientChannelManager.java:67) [stack-client-0.2.4.jar:0.2.4]
at org.eclipse.milo.opcua.stack.client.UaTcpStackClient.connect(UaTcpStackClient.java:127) [stack-client-0.2.4.jar:0.2.4]
at org.eclipse.milo.opcua.sdk.client.OpcUaClient.connect(OpcUaClient.java:312) [sdk-client-0.2.4.jar:0.2.4]
at de.dlh.lht.ticc.esa.opcua.client.lib.SmokeManualTest.run(SmokeManualTest.java:95) [test-classes/:?]
at de.dlh.lht.ticc.esa.opcua.client.lib.SmokeManualTest.credentialsTest(SmokeManualTest.java:104) [test-classes/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_101]
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) [junit-4.12.jar:4.12]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) [junit-4.12.jar:4.12]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.12.jar:4.12]
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.12.jar:4.12]
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) [junit-4.12.jar:4.12]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) [junit-4.12.jar:4.12]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12]
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) [junit-rt.jar:?]
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) [junit-rt.jar:?]
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) [junit-rt.jar:?]
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) [junit-rt.jar:?]
09:28:12.440 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - Channel bootstrap failed: null
java.nio.channels.ClosedChannelException: null
Таким образом, похоже, что ClientChannelManager пытается подключиться после отключения, которое он инициировал сам.
Еще я попробовал
builder.setCertificateValidator( new InsecureCertificateValidator());
предполагая, что самозаверяющий сертификат сервера отклонен, но это не помогло. Даже журнал этого класса не печатается, поэтому я предполагаю, что валидатор сертификата не вызывается, а ошибка возникает еще раньше.
Ради интереса я также добавил
static {
CryptoRestrictions.remove();
Security.addProvider(new BouncyCastleProvider());
}
к моему дымовому тесту. все еще не повезло
0.2.3, пробовал с 0.2.4. сегодня тоже, но это не имеет значения. я постараюсь создать минимальный пример, где ошибка возникает сегодня
постепенно у меня заканчиваются идеи, но я добавил к этому вопросу гораздо больше из того, что узнал два дня назад. Видите что-нибудь очевидное, может быть, @KevinHerron? Все еще надеюсь, что я просто забыл передать что-то одному из установщиков строителей, что связано с безопасностью. Должен ли я предоставлять SecurityPolicy где-нибудь помимо фильтрации конечных точек самостоятельно?
хорошо, еще одно обновление, я начинаю думать, что моя ошибка просто заключается в том, что одного сертификата достаточно, но, как вы описали в stackoverflow.com/questions/46411925/…, кажется, что один сертификат требуется для аутентификации, а другой - для передачи зашифрованного сообщения, который должен соответствовать URI приложения клиент. я попробую это




Конечно, это была довольно простая проблема. Остальные ошибки в журнале не имели к этому никакого отношения.
Еще один взгляд на Понимание безопасности OPC-UA с использованием Eclipse Milo очень помог.
Видите ли, вам всегда нужен сертификат приложения при использовании SecurityPolicy, отличного от «None», поскольку этот сертификат используется для шифрования и подписи сообщение. Это также несколько особый сертификат, поскольку он содержит uri приложения, который должен соответствовать - uri приложения, который вы настраиваете для своего клиента через builder.setApplicationUri ()
При использовании аутентификация через сертификат вы предоставляете второй сертификат (и закрытый ключ), который используется для подтверждения вашей личности на сервере. Это также причина, по которой вы можете аутентифицировать через сертификат или имя пользователя / пароль, вообще не имея шифрование и подпись сообщений
Не могли бы вы поделиться немного своим клиентским кодом? А какую версию Milo вы используете?