Web Applications
| dmapi | dmweb | |
|---|---|---|
| Description | HTTP-RPC API | Web UI |
| Base Path | /api/v2/ |
/dmpack/ |
| Protocol | FastCGI | CGI |
| Location | server | client, server |
| Configuration | environment variables | environment variables |
| Authentication | HTTP Basic Auth | HTTP Basic Auth |
| Content Types | CSV, JSON, JSON Lines, Namelist, Text | HTML5 |
| HTTP Methods | GET, POST, PUT | GET, POST |
| Database | SQLite 3 | SQLite 3 |
| Read-Only Mode | ✓ | ✓ |
The following web applications are part of DMPACK:
- dmapi
-
HTTP-RPC API for data synchronisation, time series access, and heartbeat collection.
- dmweb
-
Web user interface for database configuration, data access, and plotting.
Both applications may be served by the same web server. It is recommended to run them in lighttpd(1). On Debian-based Linux distributions, install the package by running:
$ sudo apt-get install lighttpd
On FreeBSD, instead:
$ doas pkg install www/lighttpd
The web server is configured through /usr/local/etc/lighttpd/lighttpd.conf. See the lighttpd wiki on how to configure the web server. An
example configuration for dmapi and dmweb is
provided in /usr/local/share/dmpack/lighttpd/.
In the listed examples, the DMPACK executables are assumend to be in /usr/local/bin/, but you may copy
the programs to /var/www/cgi-bin/ or any other directory. Set an appropriate owner, such as the one the
server is running as.
Authentication
The HTTP-RPC API and the web interface will be publicly accessible if the web server is not configured to manage user
authentication. HTTP Basic Auth is a simple method to authenticate users by name and password. The lighttpd(1)
web server includes an auth module with
various back-ends. In the web server configuration, set auth.backend.htpasswd.userfile to the path of the
file that contains the credentials. You can run openssl(1) to add one or more user accounts with hashed
password (SHA-512) to the htpasswd file, in this case /usr/local/etc/lighttpd/htpasswd:
# read AUTH_USR
# read AUTH_PWD
# printf "%s:%s\n" $AUTH_USR `openssl passwd -6 "$AUTH_PWD"` \
>> /usr/local/etc/lighttpd/htpasswd
Enter the user name and the associated password after the read commands. As an alternative to storing
the credentials in a flat file, we can select a different authentication back-end, for example, LDAP, PAM, or database.
See the documentation of the module for further instructions. In the web server configuration, load module
mod_authn_file, select the back-end, and enable authentication globally or for specific routes:
# Load authentication module.
server.modules += ( "mod_authn_file" )
# Authentication back-end and path of user file.
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/usr/local/etc/lighttpd/htpasswd"
# Protected routes.
auth.require = (
"/api/v2" => (
"method" => "basic",
"realm" => "dmpack",
"require" => "valid-user"
),
"/dmpack" => (
"method" => "basic",
"realm" => "dmpack",
"require" => "valid-user"
)
)
Cross-Origin Resource Sharing
If the HTTP-RPC API will be accessed by a client-side application running in the browser, the web server has to be
configured to send the appropriate Cross-Origin
Resource Sharing (CORS) headers. By default, asynchronous JavaScript requests are forbidden by the same-origin
security policy. Refer to the documentation of the web server on how to set the Access-Control-* headers.
For lighttpd(1), load the module mod_setenv and add response headers for OPTION requests:
$HTTP["request-method"] =~ "^(OPTIONS)$" {
setenv.add-response-header = (
"Access-Control-Allow-Origin" => "*",
"Access-Control-Allow-Headers" =>
"accept, origin, x-requested-with, content-type, x-transmission-session-id",
"Access-Control-Expose-Headers" => "X-Transmission-Session-Id",
"Access-Control-Allow-Methods" => "GET, POST, OPTIONS"
)
}
If the web server is behind a reverse proxy, CORS headers should be set by the proxy instead.
Databases
The databases are expected to be in directory /var/dmpack/. Change the environment variables in the web
server configuration to the actual paths. The observation, log, and beat databases the web applications will access must
be created and initialised beforehand:
# dminit --type observ --database /var/dmpack/observ.db --wal
# dminit --type log --database /var/dmpack/log.db --wal
# dminit --type beat --database /var/dmpack/beat.db --wal
Make sure the web server has read and write access to the directory and all databases inside:
# chown -R www:www /var/dmpack
Change www:www to the user and the group the web server is running as.
RPC Server
The snippet in this section may be added to the lighttpd(1) configuration to run the dmapi service. The lighttpd(1) web server does not require an additional FastCGI spawner. The following server modules have to be imported:
mod_authn_file(HTTP Basic Auth)mod_extforward(real IP, only if the server is behind a reverse proxy)mod_fastcgi(FastCGI)
Add the IP address of the proxy server to the list of trusted forwarders to have access to the real IP of a client.
The following example configuration may be appended to your lighttpd.conf:
# Listen on all network interfaces.
$SERVER["socket"] == "0.0.0.0:80" { }
# Load lighttpd modules.
server.modules += (
"mod_authn_file",
"mod_extforward",
"mod_fastcgi"
)
# Real IP of client in case the server is behind a reverse proxy. Set one or
# more trusted proxies.
# extforward.headers = ( "X-Real-IP" )
# extforward.forwarder = ( "<PROXY IP>" => "trust" )
# Set authentication back-end and path of user file.
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/usr/local/etc/lighttpd/htpasswd"
# Protected routes.
auth.require = ( "/api/v2" => (
"method" => "basic",
"realm" => "dmpack",
"require" => "valid-user"
))
# FastCGI configuration. Run 4 worker processes, and pass the database paths
# through environment variables.
fastcgi.server = (
"/api/v2" => ((
"socket" => "/var/lighttpd/sockets/dmapi.sock",
"bin-path" => "/usr/local/bin/dmapi",
"max-procs" => 4,
"check-local" => "disable",
"bin-environment" => (
"DM_BEAT_DB" => "/var/dmpack/beat.db",
"DM_IMAGE_DB" => "/var/dmpack/image.db",
"DM_IMAGE_DIR" => "/var/dmpack/images/",
"DM_LOG_DB" => "/var/dmpack/log.db",
"DM_OBSERV_DB" => "/var/dmpack/observ.db",
"DM_READ_ONLY" => "0"
)
))
)
The FastCGI socket will be written to /var/run/lighttpd/sockets/dmapi.sock. Change
max-procs to the desired number of FastCGI processes. Set the environment variables to the locations of the
databases. The databases must exist prior start. On FreeBSD, add the service to the system rc file
/etc/rc.conf and start the server manually:
# sysrc lighttpd_enable="YES"
# service lighttpd start
On Linux, enable and start the service:
# systemctl enable lighttpd.service
# systemctl start lighttpd.service
If served locally, access the RPC API at http://127.0.0.1/api/v2/.
Web UI
The lighttpd(1) web server has to be configured to run the CGI application under base path
/dmpack. The following server modules are required:
mod_alias(URL rewrites)mod_authn_file(HTTP Basic Auth)mod_cgi(Common Gateway Interface)mod_setenv(CGI environment variables)
The example configuration may be appended to your lighttpd.conf:
# Listen on all network interfaces.
$SERVER["socket"] == "0.0.0.0:80" { }
# Load lighttpd modules.
server.modules += (
"mod_alias",
"mod_authn_file",
"mod_cgi",
"mod_setenv"
)
# Set maximum number of concurrent connections and maximum
# HTTP request size of 8192 KiB (optional).
server.max-connections = 32
server.max-request-size = 8192
# Pass the database paths through environment variables.
setenv.add-environment = (
"DM_BEAT_DB" => "/var/dmpack/beat.db",
"DM_IMAGE_DB" => "/var/dmpack/image.db",
"DM_IMAGE_DIR" => "/images",
"DM_LOG_DB" => "/var/dmpack/log.db",
"DM_OBSERV_DB" => "/var/dmpack/observ.db",
"DM_READ_ONLY" => "0",
"DM_TILE_URL" => "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
)
# Set authentication back-end and path of user file.
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/usr/local/etc/lighttpd/htpasswd"
# Protected routes.
auth.require = ( "/dmpack" => (
"method" => "basic",
"realm" => "dmpack",
"require" => "valid-user"
))
# URL routing.
$HTTP["url"] =~ "^/dmpack" {
# Map URL to CGI executable.
alias.url += ( "/dmpack" => "/usr/local/bin/dmweb" )
# CGI settings. Do not assign file endings to script interpreters,
# execute only applications with execute bit set, enable write and
# read timeouts of 30 seconds.
cgi.assign = ( "" => "" )
cgi.execute-x-only = "enable"
cgi.limits = (
"write-timeout" => 30,
"read-timeout" => 30,
"tcp-fin-propagate" => "SIGTERM"
)
}
Copy the directory dmweb from /usr/local/share/dmpack (or /opt/share/dmpack)
to the WWW root directory, in this case, /var/www, or simply create a symlink:
# ln -s /usr/local/share/dmpack/dmweb /var/www/dmweb
If the image files are stored outside the WWW root directory, for example, in /var/dmpack/images/,
create a symlink, too:
# ln -s /var/dmpack/images /var/www/images
The environment variable DM_IMAGE_DIR must be set to /images. On FreeBSD, add the service
to the system rc file /etc/rc.conf and start the web server manually:
# sysrc lighttpd_enable="YES"
# service lighttpd start
On Linux, enable and start the service:
# systemctl enable lighttpd.service
# systemctl start lighttpd.service
If served locally, access the web application at http://127.0.0.1/dmpack/.