parent
808de3fdbf
commit
48773de33a
|
@ -1,43 +0,0 @@
|
|||
# Software architecture
|
||||
|
||||
## Program flow
|
||||
|
||||
`init.php`
|
||||
: Initializes common values
|
||||
|
||||
`router.php`
|
||||
: Receives every external HTTP request from the web server, executes actions required in any case, executes matching code in `pg-act` if appropriate, and calls `view.php` either way.
|
||||
|
||||
`pg-act/`
|
||||
: Executed when a form is submitted: checks that every parameter is valid and secure, then executes the feature of the page according to the parameters.
|
||||
|
||||
`view.php`
|
||||
: Displays global HTML and includes matching file from `pg-view`.
|
||||
|
||||
`pg-view/`
|
||||
: Displays the main page content (notably HTML forms), may sometimes display form output passed through the `$data` array.
|
||||
|
||||
The `output` function is used to return success or error messages and stop processing of the request.
|
||||
|
||||
## Other components
|
||||
|
||||
`fn/`
|
||||
: Functions, grouped by concerned service
|
||||
|
||||
`jobs/`
|
||||
: CLI scripts ; should be run as the same user as the rest of the program (e.g. `sudo -u servnest php /srv/servnest/core/jobs/something.php`)
|
||||
|
||||
`sftpgo-auth.php`
|
||||
: When someone tries to log in over SFTP, SFTPGo sends username and password to this script, which queries the database and replies whether authentication succeeded or not.
|
||||
|
||||
`DOCS/`
|
||||
: Documentation (some important or standard files may be directly in the root)
|
||||
|
||||
`css/`
|
||||
: Each `.css` file in this directory is declared in every page.
|
||||
|
||||
`db/`
|
||||
: SQlite database, the only directory writable by the program
|
||||
|
||||
`locales/`
|
||||
: Gettext translations, see [translation.md](translation.md)
|
|
@ -1,257 +0,0 @@
|
|||
# Configuration reference
|
||||
|
||||
This document describes the ServNest configuration directives that are part of `config.ini` (distributed as `config.template.ini`). It's an INI file, parsed by [PHP's `parse_ini_file` function](https://www.php.net/manual/function.parse-ini-file.php). Every directive is expected to be present.
|
||||
|
||||
## `[common]`
|
||||
|
||||
### `public_domains[]`
|
||||
|
||||
Allowed server names. Used to make the authentication tokens specific to the service.
|
||||
|
||||
You can specify multiple domains:
|
||||
```
|
||||
public_domains[] = "servnest.example"
|
||||
public_domains[] = "4example4example4example4example4example4example4example.onion"
|
||||
```
|
||||
|
||||
### `prefix`
|
||||
|
||||
Path that is prepended to the HTTP root where the service can be reached. Used for redirections and emitting cookies.
|
||||
|
||||
If the service answers at `https://servnest.example/servnest/`, you need to set `prefix = "/servnest"`.
|
||||
|
||||
### `service_name`
|
||||
|
||||
String defining the displayed identity of the service.
|
||||
|
||||
### `service_emoji`
|
||||
|
||||
Pretty string sometimes prefixed to the service name. Can be empty.
|
||||
|
||||
### `about_url`
|
||||
|
||||
Address of the service presentation page.
|
||||
|
||||
### `services[]`
|
||||
|
||||
Keys `auth`, `reg`, `ns` and `ht` are required.
|
||||
|
||||
Values can be:
|
||||
* `enabled`: The service is provided as usual.
|
||||
* `no-registration` (`auth` only): Same as `enabled`, but no new account can be created.
|
||||
* `error`: For maintenance/debugging purposes, the service is temporarily unavailable. When used on the `auth` service, users can't submit any form, but this doesn't prevent already logged in SFTP users to act on the filesystem.
|
||||
* `disabled` (`reg`, `ns` and `ht` only): The service is ignored everywhere, this installation never provides it.
|
||||
|
||||
## `[dns]`
|
||||
|
||||
This configuration section is used by both the registry (`reg`) and the public name server (`ns`).
|
||||
|
||||
### `knotc_path`
|
||||
|
||||
Filesystem path to the `knotc` binary.
|
||||
|
||||
### `kdig_path`
|
||||
|
||||
Filesystem path to the `kdig` binary. Used to authenticate resources possession using the DNS.
|
||||
|
||||
## `[reg]`
|
||||
|
||||
### `suffixes[]`
|
||||
|
||||
Lists the suffixes that the registry manages.
|
||||
|
||||
The key is the suffix (ending with a dot) and the value is its registration availability, which can be one of the following:
|
||||
|
||||
* `all`: every account can register
|
||||
* `approved`: only approved accounts can register
|
||||
* `none`: nobody can register
|
||||
|
||||
This impacts only new registrations, existing domains can always be managed by users if their suffix appears in the list.
|
||||
|
||||
### `suffixes_path`
|
||||
|
||||
Filesystem path to the registries directory. The full path to the registry zonefile is `suffixes_path` + `/` + suffixes (as defined in suffixes[]) + `zone`.
|
||||
|
||||
### `ttl`
|
||||
|
||||
The TTL of every DNS record created by users (i.e. NS, DS and glue records).
|
||||
|
||||
### `address`
|
||||
|
||||
Host where the Knot DNS server answers the registry values. Should be a secure (local) address, as answers are not authenticated.
|
||||
|
||||
(Used to check the transfer authentication records.)
|
||||
|
||||
## `[ns]`
|
||||
|
||||
### `knot_zones_path`
|
||||
|
||||
Filesystem path to the zones directory. The full path to created zonefiles will be `knot_zones_path/<zone-apex-domain>.zone`.
|
||||
|
||||
### `servers[]`
|
||||
|
||||
The first element is set as the primary server in the SOA when creating a zone.
|
||||
|
||||
All elements are used as NS records for newly created zones and listed in the interface so users can know what NS records must be delegated from the registry.
|
||||
|
||||
The script `jobs/ns-update.php` may be run after updating this setting to update NS records for already created zones.
|
||||
|
||||
### `kzonecheck_path`
|
||||
|
||||
Filesystem path to the `kzonecheck` binary. Used to check sent plaintext zonefiles.
|
||||
|
||||
### `public_soa_email`
|
||||
|
||||
Administrator email address published in every SOA record. Ends with a `.`, `@` is replaced by a `.`, an hypothetical `.` in the first part of the address is escaped using a `\` before, thus `contact.admin@servnest.example` becomes `contact\.admin.servnest.example.`
|
||||
|
||||
### `local_only_check`
|
||||
|
||||
Check for records on the local registry name server when adding a zone.
|
||||
|
||||
Development feature, should not be enabled for a public server.
|
||||
|
||||
## `[ht]`
|
||||
|
||||
### `ht_path`
|
||||
|
||||
Apache can be [chroot](https://httpd.apache.org/docs/current/mod/mod_unixd.html#chrootdir)ed to this directory.
|
||||
|
||||
`<ht_path>/fs/<internal-user-id>/` is the users files base directory.
|
||||
|
||||
`<ht_path>/uri/<address>/` is automatically reachable by Apache (using [mod_vhost_alias](https://httpd.apache.org/docs/current/mod/mod_vhost_alias.html)) and contains relative symlinks to users managed directories.
|
||||
|
||||
### `user_quota_testing`, `user_quota_approved`
|
||||
|
||||
Maximum bytes a user can use on its SFTP space, depending on its account type.
|
||||
|
||||
### `subpath_domain` and `subpath_path`
|
||||
|
||||
For the feature of sites in subpathes of a single domain:
|
||||
|
||||
`subpath_domain` is the said shared domain, displayed in the interface
|
||||
|
||||
`subpath_path` is the filesystem path to the directory whose address is the HTTP root of `subpath_domain`
|
||||
|
||||
`https://<subpath_domain>/example/` maps to `<subpath_path>/example/`
|
||||
|
||||
### `subdomain_domain` and `subdomain_path`
|
||||
|
||||
For the feature of sites in subdomains of a root domain:
|
||||
|
||||
(The root domain must have a wildcard TLS certificate and wildcard AAAA and A records.)
|
||||
|
||||
`subdomain_domain` is the root domain, displayed in the interface
|
||||
|
||||
`subdomain_path` is the filesystem path to the directory whose direct subdirectories are mapped to direct subdomains of `subdomain_domain`
|
||||
|
||||
`https://example.<subdomain_domain>/` maps to `<subdomain_path>/example/`
|
||||
|
||||
### `tor_config_path`
|
||||
|
||||
Filesystem path to the directory containing Tor configuration for onion accesses. The full Tor configuration file path is `tor_config_path/<internal-user-id>/<site-dir-name>`
|
||||
|
||||
### `tor_keys_path`
|
||||
|
||||
Tor sets up keys inside the directory `tor_keys_path/<internal-user-id>/<site-dir-name>/`
|
||||
|
||||
### `tor_user`
|
||||
|
||||
Linux user as who runs the Tor daemon. Some commands are executed as this user through sudo.
|
||||
|
||||
### `tor_reload_cmd`
|
||||
|
||||
Command to execute through sudo to reload the Tor daemon.
|
||||
|
||||
### `onion_internal_host`
|
||||
|
||||
HTTP Onion services listen on port 80 and forward requests to this host.
|
||||
|
||||
### `sudo_path`
|
||||
|
||||
Filesystem path to the sudo binary.
|
||||
|
||||
### `certbot_path`
|
||||
|
||||
Filesystem path to the certbot binary. It is used through sudo to get a Let's Encrypt certificate.
|
||||
|
||||
### `chgrp_path`, `cat_path`, `rm_path`, `mkdir_path`
|
||||
|
||||
Filesystem paths to the corresponding GNU coreutils binary (other implementations are not tested). (Their PHP counterpart can't be used as they need to act as another user through sudo.)
|
||||
|
||||
### `sftpgo_group`
|
||||
|
||||
Linux group as who runs SFTPGo. (Gets full permissions on users directories.)
|
||||
|
||||
### `sftpgo_user`
|
||||
|
||||
Linux user as who runs SFTPGo. (Used to delete files that users created.)
|
||||
|
||||
### `cname`
|
||||
|
||||
For a site with dedicated domain, the domain that users must point their domain to.
|
||||
|
||||
This domain should have the following records:
|
||||
|
||||
AAAA
|
||||
: `ipv6_address`
|
||||
|
||||
A
|
||||
: `ipv4_address`
|
||||
|
||||
CAA
|
||||
: `caa_account_uris[testing]`
|
||||
|
||||
CAA
|
||||
: `caa_account_uris[approved]`
|
||||
|
||||
### `ipv6_address`, `ipv4_address`
|
||||
|
||||
For a site with dedicated domain, when manually copying records, public IPv6 and IPv4 addresses that users must set in their AAAA and A records.
|
||||
|
||||
Should be the same as the AAAA and A records for `cname`.
|
||||
|
||||
### `caa_account_uris[]`
|
||||
|
||||
For a site with dedicated domain, when manually copying records, the URIs of the accounts (both stable and staging) that request Let's Encrypt certificates. Keys `testing` and `approved` must be set to outputs of respectively `certbot show_account --test-cert` and `certbot show_account`
|
||||
|
||||
Should be the same as the CAA records for `cname`.
|
||||
|
||||
### `sftp_pub`
|
||||
|
||||
Filesystem path to where the public key of the SFTP service is available.
|
||||
|
||||
### `sftp_fp`
|
||||
|
||||
Filesystem path to where the public key fingerprint of the SFTP service is available.
|
||||
|
||||
### `sftp_asciiart`
|
||||
|
||||
Filesystem path to where the ASCII art of the public key of the SFTP service is available.
|
||||
|
||||
### `sftp_domain`
|
||||
|
||||
Domain name that users need to direct their SFTP clients to. May be the same key as in `public_domains[]`.
|
||||
|
||||
### `public_sftp_port`
|
||||
|
||||
Network port that users need to direct their SFTP clients to. The common default port is `22`.
|
||||
|
||||
## `[check]`
|
||||
|
||||
This configuration section is used only when running `check.php`.
|
||||
|
||||
### `https_port`
|
||||
|
||||
Port where the public nginx reverse proxy can be reached. Usually `443` for production.
|
||||
|
||||
### `sftp_path`
|
||||
|
||||
Filesystem path to the sftp binary.
|
||||
|
||||
### `sshpass_path`
|
||||
|
||||
Filesystem path to the sshpass binary.
|
||||
|
||||
### `tor_proxy`
|
||||
|
||||
Curl's [CURLOPT_PROXY](https://curl.se/libcurl/c/CURLOPT_PROXY.html) argument, used to test onion services.
|
|
@ -1,304 +0,0 @@
|
|||
# ServNest installation
|
||||
|
||||
## Notable prerequisites
|
||||
|
||||
* sudo 1.9.10+ (available in Debian 12+)
|
||||
* SFTPGo, is usually not available from most distributions (as of january 2023)
|
||||
* Ports 22, 53 and 443 on public IPv6 and IPv4 addresses (not required for a local development/testing setup)
|
||||
|
||||
## Steps
|
||||
|
||||
[The `servnest-mkosi` repository](https://code.antopie.org/servnest/servnest-mkosi) contains all the information needed to automatically build systems configured to run ServNest. Configuration files used in this document refer to it's `install/` subdirectory.
|
||||
|
||||
### DNS resolution
|
||||
|
||||
A caching, DNSSEC-validating and TLS-forwarding local stub resolver is recommended, e.g. systemd-resolved, Knot Resolver or Unbound. For systemd-resolved, `ResolveUnicastSingleLabel=yes` is required.
|
||||
|
||||
### sudo / sudoers
|
||||
|
||||
For the HTTP hosting service, ServNest requires to execute some commands as other users through sudo.
|
||||
|
||||
The required sudoers configuration is `sudoers` and can be placed at `/etc/sudoers.d/servnest`.
|
||||
|
||||
### Tor
|
||||
|
||||
Install the `torrc` file as your Tor configuration. The `%include` statement inside it includes configuration files that will be placed inside any subdirectory of `/srv/servnest/tor-config/`, and is central to the way ServNest uses Tor.
|
||||
|
||||
```shell
|
||||
mkdir /srv/servnest/tor-config
|
||||
chown -R servnest:tor /srv/servnest/tor-config
|
||||
chmod -R u=rwX,g=rX,o= /srv/servnest/tor-config
|
||||
|
||||
mkdir /srv/servnest/tor-keys
|
||||
chown -R tor: /srv/servnest/tor-keys
|
||||
chmod -R u=rwX,g=,o= /srv/servnest/tor-keys
|
||||
```
|
||||
|
||||
If you're using systemd, you might need to override your distribution configuration by placing `tor.service.override.conf` inside `/etc/systemd/system/tor.service.d/`.
|
||||
|
||||
### Knot DNS
|
||||
|
||||
A local primary Knot DNS server is used for both the registry and name server services. Knot DNS configuration is inside `knot.conf`. Change `42053` port to `53` and local IPs to `::` and `0.0.0.0` (or specific ones).
|
||||
|
||||
For a public server, at least one secondary server should be set up. As zones can be dynamically added and deleted from the primary server, [catalog zones](https://zones.cat/) should be used. Configuration for a primary and a secondary server can be found respectively at `mkosi.extra/etc/knot/knot-primary.conf` and `mkosi.extra/etc/knot/knot-secondary.conf`.
|
||||
|
||||
Add user `servnest` to group `knot` to allow ServNest to send commands to Knot:
|
||||
```shell
|
||||
usermod -aG knot servnest
|
||||
```
|
||||
|
||||
#### Database configuration
|
||||
|
||||
Knot configuration must be dynamic, therefore the configuration must stored in database, using:
|
||||
```shell
|
||||
sudo -u knot knotc conf-import /etc/knot/knot.conf
|
||||
```
|
||||
|
||||
The configuration file won't be used by Knot anymore.
|
||||
|
||||
#### Database configuration edition
|
||||
|
||||
Database configuration can be changed using `knotc conf-*` commands, see [Knot DNS 3.2 documentation > Operation > Dynamic configuration](https://www.knot-dns.cz/docs/3.2/html/operation.html#dynamic-configuration). If you don't want to use that and don't want the best uptime possible, you can do the following steps to edit configuration through a plaintext file:
|
||||
|
||||
1. Set `enabled` to `false` in `[reg]` and `[ns]` sections of `config.ini`
|
||||
2. `knotc conf-export /etc/knot/knot.conf`
|
||||
3. Edit `/etc/knot/knot.conf`
|
||||
4. Stop the Knot DNS daemon
|
||||
5. `sudo -u knot knotc conf-import /etc/knot/knot.conf`
|
||||
6. Restart the Knot DNS daemon
|
||||
7. Check for errors in logs: `cat /var/log/knot/knot.log`
|
||||
8. Reverse the first step to `true`
|
||||
|
||||
#### Directories
|
||||
|
||||
```shell
|
||||
mkdir /srv/servnest/reg /srv/servnest/ns
|
||||
chown -R servnest:knot /srv/servnest/reg /srv/servnest/ns
|
||||
chmod -R u=rwX,g=rwX,o= /srv/servnest/reg /srv/servnest/ns
|
||||
```
|
||||
|
||||
#### Registry files initialisation
|
||||
|
||||
In addition to being described in configuration, registry zone files need to be initialized (i.e. SOA and NS records) inside `/srv/servnest/reg/`.
|
||||
|
||||
### ServNest core
|
||||
|
||||
Set up the source code inside `/srv/servnest/core/`:
|
||||
```shell
|
||||
git clone https://code.antopie.org/servnest/servnest/ /srv/servnest/core
|
||||
```
|
||||
|
||||
Set permissions (except for `.git/` and `db/`):
|
||||
```shell
|
||||
chmod -R u=rX,g=rX,o= $(find /srv/servnest/core -mindepth 1 -maxdepth 1 ! -name .git ! -name db)
|
||||
chown -R servnest:nginx $(find /srv/servnest/core -mindepth 1 -maxdepth 1 ! -name .git ! -name db)
|
||||
```
|
||||
|
||||
Generate new SQLite database:
|
||||
```shell
|
||||
sqlite3 /srv/servnest/core/db/servnest.db < /srv/servnest/core/db/schema.sql
|
||||
```
|
||||
|
||||
Set permissions for database:
|
||||
```shell
|
||||
chmod -R u=rwX,g=,o= /srv/servnest/core/db
|
||||
chown -R servnest: /srv/servnest/core/db
|
||||
```
|
||||
|
||||
Initialize database secret keys:
|
||||
```shell
|
||||
echo "UPDATE params SET value = '$(openssl rand -hex 16)' WHERE name = 'username_salt';" | sqlite3 /srv/servnest/core/db/servnest.db
|
||||
```
|
||||
|
||||
Generate gettext translations:
|
||||
```shell
|
||||
msgfmt /srv/servnest/core/locales/fr/C/LC_MESSAGES/messages.po -o /srv/servnest/core/locales/fr/C/LC_MESSAGES/messages.mo
|
||||
chmod u=r,g=,o= /srv/servnest/core/locales/fr/C/LC_MESSAGES/messages.mo
|
||||
chown servnest: /srv/servnest/core/locales/fr/C/LC_MESSAGES/messages.mo
|
||||
```
|
||||
|
||||
### PHP
|
||||
|
||||
In addition to PHP itself, the following PHP extensions are required and their packages probably needs to be installed:
|
||||
|
||||
* pdo
|
||||
* pdo_sqlite
|
||||
* libsodium
|
||||
* gettext
|
||||
* curl (only for the `check.php` script)
|
||||
|
||||
You might also want to enable the OPcache extension to improve performance.
|
||||
|
||||
#### `php.ini`
|
||||
|
||||
Set appropriately your `php.ini` to either `php.ini-production` or `php.ini-development` (distributions usually ship `php.ini-production` as the default `php.ini`).
|
||||
|
||||
Use `php.ini` as additional PHP configuration (e.g. in `/etc/php/conf.d/servnest.ini`).
|
||||
|
||||
#### `php-fpm.conf`
|
||||
|
||||
Use `php-fpm.conf` as the PHP-FPM configuration (e.g. in `/etc/php/php-fpm.d/servnest.conf`).
|
||||
|
||||
##### For systemd
|
||||
|
||||
`php-fpm.service.override.conf` may be required as the PHP-FPM service configuration override.
|
||||
|
||||
### Certbot
|
||||
|
||||
If you are setting up a testing environment, running `certbot` commands in this document without `--test-cert` is probably useless.
|
||||
|
||||
Register an ACME account for Let's Encrypt (production and staging):
|
||||
```shell
|
||||
certbot register --no-eff-email
|
||||
certbot register --no-eff-email --test-cert
|
||||
```
|
||||
|
||||
Copy and adapt `certbot.ini` in `/etc/letsencrypt/cli.ini`
|
||||
|
||||
Install the Certbot deploy hook:
|
||||
```shell
|
||||
cp certbot-deploy-hook.sh /root/certbot-deploy-hook.sh
|
||||
chmod +x /root/certbot-deploy-hook.sh
|
||||
```
|
||||
|
||||
### nginx
|
||||
|
||||
nginx is used for 2 purposes:
|
||||
* serving the PHP interface
|
||||
* acting as a reverse proxy before Apache, terminating TLS and enforcing headers policy
|
||||
|
||||
Create the ACME HTTP challenge directory used by Certbot:
|
||||
```shell
|
||||
mkdir /srv/servnest/acme
|
||||
chown nginx: /srv/servnest/acme
|
||||
chmod u=rX,g=,o= /srv/servnest/acme
|
||||
```
|
||||
|
||||
Generate default self-signed certificates:
|
||||
```shell
|
||||
openssl req -subj '/' -new -newkey RSA:3072 -days 3650 -nodes -x509 -keyout /etc/ssl/private/servnest.key -out /etc/ssl/certs/servnest.crt
|
||||
openssl req -subj '/CN=servnest.test' -new -newkey RSA:3072 -days 3650 -nodes -x509 -keyout /etc/ssl/private/servnest.test.key -out /etc/ssl/certs/servnest.test.crt
|
||||
openssl req -subj '/CN=ht.servnest.test' -new -newkey RSA:3072 -days 3650 -nodes -x509 -keyout /etc/ssl/private/ht.servnest.test.key -out /etc/ssl/certs/ht.servnest.test.crt
|
||||
openssl req -subj '/CN=*.ht.servnest.test' -new -newkey RSA:3072 -days 3650 -nodes -x509 -keyout /etc/ssl/private/wildcard.ht.servnest.test.key -out /etc/ssl/certs/wildcard.ht.servnest.test.crt
|
||||
```
|
||||
|
||||
A precise configuration is inside the `nginx/` directory. It requires the *headers more* nginx module.
|
||||
|
||||
This configuration listens on `[::1]:42443`, `127.0.0.1:42443`, `[::1]:42080` and `127.0.0.1:42080`. For a public server, these should be replaced respectively by `[::]:443`, `0.0.0.0:443`, `[::]:80` and `0.0.0.0:80`. Other addresses (i.e for Onion services and SFTPGo authentication) are not meant to be publicly exposed.
|
||||
|
||||
Once this configuration is put in place, replace self-signed certificates by Let's Encrypt certificates:
|
||||
```shell
|
||||
certbot certonly -d "ht.servnest.example"
|
||||
certbot certonly -d "servnest.example"
|
||||
```
|
||||
|
||||
Getting a Let's Encrypt certificate for a wildcard domain requires an ACME [DNS challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge). The following command asks to setup a DNS record, this can be done by editing `/srv/servnest/reg/servnest.example` then reload configuration using `knotc zone-reload servnest.example`.
|
||||
```shell
|
||||
certbot certonly --manual -d "*.ht.servnest.example"
|
||||
```
|
||||
This method also requires manual operations for renewal.
|
||||
|
||||
The nginx configuration provided above uses the self-signed key pair at the locations set in the `openssl` command above. Replace those by the ones Certbot told you and reload nginx configuration.
|
||||
|
||||
Allow nginx to access certificates:
|
||||
```shell
|
||||
mkdir -p /etc/letsencrypt/archive/ /etc/letsencrypt/live/
|
||||
chmod 710 /etc/letsencrypt/archive/ /etc/letsencrypt/live/
|
||||
chown root:nginx /etc/letsencrypt/archive/ /etc/letsencrypt/live/
|
||||
/root/certbot-deploy-hook.sh
|
||||
```
|
||||
|
||||
### Apache HTTP Server
|
||||
|
||||
Apache in distributions is usually named `httpd`, `apache` or `apache2`. Adapt these instructions as appropriate.
|
||||
|
||||
Apache configuration is inside the `apache/` directory. It runs Apache inside a chroot, though it is not required by the ServNest design. Some paths may need adaptation according to the distribution used (e.g. modules or logs).
|
||||
|
||||
Set up the directory where Apache will be chrooted:
|
||||
```shell
|
||||
mkdir /srv/servnest/ht
|
||||
cp -r /install/http-messages /srv/servnest/ht/http-messages
|
||||
chown -R root:root /srv/servnest/ht
|
||||
chmod -R u=rX,g=rX,o=rX /srv/servnest/ht
|
||||
```
|
||||
|
||||
Set up the directory managed by SFTPGo users:
|
||||
```shell
|
||||
mkdir /srv/servnest/ht/fs
|
||||
chown -R apache:sftpgo /srv/servnest/ht/fs
|
||||
chmod -R u=rX,g=rwX,o= /srv/servnest/ht/fs
|
||||
```
|
||||
|
||||
Set up the directory accessed by Apache and managed by ServNest that maps Web addresses to users directories using links:
|
||||
```shell
|
||||
mkdir /srv/servnest/ht/uri
|
||||
mkdir /srv/servnest/ht/uri/ht.servnest.test # Subpath access
|
||||
chown -R servnest:apache /srv/servnest/ht/uri
|
||||
chmod -R u=rwX,g=rX,o= /srv/servnest/ht/uri
|
||||
```
|
||||
|
||||
For Apache to work in a chroot, hardlinking some system dependencies inside the chroot may be needed:
|
||||
```shell
|
||||
# Display dependencies paths
|
||||
ldd $(which httpd)
|
||||
|
||||
# Create hardlink's parent directory
|
||||
mkdir -p /srv/servnest/ht/usr/lib
|
||||
|
||||
# Hardlink (with a specific example)
|
||||
ln /usr/lib/libc.so.6 /srv/servnest/ht/usr/lib/libc.so.6
|
||||
```
|
||||
|
||||
### SFTPGo
|
||||
|
||||
#### Install SFTPGo
|
||||
|
||||
The script at `../root/sftpgo.sh` can be used to build SFTPGo from source. You can use other methods to get SFTPGo builds.
|
||||
|
||||
Create a directory for configuration: `mkdir /etc/sftpgo`
|
||||
|
||||
Copy the systemd service: `cp /install/sftpgo.service /etc/systemd/system/sftpgo.service`
|
||||
|
||||
Allow listening on privileged ports: `setcap 'cap_net_bind_service=+ep' /usr/local/bin/sftpgo`
|
||||
|
||||
#### Configure SFTPGo for ServNest
|
||||
|
||||
Generate a key pair using `ssh-keygen -f /etc/sftpgo/ed25519 -t ed25519 -N "" -C ""`
|
||||
|
||||
Compute key pair fingerprints:
|
||||
```shell
|
||||
fp=($(ssh-keygen -l -f /etc/sftpgo/ed25519))
|
||||
echo ${fp[1]} > /etc/sftpgo/ed25519.fp
|
||||
ssh-keygen -lv -f /etc/sftpgo/ed25519 | tail -n +2 > /etc/sftpgo/ed25519.asciiart
|
||||
```
|
||||
|
||||
Copy the SFTPGo configuration: `cp /install/sftpgo.toml /etc/sftpgo/sftpgo.toml`. For a public setup, change `[[sftpd.bindings]]` sections in it to public IPs and port 22. You can optionally set up in `/etc/sftpgo/banner.txt` a message displayed to users when logging in.
|
||||
|
||||
Add user `servnest` to group `sftpgo`:
|
||||
```shell
|
||||
usermod -aG sftpgo servnest
|
||||
```
|
||||
|
||||
Permissions for `/etc/sftpgo`:
|
||||
```shell
|
||||
chown -R sftpgo: /etc/sftpgo
|
||||
chmod -R u=rX,g=rX,o= /etc/sftpgo
|
||||
chmod u=r,g=,o= /etc/sftpgo/ed25519
|
||||
```
|
||||
|
||||
Generate and add SSHFP record for the public SFTP domain:
|
||||
```shell
|
||||
echo sftp.servnest.test. 86400 SSHFP 4 2 $(cut -d ' ' -f 2 /etc/sftpgo/ed25519.pub | base64 -d | sha256sum | cut -d ' ' -f 1) >> /srv/servnest/reg/servnest.test.zone
|
||||
```
|
||||
|
||||
### ServNest core configuration
|
||||
|
||||
Copy the configuration template to the actual configuration file and adapt it according to [the ServNest configuration reference](configuration.md):
|
||||
```shell
|
||||
cp /srv/servnest/core/config.template.ini /srv/servnest/core/config.ini
|
||||
vim /srv/servnest/core/config.ini
|
||||
```
|
||||
|
||||
### Cronie
|
||||
|
||||
Set the `cronie` file as `/etc/cron.d/servnest`.
|
|
@ -1,38 +0,0 @@
|
|||
# Memo to work with gettext
|
||||
|
||||
## As a developer
|
||||
|
||||
Extract messages to be translated from the source files and into a Portable Object Template file:
|
||||
```shell
|
||||
xgettext --from-code=UTF-8 --no-wrap -d messages -p locales/ *.php */*.php */*/*.php
|
||||
mv locales/messages.po locales/messages.pot
|
||||
```
|
||||
|
||||
Merge messages into existing Portable Objects:
|
||||
```shell
|
||||
msgmerge --no-wrap locales/fr/C/LC_MESSAGES/messages.po locales/messages.pot -o locales/fr/C/LC_MESSAGES/messages.po
|
||||
```
|
||||
|
||||
## As a translator
|
||||
|
||||
### To start a new translation
|
||||
|
||||
```shell
|
||||
mkdir -p locales/fr/C/LC_MESSAGES/
|
||||
msginit -i locales/messages.pot -o locales/fr/C/LC_MESSAGES/messages.po
|
||||
```
|
||||
|
||||
### To translate
|
||||
|
||||
Edit `locales/fr/C/LC_MESSAGES/messages.po` using either
|
||||
* any text editor
|
||||
* dedicated translation software like [Poedit](https://poedit.net/), [KDE's Lokalize](https://apps.kde.org/lokalize/) or [GNOME Translation Editor](https://wiki.gnome.org/Apps/Gtranslator).
|
||||
|
||||
## As an administrator
|
||||
|
||||
To compile Portable Objects into Machine Objects:
|
||||
```shell
|
||||
msgfmt locales/fr/C/LC_MESSAGES/messages.po -o locales/fr/C/LC_MESSAGES/messages.mo
|
||||
```
|
||||
|
||||
Machine Objects files are kept in cache by the PHP gettext extension, so PHP-FPM needs to be restarted to update translations.
|
127
README.md
127
README.md
|
@ -1,126 +1,5 @@
|
|||
# ServNest
|
||||
This is the ServNest source code, see [the ServNest documentation website](https://servnest.niv.re/) ([its source code](https://code.antopie.org/servnest/docs/)) for more information.
|
||||
|
||||
ServNest (formerly Niver) is software allowing users to manage 3 independent services:
|
||||
# License
|
||||
|
||||
* Public suffix registry
|
||||
* Domain name server
|
||||
* Static HTTP site hosting
|
||||
|
||||
## Status
|
||||
|
||||
ServNest is alpha software.
|
||||
|
||||
Proper versioning, changelog and upgrade/migration instructions are still missing.
|
||||
|
||||
[https://niver.niv.re/](Niver) is an installation administrated by the main developer.
|
||||
|
||||
## Detailed services features
|
||||
|
||||
### Public suffix registry (`reg`)
|
||||
|
||||
* Register a subdomain of the registry
|
||||
* Set domain's nameservers
|
||||
* Set a DS record to enable DNSSEC
|
||||
* Set Glue records
|
||||
* Display records
|
||||
* Transfer domain to another account
|
||||
* Partial `CSYNC` and `CDS` support to synchronize from child zone
|
||||
|
||||
### Name server (`ns`)
|
||||
|
||||
* Host a zone on the server
|
||||
* Plain zone file edition
|
||||
* Dedicated forms to set/unset `A`, `AAAA`, `NS`, `TXT`, `CAA`, `SRV`, `MX`, `SRV`, `SSHFP`, `TLSA`, `CNAME`, `DNAME` and `LOC` records
|
||||
* Display records or the full zone file
|
||||
* Keep records in sync with another domain (`CNAME` alternative for apex domains)
|
||||
|
||||
### Static HTTP site hosting (`ht`)
|
||||
|
||||
Upload site's files to the server using SFTP. The way the site is accessed can then be choosed:
|
||||
|
||||
* Dedicated domain name and Let's Encrypt certificate
|
||||
* Dedicated onion service (through Tor)
|
||||
* Subdomain of a shared root domain
|
||||
* HTTP subpath of a shared domain
|
||||
|
||||
Some Apache configuration directives are available through `.htaccess`.
|
||||
|
||||
## Software used
|
||||
|
||||
[PHP](https://www.php.net/)
|
||||
: main language
|
||||
|
||||
[SQLite](https://www.sqlite.org/index.html)
|
||||
: accounts data storage
|
||||
|
||||
[Knot DNS](https://www.knot-dns.cz/)
|
||||
: DNS server for both registry and DNS hosting
|
||||
|
||||
[sudo](https://www.sudo.ws/) 1.9.10+
|
||||
: execute actions that match a regex as privileged or specific users
|
||||
|
||||
[SFTPGo](https://github.com/drakkan/sftpgo)
|
||||
: upload sites files using SFTP
|
||||
|
||||
[Apache HTTP Server](https://httpd.apache.org/)
|
||||
: static HTTP server, with content negotiation and `.htaccess` dynamic configuration
|
||||
|
||||
[nginx](https://nginx.org/)
|
||||
: HTTP reverse proxy for Apache; terminates TLS and enforces security headers
|
||||
|
||||
Tor
|
||||
: [Onion services](https://community.torproject.org/onion-services/)
|
||||
|
||||
[Certbot](https://certbot.eff.org/)
|
||||
: get [Let's Encrypt](https://letsencrypt.org/) certificates for TLS
|
||||
|
||||
Cronie (or another cron daemon)
|
||||
: periodically run script to sync registry records with child zones and pseudo-CNAMEs at apex
|
||||
|
||||
[GNU Core Utilities](https://www.gnu.org/software/coreutils/) or [BusyBox](https://www.busybox.net/)
|
||||
: manipulate the filesystem through sudo
|
||||
|
||||
## Installation
|
||||
|
||||
Manual installation instructions can be found in [`DOCS/installation.md`](DOCS/installation.md).
|
||||
|
||||
[servnest-mkosi](https://code.antopie.org/servnest/servnest-mkosi) can automatically build a system image for ServNest and has configuration files and scripts.
|
||||
|
||||
## Resources
|
||||
|
||||
[Matrix room](matrix:r/servnest:matrix.antopie.org) (`#servnest:matrix.antopie.org`)
|
||||
: english/french
|
||||
: discuss, get help and organise contribution
|
||||
|
||||
[Issue tracker](https://code.antopie.org/servnest/servnest/issues)
|
||||
: english
|
||||
: keep track of bugs et wanted features
|
||||
|
||||
[Git repository](https://code.antopie.org/servnest/servnest)
|
||||
: english
|
||||
: code, administration documentation
|
||||
|
||||
## Direct contact details
|
||||
|
||||
Find them on [https://miraty.antopie.org/](my site).
|
||||
|
||||
## License
|
||||
|
||||
ServNest is ethical libre software: you can use, redistribute or modify it under the terms of the CNPL-NAv7+ as found in LICENSE.md or at <https://git.pixie.town/thufie/npl-builder>.
|
||||
|
||||
## Somehow similar projects
|
||||
|
||||
[DNSManager](https://github.com/KaneRoot/dnsmanager):
|
||||
: domain registry powering [netlib.re](https://netlib.re/)
|
||||
|
||||
[EU.org](https://nic.eu.org/)
|
||||
: domain registry
|
||||
|
||||
[DNS Witch](https://dns-witch.net.eu.org/)
|
||||
: user-friendly domain hosting based on EU.org
|
||||
|
||||
[Codeberg Pages](https://codeberg.page/)
|
||||
: static website hosting published through Git
|
||||
|
||||
[Njalla](https://njal.la/)
|
||||
: anonymous domain registrar
|
||||
ServNest is ethical libre software: you can use, redistribute or modify it under the terms of the CNPL-NAv7+ as found in [`LICENSE.md`](LICENSE.md) or at <https://git.pixie.town/thufie/npl-builder>.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; Directives here are described in DOCS/configuration.md
|
||||
; Directives here are described in https://servnest.niv.re/back/configuration
|
||||
|
||||
[common]
|
||||
public_domains[] = "servnest.test"
|
||||
|
|
Loading…
Reference in New Issue