Connect to OPCUA server with username and password - python

I am using UAExpert application and i am connecting to my machine with these settings:
I want to connect to my device with python.
I have this code but it doesn't work.
from opcua import Client
client = Client("opc.tcp://<ip>:4840")
client.set_user("username")
client.set_password("password")
client.set_security_string("Basic256Sha256,Sign,cert.der,key.pem")
client.connect()
I am getting this error:
raise ua.UaError("No matching endpoints: {0}, {1}".format(security_mode, policy_uri))
opcua.ua.uaerrors._base.UaError: No matching endpoints: 2, http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256
UPDATE:
I think it's the issue of the certificate. So i found from UAExpert settings where it gets the certificate from.
I use the same path for cert.der but i don't know where i can find the key.pem

Ok so i made it work. This is my current code:
import asyncio
import opcua
async def main():
client = opcua.Client("opc.tcp://<ip>:4840", timeout=60)
client.application_uri = "urn:<ip>:UPS1600" # Should match in your certificate
client.set_user("username")
client.set_password("password")
client.set_security_string("Basic256Sha256,SignAndEncrypt,<path_to_certificate.pem>,<path_to_key.pem")
client.connect()
struct = client.get_node("ns=3;i=100191")
value= struct.get_value()
print(value)
if __name__ == '__main__':
asyncio.run(main())
Where certificate.pem and key.pem i have created them from
here

Related

grpc python client authentication throwing SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED

I am building one grpc based application with secure authentication, is there any issue with grpc python client or i am missing anything ? because on documentation it don't say much things.
My environment is following:
OS: "Ubuntu 18.04.5 LTS"
python 3.7
openssl V 1.1.1-1ubuntu2.1~18.04.13
grpcio==1.39.0
grpcio-tools==1.39.0
protobuf==3.17.3
I am always getting SSL_ERROR_SSL: CERTIFICATE_VERIFY_FAILED
E0901 13:16:05.996420843 13512 ssl_transport_security.cc:1468] Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
E0901 13:16:06.495380631 13512 ssl_transport_security.cc:1468] Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
E0901 13:16:06.953751870 13512 ssl_transport_security.cc:1468] Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
E0901 13:16:07.407166253 13512 ssl_transport_security.cc:1468] Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
Traceback (most recent call last):
File "grpc-client.py", line 21, in <module>
main()
File "grpc-client.py", line 11, in main
response = stub.ApiEndpoint(request)
File "/home/ggarg/.local/lib/python3.7/site-packages/grpc/_channel.py", line 946, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/home/ggarg/.local/lib/python3.7/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "failed to connect to all addresses"
my proto file is:
syntax = "proto3";
service Api{
rpc ApiEndpoint(ApiRequest) returns (ApiResponse);
}
message ApiRequest{
string name = 1;
string message = 2;
}
message ApiResponse{
string reply = 1;
}
server code is:
import grpc
from concurrent import futures
import time
import api_pb2
import api_pb2_grpc
import os
class ChatBox(api_pb2_grpc.ApiServicer):
def ApiEndpoint(self, request, context):
response = api_pb2.ApiResponse()
response.reply = "Hi {}, myself {} , Thanks for this message : {}".format(
request.name, os.getenv("POD_NAME"), request.message)
return response
if __name__ == '__main__':
# create a gRPC server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
with open('cert/server.key', 'rb') as f:
private_key = f.read()
with open('cert/server.crt', 'rb') as f:
certificate_chain = f.read()
server_credentials = grpc.ssl_server_credentials(
((private_key, certificate_chain), ))
# add the servier created above tp the server
api_pb2_grpc.add_ApiServicer_to_server(ChatBox(), server)
# listen on port 50051
print('Starting server. Listening on port 50051.')
server.add_secure_port('[::]:50051', server_credentials)
server.start()
# since server.start() will not block,
# a sleep-loop is added to keep alive
try:
while True:
time.sleep(86400)
except KeyboardInterrupt:
server.stop(0)
and client code is:
import grpc
import api_pb2_grpc
import api_pb2
import time
def main():
request = api_pb2.ApiRequest(
name="timus",
message="You are awesome")
response = stub.ApiEndpoint(request)
print(response)
if __name__ == '__main__':
with open('cert/server.crt', 'rb') as f:
creds = grpc.ssl_channel_credentials(f.read())
#channel = grpc.secure_channel('www.timus.com:443', creds)
channel = grpc.secure_channel('0.0.0.0:50051', creds)
stub = api_pb2_grpc.ApiStub(channel)
while True:
main()
time.sleep(2)
I used following openssl command to generate crt.
openssl req -newkey rsa:4096 -nodes -sha512 -x509 -days 3650 -nodes -out server.crt -keyout server.key
I pasted above code as a example. for simplicity i am using same certificate on client and server. Initially i used ca/server/client certificate differently but I was having this issue and just for testing i used server certificate on both client and server side. but still getting same issue ? did anyone encounter similar issue ? thanks in advance.
It seems you are trying to assign the server certificate as the client's trust certificate. That will require the certificate to be a self-signed certificate. You will have to check that.
Even if it is self-signed, it is not the usual way for us to establish TLS connections. That can leave your applications to man-in-the-middle attack. You will want to have your client set a trust certificate that is issued by a CA, and have the CA sign the server's certificate. That can make sure there is a trustworthy third-party making sure the authentication is good.
You will also make sure the syntax is correct(sorry I am not that familiar with the Python syntax). We allow certs, root certs in both client and server for mutual TLS, but for single TLS, you only need to set certs for server, and root certs for client.

