Add Apache HTTP Server (keep nginx as reverse proxy)

This commit is contained in:
Miraty 2023-04-11 16:14:20 +02:00
parent 4151c456d4
commit 246d395b59
40 changed files with 623 additions and 173 deletions

44
install/apache.sh Normal file
View file

@ -0,0 +1,44 @@
#!/usr/bin/bash
mkdir /srv/servnest/ht
cp -r /install/http-messages /srv/servnest/ht/http-messages
chown -R root:root /srv/servnest/ht
chmod -R u=rX,g=rX,o=rX /srv/servnest/ht
mkdir /srv/servnest/ht/fs
chown -R $apache:$sftpgo /srv/servnest/ht/fs
chmod -R u=rX,g=rwX,o= /srv/servnest/ht/fs
mkdir /srv/servnest/ht/uri
mkdir /srv/servnest/ht/uri/ht.servnest.test
chown -R $servnest:$apache /srv/servnest/ht/uri
chmod -R u=rwX,g=rX,o= /srv/servnest/ht/uri
if [[ $OS = "arch" ]]; then
rm -r /etc/httpd/*
mkdir /etc/httpd/conf/
cp -r /install/apache/* /etc/httpd/
mv /etc/httpd/httpd.conf /etc/httpd/conf/httpd.conf
mkdir -p /srv/servnest/ht/usr/lib
ln /usr/lib/libc.so.6 /srv/servnest/ht/usr/lib/libc.so.6
systemctl enable httpd
fi
if [[ $OS = "debian" ]]; then
rm -r /etc/apache2/*
cp -r /install/apache/* /etc/apache2/
mv /etc/apache2/httpd.conf /etc/apache2/apache2.conf
sed -i 's#/usr/lib/httpd/modules/#/usr/lib/apache2/modules/#g' /etc/apache2/apache2.conf
sed -i 's#ServerRoot "/etc/httpd"#ServerRoot "/etc/apache2"#' /etc/apache2/apache2.conf
sed -i 's/LoadModule unixd_module/#LoadModule unixd_module/' /etc/apache2/apache2.conf
sed -i 's/LoadModule mpm_event_module/#LoadModule mpm_event_module/' /etc/apache2/apache2.conf
sed -i 's/LoadModule log_config_module/#LoadModule log_config_module/' /etc/apache2/apache2.conf
sed -i 's#/var/log/httpd/#/var/log/apache2/#g' /etc/apache2/apache2.conf
mkdir -p /srv/servnest/ht/lib/x86_64-linux-gnu
ln /lib/x86_64-linux-gnu/libgcc_s.so.1 /srv/servnest/ht/lib/x86_64-linux-gnu/libgcc_s.so.1
ln /lib/x86_64-linux-gnu/libc.so.6 /srv/servnest/ht/lib/x86_64-linux-gnu/libc.so.6
fi

View file

@ -0,0 +1,43 @@
Alias /http-messages/ "/http-messages/"
<Directory "/http-messages/">
Require all granted
Options Multiviews
AddLanguage fr fr
AddLanguage en en
AddType text/html html
LanguagePriority en fr
ForceLanguagePriority Fallback
</Directory>
# 400 Bad Request
ErrorDocument 400 /http-messages/400
# 403 Forbidden
ErrorDocument 403 /http-messages/403
# 404 Not Found
ErrorDocument 404 /http-messages/404
# 405 Method Not Allowed
ErrorDocument 405 /http-messages/405
# 410 Gone
ErrorDocument 410 /http-messages/410
# 418 I'm a teapot
#ErrorDocument 418 /http-messages/418
# 500 Internal Server Error
ErrorDocument 500 /http-messages/500
# 502 Bad Gateway
ErrorDocument 502 /http-messages/502
# 503 Service Unavailable
ErrorDocument 503 /http-messages/503
# 504 Gateway Timeout
ErrorDocument 504 /http-messages/503

76
install/apache/httpd.conf Normal file
View file

@ -0,0 +1,76 @@
ServerRoot "/etc/httpd"
User apache
Group apache
ChrootDir "/srv/servnest/ht"
Suexec Off
LoadModule unixd_module /usr/lib/httpd/modules/mod_unixd.so
LoadModule mpm_event_module /usr/lib/httpd/modules/mod_mpm_event.so
LoadModule authz_core_module /usr/lib/httpd/modules/mod_authz_core.so
LoadModule vhost_alias_module /usr/lib/httpd/modules/mod_vhost_alias.so
LoadModule mime_module /usr/lib/httpd/modules/mod_mime.so
LoadModule headers_module /usr/lib/httpd/modules/mod_headers.so
LoadModule dir_module /usr/lib/httpd/modules/mod_dir.so
LoadModule expires_module /usr/lib/httpd/modules/mod_expires.so
LoadModule filter_module /usr/lib/httpd/modules/mod_filter.so
LoadModule brotli_module /usr/lib/httpd/modules/mod_brotli.so
LoadModule deflate_module /usr/lib/httpd/modules/mod_deflate.so
LoadModule autoindex_module /usr/lib/httpd/modules/mod_autoindex.so
LoadModule alias_module /usr/lib/httpd/modules/mod_alias.so
LoadModule negotiation_module /usr/lib/httpd/modules/mod_negotiation.so
<Directory "/">
Require all denied
</Directory>
ErrorLog "/var/log/httpd/error.log"
Define compress "text/plain text/html text/markdown text/gemini text/css text/javascript text/csv application/json application/ld+json application/manifest+json application/xml application/xhtml+xml application/atom+xml application/atomcat+xml application/atomsvc+xml application/rss+xml application/mathml+xml application/emotionml+xml font/ttf font/otf"
# brotli
AddOutputFilterByType BROTLI_COMPRESS ${compress}
# gzip
AddOutputFilterByType DEFLATE ${compress}
TypesConfig types
AddDefaultCharset utf-8
FileETag None
LimitInternalRecursion 5
ServerTokens ProductOnly
Include errors.conf
Define interface "[::1]:42999"
Listen ${interface}
<VirtualHost ${interface}>
VirtualDocumentRoot "/uri/%0"
AccessFileName ".htaccess"
DirectoryIndex index.html index.md index.gmi
<Directory "/uri/*/">
Require all granted
AllowOverride Nonfatal=All
AllowOverrideList \
<Files <FilesMatch \
Redirect RedirectMatch RedirectPermanent RedirectTemp \
ErrorDocument \
AddType ForceType \
DefaultLanguage AddLanguage LanguagePriority ForceLanguagePriority \
DirectoryIndex DirectorySlash \
RemoveType RemoveOutputFilter RemoveLanguage RemoveEncoding RemoveCharset \
ExpiresActive ExpiresDefault ExpiresByType \
DefaultIcon AddDescription AddAlt AddAltByEncoding AddAltByType AddIcon AddIconByEncoding AddIconByType \
IndexIgnore IndexIgnoreReset IndexOptions IndexOrderDefault HeaderName ReadmeName IndexStyleSheet \
Header
</Directory>
</VirtualHost>

85
install/apache/types Normal file
View file

@ -0,0 +1,85 @@
text/plain txt
application/octet-stream bin
# Hypertext
text/html html
text/markdown md
text/gemini gmi
# Misc
text/css css
text/javascript js
text/csv csv
text/calendar ics ifb
text/vtt vtt
text/dns zone soa
application/mbox mbox
application/x-bittorrent torrent
# Compressed
application/gzip gz
application/zip zip
application/epub+zip epub
application/pdf pdf
# JSON
application/json json
application/ld+json jsonld
application/manifest+json webmanifest
# XML
application/xml xml
application/xhtml+xml xhtml
application/atom+xml atom
application/atomcat+xml atomcat
application/atomsvc+xml atomsvc
application/rss+xml rss
application/mathml+xml mml
application/emotionml+xml emotionml
# OpenDocument
application/vnd.oasis.opendocument.chart odc
application/vnd.oasis.opendocument.chart-template otc
application/vnd.oasis.opendocument.database odb
application/vnd.oasis.opendocument.formula odf
application/vnd.oasis.opendocument.formula-template odft
application/vnd.oasis.opendocument.graphics odg
application/vnd.oasis.opendocument.graphics-template otg
application/vnd.oasis.opendocument.image odi
application/vnd.oasis.opendocument.image-template oti
application/vnd.oasis.opendocument.presentation odp
application/vnd.oasis.opendocument.presentation-template otp
application/vnd.oasis.opendocument.spreadsheet ods
application/vnd.oasis.opendocument.spreadsheet-template ots
application/vnd.oasis.opendocument.text odt
application/vnd.oasis.opendocument.text-master odm
application/vnd.oasis.opendocument.text-template ott
application/vnd.oasis.opendocument.text-web oth
# Font
font/ttf ttf
font/otf otf
font/woff woff
font/woff2 woff2
# Image
image/svg+xml svg svgz
image/png png
image/gif gif
image/jpeg jpeg jpg
image/webp webp
image/avif avif
image/jxl jxl
image/openraster ora
# Audio
audio/opus opus
audio/ogg ogg oga spx
audio/mpeg mp3
audio/webm weba
audio/flac flac
# Video
video/ogg ogv
video/webm webm
video/mp4 mp4

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bad request · HTTP 400</title>
</head>
<body>
<h1>Bad request</h1>
<p>
The request is malformed.
</p>
<small>HTTP <code>400</code></small>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Access forbidden · HTTP 403</title>
</head>
<body>
<h1>Access forbidden</h1>
<p>
The server refused to process the request for security reasons.
</p>
<small>HTTP <code>403</code></small>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>File not found · HTTP 404</title>
</head>
<body>
<h1>File not found</h1>
<p>
The server did not find anything at the requested address.
</p>
<ul>
<li>The file may have been moved or deleted.</li>
<li>Perhaps the address was mistyped.</li>
</ul>
<small>HTTP <code>404</code></small>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fichier introuvable · HTTP 404</title>
</head>
<body>
<h1>Fichier introuvable</h1>
<p>
Le serveur n'a rien trouvé à l'adresse demandée.
</p>
<ul>
<li>Le fichier a pu être déplacé ou supprimé.</li>
<li>L'adresse a peut-être été mal saisie.</li>
</ul>
<small>HTTP <code>404</code></small>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Method Not Allowed · HTTP 405</title>
</head>
<body>
<h1>Method Not Allowed</h1>
<p>
The request method is not supported for this resource.
</p>
<small>HTTP <code>405</code></small>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Gone · HTTP 410</title>
</head>
<body>
<h1>Gone</h1>
<p>
The requested resource is not available anymore.
</p>
<small>HTTP <code>410</code></small>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>I'm a teapot · HTTP 418</title>
</head>
<body>
<h1>I'm a teapot</h1>
<p>
Your coffee cannot be brewed because this server is a teapot.
</p>
<small>HTTP <code>418</code></small>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Server error · HTTP 500</title>
</head>
<body>
<h1>Server error</h1>
<p>
The server encountered an error and is unable to satisfy your request.
</p>
<ul>
<li>This error is probably temporary.</li>
<li>If it isn't, you can try to contact an administrator.</li>
</ul>
<small>HTTP <code>500</code></small>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Erreur du serveur · HTTP 500</title>
</head>
<body>
<h1>Erreur du serveur</h1>
<p>
Le serveur a rencontré une erreur et ne peut pas répondre à cette requête.
</p>
<ul>
<li>Cette erreur est probablement temporaire.</li>
<li>Si ce n'est pas le cas, vous pouvez contacter ane administrataire.</li>
</ul>
<small>HTTP <code>500</code></small>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bad gateway · HTTP 502</title>
</head>
<body>
<h1>Bad gateway</h1>
<p>
The backend server encountered an error and is unable to satisfy your request.
</p>
<ul>
<li>This error is probably temporary.</li>
<li>If it isn't, you can try to contact an administrator.</li>
</ul>
<small>HTTP <code>502</code></small>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Service unavailable · HTTP 503</title>
</head>
<body>
<h1>Service unavailable</h1>
<p>
The server cannot handle the request, because it is overloaded or down for maintenance.
</p>
<ul>
<li>This error is probably temporary.</li>
<li>If it isn't, you can try to contact an administrator.</li>
</ul>
<small>HTTP <code>503</code></small>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Service indisponible · HTTP 503</title>
</head>
<body>
<h1>Service indisponible</h1>
<p>
Le serveur ne peut pas répondre à cette requête, car il est surchargé ou en cours de maintenance.
</p>
<ul>
<li>Cette erreur est probablement temporaire.</li>
<li>Si ce n'est pas le cas, vous pouvez contacter ane administrataire.</li>
</ul>
<small>HTTP <code>503</code></small>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Gateway timeout · HTTP 504</title>
</head>
<body>
<h1>Gateway timeout</h1>
<p>
The backend server did not send a timely response.
</p>
<ul>
<li>This error is probably temporary.</li>
<li>If it isn't, you can try to contact an administrator.</li>
</ul>
<small>HTTP <code>504</code></small>
</body>
</html>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>TLS required</title>
</head>
<body>
<h1>TLS required</h1>
<p>
This site does not accept HTTP requests without TLS.
</p>
<h2>What happened?</h2>
<p>
You made a request using HTTP without TLS to the server, which refused this for privacy and security reasons, as unsecure HTTP connections can be watched and modified by any device on the way.
</p>
<h2>How to solve this?</h2>
<p>
You can replace the URI scheme <code>http</code> by <code>https</code> to tell your client to make the request using TLS.
</p>
<code>HTTP 403</code>
</body>
</html>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Nécessite TLS</title>
</head>
<body>
<h1>Nécessite TLS</h1>
<p>
Ce site n'accepte pas les connexions HTTP sans TLS.
</p>
<h2>Que s'est-il passé ?</h2>
<p>
Vous avez envoyé une requête HTTP sans TLS au serveur, qui l'a refusée pour des raisons de sécurité et de confidentialité.
</p>
<h2>Comment régler ce problème ?</h2>
<p>
Vous pouvez remplacer le schéma d'URI <code>http</code> par <code>https</code> pour indiquer à votre client de faire la requête avec TLS.
</p>
<code>HTTP 403</code>
</body>
</html>

