From 5c83aa1e2856fdfb093cd236babfc6ede332acbc Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Thu, 29 Mar 2018 05:40:27 -0500 Subject: [PATCH] refactor: LDAP debug output (#8434) * LDAP debug Updated LDAP and AD docs ldap protocol default to v3 (so we don't have to set it all the time). If this fails it should revert to v2. ad was using auth_ad_timeout incorrectly (1 I think) * Add option to list all users. --- .../ActiveDirectoryAuthorizer.php | 2 +- LibreNMS/Authentication/LdapAuthorizer.php | 23 ++++-- doc/Extensions/Authentication.md | 71 ++++++++++--------- scripts/auth_test.php | 20 ++++-- 4 files changed, 71 insertions(+), 45 deletions(-) diff --git a/LibreNMS/Authentication/ActiveDirectoryAuthorizer.php b/LibreNMS/Authentication/ActiveDirectoryAuthorizer.php index 8400d0f4e8..e86e30e526 100644 --- a/LibreNMS/Authentication/ActiveDirectoryAuthorizer.php +++ b/LibreNMS/Authentication/ActiveDirectoryAuthorizer.php @@ -403,7 +403,7 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase ldap_set_option( $this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, - Config::has('auth_ad_timeout') ? Config::has('auth_ad_timeout') : 5 + Config::get('auth_ad_timeout', 5) ); // With specified bind user diff --git a/LibreNMS/Authentication/LdapAuthorizer.php b/LibreNMS/Authentication/LdapAuthorizer.php index ae073c2744..a84a24988e 100644 --- a/LibreNMS/Authentication/LdapAuthorizer.php +++ b/LibreNMS/Authentication/LdapAuthorizer.php @@ -267,7 +267,7 @@ class LdapAuthorizer extends AuthorizerBase throw new AuthenticationException('Unable to connect to ldap server'); } - ldap_set_option($this->ldap_connection, LDAP_OPT_PROTOCOL_VERSION, Config::get('auth_ldap_version', 2)); + ldap_set_option($this->ldap_connection, LDAP_OPT_PROTOCOL_VERSION, Config::get('auth_ldap_version', 3)); $use_tls = Config::get('auth_ldap_starttls'); if ($use_tls == 'optional'||$use_tls == 'require') { @@ -282,6 +282,10 @@ class LdapAuthorizer extends AuthorizerBase return $this->ldap_connection; } + if (Config::get('auth_ldap_debug')) { + ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7); + } + // set timeout ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, Config::get('auth_ldap_timeout', 5)); @@ -295,11 +299,14 @@ class LdapAuthorizer extends AuthorizerBase $bind_dn = $this->getFullDn(Config::get('auth_ldap_binduser')); } - if (ldap_bind( - $this->ldap_connection, - $bind_dn, - Config::get('auth_ldap_bindpassword') - )) { + + $bind_result = ldap_bind($this->ldap_connection, $bind_dn, Config::get('auth_ldap_bindpassword')); + + if (Config::get('auth_ldap_debug')) { + echo "Bind result: " . ldap_error($this->ldap_connection) . PHP_EOL; + } + + if ($bind_result) { ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout return $this->ldap_connection; } @@ -308,6 +315,10 @@ class LdapAuthorizer extends AuthorizerBase // Anonymous ldap_bind($this->ldap_connection); + if (Config::get('auth_ldap_debug')) { + echo "Anonymous bind result: " . ldap_error($this->ldap_connection) . PHP_EOL; + } + ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout return $this->ldap_connection; } diff --git a/doc/Extensions/Authentication.md b/doc/Extensions/Authentication.md index 8ae6ac9943..706343c5b8 100644 --- a/doc/Extensions/Authentication.md +++ b/doc/Extensions/Authentication.md @@ -87,23 +87,24 @@ Cleanup of old accounts is done by checking the authlog. You will need to set th ### Sample configuration -``` -$config['auth_mechanism'] = "active_directory"; -$config['auth_ad_url'] = "ldaps://"; // you can add multiple servers, separated by a space -$config['auth_ad_domain'] = ""; -$config['auth_ad_base_dn'] = ""; // groups and users must be under this dn -$config['auth_ad_check_certificates'] = true; // require a valid ssl certificate -$config['auth_ad_binduser'] = 'examplebinduser'; -$config['auth_ad_bindpassword'] = 'examplepassword'; -$config['auth_ad_timeout'] = 5; // time to wait before giving up (or trying the next server) -$config['auth_ad_debug'] = false; // enable for verbose debug messages -$config['active_directory']['users_purge'] = 30; // purge users who haven't logged in for 30 days. -$config['auth_ad_require_groupmembership'] = false; // require users to be members of a group listed below -$config['auth_ad_groups']['']['level'] = 10; -$config['auth_ad_groups']['']['level'] = 7; +```php +$config['auth_mechanism'] = 'active_directory'; +$config['auth_ad_url'] = 'ldaps://server.example.com'; // Set server(s), space separated. Prefix with ldaps:// for ssl +$config['auth_ad_domain'] = 'example.com'; +$config['auth_ad_base_dn'] = 'dc=example,dc=com'; // groups and users must be under this dn +$config['auth_ad_check_certificates'] = true; // require a valid ssl certificate +$config['auth_ad_binduser'] = 'examplebinduser'; // bind user (non-admin) +$config['auth_ad_bindpassword'] = 'examplepassword'; // bind password +$config['auth_ad_timeout'] = 5; // time to wait before giving up (or trying the next server) +$config['auth_ad_debug'] = false; // enable for verbose debug messages +$config['active_directory']['users_purge'] = 30; // purge users who haven't logged in for 30 days. +$config['auth_ad_require_groupmembership'] = true; // false: allow all users to auth level 0 +$config['auth_ad_groups']['ad-admingroup']['level'] = 10; // set the "AD AdminGroup" group to admin level +$config['auth_ad_groups']['ad-usergroup']['level'] = 5; // set the "AD UserGroup" group to global read only level + ``` -Replace `` with your Active Directory admin-user group and `` with your standard user group. +Replace `ad-admingroup` with your Active Directory admin-user group and `ad-usergroup` with your standard user group. It is __highly suggested__ to create a bind user, otherwise "remember me", alerting users, and the API will not work. ### Active Directory redundancy @@ -132,25 +133,33 @@ This yields `(&(objectclass=user)(sAMAccountName=$username))` for the user filte Config option: `ldap` -Install __php_ldap__ or __php7.0-ldap__, making sure to install the same version as PHP. +Install __php_ldap__ or __php7.0-ldap__, making sure to install the same version as PHP. + +### Standard config + +```php +$config['auth_mechanism'] = 'ldap'; +$config['auth_ldap_server'] = 'ldap.example.com'; // Set server(s), space separated. Prefix with ldaps:// for ssl +$config['auth_ldap_suffix'] = ',ou=People,dc=example,dc=com'; // appended to usernames +$config['auth_ldap_groupbase'] = 'ou=groups,dc=example,dc=com'; // all groups must be inside this +$config['auth_ldap_groups']['admin']['level'] = 10; // set admin group to admin level +$config['auth_ldap_groups']['pfy']['level'] = 5; // set pfy group to global read only level +$config['auth_ldap_groups']['support']['level'] = 1; // set support group as a normal user +``` + +### Additional options (usually not needed): ```php $config['auth_ldap_version'] = 3; # v2 or v3 -$config['auth_ldap_server'] = "ldap.example.com"; -$config['auth_ldap_port'] = 389; -$config['auth_ldap_prefix'] = "uid="; -$config['auth_ldap_suffix'] = ",ou=People,dc=example,dc=com"; -$config['auth_ldap_group'] = "cn=groupname,ou=groups,dc=example,dc=com"; -$config['auth_ldap_groupbase'] = "ou=groups,dc=example,dc=com"; -$config['auth_ldap_groups']['admin']['level'] = 10; -$config['auth_ldap_groups']['pfy']['level'] = 7; -$config['auth_ldap_groups']['support']['level'] = 1; -$config['auth_ldap_groupmemberattr'] = "memberUid"; -$config['auth_ldap_uid_attribute'] = 'uidnumber'; +$config['auth_ldap_port'] = 389; // 389 or 636 for ssl +$config['auth_ldap_starttls'] = True; // Enable TLS on port 389 +$config['auth_ldap_prefix'] = 'uid='; // prepended to usernames +$config['auth_ldap_group'] = 'cn=groupname,ou=groups,dc=example,dc=com'; // generic group with level 0 +$config['auth_ldap_groupmemberattr'] = 'memberUid'; // attribute to use to see if a user is a member of a group +$config['auth_ldap_uid_attribute'] = 'uidnumber'; // attribute for unique id +$config['auth_ldap_debug'] = false; // enable for verbose debug messages ``` -Typically auth_ldap_suffix, auth_ldap_group, auth_ldap_groupbase, auth_ldap_groups are what's required to be configured. - ### LDAP bind user (optional) If your ldap server does not allow anonymous bind, it is highly suggested to create a bind user, otherwise "remember me", alerting users, and the API will not work. ```php @@ -171,9 +180,6 @@ An example config setup for use with Jumpcloud LDAP as a service is: ```php $config['auth_mechanism'] = "ldap"; -unset($config['auth_ldap_group']); -unset($config['auth_ldap_groups']); -$config['auth_ldap_groups']['librenms']['level'] = 10; $config['auth_ldap_version'] = 3; $config['auth_ldap_server'] = "ldap.jumpcloud.com"; $config['auth_ldap_port'] = 389; @@ -181,6 +187,7 @@ $config['auth_ldap_prefix'] = "uid="; $config['auth_ldap_suffix'] = ",ou=Users,o={id},dc=jumpcloud,dc=com"; $config['auth_ldap_groupbase'] = "cn=librenms,ou=Users,o={id},dc=jumpcloud,dc=com"; $config['auth_ldap_groupmemberattr'] = "memberUid"; +$config['auth_ldap_groups']['librenms']['level'] = 10; ``` Replace {id} with the unique ID provided by Jumpcloud. diff --git a/scripts/auth_test.php b/scripts/auth_test.php index 8aec5eeafd..1fe86b7089 100755 --- a/scripts/auth_test.php +++ b/scripts/auth_test.php @@ -3,10 +3,11 @@ use LibreNMS\Authentication\Auth; -$options = getopt('u:rdvh'); -if (isset($options['h']) || !isset($options['u'])) { +$options = getopt('u:rldvh'); +if (isset($options['h']) || (!isset($options['l']) && !isset($options['u']))) { echo ' -u (Required) username to test -r Reauthenticate user, (requires previous web login with "Remember me" enabled) + -l List all users (checks that auth can enumerate all allowed users) -d Enable debug output -v Enable verbose debug output -h Display this help message @@ -14,15 +15,14 @@ if (isset($options['h']) || !isset($options['u'])) { exit; } -$test_username = $options['u']; - if (isset($options['d'])) { $debug = true; } if (isset($options['v'])) { - // might need more options for other auth methods - $config['auth_ad_debug'] = 1; // active_directory + // Enable debug mode for auth methods that have it + $config['auth_ad_debug'] = 1; + $config['auth_ldap_debug'] = 1; } $init_modules = array('web', 'auth'); @@ -81,6 +81,14 @@ try { } } + if (isset($options['l'])) { + $users = $authorizer->getUserlist(); + echo "Users: " . implode(', ', array_column($users, 'username')) . PHP_EOL; + echo "Total users: " . count($users) . PHP_EOL; + exit; + } + + $test_username = $options['u']; $auth = false; if (isset($options['r'])) { echo "Reauthenticate Test\n";