Skip to content

Add FIDO/U2F support to Duo authentication#127

Merged
venth merged 8 commits intoventh:masterfrom
pdecat:duo_u2f
Sep 25, 2019
Merged

Add FIDO/U2F support to Duo authentication#127
venth merged 8 commits intoventh:masterfrom
pdecat:duo_u2f

Conversation

@pdecat
Copy link
Collaborator

@pdecat pdecat commented Jul 19, 2019

This PR adds support for FIDO/U2F to Duo authentication.

If Duo reports U2F is supported for the user, it is used concurrently to the default authentication method.

It's a rough draft that works but needs cleanup, hence the WIP.
I opened the PR now to get early feedback if possible.

Right now, if Duo reports U2F is supported for the user, only that authentication method is used.

Example usage shown here: #127 (comment)

Tested in USB mode with:

  • Yubikey Neo
  • Yubikey 5 NFC
  • Yubikey 5 Nano

It should support NFC mode too but that is not tested yet.

TODO:

  • manage default authentication (call or push) concurrently to U2F
  • manage multiple U2F better (right now, each device is tried sequentially)
  • cleanup code
  • add tests
  • add documentation

@venth
Copy link
Owner

venth commented Jul 28, 2019

Is it ready to be merged or still it’s a work in progress there?

@pdecat
Copy link
Collaborator Author

pdecat commented Jul 28, 2019

Hi @venth, right now it works great for me, but I feel like it could have some more real world testing from others. I've asked some colleagues to give it a go, waiting for their feedback.

Also, there are some improvements I'd like to address like still having the default authentication (call or push) happen in parallel to U2F (that may be really useful if U2F key is e.g. forgotten at home).

Another thing that may be changed could be making fido2 an optional dependency, especially as it is only needed/supported for Duo right now, not for the other providers.

At last, please have a look a the code change and do not hesitate to report any comments or questions you may have. I'll be glad to address them.

Thanks!

PS: I'll be AFK for the next two weeks so I won't be able to work on that before the second half of August.

…kies have an 'expires' date too far in the future and they are converted from timestamp to datetime
@pdecat
Copy link
Collaborator Author

pdecat commented Sep 18, 2019

Alright, got feedback from co-workers: it works fine on Linux and Windows (native, not WSL as it does not have access USB devices). And I've been using it myself exclusively for two months.

I'm resuming work on this to implement the first two items on the Todo list:

  • manage default authentication (call or push) concurrently to U2F
  • manage multiple U2F better (right now, each device is tried sequentially)

As those need the ability to perform asynchronous tasks, I'm considering the use of python 3.5 features like async/await.

As python 2.7 is soon EOL (2020-01-01) and python 3.4 is already EOL (2019-03-18); I guess dropping support for those could be acceptable, maybe releasing a new major version of aws-adfs.
If it isn't, I'll look into alternative options, maybe threading.

Update: the fido2 library already relies on threading so I'll go that way, no need to drop support for any python version.

@pdecat
Copy link
Collaborator Author

pdecat commented Sep 19, 2019

Support for prompting multiple U2F devices concurrently has been implemented with threading.

With a single USB device:

# rm ~/.aws/adfs_cookies
# aws-adfs login --env --profile=****** --region=eu-west-1 --adfs-host=****** --ssl-verification --session-duration=14400 --no-sspi
2019-09-19 15:45:02,470 [authenticator authenticator.py:authenticate] [6905-MainProcess] [140102118655808-MainThread] - ERROR: Cannot extract saml assertion. Re-authentication needed?
Sending request for authentication
Waiting for additional authentication
Activate your FIDO U2F authenticator now: 'CtapHidDevice(/dev/hidraw7)'
Got response from FIDO U2F authenticator: 'CtapHidDevice(/dev/hidraw7)'
Going for aws roles

        Prepared ADFS configuration as follows:
            * AWS CLI profile                   : '******'
            * AWS region                        : 'eu-west-1'
            * Output format                     : 'json'
            * SSL verification of ADFS Server   : 'ENABLED'
            * Selected role_arn                 : 'arn:aws:iam::******:role/******'
            * ADFS Server                       : '******'
            * ADFS Session Duration in seconds  : '28800'
            * Provider ID                       : 'urn:amazon:webservices'
            * S3 Signature Version              : 'None'
            * STS Session Duration in seconds   : '14400'