View file

@ -3,6 +3,7 @@ export sftpgo='sftpgo'
export servnest='servnest'
export knot='knot'
export nginx='nginx'
export apache='apache'
export tor='tor'
if [[ $OS = "debian" ]]; then
export tor='debian-tor'
@ -12,6 +13,7 @@ fi
useradd -U -r -s $(which nologin) $nginx
useradd -U -r -s $(which nologin) $servnest
useradd -U -r -s $(which nologin) $sftpgo
useradd -U -r -s $(which nologin) $apache
# Execute installation steps
source /install/sudo.sh
@ -20,5 +22,6 @@ source /install/knot.sh
source /install/servnest.sh
source /install/php.sh
source /install/nginx.sh
source /install/apache.sh
source /install/sftpgo.sh
source /install/certbot.sh

View file

@ -3,9 +3,7 @@
# Generate default self-signed TLS key pair
openssl req -subj '/' -new -newkey RSA:3072 -days 3650 -nodes -x509 -keyout /etc/ssl/private/servnest.key -out /etc/ssl/certs/servnest.crt
openssl req -subj '/' -new -newkey RSA:3072 -days 3650 -nodes -x509 -keyout /etc/ssl/private/ht.servnest.test.key -out /etc/ssl/certs/ht.servnest.test.crt
rm -r /etc/nginx/*
cp -r /install/nginx/* /etc/nginx/
mkdir /srv/servnest/nginx /srv/servnest/subpath /srv/servnest/subdomain
chown $servnest:$nginx /srv/servnest/nginx /srv/servnest/subpath /srv/servnest/subdomain
chmod u=rwX,g=rX,o= /srv/servnest/nginx /srv/servnest/subpath /srv/servnest/subdomain

View file

@ -1,82 +1,20 @@
recursive_error_pages on;
# 403 Forbidden
error_page 403 @403;
location @403 {
root /srv/servnest/core/http-errors;
try_files /403.html =500;
location /http-messages {
proxy_pass http://[::1]:42999;
proxy_ignore_client_abort on;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_redirect http://$host:42999/ /;
}
# 404 Not Found
error_page 404 @local404;
location @local404 {
try_files /404.html /404.md /404.gmi @servnest404;
}
location @servnest404 {
root /srv/servnest/core/http-errors;
try_files /404.php =500;
index /404.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/servnest.sock;
include inc/fastcgi.conf;
fastcgi_index /404.php;
}
# 405 Method Not Allowed
error_page 405 @405;
location @405 {
root /srv/servnest/core/http-errors;
try_files /405.html =500;
}
# 410 Gone
error_page 410 @410;
location @410 {
root /srv/servnest/core/http-errors;
try_files /410.html =500;
}
# 418 I'm a teapot
error_page 418 @418;
location @418 {
root /srv/servnest/core/http-errors;
try_files /418.html =500;
}
# 500 Internal Server Error
error_page 500 @500;
location @500 {
root /srv/servnest/core/http-errors;
try_files /500.php /500.en.html =500;
index /500.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/servnest.sock;
include inc/fastcgi.conf;
fastcgi_index /500.php;
}
# 502 Bad Gateway
error_page 502 @502;
location @502 {
root /srv/servnest/core/http-errors;
try_files /502.html =500;
}
# 503 Service Unavailable
error_page 503 @503;
location @503 {
root /srv/servnest/core/http-errors;
try_files /503.php =500;
index /503.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/servnest.sock;
include inc/fastcgi.conf;
fastcgi_index /503.php;
}
# 504 Gateway Timeout
error_page 504 @504;
location @504 {
root /srv/servnest/core/http-errors;
try_files /504.html =500;
}
error_page 400 /http-messages/400;
error_page 403 /http-messages/403;
error_page 404 /http-messages/404;
error_page 405 /http-messages/405;
error_page 410 /http-messages/410;
error_page 418 /http-messages/418;
error_page 500 /http-messages/500;
error_page 502 /http-messages/502;
error_page 503 /http-messages/503;
error_page 504 /http-messages/504;

View file

@ -1,3 +0,0 @@
# This configuration file is included by dedicated Onion sites created by ServNest
include inc/ht.conf;

View file

@ -1,4 +0,0 @@
# This configuration file is included by dedicated DNS and TLS sites created by ServNest
include inc/ht.conf;
include inc/tls.conf;

View file

@ -1,7 +1,14 @@
include inc/errors.conf;
more_clear_headers "Set-Cookie";
more_clear_input_headers "Cookie";
more_set_headers "Content-Security-Policy : default-src 'none'; style-src 'self' 'unsafe-inline' data:; img-src 'self' data:; font-src 'self' data:; media-src 'self' data:; frame-ancestors 'none'; form-action 'none';";
location / {
try_files $uri $uri/index.html $uri/index.md $uri/index.gmi =404;
proxy_pass http://[::1]:42999/;
proxy_ignore_client_abort on;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_redirect http://$host:42999/ /;
}
include inc/errors.conf;

View file

@ -1,2 +0,0 @@
ssl_protocols TLSv1.3;
ssl_ecdh_curve X25519:X448;

View file

@ -43,7 +43,7 @@ types {
application/vnd.oasis.opendocument.chart-template otc;
application/vnd.oasis.opendocument.database odb;
application/vnd.oasis.opendocument.formula odf;
application/vnd.oasis.opendocument.formula-template otf;
application/vnd.oasis.opendocument.formula-template odft;
application/vnd.oasis.opendocument.graphics odg;
application/vnd.oasis.opendocument.graphics-template otg;
application/vnd.oasis.opendocument.image odi;
@ -58,27 +58,30 @@ types {
application/vnd.oasis.opendocument.text-web oth;
# Font
font/ttf ttf;
font/otf otf;
font/woff woff;
font/woff2 woff2;
# Image
image/svg+xml svg svgz;
image/png png;
image/gif gif;
image/jpeg jpeg jpg;
image/svg+xml svg svgz;
image/webp webp;
image/avif avif;
image/jxl jxl;
image/openraster ora;
# Audio
audio/opus opus;
audio/ogg ogg oga spx;
audio/mpeg mp3;
audio/webm weba;
audio/flac flac;
audio/opus opus;
audio/ogg ogg oga spx;
audio/mpeg mp3;
audio/webm weba;
audio/flac flac;
# Video
video/ogg ogv;
video/webm webm;
video/mp4 mp4;
video/ogg ogv;
video/webm webm;
video/mp4 mp4;
}

View file

@ -27,29 +27,29 @@ http {
gzip_static on;
# Logging
map $http_cookie $loggable {
"" 0;
default 1;
}
log_format servnest '|$time_local| [$remote_addr]@$server_name {$ssl_protocol $ssl_cipher} $status $body_bytes_sent "$request" "$http_user_agent"';
error_log /var/log/nginx/error.log notice;
access_log /var/log/nginx/access.log servnest if=$loggable;
access_log off;
# Disable useless/dangerous features
etag off;
server_tokens off;
more_clear_headers Server;
more_clear_headers "Server";
# Delete unused request headers
more_clear_input_headers "User-Agent";
more_clear_input_headers "Referer";
more_clear_input_headers "From";
more_clear_input_headers "DNT";
# Basic security headers
more_set_headers "Referrer-Policy : no-referrer";
more_set_headers "Strict-Transport-Security : max-age=94608000; includeSubDomains; preload";
more_set_headers "Strict-Transport-Security : max-age=31536000";
more_set_headers "X-Content-Type-Options : nosniff";
#more_set_headers "X-XSS-Protection : 1; mode=block";
#more_set_headers "X-Download-Options : noopen";
#more_set_headers "X-Permitted-Cross-Domain-Policies : none";
#more_set_headers "X-Frame-Options : DENY";
# Basic TLS settings
# TLS
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_ecdh_curve X25519:X448:prime256v1;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

View file

@ -1,25 +0,0 @@
# This server block is reached only if no other server block can match, and displays some explanations
server {
listen [::1]:42443 ssl http2 default_server;
listen 127.0.0.1:42443 ssl http2 default_server;
ssl_certificate /etc/ssl/certs/servnest.crt;
ssl_certificate_key /etc/ssl/private/servnest.key;
ssl_stapling off;
location / {
root /srv/servnest/core/http-errors;
try_files /index.php =500;
index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/servnest.sock;
include /etc/nginx/inc/fastcgi.conf;
}
include /etc/nginx/inc/tls.conf;
include /etc/nginx/inc/errors.conf;
more_set_headers "Content-Security-Policy : default-src 'none'; frame-ancestors 'none';";
}

View file

@ -0,0 +1,10 @@
# DNS+TLS site access
server {
listen [::1]:42443 ssl http2 default_server;
listen 127.0.0.1:42443 ssl http2 default_server;
ssl_certificate /etc/ssl/certs/${ssl_server_name}.crt;
ssl_certificate_key /etc/ssl/private/${ssl_server_name}.key;
include inc/proxy.conf;
}

View file

@ -4,20 +4,13 @@ server {
listen [::1]:42080 default_server;
listen 127.0.0.1:42080 default_server;
include inc/errors.conf;
location / {
return 403; # Don't allow unsecure HTTP requests
}
# Display an explanation page
error_page 403 @http403;
location @http403 {
root /srv/servnest/core/http-errors;
try_files /unsecure.php =500;
index unsecure.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/servnest.sock;
include inc/fastcgi.conf;
}
error_page 403 /http-messages/unsecure;
location /.well-known/acme-challenge {
root /srv/servnest/acme/;

View file

@ -1,5 +1,6 @@
# This server block is the publicly exposed ServNest control interface
log_format servnest '|$time_local| [$ip_start]@$server_name $status $body_bytes_sent "$request"';
server {
listen [::1]:42443 ssl http2;
listen 127.0.0.1:42443 ssl http2;
@ -7,7 +8,6 @@ server {
root /srv/servnest/core;
include inc/tls.conf;
include inc/errors.conf;
more_set_headers "Content-Security-Policy : default-src 'none'; style-src 'self'; frame-ancestors 'none'; form-action 'self';";
@ -29,7 +29,18 @@ server {
alias /srv/servnest/docs;
}
access_log /var/log/nginx/servnest-access.log servnest if=$loggable;
# For a public server, these should point to a Let's Encrypt-trusted key pair
ssl_certificate /etc/ssl/certs/servnest.crt;
ssl_certificate_key /etc/ssl/private/servnest.key;
}
map $request_method $loggable { # Log only POST requests
"POST" 1;
default 0;
}
map $remote_addr $ip_start {
"~^(?P<ipv6_start>[^:]+:[^:]+)" $ipv6_start; # Log 4 first bytes for IPv6
"~^(?P<ipv4_start>[^.]+\.[^.]+\.[^.]+)" $ipv4_start; # Log 3 first bytes for IPv4
default $remote_addr;
}

View file

@ -0,0 +1,6 @@
# Onion service site access
server {
listen [::1]:9080 default_server;
include inc/proxy.conf;
}

View file

@ -3,12 +3,10 @@
server {
listen [::1]:42443 ssl http2;
listen 127.0.0.1:42443 ssl http2;
server_name "~^(?<subdomain>[a-z0-9]{1,32})\.ht\.servnest\.test$";
server_name *.ht.servnest.test;
include inc/ht-tls.conf;
ssl_certificate /etc/ssl/certs/ht.servnest.test.crt;
ssl_certificate_key /etc/ssl/private/ht.servnest.test.key;
ssl_certificate /etc/ssl/certs/servnest.crt;
ssl_certificate_key /etc/ssl/private/servnest.key;
root /srv/servnest/subdomain/${subdomain}/;
include inc/proxy.conf;
}

View file

@ -5,10 +5,8 @@ server {
listen 127.0.0.1:42443 ssl http2;
server_name ht.servnest.test;
include inc/ht-tls.conf;
ssl_certificate /etc/ssl/certs/ht.servnest.test.crt;
ssl_certificate_key /etc/ssl/private/ht.servnest.test.key;
ssl_certificate /etc/ssl/certs/servnest.crt;
ssl_certificate_key /etc/ssl/private/servnest.key;
root /srv/servnest/subpath/;
include inc/proxy.conf;
}

View file

@ -16,8 +16,6 @@ pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
access.log = /var/log/php/servnest-access.log
catch_workers_output = yes
decorate_workers_output = yes

View file

@ -20,10 +20,6 @@ chown -R $sftpgo: /etc/sftpgo
chmod -R u=rX,g=rX,o= /etc/sftpgo
chmod u=r,g=,o= /etc/sftpgo/ed25519
mkdir /srv/servnest/ht
chown -R $nginx:$sftpgo /srv/servnest/ht
chmod -R u=rX,g=rwX,o= /srv/servnest/ht
# For systemd
cp /install/sftpgo.service /etc/systemd/system/
systemctl enable sftpgo

View file

@ -1,9 +1,8 @@
servnest ALL=(root) NOPASSWD: /usr/bin/systemctl reload nginx
servnest ALL=(root) NOPASSWD: /usr/bin/systemctl reload tor
servnest ALL=(root) NOPASSWD: /usr/bin/chgrp ^sftpgo /srv/servnest/ht/[0-9a-f]{64} --no-dereference$
servnest ALL=(root) NOPASSWD: /usr/bin/chgrp ^sftpgo /srv/servnest/ht/fs/[0-9a-f]{64} --no-dereference$
servnest ALL=(root) NOPASSWD: /usr/bin/certbot ^certonly( --test-cert)? --key-type rsa --rsa-key-size 3072 --webroot --webroot-path /srv/servnest/acme --domain ([a-z0-9_-]{1,63}\.){1,126}[a-z0-9]{1,63}$
servnest ALL=(root) NOPASSWD: /usr/bin/certbot ^delete --quiet --cert-name ([a-z0-9_-]{1,63}\.){1,126}[a-z0-9]{1,63}$
servnest ALL=(tor) NOPASSWD: /usr/bin/cat ^/srv/servnest/tor-keys/[0-9a-f]{64}/[a-zA-Z0-9_-]{1,64}/hostname$
servnest ALL=(tor) NOPASSWD: /usr/bin/mkdir ^--mode=0700 /srv/servnest/tor-keys/[0-9a-f]{64}$
servnest ALL=(tor) NOPASSWD: /usr/bin/rm ^--recursive /srv/servnest/tor-keys/[0-9a-f]{64}(/[a-zA-Z0-9_-]{1,64})?$
servnest ALL=(sftpgo) NOPASSWD: /usr/bin/rm ^--recursive /srv/servnest/ht/[0-9a-f]{64}$
servnest ALL=(sftpgo) NOPASSWD: /usr/bin/rm ^--recursive /srv/servnest/ht/fs/[0-9a-f]{64}$

View file

@ -8,6 +8,7 @@ Output = /var/lib/machines/servnest-arch
[Content]
Packages =
apache
nginx-mod-headers-more
certbot-nginx
php-sqlite
@ -16,3 +17,4 @@ Packages =
openssh
iputils
which
sshpass

View file

@ -9,6 +9,7 @@ Output = /var/lib/machines/servnest-debian
[Content]
Packages =
apt-transport-tor
apache2
libnginx-mod-http-headers-more-filter
python3-certbot-nginx
knot-dnsutils
@ -17,3 +18,5 @@ Packages =
openssh-server
iputils-ping
gettext
php-curl
sshpass