MQRC_SSL_INITIALIZATION_ERROR with PyMQI (however it connects successfully with c application amssslc)

I am using the same computer local windows 7 computer with MQ Client 9.0.4.0, when trying to connect to the server with amqssslc I can successfully connect to the QMGR (connected like so), however, when I try to connect with PyMQI, I get the following error,
MQI Error. Comp: 2, Reason 2393: FAILED: MQRC_SSL_INITIALIZATION_ERROR
The code that I am using is the following,
import pymqi
import logging
import sys, codecs, locale
logging.basicConfig(level=logging.INFO)
queue_manager = 'QMGR'
channel = 'channel'
host = 'server.com'
port = '1414'
conn_info = '%s(%s)' % (host, port)
ssl_cipher_spec = str.encode('TLS_RSA_WITH_AES_256_CBC_SHA256')
key_repo_location = str.encode('T:/Desktop/certificates/key')
message = 'TEST Message'
channel = str.encode(channel)
host = str.encode(host)
conn_info = str.encode(conn_info)
cd = pymqi.CD(Version=pymqi.CMQXC.MQCD_VERSION_11)
cd.ChannelName = channel
cd.ConnectionName = conn_info
cd.ChannelType = pymqi.CMQC.MQCHT_CLNTCONN
cd.TransportType = pymqi.CMQC.MQXPT_TCP
cd.SSLCipherSpec = ssl_cipher_spec
cd.CertificateLabel = 'edgar'.encode()
sco = pymqi.SCO()
sco.KeyRepository = key_repo_location
qmgr = pymqi.QueueManager(None)
qmgr.connect_with_options(queue_manager, cd, sco)
However when using amqssslc, that comes when installing the MQ Client on my machine, it does work without any errors and connects successfully.
The error from the AMQERR01 log file says the following,
AMQ9716E: Remote SSL certificate revocation status check failed for channel
'channel_name'.
EXPLANATION:
IBM MQ failed to determine the revocation status of the remote SSL certificate
for one of the following reasons:
(a) The channel was unable to contact any of the CRL servers or OCSP responders
for the certificate.
(b) None of the OCSP responders contacted knows the revocation status of the
certificate.
(c) An OCSP response was received, but the digital signature of the response
could not be verified.
I can't change my mqclient.ini config file, since it is locked by not having admin rights (company policies). What I find weird, is that amqssslc works, when they are both using the same mqclient file. I have also tried setting up the path of the MQCLTNFC to another folder including a different config file without success.
Any help would be truly appreciated!

grpc client dns resolution failed when trying to access grpc server on same network

I'm trying to call a GRPC server running on a .Net Core project from a Python client.
When running against localhost:5001 it works fine, but running against the actual IP of the machine from within the same network like 192.168.1.230:5001 it doesn't work and I get an error DNS resolution failed.
I've downloaded the SSL cert and am at the moment reading it as a file from the client. It works when running against localhost so I don't think that is the problem.
Is there a better way to do this kind of testing of having clients run on separate devices but on the same network as the server? Hosting the GRPC server outside during development doesn't really seem like the best solution.
Python code:
import grpc
import datamessage_pb2 as datamessage
import datamessage_pb2_grpc as datamessageService
def main():
print("Calling grpc server")
with open("localhost.cer", "rb") as file:
cert = file.read()
credentials = grpc.ssl_channel_credentials(cert)
channel = grpc.secure_channel("https://192.168.1.230:5001", credentials)
# channel = grpc.secure_channel("localhost:5001", credentials)
stub = datamessageService.StationDataHandlerStub(channel)
request = datamessage.StationDataModel(
temperature=22.3, humidity=13.3, soilMoisture=35.0)
result = stub.RegisterNewStationData(request)
print(result)
main()
Server settings in Program.cs:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseUrls("https://*:5001");
webBuilder.UseStartup<Startup>();
});
Settings in firewall:
Traceback:
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "DNS resolution failed"
debug_error_string = "{"created":"#1576101634.549000000","description":"Failed to pick subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":3934,"referenced_errors":[{"created":"#1576101634.549000000","description":"Resolver transient failure","file":"src/core/ext/filters/client_channel/resolving_lb_policy.cc","file_line":262,"referenced_errors":[{"created":"#1576101634.549000000","description":"DNS resolution failed","file":"src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc","file_line":202,"grpc_status":14,"referenced_errors":[{"created":"#1576101634.549000000","description":"OS Error","file":"src/core/lib/iomgr/resolve_address_windows.cc","file_line":96,"os_error":"No such host is known.\r\n","syscall":"getaddrinfo","wsa_error":11001}]}]}]}"
In Python gRPC client, calling channel without protocol (https:) is required. So, I called gRPC service in dotnet core framework with following and it worked. Note, dotnet gRPC server was listening on https://localhost:5001.
with open('localhost.crt', 'rb') as f:
credentials = grpc.ssl_channel_credentials(f.read())
with grpc.secure_channel('localhost:5001', credentials) as channel:
stub = pb2_grpc.GreeterStub(channel)
request = pb2.HelloRequest(name = "GreeterPythonClient")
response = stub.SayHello(request)

