Compare commits

...

13 commits
main ... podman

Author SHA1 Message Date
Miraty
4cc1f2bebd put back license information on readme 2024-09-29 22:09:33 +02:00
Miraty
4c24e5720b readme: more information 2024-09-22 18:38:33 +02:00
Miraty
72f793c5dd add .gitkeep for more required directories 2024-09-22 18:33:09 +02:00
Miraty
cd9234adc5 add .gitkeep for required directories 2024-09-10 18:38:27 +02:00
Miraty
7f94b9d919 add default zone files for registry 2024-08-08 02:51:15 +02:00
Miraty
dfbf57a155 various minor fixes 2024-08-08 00:11:05 +02:00
Miraty
9a03df85f2 run tor as root 2024-08-08 00:03:43 +02:00
Miraty
c438fc348d rename root directories 2024-07-26 01:43:56 +02:00
Miraty
40a2fec99d make every container read-only 2024-07-25 21:20:03 +02:00
Miraty
05e4dbcd63 sftpgo.toml: force umask to 022 + don't show version 2024-07-25 15:20:22 +02:00
Miraty
2088d187d3 add alpine as base image + add cronie service 2024-07-24 18:30:48 +02:00
Miraty
4b387af85e move container/ tree at root, del mkosi, add certbot 2024-07-23 00:27:43 +02:00
Miraty
b6ec2e2ef6 podman containers introduction 2024-07-18 20:58:12 +02:00
115 changed files with 413 additions and 4664 deletions

2
.env Normal file
View file

@ -0,0 +1,2 @@
SYS=alpine-minirootfs-3.20.2-x86_64.tar.gz
SFTPGO=sftpgo-v2.6.2.tar.gz

30
.gitignore vendored
View file