With two USB devices:

# rm ~/.aws/adfs_cookies
# aws-adfs login --env --profile=****** --region=eu-west-1 --adfs-host=****** --ssl-verification --session-duration=14400 --no-sspi
2019-09-19 15:47:07,604 [authenticator authenticator.py:authenticate] [13535-MainProcess] [139727676925760-MainThread] - ERROR: Cannot extract saml assertion. Re-authentication needed?
Sending request for authentication
Waiting for additional authentication
Activate your FIDO U2F authenticator now: 'CtapHidDevice(/dev/hidraw7)'
Activate your FIDO U2F authenticator now: 'CtapHidDevice(/dev/hidraw3)'
Got response from FIDO U2F authenticator: 'CtapHidDevice(/dev/hidraw3)'
Going for aws roles

        Prepared ADFS configuration as follows:
            * AWS CLI profile                   : '******'
            * AWS region                        : 'eu-west-1'
            * Output format                     : 'json'
            * SSL verification of ADFS Server   : 'ENABLED'
            * Selected role_arn                 : 'arn:aws:iam::******:role/******'
            * ADFS Server                       : '******'
            * ADFS Session Duration in seconds  : '28800'
            * Provider ID                       : 'urn:amazon:webservices'
            * S3 Signature Version              : 'None'
            * STS Session Duration in seconds   : '14400'

@pdecat
Copy link
Collaborator Author

pdecat commented Sep 23, 2019

Support for triggering default authentication (call or push) concurrently to U2F has been implemented.

With no USB device and answering the default authentication method (push here):

# rm ~/.aws/adfs_cookies
# aws-adfs login --env --profile=****** --region=eu-west-1 --adfs-host=****** --ssl-verification --session-duration=14400 --no-sspi
2019-09-23 15:48:43,870 [authenticator authenticator.py:authenticate] [14957-MainProcess] [139755917858624-MainThread] - ERROR: Cannot extract saml assertion. Re-authentication needed?
Sending request for authentication
Waiting for additional authentication
Going for aws roles

        Prepared ADFS configuration as follows:
            * AWS CLI profile                   : '******'
            * AWS region                        : 'eu-west-1'
            * Output format                     : 'json'
            * SSL verification of ADFS Server   : 'ENABLED'
            * Selected role_arn                 : 'arn:aws:iam::******:role/******'
            * ADFS Server                       : '******'
            * ADFS Session Duration in seconds  : '28800'
            * Provider ID                       : 'urn:amazon:webservices'
            * S3 Signature Version              : 'None'
            * STS Session Duration in seconds   : '14400'

With a single USB device and answering the default authentication method (push here):

2019-09-23 15:50:59,251 [authenticator authenticator.py:authenticate] [23179-MainProcess] [140027943323456-MainThread] - ERROR: Cannot extract saml assertion. Re-authentication needed?
Sending request for authentication
Waiting for additional authentication
Activate your FIDO U2F authenticator now: 'CtapHidDevice(/dev/hidraw3)'
Going for aws roles

        Prepared ADFS configuration as follows:
            * AWS CLI profile                   : '******'
            * AWS region                        : 'eu-west-1'
            * Output format                     : 'json'
            * SSL verification of ADFS Server   : 'ENABLED'
            * Selected role_arn                 : 'arn:aws:iam::******:role/******'
            * ADFS Server                       : '******'
            * ADFS Session Duration in seconds  : '28800'
            * Provider ID                       : 'urn:amazon:webservices'
            * S3 Signature Version              : 'None'
            * STS Session Duration in seconds   : '14400'

