ht: subdomain and subpath on shared domain
This commit is contained in:
parent
57dfb02a40
commit
a3da268ead
21 changed files with 194 additions and 114 deletions
|
@ -31,6 +31,13 @@ enabled = true
|
||||||
|
|
||||||
; Path were user's sites will be stored
|
; Path were user's sites will be stored
|
||||||
ht_path = "/srv/niver/ht"
|
ht_path = "/srv/niver/ht"
|
||||||
|
|
||||||
|
subpath_domain = "ht.niver.test"
|
||||||
|
subpath_path = "/srv/niver/subpath"
|
||||||
|
|
||||||
|
subdomain_domain = "ht.niver.test"
|
||||||
|
subdomain_path = "/srv/niver/subdomain"
|
||||||
|
|
||||||
; Nginx configuration directory
|
; Nginx configuration directory
|
||||||
nginx_config_path = "/srv/niver/nginx"
|
nginx_config_path = "/srv/niver/nginx"
|
||||||
nginx_reload_cmd = "/usr/bin/systemctl reload nginx"
|
nginx_reload_cmd = "/usr/bin/systemctl reload nginx"
|
||||||
|
@ -58,7 +65,7 @@ ipv4_address = "127.0.0.1"
|
||||||
sftp_pub = "/etc/sftpgo/ed25519.pub"
|
sftp_pub = "/etc/sftpgo/ed25519.pub"
|
||||||
sftp_fp = "/etc/sftpgo/ed25519.fp"
|
sftp_fp = "/etc/sftpgo/ed25519.fp"
|
||||||
sftp_asciiart = "/etc/sftpgo/ed25519.asciiart"
|
sftp_asciiart = "/etc/sftpgo/ed25519.asciiart"
|
||||||
sftp_domain = "ht.niver.test"
|
sftp_domain = "sftp.niver.test"
|
||||||
public_sftp_port = 2022
|
public_sftp_port = 2022
|
||||||
|
|
||||||
; Will be used in configuration files
|
; Will be used in configuration files
|
||||||
|
|
|
@ -39,11 +39,12 @@ CREATE TABLE IF NOT EXISTS "zones" (
|
||||||
CREATE TABLE IF NOT EXISTS "sites" (
|
CREATE TABLE IF NOT EXISTS "sites" (
|
||||||
"username" TEXT NOT NULL,
|
"username" TEXT NOT NULL,
|
||||||
"site_dir" TEXT NOT NULL,
|
"site_dir" TEXT NOT NULL,
|
||||||
"domain" TEXT NOT NULL UNIQUE,
|
"address" TEXT NOT NULL,
|
||||||
"domain_type" TEXT NOT NULL,
|
"type" TEXT NOT NULL,
|
||||||
"protocol" TEXT NOT NULL,
|
|
||||||
"creation_date" TEXT NOT NULL,
|
"creation_date" TEXT NOT NULL,
|
||||||
PRIMARY KEY("domain"),
|
UNIQUE("address", "type"),
|
||||||
|
UNIQUE("username", "site_dir", "type"),
|
||||||
|
PRIMARY KEY("address", "type"),
|
||||||
FOREIGN KEY("username") REFERENCES "users"("id")
|
FOREIGN KEY("username") REFERENCES "users"("id")
|
||||||
);
|
);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
53
fn/ht.php
53
fn/ht.php
|
@ -21,24 +21,22 @@ function listFsDirs($username) {
|
||||||
return $dirs;
|
return $dirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSite($username, $siteDir, $domain, $domainType, $protocol) {
|
function addSite($username, $siteDir, $address, $type) {
|
||||||
insert('sites', [
|
insert('sites', [
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
'site_dir' => $siteDir,
|
'site_dir' => $siteDir,
|
||||||
'domain' => $domain,
|
'address' => $address,
|
||||||
'domain_type' => $domainType,
|
'type' => $type,
|
||||||
'protocol' => $protocol,
|
|
||||||
'creation_date' => date('Y-m-d H:i:s'),
|
'creation_date' => date('Y-m-d H:i:s'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function dirsStatuses($domainType, $protocol) {
|
function dirsStatuses($type) {
|
||||||
if (isset($_SESSION['id']) !== true)
|
if (isset($_SESSION['id']) !== true)
|
||||||
return [];
|
return [];
|
||||||
$dbDirs = query('select', 'sites', [
|
$dbDirs = query('select', 'sites', [
|
||||||
'username' => $_SESSION['id'],
|
'username' => $_SESSION['id'],
|
||||||
'domain_type' => $domainType,
|
'type' => $type,
|
||||||
'protocol' => $protocol,
|
|
||||||
], 'site_dir');
|
], 'site_dir');
|
||||||
$dirs = [];
|
$dirs = [];
|
||||||
foreach (listFsDirs($_SESSION['id']) as $fsDir)
|
foreach (listFsDirs($_SESSION['id']) as $fsDir)
|
||||||
|
@ -46,9 +44,31 @@ function dirsStatuses($domainType, $protocol) {
|
||||||
return $dirs;
|
return $dirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
function htDeleteSite($dir, $domainType, $protocol) {
|
function htDeleteSite($address, $type) {
|
||||||
|
match ($type) {
|
||||||
|
'onion', 'dns' => htDeleteDedicatedSite($address, $type),
|
||||||
|
'subpath', 'subdomain' => htDeleteSubSite($address, $type)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if ($domainType === 'onion') {
|
function htDeleteSubSite($address, $type) {
|
||||||
|
if (unlink(CONF['ht'][$type . '_path'] . '/' . $address) !== true)
|
||||||
|
output(500, 'Unable to delete symlink.');
|
||||||
|
|
||||||
|
query('delete', 'sites', [
|
||||||
|
'username' => $_SESSION['id'],
|
||||||
|
'type' => $type,
|
||||||
|
'address' => $address,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function htDeleteDedicatedSite($address, $type) {
|
||||||
|
$dir = query('select', 'sites', [
|
||||||
|
'address' => $address,
|
||||||
|
'type' => $type,
|
||||||
|
], 'site_dir')[0];
|
||||||
|
|
||||||
|
if ($type === 'onion') {
|
||||||
// Delete Tor config
|
// Delete Tor config
|
||||||
if (unlink(CONF['ht']['tor_config_path'] . '/' . $_SESSION['id'] . '/' . $dir) !== true)
|
if (unlink(CONF['ht']['tor_config_path'] . '/' . $_SESSION['id'] . '/' . $dir) !== true)
|
||||||
output(500, 'Failed to delete Tor configuration.');
|
output(500, 'Failed to delete Tor configuration.');
|
||||||
|
@ -65,13 +85,7 @@ function htDeleteSite($dir, $domainType, $protocol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete Nginx config
|
// Delete Nginx config
|
||||||
$domain = query('select', 'sites', [
|
if (unlink(CONF['ht']['nginx_config_path'] . '/' . $address . '.conf') !== true)
|
||||||
'username' => $_SESSION['id'],
|
|
||||||
'domain_type' => $domainType,
|
|
||||||
'protocol' => $protocol,
|
|
||||||
'site_dir' => $dir,
|
|
||||||
], 'domain')[0];
|
|
||||||
if (unlink(CONF['ht']['nginx_config_path'] . '/' . $domain . '.conf') !== true)
|
|
||||||
output(500, 'Failed to delete Nginx configuration.');
|
output(500, 'Failed to delete Nginx configuration.');
|
||||||
|
|
||||||
// Reload Nginx
|
// Reload Nginx
|
||||||
|
@ -79,9 +93,9 @@ function htDeleteSite($dir, $domainType, $protocol) {
|
||||||
if ($code !== 0)
|
if ($code !== 0)
|
||||||
output(500, 'Failed to reload Nginx.');
|
output(500, 'Failed to reload Nginx.');
|
||||||
|
|
||||||
if ($domainType === 'dns') {
|
if ($type === 'dns') {
|
||||||
// Delete Let's Encrypt certificate
|
// Delete Let's Encrypt certificate
|
||||||
exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['certbot_path'] . ' delete --quiet --cert-name ' . $domain, $output, $code);
|
exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['certbot_path'] . ' delete --quiet --cert-name ' . $address, $output, $code);
|
||||||
if ($code !== 0)
|
if ($code !== 0)
|
||||||
output(500, 'Certbot failed to delete the Let\'s Encrypt certificate.');
|
output(500, 'Certbot failed to delete the Let\'s Encrypt certificate.');
|
||||||
}
|
}
|
||||||
|
@ -89,8 +103,7 @@ function htDeleteSite($dir, $domainType, $protocol) {
|
||||||
// Delete from database
|
// Delete from database
|
||||||
query('delete', 'sites', [
|
query('delete', 'sites', [
|
||||||
'username' => $_SESSION['id'],
|
'username' => $_SESSION['id'],
|
||||||
'domain_type' => $domainType,
|
'type' => $type,
|
||||||
'protocol' => $protocol,
|
|
||||||
'site_dir' => $dir,
|
'site_dir' => $dir,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
32
pages.php
32
pages.php
|
@ -149,23 +149,29 @@ define('PAGES', [
|
||||||
'title' => '<span aria-hidden="true">🕸️ </span>Hypertexte',
|
'title' => '<span aria-hidden="true">🕸️ </span>Hypertexte',
|
||||||
'description' => 'Mettre en ligne son site statique sur un espace <abbr title="SSH File Transfert Protocol">SFTP</abbr>, et le faire répondre en <abbr title="HyperText Transfert Protocol">HTTP</abbr> par DNS ou Tor',
|
'description' => 'Mettre en ligne son site statique sur un espace <abbr title="SSH File Transfert Protocol">SFTP</abbr>, et le faire répondre en <abbr title="HyperText Transfert Protocol">HTTP</abbr> par DNS ou Tor',
|
||||||
],
|
],
|
||||||
'add-http-dns' => [
|
'add-subpath' => [
|
||||||
'title' => 'Ajouter un accès HTTP par DNS+TLS',
|
'title' => 'Accès par sous-chemin <code>' . CONF['ht']['subpath_domain'] . '/</code>',
|
||||||
'description' => 'Ajouter un accès HTTP par ' . linkToDocs('dns', 'DNS') . ' et ' . linkToDocs('tls', 'TLS') . ' sur un sous-dossier de l\'espace SFTP',
|
'description' => 'Son URL ressemblera à <code>https://' . CONF['ht']['subpath_domain'] . '/monsite/</code>',
|
||||||
'tokens_account_cost' => 3600,
|
'tokens_account_cost' => 900,
|
||||||
],
|
],
|
||||||
'add-http-onion' => [
|
'add-subdomain' => [
|
||||||
'title' => 'Ajouter un accès HTTP par Onion',
|
'title' => 'Accès par sous-domaine de <code>.' . CONF['ht']['subdomain_domain'] . '</code>',
|
||||||
'description' => 'Ajouter un accès HTTP par ' . linkToDocs('tor', 'service Onion') . ' sur un sous-dossier de l\'espace SFTP',
|
'description' => 'Son URL ressemblera à <code>https://monsite.' . CONF['ht']['subpath_domain'] . '/</code>',
|
||||||
'tokens_account_cost' => 1800,
|
'tokens_account_cost' => 1800,
|
||||||
],
|
],
|
||||||
'del-http-dns' => [
|
'add-dns' => [
|
||||||
'title' => 'Retirer un accès HTTP par DNS+TLS',
|
'title' => 'Accès par domaine dédié et certificat Let\'s Encrypt',
|
||||||
'description' => 'Retirer un accès HTTP par DNS et TLS d\'un sous-dossier de l\'espace SFTP',
|
'description' => 'Son URL ressemblera à <code>https://monsite.example/</code>',
|
||||||
|
'tokens_account_cost' => 3600,
|
||||||
],
|
],
|
||||||
'del-http-onion' => [
|
'add-onion' => [
|
||||||
'title' => 'Retirer un accès HTTP par Onion',
|
'title' => 'Accès par service Onion',
|
||||||
'description' => 'Retirer un accès HTTP par service Onion d\'un sous-dossier de l\'espace SFTP',
|
'description' => 'Son URL ressemblera à <code>http://nrdselxjgryq5fwek2xh3pxg4b26z26eyzlbs4y5lownk465jhaamayd.onion/</code>, qui ne fonctionnera que par le réseau Tor',
|
||||||
|
'tokens_account_cost' => 1800,
|
||||||
|
],
|
||||||
|
'del' => [
|
||||||
|
'title' => 'Retirer un accès',
|
||||||
|
'description' => 'Retirer un accès HTTP déjà existant d\'un sous-dossier de l\'espace SFTP',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -9,19 +9,8 @@ foreach (query('select', 'registry', ['username' => $_SESSION['id']], 'domain')
|
||||||
foreach (query('select', 'zones', ['username' => $_SESSION['id']], 'zone') as $zone)
|
foreach (query('select', 'zones', ['username' => $_SESSION['id']], 'zone') as $zone)
|
||||||
nsDeleteZone($zone);
|
nsDeleteZone($zone);
|
||||||
|
|
||||||
foreach (query('select', 'sites', [
|
foreach (query('select', 'sites', ['username' => $_SESSION['id']]) as $site)
|
||||||
'username' => $_SESSION['id'],
|
htDeleteSite($site['address'], $site['type']);
|
||||||
'domain_type' => 'onion',
|
|
||||||
'protocol' => 'http',
|
|
||||||
], 'site_dir') as $dir)
|
|
||||||
htDeleteSite($dir, domainType: 'onion', protocol: 'http');
|
|
||||||
|
|
||||||
foreach (query('select', 'sites', [
|
|
||||||
'username' => $_SESSION['id'],
|
|
||||||
'domain_type' => 'dns',
|
|
||||||
'protocol' => 'http',
|
|
||||||
], 'site_dir') as $dir)
|
|
||||||
htDeleteSite($dir, domainType: 'dns', protocol: 'http');
|
|
||||||
|
|
||||||
exec(CONF['ht']['sudo_path'] . ' -u ' . CONF['ht']['tor_user'] . ' ' . CONF['ht']['rm_path'] . ' --recursive ' . CONF['ht']['tor_keys_path'] . '/' . $_SESSION['id'], result_code: $code);
|
exec(CONF['ht']['sudo_path'] . ' -u ' . CONF['ht']['tor_user'] . ' ' . CONF['ht']['rm_path'] . ' --recursive ' . CONF['ht']['tor_keys_path'] . '/' . $_SESSION['id'], result_code: $code);
|
||||||
if ($code !== 0)
|
if ($code !== 0)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
$_POST['domain'] = formatDomain($_POST['domain']);
|
$_POST['domain'] = formatDomain($_POST['domain']);
|
||||||
|
|
||||||
if (dirsStatuses('dns', 'http')[$_POST['dir']] !== false)
|
if (dirsStatuses('dns')[$_POST['dir']] !== false)
|
||||||
output(403, 'Wrong value for <code>dir</code>.');
|
output(403, 'Wrong value for <code>dir</code>.');
|
||||||
|
|
||||||
if (query('select', 'sites', ['domain' => $_POST['domain']], 'domain') !== [])
|
if (query('select', 'sites', ['domain' => $_POST['domain']], 'domain') !== [])
|
||||||
|
@ -30,7 +30,7 @@ checkAuthToken($matches[1], $matches[2]);
|
||||||
|
|
||||||
rateLimit();
|
rateLimit();
|
||||||
|
|
||||||
addSite($_SESSION['id'], $_POST['dir'], $_POST['domain'], 'dns', 'http');
|
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 /srv/niver/acme --domain ' . $_POST['domain'], $output, $returnCode);
|
||||||
if ($returnCode !== 0)
|
if ($returnCode !== 0)
|
||||||
|
@ -56,4 +56,4 @@ exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['nginx_reload_cmd'], result_code
|
||||||
if ($code !== 0)
|
if ($code !== 0)
|
||||||
output(500, 'Failed to reload Nginx.');
|
output(500, 'Failed to reload Nginx.');
|
||||||
|
|
||||||
output(200, 'Accès HTTP par domaine ajouté sur ce dossier !');
|
output(200, 'Accès HTTP par domaine dédié ajouté sur ce dossier !');
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
if (dirsStatuses('onion', 'http')[$_POST['dir']] !== false)
|
if (dirsStatuses('onion')[$_POST['dir']] !== false)
|
||||||
output(403, 'Wrong value for <code>dir</code>.');
|
output(403, 'Wrong value for <code>dir</code>.');
|
||||||
|
|
||||||
rateLimit();
|
rateLimit();
|
||||||
|
@ -24,7 +24,7 @@ if (preg_match('/^[0-9a-z]{56}\.onion$/D', $onion) !== 1)
|
||||||
output(500, 'No onion address found.');
|
output(500, 'No onion address found.');
|
||||||
|
|
||||||
// Store it in the database
|
// Store it in the database
|
||||||
addSite($_SESSION['id'], $_POST['dir'], $onion, 'onion', 'http');
|
addSite($_SESSION['id'], $_POST['dir'], $onion, 'onion');
|
||||||
|
|
||||||
// Add Nginx config
|
// Add Nginx config
|
||||||
$nginxConf = 'server {
|
$nginxConf = 'server {
|
19
pg-act/ht/add-subdomain.php
Normal file
19
pg-act/ht/add-subdomain.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if (dirsStatuses('subdomain')[$_POST['dir']] !== false)
|
||||||
|
output(403, 'Wrong value for <code>dir</code>.');
|
||||||
|
|
||||||
|
if (preg_match('/^[a-z0-9]{1,32}$/D', $_POST['subdomain']) !== 1)
|
||||||
|
output(403, 'Label de domaine invalide.');
|
||||||
|
|
||||||
|
if (query('select', 'sites', ['address' => $_POST['subdomain'], 'type' => 'subdomain']) !== [])
|
||||||
|
output(403, 'Ce domaine est déjà utilisé sur ce service. Utilisez-en un autre.');
|
||||||
|
|
||||||
|
rateLimit();
|
||||||
|
|
||||||
|
addSite($_SESSION['id'], $_POST['dir'], $_POST['subdomain'], 'subdomain');
|
||||||
|
|
||||||
|
if (symlink(CONF['ht']['ht_path'] . '/' . $_SESSION['id'] . '/' . $_POST['dir'], CONF['ht']['subdomain_path'] . '/' . $_POST['subdomain']) !== true)
|
||||||
|
output(500, 'Unable to create symlink.');
|
||||||
|
|
||||||
|
output(200, 'Accès HTTP par sous-chemin ajouté sur ce dossier !');
|
19
pg-act/ht/add-subpath.php
Normal file
19
pg-act/ht/add-subpath.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if (dirsStatuses('subpath')[$_POST['dir']] !== false)
|
||||||
|
output(403, 'Wrong value for <code>dir</code>.');
|
||||||
|
|
||||||
|
if (preg_match('/^[a-z0-9]{1,32}$/D', $_POST['path']) !== 1)
|
||||||
|
output(403, 'Chemin invalide.');
|
||||||
|
|
||||||
|
if (query('select', 'sites', ['address' => $_POST['path'], 'type' => 'subpath']) !== [])
|
||||||
|
output(403, 'Ce chemin est déjà utilisé sur ce service. Utilisez-en un autre.');
|
||||||
|
|
||||||
|
rateLimit();
|
||||||
|
|
||||||
|
addSite($_SESSION['id'], $_POST['dir'], $_POST['path'], 'subpath');
|
||||||
|
|
||||||
|
if (symlink(CONF['ht']['ht_path'] . '/' . $_SESSION['id'] . '/' . $_POST['dir'], CONF['ht']['subpath_path'] . '/' . $_POST['path']) !== true)
|
||||||
|
output(500, 'Unable to create symlink.');
|
||||||
|
|
||||||
|
output(200, 'Accès HTTP par sous-chemin ajouté sur ce dossier !');
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
if (dirsStatuses('dns', 'http')[$_POST['dir']] !== true)
|
|
||||||
output(403, 'Wrong value for <code>dir</code>.');
|
|
||||||
|
|
||||||
htDeleteSite($_POST['dir'], domainType: 'dns', protocol: 'http');
|
|
||||||
|
|
||||||
output(200, 'Accès retiré.');
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
if (dirsStatuses('onion', 'http')[$_POST['dir']] !== true)
|
|
||||||
output(403, 'Wrong value for <code>dir</code>.');
|
|
||||||
|
|
||||||
htDeleteSite($_POST['dir'], domainType: 'onion', protocol: 'http');
|
|
||||||
|
|
||||||
output(200, 'Accès retiré.');
|
|
11
pg-act/ht/del.php
Normal file
11
pg-act/ht/del.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if (preg_match('/^(?<type>subpath|subdomain|onion|dns):(?<address>[a-z0-9._-]{1,256})$/D', $_POST['site'], $site) !== 1)
|
||||||
|
output(403, 'Malformed value for <code>site</code>.');
|
||||||
|
|
||||||
|
if (isset(query('select', 'sites', ['username' => $_SESSION['id'], 'address' => $site['address'], 'type' => $site['type']], 'address')[0]) !== true)
|
||||||
|
output(403, 'Unavailable value for <code>site</code>.');
|
||||||
|
|
||||||
|
htDeleteSite($site['address'], $site['type']);
|
||||||
|
|
||||||
|
output(200, 'Accès retiré.');
|
|
@ -3,7 +3,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
La présence des enregistrements ci-après sera vérifiée lors du traitement de ce formulaire.
|
Le domaine doit posséder les enregistrements ci-après lors du traitement de ce formulaire.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<select required="" name="dir" id="dir">
|
<select required="" name="dir" id="dir">
|
||||||
<option value="" disabled="" selected="">---</option>
|
<option value="" disabled="" selected="">---</option>
|
||||||
<?php
|
<?php
|
||||||
foreach (dirsStatuses('dns', 'http') as $dir => $alreadyEnabled)
|
foreach (dirsStatuses('dns') as $dir => $alreadyEnabled)
|
||||||
echo ' <option' . ($alreadyEnabled ? ' disabled=""' : '') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
echo ' <option' . ($alreadyEnabled ? ' disabled=""' : '') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
||||||
?>
|
?>
|
||||||
</select>
|
</select>
|
|
@ -1,5 +1,5 @@
|
||||||
<p>
|
<p>
|
||||||
Ajouter un accès en .onion sur un dossier
|
Ajouter un accès par <?= linkToDocs('tor', 'service Onion') ?> sur un dossier.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
|
@ -7,7 +7,7 @@
|
||||||
<select required="" name="dir" id="dir">
|
<select required="" name="dir" id="dir">
|
||||||
<option value="" disabled="" selected="">---</option>
|
<option value="" disabled="" selected="">---</option>
|
||||||
<?php
|
<?php
|
||||||
foreach (dirsStatuses('onion', 'http') as $dir => $alreadyEnabled)
|
foreach (dirsStatuses('onion') as $dir => $alreadyEnabled)
|
||||||
echo ' <option' . ($alreadyEnabled ? ' disabled=""' : '') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
echo ' <option' . ($alreadyEnabled ? ' disabled=""' : '') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
||||||
?>
|
?>
|
||||||
</select>
|
</select>
|
18
pg-view/ht/add-subdomain.php
Normal file
18
pg-view/ht/add-subdomain.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<p>
|
||||||
|
Ajouter sur un dossier de site un accès <?= linkToDocs('http', 'HTTP') ?> par sous-domaine de <code><?= CONF['ht']['subdomain_domain'] ?></code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
<label for="subdomain">Sous-domaine sur lequel répondre</label><br>
|
||||||
|
<input required="" placeholder="label" id="subdomain" name="subdomain" type="text"><code>.<?= CONF['ht']['subdomain_domain'] ?></code><br>
|
||||||
|
<label for="dir">Dossier ciblé</label><br>
|
||||||
|
<select required="" name="dir" id="dir">
|
||||||
|
<option value="" disabled="" selected="">---</option>
|
||||||
|
<?php
|
||||||
|
foreach (dirsStatuses('subdomain') as $dir => $alreadyEnabled)
|
||||||
|
echo ' <option' . ($alreadyEnabled ? ' disabled=""' : '') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
||||||
|
?>
|
||||||
|
</select>
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Ajouter l'accès">
|
||||||
|
</form>
|
18
pg-view/ht/add-subpath.php
Normal file
18
pg-view/ht/add-subpath.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<p>
|
||||||
|
Ajouter sur un dossier de site un accès <?= linkToDocs('http', 'HTTP') ?> par sous-chemin de <code><?= CONF['ht']['subpath_domain'] ?>/</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
<label for="path">Chemin sur lequel répondre</label><br>
|
||||||
|
<code>https://<?= CONF['ht']['subpath_domain'] ?>/</code><input required="" placeholder="path" id="path" name="path" type="text"><br>
|
||||||
|
<label for="dir">Dossier ciblé</label><br>
|
||||||
|
<select required="" name="dir" id="dir">
|
||||||
|
<option value="" disabled="" selected="">---</option>
|
||||||
|
<?php
|
||||||
|
foreach (dirsStatuses('subpath') as $dir => $alreadyEnabled)
|
||||||
|
echo ' <option' . ($alreadyEnabled ? ' disabled=""' : '') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
||||||
|
?>
|
||||||
|
</select>
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Ajouter l'accès">
|
||||||
|
</form>
|
|
@ -1,16 +0,0 @@
|
||||||
<p>
|
|
||||||
Retirer un accès DNS et TLS d'un dossier
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<form method="post">
|
|
||||||
<label for="dir">Dossier ciblé</label><br>
|
|
||||||
<select required="" name="dir" id="dir">
|
|
||||||
<option value="" disabled="" selected="">---</option>
|
|
||||||
<?php
|
|
||||||
foreach (dirsStatuses('dns', 'http') as $dir => $alreadyEnabled)
|
|
||||||
echo ' <option' . ($alreadyEnabled ? '' : ' disabled=""') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
<br>
|
|
||||||
<input type="submit" value="Retirer l'accès">
|
|
||||||
</form>
|
|
|
@ -1,16 +0,0 @@
|
||||||
<p>
|
|
||||||
Retirer un accès Onion d'un dossier
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<form method="post">
|
|
||||||
<label for="dir">Dossier ciblé</label><br>
|
|
||||||
<select required="" name="dir" id="dir">
|
|
||||||
<option value="" disabled="" selected="">---</option>
|
|
||||||
<?php
|
|
||||||
foreach (dirsStatuses('onion', 'http') as $dir => $alreadyEnabled)
|
|
||||||
echo ' <option' . ($alreadyEnabled ? '' : ' disabled=""') . ' value="' . $dir . '">' . $dir . '</option>' . LF;
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
<br>
|
|
||||||
<input type="submit" value="Retirer l'accès">
|
|
||||||
</form>
|
|
23
pg-view/ht/del.php
Normal file
23
pg-view/ht/del.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<p>
|
||||||
|
Retirer un accès HTTP d'un dossier
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
<label for="site">Accès à retirer</label><br>
|
||||||
|
<select required="" name="site" id="site">
|
||||||
|
<option value="" disabled="" selected="">---</option>
|
||||||
|
<?php
|
||||||
|
foreach (query('select', 'sites', ['username' => $_SESSION['id'] ?? '']) as $site) {
|
||||||
|
$url = match ($site['type']) {
|
||||||
|
'subpath' => 'https://' . CONF['ht']['subpath_domain'] . '/' . $site['address'] . '/',
|
||||||
|
'subdomain' => 'https://' . $site['address'] . '.' . CONF['ht']['subdomain_domain'] . '/',
|
||||||
|
'onion' => 'http://' . $site['address'] . '/',
|
||||||
|
'dns' => 'https://' . $site['address'] . '/',
|
||||||
|
};
|
||||||
|
echo ' <option value="' . $site['type'] . ':' . $site['address'] . '">' . $url . ' vers /' . $site['site_dir'] . '</option>' . LF;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</select>
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Retirer l'accès">
|
||||||
|
</form>
|
|
@ -15,7 +15,12 @@ if ($sites === [])
|
||||||
else {
|
else {
|
||||||
echo ' <dl>' . LF;
|
echo ' <dl>' . LF;
|
||||||
foreach ($sites as $site) {
|
foreach ($sites as $site) {
|
||||||
$url = 'http' . (($site['domain_type'] === 'onion') ? '' : 's') . '://' . $site['domain'] . '/';
|
$url = match ($site['type']) {
|
||||||
|
'subpath' => 'https://' . CONF['ht']['subpath_domain'] . '/' . $site['address'] . '/',
|
||||||
|
'subdomain' => 'https://' . $site['address'] . '.' . CONF['ht']['subdomain_domain'] . '/',
|
||||||
|
'onion' => 'http://' . $site['address'] . '/',
|
||||||
|
'dns' => 'https://' . $site['address'] . '/',
|
||||||
|
};
|
||||||
?>
|
?>
|
||||||
<dt><code>/<?= $site['site_dir'] ?></code></dt>
|
<dt><code>/<?= $site['site_dir'] ?></code></dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
@ -43,7 +48,7 @@ else {
|
||||||
Vous avez accès à un espace <abbr title="SSH File Transfert Protocol">SFTP</abbr>, limité à <?php
|
Vous avez accès à un espace <abbr title="SSH File Transfert Protocol">SFTP</abbr>, limité à <?php
|
||||||
$quotaSize = ($_SESSION['type'] === 'approved') ? CONF['ht']['user_quota_approved'] : CONF['ht']['user_quota_testing'];
|
$quotaSize = ($_SESSION['type'] === 'approved') ? CONF['ht']['user_quota_approved'] : CONF['ht']['user_quota_testing'];
|
||||||
echo (($quotaSize >> 30) >= 1) ? $quotaSize >> 30 . ' ' . linkToDocs('units', '<abbr title="gibioctet">Gio</abbr>') : $quotaSize >> 20 . ' ' . linkToDocs('units', '<abbr title="mébioctet">Mio</abbr>')
|
echo (($quotaSize >> 30) >= 1) ? $quotaSize >> 30 . ' ' . linkToDocs('units', '<abbr title="gibioctet">Gio</abbr>') : $quotaSize >> 20 . ' ' . linkToDocs('units', '<abbr title="mébioctet">Mio</abbr>')
|
||||||
?>. Vous pouvez téléverser vos sites dans <code>/<nom du site>/*</code>. Indiquez les données ci-dessous à votre client <abbr title="SSH File Transfert Protocol">SFTP</abbr> pour y accéder.
|
?>. Indiquez les données ci-dessous à votre client <abbr title="SSH File Transfert Protocol">SFTP</abbr> pour y accéder.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
@ -107,12 +112,12 @@ echo (($quotaSize >> 30) >= 1) ? $quotaSize >> 30 . ' ' . linkToDocs('units', '<
|
||||||
</p>
|
</p>
|
||||||
<h3>Compression gzip</h3>
|
<h3>Compression gzip</h3>
|
||||||
<p>
|
<p>
|
||||||
La compression <em>gzip</em> est supportée, si le client le supporte et que le fichier est disponible, <code>chemin.gz</code> est servi au lieu de <code>chemin</code>.
|
La compression <em>gzip</em> statique est supportée, si le client le supporte et que le fichier est disponible, <code>chemin.gz</code> est servi au lieu de <code>chemin</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>Page d'index</h3>
|
<h3>Page d'index</h3>
|
||||||
<p>
|
<p>
|
||||||
Lors d'une requête sur un dossier, le premier des fichiers suivants qui existe dans ce dossier est répondu :
|
Lors d'une requête sur un dossier, le premier des fichiers suivants qui existe <em>dans ce dossier</em> est répondu :
|
||||||
</p>
|
</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>index.html</code></li>
|
<li><code>index.html</code></li>
|
||||||
|
@ -122,7 +127,7 @@ echo (($quotaSize >> 30) >= 1) ? $quotaSize >> 30 . ' ' . linkToDocs('units', '<
|
||||||
|
|
||||||
<h3>Page d'erreur 404</h3>
|
<h3>Page d'erreur 404</h3>
|
||||||
<p>
|
<p>
|
||||||
Lors d'une requête aboutissant à une erreur <code>404</code>, le premier des fichiers suivants qui existe à la racine du site est répondu :
|
Lors d'une requête aboutissant à une erreur <code>404</code>, le premier des fichiers suivants qui existe <em>à la racine du site</em> est répondu :
|
||||||
</p>
|
</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>404.html</code></li>
|
<li><code>404.html</code></li>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<?php
|
<?php
|
||||||
define('TIME', hrtime(true));
|
|
||||||
define('CONF', parse_ini_file(__DIR__ . '/config.ini', true, INI_SCANNER_TYPED));
|
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/niver.db'));
|
||||||
|
|
Loading…
Reference in a new issue