diff --git a/awx/sso/validators.py b/awx/sso/validators.py index 5c46dc4c83..6a34a2c731 100644 --- a/awx/sso/validators.py +++ b/awx/sso/validators.py @@ -62,5 +62,7 @@ def validate_ldap_filter_with_user(value): def validate_tacacsplus_disallow_nonascii(value): - if not all(ord(c) < 128 for c in value): + try: + value.encode('ascii') + except (UnicodeEncodeError, UnicodeDecodeError): raise ValidationError(_('TACACS+ secret does not allow non-ascii characters')) diff --git a/docs/auth/README.md b/docs/auth/README.md new file mode 100644 index 0000000000..6c01ce7b67 --- /dev/null +++ b/docs/auth/README.md @@ -0,0 +1,16 @@ +This folder describes third-party authentications supported by Ansible Tower. These authentications can be configured and enabled inside Tower. + +When a user wants to log into Tower, she can explicitly choose some of the supported authentications to log in instead of Tower's own authentication using username and password. Here is a list of such authentications: +* Google OAuth2 +* Github OAuth2 +* Github Organization OAuth2 +* Github Team OAuth2 +* Microsoft Azure Active Directory (AD) OAuth2 + +On the other hand, the rest of authentication methods use the same types of login info as Tower(username and password), but authenticate using external auth systems rather than Tower's own database. If some of these methods are enabled, Tower will try authenticating using the enabled methods *before Tower's own authentication method*. In specific, it follows the order +* LDAP +* RADIUS +* TACACS+ +* SAML + +Tower will try authenticating against each enabled authentication method *in the specified order*, meaning if the same username and password is valid in multiple enabled auth methods (For example, both LDAP and TACACS+), Tower will only use the first positive match (In the above example, log a user in via LDAP and skip TACACS+). diff --git a/docs/auth/tacacsplus.md b/docs/auth/tacacsplus.md new file mode 100644 index 0000000000..92cd1e9cf7 --- /dev/null +++ b/docs/auth/tacacsplus.md @@ -0,0 +1,46 @@ +# TACACS+ +[Terminal Access Controller Access-Control System Plus (TACACS+)](https://en.wikipedia.org/wiki/TACACS) is a protocol developed by Cisco to handle remote authentication and related services for networked access control through a centralized server. In specific, TACACS+ provides authentication, authorization and accounting (AAA) services. Ansible Tower currently utilizes its authentication service. + +TACACS+ is configured by Tower configuration and is available under `/api//settings/tacacsplus/`. Here is a typical configuration with every configurable field included: +``` +{ + "TACACSPLUS_HOST": "127.0.0.1", + "TACACSPLUS_PORT": 49, + "TACACSPLUS_SECRET": "secret", + "TACACSPLUS_SESSION_TIMEOUT": 5, + "TACACSPLUS_AUTH_PROTOCOL": "ascii" +} +``` +Below explains each field: + +| Field Name | Field Value Type | Field Value Default | Description | +|------------------------------|---------------------|---------------------|--------------------------------------------------------------------| +| `TACACSPLUS_HOST` | String | '' (empty string) | Hostname of TACACS+ server. Empty string disables TACACS+ service. | +| `TACACSPLUS_PORT` | Integer | 49 | Port number of TACACS+ server. | +| `TACACSPLUS_SECRET` | String | '' (empty string) | Shared secret for authenticating to TACACS+ server. | +| `TACACSPLUS_SESSION_TIMEOUT` | Integer | 5 | TACACS+ session timeout value in seconds. | +| `TACACSPLUS_AUTH_PROTOCOL` | String with choices | 'ascii' | The authentication protocol used by TACACS+ client. Choices are `ascii` and `pap` | + +Under the hood, Tower uses [open-source TACACS+ python client](https://github.com/ansible/tacacs_plus) to communicate with the remote TACACS+ server. During authentication, Tower passes username and password to TACACS+ client, which packs up auth information and send to TACACS+ server. Based on what the server returns, Tower will invalidate login attempt if authentication fails. If authentication passes, Tower will create a user if she does not exist in database, and log the user in. + +## Test environment setup + +The suggested TACACS+ server for testing is [shrubbery TACACS+ daemon](http://www.shrubbery.net/tac_plus/). It is supposed to run on a centos machine. A verified candidate is centos 6.3 AMI in AWS EC2 Community AMIs (search for 'Centos 6.3 x86_64 HVM - Minimal with cloud-init aws-cfn-bootstrap and ec2-api-tools'). Note it is required to keep TCP port 49 open, since it's the default port used by TACACS+ daemon. + +We provide [a playbook](https://github.com/jangsutsr/ansible-role-tacacs) to install a working TACACS+ server. Here is a typical test setup using the provided playbook. +1. In AWS EC2, spawn the centos 6 machine. +2. In Tower, create a test project using the stand-alone playbook inventory. +3. In Tower, create a test inventory with the only host to be the spawned centos machine. +4. In Tower, create and run a job template using the created project and inventory with parameters setup as below. + +![Example tacacs+ setup jt parameters](../img/auth_tacacsplus_1.png?raw=true) + +The playbook creates a user named 'tower' with ascii password default to 'login' and modifiable by extra_var `ascii_password` and pap password default to 'papme' and modifiable by extra_var `pap_password`. In order to configure TACACS+ server to meet custom test needs, we need to modify server-side file `/etc/tac_plus.conf` and `sudo service tac_plus restart` to restart the daemon. Details on how to modify config file can be found [here](http://manpages.ubuntu.com/manpages/xenial/man5/tac_plus.conf.5.html). + +## Acceptance criteria +* All specified Tower configuration fields should be shown and configurable as documented. +* User defined by TACACS+ server should be able to log in Tower. +* User not defined by TACACS+ server should not be able to log in Tower via TACACS+. +* A user existing in TACACS+ server but not in Tower should be created after the first success log in. +* TACACS+ backend should stop authentication attempt after configured timeout and should not block the authentication pipeline in any case. +* If exceptions occur on TACACS+ server side, the exception details should be logged in Tower, and Tower should not authenticate that user via TACACS+. diff --git a/docs/img/auth_tacacsplus_1.png b/docs/img/auth_tacacsplus_1.png new file mode 100644 index 0000000000..eac65a2f7b Binary files /dev/null and b/docs/img/auth_tacacsplus_1.png differ