With a single USB device and touching it, ignoring the default authentication method that also happens:

# rm ~/.aws/adfs_cookies
# aws-adfs login --env --profile=****** --region=eu-west-1 --adfs-host=****** --ssl-verification --session-duration=14400 --no-sspi
2019-09-23 15:47:41,232 [authenticator authenticator.py:authenticate] [11187-MainProcess] [140135042541376-MainThread] - ERROR: Cannot extract saml assertion. Re-authentication needed?
Sending request for authentication
Waiting for additional authentication
Activate your FIDO U2F authenticator now: 'CtapHidDevice(/dev/hidraw3)'
Got response from FIDO U2F authenticator: 'CtapHidDevice(/dev/hidraw3)'
Going for aws roles

        Prepared ADFS configuration as follows:
            * AWS CLI profile                   : '******'
            * AWS region                        : 'eu-west-1'
            * Output format                     : 'json'
            * SSL verification of ADFS Server   : 'ENABLED'
            * Selected role_arn                 : 'arn:aws:iam::******:role/******'
            * ADFS Server                       : '******'
            * ADFS Session Duration in seconds  : '28800'
            * Provider ID                       : 'urn:amazon:webservices'
            * S3 Signature Version              : 'None'
            * STS Session Duration in seconds   : '14400'

With a two USB devices and touching one of them, ignoring the default authentication method that also happens:

# rm ~/.aws/adfs_cookies
# aws-adfs login --env --profile=****** --region=eu-west-1 --adfs-host=****** --ssl-verification --session-duration=14400 --no-sspi
2019-09-23 15:53:29,980 [authenticator authenticator.py:authenticate] [31971-MainProcess] [140592882558784-MainThread] - ERROR: Cannot extract saml assertion. Re-authentication needed?
Sending request for authentication
Waiting for additional authentication
Activate your FIDO U2F authenticator now: 'CtapHidDevice(/dev/hidraw7)'
Activate your FIDO U2F authenticator now: 'CtapHidDevice(/dev/hidraw3)'
Got response from FIDO U2F authenticator: 'CtapHidDevice(/dev/hidraw7)'
Going for aws roles

        Prepared ADFS configuration as follows:
            * AWS CLI profile                   : ''******'
            * AWS region                        : 'eu-west-1'
            * Output format                     : 'json'
            * SSL verification of ADFS Server   : 'ENABLED'
            * Selected role_arn                 : 'arn:aws:iam::'******:role/'******'
            * ADFS Server                       : ''******'
            * ADFS Session Duration in seconds  : '28800'
            * Provider ID                       : 'urn:amazon:webservices'
            * S3 Signature Version              : 'None'
            * STS Session Duration in seconds   : '14400'

@pdecat pdecat changed the title WIP: add FIDO/U2F support to Duo authentication Add FIDO/U2F support to Duo authentication Sep 23, 2019
@pdecat
Copy link
Collaborator Author

pdecat commented Sep 23, 2019

Remove WIP from PR title, ready for review.

level=logging.DEBUG if verbose else logging.ERROR,
)

if verbose:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably be moved to another flag as this makes it very verbose.

@pdecat
Copy link
Collaborator Author

pdecat commented Sep 24, 2019

I can probably go one step further and make it an option to only trigger the default authentification to avoid needless pushes/calls on the phone when no U2F device is plugged.

@venth
Copy link
Owner

venth commented Sep 25, 2019

I can probably go one step further and make it an option to only trigger the default authentification to avoid needless pushes/calls on the phone when no U2F device is plugged.

Would be awesome. I think that it could be tackled in a separate PR.

@venth venth merged commit cff4517 into venth:master Sep 25, 2019
@venth
Copy link
Owner

venth commented Sep 25, 2019

released in version 1.18.0

@pdecat pdecat deleted the duo_u2f branch September 25, 2019 14:32
@pdecat
Copy link
Collaborator Author

pdecat commented Sep 25, 2019

Thanks @venth!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants