diff --git a/raddb/mods-available/python3 b/raddb/mods-available/python3
index 246dfd74ce..0593c69f1a 100644
--- a/raddb/mods-available/python3
+++ b/raddb/mods-available/python3
@@ -13,7 +13,7 @@ python3 {
 	#  item is GLOBAL TO THE SERVER.  That is, you cannot have two
 	#  instances of the python module, each with a different path.
 	#
-#        python_path="/path/to/python/files:/another_path/to/python_files/"
+#	python_path="${modconfdir}/${.:name}:/another_path/to/python_files"
 
 	module = example
 
diff --git a/src/modules/rlm_python3/configure.ac b/src/modules/rlm_python3/configure.ac
index a00320fda4..295a2486d2 100644
--- a/src/modules/rlm_python3/configure.ac
+++ b/src/modules/rlm_python3/configure.ac
@@ -8,128 +8,75 @@ if test x$with_[]modname != xno; then
 	AC_PROG_CC
 	AC_PROG_CPP
 
-	dnl extra argument: --with-rlm-python3-bin
-	PYTHON3_BIN=
-	AC_ARG_WITH(rlm-python3-bin,
-	[  --with-rlm-python3-bin=PATH   Path to python3 binary []],
+	dnl extra argument: --with-rlm-python3-config-bin
+	PYTHON3_CONFIG_BIN=
+	AC_ARG_WITH(rlm-python3-config-bin,
+	[  --with-rlm-python3-config-bin=PATH   Path to python-config3 binary []],
 	[ case "$withval" in
 	    no)
-		AC_MSG_ERROR(Need rlm-python3-bin)
+		AC_MSG_ERROR(Need rlm-python3-config-bin)
 		;;
 	    yes)
 		;;
 	    *)
-		PYTHON3_BIN="$withval"
+		PYTHON3_CONFIG_BIN="$withval"
 		;;
 	  esac ]
 	)
 
-	if test "x$PYTHON3_BIN" = x; then
-		AC_CHECK_PROGS(PYTHON3_BIN, [ python3 ], not-found, [${PATH}:/usr/bin:/usr/local/bin])
+	if test "x$PYTHON3_CONFIG_BIN" = x; then
+		AC_CHECK_PROGS(PYTHON3_CONFIG_BIN, [ python3-config ], not-found, [${PATH}:/usr/bin:/usr/local/bin])
 	fi
 
