Niver > ServNest
This commit is contained in:
parent
3b97b3cc2f
commit
b2bfbb7bf8
14 changed files with 66 additions and 57 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
/db/niver.db
|
||||
/db/servnest.db
|
||||
/locales/*/C/LC_MESSAGES/messages.mo
|
||||
|
|
|
@ -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.
|
||||
|
|
38
README.md
38
README.md
|
@ -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
|
||||
|
||||
|
|
44
config.ini
44
config.ini
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
:root, .niver {
|
||||
:root, .common {
|
||||
--svc-color: var(--foreground-color);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.'));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
4
view.php
4
view.php
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue