diff --git a/src/modules/tls/Makefile b/src/modules/tls/Makefile index b17a305073c..1505bc64ea5 100644 --- a/src/modules/tls/Makefile +++ b/src/modules/tls/Makefile @@ -33,6 +33,8 @@ LIBS+= $(TLS_EXTRA_LIBS) # dcm: tls.cfg installed via local 'install-cfg' to update paths #MOD_INSTALL_CFGS=tls.cfg +MOD_INSTALL_UTILS=utils/openssl_mutex_shared + include ../../Makefile.modules install-tls-cert: $(cfg_prefix)/$(cfg_dir) diff --git a/src/modules/tls/doc/tls.xml b/src/modules/tls/doc/tls.xml index fe10eec08a8..b5ea415ae79 100644 --- a/src/modules/tls/doc/tls.xml +++ b/src/modules/tls/doc/tls.xml @@ -121,6 +121,11 @@ request_route { To quickly check if your Kamailio version was compiled with these options, run kamailio -V and look for USE_TLS and TLS_HOOKS among the flags. + + For OpenSSL (libssl) v1.1.x, it is required to preload + 'openssl_mutex_shared' library shipped by &kamailio;. For more details + see 'src/modules/tls/openssl_mutex_shared/README.md'. + This module includes several workarounds for various Openssl bugs (like compression and Kerberos using the wrong memory allocations diff --git a/src/modules/tls/utils/openssl_mutex_shared/Makefile b/src/modules/tls/utils/openssl_mutex_shared/Makefile new file mode 100644 index 00000000000..8edfe13a605 --- /dev/null +++ b/src/modules/tls/utils/openssl_mutex_shared/Makefile @@ -0,0 +1,26 @@ +COREPATH=../../../../../src +include $(COREPATH)/Makefile.defs +include $(COREPATH)/Makefile.targets + + +.PHONY: all +all: openssl_mutex_shared.so + +.PHONY: install-if-newer +install-if-newer: install + +.PHONY: install +install: install-modules + +.PHONY: install-modules +install-modules: openssl_mutex_shared.so + mkdir -p $(modules_prefix)/$(lib_dir)/openssl_mutex_shared + $(INSTALL_TOUCH) $(modules_prefix)/$(lib_dir)/openssl_mutex_shared/openssl_mutex_shared.so + $(INSTALL_BIN) openssl_mutex_shared.so $(modules_prefix)/$(lib_dir)/openssl_mutex_shared + +openssl_mutex_shared.so: openssl_mutex_shared.c + $(CC) -g -D_GNU_SOURCE -std=c99 -fvisibility=hidden -pthread -o $@ -O3 -Wall -shared -fPIC -ldl $< + +.PHONY: clean +clean: + rm -f openssl_mutex_shared.so diff --git a/src/modules/tls/utils/openssl_mutex_shared/README.md b/src/modules/tls/utils/openssl_mutex_shared/README.md new file mode 100644 index 00000000000..9f2e9c57e38 --- /dev/null +++ b/src/modules/tls/utils/openssl_mutex_shared/README.md @@ -0,0 +1,53 @@ +# OpenSSL Shared Mutex # + +This is a shared library required as a short term workaround for using Kamailio +with OpenSSL (libssl) v1.1. It has to be pre-loaded before starting Kamailio. + +In v1.1, libssl does not allow setting custom locking functions, using internally +pthread mutexes and rwlocks, but they are not initialized with process shared +option (PTHREAD_PROCESS_SHARED), which can result in blocking Kamailio worker +processes. + +## Installation ## + +By default, it is installed when the tls module is installed. + +It can be installed manually, in this folder execute: + +``` +make +make install +``` + +It is installed at the same place where Kamailio deploys the directory with +modules. + +For example, when installing from sources on a 64b system, the location is: + +``` +/usr/local/lib64/kamailio/openssl_mutex_shared/openssl_mutex_shared.so +``` + +For Debian packing, the location is like: + +``` +/usr/lib/x86_64-linux-gnu/kamailio/openssl_mutex_shared/openssl_mutex_shared.so +``` + +## Usage ## + +Use LD_PRELOAD to tell the linker to preload this shared object before starting +Kamailio. + +Example, when Kamailio was installed from sources: + +``` +LD_PRELOAD=/usr/local/lib64/kamailio/openssl_mutex_shared/openssl_mutex_shared.so; \ + /usr/local/sbin/kamailio -f /usr/local/etc/kamailio/kamailio.cfg +``` + +If using systemd, add to service file: + +``` +Environment='LD_PRELOAD=/usr/local/lib64/kamailio/openssl_mutex_shared/openssl_mutex_shared.so' +``` diff --git a/src/modules/tls/utils/openssl_mutex_shared/openssl_mutex_shared.c b/src/modules/tls/utils/openssl_mutex_shared/openssl_mutex_shared.c new file mode 100644 index 00000000000..00c9c8056e0 --- /dev/null +++ b/src/modules/tls/utils/openssl_mutex_shared/openssl_mutex_shared.c @@ -0,0 +1,46 @@ +#include +#include + +#define SYMBOL_EXPORT __attribute__((visibility("default"))) + +int SYMBOL_EXPORT pthread_mutex_init (pthread_mutex_t *__mutex, const pthread_mutexattr_t *__mutexattr) +{ + static int (*real_pthread_mutex_init)(pthread_mutex_t *__mutex, const pthread_mutexattr_t *__mutexattr); + if (!real_pthread_mutex_init) + real_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init"); + + if (__mutexattr) { + pthread_mutexattr_t attr = *__mutexattr; + pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + return real_pthread_mutex_init(__mutex, &attr); + } + + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + int ret = real_pthread_mutex_init(__mutex, &attr); + pthread_mutexattr_destroy(&attr); + return ret; +} + +int SYMBOL_EXPORT pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock, + const pthread_rwlockattr_t *__restrict __attr) +{ + static int (*real_pthread_rwlock_init)(pthread_rwlock_t *__restrict __rwlock, + const pthread_rwlockattr_t *__restrict __attr); + if (!real_pthread_rwlock_init) + real_pthread_rwlock_init = dlsym(RTLD_NEXT, "pthread_rwlock_init"); + + if (__attr) { + pthread_rwlockattr_t attr = *__attr; + pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + return real_pthread_rwlock_init(__rwlock, &attr); + } + + pthread_rwlockattr_t attr; + pthread_rwlockattr_init(&attr); + pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + int ret = real_pthread_rwlock_init(__rwlock, &attr); + pthread_rwlockattr_destroy(&attr); + return ret; +}