Encrypted Livestatus with Python - Bug?

I have been using my own Python script for many years to query the live status.
Since Werk #7017 the live status is encrypted, I would like to implement this in my script now.

But I can’t get it to work :-/

With the following command I can query the live status with SSL/TLS.

echo -e "GET status\nOutputFormat: json\n\n" | openssl s_client -connect x.x.x.x:6558 -ign_eof -quiet

As an example script let’s take the script from section 2.2 https://checkmk.de/cms_livestatus.html
Does anyone have an idea how I have to adapt the script to query the live status with ssl/tls?

#!/usr/bin/env python
# Sample program for accessing Livestatus from Python

import json, os, socket, ssl

# for local site only: file path to socket
#address = "%s/tmp/run/live" % os.getenv("OMD_ROOT")
# for local/remote sites: TCP address/port for Livestatus socket
#address = ("localhost", 6557)
address = ('x.x.x.x', 6558)

# connect to Livestatus
family = socket.AF_INET if type(address) == tuple else socket.AF_UNIX
sock = socket.socket(family, socket.SOCK_STREAM)


#sock_ssl = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLSv1_2, keyfile=None, certfile=None, server_side=False, cert_reqs=ssl.CERT_NONE)
#sock_ssl = ssl.wrap_socket(sock)
#ssl._create_default_https_context = ssl._create_unverified_context
context = ssl.create_default_context()
#context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
#context.load_default_certs()

sock_ssl = context.wrap_socket(sock)


sock_ssl.connect(address)
print sock_ssl.getpeercert()

# send our request and let Livestatus know we're done
sock_ssl.sendall("GET status\nOutputFormat: json\n\n")
sock_ssl.shutdown(socket.SHUT_WR)

# receive the reply as a JSON string
chunks = []
while len(chunks) == 0 or chunks[-1] != "":
    chunks.append(sock_ssl.recv(4096))
    print(chunks)
sock_ssl.close()
reply = "".join(chunks)

# print the parsed reply
print(json.loads(reply))

Have you uncommented all the lines in the script that setup TLS/SSL starting with

#sock_ssl = ssl.wrap_socket(sock, ssl_ver…

?

sock_ssl.shutdown(socket.SHUT_WR) is the problem, this must be commented out with ssl/tls .

I thought I had solved the problem :-/
I am getting data now, but the data is not complete.
When I use len() to display the length of the received data, it is always different for the same lql request (output about 1000 services). Also converting to json/pyton is not possible because the data is not complete.

$ echo -e "GET services\nColumns: host_name host_alias host_address plugin_output host_filename\nFilter: check_command = check_mk-snmp_info_v2\nOutputFormat: python\n\n" | openssl s_client -connect x.x.x.x:6558 -ign_eof -quiet | wc -c
198656

$ echo -e "GET services\nColumns: host_name host_alias host_address plugin_output host_filename\nFilter: check_command = check_mk-snmp_info_v2\nOutputFormat: python\n\n" | openssl s_client -connect x.x.x.x:6558 -ign_eof -quiet | wc -c
280576

$ echo -e "GET services\nColumns: host_name host_alias host_address plugin_output host_filename\nFilter: check_command = check_mk-snmp_info_v2\nOutputFormat: python\n\n" | openssl s_client -connect x.x.x.x:6558 -ign_eof -quiet | wc -c
198656

$ echo -e "GET services\nColumns: host_name host_alias host_address plugin_output host_filename\nFilter: check_command = check_mk-snmp_info_v2\nOutputFormat: python\n\n" | openssl s_client -connect x.x.x.x:6558 -ign_eof -quiet | wc -c
231424

$ echo -e "GET services\nColumns: host_name host_alias host_address plugin_output host_filename\nFilter: check_command = check_mk-snmp_info_v2\nOutputFormat: python\n\n" | openssl s_client -connect x.x.x.x:6558 -ign_eof -quiet | wc -c
296960

is that a bug from livestatus?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.