Niver > ServNest

This commit is contained in:
Miraty 2023-01-29 21:09:00 +01:00
parent 3b97b3cc2f
commit b2bfbb7bf8
14 changed files with 66 additions and 57 deletions

2
.gitignore vendored
View file

@ -1,2 +1,2 @@
/db/niver.db
/db/servnest.db
/locales/*/C/LC_MESSAGES/messages.mo

View file

@ -14,7 +14,7 @@ Allowed server names. Used to make the authentication tokens specific to the ser
You can specify multiple domains:
```
public_domains[] = "niver.example"
public_domains[] = "servnest.example"
public_domains[] = "4example4example4example4example4example4example4example.onion"
```
@ -22,7 +22,7 @@ public_domains[] = "4example4example4example4example4example4example4example.oni
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://niver.example/niver/`, you need to set `prefix = "/niver"`.
If the service answers at `https://servnest.example/servnest/`, you need to set `prefix = "/servnest"`.
### `service_name`
@ -98,7 +98,7 @@ Filesystem path to the `kzonecheck` binary. Used to check sent plaintext zonefil
### `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@niver.example` becomes `contact\.admin.niver.example.`
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.`
## `[ht]`
@ -170,6 +170,10 @@ Filesystem path to the certbot binary. It is used through sudo to get a Let's En
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.)
### `acme_path`
Filesystem path to the root directory that is served when a request hits `.well-known/acme-challenge` on port 80. Certbot places ACME authentication files here to get Let's Encrypt certificates through the HTTP-01 challenge.
### `sftpgo_group`
Linux group as who runs SFTPGo. (Gets full permissions on users directories.)
@ -178,7 +182,6 @@ Linux group as who runs SFTPGo. (Gets full permissions on users directories.)
Linux user as who runs SFTPGo. (Used to delete files that users created.)
### `ipv6_address`, `ipv4_address`
Public IPv6 and IPv4 addresses that users must set in their AAAA and A records for a site with dedicated domain.

View file

@ -1,20 +1,16 @@
# Niver
# ServNest
Niver is a set of 3 network services:
ServNest (formerly Niver) is software providing a web interface allowing users to manage 3 independent services:
* Public suffix registry
* Nameserver
* Domain name server
* Static HTTP site hosting
## Demo
<https://niver.4.niv.re/>
## Status
I plan to create and maintain a public stable instance of Niver, but I haven't done so yet. Thus Niver is not yet tested with real world and long-term usages, and is **alpha software**.
I plan to create and maintain a public stable instance of ServNest, but I haven't done so yet. Thus it is not yet tested with real world and long-term usages, and is **alpha software**.
## Detailed features
## Detailed services features
### Public suffix registry (`reg`)
@ -23,19 +19,23 @@ I plan to create and maintain a public stable instance of Niver, but I haven't d
* Set a DS record to enable DNSSEC
* Set Glue records
* Display your records
* Transfer domain to another account
### Nameserver (`ns`)
### Name server (`ns`)
* 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
### HTTP hosting (`ht`)
### Static HTTP site hosting (`ht`)
* Upload your site's files using SFTP
* Host a static site with a domain name and a Let's Encrypt certificate
* Host a static site with an Onion service (through Tor)
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
## Software used
@ -68,13 +68,13 @@ Tor
## Installation
There is currently no proper documentation to install Niver, but you can create a system image or look at configuration files and scripts from [niver-mkosi](https://code.antopie.org/niver/niver-mkosi).
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).
## Contribute
- Git repository : <https://code.antopie.org/niver/niver>
- Issue tracker : <https://code.antopie.org/niver/niver/issues>
- Matrix channel : [#niver:matrix.antopie.org](matrix:r/niver:matrix.antopie.org)
- Git repository : <https://code.antopie.org/servnest/servnest>
- Issue tracker : <https://code.antopie.org/servnest/servnest/issues>
- Matrix channel : [#servnest:matrix.antopie.org](matrix:r/servnest:matrix.antopie.org)
## Direct contact details
@ -82,7 +82,7 @@ See <https://miraty.antopie.org/>.
## License
Niver 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>.
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>.
## Similar projects

View file

@ -1,11 +1,11 @@
; Directives here are described in DOCS/configuration.md
[common]
root_path = "/srv/niver/core"
public_domains[] = "niver.test"
root_path = "/srv/servnest/core"
public_domains[] = "servnest.test"
prefix = ""
service_name = "Niver"
service_emoji = "🪐"
service_name = "ServNest"
service_emoji = "🪺"
[dns]
knotc_path = "/usr/sbin/knotc"
@ -13,37 +13,37 @@ kdig_path = "/usr/bin/kdig"
[reg]
enabled = true
suffixes[niver.test.] = "approved"
suffixes[test.niver.test.] = "all"
suffixes[old.niver.test.] = "none"
suffixes_path = "/srv/niver/reg"
suffixes[servnest.test.] = "approved"
suffixes[test.servnest.test.] = "all"
suffixes[old.sernnest.test.] = "none"
suffixes_path = "/srv/servnest/reg"
ttl = 86400
address = "[::1]:42053"
[ns]
enabled = true
knot_zones_path = "/srv/niver/ns"
servers[] = "ns1.niver.test."
servers[] = "ns2.niver.test."
knot_zones_path = "/srv/servnest/ns"
servers[] = "ns1.servnest.test."
servers[] = "ns2.servnest.test."
kzonecheck_path = "/usr/bin/kzonecheck"
public_soa_email = "hostmaster.niver.invalid."
public_soa_email = "hostmaster.invalid."
[ht]
enabled = true
ht_path = "/srv/niver/ht"
ht_path = "/srv/servnest/ht"
subpath_domain = "ht.niver.test"
subpath_path = "/srv/niver/subpath"
subpath_domain = "ht.servnest.test"
subpath_path = "/srv/servnest/subpath"
subdomain_domain = "ht.niver.test"
subdomain_path = "/srv/niver/subdomain"
subdomain_domain = "ht.servnest.test"
subdomain_path = "/srv/servnest/subdomain"
nginx_config_path = "/srv/niver/nginx"
nginx_config_path = "/srv/servnest/nginx"
nginx_reload_cmd = "/usr/bin/systemctl reload nginx"
tor_config_path = "/srv/niver/tor-config"
tor_keys_path = "/srv/niver/tor-keys"
tor_config_path = "/srv/servnest/tor-config"
tor_keys_path = "/srv/servnest/tor-keys"
tor_user = "tor"
tor_reload_cmd = "/usr/bin/systemctl reload tor"
@ -54,6 +54,8 @@ cat_path = "/usr/bin/cat"
rm_path = "/usr/bin/rm"
mkdir_path = "/usr/bin/mkdir"
acme_path = "/srv/servnest/acme"
sftpgo_group = "sftpgo"
sftpgo_user = "sftpgo"
@ -63,7 +65,7 @@ ipv4_address = "127.0.0.1"
sftp_pub = "/etc/sftpgo/ed25519.pub"
sftp_fp = "/etc/sftpgo/ed25519.fp"
sftp_asciiart = "/etc/sftpgo/ed25519.asciiart"
sftp_domain = "sftp.niver.test"
sftp_domain = "sftp.servnest.test"
public_sftp_port = 2022
; Will be used in configuration files

View file

@ -1,5 +1,5 @@
:root, .niver {
:root, .common {
--svc-color: var(--foreground-color);
}

View file

@ -4,7 +4,7 @@ function output($code, $msg = '', $logs = ['']) {
http_response_code($code);
$shortCode = $code / 100 % 10;
if ($shortCode === 5)
error_log('Niver internal error: ' . strip_tags($msg) . implode(LF, $logs));
error_log('Internal error: ' . strip_tags($msg) . implode(LF, $logs));
$final_message = match ($shortCode) {
2 => ($msg === '') ? '' : '<p><output>' . _('<strong>Success</strong>: ') . '<em>' . $msg . '</em></output></p>' . LF,
4 => '<p><output>' . _('<strong>User error</strong>: ') . '<em>' . $msg . '</em></output></p>' . LF,

View file

@ -23,7 +23,7 @@ function regDeleteDomain($domain) {
if (file_put_contents($path, $content) === false)
output(500, 'Failed to write new registry file.');
// Delete from Niver's database
// Delete from database
query('delete', 'registry', [
'domain' => $domain,
'username' => $_SESSION['id'],

View file

@ -32,7 +32,7 @@ rateLimit();
addSite($_SESSION['id'], $_POST['dir'], $_POST['domain'], 'dns');
exec('2>&1 ' . CONF['ht']['sudo_path'] . ' ' . CONF['ht']['certbot_path'] . ' certonly' . (($_SESSION['type'] === 'approved') ? '' : ' --test-cert') . ' --key-type rsa --rsa-key-size 3072 --webroot --webroot-path /srv/niver/acme --domain ' . $_POST['domain'], $output, $returnCode);
exec('2>&1 ' . CONF['ht']['sudo_path'] . ' ' . CONF['ht']['certbot_path'] . ' certonly' . (($_SESSION['type'] === 'approved') ? '' : ' --test-cert') . ' --key-type rsa --rsa-key-size 3072 --webroot --webroot-path ' . CONF['ht']['acme_path'] . ' --domain ' . $_POST['domain'], $output, $returnCode);
if ($returnCode !== 0)
output(500, 'Certbot failed to get a Let\'s Encrypt certificate.', $output);

View file

@ -46,7 +46,7 @@ if (chmod($knotZonePath, 0660) !== true)
knotcConfExec([
"set 'zone[" . $_POST['domain'] . "]'",
"set 'zone[" . $_POST['domain'] . "].template' 'niver'",
"set 'zone[" . $_POST['domain'] . "].template' 'servnest'",
]);
output(200, _('Zone created.'));

View file

@ -1,9 +1,13 @@
# List of subdomains not available to register
#
# They may be forbidden because:
# - they may be privileged for impersonating Niver, spamming or fishing
# - they may be privileged for impersonating, spamming or fishing
# - they are reserved for a project asking for it and deserving such a well-known name
servnest
serv
nest
srvnst
niver
# Registry-related

View file

@ -8,7 +8,7 @@
<div>
<label for="subdomain"><?= _('Subdomain') ?></label>
<br>
<input id="subdomain" pattern="<?= SUBDOMAIN_REGEX ?>" required="" placeholder="niver" name="subdomain" type="text">
<input id="subdomain" pattern="<?= SUBDOMAIN_REGEX ?>" required="" placeholder="servnest" name="subdomain" type="text">
</div>
<div>
<label for="suffix"><?= _('Suffix') ?></label>

View file

@ -8,7 +8,7 @@
<div>
<label for="subdomain"><?= _('Subdomain') ?></label>
<br>
<input id="subdomain" pattern="<?= SUBDOMAIN_REGEX ?>" required="" placeholder="niver" name="subdomain" type="text">
<input id="subdomain" pattern="<?= SUBDOMAIN_REGEX ?>" required="" placeholder="servnest" name="subdomain" type="text">
</div>
<div>
<label for="suffix"><?= _('Suffix') ?></label>

View file

@ -1,7 +1,7 @@
<?php
define('CONF', parse_ini_file(__DIR__ . '/config.ini', true, INI_SCANNER_TYPED));
define('DB', new PDO('sqlite:' . CONF['common']['root_path'] . '/db/niver.db'));
define('DB', new PDO('sqlite:' . CONF['common']['root_path'] . '/db/servnest.db'));
$locale = 'en';
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
@ -70,7 +70,7 @@ if (!TITLES_LINEAGE[array_key_last(TITLES_LINEAGE)]) {
exit('Page not found.');
}
const SESSION_COOKIE_NAME = 'niver-session-key';
const SESSION_COOKIE_NAME = 'servnest-session-key';
function startSession() {
session_start([
'name' => SESSION_COOKIE_NAME,

View file

@ -25,7 +25,7 @@
<?php
foreach (TITLES_LINEAGE as $id => $title) {
$lastTitle = (TITLES_LINEAGE[array_key_last(TITLES_LINEAGE)] === $title);
echo '<ul><li>' . ($lastTitle ? '<h1>' : '') . '<a' . (($id === 0) ? ' class="niver"' : '') . ' href="' . CONF['common']['prefix'] . ($lastTitle ? '/' . PAGE_URL : '/' . implode('/', array_slice(PAGE_LINEAGE, 0, $id)) . (($lastTitle OR $id === 0) ? '' : '/')) . '">' . $title . '</a>' . ($lastTitle ? '</h1>' : '') . LF;
echo '<ul><li>' . ($lastTitle ? '<h1>' : '') . '<a' . (($id === 0) ? ' class="common"' : '') . ' href="' . CONF['common']['prefix'] . ($lastTitle ? '/' . PAGE_URL : '/' . implode('/', array_slice(PAGE_LINEAGE, 0, $id)) . (($lastTitle OR $id === 0) ? '' : '/')) . '">' . $title . '</a>' . ($lastTitle ? '</h1>' : '') . LF;
}
echo str_repeat('</li></ul>', count(TITLES_LINEAGE));
?>
@ -45,7 +45,7 @@
?>
</main>
<footer>
<small><?= sprintf(_('%sSource code%s available under %s.'), '<a rel="external" href="https://code.antopie.org/niver/niver" class="niver">', '</a>', '<abbr title="Cooperative Nonviolent Public License No Attribution version 7 or more">CNPL-NAv7+</abbr>') ?></small>
<small><?= sprintf(_('%sSource code%s available under %s.'), '<a rel="external" href="https://code.antopie.org/servnest/servnest" class="common">', '</a>', '<abbr title="Cooperative Nonviolent Public License No Attribution version 7 or more">CNPL-NAv7+</abbr>') ?></small>
</footer>
</body>
</html>