@ -1,4 +1,26 @@
/mkosi.passphrase
/mkosi.passwd
/mkosi.extra/root/.ssh/authorized_keys
/mkosi.extra/usr/local/bin/sftpgo
/*.tar.gz
/data/servnest.db
/logs/certbot/letsencrypt.log*
/data/certbot/live/*/*.pem
/data/certbot/archive/*/*.pem
/data/certbot/**/README
/data/certbot/renewal/*.conf
/data/ht/fs/*
/data/ht/uri/ht.servnest.test/*
/data/ht/uri/*
/data/ns/*.zone
/data/reg/servnest.test.zone
/data/reg/test.servnest.test.zone
/data/tor-config/*
/data/tor-keys/*
/logs/sftpgo/sftpgo.log
/logs/php/error.log
/logs/cronie/*.log
/logs/nginx/servnest-access.log
/logs/nginx/error.log
/logs/apache/error.log
/data/certbot/accounts/acme-staging-v02.api.letsencrypt.org/directory/*/*.json
/sock/knot/knot.pid
/data/knot/confdb/*.mdb
/data/knot/servnest.test.invalid.zone
/tmp/tor/*

View file

@ -1,35 +1,55 @@
# ServNest system images generator
# podman-compose setup
This is the sources to build system images of ServNest using mkosi 22. You can then use them with systemd-nspawn.
## Use
This repository also contains configuration files and installation scripts inside `install` that may also be useful for the manual installation process, without mkosi.
### Preparation
## Usage
This generator allows to build images for both Arch Linux and Debian, you can replace `<sysid>` by either `sn-arch` or `sn-debian` in the following examples. Note that mkosi may require tools that are not available on your distribution.
First:
- Put the ServNest source code inside `mkosi.extra/srv/servnest/core/`
- Put a SFTPGo binary compiled as bundle in `mkosi.extra/usr/local/bin/sftpgo` (`mkosi.extra/root/sftpgo.sh` is provided for this purpose)
- Put your SSH public key in `mkosi.extra/root/.ssh/authorized_keys`
You can generate a new image in `/var/lib/machines/<sysid>` by running `mkosi --force --image <sysid> build` from this repository (`--force` erases an already existing image).
You need to copy `mkosi.nspawn` into `/etc/systemd/nspawn/<sysid>.nspawn` to allow the container to use network without restrictions.
You can then boot the container:
```shell
machinectl start <sysid>
machinectl shell <sysid>
Set the following in `~/.config/containers/containers.conf` (or `/etc/containers/containers.conf`):
```toml
[containers]
no_hosts=true
```
The full explanation of the structure in this repository can be found on the mkosi manpage. Here is a summary of what mkosi will do in this repository:
```shell
knotc --confdb data/knot/confdb conf-import conf/knot.conf
cp data/reg/servnest.test.zone.default data/reg/servnest.test.zone
cp data/reg/test.servnest.test.zone.default data/reg/test.servnest.test.zone
chmod u=rwX,g=rX,o=rX -R conf core
chmod u=rwX,g=rwX,o=rwX logs/sftpgo logs/php sock/php logs/apache logs/nginx sock/tor-client sock/nginx-onion sock/knot data/knot data/knot/confdb data/knot/confdb/*.mdb tmp/nginx tmp/certbot tmp/acme data/reg data/reg/*.zone core/db core/db/servnest.db
chmod u=rwX,g=rX,o= sock/tor-control
wget https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/x86_64/alpine-minirootfs-3.20.2-x86_64.tar.gz
wget https://github.com/drakkan/sftpgo/archive/refs/tags/v2.6.2.tar.gz -O sftpgo-v2.6.2.tar.gz
sha256sum -c sha256sums
```
1. Load configuration from `mkosi.default` and `mkosi.default.d/<sysid>/mkosi.default`
2. Install packages according to configuration
3. Copy this repository to the container root
4. Run `mkosi.postinst`, which runs specific scripts inside `install`, which do configuration (depending on the distribution)
### Build
```shell
podman-compose -f base.yaml build alpine # build base image
podman-compose build # build services images
```
### Run
```shell
podman-compose up # start containers
podman-compose exec php php /srv/servnest/core/jobs/check.php # test main features
```
When running `up`, the only expected error messages are:
> [sftpgo] | WRN provider initialized but data loading failed: stat sftpgo.db: no such file or directory
> [tor] | [warn] You are running Tor as root. You don't need to, and you probably shouldn't.
Podman Compose 1.2.0 randomly fails to start some services (see [issue 921](https://github.com/containers/podman-compose/issues/921)). The workaround is to retry multiple times.
### Reset
```shell
podman container rm --all
podman image rm --all
podman rm $(podman container list --external -q)
```
## License
ServNest system images generator is ethical libre software: you can use, redistribute or modify it under the terms of the CNPL-NAv7+ as found in LICENSE.md or at <https://git.pixie.town/thufie/npl-builder>.
This project is published under the Cooperative Nonviolent Public License No Attributions, version 7 or any later version (<abbr>CNPL-NAv7+</abbr>), as found in [`LICENSE.md`](LICENSE.md) or at <https://git.pixie.town/thufie/npl-builder>.

9
alpine.Containerfile Normal file
View file

@ -0,0 +1,9 @@
FROM scratch
ARG SYS
ADD $SYS /
RUN apk upgrade -U
RUN apk add shadow
RUN \
useradd --user-group --system --no-create-home --uid 500 servnest && \
useradd --user-group --system --no-create-home --uid 501 nginx && \
useradd --user-group --system --no-create-home --uid 505 sftpgo

5
apache.Containerfile Normal file
View file

@ -0,0 +1,5 @@
FROM servnest_alpine
RUN apk add apache2 apache2-brotli
RUN chown apache: /run/apache2/
USER apache
CMD ["httpd", "-D", "FOREGROUND"]

21
base.yaml Normal file
View file

@ -0,0 +1,21 @@
name: servnest
services:
alpine:
build:
args:
SYS: $SYS
dockerfile: alpine.Containerfile
cpus: '0.5'
mem_limit: 16mb
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
restart: "always"
base: # Reset "args" to avoid unused arg warning
extends:
service: alpine
build:
args: {}

132
compose.yaml Normal file
View file

@ -0,0 +1,132 @@
name: servnest
services:
tor:
extends:
file: base.yaml
service: base
build:
dockerfile: tor.Containerfile
volumes:
- ./conf/torrc:/etc/tor/torrc:ro
- ./data/tor-config/:/srv/servnest/tor-config/:ro
- ./data/tor-keys/:/srv/servnest/tor-keys/:rw
- ./sock/tor-client/:/run/tor-client/:rw
- ./sock/tor-control/:/run/tor-control/:rw
- ./sock/nginx-onion/:/run/nginx-onion/:rw
- ./tmp/tor/:/var/lib/tor/:rw
mem_limit: 128m
sftpgo:
extends:
file: base.yaml
service: base
build:
dockerfile: sftpgo.Containerfile
args:
SFTPGO: $SFTPGO
ports:
- "[::1]:42022:42022/tcp"
links:
- nginx:servnest.test
volumes:
- ./conf/sftpgo.toml:/etc/sftpgo/sftpgo.toml:ro
- ./data/ht/fs/:/srv/servnest/ht/fs/:rw
- ./logs/sftpgo/:/var/log/sftpgo/:rw
mem_limit: 256mb
knot:
extends:
file: base.yaml
service: base
build:
dockerfile: knot.Containerfile
ports:
- "[::1]:42053:42053/udp"
- "[::1]:42053:42053/tcp"
volumes:
- ./data/reg/:/srv/servnest/reg/:rw
- ./data/ns/:/srv/servnest/ns/:rw
- ./data/knot/:/var/lib/knot/:rw
- ./sock/knot/:/run/knot/:rw
apache:
extends:
file: base.yaml
service: base
build:
dockerfile: apache.Containerfile
volumes:
- ./conf/apache/:/etc/apache2/:ro
- ./conf/http-messages/:/srv/servnest/ht/http-messages/:ro
- ./data/ht/:/srv/servnest/ht/:ro
- ./logs/apache/:/var/log/apache2/:rw
php:
extends:
file: base.yaml
service: base
build:
dockerfile: php.Containerfile
group_add:
- knot
- root # For tor control socket
links:
- nginx:servnest.test
- nginx:ht.servnest.test
- sftpgo:sftp.servnest.test
volumes:
- ./core/:/srv/servnest/core/:ro
- ./core/db/:/srv/servnest/core/db/:rw
- ./conf/php.ini:/etc/php83/conf.d/servnest.ini:ro
- ./conf/php-fpm.conf:/etc/php83/php-fpm.d/servnest.conf:ro
- ./conf/sudoers:/etc/sudoers.d/servnest:ro
- ./conf/certbot.ini:/etc/letsencrypt/servnest.ini:ro
- ./conf/certbot-deploy-hook.sh:/root/certbot-deploy-hook.sh:ro
- ./data/reg/:/srv/servnest/reg/:rw
- ./data/ns/:/srv/servnest/ns/:rw
- ./data/ht/fs/:/srv/servnest/ht/fs/:rw
- ./data/ht/uri/:/srv/servnest/ht/uri/:rw
- ./data/tor-config/:/srv/servnest/tor-config/:rw
- ./data/tor-keys/:/srv/servnest/tor-keys/:rw
- ./data/certbot/:/etc/letsencrypt/:rw
- ./sock/php/:/run/php-fpm/:rw
- ./sock/tor-client/:/run/tor-client/:rw
- ./sock/tor-control/:/run/tor-control/:rw
- ./sock/knot/:/run/knot/:rw
- ./logs/php/:/var/log/php83/:rw
- ./logs/certbot/:/var/log/letsencrypt/:rw
- ./tmp/acme/:/srv/servnest/acme/:rw
- ./tmp/certbot/:/var/lib/letsencrypt/:rw
mem_limit: 256mb
# For sudo
security_opt:
- no-new-privileges:false
cap_add:
- SETUID
- SETGID
- CHOWN
cronie:
extends:
service: php
build:
dockerfile: cronie.Containerfile
volumes:
- ./conf/cronie:/etc/cron.d/servnest:ro
- ./logs/cronie/:/var/log/cronie/:rw
nginx:
extends:
file: base.yaml
service: base
build:
dockerfile: nginx.Containerfile
ports:
- "[::1]:42080:42080/tcp"
- "[::1]:42443:42443/tcp"
depends_on:
- apache
volumes:
- ./core/:/srv/servnest/core/:ro
- ./conf/nginx/:/etc/nginx/:ro
- ./data/certbot/live/:/etc/letsencrypt/live/:ro
- ./data/certbot/archive/:/etc/letsencrypt/archive/:ro
- ./sock/php/:/run/php-fpm/:rw
- ./sock/nginx-onion/:/run/nginx-onion/:rw
- ./logs/nginx/:/var/lib/nginx/logs/:rw
- ./tmp/nginx/:/var/lib/nginx/tmp/:rw
- ./tmp/acme/:/srv/servnest/acme/:ro

View file

@ -1,6 +1,6 @@
Alias /http-messages/ "/http-messages/"
Alias /http-messages/ "/srv/servnest/ht/http-messages/"
<Directory "/http-messages/">
<Directory "/srv/servnest/ht/http-messages/">
Require all granted
Options Multiviews
AddLanguage fr fr

View file

@ -1,31 +1,31 @@
ServerRoot "/etc/httpd"
ServerRoot "/etc/apache2"
User apache
Group apache
ChrootDir "/srv/servnest/ht"
#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 unixd_module /usr/lib/apache2/mod_unixd.so
LoadModule mpm_event_module /usr/lib/apache2/mod_mpm_event.so
LoadModule authz_core_module /usr/lib/apache2/mod_authz_core.so
LoadModule vhost_alias_module /usr/lib/apache2/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
LoadModule mime_module /usr/lib/apache2/mod_mime.so
LoadModule headers_module /usr/lib/apache2/mod_headers.so
LoadModule dir_module /usr/lib/apache2/mod_dir.so
LoadModule expires_module /usr/lib/apache2/mod_expires.so
LoadModule filter_module /usr/lib/apache2/mod_filter.so
LoadModule brotli_module /usr/lib/apache2/mod_brotli.so
LoadModule deflate_module /usr/lib/apache2/mod_deflate.so
LoadModule autoindex_module /usr/lib/apache2/mod_autoindex.so
LoadModule alias_module /usr/lib/apache2/mod_alias.so
LoadModule negotiation_module /usr/lib/apache2/mod_negotiation.so
<Directory "/">
Require all denied
</Directory>
ErrorLog "/var/log/httpd/error.log"
ErrorLog "/var/log/apache2/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
@ -43,20 +43,22 @@ LimitInternalRecursion 5
ServerTokens ProductOnly
ServerName localhost
Include errors.conf
Define interface "[::1]:42999"
Define interface "0.0.0.0:42999"
Listen ${interface}
<VirtualHost ${interface}>
VirtualDocumentRoot "/uri/%0"
VirtualDocumentRoot "/srv/servnest/ht/uri/%0"
AccessFileName ".htaccess"
DirectoryIndex index.html index.md index.gmi
<Directory "/uri/*/">
<Directory "/srv/servnest/ht/uri/*/">
Require all granted
AllowOverride Nonfatal=All

