WL#12503: Authentication for HTTP component
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
- Credentials stored by the HTTP Component MUST be stored securely.
- Follow RFC 7617 and RFC 7235 to integrate with existing HTTP clients.
- 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.