mod_auth_token/README.markdown
author Kim Alvefur <zash@zash.se>
Tue, 18 Jan 2022 18:55:20 +0100
changeset 4881 adc6241e5d16
parent 3475 b4bcb84997e7
permissions -rw-r--r--
mod_measure_process: Report the enforced limit The soft limit is what the kernel actually enforces, while the hard limit is is how far you can change the soft limit without privileges. Unless the process dynamically adjusts the soft limit, knowing the hard limit is not as useful as knowing the soft limit. Reporting the soft limit and the number of in-use FDs allows placing alerts on expressions like 'process_open_fds / process_max_fds >= 0.95'
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2960
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
     1
# mod_auth_token
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
     2
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
     3
This module enables Prosody to authenticate time-based one-time-pin (TOTP) HMAC tokens.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
     4
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
     5
This is an alternative to "external authentication" which avoids the need to
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
     6
make a blocking HTTP call to the external authentication service (usually a web application backend).
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
     7
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
     8
Instead, the application generates the HMAC token, which is then sent to
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
     9
Prosody via the XMPP client and Prosody verifies the authenticity of this
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    10
token.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    11
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    12
If the token is verified, then the user is authenticated.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    13
3475
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    14
## Luarocks dependencies
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    15
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    16
You'll need to install the following luarocks
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    17
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    18
  otp 0.1-5
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    19
  luatz 0.3-1
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    20
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    21
## How to generate the TOTP seed and shared signing secret
2960
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    22
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    23
You'll need a shared OTP_SEED value for generating time-based one-time-pin
3475
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    24
(TOTP) values and a shared private key for signing the HMAC token.
2960
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    25
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    26
You can generate the OTP_SEED value with Python, like so:
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    27
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    28
    >>> import pyotp
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    29
    >>> pyotp.random_base32()
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    30
    u'XVGR73KMZH2M4XMY'
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    31
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    32
and the shared secret key as follows:
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    33
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    34
    >>> import pyotp
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    35
    >>> pyotp.random_base32(length=32)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    36
    u'JYXEX4IQOEYFYQ2S3MC5P4ZT4SDHYEA7'
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    37
3475
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    38
## Configuration
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    39
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    40
Firest you need to enable the relevant modules to your Prosody.cfg file.
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    41
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    42
Look for the line `modules_enabled` (either globally or for your
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    43
particular `VirtualHost`), and then add the following to tokens:
2960
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    44
3475
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    45
    modules_enabled = {
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    46
        -- Token authentication
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    47
            "auth_token";
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    48
            "sasl_token";
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    49
    }
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    50
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    51
The previously generated token values also need to go into your Prosody.cfg file:
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    52
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    53
    authentication = "token";
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    54
    token_secret = "JYXEX4IQOEYFYQ2S3MC5P4ZT4SDHYEA7";
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    55
    otp_seed = "XVGR73KMZH2M4XMY";
2960
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    56
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    57
The application that generates the tokens also needs access to these values.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    58
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    59
For an example on how to generate a token, take a look at the `generate_token`
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    60
function in the `test_token_auth.lua` file inside this directory.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    61
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    62
## Custom SASL auth
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    63
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    64
This module depends on a custom SASL auth mechanism called X-TOKEN and which
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    65
is provided by the file `mod_sasl_token.lua`.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    66
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    67
Prosody doesn't automatically pick up this file, so you'll need to update your
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    68
configuration file's `plugin_paths` to link to this subdirectory (for example
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
    69
to `/usr/lib/prosody-modules/mod_auth_token/`).
3475
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    70
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    71
## Generating the token
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    72
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    73
Here's a Python snippet showing how you can generate the token that Prosody
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    74
will then verify:
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    75
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    76
    import base64
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    77
    import pyotp
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    78
    import random
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    79
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    80
    # Constants
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    81
    OTP_INTERVAL = 30
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    82
    OTP_DIGITS = 8
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    83
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    84
    jid = '{}@{}'.format(username, domain)
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    85
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    86
    otp_service = pyotp.TOTP(
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    87
        OTP_SEED,  # OTP_SEED must be set to the value generated previously (see above)
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    88
        digits=OTP_DIGITS,
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    89
        interval=OTP_INTERVAL
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    90
    )
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    91
    otp = otp_service.generate_otp(otp_service.timecode(datetime.utcnow()))
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    92
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    93
    nonce = ''.join([str(random.randint(0, 9)) for i in range(32)])
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    94
    string_to_sign = otp + nonce + jid
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    95
    signature = hmac.new(token_secret, string_to_sign, hashlib.sha256).digest()
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    96
    token = u"{} {}".format(otp+nonce, base64.b64encode(signature))
b4bcb84997e7 mod_auth_token: Update README.
JC Brand <jc@opkode.com>
parents: 2964
diff changeset
    97