WL#12503: Authentication for HTTP component

Affects: Server-8.0   —   Status: Complete

Motivation

The HTTP component of the MySQL Router (WL#11891) provides basic HTTP support.

Authentication for HTTP as defined by RFC 7235 is need to protect resources exposed by the HTTP component to authenticated users.

While HTTP specifies several Authentication methods "Basic" RFC 7617 is the most widely supported and allows most flexible integration with credential stores.

Note: Digest Authentication also exists (RFC 7616), but only the insecure "MD5" method is widely supported by clients.

Design Requirements

  1. Credentials stored by the HTTP Component MUST be stored securely.
  2. Follow RFC 7617 and RFC 7235 to integrate with existing HTTP clients.
  3. Credential store must be managable independent of a running HTTP component.

Goal

  • Allow authentication via Basic Authentication RFC 7617
  • Allow authentication against a secure, file based password storage
  • Provide a standalone tool to manage secure, file based password storage

Function Requirements

HTTP Component

FR1
"Authorization" header MUST be parsed by server-side according to RFC 7617
FR2
"WWW-Authenticate" header MUST be generated by server-side according to RFC 7617
FR3
file-based storage of credentials SHOULD NOT be hashed by broken hash algorithms.
FR4
if a username exists more than once in the file-storage, only the first entry MUST be used.
FR5
if hash-spec is not supported authentication MUST fail in the same way as if the password wouldn't match.
FR6
invalid authentication methods in the configuration MUST lead to failure to start
FR7
file-based storage of credentials MUST be only read/write-able by the router user and router group.

mysqlrouter_passwd

mysqlrouter_passwd

PW_F1
MUST be able to add sha256_crypt hashed passwords to passwd file
PW_F2
MUST be able to add sha512_crypt hashed passwords to passwd file
PW_F3
MUST accepted passwords via stdin only
PW_F4
MUST be able to verify sha256_crypt hashed passwords against passwd file
PW_F5
MUST be able to verify sha512_crypt hashed passwords against passwd file
PW_F6
MUST be able to delete accounts from passwd file
PW_F7
MUST be able to list all accounts
PW_F8
MUST be able to list accounts by username

password file format

  • one line per username:hashed-password-spec
  • each username should be unique, duplicating usernames are ignored
  • hashed-password-spec follows https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md
  • supported Key Derivation Functions
    • sha256_crypt
    • sha512_crypt
    • pbkdf2_sha256
    • pkkdf2_sha512

Note: similar to /etc/shadow and htpasswd

Format:

[{username}:{hashed-password-spec}\n]*
username
[^:\n]*
hashed-password-spec
$<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]] see https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md
sha256-crypt:
$5[$rounds={unsigned-int}]${salt}[${checksum}]
sha512-crypt:
$6[$rounds={unsigned-int}]${salt}[${checksum}]
pbkdf2-sha256:
$pbkdf2-sha256${unsigned-int}${salt}[${checksum}]
pbkdf2-sha512:
$pbkdf2-sha512${unsigned-int}${salt}[${checksum}]

HTTP Component

Authentication Method

In HTTP a server tells a client that authentication is required with:

HTTP/1.1 401 Unauthenticated
WWW-Authenticate: Basic realm="..."
...

A client answers with:

GET / HTTP/1.1
Authorization: Basic ....

The credentials provided by the client are decoded according to the Authentication Method's spec. For Basic Authentication, the payload of the Authorization header is Base64 encoded(username:password).

If Authorization failed, "403 Forbidden" is returned, otherwise the request is processed.

File Authentication Backend

The credentials provided by a authentication method are verified against a authentication backend.

The file backend verifies credentials against a passwd-like file that is expected to be in "password file format" specified above.

Configuration

Storage

Zero or more HTTP authentication backends may be specified in the configuration:

[http_auth_backend:local]
backend=file
filename=passwd
backend
name of the backend implementation: file
filename
name of the storage for backend. Relative to data_folder

Realms

Zero or more realms may be specified in the configuration:

[http_auth_realm:secure_api]
backend=local
method=basic
name=API
require=valid-user
backend
name of the http_auth_backend section
method
basic
require
optional, "valid-user", default valid-user. "valid-user" checks requires a provided user validates with the authentication backend.
name
name of the realm presented to authenticated user

Realm of Server

The HTTP-server component described in WL#11891 gets extended by require_realm .

[http_server]
port=8000
require_realm=secure_api
require_realm
name of a http_auth_realm instance.

mysqlrouter_passwd

mysqlrouter_passwd is a new command line application to manage the accounts in the passwd file.

set account

Set (add or replace) account made up of username and hashed password that was taken from stdin to file.

required options
filename username
exit-code
0 on success, 1 on error

verify account

Check if password passed through stdin matches the hash stored in the file.

required options
--verify filename username
exit-code
0 on success, 1 if not verification failed.

delete account

Delete an account matched by username from file.

required options
--delete filename username
exit-code
0 on success, 1 on failure (username not found, ...)

list account

List one or all accounts in "password file format".

required options
--list filename
optional username
--list filename username
exit-code
0 on success, 1 on failure (username not found, file not readable, parse-error, ...)

Other options

key derivation function (KDF)
--kdf <name>
work-factor for the KDF
--work-factor <num> (valid range: 0-2^32-1). KDF may apply its own narrower limits. Default value dependent on KDF.
help
--help
version
--version

Help output

Usage: ./mysqlrouter_passwd [--delete] [-?|--help] [--kdf=<name>] [--list] [--verify]
                            [-V|--version] [--work-factor=<num>] [filename username]
Options:

  --delete
      Delete username if it exists.
  -?, --help
      Display this help and exit.
  --kdf <name>
      Key Derivation Function. One of pbkdf2-sha256, pbkdf2-sha512, sha256-crypt, sha512-crypt. default: sha256-crypt
  --list
      List account(s).
  --verify
      Verify password against stored hash for username. Exit-code is 0 if password matches, 1 otherwise
  -V, --version
      Display version information and exit.
  --work-factor <num>
      Work-factor hint for KDF if account is updated.

mysqlrouter_passwd

Uses the "File Authentication Backend" of the HTTP component.