.gitlab-ci-files | ||
httpd | ||
logrotate | ||
scripts/util | ||
src | ||
.gitignore | ||
.gitlab-ci.yml | ||
CHANGELOG.md | ||
COPYING | ||
lime-server.spec | ||
Makefile | ||
README.md | ||
README.packaging.md | ||
README.update.md |
PHP Authenticated Lime server
Disclaimer
The secure access to this server is based on authentication credentials provided externally, it is designed to be used in conjunction with flexisip but may be used with any other login/password provider as long as the login follow the following rule:
- username and realm are combined to authentify the lime device id which is expected to be the GRUU
so it is checked that the lime device id matches:
/^sip:<username>@<realm>;gr=*/
Requirements
The server requires a functional web server serving php script located (by default) in /opt/belledonne-communications/share/lime-server/lime-server.php
The server requires reading access to an authentication database (holding username and password hash - see configuration file for details).
The server requires a database read/write access, the tables content details is : Users table:
- Uid: as primary key (internal use)
- UserId: shall be the GRUU
- Ik: Identity key - EDDSA public key
- SPk: the current signed pre-key - ECDH public key
- SPk_sig: current SPk public key signed with Identity key
- SPk_id: id for SPk provided and internally used by client) - 4 bytes unsigned integer
OPk table:
- id: as primary key (internal use)
- Uid: Id of user owning that key, a foreign key
- OPk: the public key (ECDH public key)
- OPk_id: id for OPk provided and internally used by client - 4 bytes unsigned integer
Requests table:
- source: the source UserId of the bundle request
- target: the target UserId of the bundle request
- at: timestamp set when the request is served
Config table: holds one row: version
- Name: the parameter name (version)
- Value: the parameter value (db version scheme)
Security Considerations
Recommendations:
- Use updated PHP version installed from a reliable source
- Serve the php script on HTTPS connection only, be sure the TLS configuration is correct and does not allow weak cipher schemes
- The database access must use a dedicated user with access allowing only the needed access rights: read on the Config table, read/write on the Users and OPk tables
- The lime-createBase.php shall be deleted after use or at least not served by the web server (It is protected against execution not in command line but better be safe than sorry)
Notes:
- This server does not rely on any php framework but use core PHP functionnalities only and mysqli PHP module, this keeps it simple to update and limit the attack surface.
- All database access in this scripts use mysqli prepared statements.
Foreign Domain support
When a server receives a key bundle request including users on another domain(refered here as foreign domain), it has the possibility to request them to the foreign domain lime server. Ex:
- the local server serves the domain sip.example.org and receive a key bundle request for user1@sip.foreign-example.org
- the local server requests to the sip.foreign-example.org lime server the key bundle, and then forward the response to the original requester
To enable this functionnality, the configuration on the local server must:
- have an URL to contact the lime server managing sip.foreign-example.org domain, provide a way to authenticate on it
- the foreign-example.org lime server must be configured to accept requests from sip.example.org lime server and authenticate it
One server may authenticate itself to another one using:
-
TLS Client certificate The client certificate must have a SAN (CN is deprecated but accepted) holding the server username accepted by the other server. Ex: sip.example.org will authenticate on a foreign lime server presenting a certificate with a SAN holding the a username accepted by the foreign server. The foreign server must be configured to accept this certificate(so its CA can verify it) and accept the username present in the SAN.
-
HTTP digest authentication: The digest auth uses SHA-256 auth. - On the local server, set the sha-256(user:realm:password) in the configuration array holding the foreign server url and credentials - On the foreign server, set the same hash in the configuration array holding the list of external domains server authorized to make key bundle requests
Note: You do not really need to know the password used in the digest auth, just put the same hash(a 64 characters hexadecimal string) in both configuration file. If you do need to know the password - there shall not be any good reason for that - the username is set configuration file (the local domain is used by default) and the realm is the foreign domain one.
Deployment
- complete the configuration file /etc/lime-server/lime-server.conf (see configuration file itself and the configuration section of this readme for details The script is served at SERVER_URL/lime-server/lime-server.php, configure your clients accordingly
User Authentication
This server supports two clients authentication methods, which are enabled by default.
TLS client certificate
When this method is enabled, if your web server is correctly configured, for example using Apache, in the VirtualHost section:
SSLVerifyClient optional
or SSLVerifyClient require
SSLVerifyDepth 10
SSLOptions +StdEnvVars
SSLCACertificateFile <path to your enabled certificate chain
SSLCARevocationFile <path to your revoked client certificate
The client identity (its sip:uri) is expected to be provided in subject altName DNS entry but also fallback on subject Common Name if no identity matching the provided lime userid (the GRUU) is find in the altName DNS entries.
Digest authentication
When this option is enabled the lime-server configuration file must hold:
AUTH_REALM
: the realm to perform authentication on. If this is not defined, the realm is fetched from the HTTP header,
allowing for multiple domains to run on one server.
AUTH_NONCE_KEY
: a secret key to generate the nonce used by the digest authentication scheme
AUTH_QUERY
: a sql query to reach the user/password DB.
Digest authentication supports MD5 and SHA256 hashes
When TLS client certificates is enabled but optional and the client fails to present a certificate, if the digest authentication mode is enabled, the user will be given the opportunity to log in using the digest scheme.
Invalid, revoked certificate or mismatch between certificate subject CN and lime user name (given in the From
http header)
will lead to a connection rejection without trying to log using the digest scheme.
Configuration
At install the server is not functionnal, to set it up, in the configuration file, you must:
-
activate a subset of the supported base algorithm (from C25519, C448 and C25519K512)
-
set all the database access codes : lime database and user/password db (if digest authentication is enabled)
-
create the lime database and tables according to your selected base algorithms :
- either using the php script provided (prefered method):
- first complete the configuration file. The user/password given in the configuration must be granted with database creation rights
cd /opt/belledonne-communications/share/lime-server && php lime-createBase.php --curve [C25519|C448|C25519K512]
This step must be run for each of the enabled base algorithm- lime-createBase.php use the default /etc/lime-server/lime-server.conf, you can provide another one using --config_path option.
- set in the configuration file a user with mysql access restricted as indicated in the security considerations sections.
- or running the SQL code given below with a user granted to create databases.
- either using the php script provided (prefered method):
-
set the
AUTH_NONCE_KEY
if the digest authentication scheme is enabled -
Configure the optional features, see the config file comments for details. WARNING: external domain and key bundle request limitation interact in a tricky way. If you enable both, make sure you understand what you're doing. See the configuration file for details on this.
START TRANSACTION;
CREATE TABLE IF NOT EXISTS `Users` (
`Uid` INTEGER NOT NULL AUTO_INCREMENT,
`UserId` TEXT COLLATE utf8_bin NOT NULL,
`Ik` BLOB NOT NULL,
`SPk` BLOB DEFAULT NULL,
`SPk_sig` BLOB DEFAULT NULL,
`SPk_id` INTEGER UNSIGNED DEFAULT NULL,
PRIMARY KEY(`Uid`),
INDEX(UserId(100))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `OPk` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`Uid` INTEGER NOT NULL,
`OPk` BLOB NOT NULL,
`OPk_id` INTEGER UNSIGNED NOT NULL,
PRIMARY KEY(`id`),
FOREIGN KEY(`Uid`) REFERENCES Users(`Uid`) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS Requests (
`source` TEXT NOT NULL,
`target` TEXT NOT NULL,
`at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `Config` (
`Name` VARCHAR(20) COLLATE utf8_bin DEFAULT NULL,
`Value` INTEGER NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `Config` (`Name`, `Value`) VALUES
('version', 1),
CREATE EVENT clean_requests ON SCHEDULE EVERY 1 WEEK DO
DELETE FROM Requests WHERE at < DATE_SUB(NOW(), INTERVAL 2 WEEK);
COMMIT;
Migrate to version 1.3 and above from previous versions
See README.update.md
Package
See README.packaging.md