Skip to content
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

TLS PSK usage with ZabbixSender #114

Open
KostyaEsmukov opened this issue Apr 6, 2019 · 5 comments
Open

TLS PSK usage with ZabbixSender #114

KostyaEsmukov opened this issue Apr 6, 2019 · 5 comments

Comments

@KostyaEsmukov
Copy link

I've spent quite a lot of time trying to set up a TLS connection with PSK. I finally managed to do that, so I thought I'd share my solution in hope that it would save someone time.

The python ssl package doesn't provide support for PSK, it supports just the certificates. But there's a nice little package which does provide support for TLS PSK: https://github.com/drbild/sslpsk

The tricks are:

  • sslpsk expects that its wrap_socket would be called after socket.connect(...), while the ssl.wrap_socket expects that it would be called before socket.connect(...).
  • Zabbix server seems to accept only a single TLS cipher, which the client might not announce (I guess because it is a weak one).

So here is a solution that works for me with Zabbix server 4.2:

import functools
import ssl

import sslpsk
from pyzabbix import ZabbixMetric, ZabbixSender


class PyZabbixPSKSocketWrapper:
    """Implements ssl.wrap_socket with PSK instead of certificates.

    Proxies calls to a `socket` instance.
    """

    def __init__(self, sock, *, identity, psk):
        self.__sock = sock
        self.__identity = identity
        self.__psk = psk

    def connect(self, *args, **kwargs):
        # `sslpsk.wrap_socket` must be called *after* socket.connect,
        # while the `ssl.wrap_socket` must be called *before* socket.connect.
        self.__sock.connect(*args, **kwargs)

        # `sslv3 alert bad record mac` exception means incorrect PSK
        self.__sock = sslpsk.wrap_socket(
            self.__sock,
            # https://github.com/zabbix/zabbix/blob/f0a1ad397e5653238638cd1a65a25ff78c6809bb/src/libs/zbxcrypto/tls.c#L3231
            ssl_version=ssl.PROTOCOL_TLSv1_2,
            # https://github.com/zabbix/zabbix/blob/f0a1ad397e5653238638cd1a65a25ff78c6809bb/src/libs/zbxcrypto/tls.c#L3179
            ciphers="PSK-AES128-CBC-SHA",
            psk=(self.__psk, self.__identity),
        )

    def __getattr__(self, name):
        return getattr(self.__sock, name)


sender = ZabbixSender(
    zabbix_server="my.zabbix.host",
    socket_wrapper=functools.partial(
        PyZabbixPSKSocketWrapper,
        identity="PSK myidentity",  # your PSK identity
        psk=bytes.fromhex(
            "0cd204cf169ade0bbdcd13c95594eadd008eed1b4411856b6e16e10ee6b69458"  # your PSK
        ),
    ),
)

It would be nice if ZabbixSender(use_config=True) could automatically detect PSK settings from the config and use them, but I guess this solution might seem to be a bit hacky to be included to the package. Especially given that the sslpsk package on pypi does not provide manylinux/macos wheels and needs openssl headers and gcc to be present on the system to be installed.

I would be glad to know if there's a cleaner way to achieve the TLS PSK support with this package.

@KostyaEsmukov KostyaEsmukov changed the title TLS PSK usage TLS PSK usage with ZabbixSender Apr 6, 2019
@ghost
Copy link

ghost commented Jul 9, 2019

I have tested this on my landscape and it works perfectly.

@rlaunch
Copy link

rlaunch commented Dec 24, 2020

Works perfectly on Zabbix 5, thanks for sharing.

mcdir pushed a commit to mcdir/py-zabbix that referenced this issue Jan 29, 2021
mcdir pushed a commit to mcdir/py-zabbix that referenced this issue Jan 29, 2021
mcdir pushed a commit to mcdir/py-zabbix that referenced this issue Jan 29, 2021
@mcdir
Copy link

mcdir commented Jan 29, 2021

MR with fix #139

mcdir pushed a commit to mcdir/py-zabbix that referenced this issue Jan 29, 2021
mcdir pushed a commit to mcdir/py-zabbix that referenced this issue Jan 29, 2021
mcdir pushed a commit to mcdir/py-zabbix that referenced this issue Jan 29, 2021
mcdir pushed a commit to mcdir/py-zabbix that referenced this issue Jan 29, 2021
mcdir pushed a commit to mcdir/py-zabbix that referenced this issue Jan 29, 2021
@HoracioDos
Copy link

Hello.
I guess this problem isn't fixed yet. Zabbix Agent 2 is working fine but I get these messages in proxy log.

218746:20210902:103052.576 connection of type "unencrypted" is not allowed for host "piapc"
218744:20210902:103053.697 connection of type "unencrypted" is not allowed for host "piapc"
218737:20210902:103054.811 connection of type "unencrypted" is not allowed for host "piapc"

@mcdir does your branch have these fixes applied?
Thanks in advance.

@gitbock
Copy link

gitbock commented Jan 24, 2023

Thank you @KostyaEsmukov for providing this!

I hit a bug in the sslpsk lib.
AttributeError: '_ssl._SSLSocket' object has no attribute '_sslobj'

I could solve it by applying this patch manually to the file sslpsk.py
See also this thread.

After this it's working fine!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants