Use ini file for config + remove old SFTP page

This commit is contained in:
Miraty 2022-05-20 00:15:13 +02:00
parent e5c306c24b
commit 46218fb3d3
32 changed files with 178 additions and 330 deletions

View file

@ -3,9 +3,6 @@
define("USERNAME_REGEX", "^[a-z]{4,32}$");
define("PASSWORD_REGEX", "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]{8,1024}|.{10,1024}$");
define("ORIGIN", "https://niver.test:42443");
define("CHGRP_PATH", "/usr/bin/chgrp");
// Password storage security
define("ALGO_PASSWORD", PASSWORD_ARGON2ID);
define("OPTIONS_PASSWORD", array(

View file

@ -2,10 +2,10 @@
<footer>
<small>
<?php if (isset($_SESSION['username'])) {
echo "Connecté·e en tant que " . $_SESSION['username'] . "<br><a class='authButton' href='" . PREFIX . "/auth/logout'>Se déconnecter</a>";
echo "Connecté·e en tant que " . $_SESSION['username'] . "<br><a class='authButton' href='" . CONF['common']['prefix'] . "/auth/logout'>Se déconnecter</a>";
} else { ?>
Vous n'êtes pas connecté·e à un compte Niver
<br><a class="authButton" href="<?= PREFIX ?>/auth/login?redir=<?= SERVICE ?>/<?= PAGE ?>">Se connecter</a>
<br><a class="authButton" href="<?= CONF['common']['prefix'] ?>/auth/login?redir=<?= SERVICE ?>/<?= PAGE ?>">Se connecter</a>
<?php } ?>
</small>
</footer>

View file

@ -1,19 +1,16 @@
<?php
define("DOMAIN_EXAMPLE", "example"); // From RFC2606: Reserved Top Level DNS Names > 2. TLDs for Testing, & Documentation Examples
define("PREFIX", ""); // Prefix in URL, if any
define("ROOT_PATH", "/srv/php/niver"); // niver-php directory
define("SERVICE", substr(dirname($_SERVER['PHP_SELF']), strlen(PREFIX) + 1));
define("CONF", parse_ini_file(__DIR__ . "/../config.ini", true, INI_SCANNER_TYPED));
define("SERVICE", substr(dirname($_SERVER['PHP_SELF']), strlen(CONF['common']['prefix']) + 1));
define("PAGE", basename($_SERVER['PHP_SELF'], '.php'));
define("DB_PATH", ROOT_PATH . "/db/niver.db"); // Niver's SQLite database
define("SUDO_PATH", "/usr/bin/sudo");
define("HT_PATH", "/srv/ht");
define("DB_PATH", CONF['common']['root_path'] . "/db/niver.db"); // Niver's SQLite database
// Service-specific functions and constants
if (SERVICE === "reg" OR SERVICE === "ns")
require ROOT_PATH . "/dns.php";
require CONF['common']['root_path'] . "/dns.php";
if (SERVICE !== "")
require ROOT_PATH . "/" . SERVICE . ".php";
require CONF['common']['root_path'] . "/" . SERVICE . ".php";
// Page titles definition
require "pages.php";

View file

@ -101,9 +101,6 @@ switch (SERVICE) {
case "index":
$page['title'] = $page['service'];
break;
case "sftp":
$page['title'] = "Gérer l'accès SFTP";
break;
}
break;
}

View file

@ -22,7 +22,7 @@ if (
'cookie_secure' => true,
'cookie_httponly' => true,
'cookie_samesite' => 'Strict',
'cookie_path' => PREFIX . '/',
'cookie_path' => CONF['common']['prefix'] . '/',
'cookie_lifetime' => 432000, // = 60*60*24*5 = 5 days
'gc_maxlifetime' => 10800,
'use_strict_mode' => true,
@ -51,22 +51,22 @@ define("THEME", array(
'darkColor' => '#000000',
));
require_once ROOT_PATH . "/lessphp/lib/Less/Autoloader.php";
require_once CONF['common']['root_path'] . "/lessphp/lib/Less/Autoloader.php";
Less_Autoloader::register();
// List files in less/
$relativeLessFiles = array_diff(scandir(ROOT_PATH . "/less"), array('..', '.'));
$relativeLessFiles = array_diff(scandir(CONF['common']['root_path'] . "/less"), array('..', '.'));
// Replace keys by values, and values by keys
$relativeLessFiles = array_flip($relativeLessFiles);
// Change relative paths into absolute paths
foreach ($relativeLessFiles as $relativeLessFile => $nothing) {
$absoluteLessFiles[ROOT_PATH . "/less/" . $relativeLessFile] = "";
$absoluteLessFiles[CONF['common']['root_path'] . "/less/" . $relativeLessFile] = "";
}
// Generate one minified CSS file into public/css/ from sources in less/
$options = array(
'cache_dir' => ROOT_PATH . '/public/css/',
'cache_dir' => CONF['common']['root_path'] . '/public/css/',
'compress' => true
);
$cssFileName = Less_Cache::Get($absoluteLessFiles, $options, THEME);
@ -82,7 +82,7 @@ $cssFileName = Less_Cache::Get($absoluteLessFiles, $options, THEME);
if (isset($page['service']))
echo $page['service'] . " < ";
?>Niver</title>
<link type="text/css" rel="stylesheet" href="<?= PREFIX ?>/css/<?= $cssFileName ?>">
<link type="text/css" rel="stylesheet" href="<?= CONF['common']['prefix'] ?>/css/<?= $cssFileName ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
@ -90,9 +90,9 @@ $cssFileName = Less_Cache::Get($absoluteLessFiles, $options, THEME);
<header>
<nav>
<a href="<?= PREFIX ?>/">Niver</a><?php
<a href="..">Niver</a><?php
if (isset($page['service']))
echo ' > <a href="./">' . $page['service'] . '</a>';
echo ' > <a href=".">' . $page['service'] . '</a>';
if (PAGE != "index")
echo ' > <a href="' . PAGE . '">' . $page['title'] . "</a>";
?>

40
config.ini Normal file
View file

@ -0,0 +1,40 @@
[common]
root_path = "/srv/php/niver"
; Prefix in URL, if any
prefix =
ht_path = "/srv/ht"
; From RFC2606: Reserved Top Level DNS Names > 2. TLDs for Testing, & Documentation Examples
domain_example = "example"
; From RFC3849: IPv6 Address Prefix Reserved for Documentation
ipv6_example = "2001:db8::3"
; From RFC5737: IPv4 Address Blocks Reserved for Documentation
ipv4_example = "203.0.113.42"
[auth]
chgrp_path = "/usr/bin/chgrp"
[reg]
knotc_path = "/usr/sbin/knotc"
registry = niver.test
subdomain_regex = "^[a-z0-9]{4,63}$"
[ns]
knotc_path = "/usr/sbin/knotc"
knot_zones_path = "/srv/ns"
[ht]
ipv6_address = "::1"
ipv4_address = "127.0.0.1"
sftp_domain = "sftp.niver.test"
public_sftp_port = 2022
https_port = 42443
internal_onion_http_port = 9080
sudo_path = "/usr/bin/sudo"
systemctl_path = "/usr/bin/systemctl"
certbot_path = "/usr/bin/certbot"
; Nginx configuration directory
nginx_config_path = "/etc/nginx/ht"
; Tor configuration file
tor_config_path = "/etc/tor/instances/niver/torrc"
; Tor keys directory
tor_keys_path = "/var/lib/tor-instances/niver/keys"

View file

@ -1,11 +1,5 @@
<?php
// Example IP adresses (for placeholders)
define("IPV6_EXAMPLE", "2001:db8::3"); // See RFC3849: IPv6 Address Prefix Reserved for Documentation
define("IPV4_EXAMPLE", "203.0.113.42"); // See RFC5737: IPv4 Address Blocks Reserved for Documentation
define("KNOTC_PATH", "/usr/sbin/knotc");
function checkIpFormat($ip) {
if (!filter_var($ip, FILTER_VALIDATE_IP))
exit("ERROR: wrong IP address");

17
ht.php
View file

@ -1,18 +1,5 @@
<?php
// Public IP adresses (shown on the interface)
define("IPV6_ADDRESS", "::1");
define("IPV4_ADDRESS", "127.0.0.1");
define("HTTPS_PORT", "42443");
define("INTERNAL_ONION_HTTP_PORT", "9080");
define("SYSTEMCTL_PATH", "/usr/bin/systemctl");
define("CERTBOT_PATH", "/usr/bin/certbot");
define("NGINX_CONFIG_PATH", "/etc/nginx/ht"); // Nginx configuration directory
define("TOR_CONFIG_PATH", "/etc/tor/instances/niver/torrc"); // Tor configuration file
define("TOR_KEYS_PATH", "/var/lib/tor-instances/niver/keys"); // Tor keys directory
function checkDomainFormat($domain) {
// If the domain must end without a dot
if (!filter_var($domain, FILTER_VALIDATE_DOMAIN) OR !preg_match("/^([a-z0-9_-]{1,63}\.){1,126}[a-z0-9]{1,63}$/", $domain))
@ -28,11 +15,11 @@ function addNiverLog($message, $outputLines, $returnCode = false) {
foreach ($outputLines as $outputLine) {
$logs = $logs . " " . $outputLine . "\n";
}
file_put_contents(ROOT_PATH . "/niver.log", $logs, FILE_APPEND);
file_put_contents(CONF['common']['root_path'] . "/niver.log", $logs, FILE_APPEND);
}
function listFsDirs($username) {
$absoluteDirs = glob(HT_PATH . "/" . $username . "/*/", GLOB_ONLYDIR);
$absoluteDirs = glob(CONF['common']['root_path'] . "/" . $username . "/*/", GLOB_ONLYDIR);
$relativeDirs = false;
foreach ($absoluteDirs as $i => $absoluteDir) {
if (preg_match("/^[a-z0-9-]{1,32}$/", basename($absoluteDir)))

2
ns.php
View file

@ -1,7 +1,5 @@
<?php
define("KNOT_ZONES_PATH", "/srv/ns");
function nsCommonRequirements() {
if (isset($_POST['action'])
AND isset($_POST['zone'])

View file

@ -20,7 +20,7 @@ if (isset($_POST['username']) AND isset($_POST['password'])) {
umask(0002);
if (!mkdir("/srv/ht/" . $username, 0775))
exit("ERROR: Can't create directory");
exec(SUDO_PATH . " " . CHGRP_PATH . " sftpgo " . HT_PATH . "/" . $username, $stdout, $code);
exec(CONF['ht']['sudo_path'] . " " . CHGRP_PATH . " sftpgo " . CONF['ht']['ht_path'] . "/" . $username, $stdout, $code);
if ($code !== 0)
exit("ERROR: Can't change group");

View file

@ -58,24 +58,24 @@ if (isset($_POST['dir']) AND isset($_SESSION['username'])) {
exit("ERROR : Wrong value for dir");
// Generate a .onion address
$torConf = file_get_contents(TOR_CONFIG_PATH);
$torConf = $torConf . "HiddenServiceDir " . TOR_KEYS_PATH . "/" . $_POST['dir'] . "/
HiddenServicePort 80 [::1]:" . INTERNAL_ONION_HTTP_PORT . "
$torConf = file_get_contents(CONF['ht']['tor_config_path']);
$torConf = $torConf . "HiddenServiceDir " . CONF['ht']['tor_keys_path'] . "/" . $_POST['dir'] . "/
HiddenServicePort 80 [::1]:" . CONF['ht']['internal_onion_http_port'] . "
";
file_put_contents(TOR_CONFIG_PATH, $torConf);
file_put_contents(CONF['ht']['tor_config_path'], $torConf);
exec(SUDO_PATH . " " . SYSTEMCTL_PATH . " reload tor", $output);
exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['systemctl_path'] . " reload tor", $output);
addNiverLog("Tor reloaded by " . $_SESSION['username'], $output);
// Copy generated address to a location readable by PHP
exec(SUDO_PATH . " " . MANIVER_PATH . " export-tor " . $_SESSION['username'] . " " . $_POST['dir'], $output);
exec(CONF['ht']['sudo_path'] . " " . MANIVER_PATH . " export-tor " . $_SESSION['username'] . " " . $_POST['dir'], $output);
addNiverLog("Tor data exported by " . $_SESSION['username'], $output);
// Wait
sleep(1);
// Get the address generated by Tor
$onion = file_get_contents(HT_PATH . "/" . $_SESSION['username'] . "/" . $_POST['dir'] . "/hostname");
$onion = file_get_contents(CONF['ht']['ht_path'] . "/" . $_SESSION['username'] . "/" . $_POST['dir'] . "/hostname");
$onion = str_replace(array("\r", "\n"), "", $onion);
if (preg_match("/[0-9a-z]{56}\.onion/", $onion) !== 1)
exit("ERROR: No onion address found");
@ -85,15 +85,15 @@ HiddenServicePort 80 [::1]:" . INTERNAL_ONION_HTTP_PORT . "
// Add it to Nginx
$nginxConf = file_get_contents(NIVER_TEMPLATE_PATH . "/nginx/onion.template");
$nginxConf = str_replace("{{INTERNAL_ONION_HTTP_PORT}}", INTERNAL_ONION_HTTP_PORT, $nginxConf);
$nginxConf = str_replace("{{CONF['ht']['internal_onion_http_port']}}", CONF['ht']['internal_onion_http_port'], $nginxConf);
$nginxConf = str_replace("{{DOMAIN}}", $onion, $nginxConf);
$nginxConf = str_replace("{{HT_PATH}}", HT_PATH, $nginxConf);
$nginxConf = str_replace("{{CONF['ht']['ht_path']}}", CONF['ht']['ht_path'], $nginxConf);
$nginxConf = str_replace("{{USERNAME}}", $_SESSION['username'], $nginxConf);
$nginxConf = str_replace("{{DIR}}", $_POST['dir'], $nginxConf);
file_put_contents(NGINX_CONFIG_PATH . "/" . $_POST['dir'] . ".conf", $nginxConf);
file_put_contents(CONF['ht']['nginx_config_path'] . "/" . $_POST['dir'] . ".conf", $nginxConf);
// Reload Nginx
exec(SUDO_PATH . " " . SYSTEMCTL_PATH . " reload nginx", $output);
exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['systemctl_path'] . " reload nginx", $output);
addNiverLog("Nginx reloaded by " . $_SESSION['username'], $output);
// Tell the user their site address

View file

@ -3,13 +3,13 @@
<p>
Ajouter un domaine sur un dossier de site<br>
Le domaine doit pointer vers ces adresses IP :
<br>IPv4 : <code><?= IPV4_ADDRESS ?></code>
<br>IPv6 : <code><?= IPV6_ADDRESS ?></code>
<br>IPv4 : <code><?= CONF['ht']['ipv4_address'] ?></code>
<br>IPv6 : <code><?= CONF['ht']['ipv6_address'] ?></code>
</p>
<form method="post">
<label for="domain">Domaine sur lequel répondre</label><br>
<input required="" placeholder="site.<?= DOMAIN_EXAMPLE ?>" id="domain" name="domain" type="text"><br>
<input required="" placeholder="site.<?= CONF['common']['domain_example'] ?>" id="domain" name="domain" type="text"><br>
<label for="dir">Dossier ciblé</label><br>
<select required="" name="dir" id="dir">
<option value="" disabled="" selected="">---</option>
@ -70,10 +70,10 @@ if (isset($_POST['domain']) AND isset($_POST['dir']) AND isset($_SESSION['userna
addSite($_SESSION['username'], $_POST['dir'], $_POST['domain'], "dns", "http");
$nginxConf = 'server {
listen [::1]:' . HTTPS_PORT . ' ssl http2;
listen 127.0.0.1:' . HTTPS_PORT . ' ssl http2;
listen [::1]:' . CONF['ht']['https_port'] . ' ssl http2;
listen 127.0.0.1:' . CONF['ht']['https_port'] . ' ssl http2;
server_name ' . $_POST['domain'] . ';
root ' . HT_PATH . '/' . $_SESSION['username'] . '/' . $_POST['dir'] . ';
root ' . CONF['ht']['ht_path'] . '/' . $_SESSION['username'] . '/' . $_POST['dir'] . ';
ssl_certificate /etc/ssl/certs/niver.crt;
ssl_certificate_key /etc/ssl/private/niver.key;
@ -85,10 +85,10 @@ if (isset($_POST['domain']) AND isset($_POST['dir']) AND isset($_SESSION['userna
}
}
';
file_put_contents(NGINX_CONFIG_PATH . "/" . $_POST['domain'] . ".conf", $nginxConf);
file_put_contents(CONF['ht']['nginx_config_path'] . "/" . $_POST['domain'] . ".conf", $nginxConf);
// Reload Nginx
exec(SUDO_PATH . " " . SYSTEMCTL_PATH . " reload nginx");
exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['systemctl_path'] . " reload nginx");
echo "Accès HTTP par domaine ajouté sur ce dossier !";
}

View file

@ -1,10 +1,39 @@
<?php require "../../common/top.php"; ?>
Vous avez accès à un espace <abbr title="SSH File Transfert Protocol">SFTP</abbr>. Vous pouvez téléverser vos sites dans <code>/&lt;nom du site&gt;/*</code>.
<a href="sftp://<?= $_SESSION['username'] ?>@<?= CONF['ht']['sftp_domain'] ?>:<?= CONF['ht']['public_sftp_port'] ?>/">sftp://<?= $_SESSION['username'] ?>@<?= CONF['ht']['sftp_domain'] ?>:<?= CONF['ht']['public_sftp_port'] ?>/</a>
Indiquez les données ci-dessous à votre client <abbr title="SSH File Transfert Protocol">SFTP</abbr> pour y accéder.
<dl>
<dt><a class="htButton" href="sftp">Gérer l'accès SFTP</a></dt>
<dt>Utilisataire</dt>
<dd>
Accéder à son espace SFTP, pour publier et mettre à jour ses sites
<code><?= $_SESSION['username'] ?></code>
</dd>
<dt>Clé de passe</dt>
<dd>
celle que vous avez définit lors de l'activation de l'accès <abbr title="SSH File Transfert Protocol">SFTP</abbr>
</dd>
<dt>Serveur</dt>
<dd>
<code><?= CONF['ht']['sftp_domain'] ?></code>
</dd>
<dt>Port</dt>
<dd>
<code><?= CONF['ht']['public_sftp_port'] ?></code><?php if (CONF['ht']['public_sftp_port'] === 22) echo " (par défaut)"; ?>
</dd>
<dt>Dossier</dt>
<dd>
<code>/</code>
</dd>
</dl>
<dl>
<dt><a class="htButton" href="http-onion">Accès HTTP en Onion</a></dt>
<dd>
Un site HTML, accessible par Tor, avec une adresse en .onion

View file

@ -24,7 +24,7 @@ if (isset($_POST['domain']) AND isset($_SESSION['username'])) {
antiCSRF();
exec(SUDO_PATH . " " . CERTBOT_PATH . " certonly --dry-run --test-cert --webroot --webroot-path /srv/acme --register-unsafely-without-email --agree-tos --domain " . $_POST['domain'], $output, $returnCode);
exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['certbot_path'] . " certonly --dry-run --test-cert --webroot --webroot-path /srv/acme --register-unsafely-without-email --agree-tos --domain " . $_POST['domain'], $output, $returnCode);
// Log Certbot response
addNiverLog($_SESSION['username'] . " installed a Let's Encrypt certificate on their site", $output, $returnCode);
@ -34,13 +34,13 @@ if (isset($_POST['domain']) AND isset($_SESSION['username'])) {
exit("Let's Encrypt certificate obtention failed. Try again later, or contact an administrator.");
// Replace self-signed certificate by Let's Encrypt certificate in Nginx configuration
$conf = file_get_contents(NGINX_CONFIG_PATH . "/" . $_POST['domain'] . ".conf");
$conf = file_get_contents(CONF['ht']['nginx_config_path'] . "/" . $_POST['domain'] . ".conf");
$conf = preg_replace("#/etc/ssl/certs/niver\.crt#", "/etc/letsencrypt/live/" . $_POST['domain'] . "/fullchain.pem", $conf);
$conf = preg_replace("#/etc/ssl/private/niver\.key#", "/etc/letsencrypt/live/" . $_POST['domain'] . "/privkey.pem", $conf);
file_put_contents(NGINX_CONFIG_PATH . "/" . $_POST['domain'] . ".conf", $conf);
file_put_contents(CONF['ht']['nginx_config_path'] . "/" . $_POST['domain'] . ".conf", $conf);
// Reload Nginx
exec(SUDO_PATH . " " . SYSTEMCTL_PATH . " reload nginx reload", $output, $returnCode);
exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['systemctl_path'] . " reload nginx reload", $output, $returnCode);
// Abort if Nginx reload failed
if ($returnCode !== 0)

View file

@ -1,169 +0,0 @@
<?php require "../../common/top.php"; ?>
<?php
if ($_SESSION['sftp_enabled'] == false) { ?>
<p>
Pour que vous puissiez mettre en ligne votre site via <abbr title="SSH File Transfert Protocol">SFTP</abbr>, veuillez définir un mot de passe.
<br>Il sera loggué en clair dans le système et il ne pourra pas être modifié.
</p>
<form method="post">
<label for="password">Créer le mot de passe</label><br>
<input required="" placeholder="**********" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]{8,}|.{10,1024}$" id="password" name="password" type="password"><br>
<input value="Activer" type="submit">
</form>
<?php
if (isset($_SESSION['username']) AND isset($_POST['password'])) {
antiCSRF();
// Setup SFTP access
exec(SUDO_PATH . " " . MANIVER_PATH . " setup-user " . $_SESSION['username'] . " " . $_POST['password'], $output);
addNiverLog($_SESSION['username'] . " enabled SFTP on their account", $output);
enableSftp($_SESSION['username']);
$_SESSION['sftp_enabled'] = true;
header('Location: ' . PREFIX . '/' . SERVICE . '/' . PAGE . '', true, 302);
exit();
}
} else if ($_SESSION['sftp_enabled'] == true) { ?>
Vous avez désormais accès à un espace <abbr title="SSH File Transfert Protocol">SFTP</abbr>. Vous pouvez téléverser vos sites dans <code>/ht/&lt;nom du site&gt;/*</code>.
<br>
<section>
<h2>Quota</h2>
L'espace est limité au total à 10Kio de stockage et 10 fichiers/dossiers.
</section>
<section>
<h2>Clients SFTP</h2>
<strong>Dolphin</strong> et <strong>GNOME Fichiers</strong> (<em>Nautilus</em>) sont disponibles sur la plupart des distributions GNU et sont installés par défaut respectivement sur les environnements de bureau KDE et GNOME. <a href="https://filezilla-project.org/"><strong>FileZilla</strong></a> est disponible aussi pour les autres systèmes d'exploitation de bureau.
<br>
C'est aussi possible d'utiliser le client <code>sftp</code> en ligne de commande.
</section>
<section>
<h2>Informations de connexion</h2>
<div>
<a href="sftp://<?= $_SESSION['username'] ?>@sftp.niver.4.niv.re/">sftp://<?= $_SESSION['username'] ?>@sftp.niver.4.niv.re/</a>
</div>
Indiquez les données ci-dessous à votre client <abbr title="SSH File Transfert Protocol">SFTP</abbr> pour y accéder.
<dl>
<dt>Utilisataire</dt>
<dd>
<code><?= $_SESSION['username'] ?></code>
</dd>
<dt>Clé de passe</dt>
<dd>
celle que vous avez définit lors de l'activation de l'accès <abbr title="SSH File Transfert Protocol">SFTP</abbr>
</dd>
<dt>Serveur</dt>
<dd>
<code>sftp.niver.4.niv.re</code>
</dd>
<dt>Port</dt>
<dd>
<code>22</code> (par défaut)
</dd>
<dt>Dossier</dt>
<dd>
<code>/</code>
</dd>
</dl>
</section>
<section>
<h2>Vérifier la connexion</h2>
<section>
<h3>Ed25519</h3>
<ul>
<li>
<code class="breakable">
SHA256:k5gzcFr5BbOhNUgS6Nbyy15dXPpw6pmTo8OLZ5mLRmA
</code>
</li>
<li>
<code class="breakable">
AAAAC3NzaC1lZDI1NTE5AAAAIF3RT3r6bYGw88TQ190PIZz1UUVV3Xt5SLOo39G+ShjR
</code>
</li>
<li>
<details>
<summary>Image ASCII</summary>
<samp>
<pre>
+--[ED25519 256]--+
| .oo..* |
| . ..+ * |
| . .. = . . . |
| + E= + + o |
| . +..= S = . |
| . .+ o = |
| . o...o... |
| o..oB.+o |
| ...oo+=+o |
+----[SHA256]-----+
</pre>
</samp>
</details>
</li>
</ul>
</section>
<section>
<h3>RSA 3072 bits</h3>
<ul>
<li>
<code class="breakable">
SHA256:yu9PGTGpeCyjaDDG0RiInsMIa1w6t2c6Gv6oemzeFN4
</code>
</li>
<li>
<details>
<summary>Clé publique</summary>
<code class="breakable">
AAAAB3NzaC1yc2EAAAADAQABAAABgQC5Zj5nghhFpdFsyxS6LZd+cYejGR82kow2UsnoRtQ20SU6ro36f4HnFkRcJyY4uPeTyUECX9uBircpKsizfkdfzJf3sTtjrAwghVVdH8EXsK1UjWTt4rRaav3F+g86DEcx7mqMva6zpnoxONjzA+Inm3SD89VuvSl1ZmZBBEEsqsIifNPYVPG1LQg62OEY1gpe89w92CXeEM7rGarp04ux76ORxN93BwnH27q9yjyBensZ/AjL6OmTtDHD8wWG0G6E3gqsyVUiELysyvwW4z3bfSOLRTwtwFaHe7WRjf9iy53h+ZcYZeA+Xe1eTffj0JGtNX2Fh6DWgso1yOeVV0Nziw4wI3Cpr2iO1x4oxeT8qwgklYMuJTAlNaahLXmENtmeq7BkaDKVZb/IW+uLj517c7WnOEUtr1xUcw4yuXXFVRBspmHzkwEvHsix/ZNmofkqo7ZZv5MIoRW1ad6peb8ApkxZ8UNVGcxmJgZmOrW1GBlCpyJdwwSMrLfQH5Zw8dk=
</code>
</details>
</li>
<li>
<details>
<summary>Image ASCII</summary>
<samp>
<pre>
+---[RSA 3072]----+
|o. |
|+ +. . |
|*++. + |
|+X.. o . o |
|+o+ o + S . |
|.o + B = o |
| oo B E o |
|..*= . . |
|=B+.o .o.. |
+----[SHA256]-----+
</pre>
</samp>
</details>
</li>
</ul>
</section>
N'acceptez la connexion que si votre client vous montre l'une de ces signatures !
</section>
<br>
<?php
} else {
exit("Wrong value for sftp_enabled");
}
?>
<?php require "../../common/bottom.php"; ?>

View file

@ -39,9 +39,9 @@ if (nsCommonRequirements()
if (!(preg_match("/^[a-z0-9.-]{1,255}$/", $_POST['value'])))
exit("ERROR: Wrong value for value");
exec(KNOTC_PATH . " zone-begin " . $_POST['zone']);
exec(KNOTC_PATH . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN CAA " . $_POST['flag'] . " " . $_POST['tag'] . " " . $_POST['value']);
exec(KNOTC_PATH . " zone-commit " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN CAA " . $_POST['flag'] . " " . $_POST['tag'] . " " . $_POST['value']);
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}

View file

@ -31,7 +31,7 @@ if (isset($_POST['zone']) AND isset($_SESSION['username'])) {
nsCheckZonePossession($_POST['zone']);
$zoneContent = file_get_contents(KNOT_ZONES_PATH . "/" . $_POST['zone'] . "zone");
$zoneContent = file_get_contents(CONF['ns']['knot_zones_path'] . "/" . $_POST['zone'] . "zone");
$found = preg_match("#\n" . preg_quote($_POST['zone']) . "\s+0\s+CDS\s+([0-9]{1,5})\s+([0-9]{1,2})\s+([0-9])\s+([0-9A-F]{64})\n#", $zoneContent, $matches);
if ($found !== 1)

View file

@ -8,7 +8,7 @@
<form method="post">
<?php require "../../form.ns.php"; ?>
<label for="ip">Adresse IP</label><br>
<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="7" maxlength="39" size="40" type="text" placeholder="<?= IPV6_EXAMPLE ?> ou <?= IPV4_EXAMPLE ?>"><br>
<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="7" maxlength="39" size="40" type="text" placeholder="<?= CONF['common']['ipv6_example'] ?> ou <?= CONF['common']['ipv4_example'] ?>"><br>
<input value="Valider" type="submit">
</form>
@ -28,9 +28,9 @@ if (nsCommonRequirements()
else
exit("ERROR: unknown IP format");
exec(KNOTC_PATH . " zone-begin " . $_POST['zone']);
exec(KNOTC_PATH . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN " . $record . " " . $_POST['ip']);
exec(KNOTC_PATH . " zone-commit " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN " . $record . " " . $_POST['ip']);
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}

View file

@ -39,9 +39,9 @@ if (nsCommonRequirements()
if (!(preg_match("/^[a-z0-9.-]{1,255}$/", $_POST['value'])))
exit("ERROR: Wrong value for value");
exec(KNOTC_PATH . " zone-begin " . $_POST['zone']);
exec(KNOTC_PATH . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN CAA " . $_POST['flag'] . " " . $_POST['tag'] . " " . $_POST['value']);
exec(KNOTC_PATH . " zone-commit " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN CAA " . $_POST['flag'] . " " . $_POST['tag'] . " " . $_POST['value']);
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}

View file

@ -14,7 +14,7 @@
<label for="host">Hôte</label>
<br>
<input id="host" placeholder="mail.<?= DOMAIN_EXAMPLE ?>." name="host" type="text">
<input id="host" placeholder="mail.<?= CONF['common']['domain_example'] ?>." name="host" type="text">
<br>
<input value="Valider" type="submit">
@ -34,9 +34,9 @@ if (nsCommonRequirements()
checkAbsoluteDomainFormat($_POST['host']);
exec(KNOTC_PATH . " zone-begin " . $_POST['zone']);
exec(KNOTC_PATH . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN MX " . $_POST['priority'] . " " . $_POST['host']);
exec(KNOTC_PATH . " zone-commit " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN MX " . $_POST['priority'] . " " . $_POST['host']);
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}

View file

@ -5,7 +5,7 @@
<br>
<label for="ns">Serveur de nom</label>
<br>
<input id="ns" placeholder="ns1.<?= DOMAIN_EXAMPLE ?>" name="ns" type="text">
<input id="ns" placeholder="ns1.<?= CONF['common']['domain_example'] ?>" name="ns" type="text">
<br>
<input value="Procéder" type="submit">
</form>
@ -19,9 +19,9 @@ if (nsCommonRequirements()
checkAbsoluteDomainFormat($_POST['ns']);
exec(KNOTC_PATH . " zone-begin " . $_POST['zone']);
exec(KNOTC_PATH . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN NS " . $_POST['ns']);
exec(KNOTC_PATH . " zone-commit " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN NS " . $_POST['ns']);
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}

View file

@ -26,7 +26,7 @@
<label for="target">Cible</label>
<br>
<input id="target" minlenght="1" maxlength="128" placeholder="service.<?= DOMAIN_EXAMPLE ?>." name="target" type="text">
<input id="target" minlenght="1" maxlength="128" placeholder="service.<?= CONF['common']['domain_example'] ?>." name="target" type="text">
<br>
<input value="Valider" type="submit">
@ -54,9 +54,9 @@ if (nsCommonRequirements()
checkAbsoluteDomainFormat($_POST['target']);
exec(KNOTC_PATH . " zone-begin " . $_POST['zone']);
exec(KNOTC_PATH . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN SRV " . $_POST['priority'] . " " . $_POST['weight'] . " " . $_POST['port'] . " " . $_POST['target']);
exec(KNOTC_PATH . " zone-commit " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN SRV " . $_POST['priority'] . " " . $_POST['weight'] . " " . $_POST['port'] . " " . $_POST['target']);
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}

View file

@ -51,9 +51,9 @@ if (nsCommonRequirements()
if (!(preg_match("/^[a-z0-9]{64}$/", $_POST['fp'])))
exit("ERROR: Wrong value for fp");
exec(KNOTC_PATH . " zone-begin " . $_POST['zone']);
exec(KNOTC_PATH . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN SSHFP " . $_POST['algo'] . " " . $_POST['type'] . " " . $_POST['fp']);
exec(KNOTC_PATH . " zone-commit " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN SSHFP " . $_POST['algo'] . " " . $_POST['type'] . " " . $_POST['fp']);
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}

View file

@ -65,9 +65,9 @@ if (nsCommonRequirements()
if (!(preg_match("/^[a-zA-Z0-9.-]{1,1024}$/", $_POST['content'])))
exit("ERROR: Wrong value for content");
exec(KNOTC_PATH . " zone-begin " . $_POST['zone']);
exec(KNOTC_PATH . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN TLSA " . $_POST['use'] . " " . $_POST['selector'] . " " . $_POST['type'] . " " . $_POST['content']);
exec(KNOTC_PATH . " zone-commit " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN TLSA " . $_POST['use'] . " " . $_POST['selector'] . " " . $_POST['type'] . " " . $_POST['content']);
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}

View file

@ -20,9 +20,9 @@ if (nsCommonRequirements()
if (!(preg_match("/^[a-zA-Z0-9 =:!%$+\/\()[\]_-]{5,8192}$/", $_POST['txt'])))
exit("ERROR : Wrong caracter or wrong caracter quantity");
exec(KNOTC_PATH . " zone-begin " . $_POST['zone']);
exec(KNOTC_PATH . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . ' IN TXT \"' . $_POST['txt'] . '\"');
exec(KNOTC_PATH . " zone-commit " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . ' IN TXT \"' . $_POST['txt'] . '\"');
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}

View file

@ -3,7 +3,7 @@
<form method="post">
<h2>Ajouter une zone</h2>
<label for="domain">Domaine</label><br>
<input required="" placeholder="domain.<?= DOMAIN_EXAMPLE ?>." id="domain" name="domain" type="text"><br>
<input required="" placeholder="domain.<?= CONF['common']['domain_example'] ?>." id="domain" name="domain" type="text"><br>
<input value="Ajouter" type="submit">
</form>
@ -23,17 +23,17 @@ if (isset($_POST['domain']) AND isset($_SESSION['username'])) {
$stmt->execute();
$knotZonePath = KNOT_ZONES_PATH . "/" . $_POST['domain'] . "zone";
$knotZonePath = CONF['ns']['knot_zones_path'] . "/" . $_POST['domain'] . "zone";
$knotZone = $_POST['domain'] . ' 3600 SOA ns1.niver.test. admin.niver.test. 1 21600 7200 3628800 3600
' . $_POST['domain'] . ' 86400 NS ns1.niver.test.
';
file_put_contents($knotZonePath, $knotZone);
chmod($knotZonePath, 0660);
exec(KNOTC_PATH . " conf-begin");
exec(KNOTC_PATH . " conf-set 'zone[" . $_POST['domain'] . "]'");
exec(KNOTC_PATH . " conf-set 'zone[" . $_POST['domain'] . "].template' 'niver'");
exec(KNOTC_PATH . " conf-commit");
exec(CONF['ns']['knotc_path'] . " conf-begin");
exec(CONF['ns']['knotc_path'] . " conf-set 'zone[" . $_POST['domain'] . "]'");
exec(CONF['ns']['knotc_path'] . " conf-set 'zone[" . $_POST['domain'] . "].template' 'niver'");
exec(CONF['ns']['knotc_path'] . " conf-commit");
echo "La requête a été traitée.";
@ -67,15 +67,15 @@ if (isset($_POST['zone']) AND isset($_SESSION['username'])) {
nsCheckZonePossession($_POST['zone']);
// Remove from Knot configuration
exec(KNOTC_PATH . " conf-begin");
exec(KNOTC_PATH . " conf-unset 'zone[" . $_POST['zone'] . "]'");
exec(KNOTC_PATH . " conf-commit");
exec(CONF['ns']['knotc_path'] . " conf-begin");
exec(CONF['ns']['knotc_path'] . " conf-unset 'zone[" . $_POST['zone'] . "]'");
exec(CONF['ns']['knotc_path'] . " conf-commit");
// Remove Knot zone file
unlink(KNOT_ZONES_PATH . "/" . $_POST['zone'] . "zone");
unlink(CONF['ns']['knot_zones_path'] . "/" . $_POST['zone'] . "zone");
// Remove Knot related data
exec(KNOTC_PATH . " zone-purge " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-purge " . $_POST['zone']);
// Remove from Niver's database
$db = new PDO('sqlite:' . DB_PATH);

View file

@ -95,9 +95,9 @@ if (isset($_POST['zone']) AND isset($_POST['keytag']) AND isset($_POST['algo'])
$suffix = regGetUpperDomain($_POST['zone']);
exec(KNOTC_PATH . " zone-begin " . $suffix);
exec(KNOTC_PATH . " zone-" . $action . "set " . $suffix . " " . $_POST['zone'] . " 86400 IN DS " . $_POST['keytag'] . " " . $_POST['algo'] . " " . $_POST['dt'] . " " . $_POST['key']);
exec(KNOTC_PATH . " zone-commit " . $suffix);
exec(CONF['reg']['knotc_path'] . " zone-begin " . $suffix);
exec(CONF['reg']['knotc_path'] . " zone-" . $action . "set " . $suffix . " " . $_POST['zone'] . " 86400 IN DS " . $_POST['keytag'] . " " . $_POST['algo'] . " " . $_POST['dt'] . " " . $_POST['key']);
exec(CONF['reg']['knotc_path'] . " zone-commit " . $suffix);
echo "La requête a été envoyée à Knot";
}

View file

@ -34,7 +34,7 @@
</div>
</fieldset>
<label for="ip">IP</label><br>
<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="7" maxlength="39" size="40" type="text" placeholder="<?= IPV4_EXAMPLE ?> ou <?= IPV6_EXAMPLE ?>">
<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="7" maxlength="39" size="40" type="text" placeholder="<?= CONF['common']['ipv4_example'] ?> ou <?= CONF['common']['ipv6_example'] ?>">
<br>
<input value="Valider" type="submit">
</form>
@ -68,9 +68,9 @@ if (isset($_POST['action']) AND isset($_POST['subdomain']) AND isset($_POST['suf
$publicSuffix = regGetUpperDomain($_POST['suffix']);
exec(KNOTC_PATH . " zone-begin " . $publicSuffix);
exec(KNOTC_PATH . " zone-" . $action . "set " . $publicSuffix . " " . $domain . " 86400 IN " . $record . " " . $_POST['ip']);
exec(KNOTC_PATH . " zone-commit " . $publicSuffix);
exec(CONF['reg']['knotc_path'] . " zone-begin " . $publicSuffix);
exec(CONF['reg']['knotc_path'] . " zone-" . $action . "set " . $publicSuffix . " " . $domain . " 86400 IN " . $record . " " . $_POST['ip']);
exec(CONF['reg']['knotc_path'] . " zone-commit " . $publicSuffix);
echo "Glue record ajouté";
}

View file

@ -3,11 +3,11 @@
<dl>
<dt><a class="regButton" href="register">Enregistrer un nouveau domaine</a></dt>
<dd>
Prendre possession d'un sous-domaine de <code><?= REGISTRY ?></code>
Prendre possession d'un sous-domaine de <code><?= CONF['reg']['registry'] ?></code>
</dd>
<dt><a class="regButton" href="ns">Enregistrement <abbr title="Name Server">NS</abbr></a></dt>
<dd>
Indiquer les serveurs de noms de son sous-domaine de <code><?= REGISTRY ?></code>
Indiquer les serveurs de noms de son sous-domaine de <code><?= CONF['reg']['registry'] ?></code>
</dd>
<dt><a class="regButton" href="ds">Enregistrement <abbr title="Delegation Signer">DS</abbr></a></dt>
<dd>
@ -15,7 +15,7 @@
</dd>
<dt><a class="regButton" href="glue">Glue Record</a></dt>
<dd>
Indiquer les IP de ses serveurs de noms de son sous-domaine de <code><?= REGISTRY ?></code> dont les adresses se trouvent sur ce même sous-domaine
Indiquer les IP de ses serveurs de noms de son sous-domaine de <code><?= CONF['reg']['registry'] ?></code> dont les adresses se trouvent sur ce même sous-domaine
</dd>
</dl>

View file

@ -27,7 +27,7 @@
<br>
<label for="ns">Serveur de nom</label>
<br>
<input id="ns" placeholder="ns1.<?= DOMAIN_EXAMPLE ?>." name="ns" type="text">
<input id="ns" placeholder="ns1.<?= CONF['common']['domain_example'] ?>." name="ns" type="text">
<br>
<input value="Valider" type="submit">
</form>
@ -45,9 +45,9 @@ if (isset($_POST['domain']) AND isset($_POST['action']) AND isset($_POST['ns'])
$suffix = regGetUpperDomain($_POST['domain']);
exec(KNOTC_PATH . " zone-begin " . $suffix, $output);
exec(KNOTC_PATH . " zone-" . $action . "set " . $suffix . " " . $_POST['domain'] . " 86400 IN NS " . $_POST['ns'], $output);
exec(KNOTC_PATH . " zone-commit " . $suffix, $output);
exec(CONF['reg']['knotc_path'] . " zone-begin " . $suffix, $output);
exec(CONF['reg']['knotc_path'] . " zone-" . $action . "set " . $suffix . " " . $_POST['domain'] . " 86400 IN NS " . $_POST['ns'], $output);
exec(CONF['reg']['knotc_path'] . " zone-commit " . $suffix, $output);
$error = false;
foreach ($output as $line) {
if ($line !== "OK") {

View file

@ -5,37 +5,23 @@ Ce domaine doit être composé uniquement d'au moins 4 lettres latines non accen
<br>
<br>
<form method="post">
<fieldset>
<legend>Domaine</legend>
<div>
<label for="subdomain">Sous-domaine</label>
<br>
<input id="subdomain" pattern="<?= SUBDOMAIN_REGEX ?>" required="" placeholder="niver" name="subdomain" type="text">
</div>
<div>
<label for="suffix">Suffixe</label>
<br>
<select required="" id="suffix" name="suffix">
<option selected="" value="<?= REGISTRY ?>">.<?= REGISTRY ?></option>
</select>
</div>
</fieldset>
<br>
<div>
<label for="subdomain">Sous-domaine</label>
<br>
<input id="subdomain" pattern="<?= CONF['reg']['subdomain_regex'] ?>" required="" placeholder="niver" name="subdomain" type="text">.<?= CONF['reg']['registry'] ?>
</div>
<input value="Valider" type="submit">
</form>
<?php
if (isset($_POST['subdomain']) AND isset($_POST['suffix']) AND isset($_SESSION['username'])) {
if (isset($_POST['subdomain']) AND isset($_SESSION['username'])) {
antiCSRF();
if (preg_match("/" . SUBDOMAIN_REGEX . "/", $_POST['subdomain'])) {
if (preg_match("/" . CONF['reg']['subdomain_regex'] . "/", $_POST['subdomain'])) {
if (!in_array($_POST['suffix'], SUFFIXES))
exit("Wrong value for suffix");
$domain = $_POST['subdomain'] . "." . $_POST['suffix'];
$domain = $_POST['subdomain'] . "." . CONF['reg']['registry'];
checkAbsoluteDomainFormat($domain);

View file

@ -1,13 +1,5 @@
<?php
define("SUBDOMAIN_REGEX", "^[a-z]{4,63}$");
define("REGISTRY", "niver.test.");
define("SUFFIXES", array(
REGISTRY,
));
function regGetUpperDomain($domain) {
// Remove anything before the first dot and the first dot itself
return preg_replace("/^[^.]+\./", "", $domain);