-	if test "x$PYTHON3_BIN" = "xnot-found"; then
-		fail="python-binary"
-	fi
-
-	dnl extra argument: --with-rlm-python3-lib-dir
-	PY_LIB_DIR=
-	AC_ARG_WITH(rlm-python3-lib-dir,
-	[  --with-rlm-python3-lib-dir=DIR       Directory for Python library files []],
-	[ case "$withval" in
-	    no)
-		AC_MSG_ERROR(Need rlm-python3-lib-dir)
-		;;
-	    yes)
-		;;
-	    *)
-		PY_LIB_DIR="$withval"
-		;;
-	  esac ]
-	)
-
-	dnl extra argument: --with-rlm-python3-include-dir
-	PY_INC_DIR=
-	AC_ARG_WITH(rlm-python3-include-dir,
-	[  --with-rlm-python3-include-dir=DIR   Directory for Python include files []],
-	[ case "$withval" in
-	    no)
-		AC_MSG_ERROR(Need rlm-python3-include-dir)
-		;;
-	    yes)
-		;;
-	    *)
-		PY_INC_DIR="$withval"
-		;;
-	  esac ]
-	)
-
-	if test x$fail = x; then
-		PY_PREFIX=`${PYTHON3_BIN} -c 'import sys ; print(sys.prefix)'`
-		AC_MSG_NOTICE([Python sys.prefix \"${PY_PREFIX}\"])
-
-		PY_EXEC_PREFIX=`${PYTHON3_BIN} -c 'import sys ; print(sys.exec_prefix)'`
-		AC_MSG_NOTICE([Python sys.exec_prefix \"${PY_EXEC_PREFIX}\"])
-
-		PY_SYS_VERSION=`${PYTHON3_BIN} -c 'import sys ; print(sys.version[[0:3]])'`
-		AC_MSG_NOTICE([Python sys.version \"${PY_SYS_VERSION}\"])
-
-		if test "x$PY_LIB_DIR" = "x"; then
-			PY_LIB_DIR="$PY_EXEC_PREFIX/lib/python${PY_SYS_VERSION}/config"
-			PY_LIB_LOC="-L$PY_EXEC_PREFIX/lib/python${PY_SYS_VERSION}/config"
-		fi
-
-		PY_MAKEFILE="$PY_EXEC_PREFIX/lib/python${PY_SYS_VERSION}/config/Makefile"
-		if test -f ${PY_MAKEFILE}; then
-			PY_LOCAL_MOD_LIBS=`sed -n -e 's/^LOCALMODLIBS=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[[:blank:]]]/ /g;s/^ *//;s/ *$//'`
-			AC_MSG_NOTICE([Python local_mod_libs \"${PY_LOCAL_MOD_LIBS}\"])
-
-			PY_BASE_MOD_LIBS=`sed -n -e 's/^BASEMODLIBS=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[[:blank:]]]/ /g;s/^ *//;s/ *$//'`
-			AC_MSG_NOTICE([Python base_mod_libs \"${PY_BASE_MOD_LIBS}\"])
-
-			PY_OTHER_LIBS=`sed -n -e 's/^LIBS=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[[:blank:]]]/ /g;s/  / /g;s/^ *//;s/ *$//'`
-			PY_OTHER_LDFLAGS=`sed -n -e 's/^LINKFORSHARED=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[[:blank:]]]/ /g;s/  / /g;s/^ *//;s/ *$//'`
-			AC_MSG_NOTICE([Python other_libs \"${PY_OTHER_LDFLAGS} ${PY_OTHER_LIBS}\"])
-		fi
-		PY_EXTRA_LIBS="$PY_LOCALMODLIBS $PY_BASE_MOD_LIBS $PY_OTHER_LIBS"
+	if test "x$PYTHON3_CONFIG_BIN" = xnot-found; then
+		fail="$fail python3-config"
+	else
+		dnl #
+		dnl # It is necessary due to a weird behavior with 'python3-config'
+		dnl #
+		old_CFLAGS="$CFLAGS"
+		unset CFLAGS
+
+		python3_cflags=`${PYTHON3_CONFIG_BIN} --cflags`
+		AC_MSG_NOTICE([${PYTHON3_CONFIG_BIN}'s cflags were \"${python3_cflags}\"])
+
+		dnl # Convert -I to -isystem to get rid of warnings about issues in Python headers
+		dnl # Strip -systemroot
+		dnl # Strip optimisation flags (-O[0-9]?). We decide our optimisation level, not python.
+		dnl # -D_FORTIFY_SOURCE needs -O.
+		dnl # Strip debug symbol flags (-g[0-9]?). We decide on debugging symbols, not python
+		dnl # Strip -W*, we decide what warnings are important
+		dnl # Strip -DNDEBUG
+		mod_cflags=`echo $python3_cflags | sed -e '\
+			s/-I/-isystem/g;\
+			s/-isysroot[[ =]]\{0,1\}[[^-]]*//g;\
+			s/-O[[^[[:blank:]]]]*//g;\
+			s/-Wp,-D_FORTIFY_SOURCE=[[[:digit:]]]//g;\
+			s/-g[[^ ]]*//g;\
+			s/-W[[^ ]]*//g;\
+			s/-DNDEBUG[[[:blank:]]]*//g;
+			'`
+		AC_MSG_NOTICE([Sanitized cflags were \"${mod_cflags}\"])
+
+		python3_ldflags=`${PYTHON3_CONFIG_BIN} --ldflags`
+		AC_MSG_NOTICE([${PYTHON3_CONFIG_BIN}'s ldflags were \"$python3_ldflags}\"])
+
+		dnl # Strip -Wl,-O1... Is -O even a valid linker flag??
+		dnl # Strip -Wl,-Bsymbolic-functions as thats not always supported or required
+		dnl # Strip -Xlinker -export-dynamic as it causes weird linking issues on Linux
+		dnl #   See: https://bugs.python.org/issue36508
+		mod_ldflags=`echo $python3_ldflags | sed -e '\
+			s/-Wl,-O[[[:digit:]]][[[:blank:]]]*//g;\
+			s/-Wl,-Bsymbolic-functions[[[:blank:]]]*//g;\
+			s/-Xlinker -export-dynamic//g;\
+			s/-Wl,-stack_size,[[[:digit:]]]*[[[:blank:]]]//g;
+			'`
+		AC_MSG_NOTICE([Sanitized ldflags were \"${mod_ldflags}\"])
 
-		old_CFLAGS=$CFLAGS
-		CFLAGS="$CFLAGS $PY_CFLAGS"
-		smart_try_dir="$PY_PREFIX/include/python$PY_SYS_VERSION"
-		FR_SMART_CHECK_INCLUDE(Python.h)
 		CFLAGS=$old_CFLAGS
 
-		if test "x$ac_cv_header_Python_h" = "xyes"; then
-			mod_cflags="$SMART_CPPFLAGS"
-		else
-			fail="$fail Python.h"
-			targetname=
-		fi
-
-		old_LIBS=$LIBS
-		LIBS="$LIBS $PY_LIB_LOC $PY_EXTRA_LIBS -lm"
-		smart_try_dir=$PY_LIB_DIR
-		FR_SMART_CHECK_LIB(python${PY_SYS_VERSION}, Py_Initialize)
-		LIBS=$old_LIBS
-
-		eval t=\${ac_cv_lib_${sm_lib_safe}_${sm_func_safe}}
-		if test "x$t" = "xyes"; then
-			mod_ldflags="$PY_LIB_LOC $PY_EXTRA_LIBS $SMART_LIBS -lm"
-			targetname=modname
-		else
-			FR_SMART_CHECK_LIB(python${PY_SYS_VERSION}m, Py_Initialize)
-			eval t=\${ac_cv_lib_${sm_lib_safe}_${sm_func_safe}}
-			if test "x$t" = "xyes"; then
-				mod_ldflags="$PY_LIB_LOC $PY_EXTRA_LIBS $SMART_LIBS -lm"
-				targetname=modname
-			else
-				targetname=
-				fail="$fail libpython$PY_SYS_VERSION"
-			fi
-		fi
+		targetname="rlm_python3"
 	fi
-
-	AC_CHECK_FUNCS([dl_iterate_phdr])
 else
 	targetname=
 	echo \*\*\* module modname is disabled.
diff --git a/src/modules/rlm_python3/rlm_python3.c b/src/modules/rlm_python3/rlm_python3.c
index 06187e4ffa..8e893a0eaa 100644
--- a/src/modules/rlm_python3/rlm_python3.c
+++ b/src/modules/rlm_python3/rlm_python3.c
@@ -67,8 +67,10 @@ static CONF_PARSER module_config[] = {
 	A(preacct)
 	A(accounting)
 	A(checksimul)
+#ifdef WITH_PROXY
 	A(pre_proxy)
 	A(post_proxy)
+#endif
 	A(post_auth)
 #ifdef WITH_COA
 	A(recv_coa)
@@ -98,7 +100,9 @@ static struct {
 	A(L_AUTH)
 	A(L_INFO)
 	A(L_ERR)
+#ifdef WITH_PROXY
 	A(L_PROXY)
+#endif
 	A(L_ACCT)
 	A(L_DBG_WARN)
 	A(L_DBG_ERR)
@@ -510,6 +514,7 @@ static rlm_rcode_t do_python_single(REQUEST *request, PyObject *pFunc, char cons
 			goto finish;
 		}
 
+#ifdef WITH_PROXY
 		/* fill proxy vps */
 		if (request->proxy) {
 			if (!mod_populate_vps(pArgs, 4, request->proxy->vps)) {
@@ -517,10 +522,13 @@ static rlm_rcode_t do_python_single(REQUEST *request, PyObject *pFunc, char cons
 				ret = RLM_MODULE_FAIL;
 				goto finish;
 			}
-		} else {
+		} else
+#endif
+		{
 			mod_populate_vps(pArgs, 4, NULL);
 		}
 
+#ifdef WITH_PROXY
 		/* fill proxy_reply vps */
 		if (request->proxy_reply) {
 			if (!mod_populate_vps(pArgs, 5, request->proxy_reply->vps)) {
@@ -528,7 +536,9 @@ static rlm_rcode_t do_python_single(REQUEST *request, PyObject *pFunc, char cons
 				ret = RLM_MODULE_FAIL;
 				goto finish;
 			}
-		} else {
+		} else
+#endif
+		{
 			mod_populate_vps(pArgs, 5, NULL);
 		}
 
@@ -550,9 +560,14 @@ static rlm_rcode_t do_python_single(REQUEST *request, PyObject *pFunc, char cons
 		    PyDict_SetItemString(pDictInput, "request", PyTuple_GET_ITEM(pArgs, 0)) ||
 		    PyDict_SetItemString(pDictInput, "reply", PyTuple_GET_ITEM(pArgs, 1)) ||
 		    PyDict_SetItemString(pDictInput, "config", PyTuple_GET_ITEM(pArgs, 2)) ||
-		    PyDict_SetItemString(pDictInput, "session-state", PyTuple_GET_ITEM(pArgs, 3)) ||
+		    PyDict_SetItemString(pDictInput, "session-state", PyTuple_GET_ITEM(pArgs, 3))
+#ifdef WITH_PROXY
+		    ||
 		    PyDict_SetItemString(pDictInput, "proxy-request", PyTuple_GET_ITEM(pArgs, 4)) ||
-		    PyDict_SetItemString(pDictInput, "proxy-reply", PyTuple_GET_ITEM(pArgs, 5))) {
+		    PyDict_SetItemString(pDictInput, "proxy-reply", PyTuple_GET_ITEM(pArgs, 5))
+#endif
+		    ) {
+
 			ERROR("%s:%d, %s - PyDict_SetItemString failed", __func__, __LINE__, funcname);
 			ret = RLM_MODULE_FAIL;
 			goto finish;
@@ -819,8 +834,10 @@ MOD_FUNC(authorize)
 MOD_FUNC(preacct)
 MOD_FUNC(accounting)
 MOD_FUNC(checksimul)
+#ifdef WITH_PROXY
 MOD_FUNC(pre_proxy)
 MOD_FUNC(post_proxy)
+#endif
 MOD_FUNC(post_auth)
 #ifdef WITH_COA
 MOD_FUNC(recv_coa)
@@ -1102,7 +1119,7 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
 		python_dlhandle = dlopen_libpython(RTLD_NOW | RTLD_GLOBAL);
 		if (!python_dlhandle) WARN("Failed loading libpython symbols into global symbol table");
 
-#if PY_VERSION_HEX > 0x03050000
+#if PY_VERSION_HEX >= 0x03050000
 		{
 			wchar_t  *name;
 
@@ -1110,13 +1127,6 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
 			Py_SetProgramName(name);		/* The value of argv[0] as a wide char string */
 			PyMem_RawFree(name);
 		}
-#elif PY_VERSION_HEX > 0x0300000
-		{
-			wchar_t *name;
-
-			MEM(name = _Py_char2wchar(main_config.name, NULL));
-			Py_SetProgramName(inst->wide_name);		/* The value of argv[0] as a wide char string */
-		}
 #else
 		{
 			char *name;
@@ -1163,37 +1173,34 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
 		 *	the lifetime of the module.
 		 */
 		if (inst->python_path) {
+			char *p, *path;
+			PyObject *sys = PyImport_ImportModule("sys");
+			PyObject *sys_path = PyObject_GetAttrString(sys, "path");
+
+			memcpy(&p, &inst->python_path, sizeof(path));
+
+			for (path = strtok(p, ":"); path != NULL; path = strtok(NULL, ":")) {
 #if PY_VERSION_HEX > 0x03050000
-			{
-				wchar_t *path;
-				PyObject* sys = PyImport_ImportModule("sys");
-				PyObject* sys_path = PyObject_GetAttrString(sys,"path");
-
-				MEM(path = Py_DecodeLocale(inst->python_path, NULL));
-				PyList_Append(sys_path, PyUnicode_FromWideChar(path,-1));				
-				PyObject_SetAttrString(sys,"path",sys_path);
-				PyMem_RawFree(path);
-			}
+				wchar_t *py_path;
+
+				MEM(py_path = Py_DecodeLocale(path, NULL));
+				PyList_Append(sys_path, PyUnicode_FromWideChar(py_path, -1));
+				PyMem_RawFree(py_path);
 #elif PY_VERSION_HEX > 0x03000000
-			{
-				wchar_t *path;
-				PyObject* sys = PyImport_ImportModule("sys");
-				PyObject* sys_path = PyObject_GetAttrString(sys,"path");
-
-				MEM(path = _Py_char2wchar(inst->python_path, NULL));
-				PyList_Append(sys_path, PyUnicode_FromWideChar(path,-1));				
-				PyObject_SetAttrString(sys,"path",sys_path);
-			}
-#else
-			{
-				char *path;
+				wchar_t *py_path;
 
-				memcpy(&path, &inst->python_path, sizeof(path));
-				Py_SetPath(path);
-			}
+				MEM(py_path = _Py_char2wchar(path, NULL));
+				PyList_Append(sys_path, PyUnicode_FromWideChar(py_path, -1));
+				PyMem_RawFree(py_path);
+#else
+				PyList_Append(sys_path, PyLong_FromString(path));
 #endif
-		}
+			}
 
+			PyObject_SetAttrString(sys, "path", sys_path);
+			Py_DecRef(sys);
+			Py_DecRef(sys_path);
+		}
 	} else {
 		inst->module = main_module;
 		Py_IncRef(inst->module);
@@ -1220,7 +1227,7 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
 static int mod_instantiate(CONF_SECTION *conf, void *instance)
 {
 	rlm_python_t	*inst = instance;
-	int		code = 0;
+	int		code = RLM_MODULE_OK;
 
 	inst->name = cf_section_name2(conf);
 	if (!inst->name) inst->name = cf_section_name1(conf);
@@ -1245,8 +1252,10 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
 	PYTHON_FUNC_LOAD(preacct);
 	PYTHON_FUNC_LOAD(accounting);
 	PYTHON_FUNC_LOAD(checksimul);
+#ifdef WITH_PROXY
 	PYTHON_FUNC_LOAD(pre_proxy);
 	PYTHON_FUNC_LOAD(post_proxy);
+#endif
 	PYTHON_FUNC_LOAD(post_auth);
 #ifdef WITH_COA
 	PYTHON_FUNC_LOAD(recv_coa);
@@ -1257,12 +1266,14 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
 	/*
 	 *	Call the instantiate function.
 	 */
-	code = do_python_single(NULL, inst->instantiate.function, "instantiate", inst->pass_all_vps, inst->pass_all_vps_dict);
-	if (code < 0) {
-	error:
-		python_error_log();	/* Needs valid thread with GIL */
-		PyEval_SaveThread();
-		return -1;
+	if (inst->instantiate.function) {
+		code = do_python_single(NULL, inst->instantiate.function, "instantiate", inst->pass_all_vps, inst->pass_all_vps_dict);
+		if (code < 0) {
+		error:
+			python_error_log();	/* Needs valid thread with GIL */
+			PyEval_SaveThread();
+			return -1;
+		}
 	}
 	PyEval_SaveThread();
 
@@ -1272,22 +1283,31 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
 static int mod_detach(void *instance)
 {
 	rlm_python_t *inst = instance;
-	int	     ret;
+	int	     ret = RLM_MODULE_OK;
 
 	/*
 	 *	Call module destructor
 	 */
 	PyEval_RestoreThread(inst->sub_interpreter);
 
-	ret = do_python_single(NULL, inst->detach.function, "detach", inst->pass_all_vps, inst->pass_all_vps_dict);
+	if (inst->detach.function) ret = do_python_single(NULL, inst->detach.function, "detach", inst->pass_all_vps, inst->pass_all_vps_dict);
 
 #define PYTHON_FUNC_DESTROY(_x) python_function_destroy(&inst->_x)
 	PYTHON_FUNC_DESTROY(instantiate);
-	PYTHON_FUNC_DESTROY(authorize);
 	PYTHON_FUNC_DESTROY(authenticate);
+	PYTHON_FUNC_DESTROY(authorize);
 	PYTHON_FUNC_DESTROY(preacct);
 	PYTHON_FUNC_DESTROY(accounting);
 	PYTHON_FUNC_DESTROY(checksimul);
+#ifdef WITH_PROXY
+	PYTHON_FUNC_DESTROY(pre_proxy);
+	PYTHON_FUNC_DESTROY(post_proxy);
+#endif
+	PYTHON_FUNC_DESTROY(post_auth);
+#ifdef WITH_COA
+	PYTHON_FUNC_DESTROY(recv_coa);
+	PYTHON_FUNC_DESTROY(send_coa);
+#endif
 	PYTHON_FUNC_DESTROY(detach);
 
 	Py_DecRef(inst->pythonconf_dict);
@@ -1313,14 +1333,8 @@ static int mod_detach(void *instance)
 		PyThreadState_Swap(main_interpreter); /* Swap to the main thread */
 		Py_Finalize();
 		dlclose(python_dlhandle);
-
-#if PY_VERSION_HEX > 0x03050000
-		//if (inst->wide_name) PyMem_RawFree(inst->wide_name);
-		//if (inst->wide_path) PyMem_RawFree(inst->wide_path);
-#endif
 	}
 
-
 	return ret;
 }
 
@@ -1348,8 +1362,10 @@ module_t rlm_python3 = {
 		[MOD_PREACCT]		= mod_preacct,
 		[MOD_ACCOUNTING]	= mod_accounting,
 		[MOD_SESSION]		= mod_checksimul,
+#ifdef WITH_PROXY
 		[MOD_PRE_PROXY]		= mod_pre_proxy,
 		[MOD_POST_PROXY]	= mod_post_proxy,
+#endif
 		[MOD_POST_AUTH]		= mod_post_auth,
 #ifdef WITH_COA
 		[MOD_RECV_COA]		= mod_recv_coa,
