User Authentication ******************* NetSpyGlass has the following modes of operation: - "unprotected" - "protected" - "reverseProxy" The mode of operation is controlled by the configuration parameter `ui.authentication.type` that can have value "none", "reverseProxy" or "internal". The default setting of this parameter is `none`, which turns authentication off and makes the system run in unprotected mode. Setting it to `internal` turns on authentication internal using internal user accounts and setting it to `reverseProxy` activates support for reverse proxy with authentication. .. _unprotected_mode: Unprotected mode ================ there is no user authentication for the UI and access to the API is also unprotected. .. _protected_mode: Protected mode ============== In protected mode the system requires user authentication to access all resources (currently using internal passwords, support for LDAP and Radius to be added in the future). API requires either valid session or access token. Protected mode is activated when configuration parameter `ui.authentication.type` is set to "internal": .. code-block:: none ui { authentication { type = internal } } Protected mode requires UI backend server to be configured to run using `https` protocol. See document `ssl.md` for more details on how to do this. UI backend server endpoints: - ``/`` serves static files (html and such) - ``/login.html`` login form - ``/logout`` serves as a "command" to invalidate the session and recirect to "/" - ``/api/ui`` API endpoint (UI-related functions) - ``/api/monitor`` API endpoint (monitoring data functions) - ``/api/metrics`` internal metrics (health status monitoring and statistics, does not require session or token) API access (path `/api/ui` or `/api/monitor`) is allowed after valid session has been established (we are using cookie `NSGSESSION`). Alternatively, API access is allowed when the query includes parameter `access_token`, this is intended for third-party scripts and does not require valid session (cookie `NSGSESSION` is not used). User logins are supported by Java JAAS framework that uses configuration file `login.conf` to determine the method it should use for authentication. The file is located in the `${home}/etc/` directory (${home} is NetSpyGlass home directory defined by the parameter `home` in the config file). At this time the only supported method of authentication is through local accounts (we plan to add support for LDAP and Radius in the future). Here is how the default `login.conf` file looks like: .. code-block:: none nsg { org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required debug="true" file="etc/users.properties"; }; You do not need to modify this file if you plan to use local user accounts for authentication. User accounts are stored in the file `${home}/etc/users.properties` which has simple format: .. code-block:: none # : [, ...] test1: MD5:098f6bcd4621d373cade4e832627b4f6,user There is only one role at this time, `user`. You can store the password in plain text, obfuscated format or as MD5 hash. To generate passwords in obfuscated or md5-hash format, use script `nsgpasswd.sh` that comes with NetSpyGlass: .. code-block:: none $ ./nsgpasswd vadim test test OBF:1z0f1vu91vv11z0f MD5:098f6bcd4621d373cade4e832627b4f6 CRYPT:va/5VIyG0bPak Just copy and paste generated obfuscated password or md5 hash to the file `users.properties` as shown in an example of user account "test1" above. You do not need to restart NetSpyGlass when you add or modify user accounts. .. _access_tokens: Using access tokens for script access to API ============================================ This is only required when the server is running in protected mode. Normally, UI running in the browser is allowed to access API if it presents valid session cookie `NSGSESSION`. Third party scripts, such as Nagios plugin or other scripts using our JSON API, do not have the session and can not use this mechanism to access the API. Instead, these scripts must provide valid access token as a query parameter `access_token`. Examples: .. code-block:: none /api/ui/status?access_token=5a105e8b9d40e1329780d62ea2265d8a /api/ui/networks/1/gw/?name=ifOutRate&access_token=5a105e8b9d40e1329780d62ea2265d8a /api/ui/networks/1/views/6/map?access_token=5a105e8b9d40e1329780d62ea2265d8a Attempts to access API without access token or with invalid one ends with response 401 "Unauthorized response from the server". Access tokens are defined in the configuration file, parameter `api.accessTokens`: .. code-block:: none # here you can add access tokens for third-party API access api { accessTokens : { test_access_1: abcdefgh, another_script: 5a105e8b9d40e1329780d62ea2265d8a, script5: "token$3167 % & with_special_chars or spaces" } Each record consists of the name and token string. The name is used internally in place of "user name" if the script calls API funcions that require it. Token scring can be any text that conforms to the rules of the configuration file syntax (see document config.md). Tokens that contain special characters and white space must be url-encoded when used in the query. Default configuration includes access token called `api`, it is used for the API calls between NetSpyGlass servers when NetSpyGlass is running in cluster configuration. You can change this token to make it something different from the default by adding the following to the `nw2.conf` file in all cluster members: .. code-block:: none api.accessTokens.api = "YourOwnSecretToken" or, if you have multiple tokens: .. code-block:: none api { accessTokens { api = "YourOwnSecretToken" test_access_1: abcdefgh, another_script: 5a105e8b9d40e1329780d62ea2265d8a, script5: "token$3167 % & with_special_chars or spaces" } } .. _rev_proxy_mode: Running NetSpyGlass behind reverse proxy with authentication ============================================================ NetSpyGlass can work behind reverse proxy with authentication and can use HTTP headers inserted by the proxy to distinguish logged in users who use the UI to improve their experience. In particular, NetSpyGlass can make map layout specific to the user so that changes in map layout made by one user are not visible to others. There is no authentication in this mode because we expect the proxy to perform it. API access is also unprotected, however the server expects each request to have HTTP header configured via parameter `ui.authentication.reverseProxyAuthenticationHeader`. This parameter defines regular expression used to match the header line to extract authenticated user name. This assumes the server works behind authenticating reverse proxy that inserts this HTTP header. This mode is activated when configuration parameter `ui.authentication.type` is set to `reversePoxy`. How to configure NetSpyGlass to parse HTTP header to extact user name --------------------------------------------------------------------- This is done by adding configuration parameter `ui.authentication.reverseProxyAuthenticationHeader`, its value is header name and regular expression to match its value. Example: .. code-block:: none ui { authentication { # authenticaton is done by reverse proxy in front of NetSpyGlass type = reverseProxy # proxy injects HTTP header that includes authenticated user's name. # Parameter reverseProxyAuthenticationHeader is a regular expression # with a group match that should match user name reverseProxyAuthenticationHeader = "X-Forwarded-User: ([^ ]+)" } } Here NetSpyGlass expects HTTP header `X-Forward-User` with user name as a value, e.g.: .. code-block:: none X-Forwarded-User: test1 Configured this way, NetSpyGlass is going to make map layout data specific to each user, so each user can have their own map layout. .. _logged_in_display: UI indication of successful authentication ========================================== When authentication is turned on and user has successfully authenticated, the UI displays user name with "Loggen in:" prompt in the upper right corner of the page. This works for both intrnal and reverse proxy authentication and looks like this: .. image:: images/authenticated_user_screenshot.png User Roles ========== NetSpyGlass provides simple RBAC (Role Based Access Control) system where administrator can assign roles to user accounts using configuration block `ui.authentication.roles`. Currently this are two roles, `admin` and `other`. To make a user an admin, add corresponding user name to the list `ui.authentication.roles.admin`: .. code-block:: none ui { authentication { roles { admin: [ "user@company.com", another_user ] } } } All users who are not explicitly assigned role `admin` are considered to only have one role `other`. User names should be added exactly as they appear in the `etc/users.properties` file (if parameter `authentication.type` has value `internal`, see :ref:`protected_mode`). To check what you should add to the configuration statement, look at the user name that appears in the upper right corner of the UI pages where it says "Logged in:". See :ref:`logged_in_display` This works with both internal and reverse proxy based authentication methods. If authentication is turned off (i.e. the server works in the unprotected mode), then all users are given admin level access. Currently there is only one function that requires admin level access, it is ability to start network discovery by clicking "Discover" button in the UI. If logged in user is an admin, the UI control is clickable and starts discovery. If logged in user is not an admin, the control looks differently and is not clickable. If authentication is turned off, the control is always enabled. Example: using Apache web server as proxy ----------------------------------------- To use Apache as authenticating proxy in front of NetSpyGlass, configure it as follows: .. code-block:: none ServerAdmin webmaster@localhost Order deny,allow Allow from all Deny from all AuthType Basic AuthName "Password Required" AuthUserFile password.file Require valid-user ProxyRequests On ProxyVia On ProxyPreserveHost On ProxyPass / http://127.0.0.1:9100/ ProxyPassReverse / http://127.0.0.1:9100/ RewriteEngine On RewriteCond %{LA-U:REMOTE_USER} (.+) RewriteRule . - [E=RU:%1] RequestHeader add X-Forwarded-User %{RU}e ErrorLog /var/log/apache2/nw2error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog /var/log/apache2/nw2access.log combined In this example we assume that Apache runs on the same server with NetSpyGlass, NetSpyGlass UI backend listens on port 9100 and Apache listens on port 9101. Apache will inject HTTP header "X-Forwarded-User". How to limit access to NetSpyGlass running behind the proxy ----------------------------------------------------------- If NetSpyGlass runs behind the proxy for security reasons, it should be configured to listen on the address or port that is not accessible to the users directly to make sure they don't circumvent the protection by connecting directly to NetSpyGlass instead of going through proxy. To do this, use address that is only accessible by the proxy in `ui.url` configuration parameter. If proxy runs on the same host, then loopback address 127.0.0.1 is probably good choice. If proxy runs on a different machine, firewall rules may provide needed protection.