How to FIX "ovirtsdk4.Error: Error while sending HTTP request:" error in oVirt

I want to backup the VM on the server through the Python API interface, and I backup the VM via ovirt-engine. How do I backup using Ovirtsdk4?
I've tried a number of times, still errors
import logging
import ovirtsdk4 as sdk
logging.basicConfig(level=logging.DEBUG, filename='example.log')
def get_connection():
# Create the connection to the server:
return sdk.Connection(
url='https://172.32.42.75/ovirt-engine/api',
username='admin#internal',
password='password',
ca_file='/etc/pki/ovirt-engine/ca.pem',
debug=True,
log=logging.getLogger(),
)
if __name__ == "__main__":
# Set VM name
vm_name = 'myvm'
# Create a connection to the server:
connection = get_connection()
# Get a reference to the root service:
system_service = connection.system_service()
# Get the reference to the "vms" service:
vms_service = system_service.vms_service()
# Locate VM service
try:
vm = vms_service.list(search="name=%s" % vm_name, all_content=True)[0]
ovf_filename = "%s.ovf" % vm.id
with open(ovf_filename, "wb") as ovf_file:
ovf_file.write(vm.initialization.configuration.data)
finally:
# Close the connection to the server:
connection.close()
I hope the VM that will do the backup can run properly using the Python API oVirt.error of ovirtsdk4
I think error might be because of older curl. Please update curl, libcurl and NSS libraries and try again.
Ref: curl: (35) SSL connect error

How to securely connect to Bitstamp Websocket v2.0 API with python websockets? Certrificate verification error

I'm trying to get real time bitcoin price data from the Bitstamp Websocket v2.0 API. Where can I get the certificate if needed? If download of the certificate is automatic, how can I make sure that it is possible for python to verify the received certificate?
The documentation on the Bitstamp website is rather scarce on this matter. Here's a quote from Bitstamp api documentation:
"Once you open a connection via websocket handshake (using HTTP upgrade header), you can subscribe to desired channels."
Bitstamp api docs: https://www.bitstamp.net/websocket/v2/
Tried searching in websockets documentation: https://websockets.readthedocs.io/en/stable/
I have looked into websockets and ssl. Now I know a bit about the handshake but still after much trying and searching I can't figure out what to do.
import asyncio
import websockets
async def bitstamp_ticker():
async with websockets.connect(
'wss://ws.bitstamp.net', ssl=True) as websocket:
pass
asyncio.get_event_loop().run_until_complete(bitstamp_ticker())
From what I understand in the websocket documentation adding ssl=True should be enough to establish a secure connection. But it seems that maybe the bitstamp certificate is not recognized by a Certificate Authority built into Python 3.6. and this is why the error occurs?
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)
I didn't spend time looking into this ssl cert issue for Bitstamp. But I just disabled ssl cert verification to make the web-socket market data push work. Below is the sample code, and appreciated if you could share your future progress on this issue.
# -*- coding: utf-8 -*-
import websocket
import json
import ssl
bitstamp_endpoint = 'wss://ws.bitstamp.net'
def subscribe_marketdata(ws):
params = {
'event': 'bts:subscribe',
'data': {
'channel': 'order_book_btcusd'
}
}
market_depth_subscription = json.dumps(params)
ws.send(market_depth_subscription)
def on_open(ws):
print('web-socket connected.')
subscribe_marketdata(ws)
def on_message(ws, data):
data = json.loads(data)
print(data)
def on_error(ws, msg):
print(msg)
if __name__ == '__main__':
marketdata_ws = websocket.WebSocketApp(bitstamp_endpoint, on_open=on_open, on_message=on_message, on_error=on_error)
marketdata_ws.run_forever(sslopt={'cert_reqs': ssl.CERT_NONE})

Categories