Browse Source

Add installation instructions

Miraty 2 years ago
parent
commit
ff7e770654
2 changed files with 297 additions and 5 deletions
  1. 290 0
      DOCS/installation.md
  2. 7 5
      README.md

+ 290 - 0
DOCS/installation.md

@@ -0,0 +1,290 @@
+# 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
+chown -R servnest:knot /srv/servnest/reg
+chmod -R u=rwX,g=rwX,o= /srv/servnest/reg
+
+mkdir /srv/servnest/ns
+chown -R servnest:knot /srv/servnest/ns
+chmod -R u=rwX,g=rwX,o= /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.
+
+### 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`
+
+#### 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
+
+Configure `/srv/servnest/core/config.ini` according to [the ServNest configuration reference](configuration.md).

+ 7 - 5
README.md

@@ -18,7 +18,7 @@ I plan to create and maintain a public stable instance of ServNest, but I haven'
 * Set domain's nameservers
 * Set a DS record to enable DNSSEC
 * Set Glue records
-* Display your records
+* Display records
 * Transfer domain to another account
 
 ### Name server (`ns`)
@@ -26,7 +26,7 @@ I plan to create and maintain a public stable instance of ServNest, but I haven'
 * Host a zone on the server
 * Zone file edition through `<textarea>`
 * Dedicated forms to set/unset `A`, `AAAA`, `NS`, `TXT`, `CAA`, `SRV`, `MX`, `SRV`, `SSHFP`, `TLSA`, `CNAME`, `DNAME` and `LOC` records
-* Display your records or the full zone file
+* Display records or the full zone file
 
 ### Static HTTP site hosting (`ht`)
 
@@ -37,7 +37,7 @@ Upload site's files to the server using SFTP. The way the site is accessed can t
 * Subdomain of a shared root domain
 * HTTP subpath of a shared domain
 
-Some Apache configuration directive are available through `.htaccess`.
+Some Apache configuration directives are available through `.htaccess`.
 
 ## Software used
 
@@ -68,12 +68,14 @@ Tor
 [Certbot](https://certbot.eff.org/)
 : get [Let's Encrypt](https://letsencrypt.org/) certificates for TLS
 
-[GNU Core Utilities](https://www.gnu.org/software/coreutils/)
+[GNU Core Utilities](https://www.gnu.org/software/coreutils/) or [BusyBox](https://www.busybox.net/)
 : manipulate the filesystem through sudo
 
 ## Installation
 
-There is currently no proper documentation to install ServNest, but you can create a system image or look at configuration files and scripts from [servnest-mkosi](https://code.antopie.org/servnest/servnest-mkosi).
+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.
 
 ## Contribute