View file

@ -3,7 +3,7 @@ non-interactive
agree-tos
no-eff-email
; Set your email address
email = "address@invalid"
email = "address@test.org"
webroot
webroot-path = "/srv/servnest/acme"

4
conf/cronie Normal file
View file

@ -0,0 +1,4 @@
48 0,6,12,18 * * * root echo "ns-sync: $(sudo -u servnest php83 /srv/servnest/core/jobs/ns-sync.php)" | ts >> /var/log/cronie/ns-sync.log 2>&1
14 4 * * * root echo "reg-cds: $(sudo -u servnest php83 /srv/servnest/core/jobs/reg-cds.php)" | ts >> /var/log/cronie/reg-cds.log 2>&1
34 4 * * * root echo "reg-csync: $(sudo -u servnest php83 /srv/servnest/core/jobs/reg-csync.php)" | ts >> /var/log/cronie/reg-csync.log 2>&1
24 11 * * * root echo "certbot renew: $(certbot renew)" | ts >> /var/log/cronie/certbot-renew.log 2>&1

View file

@ -2,12 +2,12 @@ server:
version: "Knot"
nsid: ""
rundir: "/run/knot"
user: "knot:knot"
listen: [ "::1@42053", "127.0.0.1@42053" ]
# user: "knot:knot"
listen: [ "::1@42053", "127.0.0.1@42053", "/run/knot/dns.sock" ]
log:
- target: "syslog"
any: "debug"
- target: stderr
any: warning
database:
storage: "/var/lib/knot"

View file

@ -1,4 +1,4 @@
proxy_pass http://[::1]:42999;
proxy_pass http://apache:42999;
proxy_ignore_client_abort on;
proxy_http_version 1.1;
proxy_set_header Host $host;

View file

@ -1,6 +1,6 @@
load_module "/usr/lib/nginx/modules/ngx_http_headers_more_filter_module.so";
worker_processes auto;
user nginx nginx;
#user nginx nginx;
pcre_jit on;
events {

12
conf/nginx/sites/dns.conf Normal file
View file

@ -0,0 +1,12 @@
# Dedicated DNS+TLS access
server {
listen [::]:42443 ssl default_server;
listen 0.0.0.0:42443 ssl default_server;
http2 on;
ssl_certificate /etc/letsencrypt/live/${ssl_server_name}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${ssl_server_name}/privkey.pem;
include inc/serve-static.conf;
}

View file

@ -2,8 +2,9 @@
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;
listen [::]:42443 ssl;
listen 0.0.0.0:42443 ssl;
http2 on;
server_name servnest.test;
root /srv/servnest/core;
@ -25,10 +26,6 @@ server {
alias /srv/servnest/core/css;
}
location /docs {
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

View file

@ -1,8 +1,8 @@
# This server block should listen on port 80 to warn users they tried to make an unsecure connection
server {
listen [::1]:42080 default_server;
listen 127.0.0.1:42080 default_server;
listen [::]:42080 default_server;
listen 0.0.0.0:42080 default_server;
location / {
return 403; # Don't allow unsecure HTTP requests

View file

@ -1,6 +1,6 @@
# Dedicated Onion service access
server {
listen [::1]:9080 default_server;
listen unix:/run/nginx-onion/socket default_server;
include inc/serve-static.conf;
}

View file

@ -1,7 +1,7 @@
# This server block and the PHP script it maps make ServNest authentication available to the SFTPGo external authenticator
server {
listen [::1]:8055; # It's meant to stay a private IP
listen 0.0.0.0:8055; # It's meant to stay private
root /srv/servnest/core;

View file

@ -1,8 +1,9 @@
# Subdomain access
server {
listen [::1]:42443 ssl http2;
listen 127.0.0.1:42443 ssl http2;
listen [::]:42443 ssl;
listen 0.0.0.0:42443 ssl;
http2 on;
server_name *.ht.servnest.test;
ssl_certificate /etc/ssl/certs/wildcard.ht.servnest.test.crt;

View file

@ -1,8 +1,9 @@
# Subpath access
server {
listen [::1]:42443 ssl http2;
listen 127.0.0.1:42443 ssl http2;
listen [::]:42443 ssl;
listen 0.0.0.0:42443 ssl;
http2 on;
server_name ht.servnest.test;
ssl_certificate /etc/ssl/certs/ht.servnest.test.crt;

View file

@ -2,13 +2,13 @@
[servnest]
user = servnest
group = knot
;user = servnest
;group = knot
listen = /run/php-fpm/servnest.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0600
;listen.owner = nginx
;listen.group = nginx
listen.mode = 0666
pm = dynamic
pm.max_children = 5

11
conf/php.ini Normal file
View file

@ -0,0 +1,11 @@
#error_log = syslog
#extension = pdo_sqlite
#extension = sqlite3
#extension = gettext
# Only required for the check.php script
#extension = curl
# Optional
expose_php = Off
#zend_extension = opcache

16
mkosi.extra/install/sftpgo.toml → conf/sftpgo.toml Normal file → Executable file
View file

@ -1,3 +1,7 @@
[common]
umask = "022"
server_version = "short"
[sftpd]
banner = "SFTPGo"
host_keys = [
@ -23,17 +27,17 @@ login_banner_file = "/etc/sftpgo/banner.txt"
enabled_ssh_commands = []
[[sftpd.bindings]]
address = "[::1]"
port = 2022
address = "[::]"
port = 42022
[[sftpd.bindings]]
address = "127.0.0.1"
port = 2022
#[[sftpd.bindings]]
#address = "0.0.0.0"
#port = 42022
[data_provider]
driver = "memory"
users_base_dir = "/srv/servnest/ht"
external_auth_hook = "http://[::1]:8055/sftpgo-auth.php"
external_auth_hook = "http://servnest.test:8055/sftpgo-auth.php"
external_auth_scope = 3
naming_rules = 1

7
conf/sudoers Normal file
View file

@ -0,0 +1,7 @@
servnest ALL=(root) NOPASSWD: /bin/chgrp ^--no-dereference -- sftpgo /srv/servnest/ht/fs/[0-9a-f]{64}$
servnest ALL=(root) NOPASSWD: /usr/bin/certbot ^--config /etc/letsencrypt/servnest\.ini certonly --domain ([a-z0-9_-]{1,63}\.){1,126}[a-z0-9]{1,63}( --test-cert)?$
servnest ALL=(root) NOPASSWD: /usr/bin/certbot ^--config /etc/letsencrypt/servnest\.ini delete --quiet --cert-name ([a-z0-9_-]{1,63}\.){1,126}[a-z0-9]{1,63}$
servnest ALL=(root) NOPASSWD: /bin/cat ^-- /srv/servnest/tor-keys/[0-9a-f]{64}/[a-zA-Z0-9_-]{1,64}/hostname$
servnest ALL=(root) NOPASSWD: /bin/mkdir ^--mode=0700 -- /srv/servnest/tor-keys/[0-9a-f]{64}$
servnest ALL=(root) NOPASSWD: /bin/rm ^-r -- /srv/servnest/tor-keys/[0-9a-f]{64}(/[a-zA-Z0-9_-]{1,64})?$
servnest ALL=(sftpgo) NOPASSWD: /bin/rm ^-r -- /srv/servnest/ht/fs/[0-9a-f]{64}$

6
conf/torrc Normal file
View file

@ -0,0 +1,6 @@
#User tor
DataDirectory /var/lib/tor
SocksPort unix:/run/tor-client/socket WorldWritable
ControlPort unix:/run/tor-control/socket GroupWritable
%include /srv/servnest/tor-config/*

1
core Submodule

@ -0,0 +1 @@
Subproject commit d9ff87a833eb70ae342aa9b0f15237f4c1d2fe8b

4
cronie.Containerfile Normal file
View file

@ -0,0 +1,4 @@
FROM servnest_php
USER root
RUN apk add cronie moreutils
CMD ["crond", "-n", "-s"]

View file

View file

4
knot.Containerfile Normal file
View file

@ -0,0 +1,4 @@
FROM servnest_alpine
RUN apk add knot
USER knot
CMD ["knotd", "--confdb", "/var/lib/knot/confdb/"]

0
logs/apache/.gitkeep Normal file
View file

0
logs/nginx/.gitkeep Normal file
View file

0
logs/php/.gitkeep Normal file
View file

0
logs/sftpgo/.gitkeep Normal file
View file

View file

@ -1,29 +0,0 @@
[Output]
Format = directory
CacheDirectory = ../mkosi.cache/
OutputDirectory = /var/lib/machines
[Content]
Autologin = yes
Hostname = servnest.test
WithDocs = yes
Packages =
iproute2
tor
torsocks
openssl
certbot
nginx
php-fpm
knot
sudo
git
sqlite3
knot-resolver
man-db
curl
lsof
tree
vim
htop
ncdu

View file

@ -1,6 +0,0 @@
#deb https://deb.debian.org/debian testing main
#deb https://deb.debian.org/debian-security/ testing-security main
deb https://deb.debian.org/debian bookworm main
deb https://deb.debian.org/debian-security/ bookworm-security main
deb https://deb.debian.org/debian bookworm-updates main

View file

@ -1,8 +0,0 @@
::1 servnest.test
::1 ns1.servnest.test
::1 ns2.servnest.test
::1 sftp.servnest.test
::1 ht.servnest.test
::1 test1.ht.servnest.test
::1 test2.ht.servnest.test
::1 test3.ht.servnest.test

View file

@ -1,19 +0,0 @@
net.listen('127.0.0.50', 53, { kind = 'dns', freebind = true })
-- Load useful modules
modules = {
'hints > iterate', -- Allow loading /etc/hosts or custom root hints
'stats', -- Track internal statistics
'predict', -- Prefetch expiring/frequent records
}
-- Forward requests to those resolvers over TLS
policy.TLS_FORWARD({
-- UncensoredDNS <https://blog.uncensoreddns.org/>
{'2a01:3a0:53:53::', hostname='unicast.uncensoreddns.org'},
{'89.233.43.71', hostname='unicast.uncensoreddns.org'},
{'2001:67c:28a4::', hostname='anycast.uncensoreddns.org'},
{'91.239.100.100', hostname='anycast.uncensoreddns.org'},
})
cache.size = 100 * MB

View file

@ -1,55 +0,0 @@
server:
version: "Knot"
nsid: ""
rundir: "/run/knot"
user: "knot:knot"
automatic-acl: "on"
listen: [ "2001:db8::1@42053", "203.0.113.1@42053" ]
log:
- target: "syslog"
any: "debug"
database:
storage: "/var/lib/knot"
key:
- id: "primary-to-secondary."
algorithm: "hmac-sha256"
secret: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGH" # keymgr -t primary-to-secondary hmac-sha256
remote:
- id: "secondary"
address: [ "2001:db8::2@53", "203.0.113.2@53" ]
key: "primary-to-secondary."
policy:
- id: "servnest"
algorithm: "ed25519"
nsec3: "on"
nsec3-iterations: 10
template:
- id: "servnest"
storage: "/srv/servnest/ns"
file: "%s.zone"
zonefile-load: "whole"
journal-content: "all"
dnssec-signing: "on"
dnssec-policy: "servnest"
catalog-role: "member"
catalog-zone: "servnest.test.invalid."
zone:
- domain: "servnest.test.invalid."
notify: "secondary"
zonefile-load: "whole"
journal-content: "all"
catalog-role: "generate"
- domain: "servnest.test."
template: "servnest"
storage: "/srv/servnest/reg"
- domain: "test.servnest.test."
template: "servnest"
storage: "/srv/servnest/reg"

View file

@ -1,36 +0,0 @@
server:
version: "Knot"
nsid: ""
rundir: "/run/knot"
user: "knot:knot"
automatic-acl: "on"
listen: [ "2001:db8::2@53", "203.0.113.2@53" ]
log:
- target: "syslog"
any: "debug"
database:
storage: "/var/lib/knot"
key:
- id: "primary-to-secondary."
algorithm: "hmac-sha256"
secret: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGH"
remote:
- id: "primary"
address: [ "2001:db8::1@53", "203.0.113.1@53" ]
key: "primary-to-secondary."
template:
- id: "servnest"
storage: "/var/lib/knot"
file: "%s.zone"
master: "primary"
zone:
- domain: "servnest.test.invalid."
master: "primary"
catalog-role: interpret
catalog-template: "servnest"

View file

@ -1,3 +0,0 @@
Server = https://mirrors.celianvdb.fr/archlinux/$repo/os/$arch
Server = https://mirror.sysa.tech/archlinux/$repo/os/$arch
Server = https://mirror.wormhole.eu/archlinux/$repo/os/$arch

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
nameserver 127.0.0.50

View file

@ -1,61 +0,0 @@
LogLevel INFO
AllowUsers root
Subsystem sftp internal-sftp
UsePAM yes
# Network
AddressFamily any
ListenAddress [::1]
ListenAddress 127.0.0.1
Port 42022
# Cryptography
HostKey /etc/ssh/ed25519
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
HostKeyAlgorithms ssh-ed25519
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com
# Sessions
PermitRootLogin prohibit-password
StrictModes yes
MaxAuthTries 6
MaxSessions 1
MaxStartups 3:20:200
LoginGraceTime 3m
PrintMotd yes
# Disable everything
PermitTTY no
PermitTunnel no
AllowTcpForwarding no
X11Forwarding no
AllowAgentForwarding no
AllowStreamLocalForwarding no
DisableForwarding yes # Disables all forwarding features, including X11, ssh-agent(1), TCP and StreamLocal.
PermitUserRC no
PermitUserEnvironment no
IgnoreRhosts yes
AuthorizedKeysFile none
AuthenticationMethods none
PubkeyAuthentication no
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
# Enable what is necessary
Match User root
PermitTTY yes
PubkeyAuthentication yes
AuthenticationMethods publickey
AuthorizedKeysFile .ssh/authorized_keys

View file

@ -1,6 +0,0 @@
[Resolve]
DNS=2a01:e0a:5d6:6de0:acab:3:3:3#dot.antopie.org 82.66.61.19#dot.antopie.org
DNSOverTLS=yes
DNSSEC=yes
Cache=yes
ResolveUnicastSingleLabel=yes

View file

@ -1,3 +0,0 @@
d /run/servnest 0555 root root - -
d /run/knot 0755 knot knot - -
d /run/php-fpm 0755 nginx nginx - -

View file

@ -1,43 +0,0 @@
#!/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 -m 0755 /srv/servnest/ht/usr
mkdir -m 0755 /srv/servnest/ht/usr/lib
ln /usr/lib/libc.so.6 /srv/servnest/ht/usr/lib/libc.so.6
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 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 -m 0755 /srv/servnest/ht/lib
mkdir -m 0755 /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

@ -1,13 +0,0 @@
mkdir /srv/servnest/acme
chown $nginx: /srv/servnest/acme
chmod u=rX,g=,o= /srv/servnest/acme
cp /install/certbot.ini /etc/letsencrypt/servnest.ini
cp /install/certbot-deploy-hook.sh /root/certbot-deploy-hook.sh
chmod +x /root/certbot-deploy-hook.sh
mkdir -p /etc/letsencrypt/archive/ /etc/letsencrypt/live/
chmod 710 /etc/letsencrypt/archive/ /etc/letsencrypt/live/
chown root:nginx /etc/letsencrypt/archive/ /etc/letsencrypt/live/
#/root/certbot-deploy-hook.sh

View file

@ -1,3 +0,0 @@
* */6 * * * root sudo -u servnest php /srv/servnest/core/jobs/ns-sync.php >> /var/log/servnest.log 2>&1
* */24 * * * root sudo -u servnest php /srv/servnest/core/jobs/reg-cds.php >> /var/log/servnest.log 2>&1
* */24 * * * root sudo -u servnest php /srv/servnest/core/jobs/reg-csync.php >> /var/log/servnest.log 2>&1

View file

@ -1,27 +0,0 @@
# Set users and groups names
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'
fi
# Create system users and groups
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/servnest.sh
source /install/sudo.sh
source /install/tor.sh
source /install/knot.sh
source /install/php.sh
source /install/nginx.sh
source /install/apache.sh
source /install/sftpgo.sh
source /install/certbot.sh

View file

@ -1,15 +0,0 @@
#!/usr/bin/bash
mkdir -p /var/lib/knot/confdb/
# Load configuration in Knot database
knotc conf-import /install/knot.conf
# We need servnest to be allowed to configure Knot
usermod -aG $knot $servnest # Add user $servnest to group $knot
chown -R $knot: /var/lib/knot/confdb
chmod -R u=rwX,g=rwX,o= /var/lib/knot/confdb
mkdir -p /srv/servnest/reg /srv/servnest/ns
chown -R $servnest:$knot /srv/servnest/reg /srv/servnest/ns
chmod -R u=rwX,g=rwX,o= /srv/servnest/reg /srv/servnest/ns

View file

@ -1,13 +0,0 @@
#!/usr/bin/bash
# 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 '/CN=servnest.test' -new -newkey RSA:3072 -days 3650 -nodes -x509 -keyout /etc/ssl/private/servnest.test.key -out /etc/ssl/certs/servnest.test.crt
openssl req -subj '/CN=ht.servnest.test' -new -newkey RSA:3072 -days 3650 -nodes -x509 -keyout /etc/ssl/private/ht.servnest.test.key -out /etc/ssl/certs/ht.servnest.test.crt
openssl req -subj '/CN=*.ht.servnest.test' -new -newkey RSA:3072 -days 3650 -nodes -x509 -keyout /etc/ssl/private/wildcard.ht.servnest.test.key -out /etc/ssl/certs/wildcard.ht.servnest.test.crt
rm -r /etc/nginx/*
cp -r /install/nginx/* /etc/nginx/

View file

@ -1,11 +0,0 @@
# Dedicated DNS+TLS 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/serve-static.conf;
}

View file

@ -1,11 +0,0 @@
error_log = syslog
extension = pdo_sqlite
extension = sqlite3
extension = gettext
# Only required for the check.php script
extension = curl
# Optional
expose_php = Off
zend_extension = opcache

View file

@ -1,29 +0,0 @@
#!/usr/bin/bash
rm -r /etc/php/*
cp /install/php-fpm.conf /etc/php/
export PHP_INI=/etc/php/php.ini
if [[ $OS = "debian" ]]; then
mkdir -p /etc/php/8.2/fpm/
ln -s /etc/php/8.2/fpm/ /etc/php/8.2/cli
mv /etc/php/php-fpm.conf /etc/php/8.2/fpm/
export PHP_INI=/etc/php/8.2/fpm/php.ini
fi
cp /etc/php.ini-development $PHP_INI
if [[ $OS = "debian" ]]; then
echo "extension = pdo" >> $PHP_INI
fi
if [[ $OS = "arch" ]]; then
echo "extension = sodium" >> $PHP_INI
fi
cat /install/php.ini >> $PHP_INI
# For systemd
mkdir /etc/systemd/system/php-fpm.service.d
cp /install/php-fpm.service.override.conf /etc/systemd/system/php-fpm.service.d/

View file

@ -1,26 +0,0 @@
#!/usr/bin/bash
# Initialize configuration
cp /srv/servnest/core/config.template.ini /srv/servnest/core/config.ini
# Create database
sqlite3 /srv/servnest/core/db/servnest.db < /srv/servnest/core/db/schema.sql
echo "UPDATE params SET value = '$(openssl rand -hex 16)' WHERE name = 'username_salt';" | sqlite3 /srv/servnest/core/db/servnest.db
for i in $(seq 50)
do
echo "INSERT INTO 'approval-keys'(key) VALUES('$(openssl rand -hex 16)');" | sqlite3 /srv/servnest/core/db/servnest.db
done
# Create translation Machine Objects files
msgfmt /srv/servnest/core/locales/fr/C/LC_MESSAGES/messages.po -o /srv/servnest/core/locales/fr/C/LC_MESSAGES/messages.mo
chmod u=rX,g=rX,o=rX /srv/servnest /srv/servnest/core
chown root:root /srv/servnest /srv/servnest/core
chmod -R u=rX,g=rX,o= $(find /srv/servnest/core -mindepth 1 -maxdepth 1 ! -name .git ! -name db)
chown -R $servnest:$nginx $(find /srv/servnest/core -mindepth 1 -maxdepth 1 ! -name .git ! -name db)
chown -R $servnest: /srv/servnest/core/db
chmod -R u=rwX,g=,o= /srv/servnest/core/db

View file

@ -1,27 +0,0 @@
#!/usr/bin/bash
mkdir /etc/sftpgo
# Generate SFTPGo key pair
ssh-keygen -f /etc/sftpgo/ed25519 -t ed25519 -N "" -C ""
# Generate fingerprints
fp=($(ssh-keygen -l -f /etc/sftpgo/ed25519))
echo ${fp[1]} > /etc/sftpgo/ed25519.fp
ssh-keygen -lv -f /etc/sftpgo/ed25519 | tail -n +2 > /etc/sftpgo/ed25519.asciiart
# Generate SSHFP record
echo ht.servnest.test. 86400 SSHFP 4 2 $(cut -d ' ' -f 2 /etc/sftpgo/ed25519.pub | base64 -d | sha256sum | cut -d ' ' -f 1) >> /srv/servnest/reg/servnest.test.zone
cp /install/sftpgo.toml /etc/sftpgo/
touch /etc/sftpgo/banner.txt
usermod -aG $sftpgo $servnest # Add user servnest to group sftpgo
chown -R $sftpgo: /etc/sftpgo
chmod -R u=rX,g=rX,o= /etc/sftpgo
chmod u=r,g=,o= /etc/sftpgo/ed25519
# For systemd
cp /install/sftpgo.service /etc/systemd/system/
# Allow listening on privileged ports
setcap 'cap_net_bind_service=+ep' /usr/local/bin/sftpgo

View file

@ -1,3 +0,0 @@
#!/usr/bin/bash
cp /install/sudoers /etc/sudoers.d/servnest

View file

@ -1,8 +0,0 @@
servnest ALL=(root) NOPASSWD: /usr/bin/systemctl reload tor
servnest ALL=(root) NOPASSWD: /usr/bin/chgrp ^--no-dereference -- sftpgo /srv/servnest/ht/fs/[0-9a-f]{64}$
servnest ALL=(root) NOPASSWD: /usr/bin/certbot ^--config /etc/letsencrypt/servnest\.ini certonly --domain ([a-z0-9_-]{1,63}\.){1,126}[a-z0-9]{1,63}( --test-cert)?$
servnest ALL=(root) NOPASSWD: /usr/bin/certbot ^--config /etc/letsencrypt/servnest\.ini 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 ^-r -- /srv/servnest/tor-keys/[0-9a-f]{64}(/[a-zA-Z0-9_-]{1,64})?$
servnest ALL=(sftpgo) NOPASSWD: /usr/bin/rm ^-r -- /srv/servnest/ht/fs/[0-9a-f]{64}$

View file

@ -1,23 +0,0 @@
rm -r /etc/tor/*
cp /install/torrc /etc/tor/
mkdir /srv/servnest/tor-config
chown -R $servnest:$tor /srv/servnest/tor-config
chmod -R u=rwX,g=rX,o= /srv/servnest/tor-config
mkdir /srv/servnest/tor-keys
chown -R $tor: /srv/servnest/tor-keys
chmod -R u=rwX,g=,o= /srv/servnest/tor-keys
# For systemd
mkdir /etc/systemd/system/tor.service.d
cp /install/tor.service.override.conf /etc/systemd/system/tor.service.d/
if [[ $OS = "debian" ]]; then
mv /etc/systemd/system/tor.service.d/ /etc/systemd/system/tor@default.service.d/
sed -i 's/User tor/User debian-tor/' /etc/tor/torrc
sed -i 's/reload tor/reload tor@default/' /etc/sudoers.d/servnest
sed -i 's/ALL=(tor)/ALL=(debian-tor)/' /etc/sudoers.d/servnest
sed -i 's/systemctl reload tor"/systemctl reload tor@default"/' /srv/servnest/core/config.ini
sed -i 's/tor_user = "tor"/tor_user = "debian-tor"/' /srv/servnest/core/config.ini
fi

View file

@ -1,5 +0,0 @@
User tor
SocksPort 0
DataDirectory /var/lib/tor
%include /srv/servnest/tor-config/*

View file

@ -1,25 +0,0 @@
#!/usr/bin/env bash
source /etc/os-release
set -euo pipefail
# Download latest release
if [[ ! -d "sftpgo-src" ]]; then
git clone https://github.com/drakkan/sftpgo sftpgo-src
fi
cd sftpgo-src
git checkout main
git pull origin HEAD
git checkout $(git tag | tail -n 1)
# Prepare