Add installation instructions
This commit is contained in:
parent
81229a5e33
commit
ff7e770654
2 changed files with 297 additions and 5 deletions
290
DOCS/installation.md
Normal file
290
DOCS/installation.md
Normal file
|
@ -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).
|
12
README.md
12
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 domain's nameservers
|
||||||
* Set a DS record to enable DNSSEC
|
* Set a DS record to enable DNSSEC
|
||||||
* Set Glue records
|
* Set Glue records
|
||||||
* Display your records
|
* Display records
|
||||||
* Transfer domain to another account
|
* Transfer domain to another account
|
||||||
|
|
||||||
### Name server (`ns`)
|
### 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
|
* Host a zone on the server
|
||||||
* Zone file edition through `<textarea>`
|
* 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
|
* 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`)
|
### 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
|
* Subdomain of a shared root domain
|
||||||
* HTTP subpath of a shared 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
|
## Software used
|
||||||
|
|
||||||
|
@ -68,12 +68,14 @@ Tor
|
||||||
[Certbot](https://certbot.eff.org/)
|
[Certbot](https://certbot.eff.org/)
|
||||||
: get [Let's Encrypt](https://letsencrypt.org/) certificates for TLS
|
: 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
|
: manipulate the filesystem through sudo
|
||||||
|
|
||||||
## Installation
|
## 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
|
## Contribute
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue