FreeRADIUS 3.0.12, Ubuntu 16.04 - Python module is unable to load
Hi, I am trying to develop a python module and hook it into FreeRADIUS. The module supposes to query LDAP for some specific parameters and allows or rejects user's access based on the result. For some reasons, whenever I try to import ldap3 module ( http://ldap3.readthedocs.io), I encounter this issue: Python version: 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] python_function_load - Module 'session_limit' not found <class 'ldap3.core.exceptions.LDAPSSLNotSupportedError'> (SSL not supported in this Python interpreter) python_function_load - Failed to import python function 'session_limit.instantiate' /etc/freeradius/mods-enabled/python[9]: Instantiation failed for module "python" Remove the import in the module, it works fine. Is there anything I could do to solve this? With the same script I can run using normal python environment (the script has the import ldap3). Below is the debug with import ldap3 root@rad01:/etc/freeradius/mods-config/python# freeradius -X FreeRADIUS Version 3.0.12 Copyright (C) 1999-2016 The FreeRADIUS server project and contributors There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE You may redistribute copies of FreeRADIUS under the terms of the GNU General Public License For more information about these matters, see the file named COPYRIGHT Starting - reading configuration files ... including dictionary file /usr/share/freeradius/dictionary including dictionary file /usr/share/freeradius/dictionary.dhcp including dictionary file /usr/share/freeradius/dictionary.vqp including dictionary file /etc/freeradius/dictionary including configuration file /etc/freeradius/radiusd.conf including configuration file /etc/freeradius/proxy.conf including configuration file /etc/freeradius/clients.conf including files in directory /etc/freeradius/mods-enabled/ including configuration file /etc/freeradius/mods-enabled/detail including configuration file /etc/freeradius/mods-enabled/echo including configuration file /etc/freeradius/mods-enabled/cache_eap including configuration file /etc/freeradius/mods-enabled/sql including configuration file /etc/freeradius/mods-config/sql/main/mysql/queries.conf including configuration file /etc/freeradius/mods-enabled/digest including configuration file /etc/freeradius/mods-enabled/attr_filter including configuration file /etc/freeradius/mods-enabled/linelog including configuration file /etc/freeradius/mods-enabled/unpack including configuration file /etc/freeradius/mods-enabled/logintime including configuration file /etc/freeradius/mods-enabled/replicate including configuration file /etc/freeradius/mods-enabled/mschap including configuration file /etc/freeradius/mods-enabled/python including configuration file /etc/freeradius/mods-enabled/soh including configuration file /etc/freeradius/mods-enabled/radutmp including configuration file /etc/freeradius/mods-enabled/chap including configuration file /etc/freeradius/mods-enabled/always including configuration file /etc/freeradius/mods-enabled/eap including configuration file /etc/freeradius/mods-enabled/detail.log including configuration file /etc/freeradius/mods-enabled/pap including configuration file /etc/freeradius/mods-enabled/preprocess including configuration file /etc/freeradius/mods-enabled/utf8 including configuration file /etc/freeradius/mods-enabled/sradutmp including configuration file /etc/freeradius/mods-enabled/expiration including configuration file /etc/freeradius/mods-enabled/files including configuration file /etc/freeradius/mods-enabled/ntlm_auth including configuration file /etc/freeradius/mods-enabled/date including configuration file /etc/freeradius/mods-enabled/exec including configuration file /etc/freeradius/mods-enabled/ldap including configuration file /etc/freeradius/mods-enabled/realm including configuration file /etc/freeradius/mods-enabled/dynamic_clients including configuration file /etc/freeradius/mods-enabled/expr including configuration file /etc/freeradius/mods-enabled/unix including configuration file /etc/freeradius/mods-enabled/passwd including files in directory /etc/freeradius/policy.d/ including configuration file /etc/freeradius/policy.d/operator-name including configuration file /etc/freeradius/policy.d/filter including configuration file /etc/freeradius/policy.d/control including configuration file /etc/freeradius/policy.d/abfab-tr including configuration file /etc/freeradius/policy.d/canonicalization including configuration file /etc/freeradius/policy.d/eap including configuration file /etc/freeradius/policy.d/accounting including configuration file /etc/freeradius/policy.d/cui including configuration file /etc/freeradius/policy.d/debug including configuration file /etc/freeradius/policy.d/moonshot-targeted-ids including configuration file /etc/freeradius/policy.d/dhcp including files in directory /etc/freeradius/sites-enabled/ including configuration file /etc/freeradius/sites-enabled/control-socket including configuration file /etc/freeradius/sites-enabled/default main { security { user = "freerad" group = "freerad" allow_core_dumps = no } name = "freeradius" prefix = "/usr" localstatedir = "/var" logdir = "/var/log/freeradius" run_dir = "/var/run/freeradius" } main { name = "freeradius" prefix = "/usr" localstatedir = "/var" sbindir = "/usr/sbin" logdir = "/var/log/freeradius" run_dir = "/var/run/freeradius" libdir = "/usr/lib/freeradius" radacctdir = "/var/log/freeradius/radacct" hostname_lookups = no max_request_time = 30 cleanup_delay = 5 max_requests = 16384 pidfile = "/var/run/freeradius/freeradius.pid" checkrad = "/usr/sbin/checkrad" debug_level = 0 proxy_requests = yes log { stripped_names = no auth = yes auth_badpass = yes auth_goodpass = no msg_badpass = "Password is wrong" colourise = yes msg_denied = "You are already logged in - access denied" } resources { } security { max_attributes = 200 reject_delay = 1.000000 status_server = yes } } radiusd: #### Loading Realms and Home Servers #### proxy server { retry_delay = 5 retry_count = 3 default_fallback = no dead_time = 120 wake_all_if_all_dead = no } home_server localhost { ipaddr = 127.0.0.1 port = 1812 type = "auth" secret = <<< secret >>> response_window = 20.000000 response_timeouts = 1 max_outstanding = 65536 zombie_period = 40 status_check = "status-server" ping_interval = 30 check_interval = 30 check_timeout = 4 num_answers_to_alive = 3 revive_interval = 120 limit { max_connections = 16 max_requests = 0 lifetime = 0 idle_timeout = 0 } coa { irt = 2 mrt = 16 mrc = 5 mrd = 30 } } home_server_pool my_auth_failover { type = fail-over home_server = localhost } realm starhub.com { auth_pool = my_auth_failover } realm LOCAL { } realm ~(.*\.)*webspeed\.com.sg$ { auth_pool = my_auth_failover } realm ~(.*\.)*starhub\.com$ { auth_pool = my_auth_failover } radiusd: #### Loading Clients #### client localhost { ipaddr = 127.0.0.1 require_message_authenticator = no secret = <<< secret >>> nas_type = "other" proto = "*" limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } client localhost_ipv6 { ipv6addr = ::1 require_message_authenticator = no secret = <<< secret >>> limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } client 192.168.254.1 { ipaddr = 192.168.254.1 require_message_authenticator = no secret = <<< secret >>> limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } client private-network-2 { ipaddr = 61.0.240.0/24 require_message_authenticator = no secret = <<< secret >>> limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } Debugger not attached # Creating Auth-Type = mschap # Creating Auth-Type = digest # Creating Auth-Type = eap # Creating Auth-Type = PAP # Creating Auth-Type = CHAP # Creating Auth-Type = MS-CHAP radiusd: #### Instantiating modules #### modules { # Loaded module rlm_detail # Loading module "detail" from file /etc/freeradius/mods-enabled/detail detail { filename = "/var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d" header = "%t" permissions = 384 locking = no escape_filenames = no log_packet_header = no } # Loaded module rlm_exec # Loading module "echo" from file /etc/freeradius/mods-enabled/echo exec echo { wait = yes program = "/bin/echo %{User-Name}" input_pairs = "request" output_pairs = "reply" shell_escape = yes } # Loaded module rlm_cache # Loading module "cache_eap" from file /etc/freeradius/mods-enabled/cache_eap cache cache_eap { driver = "rlm_cache_rbtree" key = "%{%{control:State}:-%{%{reply:State}:-%{State}}}" ttl = 15 max_entries = 0 epoch = 0 add_stats = no } # Loaded module rlm_sql # Loading module "sql" from file /etc/freeradius/mods-enabled/sql sql { driver = "rlm_sql_mysql" server = "localhost" port = 3306 login = "radius" password = <<< secret >>> radius_db = "radius" read_groups = yes read_profiles = yes read_clients = no delete_stale_sessions = yes sql_user_name = "%{User-Name}" logfile = "/var/log/freeradius/sqllog.sql" default_user_profile = "" client_query = "SELECT id, nasname, shortname, type, secret, server FROM nas" authorize_check_query = "SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id" authorize_reply_query = "SELECT id, username, attribute, value, op FROM radreply WHERE username = '%{SQL-User-Name}' ORDER BY id" authorize_group_check_query = "SELECT id, groupname, attribute, Value, op FROM radgroupcheck WHERE groupname = '%{SQL-Group}' ORDER BY id" authorize_group_reply_query = "SELECT id, groupname, attribute, value, op FROM radgroupreply WHERE groupname = '%{SQL-Group}' ORDER BY id" group_membership_query = "SELECT groupname FROM radusergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority" simul_count_query = "SELECT COUNT(*) FROM radacct WHERE username = '%{SQL-User-Name}' AND acctstoptime IS NULL" simul_verify_query = "SELECT radacctid, acctsessionid, username, nasipaddress, nasportid, framedipaddress, callingstationid, framedprotocol FROM radacct WHERE username = '%{SQL-User-Name}' AND acctstoptime IS NULL" safe_characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /" query_timeout = 5 accounting { reference = "%{tolower:type.%{Acct-Status-Type}.query}" type { accounting-on { query = "UPDATE radacct SET acctstoptime = FROM_UNIXTIME(%{integer:Event-Timestamp}), acctsessiontime = '%{integer:Event-Timestamp}' - UNIX_TIMESTAMP(acctstarttime), acctterminatecause = '%{%{Acct-Terminate-Cause}:-NAS-Reboot}' WHERE acctstoptime IS NULL AND nasipaddress = '%{NAS-IP-Address}' AND acctstarttime <= FROM_UNIXTIME(%{integer:Event-Timestamp})" } accounting-off { query = "UPDATE radacct SET acctstoptime = FROM_UNIXTIME(%{integer:Event-Timestamp}), acctsessiontime = '%{integer:Event-Timestamp}' - UNIX_TIMESTAMP(acctstarttime), acctterminatecause = '%{%{Acct-Terminate-Cause}:-NAS-Reboot}' WHERE acctstoptime IS NULL AND nasipaddress = '%{NAS-IP-Address}' AND acctstarttime <= FROM_UNIXTIME(%{integer:Event-Timestamp})" } start { query = "INSERT INTO radacct (acctsessionid, acctuniqueid, username, realm, nasipaddress, nasportid, nasporttype, acctstarttime, acctupdatetime, acctstoptime, acctsessiontime, acctauthentic, connectinfo_start, connectinfo_stop, acctinputoctets, acctoutputoctets, calledstationid, callingstationid, acctterminatecause, servicetype, framedprotocol, framedipaddress) VALUES ('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{%{NAS-Port-ID}:-%{NAS-Port}}', '%{NAS-Port-Type}', FROM_UNIXTIME(%{integer:Event-Timestamp}), FROM_UNIXTIME(%{integer:Event-Timestamp}), NULL, '0', '%{Acct-Authentic}', '%{Connect-Info}', '', '0', '0', '%{Called-Station-Id}', '%{Calling-Station-Id}', '', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}')" } interim-update { query = "UPDATE radacct SET acctupdatetime = (@acctupdatetime_old:=acctupdatetime), acctupdatetime = FROM_UNIXTIME(%{integer:Event-Timestamp}), acctinterval = %{integer:Event-Timestamp} - UNIX_TIMESTAMP(@acctupdatetime_old), framedipaddress = '%{Framed-IP-Address}', acctsessiontime = %{%{Acct-Session-Time}:-NULL}, acctinputoctets = '%{%{Acct-Input-Gigawords}:-0}' << 32 | '%{%{Acct-Input-Octets}:-0}', acctoutputoctets = '%{%{Acct-Output-Gigawords}:-0}' << 32 | '%{%{Acct-Output-Octets}:-0}' WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}'" } stop { query = "UPDATE radacct SET acctstoptime = FROM_UNIXTIME(%{integer:Event-Timestamp}), acctsessiontime = %{%{Acct-Session-Time}:-NULL}, acctinputoctets = '%{%{Acct-Input-Gigawords}:-0}' << 32 | '%{%{Acct-Input-Octets}:-0}', acctoutputoctets = '%{%{Acct-Output-Gigawords}:-0}' << 32 | '%{%{Acct-Output-Octets}:-0}', acctterminatecause = '%{Acct-Terminate-Cause}', connectinfo_stop = '%{Connect-Info}' WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}'" } } } post-auth { reference = ".query" query = "INSERT INTO radpostauth (username, pass, reply, authdate) VALUES ( '%{SQL-User-Name}', '%{%{User-Password}:-%{Chap-Password}}', '%{reply:Packet-Type}', '%S')" } } rlm_sql (sql): Driver rlm_sql_mysql (module rlm_sql_mysql) loaded and linked Creating attribute SQL-Group # Loaded module rlm_digest # Loading module "digest" from file /etc/freeradius/mods-enabled/digest # Loaded module rlm_attr_filter # Loading module "attr_filter.post-proxy" from file /etc/freeradius/mods-enabled/attr_filter attr_filter attr_filter.post-proxy { filename = "/etc/freeradius/mods-config/attr_filter/post-proxy" key = "%{Realm}" relaxed = no } # Loading module "attr_filter.pre-proxy" from file /etc/freeradius/mods-enabled/attr_filter attr_filter attr_filter.pre-proxy { filename = "/etc/freeradius/mods-config/attr_filter/pre-proxy" key = "%{Realm}" relaxed = no } # Loading module "attr_filter.access_reject" from file /etc/freeradius/mods-enabled/attr_filter attr_filter attr_filter.access_reject { filename = "/etc/freeradius/mods-config/attr_filter/access_reject" key = "%{User-Name}" relaxed = no } # Loading module "attr_filter.access_challenge" from file /etc/freeradius/mods-enabled/attr_filter attr_filter attr_filter.access_challenge { filename = "/etc/freeradius/mods-config/attr_filter/access_challenge" key = "%{User-Name}" relaxed = no } # Loading module "attr_filter.accounting_response" from file /etc/freeradius/mods-enabled/attr_filter attr_filter attr_filter.accounting_response { filename = "/etc/freeradius/mods-config/attr_filter/accounting_response" key = "%{User-Name}" relaxed = no } # Loaded module rlm_linelog # Loading module "linelog" from file /etc/freeradius/mods-enabled/linelog linelog { filename = "/var/log/freeradius/linelog" escape_filenames = no syslog_severity = "info" permissions = 384 format = "This is a log message for %{User-Name}" reference = "messages.%{%{reply:Packet-Type}:-default}" } # Loading module "log_accounting" from file /etc/freeradius/mods-enabled/linelog linelog log_accounting { filename = "/var/log/freeradius/linelog-accounting" escape_filenames = no syslog_severity = "info" permissions = 384 format = "" reference = "Accounting-Request.%{%{Acct-Status-Type}:-unknown}" } # Loaded module rlm_unpack # Loading module "unpack" from file /etc/freeradius/mods-enabled/unpack # Loaded module rlm_logintime # Loading module "logintime" from file /etc/freeradius/mods-enabled/logintime logintime { minimum_timeout = 60 } # Loaded module rlm_replicate # Loading module "replicate" from file /etc/freeradius/mods-enabled/replicate # Loaded module rlm_mschap # Loading module "mschap" from file /etc/freeradius/mods-enabled/mschap mschap { use_mppe = yes require_encryption = no require_strong = no with_ntdomain_hack = yes passchange { } allow_retry = yes } # Loaded module rlm_python # Loading module "python" from file /etc/freeradius/mods-enabled/python python { mod_instantiate = "session_limit" func_instantiate = "instantiate" mod_authorize = "session_limit" func_authorize = "authorize" mod_authenticate = "session_limit" func_authenticate = "authenticate" mod_preacct = "session_limit" func_preacct = "preacct" mod_accounting = "session_limit" func_accounting = "accounting" mod_checksimul = "session_limit" func_checksimul = "checksimul" mod_pre_proxy = "session_limit" func_pre_proxy = "pre_proxy" mod_post_proxy = "session_limit" func_post_proxy = "post_proxy" mod_post_auth = "session_limit" func_post_auth = "post_auth" mod_recv_coa = "session_limit" func_recv_coa = "recv_coa" mod_send_coa = "session_limit" func_send_coa = "send_coa" mod_detach = "session_limit" func_detach = "instantiate" python_path = "/etc/freeradius/mods-config/python:/usr/lib/python2.7/dist-packages/:/usr/lib/python2.7/" cext_compat = yes } # Loaded module rlm_soh # Loading module "soh" from file /etc/freeradius/mods-enabled/soh soh { dhcp = yes } # Loaded module rlm_radutmp # Loading module "radutmp" from file /etc/freeradius/mods-enabled/radutmp radutmp { filename = "/var/log/freeradius/radutmp" username = "%{User-Name}" case_sensitive = yes check_with_nas = yes permissions = 384 caller_id = yes } # Loaded module rlm_chap # Loading module "chap" from file /etc/freeradius/mods-enabled/chap # Loaded module rlm_always # Loading module "reject" from file /etc/freeradius/mods-enabled/always always reject { rcode = "reject" simulcount = 0 mpp = no } # Loading module "fail" from file /etc/freeradius/mods-enabled/always always fail { rcode = "fail" simulcount = 0 mpp = no } # Loading module "ok" from file /etc/freeradius/mods-enabled/always always ok { rcode = "ok" simulcount = 0 mpp = no } # Loading module "handled" from file /etc/freeradius/mods-enabled/always always handled { rcode = "handled" simulcount = 0 mpp = no } # Loading module "invalid" from file /etc/freeradius/mods-enabled/always always invalid { rcode = "invalid" simulcount = 0 mpp = no } # Loading module "userlock" from file /etc/freeradius/mods-enabled/always always userlock { rcode = "userlock" simulcount = 0 mpp = no } # Loading module "notfound" from file /etc/freeradius/mods-enabled/always always notfound { rcode = "notfound" simulcount = 0 mpp = no } # Loading module "noop" from file /etc/freeradius/mods-enabled/always always noop { rcode = "noop" simulcount = 0 mpp = no } # Loading module "updated" from file /etc/freeradius/mods-enabled/always always updated { rcode = "updated" simulcount = 0 mpp = no } # Loaded module rlm_eap # Loading module "eap" from file /etc/freeradius/mods-enabled/eap eap { default_eap_type = "md5" timer_expire = 60 ignore_unknown_eap_types = no cisco_accounting_username_bug = no max_sessions = 16384 } # Loading module "auth_log" from file /etc/freeradius/mods-enabled/detail.log detail auth_log { filename = "/var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/auth-detail-%Y%m%d" header = "%t" permissions = 384 locking = no escape_filenames = no log_packet_header = no } # Loading module "reply_log" from file /etc/freeradius/mods-enabled/detail.log detail reply_log { filename = "/var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/reply-detail-%Y%m%d" header = "%t" permissions = 384 locking = no escape_filenames = no log_packet_header = no } # Loading module "pre_proxy_log" from file /etc/freeradius/mods-enabled/detail.log detail pre_proxy_log { filename = "/var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/pre-proxy-detail-%Y%m%d" header = "%t" permissions = 384 locking = no escape_filenames = no log_packet_header = no } # Loading module "post_proxy_log" from file /etc/freeradius/mods-enabled/detail.log detail post_proxy_log { filename = "/var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/post-proxy-detail-%Y%m%d" header = "%t" permissions = 384 locking = no escape_filenames = no log_packet_header = no } # Loaded module rlm_pap # Loading module "pap" from file /etc/freeradius/mods-enabled/pap pap { normalise = yes } # Loaded module rlm_preprocess # Loading module "preprocess" from file /etc/freeradius/mods-enabled/preprocess preprocess { huntgroups = "/etc/freeradius/mods-config/preprocess/huntgroups" hints = "/etc/freeradius/mods-config/preprocess/hints" with_ascend_hack = no ascend_channels_per_line = 23 with_ntdomain_hack = no with_specialix_jetstream_hack = no with_cisco_vsa_hack = no with_alvarion_vsa_hack = no } # Loaded module rlm_utf8 # Loading module "utf8" from file /etc/freeradius/mods-enabled/utf8 # Loading module "sradutmp" from file /etc/freeradius/mods-enabled/sradutmp radutmp sradutmp { filename = "/var/log/freeradius/sradutmp" username = "%{User-Name}" case_sensitive = yes check_with_nas = yes permissions = 420 caller_id = no } # Loaded module rlm_expiration # Loading module "expiration" from file /etc/freeradius/mods-enabled/expiration # Loaded module rlm_files # Loading module "files" from file /etc/freeradius/mods-enabled/files files { filename = "/etc/freeradius/mods-config/files/authorize" acctusersfile = "/etc/freeradius/mods-config/files/accounting" preproxy_usersfile = "/etc/freeradius/mods-config/files/pre-proxy" } # Loading module "ntlm_auth" from file /etc/freeradius/mods-enabled/ntlm_auth exec ntlm_auth { wait = yes program = "/path/to/ntlm_auth --request-nt-key --domain=MYDOMAIN --username=%{mschap:User-Name} --password=%{User-Password}" shell_escape = yes } # Loaded module rlm_date # Loading module "date" from file /etc/freeradius/mods-enabled/date date { format = "%b %e %Y %H:%M:%S %Z" } # Loading module "exec" from file /etc/freeradius/mods-enabled/exec exec { wait = no input_pairs = "request" shell_escape = yes timeout = 10 } # Loaded module rlm_ldap # Loading module "ldap" from file /etc/freeradius/mods-enabled/ldap ldap { server = "192.168.254.110" port = 389 identity = "cn=admin,dc=starhub,dc=com" password = <<< secret >>> sasl { } user { scope = "sub" access_positive = yes sasl { } } group { filter = "(objectClass=posixGroup)" scope = "sub" name_attribute = "cn" membership_attribute = "memberOf" cacheable_name = no cacheable_dn = no } client { filter = "(objectClass=radiusClient)" scope = "sub" base_dn = "ou=Adsl-User,o=webspeed.com.sg,dc=starhub,dc=com" } profile { } options { ldap_debug = 40 chase_referrals = yes rebind = yes net_timeout = 1 res_timeout = 10 srv_timelimit = 3 idle = 60 probes = 3 interval = 3 } tls { start_tls = no } } Creating attribute LDAP-Group # Loaded module rlm_realm # Loading module "IPASS" from file /etc/freeradius/mods-enabled/realm realm IPASS { format = "prefix" delimiter = "/" ignore_default = no ignore_null = no } # Loading module "suffix" from file /etc/freeradius/mods-enabled/realm realm suffix { format = "suffix" delimiter = "@" ignore_default = no ignore_null = no } # Loading module "realmpercent" from file /etc/freeradius/mods-enabled/realm realm realmpercent { format = "suffix" delimiter = "%" ignore_default = no ignore_null = no } # Loading module "ntdomain" from file /etc/freeradius/mods-enabled/realm realm ntdomain { format = "prefix" delimiter = "\\" ignore_default = no ignore_null = no } # Loaded module rlm_dynamic_clients # Loading module "dynamic_clients" from file /etc/freeradius/mods-enabled/dynamic_clients # Loaded module rlm_expr # Loading module "expr" from file /etc/freeradius/mods-enabled/expr expr { safe_characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /äéöüàâæçèéêëîïôœùûüaÿÄÉÖÜßÀÂÆÇÈÉÊËÎÏÔŒÙÛÜŸ" } # Loaded module rlm_unix # Loading module "unix" from file /etc/freeradius/mods-enabled/unix unix { radwtmp = "/var/log/freeradius/radwtmp" } Creating attribute Unix-Group # Loaded module rlm_passwd # Loading module "etc_passwd" from file /etc/freeradius/mods-enabled/passwd passwd etc_passwd { filename = "/etc/passwd" format = "*User-Name:Crypt-Password:" delimiter = ":" ignore_nislike = no ignore_empty = yes allow_multiple_keys = no hash_size = 100 } instantiate { } # Instantiating module "detail" from file /etc/freeradius/mods-enabled/detail # Instantiating module "cache_eap" from file /etc/freeradius/mods-enabled/cache_eap rlm_cache (cache_eap): Driver rlm_cache_rbtree (module rlm_cache_rbtree) loaded and linked # Instantiating module "sql" from file /etc/freeradius/mods-enabled/sql rlm_sql_mysql: libmysql version: 5.7.18 mysql { tls { } warnings = "auto" } rlm_sql (sql): Attempting to connect to database "radius" rlm_sql (sql): Initialising connection pool pool { start = 5 min = 3 max = 32 spare = 10 uses = 0 lifetime = 0 cleanup_interval = 30 idle_timeout = 60 retry_delay = 30 spread = no } rlm_sql (sql): Opening additional connection (0), 1 of 32 pending slots used rlm_sql_mysql: Starting connect to MySQL server rlm_sql_mysql: Connected to database 'radius' on Localhost via UNIX socket, server version 5.7.18-0ubuntu0.16.04.1, protocol version 10 rlm_sql (sql): Opening additional connection (1), 1 of 31 pending slots used rlm_sql_mysql: Starting connect to MySQL server rlm_sql_mysql: Connected to database 'radius' on Localhost via UNIX socket, server version 5.7.18-0ubuntu0.16.04.1, protocol version 10 rlm_sql (sql): Opening additional connection (2), 1 of 30 pending slots used rlm_sql_mysql: Starting connect to MySQL server rlm_sql_mysql: Connected to database 'radius' on Localhost via UNIX socket, server version 5.7.18-0ubuntu0.16.04.1, protocol version 10 rlm_sql (sql): Opening additional connection (3), 1 of 29 pending slots used rlm_sql_mysql: Starting connect to MySQL server rlm_sql_mysql: Connected to database 'radius' on Localhost via UNIX socket, server version 5.7.18-0ubuntu0.16.04.1, protocol version 10 rlm_sql (sql): Opening additional connection (4), 1 of 28 pending slots used rlm_sql_mysql: Starting connect to MySQL server rlm_sql_mysql: Connected to database 'radius' on Localhost via UNIX socket, server version 5.7.18-0ubuntu0.16.04.1, protocol version 10 # Instantiating module "attr_filter.post-proxy" from file /etc/freeradius/mods-enabled/attr_filter reading pairlist file /etc/freeradius/mods-config/attr_filter/post-proxy # Instantiating module "attr_filter.pre-proxy" from file /etc/freeradius/mods-enabled/attr_filter reading pairlist file /etc/freeradius/mods-config/attr_filter/pre-proxy # Instantiating module "attr_filter.access_reject" from file /etc/freeradius/mods-enabled/attr_filter reading pairlist file /etc/freeradius/mods-config/attr_filter/access_reject [/etc/freeradius/mods-config/attr_filter/access_reject]:11 Check item "FreeRADIUS-Response-Delay" found in filter list for realm "DEFAULT". [/etc/freeradius/mods-config/attr_filter/access_reject]:11 Check item "FreeRADIUS-Response-Delay-USec" found in filter list for realm "DEFAULT". # Instantiating module "attr_filter.access_challenge" from file /etc/freeradius/mods-enabled/attr_filter reading pairlist file /etc/freeradius/mods-config/attr_filter/access_challenge # Instantiating module "attr_filter.accounting_response" from file /etc/freeradius/mods-enabled/attr_filter reading pairlist file /etc/freeradius/mods-config/attr_filter/accounting_response # Instantiating module "linelog" from file /etc/freeradius/mods-enabled/linelog # Instantiating module "log_accounting" from file /etc/freeradius/mods-enabled/linelog # Instantiating module "logintime" from file /etc/freeradius/mods-enabled/logintime # Instantiating module "mschap" from file /etc/freeradius/mods-enabled/mschap rlm_mschap (mschap): using internal authentication # Instantiating module "python" from file /etc/freeradius/mods-enabled/python Python version: 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] python_function_load - Module 'session_limit' not found <class 'ldap3.core.exceptions.LDAPSSLNotSupportedError'> (SSL not supported in this Python interpreter) python_function_load - Failed to import python function 'session_limit.instantiate' /etc/freeradius/mods-enabled/python[9]: Instantiation failed for module "python" root@rad01:/etc/freeradius/mods-config/python#
On 2 Jul 2017, at 17:19, Cuong Nguyen <cuong.nguyenduy@gmail.com> wrote:
Is there anything I could do to solve this? With the same script I can run using normal python environment (the script has the import ldap3).
There's a few possibilities, but the most likely reason is PYTHONPATH being not set correctly. Make sure that in mods-available/python config file has the directories you need. Keep in mind that FreeRADIUS runs as a non-root user, so make sure that you've installed the module to somewhere that the FreeRADIUS user account can read. Have you looked at FreeRADIUS' built in LDAP module by the way? Regards, Adam Bishop gpg: E75B 1F92 6407 DFDF 9F1C BF10 C993 2504 6609 D460 jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. Jisc Services Limited is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under company number 2881024, VAT number GB 197 0632 86. The registered office is: One Castle Park, Tower Hill, Bristol BS2 0JA. T 0203 697 5800.
Thank you, Adam, for replying. First, indeed, I am sure that $PYTHONPATH is set correctly. I can even run the script under 'freerad' user. Let me explain what I try to do: 1. I'd want to limit a number of concurrent sessions a user is allowed. In LDAP, there is an attribute - MaxConnection - to indicate maximum concurrent sessions a user can have 2. Since FreeRADIUS does not keep track of the number of sessions, my script will perform the following - POST-AUTH: For the user, get the number of sessions in MySQL, and get the MaxConnection from LDAP, then compare the two. If there are sessions >= MaxConnection --> Reject - ACCOUTING: If it is Accounting-Start --> Record in MySQL, if Accounting-Interim --> Update in MySQL, if Accounting-Stop --> Delete in MySQL My first attempt is to make sure I can load LDAP module, and I've already got the issue above. Second, I did look at the LDAP module, but have no clue how to implement the logic I describe above. In my debug output above, I *did* include sql for the purpose of testing. In actual deployment, this will not be used (MySQL operations will be done by the script). I even tried this in LDAP module in order to get the MaxConnection, which changes the 'request' list. ldap { # TESTING request:Tmp-String-1 := 'MaxConnection' } And in the script, look for "Tmp-String-1". However, I think it is not ideal. Any suggestion is appreciated. Cuong, On Mon, Jul 3, 2017 at 1:47 AM Adam Bishop <Adam.Bishop@jisc.ac.uk> wrote:
On 2 Jul 2017, at 17:19, Cuong Nguyen <cuong.nguyenduy@gmail.com> wrote:
Is there anything I could do to solve this? With the same script I can run using normal python environment (the script has the import ldap3).
There's a few possibilities, but the most likely reason is PYTHONPATH being not set correctly.
Make sure that in mods-available/python config file has the directories you need.
Keep in mind that FreeRADIUS runs as a non-root user, so make sure that you've installed the module to somewhere that the FreeRADIUS user account can read.
Have you looked at FreeRADIUS' built in LDAP module by the way?
Regards,
Adam Bishop
gpg: E75B 1F92 6407 DFDF 9F1C BF10 C993 2504 6609 D460
jisc.ac.uk
Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800.
Jisc Services Limited is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under company number 2881024, VAT number GB 197 0632 86. The registered office is: One Castle Park, Tower Hill, Bristol BS2 0JA. T 0203 697 5800.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Jul 3, 2017, at 1:52 AM, Cuong Nguyen <cuong.nguyenduy@gmail.com> wrote:
Let me explain what I try to do: 1. I'd want to limit a number of concurrent sessions a user is allowed. In LDAP, there is an attribute - MaxConnection - to indicate maximum concurrent sessions a user can have
OK...
2. Since FreeRADIUS does not keep track of the number of sessions,
Uh... what? FreeRADIUS writes session data to a database. You can query the database from FreeRADIUS. This is even documented with examples in the default configuration.
my script will perform the following - POST-AUTH: For the user, get the number of sessions in MySQL, and get the MaxConnection from LDAP, then compare the two. If there are sessions >= MaxConnection --> Reject
That's threelines of unlang: if ("%{sql:SELECT sessions...}" >= "%{ldap:get maxconnection}") { reject } The only "magic" here is writing the correct SQL select query, and writing the correct LDAP query to get MaxConnection for a user. And those two queries are just normal SQL / LDAP queries. You can write them and test them in an SQL or LDAP tool, and then just copy them to FreeRADIUS. Replace the actual user name with %{User-Name}, and you're good to go.
- ACCOUTING: If it is Accounting-Start --> Record in MySQL, if Accounting-Interim --> Update in MySQL, if Accounting-Stop --> Delete in MySQL
The default SQL module already does this. It's documented as doing this. There are tons of examples available. Why are you re-inventing this?
Second, I did look at the LDAP module, but have no clue how to implement the logic I describe above. In my debug output above, I *did* include sql for the purpose of testing. In actual deployment, this will not be used (MySQL operations will be done by the script).
I even tried this in LDAP module in order to get the MaxConnection, which changes the 'request' list.
ldap { # TESTING request:Tmp-String-1 := 'MaxConnection' }
What made you think that would work? You're just trying random things in random places. And, ignoring all of the available documentation.
Any suggestion is appreciated.
Read the documentation and examples. Read the Wiki. Look for "Simultaneous-Use", which does exactly this... Alan DeKok.
if ("%{sql:SELECT sessions...}" >= "%{ldap:get maxconnection}") { reject } yep - the only 'magic' here is that you have to ensure that the SQL and LDAP modules are correctly configured to talk to the right DB and LDAP and then the SELECT and LDAP queries need to be correctly constructed to get you the unique single values that you want. a LOT of that last part can be done using command line tools....then stick them into the server and check in full debug to see what is actually occurring at that unlang step. FreeRADIUS with unlang is a totally configurable beast. alan On 3 July 2017 at 12:03, Alan DeKok <aland@deployingradius.com> wrote:
On Jul 3, 2017, at 1:52 AM, Cuong Nguyen <cuong.nguyenduy@gmail.com> wrote:
Let me explain what I try to do: 1. I'd want to limit a number of concurrent sessions a user is allowed. In LDAP, there is an attribute - MaxConnection - to indicate maximum concurrent sessions a user can have
OK...
2. Since FreeRADIUS does not keep track of the number of sessions,
Uh... what?
FreeRADIUS writes session data to a database. You can query the database from FreeRADIUS. This is even documented with examples in the default configuration.
my script will perform the following - POST-AUTH: For the user, get the number of sessions in MySQL, and get the MaxConnection from LDAP, then compare the two. If there are sessions >= MaxConnection --> Reject
That's threelines of unlang:
if ("%{sql:SELECT sessions...}" >= "%{ldap:get maxconnection}") { reject }
The only "magic" here is writing the correct SQL select query, and writing the correct LDAP query to get MaxConnection for a user.
And those two queries are just normal SQL / LDAP queries. You can write them and test them in an SQL or LDAP tool, and then just copy them to FreeRADIUS. Replace the actual user name with %{User-Name}, and you're good to go.
- ACCOUTING: If it is Accounting-Start --> Record in MySQL, if Accounting-Interim --> Update in MySQL, if Accounting-Stop --> Delete in MySQL
The default SQL module already does this. It's documented as doing this. There are tons of examples available.
Why are you re-inventing this?
Second, I did look at the LDAP module, but have no clue how to implement the logic I describe above. In my debug output above, I *did* include sql for the purpose of testing. In actual deployment, this will not be used (MySQL operations will be done by the script).
I even tried this in LDAP module in order to get the MaxConnection, which changes the 'request' list.
ldap { # TESTING request:Tmp-String-1 := 'MaxConnection' }
What made you think that would work? You're just trying random things in random places. And, ignoring all of the available documentation.
Any suggestion is appreciated.
Read the documentation and examples. Read the Wiki. Look for "Simultaneous-Use", which does exactly this...
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Thank you all, I poked around with unlang and were able to fulfill my requirement with LDAP and MySQL, as shown below: *- /etc/freeradius/mods-enabled/ldap* ldap { update { .... control:Tmp-Integer-9 := 'MaxConnection' } } *- /etc/freeradius/sites-enabled/default* authorize { ... ldap if ("%{sql:SELECT COUNT(*) FROM radacct WHERE username LIKE '%{%{Stripped-User-Name}:-%{User-Name}}@%%.%%' AND acctstoptime IS NULL}"
= %{control:Tmp-Integer-9}){ reject } }
My intention to use "control:Tmp-Integer-9" is to reduce the number of queries to LDAP. I realized that radacct still keeps records for sessions that have "Accounting Stop", hence "AND acctstoptime IS NULL " is needed. Will play with unlang further to get better idea how it works. *Back to my original question*, is there anything I could do to make python loads ldap3 package successfully? I don't need it for the original purposes, but I may in future. Cheers, Cuong. On Tue, Jul 4, 2017 at 2:30 AM Alan Buxey <alan.buxey@gmail.com> wrote:
if ("%{sql:SELECT sessions...}" >= "%{ldap:get maxconnection}") { reject }
yep - the only 'magic' here is that you have to ensure that the SQL and LDAP modules are correctly configured to talk to the right DB and LDAP and then the SELECT and LDAP queries need to be correctly constructed to get you the unique single values that you want. a LOT of that last part can be done using command line tools....then stick them into the server and check in full debug to see what is actually occurring at that unlang step. FreeRADIUS with unlang is a totally configurable beast.
alan
On Jul 3, 2017, at 1:52 AM, Cuong Nguyen <cuong.nguyenduy@gmail.com> wrote:
Let me explain what I try to do: 1. I'd want to limit a number of concurrent sessions a user is allowed. In LDAP, there is an attribute - MaxConnection - to indicate maximum concurrent sessions a user can have
OK...
2. Since FreeRADIUS does not keep track of the number of sessions,
Uh... what?
FreeRADIUS writes session data to a database. You can query the database from FreeRADIUS. This is even documented with examples in the default configuration.
my script will perform the following - POST-AUTH: For the user, get the number of sessions in MySQL, and get the MaxConnection from LDAP, then compare the two. If there are sessions >= MaxConnection --> Reject
That's threelines of unlang:
if ("%{sql:SELECT sessions...}" >= "%{ldap:get maxconnection}") { reject }
The only "magic" here is writing the correct SQL select query, and writing the correct LDAP query to get MaxConnection for a user.
And those two queries are just normal SQL / LDAP queries. You can write them and test them in an SQL or LDAP tool, and then just copy them to FreeRADIUS. Replace the actual user name with %{User-Name}, and you're good to go.
- ACCOUTING: If it is Accounting-Start --> Record in MySQL, if Accounting-Interim --> Update in MySQL, if Accounting-Stop --> Delete in MySQL
The default SQL module already does this. It's documented as doing this. There are tons of examples available.
Why are you re-inventing this?
Second, I did look at the LDAP module, but have no clue how to implement the logic I describe above. In my debug output above, I *did* include sql for the purpose of testing. In actual deployment, this will not be used (MySQL operations will be done by the script).
I even tried this in LDAP module in order to get the MaxConnection, which changes the 'request' list.
ldap { # TESTING request:Tmp-String-1 := 'MaxConnection' }
What made you think that would work? You're just trying random things in random places. And, ignoring all of the available documentation.
Any suggestion is appreciated.
Read the documentation and examples. Read the Wiki. Look for "Simultaneous-Use", which does exactly this...
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On 3 July 2017 at 12:03, Alan DeKok <aland@deployingradius.com> wrote: - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
participants (4)
-
Adam Bishop -
Alan Buxey -
Alan DeKok -
Cuong Nguyen