From 50a462a068d4113a677f0a9b683272b2ca9fa149 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 13 Feb 2020 22:27:59 +0100 Subject: [PATCH 01/37] Initial commit --- nextcloud/README.md | 29 +++++++++++++++++++++ nextcloud/fpm.conf | 16 ++++++++++++ nextcloud/nextcloud.conf.php | 11 ++++++++ nextcloud/nginx.conf | 36 ++++++++++++++++++++++++++ nextcloud/redis.conf | 2 ++ nginx/README.md | 10 +++++++ nginx/sites-available/0nohost | 6 +++++ nginx/sites-available/redirect-ssl-all | 8 ++++++ nginx/snippets/hsts | 1 + nginx/snippets/letsencrypt | 3 +++ nginx/snippets/redirect-ssl | 3 +++ ssh/README.md | 14 ++++++++++ ssh/sshd_config | 10 +++++++ 13 files changed, 149 insertions(+) create mode 100644 nextcloud/README.md create mode 100644 nextcloud/fpm.conf create mode 100644 nextcloud/nextcloud.conf.php create mode 100644 nextcloud/nginx.conf create mode 100644 nextcloud/redis.conf create mode 100644 nginx/README.md create mode 100644 nginx/sites-available/0nohost create mode 100644 nginx/sites-available/redirect-ssl-all create mode 100644 nginx/snippets/hsts create mode 100644 nginx/snippets/letsencrypt create mode 100644 nginx/snippets/redirect-ssl create mode 100644 ssh/README.md create mode 100644 ssh/sshd_config diff --git a/nextcloud/README.md b/nextcloud/README.md new file mode 100644 index 0000000..a1e4637 --- /dev/null +++ b/nextcloud/README.md @@ -0,0 +1,29 @@ +# Nextcloud + +## Create user + +```sh +echo 'cloud:*:3000:3000::/data/cloud:/bin/sh' | sudo tee -a /etc/passwd +echo 'cloud:x:3000:' | sudo tee -a /etc/group +sudo mkdir -p /data/cloud +sudo chown cloud.cloud /data/cloud +``` + +## Install software + +```sh +sudo apt install redis-server nginx php-redis php$VERSION-{cli,curl,fpm,gd,intl,mbstring,sqlite3,xml,zip} +wget https://download.nextcloud.com/server/releases/latest.zip +cd /data/cloud +sudo -u cloud unzip ~/latest.zip +``` + +## Copy configuration + +```sh +sudo cp nginx.conf /etc/nginx/sites-available/nextcloud +sudo cp fpm.conf /etc/php/*/fpm/pool.d/nextcloud.conf +cat redis.conf | sudo tee -a /etc/redis/redis.conf +sudo -u cloud cp nextcloud.conf.php /data/cloud/nextcloud/config/local.config.php +sudo sed -i s/example.com/$DOMAIN/g /etc/nginx/sites-available/nextcloud /data/cloud/nextcloud/config/local.config.php +``` diff --git a/nextcloud/fpm.conf b/nextcloud/fpm.conf new file mode 100644 index 0000000..0c01b9f --- /dev/null +++ b/nextcloud/fpm.conf @@ -0,0 +1,16 @@ +[cloud] + +user = cloud +group = cloud +listen = /run/nextcloud.sock + +listen.owner = www-data +listen.group = www-data + +env[PATH] = /usr/bin:/bin + +pm = ondemand +pm.max_children = 5 +pm.max_requests = 500 + +php_admin_value[memory_limit] = 512M diff --git a/nextcloud/nextcloud.conf.php b/nextcloud/nextcloud.conf.php new file mode 100644 index 0000000..554b3d4 --- /dev/null +++ b/nextcloud/nextcloud.conf.php @@ -0,0 +1,11 @@ + [ 'cloud.example.com', '192.168.0.100:8080', 'localhost:8080' ], + 'versions_retention_obligation' => 'auto, 2', + 'trashbin_retention_obligation' => 'auto, 2', + 'memcache.local' => '\OC\Memcache\Redis', + 'memcache.distributed' => '\OC\Memcache\Redis', + 'memcache.locking' => '\OC\Memcache\Redis', + 'redis' => [ 'host' => '/run/redis/redis-server.sock', 'port' => 0 ], + 'filesystem_check_changes' => 1, + 'sqlite.journal_mode' => 'WAL', +]; diff --git a/nextcloud/nginx.conf b/nextcloud/nginx.conf new file mode 100644 index 0000000..d80611a --- /dev/null +++ b/nextcloud/nginx.conf @@ -0,0 +1,36 @@ +server { + server_name cloud.example.com; + + listen 443 ssl; + + set $max_size 4G; + + root /data/cloud/nextcloud; + client_max_body_size $max_size; + + location / { + index index.php; + try_files $uri /index.php$request_uri; + } + + location ~ ^/console\.php { + deny all; + } + + location ~ ^(.+?\.php)(.*)$ { + fastcgi_split_path_info ^(.+?\.php)(.*)$; + fastcgi_pass unix:/run/nextcloud.sock; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param front_controller_active true; + fastcgi_param PHP_VALUE "upload_max_filesize=$max_size\n post_max_size=$max_size"; + include fastcgi.conf; + } + + location = /.well-known/carddav { + return 301 $scheme://$host:$server_port/remote.php/dav; + } + + location = /.well-known/caldav { + return 301 $scheme://$host:$server_port/remote.php/dav; + } +} diff --git a/nextcloud/redis.conf b/nextcloud/redis.conf new file mode 100644 index 0000000..ed8ff96 --- /dev/null +++ b/nextcloud/redis.conf @@ -0,0 +1,2 @@ +unixsocket /run/redis/redis-server.sock +unixsocketperm 777 diff --git a/nginx/README.md b/nginx/README.md new file mode 100644 index 0000000..7a23a1b --- /dev/null +++ b/nginx/README.md @@ -0,0 +1,10 @@ +# Nginx + +## Copy configuration + +```sh +sudo cp -r s* /etc/nginx +cd /etc/nginx/sites-enabled +sudo ln -s ../sites-available/0nohost +sudo ln -s ../sites-available/redirect-ssl-all +``` diff --git a/nginx/sites-available/0nohost b/nginx/sites-available/0nohost new file mode 100644 index 0000000..e6350ab --- /dev/null +++ b/nginx/sites-available/0nohost @@ -0,0 +1,6 @@ +server { + listen 80 default_server; + listen 443 ssl default_server; + server_name _; + return 444; +} diff --git a/nginx/sites-available/redirect-ssl-all b/nginx/sites-available/redirect-ssl-all new file mode 100644 index 0000000..823d16d --- /dev/null +++ b/nginx/sites-available/redirect-ssl-all @@ -0,0 +1,8 @@ +server { + server_name .example.com; + + listen 80; + + include snippets/redirect-ssl; + include snippets/letsencrypt; +} diff --git a/nginx/snippets/hsts b/nginx/snippets/hsts new file mode 100644 index 0000000..07baaf3 --- /dev/null +++ b/nginx/snippets/hsts @@ -0,0 +1 @@ +add_header Strict-Transport-Security max-age=31536000; # 1yr diff --git a/nginx/snippets/letsencrypt b/nginx/snippets/letsencrypt new file mode 100644 index 0000000..ac12fe2 --- /dev/null +++ b/nginx/snippets/letsencrypt @@ -0,0 +1,3 @@ +location /.well-known/acme-challenge { + alias /data/ssl/challenge; +} diff --git a/nginx/snippets/redirect-ssl b/nginx/snippets/redirect-ssl new file mode 100644 index 0000000..385fb49 --- /dev/null +++ b/nginx/snippets/redirect-ssl @@ -0,0 +1,3 @@ +location / { + return 301 https://$host$request_uri; +} diff --git a/ssh/README.md b/ssh/README.md new file mode 100644 index 0000000..13cbf3e --- /dev/null +++ b/ssh/README.md @@ -0,0 +1,14 @@ +# SSH + +Use only one user `sshlogin` for logins to the server. +Switch to your main user with `su - adminuser` afterwards. + +```sh +echo 'sshlogin:x:999:65534::/home/sshlogin:/bin/sh' | sudo tee -a /etc/passwd +sudo mkdir -p /home/sshlogin/.ssh +sudo chown sshlogin.sshlogin /home/sshlogin/.ssh +cat sshd_config | sudo tee -a /etc/ssh/sshd_config +``` + +* Either create a password with `sudo passwd sshlogin` or +* Add a key `sudo -u sshlogin nano /home/sshlogin/.ssh/authorized_keys` diff --git a/ssh/sshd_config b/ssh/sshd_config new file mode 100644 index 0000000..4db04db --- /dev/null +++ b/ssh/sshd_config @@ -0,0 +1,10 @@ +UseDNS no +Port 22222 +AllowUsers sshlogin git backup-* +ClientAliveInterval 10 + +Match User backup-* + ForceCommand internal-sftp + ChrootDirectory %h + X11Forwarding no + AllowTcpForwarding no From 25aeba25b3c32565342ef5cf3bc71a36f78e52c0 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 13 Feb 2020 23:01:34 +0100 Subject: [PATCH 02/37] Update --- nextcloud/README.md | 14 +++++++++++++- nextcloud/crontab | 1 + nextcloud/nginx.conf | 2 +- nginx/README.md | 1 + restic/README.md | 20 ++++++++++++++++++++ restic/crontab | 2 ++ ssh/README.md | 3 ++- 7 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 nextcloud/crontab create mode 100644 restic/README.md create mode 100644 restic/crontab diff --git a/nextcloud/README.md b/nextcloud/README.md index a1e4637..bdb6bc9 100644 --- a/nextcloud/README.md +++ b/nextcloud/README.md @@ -5,14 +5,23 @@ ```sh echo 'cloud:*:3000:3000::/data/cloud:/bin/sh' | sudo tee -a /etc/passwd echo 'cloud:x:3000:' | sudo tee -a /etc/group + sudo mkdir -p /data/cloud sudo chown cloud.cloud /data/cloud ``` +## Variables + +```sh +PHPVERSION=x.x +DOMAIN=example.com +``` + ## Install software ```sh -sudo apt install redis-server nginx php-redis php$VERSION-{cli,curl,fpm,gd,intl,mbstring,sqlite3,xml,zip} +sudo apt install redis-server nginx php-redis php$PHPVERSION-{cli,curl,fpm,gd,intl,mbstring,sqlite3,xml,zip} + wget https://download.nextcloud.com/server/releases/latest.zip cd /data/cloud sudo -u cloud unzip ~/latest.zip @@ -24,6 +33,9 @@ sudo -u cloud unzip ~/latest.zip sudo cp nginx.conf /etc/nginx/sites-available/nextcloud sudo cp fpm.conf /etc/php/*/fpm/pool.d/nextcloud.conf cat redis.conf | sudo tee -a /etc/redis/redis.conf + sudo -u cloud cp nextcloud.conf.php /data/cloud/nextcloud/config/local.config.php +sudo -u cloud crontab crontab + sudo sed -i s/example.com/$DOMAIN/g /etc/nginx/sites-available/nextcloud /data/cloud/nextcloud/config/local.config.php ``` diff --git a/nextcloud/crontab b/nextcloud/crontab new file mode 100644 index 0000000..a0fe9ba --- /dev/null +++ b/nextcloud/crontab @@ -0,0 +1 @@ +*/5 * * * * php nextcloud/cron.php diff --git a/nextcloud/nginx.conf b/nextcloud/nginx.conf index d80611a..15307c4 100644 --- a/nextcloud/nginx.conf +++ b/nextcloud/nginx.conf @@ -6,7 +6,7 @@ server { set $max_size 4G; root /data/cloud/nextcloud; - client_max_body_size $max_size; + client_max_body_size 0; location / { index index.php; diff --git a/nginx/README.md b/nginx/README.md index 7a23a1b..07cce4f 100644 --- a/nginx/README.md +++ b/nginx/README.md @@ -4,6 +4,7 @@ ```sh sudo cp -r s* /etc/nginx + cd /etc/nginx/sites-enabled sudo ln -s ../sites-available/0nohost sudo ln -s ../sites-available/redirect-ssl-all diff --git a/restic/README.md b/restic/README.md new file mode 100644 index 0000000..2590eed --- /dev/null +++ b/restic/README.md @@ -0,0 +1,20 @@ +# Restic backups + +Download binary: +https://github.com/restic/restic/releases/latest + +```sh +bunzip2 restic*.bz2 +sudo cp restic* /usr/local/bin/restic + +echo 'nice /usr/local/bin/restic -r REPO -p /usr/local/share/key "$@"' | sudo tee /usr/local/bin/restic-cmd +sudo chmod +x /usr/local/bin/restic-cmd +sudo nano /usr/local/bin/restic-cmd + +cat /dev/urandom | base64 | head -c 64 | sudo tee /usr/local/share/key +sudo chmod 0600 /usr/local/share/key + +sudo restic-cmd init +sudo crontab crontab +``` + diff --git a/restic/crontab b/restic/crontab new file mode 100644 index 0000000..cb74a6b --- /dev/null +++ b/restic/crontab @@ -0,0 +1,2 @@ +48 * * * * /usr/local/bin/restic-cmd backup -q --exclude-if-present .nobackup /data +18 3 * * * /usr/local/bin/restic-cmd forget -q --keep-tag keep -H 24 -d 7 -m 24 -y 100 diff --git a/ssh/README.md b/ssh/README.md index 13cbf3e..052e596 100644 --- a/ssh/README.md +++ b/ssh/README.md @@ -5,9 +5,10 @@ Switch to your main user with `su - adminuser` afterwards. ```sh echo 'sshlogin:x:999:65534::/home/sshlogin:/bin/sh' | sudo tee -a /etc/passwd +cat sshd_config | sudo tee -a /etc/ssh/sshd_config + sudo mkdir -p /home/sshlogin/.ssh sudo chown sshlogin.sshlogin /home/sshlogin/.ssh -cat sshd_config | sudo tee -a /etc/ssh/sshd_config ``` * Either create a password with `sudo passwd sshlogin` or From 7dc51579f0247aee32768433ee48b85eb4fb76fc Mon Sep 17 00:00:00 2001 From: Adrian Date: Sat, 15 Feb 2020 23:06:27 +0100 Subject: [PATCH 03/37] postfix --- nextcloud/README.md | 17 ++++++++++------- postfix/alias.cf | 2 ++ postfix/domains.cf | 2 ++ postfix/main.cf | 33 +++++++++++++++++++++++++++++++++ postfix/relay.cf | 2 ++ postfix/schema.sql | 3 +++ postfix/transport.cf | 2 ++ postfix/virtual.cf | 2 ++ restic/README.md | 9 +++++---- 9 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 postfix/alias.cf create mode 100644 postfix/domains.cf create mode 100644 postfix/main.cf create mode 100644 postfix/relay.cf create mode 100644 postfix/schema.sql create mode 100644 postfix/transport.cf create mode 100644 postfix/virtual.cf diff --git a/nextcloud/README.md b/nextcloud/README.md index bdb6bc9..6d2886e 100644 --- a/nextcloud/README.md +++ b/nextcloud/README.md @@ -10,16 +10,11 @@ sudo mkdir -p /data/cloud sudo chown cloud.cloud /data/cloud ``` -## Variables - -```sh -PHPVERSION=x.x -DOMAIN=example.com -``` - ## Install software ```sh +PHPVERSION=x.x + sudo apt install redis-server nginx php-redis php$PHPVERSION-{cli,curl,fpm,gd,intl,mbstring,sqlite3,xml,zip} wget https://download.nextcloud.com/server/releases/latest.zip @@ -30,6 +25,8 @@ sudo -u cloud unzip ~/latest.zip ## Copy configuration ```sh +DOMAIN=example.com + sudo cp nginx.conf /etc/nginx/sites-available/nextcloud sudo cp fpm.conf /etc/php/*/fpm/pool.d/nextcloud.conf cat redis.conf | sudo tee -a /etc/redis/redis.conf @@ -38,4 +35,10 @@ sudo -u cloud cp nextcloud.conf.php /data/cloud/nextcloud/config/local.config.ph sudo -u cloud crontab crontab sudo sed -i s/example.com/$DOMAIN/g /etc/nginx/sites-available/nextcloud /data/cloud/nextcloud/config/local.config.php + +cd /etc/nginx/sites-enabled +sudo ln -s ../sites-available/nextcloud + +sudo -u cloud mkdir -p /data/cloud/.config/user-tmpfiles.d +echo 'e %h/data/*/files/tmp - - - 7d' | sudo -u cloud tee /data/cloud/.config/user-tmpfiles.d/nextcloud-tmp.conf ``` diff --git a/postfix/alias.cf b/postfix/alias.cf new file mode 100644 index 0000000..f061aaa --- /dev/null +++ b/postfix/alias.cf @@ -0,0 +1,2 @@ +dbpath = /etc/postfix/postfix.db +query = SELECT goto FROM alias WHERE address = '%s' AND active = 1 diff --git a/postfix/domains.cf b/postfix/domains.cf new file mode 100644 index 0000000..d55aa30 --- /dev/null +++ b/postfix/domains.cf @@ -0,0 +1,2 @@ +dbpath = /etc/postfix/postfix.db +query = SELECT domain FROM domain WHERE domain = '%s' AND active = 1 AND NOT (transport LIKE 'smtp%%' OR transport LIKE 'relay%%') diff --git a/postfix/main.cf b/postfix/main.cf new file mode 100644 index 0000000..42cb269 --- /dev/null +++ b/postfix/main.cf @@ -0,0 +1,33 @@ +# System + +biff = no +compatibility_level = 2 +disable_vrfy_command = yes +mailbox_size_limit = 0 +message_size_limit = 0 +mydomain = local +mynetworks_style = subnet + +# TLS + +smtp_tls_security_level = may +smtpd_tls_security_level = may +smtpd_tls_key_file = /data/ssl/certs/mail.adrian.kousz.ch/privkey.pem +smtpd_tls_cert_file = /data/ssl/certs/mail.adrian.kousz.ch/fullchain.pem + +# Custom + +relay_domains = sqlite:/etc/postfix/relay.cf +transport_maps = sqlite:/etc/postfix/transport.cf + +recipient_delimiter = + +virtual_mailbox_base = /data/mail/box +virtual_uid_maps = static:2000 +virtual_gid_maps = static:2000 +virtual_mailbox_domains = sqlite:/etc/postfix/domains.cf +virtual_mailbox_maps = sqlite:/etc/postfix/virtual.cf +virtual_alias_maps = sqlite:/etc/postfix/alias.cf +virtual_mailbox_limit = 0 + +smtpd_milters = unix:/run/opendkim/opendkim.socket +non_smtpd_milters = $smtpd_milters diff --git a/postfix/relay.cf b/postfix/relay.cf new file mode 100644 index 0000000..674ff7b --- /dev/null +++ b/postfix/relay.cf @@ -0,0 +1,2 @@ +dbpath = /etc/postfix/postfix.db +query = SELECT domain FROM domain WHERE domain = '%s' AND active = 1 AND (transport LIKE 'smtp%%' OR transport LIKE 'relay%%') diff --git a/postfix/schema.sql b/postfix/schema.sql new file mode 100644 index 0000000..f123723 --- /dev/null +++ b/postfix/schema.sql @@ -0,0 +1,3 @@ +create table alias (address varchar(255) not null primary key, goto varchar(255) not null, active int not null default 1); +create table domain (domain varchar(255) not null primary key, transport varchar(255) not null default 'virtual', active int not null default 1); +create table mailbox (username varchar(255) not null primary key, password varchar(255) not null default '', name varchar(255) not null default '', maildir varchar(255) not null, active int not null default 1); diff --git a/postfix/transport.cf b/postfix/transport.cf new file mode 100644 index 0000000..c4acd99 --- /dev/null +++ b/postfix/transport.cf @@ -0,0 +1,2 @@ +dbpath = /etc/postfix/postfix.db +query = SELECT transport FROM domain WHERE domain = '%s' AND active = 1 diff --git a/postfix/virtual.cf b/postfix/virtual.cf new file mode 100644 index 0000000..3372c2d --- /dev/null +++ b/postfix/virtual.cf @@ -0,0 +1,2 @@ +dbpath = /etc/postfix/postfix.db +query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = 1 diff --git a/restic/README.md b/restic/README.md index 2590eed..93d82a2 100644 --- a/restic/README.md +++ b/restic/README.md @@ -4,17 +4,18 @@ Download binary: https://github.com/restic/restic/releases/latest ```sh +REPO=sftp:backup-user@example.com:repo + bunzip2 restic*.bz2 sudo cp restic* /usr/local/bin/restic -echo 'nice /usr/local/bin/restic -r REPO -p /usr/local/share/key "$@"' | sudo tee /usr/local/bin/restic-cmd +echo 'nice /usr/local/bin/restic -r' "$REPO" '-p /root/backup-key "$@"' | sudo tee /usr/local/bin/restic-cmd sudo chmod +x /usr/local/bin/restic-cmd sudo nano /usr/local/bin/restic-cmd -cat /dev/urandom | base64 | head -c 64 | sudo tee /usr/local/share/key -sudo chmod 0600 /usr/local/share/key +cat /dev/urandom | base64 | head -c 64 | sudo tee /root/backup-key +sudo chmod 0600 /root/backup-key sudo restic-cmd init sudo crontab crontab ``` - From 1b3bc0f9a84ac672fb3bee01dae343c3e5abf474 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 16 Feb 2020 01:04:08 +0100 Subject: [PATCH 04/37] Update --- mail/README.md | 16 ++++++++++++++++ {postfix => mail/postfix}/alias.cf | 2 +- {postfix => mail/postfix}/domains.cf | 2 +- {postfix => mail/postfix}/main.cf | 0 {postfix => mail/postfix}/relay.cf | 2 +- {postfix => mail/postfix}/transport.cf | 2 +- {postfix => mail/postfix}/virtual.cf | 2 +- {postfix => mail}/schema.sql | 0 nginx/README.md | 2 +- ssh/README.md | 2 +- 10 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 mail/README.md rename {postfix => mail/postfix}/alias.cf (67%) rename {postfix => mail/postfix}/domains.cf (79%) rename {postfix => mail/postfix}/main.cf (100%) rename {postfix => mail/postfix}/relay.cf (79%) rename {postfix => mail/postfix}/transport.cf (68%) rename {postfix => mail/postfix}/virtual.cf (68%) rename {postfix => mail}/schema.sql (100%) diff --git a/mail/README.md b/mail/README.md new file mode 100644 index 0000000..3e00371 --- /dev/null +++ b/mail/README.md @@ -0,0 +1,16 @@ +# Postfix with SQLite + +```sh +echo 'vmail:*:2000:2000::/data/mail:/usr/sbin/nologin' | sudo tee -a /etc/passwd +echo 'vmail:x:2000:' | sudo tee -a /etc/group + +sudo mkdir -p /data/mail +sudo chown vmail.vmail /data/mail + +sudo apt install postfix postfix-sqlite +sudo cp postfix/*.cf /etc/postfix + +cat schema.sql | sudo sqlite3 /data/mail/postfix.db +sudo chown vmail.postfix /data/mail/postfix.db +sudo chmod 640 /data/mail/postfix.db +``` diff --git a/postfix/alias.cf b/mail/postfix/alias.cf similarity index 67% rename from postfix/alias.cf rename to mail/postfix/alias.cf index f061aaa..35c26ef 100644 --- a/postfix/alias.cf +++ b/mail/postfix/alias.cf @@ -1,2 +1,2 @@ -dbpath = /etc/postfix/postfix.db +dbpath = /data/mail/postfix.db query = SELECT goto FROM alias WHERE address = '%s' AND active = 1 diff --git a/postfix/domains.cf b/mail/postfix/domains.cf similarity index 79% rename from postfix/domains.cf rename to mail/postfix/domains.cf index d55aa30..9d2e909 100644 --- a/postfix/domains.cf +++ b/mail/postfix/domains.cf @@ -1,2 +1,2 @@ -dbpath = /etc/postfix/postfix.db +dbpath = /data/mail/postfix.db query = SELECT domain FROM domain WHERE domain = '%s' AND active = 1 AND NOT (transport LIKE 'smtp%%' OR transport LIKE 'relay%%') diff --git a/postfix/main.cf b/mail/postfix/main.cf similarity index 100% rename from postfix/main.cf rename to mail/postfix/main.cf diff --git a/postfix/relay.cf b/mail/postfix/relay.cf similarity index 79% rename from postfix/relay.cf rename to mail/postfix/relay.cf index 674ff7b..9d381ab 100644 --- a/postfix/relay.cf +++ b/mail/postfix/relay.cf @@ -1,2 +1,2 @@ -dbpath = /etc/postfix/postfix.db +dbpath = /data/mail/postfix.db query = SELECT domain FROM domain WHERE domain = '%s' AND active = 1 AND (transport LIKE 'smtp%%' OR transport LIKE 'relay%%') diff --git a/postfix/transport.cf b/mail/postfix/transport.cf similarity index 68% rename from postfix/transport.cf rename to mail/postfix/transport.cf index c4acd99..e57dd01 100644 --- a/postfix/transport.cf +++ b/mail/postfix/transport.cf @@ -1,2 +1,2 @@ -dbpath = /etc/postfix/postfix.db +dbpath = /data/mail/postfix.db query = SELECT transport FROM domain WHERE domain = '%s' AND active = 1 diff --git a/postfix/virtual.cf b/mail/postfix/virtual.cf similarity index 68% rename from postfix/virtual.cf rename to mail/postfix/virtual.cf index 3372c2d..661e009 100644 --- a/postfix/virtual.cf +++ b/mail/postfix/virtual.cf @@ -1,2 +1,2 @@ -dbpath = /etc/postfix/postfix.db +dbpath = /data/mail/postfix.db query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = 1 diff --git a/postfix/schema.sql b/mail/schema.sql similarity index 100% rename from postfix/schema.sql rename to mail/schema.sql diff --git a/nginx/README.md b/nginx/README.md index 07cce4f..8d37854 100644 --- a/nginx/README.md +++ b/nginx/README.md @@ -3,7 +3,7 @@ ## Copy configuration ```sh -sudo cp -r s* /etc/nginx +sudo cp -r sites-available snippets /etc/nginx cd /etc/nginx/sites-enabled sudo ln -s ../sites-available/0nohost diff --git a/ssh/README.md b/ssh/README.md index 052e596..98a8fa6 100644 --- a/ssh/README.md +++ b/ssh/README.md @@ -4,7 +4,7 @@ Use only one user `sshlogin` for logins to the server. Switch to your main user with `su - adminuser` afterwards. ```sh -echo 'sshlogin:x:999:65534::/home/sshlogin:/bin/sh' | sudo tee -a /etc/passwd +echo 'sshlogin:x:1001:65534::/home/sshlogin:/bin/sh' | sudo tee -a /etc/passwd cat sshd_config | sudo tee -a /etc/ssh/sshd_config sudo mkdir -p /home/sshlogin/.ssh From fa12798ae96bad7f33bfcdce6a298623ae859f21 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 16 Feb 2020 16:54:16 +0100 Subject: [PATCH 05/37] Update mail --- mail/README.md | 62 ++++++++++++++++++++++++++++----- mail/dovecot/local-sql.conf.ext | 9 +++++ mail/dovecot/local.conf | 17 +++++++++ mail/opendkim/local.conf | 11 ++++++ mail/postfix/alias.cf | 2 +- mail/postfix/domains.cf | 2 +- mail/postfix/main.cf | 10 +++--- mail/postfix/relay.cf | 2 +- mail/postfix/transport.cf | 2 +- mail/postfix/virtual.cf | 2 +- mail/schema.sql | 3 ++ 11 files changed, 103 insertions(+), 19 deletions(-) create mode 100644 mail/dovecot/local-sql.conf.ext create mode 100644 mail/dovecot/local.conf create mode 100644 mail/opendkim/local.conf diff --git a/mail/README.md b/mail/README.md index 3e00371..5e757fe 100644 --- a/mail/README.md +++ b/mail/README.md @@ -1,16 +1,60 @@ -# Postfix with SQLite +# Mail with SQLite + +## Create User ```sh echo 'vmail:*:2000:2000::/data/mail:/usr/sbin/nologin' | sudo tee -a /etc/passwd echo 'vmail:x:2000:' | sudo tee -a /etc/group -sudo mkdir -p /data/mail -sudo chown vmail.vmail /data/mail +sudo mkdir -p /data/mail/mail +sudo mkdir -p /data/mail/config +sudo chown vmail: /data/mail/* -sudo apt install postfix postfix-sqlite -sudo cp postfix/*.cf /etc/postfix - -cat schema.sql | sudo sqlite3 /data/mail/postfix.db -sudo chown vmail.postfix /data/mail/postfix.db -sudo chmod 640 /data/mail/postfix.db +cat schema.sql | sudo -u vmail sqlite3 /data/mail/config/vmail.db +sudo chown vmail:postfix /data/mail/config/vmail.db +sudo chmod 640 /data/mail/config/vmail.db ``` + +## Install Software + +```sh +sudo apt install sqlite3 postfix postfix-sqlite dovecot-imapd dovecot-sqlite opendkim +``` + +### Create opendkim config directory in Debian + +```sh +echo 'Include /etc/opendkim/local.conf' | sudo tee -a /etc/opendkim.conf +sudo mkdir /etc/opendkim +sudo mv /etc/opendkim.conf /etc/opendkim +echo 'Include /etc/opendkim/opendkim.conf' | sudo tee /etc/opendkim.conf +``` + +### Prepare for opendkim socket operation + +```sh +sudo mkdir /var/spool/postfix/opendkim +sudo chown opendkim: /var/spool/postfix/opendkim +sudo chmod 750 /var/spool/postfix/opendkim +sudo adduser postfix opendkim +``` + +## Apply Configuration + +```sh +DOMAIN=example.com + +sudo ln -s /data/mail/config/vmail.db /.opendkim-bug-241.db +sudo opendkim-genkey -D /data/mail -d $DOMAIN -s s + +sudo cp -r postfix dovecot opendkim /etc +sudo sed -i s/example.com/$DOMAIN/g /etc/postfix/main.cf /etc/dovecot/local.conf +``` + +## Notes + +* The vmail database parent directory needs to be writeable by the user modifying the database +* The postfix process does not load the supplementary groups (`set_eugid` only sets one gid), + hence the vmail database needs to be readable by the postfix primary group +* The dovecot process runs as root and can access the database +* OpenDKIM's `dsn` parsing is broken and opens the database in the root directory diff --git a/mail/dovecot/local-sql.conf.ext b/mail/dovecot/local-sql.conf.ext new file mode 100644 index 0000000..ee22dec --- /dev/null +++ b/mail/dovecot/local-sql.conf.ext @@ -0,0 +1,9 @@ +driver = sqlite +connect = /data/mail/config/vmail.db + +user_query = SELECT \ + REPLACE('/data/mail/mail/{dir}', '{dir}', maildir) AS home \ + , REPLACE('maildir:/data/mail/mail/{dir}:LAYOUT=fs', '{dir}', maildir) AS mail \ + FROM mailbox WHERE username = '%u' AND active = 1 + +password_query = SELECT password FROM mailbox WHERE username = '%u' diff --git a/mail/dovecot/local.conf b/mail/dovecot/local.conf new file mode 100644 index 0000000..ce2c049 --- /dev/null +++ b/mail/dovecot/local.conf @@ -0,0 +1,17 @@ +protocols = imap +mail_uid = vmail +mail_gid = vmail + +ssl = required +ssl_key = Date: Sun, 16 Feb 2020 16:54:55 +0100 Subject: [PATCH 06/37] Update --- nextcloud/README.md | 8 ++++---- nginx/README.md | 4 +--- nginx/conf.d/ssl.conf | 2 ++ restic/crontab | 2 +- ssh/README.md | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 nginx/conf.d/ssl.conf diff --git a/nextcloud/README.md b/nextcloud/README.md index 6d2886e..bccb2f5 100644 --- a/nextcloud/README.md +++ b/nextcloud/README.md @@ -1,16 +1,16 @@ # Nextcloud -## Create user +## Create User ```sh echo 'cloud:*:3000:3000::/data/cloud:/bin/sh' | sudo tee -a /etc/passwd echo 'cloud:x:3000:' | sudo tee -a /etc/group sudo mkdir -p /data/cloud -sudo chown cloud.cloud /data/cloud +sudo chown cloud: /data/cloud ``` -## Install software +## Install Software ```sh PHPVERSION=x.x @@ -22,7 +22,7 @@ cd /data/cloud sudo -u cloud unzip ~/latest.zip ``` -## Copy configuration +## Apply Configuration ```sh DOMAIN=example.com diff --git a/nginx/README.md b/nginx/README.md index 8d37854..09c9170 100644 --- a/nginx/README.md +++ b/nginx/README.md @@ -1,9 +1,7 @@ # Nginx -## Copy configuration - ```sh -sudo cp -r sites-available snippets /etc/nginx +sudo cp -r sites-available snippets conf.d /etc/nginx cd /etc/nginx/sites-enabled sudo ln -s ../sites-available/0nohost diff --git a/nginx/conf.d/ssl.conf b/nginx/conf.d/ssl.conf new file mode 100644 index 0000000..9171037 --- /dev/null +++ b/nginx/conf.d/ssl.conf @@ -0,0 +1,2 @@ +ssl_certificate /path/to/fullchain.pem; +ssl_certificate_key /path/to/privkey.pem; diff --git a/restic/crontab b/restic/crontab index cb74a6b..69bc4f2 100644 --- a/restic/crontab +++ b/restic/crontab @@ -1,2 +1,2 @@ 48 * * * * /usr/local/bin/restic-cmd backup -q --exclude-if-present .nobackup /data -18 3 * * * /usr/local/bin/restic-cmd forget -q --keep-tag keep -H 24 -d 7 -m 24 -y 100 +18 3 * * * /usr/local/bin/restic-cmd forget -q --keep-tag keep -H 24 -d 7 -m 12 -y 100 diff --git a/ssh/README.md b/ssh/README.md index 98a8fa6..3fdd920 100644 --- a/ssh/README.md +++ b/ssh/README.md @@ -8,7 +8,7 @@ echo 'sshlogin:x:1001:65534::/home/sshlogin:/bin/sh' | sudo tee -a /etc/passwd cat sshd_config | sudo tee -a /etc/ssh/sshd_config sudo mkdir -p /home/sshlogin/.ssh -sudo chown sshlogin.sshlogin /home/sshlogin/.ssh +sudo chown sshlogin:root /home/sshlogin/.ssh ``` * Either create a password with `sudo passwd sshlogin` or From 8d55ae3513d6f8168c7ceb1b81bff387143462cf Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 16 Feb 2020 18:48:12 +0100 Subject: [PATCH 07/37] Inbucket --- inbucket/README.md | 35 +++++++++++++++++++++++++++++++++++ inbucket/inbucket.conf | 9 +++++++++ inbucket/inbucket.service | 11 +++++++++++ inbucket/nginx.conf | 20 ++++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 inbucket/README.md create mode 100644 inbucket/inbucket.conf create mode 100644 inbucket/inbucket.service create mode 100644 inbucket/nginx.conf diff --git a/inbucket/README.md b/inbucket/README.md new file mode 100644 index 0000000..2807b25 --- /dev/null +++ b/inbucket/README.md @@ -0,0 +1,35 @@ +# Inbucket + +To be used together with the [`mail`](../mail) setup. + +## Install Software + +Get: https://www.inbucket.org/binaries/ + +```sh +cd /usr/local/share +sudo tar -xf ~/inbucket_* +sudo ln -s inbucket_* inbucket +sudo ln -s ../share/inbucket/inbucket /usr/local/bin +sudo ln -s ../share/inbucket/inbucket-client /usr/local/bin +``` + +## Apply Configuration + +```sh +DOMAIN=test.local + +sudo cp inbucket.service /etc/systemd/system +sudo -u vmail cp inbucket.conf /data/mail/config +sudo cp nginx.conf /etc/nginx/sites-available/inbucket + +sudo ln -s ../sites-available/inbucket /etc/nginx/sites-enabled + +echo "inbucket:$(openssl passwd -5)" | sudo -u vmail tee /data/mail/config/inbucket.htpasswd +sudo chown vmail:www-data /data/mail/config/inbucket.htpasswd +sudo chmod 640 /data/mail/config/inbucket.htpasswd + +echo "insert into domain (domain, transport) values ('$DOMAIN','smtp:[localhost]:2500')" | sudo -u vmail sqlite3 /data/mail/config/vmail.db + +sudo systemctl enable inbucket +``` diff --git a/inbucket/inbucket.conf b/inbucket/inbucket.conf new file mode 100644 index 0000000..8a1817a --- /dev/null +++ b/inbucket/inbucket.conf @@ -0,0 +1,9 @@ +INBUCKET_LOGLEVEL=warn +INBUCKET_MAILBOXNAMING=full +INBUCKET_WEB_ADDR=0.0.0.0:8025 +INBUCKET_WEB_UIDIR=/usr/local/share/inbucket/ui +INBUCKET_WEB_GREETINGFILE=/usr/local/share/inbucket/ui/greeting.html +INBUCKET_STORAGE_TYPE=file +INBUCKET_STORAGE_PARAMS=path:/data/mail +INBUCKET_STORAGE_RETENTIONPERIOD=0 +INBUCKET_STORAGE_MAILBOXMSGCAP=0 diff --git a/inbucket/inbucket.service b/inbucket/inbucket.service new file mode 100644 index 0000000..5f1d255 --- /dev/null +++ b/inbucket/inbucket.service @@ -0,0 +1,11 @@ +[Unit] +Description=Inbucket +After=network.target + +[Service] +ExecStart=/usr/local/bin/inbucket +EnvironmentFile=/data/mail/config/inbucket.conf +User=vmail + +[Install] +WantedBy=multi-user.target diff --git a/inbucket/nginx.conf b/inbucket/nginx.conf new file mode 100644 index 0000000..ff52ffd --- /dev/null +++ b/inbucket/nginx.conf @@ -0,0 +1,20 @@ +server { + server_name mail.example.com; + + listen 443 ssl; + + auth_basic "Mail"; + auth_basic_user_file /data/mail/config/inbucket.htpasswd; + + location / { + proxy_pass http://localhost:8025; + include proxy_params; + } + + location /api { + proxy_pass http://localhost:8025; + include proxy_params; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } +} From 59219ec6444c3faead731999bc57390dcbdba6b1 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 16 Feb 2020 18:48:16 +0100 Subject: [PATCH 08/37] Update --- nextcloud/README.md | 8 +++----- nextcloud/{nextcloud.conf.php => local.config.php} | 0 2 files changed, 3 insertions(+), 5 deletions(-) rename nextcloud/{nextcloud.conf.php => local.config.php} (100%) diff --git a/nextcloud/README.md b/nextcloud/README.md index bccb2f5..596ba62 100644 --- a/nextcloud/README.md +++ b/nextcloud/README.md @@ -18,8 +18,7 @@ PHPVERSION=x.x sudo apt install redis-server nginx php-redis php$PHPVERSION-{cli,curl,fpm,gd,intl,mbstring,sqlite3,xml,zip} wget https://download.nextcloud.com/server/releases/latest.zip -cd /data/cloud -sudo -u cloud unzip ~/latest.zip +sudo -u cloud unzip -d /data/cloud ~/latest.zip ``` ## Apply Configuration @@ -31,13 +30,12 @@ sudo cp nginx.conf /etc/nginx/sites-available/nextcloud sudo cp fpm.conf /etc/php/*/fpm/pool.d/nextcloud.conf cat redis.conf | sudo tee -a /etc/redis/redis.conf -sudo -u cloud cp nextcloud.conf.php /data/cloud/nextcloud/config/local.config.php +sudo -u cloud cp local.config.php /data/cloud/nextcloud/config sudo -u cloud crontab crontab sudo sed -i s/example.com/$DOMAIN/g /etc/nginx/sites-available/nextcloud /data/cloud/nextcloud/config/local.config.php -cd /etc/nginx/sites-enabled -sudo ln -s ../sites-available/nextcloud +sudo ln -s ../sites-available/nextcloud /etc/nginx/sites-enabled sudo -u cloud mkdir -p /data/cloud/.config/user-tmpfiles.d echo 'e %h/data/*/files/tmp - - - 7d' | sudo -u cloud tee /data/cloud/.config/user-tmpfiles.d/nextcloud-tmp.conf diff --git a/nextcloud/nextcloud.conf.php b/nextcloud/local.config.php similarity index 100% rename from nextcloud/nextcloud.conf.php rename to nextcloud/local.config.php From 91fba3cbd76e7d718fe7c9d08592ad12f5a7b596 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 16 Feb 2020 21:55:11 +0100 Subject: [PATCH 09/37] Update --- mail/README.md | 27 +++++---------------------- mail/dovecot/local.conf | 6 ++++++ mail/opendkim/local.conf | 3 ++- mail/postfix/login.cf | 2 ++ mail/postfix/main.cf | 8 +++++++- named/README.md | 19 +++++++++++++++++++ named/badlist-active.zone | 8 ++++++++ named/badlist-inactive.zone | 3 +++ named/options.conf | 3 +++ named/zones.conf | 1 + nextcloud/README.md | 6 +++--- restic/README.md | 1 - ssh/README.md | 4 ++-- 13 files changed, 61 insertions(+), 30 deletions(-) create mode 100644 mail/postfix/login.cf create mode 100644 named/README.md create mode 100644 named/badlist-active.zone create mode 100644 named/badlist-inactive.zone create mode 100644 named/options.conf create mode 100644 named/zones.conf diff --git a/mail/README.md b/mail/README.md index 5e757fe..a7b1410 100644 --- a/mail/README.md +++ b/mail/README.md @@ -3,8 +3,8 @@ ## Create User ```sh -echo 'vmail:*:2000:2000::/data/mail:/usr/sbin/nologin' | sudo tee -a /etc/passwd -echo 'vmail:x:2000:' | sudo tee -a /etc/group +sudo sed -i '$ a vmail:*:2000:2000::/data/mail:/usr/sbin/nologin' /etc/passwd +sudo sed -i '$ a vmail:x:2000:' /etc/passwd sudo mkdir -p /data/mail/mail sudo mkdir -p /data/mail/config @@ -21,24 +21,6 @@ sudo chmod 640 /data/mail/config/vmail.db sudo apt install sqlite3 postfix postfix-sqlite dovecot-imapd dovecot-sqlite opendkim ``` -### Create opendkim config directory in Debian - -```sh -echo 'Include /etc/opendkim/local.conf' | sudo tee -a /etc/opendkim.conf -sudo mkdir /etc/opendkim -sudo mv /etc/opendkim.conf /etc/opendkim -echo 'Include /etc/opendkim/opendkim.conf' | sudo tee /etc/opendkim.conf -``` - -### Prepare for opendkim socket operation - -```sh -sudo mkdir /var/spool/postfix/opendkim -sudo chown opendkim: /var/spool/postfix/opendkim -sudo chmod 750 /var/spool/postfix/opendkim -sudo adduser postfix opendkim -``` - ## Apply Configuration ```sh @@ -47,13 +29,14 @@ DOMAIN=example.com sudo ln -s /data/mail/config/vmail.db /.opendkim-bug-241.db sudo opendkim-genkey -D /data/mail -d $DOMAIN -s s -sudo cp -r postfix dovecot opendkim /etc +sudo cp -r postfix dovecot /etc +sudo sed -i '$ r opendkim/local.conf' /etc/opendkim.conf sudo sed -i s/example.com/$DOMAIN/g /etc/postfix/main.cf /etc/dovecot/local.conf ``` ## Notes -* The vmail database parent directory needs to be writeable by the user modifying the database +* The `vmail.db` parent directory needs to be writeable by the user modifying the database * The postfix process does not load the supplementary groups (`set_eugid` only sets one gid), hence the vmail database needs to be readable by the postfix primary group * The dovecot process runs as root and can access the database diff --git a/mail/dovecot/local.conf b/mail/dovecot/local.conf index ce2c049..fd9ce3e 100644 --- a/mail/dovecot/local.conf +++ b/mail/dovecot/local.conf @@ -15,3 +15,9 @@ passdb { driver = sql args = /etc/dovecot/local-sql.conf.ext } + +service auth { + unix_listener /var/spool/postfix/private/auth { + user = postfix + } +} diff --git a/mail/opendkim/local.conf b/mail/opendkim/local.conf index 6b72716..ebfd7ed 100644 --- a/mail/opendkim/local.conf +++ b/mail/opendkim/local.conf @@ -1,4 +1,5 @@ -Socket local:/var/spool/postfix/opendkim/opendkim.sock +Socket local:/var/spool/postfix/private/opendkim +UserID postfix InternalHosts 0.0.0.0/0 Canonicalization relaxed/relaxed diff --git a/mail/postfix/login.cf b/mail/postfix/login.cf new file mode 100644 index 0000000..30acf06 --- /dev/null +++ b/mail/postfix/login.cf @@ -0,0 +1,2 @@ +dbpath = /data/mail/config/vmail.db +query = SELECT username FROM mailbox WHERE username = '%s' AND active = 1 diff --git a/mail/postfix/main.cf b/mail/postfix/main.cf index 849d610..8b60399 100644 --- a/mail/postfix/main.cf +++ b/mail/postfix/main.cf @@ -29,5 +29,11 @@ virtual_mailbox_maps = sqlite:/etc/postfix/virtual.cf virtual_alias_maps = sqlite:/etc/postfix/alias.cf virtual_mailbox_limit = 0 -smtpd_milters = unix:/opendkim/opendkim.socket +smtpd_sasl_auth_enable = yes +smtpd_sasl_type = dovecot +smtpd_sasl_path = private/auth +smtpd_sender_restrictions = reject_sender_login_mismatch +smtpd_sender_login_maps = sqlite:/etc/postfix/login.cf, $virtual_alias_maps + +smtpd_milters = unix:private/opendkim non_smtpd_milters = $smtpd_milters diff --git a/named/README.md b/named/README.md new file mode 100644 index 0000000..520daa7 --- /dev/null +++ b/named/README.md @@ -0,0 +1,19 @@ +# Named + +## Install Software + +```sh +sudo apt install bind9 +``` + +## Apply Configuration + +```sh +sudo mkdir /data/named +sudo cp *.conf *.zone /data/named + +sudo sed -i '/directory/ a \\tinclude "/data/named/options.conf";' /etc/bind/named.conf.options +sudo sed -i '$ a include "/data/named/zones.conf";' /etc/bind/named.conf + +echo '/data/named/** r,' | sudo tee -a /etc/apparmor.d/local/usr.sbin.named +``` diff --git a/named/badlist-active.zone b/named/badlist-active.zone new file mode 100644 index 0000000..ccd42f4 --- /dev/null +++ b/named/badlist-active.zone @@ -0,0 +1,8 @@ +$TTL 1H +@ SOA localhost. named-mgr.example.com (1 1W 1W 1W 1H) +@ NS localhost. + +facebook.com CNAME . +*.facebook.com CNAME . +instagram.com CNAME . +*.instagram.com CNAME . diff --git a/named/badlist-inactive.zone b/named/badlist-inactive.zone new file mode 100644 index 0000000..e6bd4d3 --- /dev/null +++ b/named/badlist-inactive.zone @@ -0,0 +1,3 @@ +$TTL 1H +@ SOA localhost. named-mgr.example.com (1 1W 1W 1W 1H) +@ NS localhost. diff --git a/named/options.conf b/named/options.conf new file mode 100644 index 0000000..33723f3 --- /dev/null +++ b/named/options.conf @@ -0,0 +1,3 @@ +forward only; +forwarders { 1.1.1.1; }; +response-policy { zone "badlist"; }; diff --git a/named/zones.conf b/named/zones.conf new file mode 100644 index 0000000..b2cedf0 --- /dev/null +++ b/named/zones.conf @@ -0,0 +1 @@ +zone "badlist" { type master; file "/data/named/badlist-active.zone"; }; diff --git a/nextcloud/README.md b/nextcloud/README.md index 596ba62..23e88ce 100644 --- a/nextcloud/README.md +++ b/nextcloud/README.md @@ -3,8 +3,8 @@ ## Create User ```sh -echo 'cloud:*:3000:3000::/data/cloud:/bin/sh' | sudo tee -a /etc/passwd -echo 'cloud:x:3000:' | sudo tee -a /etc/group +sudo sed -i '$ a cloud:*:3000:3000::/data/cloud:/bin/sh' /etc/passwd +sudo sed -i '$ a cloud:x:3000:' /etc/group sudo mkdir -p /data/cloud sudo chown cloud: /data/cloud @@ -28,7 +28,7 @@ DOMAIN=example.com sudo cp nginx.conf /etc/nginx/sites-available/nextcloud sudo cp fpm.conf /etc/php/*/fpm/pool.d/nextcloud.conf -cat redis.conf | sudo tee -a /etc/redis/redis.conf +sudo sed -i '$ r redis.conf' /etc/redis/redis.conf sudo -u cloud cp local.config.php /data/cloud/nextcloud/config sudo -u cloud crontab crontab diff --git a/restic/README.md b/restic/README.md index 93d82a2..3c23001 100644 --- a/restic/README.md +++ b/restic/README.md @@ -11,7 +11,6 @@ sudo cp restic* /usr/local/bin/restic echo 'nice /usr/local/bin/restic -r' "$REPO" '-p /root/backup-key "$@"' | sudo tee /usr/local/bin/restic-cmd sudo chmod +x /usr/local/bin/restic-cmd -sudo nano /usr/local/bin/restic-cmd cat /dev/urandom | base64 | head -c 64 | sudo tee /root/backup-key sudo chmod 0600 /root/backup-key diff --git a/ssh/README.md b/ssh/README.md index 3fdd920..fdda9eb 100644 --- a/ssh/README.md +++ b/ssh/README.md @@ -4,8 +4,8 @@ Use only one user `sshlogin` for logins to the server. Switch to your main user with `su - adminuser` afterwards. ```sh -echo 'sshlogin:x:1001:65534::/home/sshlogin:/bin/sh' | sudo tee -a /etc/passwd -cat sshd_config | sudo tee -a /etc/ssh/sshd_config +sudo sed -i '$ a sshlogin:x:1001:65534::/home/sshlogin:/bin/sh' /etc/passwd +sudo sed -i '$ r sshd_config' /etc/ssh/sshd_config sudo mkdir -p /home/sshlogin/.ssh sudo chown sshlogin:root /home/sshlogin/.ssh From 6a692253d405b2c2a2508035a7cd943576f08922 Mon Sep 17 00:00:00 2001 From: Adrian Date: Mon, 17 Feb 2020 00:15:26 +0100 Subject: [PATCH 10/37] Update --- nextcloud/crontab | 1 + 1 file changed, 1 insertion(+) diff --git a/nextcloud/crontab b/nextcloud/crontab index a0fe9ba..5775c87 100644 --- a/nextcloud/crontab +++ b/nextcloud/crontab @@ -1 +1,2 @@ */5 * * * * php nextcloud/cron.php +15 3 * * * systemd-tmpfiles --clean --user From d78ca1203fb0c624129bdf2ef728086b6a322971 Mon Sep 17 00:00:00 2001 From: Adrian Date: Mon, 17 Feb 2020 00:24:33 +0100 Subject: [PATCH 11/37] Update --- nginx/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nginx/README.md b/nginx/README.md index 09c9170..fee1b7c 100644 --- a/nginx/README.md +++ b/nginx/README.md @@ -3,7 +3,7 @@ ```sh sudo cp -r sites-available snippets conf.d /etc/nginx -cd /etc/nginx/sites-enabled -sudo ln -s ../sites-available/0nohost -sudo ln -s ../sites-available/redirect-ssl-all +sudo rm /etc/nginx/sites-*/default +sudo ln -s ../sites-available/0nohost /etc/nginx/sites-enabled +sudo ln -s ../sites-available/redirect-ssl-all /etc/nginx/sites-enabled ``` From c1d7b063e2ab44ca0bbbdf1077d41c19f7aea450 Mon Sep 17 00:00:00 2001 From: Adrian Date: Mon, 17 Feb 2020 01:00:12 +0100 Subject: [PATCH 12/37] Update --- mail/README.md | 11 ++++++++--- mail/dkim.sql | 2 ++ mail/opendkim/local.conf | 4 ---- 3 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 mail/dkim.sql diff --git a/mail/README.md b/mail/README.md index a7b1410..15293c3 100644 --- a/mail/README.md +++ b/mail/README.md @@ -26,12 +26,17 @@ sudo apt install sqlite3 postfix postfix-sqlite dovecot-imapd dovecot-sqlite ope ```sh DOMAIN=example.com -sudo ln -s /data/mail/config/vmail.db /.opendkim-bug-241.db -sudo opendkim-genkey -D /data/mail -d $DOMAIN -s s - sudo cp -r postfix dovecot /etc sudo sed -i '$ r opendkim/local.conf' /etc/opendkim.conf sudo sed -i s/example.com/$DOMAIN/g /etc/postfix/main.cf /etc/dovecot/local.conf + +sudo ln -s /data/mail/config/vmail.db /.opendkim-bug-241.db + +opendkim-genkey -d $DOMAIN -s s +chmod +r s.private +cat dkim.sql | sed s/DOMAIN/$DOMAIN/ | sudo -u vmail sqlite3 /data/mail/config/vmail.db +cat s.txt +rm s.private s.txt ``` ## Notes diff --git a/mail/dkim.sql b/mail/dkim.sql new file mode 100644 index 0000000..c0e58e8 --- /dev/null +++ b/mail/dkim.sql @@ -0,0 +1,2 @@ +insert into dkim (match, key) values ("DOMAIN", "default"); +insert into dkim_key (key, domain, selector, private_key) values ("default", "DOMAIN", "s", readfile("s.private")); diff --git a/mail/opendkim/local.conf b/mail/opendkim/local.conf index ebfd7ed..58f5544 100644 --- a/mail/opendkim/local.conf +++ b/mail/opendkim/local.conf @@ -6,7 +6,3 @@ Canonicalization relaxed/relaxed KeyTable dsn:sqlite://./opendkim-bug-241.db/table=dkim_key?keycol=key?datacol=domain,selector,private_key SigningTable dsn:sqlite://./opendkim-bug-241.db/table=dkim?keycol=match?datacol=key - -# Domain example.com -# Selector s -# KeyFile /data/mail/s.private From 50c6e9f10501e3be342aa3cf30e17d7f70f49c1d Mon Sep 17 00:00:00 2001 From: Adrian Date: Mon, 17 Feb 2020 01:46:24 +0100 Subject: [PATCH 13/37] Update --- inbucket/README.md | 2 +- mail/README.md | 6 +++--- mail/opendkim/local.conf | 4 ++-- mail/postfix/main.cf | 2 +- nginx/conf.d/ssl.conf | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/inbucket/README.md b/inbucket/README.md index 2807b25..ddc21f9 100644 --- a/inbucket/README.md +++ b/inbucket/README.md @@ -20,8 +20,8 @@ sudo ln -s ../share/inbucket/inbucket-client /usr/local/bin DOMAIN=test.local sudo cp inbucket.service /etc/systemd/system -sudo -u vmail cp inbucket.conf /data/mail/config sudo cp nginx.conf /etc/nginx/sites-available/inbucket +sudo -u vmail cp inbucket.conf /data/mail/config sudo ln -s ../sites-available/inbucket /etc/nginx/sites-enabled diff --git a/mail/README.md b/mail/README.md index 15293c3..2c8b391 100644 --- a/mail/README.md +++ b/mail/README.md @@ -4,21 +4,20 @@ ```sh sudo sed -i '$ a vmail:*:2000:2000::/data/mail:/usr/sbin/nologin' /etc/passwd -sudo sed -i '$ a vmail:x:2000:' /etc/passwd +sudo sed -i '$ a vmail:x:2000:' /etc/group sudo mkdir -p /data/mail/mail sudo mkdir -p /data/mail/config sudo chown vmail: /data/mail/* cat schema.sql | sudo -u vmail sqlite3 /data/mail/config/vmail.db -sudo chown vmail:postfix /data/mail/config/vmail.db sudo chmod 640 /data/mail/config/vmail.db ``` ## Install Software ```sh -sudo apt install sqlite3 postfix postfix-sqlite dovecot-imapd dovecot-sqlite opendkim +sudo apt install sqlite3 postfix postfix-sqlite dovecot-imapd dovecot-sqlite opendkim libopendbx1-sqlite3 ``` ## Apply Configuration @@ -31,6 +30,7 @@ sudo sed -i '$ r opendkim/local.conf' /etc/opendkim.conf sudo sed -i s/example.com/$DOMAIN/g /etc/postfix/main.cf /etc/dovecot/local.conf sudo ln -s /data/mail/config/vmail.db /.opendkim-bug-241.db +sudo chown vmail:postfix /data/mail/config/vmail.db opendkim-genkey -d $DOMAIN -s s chmod +r s.private diff --git a/mail/opendkim/local.conf b/mail/opendkim/local.conf index 58f5544..72a9dc7 100644 --- a/mail/opendkim/local.conf +++ b/mail/opendkim/local.conf @@ -4,5 +4,5 @@ InternalHosts 0.0.0.0/0 Canonicalization relaxed/relaxed -KeyTable dsn:sqlite://./opendkim-bug-241.db/table=dkim_key?keycol=key?datacol=domain,selector,private_key -SigningTable dsn:sqlite://./opendkim-bug-241.db/table=dkim?keycol=match?datacol=key +KeyTable dsn:sqlite3://./opendkim-bug-241.db/table=dkim_key?keycol=key?datacol=domain,selector,private_key +SigningTable dsn:sqlite3://./opendkim-bug-241.db/table=dkim?keycol=match?datacol=key diff --git a/mail/postfix/main.cf b/mail/postfix/main.cf index 8b60399..4b2e97f 100644 --- a/mail/postfix/main.cf +++ b/mail/postfix/main.cf @@ -5,7 +5,7 @@ compatibility_level = 2 disable_vrfy_command = yes mailbox_size_limit = 0 message_size_limit = 0 -mydomain = example.com +mydomain = local mynetworks_style = subnet # TLS diff --git a/nginx/conf.d/ssl.conf b/nginx/conf.d/ssl.conf index 9171037..c68755d 100644 --- a/nginx/conf.d/ssl.conf +++ b/nginx/conf.d/ssl.conf @@ -1,2 +1,2 @@ -ssl_certificate /path/to/fullchain.pem; -ssl_certificate_key /path/to/privkey.pem; +ssl_certificate /data/ssl/certs/any.example.com/fullchain.pem; +ssl_certificate_key /data/ssl/certs/any.example.com/privkey.pem; From 54b4e991514354a1ca4022d6ec1894606d8a0ec1 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sat, 22 Feb 2020 11:47:47 +0100 Subject: [PATCH 14/37] Update --- gitea/README.md | 40 +++++++++++++++++++++++++++++++++++++++ gitea/gitea.service | 10 ++++++++++ gitea/nginx.conf | 10 ++++++++++ inbucket/README.md | 1 + iodine/README.md | 32 +++++++++++++++++++++++++++++++ iodine/my-iodined.conf | 2 ++ iodine/my-iodined.service | 11 +++++++++++ iptables/README.md | 7 +++++++ iptables/default.rules | 17 +++++++++++++++++ iptables/empty.rules | 10 ++++++++++ iptables/iptables.service | 13 +++++++++++++ mail/README.md | 3 ++- nextcloud/README.md | 3 +-- restic/README.md | 2 +- ssh/README.md | 2 +- 15 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 gitea/README.md create mode 100644 gitea/gitea.service create mode 100644 gitea/nginx.conf create mode 100644 iodine/README.md create mode 100644 iodine/my-iodined.conf create mode 100644 iodine/my-iodined.service create mode 100644 iptables/README.md create mode 100644 iptables/default.rules create mode 100644 iptables/empty.rules create mode 100644 iptables/iptables.service diff --git a/gitea/README.md b/gitea/README.md new file mode 100644 index 0000000..645794a --- /dev/null +++ b/gitea/README.md @@ -0,0 +1,40 @@ +# Gitea + +## Create User + +```sh +sudo sed -i '$ a git:*:2050:2050::/data/git:/bin/sh' /etc/passwd +sudo sed -i '$ a git:x:2050:' /etc/group + +sudo mkdir -p /data/git/gitea +sudo chown -R git: /data/git +``` + +## Install Software + +```sh +sudo apt install git +sudo -u git wget -O /data/git/gitea/gitea https://dl.gitea.io/gitea/... +sudo -u git chmod +x /data/git/gitea/gitea +``` + +## Apply Configuration + +```sh +DOMAIN=example.com + +sudo cp nginx.conf /etc/nginx/sites-available/git +sudo cp gitea.service /etc/systemd/system + +sudo systemctl enable gitea +sudo systemctl start gitea + +sudo sed -i s/example.com/$DOMAIN/ /etc/nginx/sites-available/git + +sudo ln -s ../sites-available/git /etc/nginx/sites-enabled +sudo nginx -s reload + +sudo -u git sed -i /MODE.*file/s/file/console/ /data/git/gitea/custom/conf/app.ini +sudo -u git sed -i /LEVEL.*info/s/info/warn/ /data/git/gitea/custom/conf/app.ini +sudo -u git /data/git/gitea/gitea admin create-user --username admin --password admin --admin --email admin +``` diff --git a/gitea/gitea.service b/gitea/gitea.service new file mode 100644 index 0000000..4bc4533 --- /dev/null +++ b/gitea/gitea.service @@ -0,0 +1,10 @@ +[Unit] +Description=Gitea +After=network.target + +[Service] +ExecStart=/data/git/gitea/gitea web +User=git + +[Install] +WantedBy=multi-user.target diff --git a/gitea/nginx.conf b/gitea/nginx.conf new file mode 100644 index 0000000..b0af6b5 --- /dev/null +++ b/gitea/nginx.conf @@ -0,0 +1,10 @@ +server { + server_name git.example.com; + + listen 443 ssl; + + location / { + proxy_pass http://localhost:3000; + include proxy_params; + } +} diff --git a/inbucket/README.md b/inbucket/README.md index ddc21f9..e190c48 100644 --- a/inbucket/README.md +++ b/inbucket/README.md @@ -24,6 +24,7 @@ sudo cp nginx.conf /etc/nginx/sites-available/inbucket sudo -u vmail cp inbucket.conf /data/mail/config sudo ln -s ../sites-available/inbucket /etc/nginx/sites-enabled +sudo sed -i s/example.com/$DOMAIN/ /etc/nginx/sites-available/inbucket echo "inbucket:$(openssl passwd -5)" | sudo -u vmail tee /data/mail/config/inbucket.htpasswd sudo chown vmail:www-data /data/mail/config/inbucket.htpasswd diff --git a/iodine/README.md b/iodine/README.md new file mode 100644 index 0000000..4fd3392 --- /dev/null +++ b/iodine/README.md @@ -0,0 +1,32 @@ +# Iodine + +## Install Software + +```sh +sudo apt install iodine +``` + +## Apply Configuration + +```sh +EXTERNAL=eth0 +INTERNAL=dns0 + +echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward +echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/60-ipv4-forward.conf + +sudo iptables -t nat -A POSTROUTING -o $EXTERNAL -j MASQUERADE +sudo iptables -A INPUT -p udp --dport 5353 -j ACCEPT +sudo iptables -A FORWARD -i $EXTERNAL -o $INTERNAL -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i $INTERNAL -o $EXTERNAL -j ACCEPT + +# Adjust domain: +sudo iptables -t nat -A PREROUTING -p udp -m udp --dport 53 -m string --hex-string "|01|t|07|example|03|com|00|" --algo bm --from 20 --to 65535 -j REDIRECT --to-ports 5353 + +sudo cp my-iodine.service /etc/systemd/system +sudo cp my-iodined.conf /etc +sudo chmod 600 /etc/iodined.conf + +sudo editor /etc/my-iodined.conf +sudo systemctl enable my-iodine +``` diff --git a/iodine/my-iodined.conf b/iodine/my-iodined.conf new file mode 100644 index 0000000..d454d38 --- /dev/null +++ b/iodine/my-iodined.conf @@ -0,0 +1,2 @@ +IODINED_OPTS="-c -p 5353 192.168.100.1 t.example.com" +IODINED_PASS=secret diff --git a/iodine/my-iodined.service b/iodine/my-iodined.service new file mode 100644 index 0000000..738fa2c --- /dev/null +++ b/iodine/my-iodined.service @@ -0,0 +1,11 @@ +[Unit] +Description=Iodine +After=network.target + +[Service] +EnvironmentFile=/etc/my-iodined.conf +ExecStartPre=mkdir -p /run/iodined +ExecStart=iodined -f -u nobody -t /run/iodined $IODINED_OPTS + +[Install] +WantedBy=multi-user.target diff --git a/iptables/README.md b/iptables/README.md new file mode 100644 index 0000000..f9d2317 --- /dev/null +++ b/iptables/README.md @@ -0,0 +1,7 @@ +# Iptables + +```sh +sudo cp *.rules /etc +sudo cp *.service /etc/systemd/system +sudo systemctl enable iptables +``` diff --git a/iptables/default.rules b/iptables/default.rules new file mode 100644 index 0000000..9332939 --- /dev/null +++ b/iptables/default.rules @@ -0,0 +1,17 @@ +*filter +:SERVICES - +-A INPUT -i lo -j ACCEPT +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -j SERVICES +-A SERVICES -p tcp -m tcp --dport 143 -j ACCEPT +-A SERVICES -p tcp -m tcp --dport 25 -j ACCEPT +-A SERVICES -p tcp -m tcp --dport 443 -j ACCEPT +-A SERVICES -p tcp -m tcp --dport 80 -j ACCEPT +-A SERVICES -p tcp -m tcp --dport 22222 -j ACCEPT +-A SERVICES -p udp -m udp --dport 53 -j ACCEPT +-A INPUT -j DROP +COMMIT + +*nat +-A PREROUTING -p tcp -m tcp --dport 4986 -j REDIRECT --to-ports 22222 +COMMIT diff --git a/iptables/empty.rules b/iptables/empty.rules new file mode 100644 index 0000000..8f9f18b --- /dev/null +++ b/iptables/empty.rules @@ -0,0 +1,10 @@ +*filter +COMMIT +*nat +COMMIT +*mangle +COMMIT +*raw +COMMIT +*security +COMMIT diff --git a/iptables/iptables.service b/iptables/iptables.service new file mode 100644 index 0000000..45847f3 --- /dev/null +++ b/iptables/iptables.service @@ -0,0 +1,13 @@ +[Unit] +Description=iptables +Before=network-pre.target +Wants=network-pre.target + +[Service] +Type=oneshot +ExecStart=iptables-restore /etc/default.rules +ExecStop=iptables-restore /etc/empty.rules +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/mail/README.md b/mail/README.md index 2c8b391..1119549 100644 --- a/mail/README.md +++ b/mail/README.md @@ -27,7 +27,8 @@ DOMAIN=example.com sudo cp -r postfix dovecot /etc sudo sed -i '$ r opendkim/local.conf' /etc/opendkim.conf -sudo sed -i s/example.com/$DOMAIN/g /etc/postfix/main.cf /etc/dovecot/local.conf +sudo sed -i s/example.com/$DOMAIN/ /etc/postfix/main.cf /etc/dovecot/local.conf +sudo sed -i '/include auth-system/ s/.*/#&/' /etc/dovecot/conf.d/10-auth.conf sudo ln -s /data/mail/config/vmail.db /.opendkim-bug-241.db sudo chown vmail:postfix /data/mail/config/vmail.db diff --git a/nextcloud/README.md b/nextcloud/README.md index 23e88ce..69888f3 100644 --- a/nextcloud/README.md +++ b/nextcloud/README.md @@ -33,9 +33,8 @@ sudo sed -i '$ r redis.conf' /etc/redis/redis.conf sudo -u cloud cp local.config.php /data/cloud/nextcloud/config sudo -u cloud crontab crontab -sudo sed -i s/example.com/$DOMAIN/g /etc/nginx/sites-available/nextcloud /data/cloud/nextcloud/config/local.config.php - sudo ln -s ../sites-available/nextcloud /etc/nginx/sites-enabled +sudo sed -i s/example.com/$DOMAIN/ /etc/nginx/sites-available/nextcloud /data/cloud/nextcloud/config/local.config.php sudo -u cloud mkdir -p /data/cloud/.config/user-tmpfiles.d echo 'e %h/data/*/files/tmp - - - 7d' | sudo -u cloud tee /data/cloud/.config/user-tmpfiles.d/nextcloud-tmp.conf diff --git a/restic/README.md b/restic/README.md index 3c23001..3cbb4ee 100644 --- a/restic/README.md +++ b/restic/README.md @@ -13,7 +13,7 @@ echo 'nice /usr/local/bin/restic -r' "$REPO" '-p /root/backup-key "$@"' | sudo t sudo chmod +x /usr/local/bin/restic-cmd cat /dev/urandom | base64 | head -c 64 | sudo tee /root/backup-key -sudo chmod 0600 /root/backup-key +sudo chmod 600 /root/backup-key sudo restic-cmd init sudo crontab crontab diff --git a/ssh/README.md b/ssh/README.md index fdda9eb..a0e5964 100644 --- a/ssh/README.md +++ b/ssh/README.md @@ -12,4 +12,4 @@ sudo chown sshlogin:root /home/sshlogin/.ssh ``` * Either create a password with `sudo passwd sshlogin` or -* Add a key `sudo -u sshlogin nano /home/sshlogin/.ssh/authorized_keys` +* Add a key `sudo -u sshlogin editor /home/sshlogin/.ssh/authorized_keys` From de5eb91e91dd0c4ba7d023663525f4ee1b8f7ebf Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 23 Feb 2020 19:47:53 +0100 Subject: [PATCH 15/37] Update --- gitea/README.md | 3 +++ iodine/README.md | 12 ++++++++---- iodine/my-iodined.service | 2 +- iptables/README.md | 26 ++++++++++++++++++++++++++ iptables/default.rules | 27 +++++++++++++-------------- iptables/empty.rules | 1 + iptables/ratelimit.rules | 16 ++++++++++++++++ 7 files changed, 68 insertions(+), 19 deletions(-) create mode 100644 iptables/ratelimit.rules diff --git a/gitea/README.md b/gitea/README.md index 645794a..6fbb691 100644 --- a/gitea/README.md +++ b/gitea/README.md @@ -34,6 +34,9 @@ sudo sed -i s/example.com/$DOMAIN/ /etc/nginx/sites-available/git sudo ln -s ../sites-available/git /etc/nginx/sites-enabled sudo nginx -s reload + +sudo iptables -t nat -A PREROUTING -p tcp --dport 4986 -j REDIRECT --to-ports 22222 + sudo -u git sed -i /MODE.*file/s/file/console/ /data/git/gitea/custom/conf/app.ini sudo -u git sed -i /LEVEL.*info/s/info/warn/ /data/git/gitea/custom/conf/app.ini sudo -u git /data/git/gitea/gitea admin create-user --username admin --password admin --admin --email admin diff --git a/iodine/README.md b/iodine/README.md index 4fd3392..3c2d6bb 100644 --- a/iodine/README.md +++ b/iodine/README.md @@ -17,16 +17,20 @@ echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/60-ipv4-forward.conf sudo iptables -t nat -A POSTROUTING -o $EXTERNAL -j MASQUERADE sudo iptables -A INPUT -p udp --dport 5353 -j ACCEPT +sudo iptables -A INPUT -i $INTERNAL -j ACCEPT + +# Necessary only if default policy is not ACCEPT sudo iptables -A FORWARD -i $EXTERNAL -o $INTERNAL -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i $INTERNAL -o $EXTERNAL -j ACCEPT # Adjust domain: -sudo iptables -t nat -A PREROUTING -p udp -m udp --dport 53 -m string --hex-string "|01|t|07|example|03|com|00|" --algo bm --from 20 --to 65535 -j REDIRECT --to-ports 5353 +sudo iptables -t nat -A PREROUTING -p udp --dport 53 -m string --hex-string "|01|t|07|example|03|com|00|" --algo bm --from 20 --to 65535 -j REDIRECT --to-ports 5353 -sudo cp my-iodine.service /etc/systemd/system +sudo cp my-iodined.service /etc/systemd/system sudo cp my-iodined.conf /etc -sudo chmod 600 /etc/iodined.conf +sudo chmod 600 /etc/my-iodined.conf sudo editor /etc/my-iodined.conf -sudo systemctl enable my-iodine +sudo systemctl enable my-iodined +sudo systemctl start my-iodined ``` diff --git a/iodine/my-iodined.service b/iodine/my-iodined.service index 738fa2c..953abfc 100644 --- a/iodine/my-iodined.service +++ b/iodine/my-iodined.service @@ -1,6 +1,6 @@ [Unit] Description=Iodine -After=network.target +After=network-online.target [Service] EnvironmentFile=/etc/my-iodined.conf diff --git a/iptables/README.md b/iptables/README.md index f9d2317..3e0dbd7 100644 --- a/iptables/README.md +++ b/iptables/README.md @@ -5,3 +5,29 @@ sudo cp *.rules /etc sudo cp *.service /etc/systemd/system sudo systemctl enable iptables ``` + +## Apply and Report Rate Limits + +The `ratelimit.rules` file adds new chains to rate limit subnets. + +```sh +sudo iptables-restore -n < ratelimit.rules + +# Common offenders +sudo iptables -t raw -A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_SUBNET_DEFAULT +sudo iptables -t raw -A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_SUBNET_DEFAULT +sudo iptables -t raw -A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_SUBNET_DEFAULT + +# Default action +sudo iptables -t raw -A RATELIMIT_SUBNET_DEFAULT -p tcp --tcp-flags SYN,ACK SYN \ + -m hashlimit --hashlimit-name drop_4h \ + --hashlimit-above 4/hour --hashlimit-burst 2 \ + --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j DROP + +# Log potential offenders +sudo iptables -t raw -A RATELIMIT_REPORT -p tcp --tcp-flags SYN,ACK SYN \ + -m hashlimit --hashlimit-name log_1s_burst4_net16 \ + --hashlimit-above 1/second --hashlimit-burst 4 \ + --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j LOG \ + --log-level 5 --log-prefix "ratelimit above 1/second burst 4 srcmask 16 " +``` diff --git a/iptables/default.rules b/iptables/default.rules index 9332939..a07b16d 100644 --- a/iptables/default.rules +++ b/iptables/default.rules @@ -1,17 +1,16 @@ *filter -:SERVICES - --A INPUT -i lo -j ACCEPT --A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT --A INPUT -j SERVICES --A SERVICES -p tcp -m tcp --dport 143 -j ACCEPT --A SERVICES -p tcp -m tcp --dport 25 -j ACCEPT --A SERVICES -p tcp -m tcp --dport 443 -j ACCEPT --A SERVICES -p tcp -m tcp --dport 80 -j ACCEPT --A SERVICES -p tcp -m tcp --dport 22222 -j ACCEPT --A SERVICES -p udp -m udp --dport 53 -j ACCEPT +:INPUT DROP +:CONNECTION - +:SERVICE - +-A INPUT -j CONNECTION +-A INPUT -j SERVICE -A INPUT -j DROP -COMMIT - -*nat --A PREROUTING -p tcp -m tcp --dport 4986 -j REDIRECT --to-ports 22222 +-A CONNECTION -i lo -j ACCEPT +-A CONNECTION -m state --state RELATED,ESTABLISHED -j ACCEPT +-A SERVICE -p tcp --dport 25 -j ACCEPT +-A SERVICE -p tcp --dport 80 -j ACCEPT +-A SERVICE -p tcp --dport 143 -j ACCEPT +-A SERVICE -p tcp --dport 443 -j ACCEPT +-A SERVICE -p tcp --dport 22222 -j ACCEPT +-A SERVICE -p udp --dport 53 -j ACCEPT COMMIT diff --git a/iptables/empty.rules b/iptables/empty.rules index 8f9f18b..7a7d32c 100644 --- a/iptables/empty.rules +++ b/iptables/empty.rules @@ -1,4 +1,5 @@ *filter +:INPUT ACCEPT COMMIT *nat COMMIT diff --git a/iptables/ratelimit.rules b/iptables/ratelimit.rules new file mode 100644 index 0000000..12bfaf2 --- /dev/null +++ b/iptables/ratelimit.rules @@ -0,0 +1,16 @@ +*raw +:RATELIMIT - +:RATELIMIT_REPORT - +:RATELIMIT_SUBNET - +:RATELIMIT_SUBNET_DEFAULT - + +-I PREROUTING -j RATELIMIT + +-A RATELIMIT -s 127.0.0.0/8 -j RETURN +-A RATELIMIT -s 10.0.0.0/8 -j RETURN +-A RATELIMIT -s 172.16.0.0/12 -j RETURN +-A RATELIMIT -s 192.168.0.0/16 -j RETURN +-A RATELIMIT -j RATELIMIT_SUBNET +-A RATELIMIT -j RATELIMIT_REPORT + +COMMIT From 18c7a935a7f9c3f8d95b6160ea2b7796178a12f0 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 23 Feb 2020 19:52:37 +0100 Subject: [PATCH 16/37] Update --- iptables/default.rules | 1 - 1 file changed, 1 deletion(-) diff --git a/iptables/default.rules b/iptables/default.rules index a07b16d..f6c250b 100644 --- a/iptables/default.rules +++ b/iptables/default.rules @@ -4,7 +4,6 @@ :SERVICE - -A INPUT -j CONNECTION -A INPUT -j SERVICE --A INPUT -j DROP -A CONNECTION -i lo -j ACCEPT -A CONNECTION -m state --state RELATED,ESTABLISHED -j ACCEPT -A SERVICE -p tcp --dport 25 -j ACCEPT From b23946b81c664f50076ac839d0a39d1f57aa546b Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 23 Feb 2020 20:02:32 +0100 Subject: [PATCH 17/37] Update --- iptables/README.md | 12 ++++++------ iptables/ratelimit.rules | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iptables/README.md b/iptables/README.md index 3e0dbd7..3e2a65d 100644 --- a/iptables/README.md +++ b/iptables/README.md @@ -14,20 +14,20 @@ The `ratelimit.rules` file adds new chains to rate limit subnets. sudo iptables-restore -n < ratelimit.rules # Common offenders -sudo iptables -t raw -A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_SUBNET_DEFAULT -sudo iptables -t raw -A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_SUBNET_DEFAULT -sudo iptables -t raw -A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_SUBNET_DEFAULT +sudo iptables -t raw -A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_DEFAULT +sudo iptables -t raw -A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_DEFAULT +sudo iptables -t raw -A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_DEFAULT # Default action -sudo iptables -t raw -A RATELIMIT_SUBNET_DEFAULT -p tcp --tcp-flags SYN,ACK SYN \ +sudo iptables -t raw -A RATELIMIT_DEFAULT -p tcp --tcp-flags SYN,ACK SYN \ -m hashlimit --hashlimit-name drop_4h \ --hashlimit-above 4/hour --hashlimit-burst 2 \ --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j DROP # Log potential offenders sudo iptables -t raw -A RATELIMIT_REPORT -p tcp --tcp-flags SYN,ACK SYN \ - -m hashlimit --hashlimit-name log_1s_burst4_net16 \ + -m hashlimit --hashlimit-name report1 \ --hashlimit-above 1/second --hashlimit-burst 4 \ --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j LOG \ - --log-level 5 --log-prefix "ratelimit above 1/second burst 4 srcmask 16 " + --log-level 5 --log-prefix "ratelimit report1 " ``` diff --git a/iptables/ratelimit.rules b/iptables/ratelimit.rules index 12bfaf2..e7dfdc9 100644 --- a/iptables/ratelimit.rules +++ b/iptables/ratelimit.rules @@ -2,7 +2,7 @@ :RATELIMIT - :RATELIMIT_REPORT - :RATELIMIT_SUBNET - -:RATELIMIT_SUBNET_DEFAULT - +:RATELIMIT_DEFAULT - -I PREROUTING -j RATELIMIT From c94ed5a66ad601e065a845a1c1742f56b013397b Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 23 Feb 2020 21:23:02 +0100 Subject: [PATCH 18/37] Update --- restic/README.md | 6 +++--- restic/crontab | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/restic/README.md b/restic/README.md index 3cbb4ee..2f94664 100644 --- a/restic/README.md +++ b/restic/README.md @@ -9,12 +9,12 @@ REPO=sftp:backup-user@example.com:repo bunzip2 restic*.bz2 sudo cp restic* /usr/local/bin/restic -echo 'nice /usr/local/bin/restic -r' "$REPO" '-p /root/backup-key "$@"' | sudo tee /usr/local/bin/restic-cmd -sudo chmod +x /usr/local/bin/restic-cmd +echo 'nice /usr/local/bin/restic -r' "$REPO" '-p /root/backup-key "$@"' | sudo tee /root/restic-cmd +sudo chmod +x /root/restic-cmd cat /dev/urandom | base64 | head -c 64 | sudo tee /root/backup-key sudo chmod 600 /root/backup-key -sudo restic-cmd init +sudo /root/restic-cmd init sudo crontab crontab ``` diff --git a/restic/crontab b/restic/crontab index 69bc4f2..5d2bebc 100644 --- a/restic/crontab +++ b/restic/crontab @@ -1,2 +1,2 @@ -48 * * * * /usr/local/bin/restic-cmd backup -q --exclude-if-present .nobackup /data -18 3 * * * /usr/local/bin/restic-cmd forget -q --keep-tag keep -H 24 -d 7 -m 12 -y 100 +48 * * * * /root/restic-cmd backup -q --exclude-if-present .nobackup /data +18 3 * * * /root/restic-cmd forget -q --keep-tag keep -H 24 -d 7 -m 12 -y 100 From 12b87e280591c189d4219d24cd36ed18c99fb8be Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 26 Feb 2020 01:14:32 +0100 Subject: [PATCH 19/37] Update --- ssh/sshd_config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ssh/sshd_config b/ssh/sshd_config index 4db04db..fb33505 100644 --- a/ssh/sshd_config +++ b/ssh/sshd_config @@ -3,6 +3,9 @@ Port 22222 AllowUsers sshlogin git backup-* ClientAliveInterval 10 +LoginGraceTime 10 +MaxAuthTries 2 + Match User backup-* ForceCommand internal-sftp ChrootDirectory %h From 45708b28a0d97553d605648f3c1796e218643ee1 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sat, 7 Mar 2020 00:41:17 +0100 Subject: [PATCH 20/37] Update --- iptables/README.md | 21 ++------------------- iptables/ratelimit.rules | 12 ++++++++++-- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/iptables/README.md b/iptables/README.md index 3e2a65d..fc67e5c 100644 --- a/iptables/README.md +++ b/iptables/README.md @@ -8,26 +8,9 @@ sudo systemctl enable iptables ## Apply and Report Rate Limits -The `ratelimit.rules` file adds new chains to rate limit subnets. +The `ratelimit.rules` file adds new chains to +limit the rate of new connections based on /16 subnets. ```sh sudo iptables-restore -n < ratelimit.rules - -# Common offenders -sudo iptables -t raw -A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_DEFAULT -sudo iptables -t raw -A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_DEFAULT -sudo iptables -t raw -A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_DEFAULT - -# Default action -sudo iptables -t raw -A RATELIMIT_DEFAULT -p tcp --tcp-flags SYN,ACK SYN \ - -m hashlimit --hashlimit-name drop_4h \ - --hashlimit-above 4/hour --hashlimit-burst 2 \ - --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j DROP - -# Log potential offenders -sudo iptables -t raw -A RATELIMIT_REPORT -p tcp --tcp-flags SYN,ACK SYN \ - -m hashlimit --hashlimit-name report1 \ - --hashlimit-above 1/second --hashlimit-burst 4 \ - --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j LOG \ - --log-level 5 --log-prefix "ratelimit report1 " ``` diff --git a/iptables/ratelimit.rules b/iptables/ratelimit.rules index e7dfdc9..db4319f 100644 --- a/iptables/ratelimit.rules +++ b/iptables/ratelimit.rules @@ -1,10 +1,10 @@ *raw :RATELIMIT - +:RATELIMIT_ENFORCE - :RATELIMIT_REPORT - :RATELIMIT_SUBNET - -:RATELIMIT_DEFAULT - --I PREROUTING -j RATELIMIT +-I PREROUTING -p tcp --tcp-flags SYN,ACK SYN -j RATELIMIT -A RATELIMIT -s 127.0.0.0/8 -j RETURN -A RATELIMIT -s 10.0.0.0/8 -j RETURN @@ -13,4 +13,12 @@ -A RATELIMIT -j RATELIMIT_SUBNET -A RATELIMIT -j RATELIMIT_REPORT +-A RATELIMIT_ENFORCE -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 2 --hashlimit-mode srcip,dstport --hashlimit-name enforce --hashlimit-srcmask 16 -j DROP + +-A RATELIMIT_REPORT -m hashlimit --hashlimit-above 1/min --hashlimit-burst 6 --hashlimit-mode srcip,dstport --hashlimit-name report1 --hashlimit-srcmask 16 -j LOG --log-prefix "ratelimit report1 " --log-level 5 + +-A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_ENFORCE +-A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_ENFORCE +-A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_ENFORCE + COMMIT From 80070352dedb8064ea66be64471eee9cc607842d Mon Sep 17 00:00:00 2001 From: Adrian Date: Sat, 7 Mar 2020 09:24:38 +0100 Subject: [PATCH 21/37] Update --- gitea/nginx.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gitea/nginx.conf b/gitea/nginx.conf index b0af6b5..56a0b41 100644 --- a/gitea/nginx.conf +++ b/gitea/nginx.conf @@ -7,4 +7,6 @@ server { proxy_pass http://localhost:3000; include proxy_params; } + + location = /robots.txt { return 200 "User-agent: *\nDisallow: */commit/*\n"; } } From 71d6a5fff3e4c0234b0fdf01cd306d1c607a3b78 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sat, 22 Feb 2020 14:20:30 +0100 Subject: [PATCH 22/37] Add NetworkManager configuration --- network-manager/99-no-wifi-on-ethernet | 11 +++++++++++ network-manager/README.md | 13 +++++++++++++ 2 files changed, 24 insertions(+) create mode 100755 network-manager/99-no-wifi-on-ethernet create mode 100644 network-manager/README.md diff --git a/network-manager/99-no-wifi-on-ethernet b/network-manager/99-no-wifi-on-ethernet new file mode 100755 index 0000000..fa44a2f --- /dev/null +++ b/network-manager/99-no-wifi-on-ethernet @@ -0,0 +1,11 @@ +#!/bin/sh + +logger -t no-wifi-on-ethernet "Device $1 is $2" + +if [ "dev:$1:$2" = "dev:eth0:up" ]; then + nmcli r wifi off +fi + +if [ "dev:$1:$2" = "dev:eth0:down" ]; then + nmcli r wifi on +fi diff --git a/network-manager/README.md b/network-manager/README.md new file mode 100644 index 0000000..6e60a35 --- /dev/null +++ b/network-manager/README.md @@ -0,0 +1,13 @@ +# NetworkManager + +## Manage ethernet devices with NetworkManager + +```sh +touch /etc/NetworkManager/conf.d/10-globally-managed-devices.conf +``` + +## Automatically switch off wifi when ethernet is connected + +```sh +sudo cp 99-no-wifi-on-ethernet /etc/NetworkManager/dispatcher.d +``` From 4c004acda81255146c86399143973412ea9b8fbe Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 15 Apr 2020 23:22:14 +0200 Subject: [PATCH 23/37] Fix unprocessed index directives --- nextcloud/nginx.conf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nextcloud/nginx.conf b/nextcloud/nginx.conf index 15307c4..8030b02 100644 --- a/nextcloud/nginx.conf +++ b/nextcloud/nginx.conf @@ -9,7 +9,6 @@ server { client_max_body_size 0; location / { - index index.php; try_files $uri /index.php$request_uri; } @@ -26,6 +25,10 @@ server { include fastcgi.conf; } + location /updater { index index.php; } + location /ocm-provider { index index.php; } + location /ocs-provider { index index.php; } + location = /.well-known/carddav { return 301 $scheme://$host:$server_port/remote.php/dav; } From 8b0615f9de0b9178f01d33e4e2953c9dcff0b5d2 Mon Sep 17 00:00:00 2001 From: Adrian Date: Mon, 13 Apr 2020 21:10:11 +0200 Subject: [PATCH 24/37] Add postfix SNI support --- mail/README.md | 12 ++++++++++-- mail/postfix/main.cf | 1 + mail/postfix/sni.cf | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 mail/postfix/sni.cf diff --git a/mail/README.md b/mail/README.md index 1119549..7945019 100644 --- a/mail/README.md +++ b/mail/README.md @@ -11,6 +11,7 @@ sudo mkdir -p /data/mail/config sudo chown vmail: /data/mail/* cat schema.sql | sudo -u vmail sqlite3 /data/mail/config/vmail.db +sudo chown vmail:postfix /data/mail/config/vmail.db sudo chmod 640 /data/mail/config/vmail.db ``` @@ -26,12 +27,13 @@ sudo apt install sqlite3 postfix postfix-sqlite dovecot-imapd dovecot-sqlite ope DOMAIN=example.com sudo cp -r postfix dovecot /etc +sudo chmod 600 /etc/postfix/sni.cf + sudo sed -i '$ r opendkim/local.conf' /etc/opendkim.conf -sudo sed -i s/example.com/$DOMAIN/ /etc/postfix/main.cf /etc/dovecot/local.conf +sudo sed -i s/example.com/$DOMAIN/ /etc/postfix/{main,sni}.cf /etc/dovecot/local.conf sudo sed -i '/include auth-system/ s/.*/#&/' /etc/dovecot/conf.d/10-auth.conf sudo ln -s /data/mail/config/vmail.db /.opendkim-bug-241.db -sudo chown vmail:postfix /data/mail/config/vmail.db opendkim-genkey -d $DOMAIN -s s chmod +r s.private @@ -40,6 +42,12 @@ cat s.txt rm s.private s.txt ``` +## Certificate Reload + +```sh +postmap -F /etc/postfix/sni.cf +``` + ## Notes * The `vmail.db` parent directory needs to be writeable by the user modifying the database diff --git a/mail/postfix/main.cf b/mail/postfix/main.cf index 4b2e97f..66b0ba0 100644 --- a/mail/postfix/main.cf +++ b/mail/postfix/main.cf @@ -14,6 +14,7 @@ smtp_tls_security_level = may smtpd_tls_security_level = may smtpd_tls_key_file = /data/ssl/certs/mail.example.com/privkey.pem smtpd_tls_cert_file = /data/ssl/certs/mail.example.com/fullchain.pem +tls_server_sni_maps = hash:/etc/postfix/sni.cf # Custom diff --git a/mail/postfix/sni.cf b/mail/postfix/sni.cf new file mode 100644 index 0000000..e9ae8a0 --- /dev/null +++ b/mail/postfix/sni.cf @@ -0,0 +1 @@ +mail.example.com /data/ssl/certs/mail.example.com/privkey.pem /data/ssl/certs/mail.example.com/fullchain.pem From f0dc028f270b3f374594f80b2985b321134b1918 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 16 Apr 2020 22:51:36 +0200 Subject: [PATCH 25/37] fixup-nginx --- nginx/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/nginx/README.md b/nginx/README.md index fee1b7c..d87501e 100644 --- a/nginx/README.md +++ b/nginx/README.md @@ -1,9 +1,19 @@ # Nginx ```sh +DOMAIN=example.com + sudo cp -r sites-available snippets conf.d /etc/nginx sudo rm /etc/nginx/sites-*/default sudo ln -s ../sites-available/0nohost /etc/nginx/sites-enabled sudo ln -s ../sites-available/redirect-ssl-all /etc/nginx/sites-enabled + +sudo sed -i s/example.com/$DOMAIN/ /etc/nginx/conf.d/ssl.conf +``` + +## Certificate Reload + +```sh +nginx -s reload ``` From 0ba0c06653ead4827731bc77ab9b1b48310e80c9 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 16 Apr 2020 23:45:18 +0200 Subject: [PATCH 26/37] Add dyndns and letsencrypt helpers --- dyndns/README.md | 16 +++++++++++++++ dyndns/dyndns-nsupdate | 10 +++++++++ dyndns/dyndns-update | 19 +++++++++++++++++ dyndns/example.com.nsupdate.txt | 12 +++++++++++ dyndns/tsig.example.com.conf | 4 ++++ dyndns/update-example.com.sh | 7 +++++++ letsencrypt/README.md | 36 +++++++++++++++++++++++++++++++++ letsencrypt/config | 5 +++++ letsencrypt/dehydrated-manual | 11 ++++++++++ letsencrypt/dehydrated-nsupdate | 24 ++++++++++++++++++++++ letsencrypt/example-hook | 7 +++++++ 11 files changed, 151 insertions(+) create mode 100644 dyndns/README.md create mode 100755 dyndns/dyndns-nsupdate create mode 100755 dyndns/dyndns-update create mode 100644 dyndns/example.com.nsupdate.txt create mode 100644 dyndns/tsig.example.com.conf create mode 100755 dyndns/update-example.com.sh create mode 100644 letsencrypt/README.md create mode 100644 letsencrypt/config create mode 100755 letsencrypt/dehydrated-manual create mode 100755 letsencrypt/dehydrated-nsupdate create mode 100644 letsencrypt/example-hook diff --git a/dyndns/README.md b/dyndns/README.md new file mode 100644 index 0000000..21e1264 --- /dev/null +++ b/dyndns/README.md @@ -0,0 +1,16 @@ +# Dynamic DNS + +Edit example files to match your needs. + +```sh +sudo mkdir /data/dns +cp *example* dyndns* /data/dns + +chmod 600 /data/dns/tsig* +``` + +## Cronjob + +```sh +/data/dns/update-example.com.sh +``` diff --git a/dyndns/dyndns-nsupdate b/dyndns/dyndns-nsupdate new file mode 100755 index 0000000..1876f7c --- /dev/null +++ b/dyndns/dyndns-nsupdate @@ -0,0 +1,10 @@ +#!/bin/sh + +DYN_DIR=/data/dns + +if test "x$DYN_TSIGKEY" = x; then DYN_TSIGKEY="$DYN_DIR/tsig.$DYN_DOMAIN.conf"; fi +if test "x$DYN_NSUPDATE" = x; then DYN_NSUPDATE="$DYN_DIR/$DYN_DOMAIN.nsupdate.txt"; fi + +if test "x$1" != x; then + cat "$DYN_NSUPDATE" | sed s/%IP%/$1/g | nsupdate -v -k "$DYN_TSIGKEY" +fi diff --git a/dyndns/dyndns-update b/dyndns/dyndns-update new file mode 100755 index 0000000..2eb07c8 --- /dev/null +++ b/dyndns/dyndns-update @@ -0,0 +1,19 @@ +#!/bin/sh + +if test "x$DYN_SERVER" = x; then echo export DYN_SERVER=ns.example.com; exit=1; fi +if test "x$DYN_DOMAIN" = x; then echo export DYN_DOMAIN=example.com; exit=1; fi +if test "x$DYN_SCRIPT" = x; then echo export DYN_SCRIPT=/path/to/script; exit=1; fi +if test "x$exit" = x1; then exit 1; fi + +if test "x$DYN_IPAPI" = x; then DYN_IPAPI=ifconfig.co; fi + +IPACTUAL=$(wget -qO - "$DYN_IPAPI") +IPSERVER=$(dig +short $DYN_DOMAIN @$DYN_SERVER) + +if test "x$IPSERVER" = x -o "x$IPACTUAL" = x; then + : # ERROR: IP unknown +elif test "x$IPSERVER" = "x$IPACTUAL"; then + : # INFO: IP not changed +else + "$DYN_SCRIPT" $IPACTUAL +fi diff --git a/dyndns/example.com.nsupdate.txt b/dyndns/example.com.nsupdate.txt new file mode 100644 index 0000000..8153944 --- /dev/null +++ b/dyndns/example.com.nsupdate.txt @@ -0,0 +1,12 @@ +server ns01.example.com +zone example.com + +update del example.com. TXT +update del example.com. A +update del *.example.com. A + +update add example.com. 86400 TXT "v=spf1 ip4:%IP%/32 -all" +update add example.com. 86400 A %IP% +update add *.example.com. 86400 A %IP% + +send diff --git a/dyndns/tsig.example.com.conf b/dyndns/tsig.example.com.conf new file mode 100644 index 0000000..1cea1d4 --- /dev/null +++ b/dyndns/tsig.example.com.conf @@ -0,0 +1,4 @@ +key "tsig.example.com." { + algorithm hmac-sha256; + secret "YWRyaXVtLmFkcml1bS4uCg=="; +}; diff --git a/dyndns/update-example.com.sh b/dyndns/update-example.com.sh new file mode 100755 index 0000000..e30dd4e --- /dev/null +++ b/dyndns/update-example.com.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +export DYN_DOMAIN=example.com +export DYN_SERVER=ns01.example.com +export DYN_SCRIPT=/data/dns/dyndns-nsupdate + +/data/dns/dyndns-update diff --git a/letsencrypt/README.md b/letsencrypt/README.md new file mode 100644 index 0000000..c1f3f51 --- /dev/null +++ b/letsencrypt/README.md @@ -0,0 +1,36 @@ +# Let's Encrypt + +Download Let's Encrypt client (only `dehydrated` needed): +https://github.com/dehydrated-io/dehydrated/releases/latest + +```sh +sudo mkdir -p /data/ssl/{configs,challenge} +sudo chown -R admin: /data/ssl + +cp config dehydrated-* /data/ssl + +# List all domains for automatic renewal +editor /data/ssl/domains.txt + +/data/ssl/dehydrated -r +``` + +To enable certificate renewal, +`include snippets/letsencrypt` or put `redirect-ssl-all` in sites-enabled. + +## Cronjob + +```sh +/data/ssl/dehydrated -c +``` + +## Wildcard Certificates + +```sh +echo "service.example.com *.service.example.com" >> /data/ssl/domains.txt +echo "CHALLENGETYPE=dns-01" >> /data/ssl/configs/service.example.com +echo "HOOK=/data/ssl/dehydrated-hook" >> /data/ssl/configs/service.example.com +``` + +There are manual and nsupdate hooks. +See [example-hook](example-hook) for an example nsupdate hook. diff --git a/letsencrypt/config b/letsencrypt/config new file mode 100644 index 0000000..8ddd42e --- /dev/null +++ b/letsencrypt/config @@ -0,0 +1,5 @@ +DOMAINS_D=/data/ssl/configs +WELLKNOWN=/data/ssl/challenge +PRIVATE_KEY_RENEW=no +KEYSIZE=2048 +# CONTACT_EMAIL=hostmaster@example.com diff --git a/letsencrypt/dehydrated-manual b/letsencrypt/dehydrated-manual new file mode 100755 index 0000000..0436362 --- /dev/null +++ b/letsencrypt/dehydrated-manual @@ -0,0 +1,11 @@ +#!/bin/sh + +if test "x$1" = xdeploy_challenge; then + echo "Add the following record and press enter to continue:" + echo "_acme-challenge.$2. TXT $4" + read dummy +elif test "x$1" = xclean_challenge; then + echo "Remove the record and press enter to continue:" + echo "_acme-challenge.$2. TXT $4" + read dummy +fi diff --git a/letsencrypt/dehydrated-nsupdate b/letsencrypt/dehydrated-nsupdate new file mode 100755 index 0000000..52fd241 --- /dev/null +++ b/letsencrypt/dehydrated-nsupdate @@ -0,0 +1,24 @@ +#!/bin/sh + +SCRIPT_TTL=30 + +if test "x$LE_SERVER" = x; then echo export LE_SERVER=ns.example.com; exit=1; fi +if test "x$LE_ZONE" = x; then echo export LE_ZONE=example.com; exit=1; fi +if test "x$LE_TSIGKEY" = x; then echo export LE_TSIGKEY=/path/to/key; exit=1; fi +if test "x$exit" = x1; then exit 1; fi + +if test "x$1" = xdeploy_challenge; then + nsupdate -v -k "$LE_TSIGKEY" <<- NSUPDATE + server $LE_SERVER + zone $LE_ZONE + update add _acme-challenge.$2. $SCRIPT_TTL TXT $4 + send + NSUPDATE +elif test "x$1" = xclean_challenge; then + nsupdate -v -k "$LE_TSIGKEY" <<- NSUPDATE + server $LE_SERVER + zone $LE_ZONE + update del _acme-challenge.$2. TXT + send + NSUPDATE +fi diff --git a/letsencrypt/example-hook b/letsencrypt/example-hook new file mode 100644 index 0000000..80a49ad --- /dev/null +++ b/letsencrypt/example-hook @@ -0,0 +1,7 @@ +#!/bin/sh + +export LE_TSIGKEY=/data/dns/tsig.example.com.conf +export LE_SERVER=ns01.example.com +export LE_ZONE=example.com + +/data/ssl/dehydrated-nsupdate "$@" From 1f983af06dc1c33157b81c9505c2ad5563f40891 Mon Sep 17 00:00:00 2001 From: Adrian Date: Tue, 14 Apr 2020 00:43:49 +0200 Subject: [PATCH 27/37] Improve iptables ratelimit rules --- iptables/ratelimit.rules | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/iptables/ratelimit.rules b/iptables/ratelimit.rules index db4319f..c5dc31a 100644 --- a/iptables/ratelimit.rules +++ b/iptables/ratelimit.rules @@ -1,24 +1,23 @@ *raw +:BLOCK - :RATELIMIT - -:RATELIMIT_ENFORCE - -:RATELIMIT_REPORT - -:RATELIMIT_SUBNET - +:WHITELIST - --I PREROUTING -p tcp --tcp-flags SYN,ACK SYN -j RATELIMIT +-A PREROUTING -j WHITELIST +-A PREROUTING -j BLOCK +-A PREROUTING -p tcp -m tcp --tcp-flags SYN,ACK SYN -j RATELIMIT --A RATELIMIT -s 127.0.0.0/8 -j RETURN --A RATELIMIT -s 10.0.0.0/8 -j RETURN --A RATELIMIT -s 172.16.0.0/12 -j RETURN --A RATELIMIT -s 192.168.0.0/16 -j RETURN --A RATELIMIT -j RATELIMIT_SUBNET --A RATELIMIT -j RATELIMIT_REPORT +-A BLOCK -s 46.229.160.0/20 -m comment --comment SEMrushBot -j DROP +-A BLOCK -s 114.119.160.0/21 -m comment --comment AspiegelBot -j DROP --A RATELIMIT_ENFORCE -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 2 --hashlimit-mode srcip,dstport --hashlimit-name enforce --hashlimit-srcmask 16 -j DROP +-A RATELIMIT -p tcp -m tcp --dport 22222 -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 2 --hashlimit-mode srcip --hashlimit-name ratelimit-ssh --hashlimit-srcmask 16 -j DROP +-A RATELIMIT -p tcp -m tcp --dport 25 -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 4 --hashlimit-mode srcip --hashlimit-name ratelimit-smtp --hashlimit-srcmask 16 -j DROP +-A RATELIMIT -p tcp -m tcp --dport 143 -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 4 --hashlimit-mode srcip --hashlimit-name ratelimit-imap --hashlimit-srcmask 16 -j DROP +-A RATELIMIT -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 16 --hashlimit-mode srcip,dstport --hashlimit-name ratelimit-other --hashlimit-srcmask 16 -j DROP --A RATELIMIT_REPORT -m hashlimit --hashlimit-above 1/min --hashlimit-burst 6 --hashlimit-mode srcip,dstport --hashlimit-name report1 --hashlimit-srcmask 16 -j LOG --log-prefix "ratelimit report1 " --log-level 5 - --A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_ENFORCE --A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_ENFORCE --A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_ENFORCE +-A WHITELIST -s 127.0.0.0/8 -m comment --comment localhost -j ACCEPT +-A WHITELIST -s 10.0.0.0/8 -m comment --comment "RFC 1918" -j ACCEPT +-A WHITELIST -s 172.16.0.0/12 -m comment --comment "RFC 1918" -j ACCEPT +-A WHITELIST -s 192.168.0.0/16 -m comment --comment "RFC 1918" -j ACCEPT COMMIT From 3200fc17e9fe7588aef60763a1038bf548e86df2 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 13 Feb 2020 23:01:34 +0100 Subject: [PATCH 28/37] Add nextcloud, backup, and ssh setup --- nextcloud/README.md | 41 ++++++++++++++++++++++++++ nextcloud/crontab | 2 ++ nextcloud/fpm.conf | 16 ++++++++++ nextcloud/local.config.php | 11 +++++++ nextcloud/nginx.conf | 36 ++++++++++++++++++++++ nextcloud/redis.conf | 2 ++ nginx/README.md | 19 ++++++++++++ nginx/conf.d/ssl.conf | 2 ++ nginx/sites-available/0nohost | 6 ++++ nginx/sites-available/redirect-ssl-all | 8 +++++ nginx/snippets/hsts | 1 + nginx/snippets/letsencrypt | 3 ++ nginx/snippets/redirect-ssl | 3 ++ restic/README.md | 20 +++++++++++++ restic/crontab | 2 ++ ssh/README.md | 15 ++++++++++ ssh/sshd_config | 13 ++++++++ 17 files changed, 200 insertions(+) create mode 100644 nextcloud/README.md create mode 100644 nextcloud/crontab create mode 100644 nextcloud/fpm.conf create mode 100644 nextcloud/local.config.php create mode 100644 nextcloud/nginx.conf create mode 100644 nextcloud/redis.conf create mode 100644 nginx/README.md create mode 100644 nginx/conf.d/ssl.conf create mode 100644 nginx/sites-available/0nohost create mode 100644 nginx/sites-available/redirect-ssl-all create mode 100644 nginx/snippets/hsts create mode 100644 nginx/snippets/letsencrypt create mode 100644 nginx/snippets/redirect-ssl create mode 100644 restic/README.md create mode 100644 restic/crontab create mode 100644 ssh/README.md create mode 100644 ssh/sshd_config diff --git a/nextcloud/README.md b/nextcloud/README.md new file mode 100644 index 0000000..69888f3 --- /dev/null +++ b/nextcloud/README.md @@ -0,0 +1,41 @@ +# Nextcloud + +## Create User + +```sh +sudo sed -i '$ a cloud:*:3000:3000::/data/cloud:/bin/sh' /etc/passwd +sudo sed -i '$ a cloud:x:3000:' /etc/group + +sudo mkdir -p /data/cloud +sudo chown cloud: /data/cloud +``` + +## Install Software + +```sh +PHPVERSION=x.x + +sudo apt install redis-server nginx php-redis php$PHPVERSION-{cli,curl,fpm,gd,intl,mbstring,sqlite3,xml,zip} + +wget https://download.nextcloud.com/server/releases/latest.zip +sudo -u cloud unzip -d /data/cloud ~/latest.zip +``` + +## Apply Configuration + +```sh +DOMAIN=example.com + +sudo cp nginx.conf /etc/nginx/sites-available/nextcloud +sudo cp fpm.conf /etc/php/*/fpm/pool.d/nextcloud.conf +sudo sed -i '$ r redis.conf' /etc/redis/redis.conf + +sudo -u cloud cp local.config.php /data/cloud/nextcloud/config +sudo -u cloud crontab crontab + +sudo ln -s ../sites-available/nextcloud /etc/nginx/sites-enabled +sudo sed -i s/example.com/$DOMAIN/ /etc/nginx/sites-available/nextcloud /data/cloud/nextcloud/config/local.config.php + +sudo -u cloud mkdir -p /data/cloud/.config/user-tmpfiles.d +echo 'e %h/data/*/files/tmp - - - 7d' | sudo -u cloud tee /data/cloud/.config/user-tmpfiles.d/nextcloud-tmp.conf +``` diff --git a/nextcloud/crontab b/nextcloud/crontab new file mode 100644 index 0000000..5775c87 --- /dev/null +++ b/nextcloud/crontab @@ -0,0 +1,2 @@ +*/5 * * * * php nextcloud/cron.php +15 3 * * * systemd-tmpfiles --clean --user diff --git a/nextcloud/fpm.conf b/nextcloud/fpm.conf new file mode 100644 index 0000000..0c01b9f --- /dev/null +++ b/nextcloud/fpm.conf @@ -0,0 +1,16 @@ +[cloud] + +user = cloud +group = cloud +listen = /run/nextcloud.sock + +listen.owner = www-data +listen.group = www-data + +env[PATH] = /usr/bin:/bin + +pm = ondemand +pm.max_children = 5 +pm.max_requests = 500 + +php_admin_value[memory_limit] = 512M diff --git a/nextcloud/local.config.php b/nextcloud/local.config.php new file mode 100644 index 0000000..554b3d4 --- /dev/null +++ b/nextcloud/local.config.php @@ -0,0 +1,11 @@ + [ 'cloud.example.com', '192.168.0.100:8080', 'localhost:8080' ], + 'versions_retention_obligation' => 'auto, 2', + 'trashbin_retention_obligation' => 'auto, 2', + 'memcache.local' => '\OC\Memcache\Redis', + 'memcache.distributed' => '\OC\Memcache\Redis', + 'memcache.locking' => '\OC\Memcache\Redis', + 'redis' => [ 'host' => '/run/redis/redis-server.sock', 'port' => 0 ], + 'filesystem_check_changes' => 1, + 'sqlite.journal_mode' => 'WAL', +]; diff --git a/nextcloud/nginx.conf b/nextcloud/nginx.conf new file mode 100644 index 0000000..15307c4 --- /dev/null +++ b/nextcloud/nginx.conf @@ -0,0 +1,36 @@ +server { + server_name cloud.example.com; + + listen 443 ssl; + + set $max_size 4G; + + root /data/cloud/nextcloud; + client_max_body_size 0; + + location / { + index index.php; + try_files $uri /index.php$request_uri; + } + + location ~ ^/console\.php { + deny all; + } + + location ~ ^(.+?\.php)(.*)$ { + fastcgi_split_path_info ^(.+?\.php)(.*)$; + fastcgi_pass unix:/run/nextcloud.sock; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param front_controller_active true; + fastcgi_param PHP_VALUE "upload_max_filesize=$max_size\n post_max_size=$max_size"; + include fastcgi.conf; + } + + location = /.well-known/carddav { + return 301 $scheme://$host:$server_port/remote.php/dav; + } + + location = /.well-known/caldav { + return 301 $scheme://$host:$server_port/remote.php/dav; + } +} diff --git a/nextcloud/redis.conf b/nextcloud/redis.conf new file mode 100644 index 0000000..ed8ff96 --- /dev/null +++ b/nextcloud/redis.conf @@ -0,0 +1,2 @@ +unixsocket /run/redis/redis-server.sock +unixsocketperm 777 diff --git a/nginx/README.md b/nginx/README.md new file mode 100644 index 0000000..d87501e --- /dev/null +++ b/nginx/README.md @@ -0,0 +1,19 @@ +# Nginx + +```sh +DOMAIN=example.com + +sudo cp -r sites-available snippets conf.d /etc/nginx + +sudo rm /etc/nginx/sites-*/default +sudo ln -s ../sites-available/0nohost /etc/nginx/sites-enabled +sudo ln -s ../sites-available/redirect-ssl-all /etc/nginx/sites-enabled + +sudo sed -i s/example.com/$DOMAIN/ /etc/nginx/conf.d/ssl.conf +``` + +## Certificate Reload + +```sh +nginx -s reload +``` diff --git a/nginx/conf.d/ssl.conf b/nginx/conf.d/ssl.conf new file mode 100644 index 0000000..c68755d --- /dev/null +++ b/nginx/conf.d/ssl.conf @@ -0,0 +1,2 @@ +ssl_certificate /data/ssl/certs/any.example.com/fullchain.pem; +ssl_certificate_key /data/ssl/certs/any.example.com/privkey.pem; diff --git a/nginx/sites-available/0nohost b/nginx/sites-available/0nohost new file mode 100644 index 0000000..e6350ab --- /dev/null +++ b/nginx/sites-available/0nohost @@ -0,0 +1,6 @@ +server { + listen 80 default_server; + listen 443 ssl default_server; + server_name _; + return 444; +} diff --git a/nginx/sites-available/redirect-ssl-all b/nginx/sites-available/redirect-ssl-all new file mode 100644 index 0000000..823d16d --- /dev/null +++ b/nginx/sites-available/redirect-ssl-all @@ -0,0 +1,8 @@ +server { + server_name .example.com; + + listen 80; + + include snippets/redirect-ssl; + include snippets/letsencrypt; +} diff --git a/nginx/snippets/hsts b/nginx/snippets/hsts new file mode 100644 index 0000000..07baaf3 --- /dev/null +++ b/nginx/snippets/hsts @@ -0,0 +1 @@ +add_header Strict-Transport-Security max-age=31536000; # 1yr diff --git a/nginx/snippets/letsencrypt b/nginx/snippets/letsencrypt new file mode 100644 index 0000000..ac12fe2 --- /dev/null +++ b/nginx/snippets/letsencrypt @@ -0,0 +1,3 @@ +location /.well-known/acme-challenge { + alias /data/ssl/challenge; +} diff --git a/nginx/snippets/redirect-ssl b/nginx/snippets/redirect-ssl new file mode 100644 index 0000000..385fb49 --- /dev/null +++ b/nginx/snippets/redirect-ssl @@ -0,0 +1,3 @@ +location / { + return 301 https://$host$request_uri; +} diff --git a/restic/README.md b/restic/README.md new file mode 100644 index 0000000..2f94664 --- /dev/null +++ b/restic/README.md @@ -0,0 +1,20 @@ +# Restic backups + +Download binary: +https://github.com/restic/restic/releases/latest + +```sh +REPO=sftp:backup-user@example.com:repo + +bunzip2 restic*.bz2 +sudo cp restic* /usr/local/bin/restic + +echo 'nice /usr/local/bin/restic -r' "$REPO" '-p /root/backup-key "$@"' | sudo tee /root/restic-cmd +sudo chmod +x /root/restic-cmd + +cat /dev/urandom | base64 | head -c 64 | sudo tee /root/backup-key +sudo chmod 600 /root/backup-key + +sudo /root/restic-cmd init +sudo crontab crontab +``` diff --git a/restic/crontab b/restic/crontab new file mode 100644 index 0000000..5d2bebc --- /dev/null +++ b/restic/crontab @@ -0,0 +1,2 @@ +48 * * * * /root/restic-cmd backup -q --exclude-if-present .nobackup /data +18 3 * * * /root/restic-cmd forget -q --keep-tag keep -H 24 -d 7 -m 12 -y 100 diff --git a/ssh/README.md b/ssh/README.md new file mode 100644 index 0000000..a0e5964 --- /dev/null +++ b/ssh/README.md @@ -0,0 +1,15 @@ +# SSH + +Use only one user `sshlogin` for logins to the server. +Switch to your main user with `su - adminuser` afterwards. + +```sh +sudo sed -i '$ a sshlogin:x:1001:65534::/home/sshlogin:/bin/sh' /etc/passwd +sudo sed -i '$ r sshd_config' /etc/ssh/sshd_config + +sudo mkdir -p /home/sshlogin/.ssh +sudo chown sshlogin:root /home/sshlogin/.ssh +``` + +* Either create a password with `sudo passwd sshlogin` or +* Add a key `sudo -u sshlogin editor /home/sshlogin/.ssh/authorized_keys` diff --git a/ssh/sshd_config b/ssh/sshd_config new file mode 100644 index 0000000..fb33505 --- /dev/null +++ b/ssh/sshd_config @@ -0,0 +1,13 @@ +UseDNS no +Port 22222 +AllowUsers sshlogin git backup-* +ClientAliveInterval 10 + +LoginGraceTime 10 +MaxAuthTries 2 + +Match User backup-* + ForceCommand internal-sftp + ChrootDirectory %h + X11Forwarding no + AllowTcpForwarding no From 694e6bf290b01d08a00249d2d0f3ea9b862542c6 Mon Sep 17 00:00:00 2001 From: Adrian Date: Mon, 17 Feb 2020 01:46:24 +0100 Subject: [PATCH 29/37] Add mail setup and named configuration --- inbucket/README.md | 36 ++++++++++++++++++++++++ inbucket/inbucket.conf | 9 ++++++ inbucket/inbucket.service | 11 ++++++++ inbucket/nginx.conf | 20 ++++++++++++++ mail/README.md | 49 +++++++++++++++++++++++++++++++++ mail/dkim.sql | 2 ++ mail/dovecot/local-sql.conf.ext | 9 ++++++ mail/dovecot/local.conf | 23 ++++++++++++++++ mail/opendkim/local.conf | 8 ++++++ mail/postfix/alias.cf | 2 ++ mail/postfix/domains.cf | 2 ++ mail/postfix/login.cf | 2 ++ mail/postfix/main.cf | 39 ++++++++++++++++++++++++++ mail/postfix/relay.cf | 2 ++ mail/postfix/transport.cf | 2 ++ mail/postfix/virtual.cf | 2 ++ mail/schema.sql | 6 ++++ named/README.md | 19 +++++++++++++ named/badlist-active.zone | 8 ++++++ named/badlist-inactive.zone | 3 ++ named/options.conf | 3 ++ named/zones.conf | 1 + 22 files changed, 258 insertions(+) create mode 100644 inbucket/README.md create mode 100644 inbucket/inbucket.conf create mode 100644 inbucket/inbucket.service create mode 100644 inbucket/nginx.conf create mode 100644 mail/README.md create mode 100644 mail/dkim.sql create mode 100644 mail/dovecot/local-sql.conf.ext create mode 100644 mail/dovecot/local.conf create mode 100644 mail/opendkim/local.conf create mode 100644 mail/postfix/alias.cf create mode 100644 mail/postfix/domains.cf create mode 100644 mail/postfix/login.cf create mode 100644 mail/postfix/main.cf create mode 100644 mail/postfix/relay.cf create mode 100644 mail/postfix/transport.cf create mode 100644 mail/postfix/virtual.cf create mode 100644 mail/schema.sql create mode 100644 named/README.md create mode 100644 named/badlist-active.zone create mode 100644 named/badlist-inactive.zone create mode 100644 named/options.conf create mode 100644 named/zones.conf diff --git a/inbucket/README.md b/inbucket/README.md new file mode 100644 index 0000000..e190c48 --- /dev/null +++ b/inbucket/README.md @@ -0,0 +1,36 @@ +# Inbucket + +To be used together with the [`mail`](../mail) setup. + +## Install Software + +Get: https://www.inbucket.org/binaries/ + +```sh +cd /usr/local/share +sudo tar -xf ~/inbucket_* +sudo ln -s inbucket_* inbucket +sudo ln -s ../share/inbucket/inbucket /usr/local/bin +sudo ln -s ../share/inbucket/inbucket-client /usr/local/bin +``` + +## Apply Configuration + +```sh +DOMAIN=test.local + +sudo cp inbucket.service /etc/systemd/system +sudo cp nginx.conf /etc/nginx/sites-available/inbucket +sudo -u vmail cp inbucket.conf /data/mail/config + +sudo ln -s ../sites-available/inbucket /etc/nginx/sites-enabled +sudo sed -i s/example.com/$DOMAIN/ /etc/nginx/sites-available/inbucket + +echo "inbucket:$(openssl passwd -5)" | sudo -u vmail tee /data/mail/config/inbucket.htpasswd +sudo chown vmail:www-data /data/mail/config/inbucket.htpasswd +sudo chmod 640 /data/mail/config/inbucket.htpasswd + +echo "insert into domain (domain, transport) values ('$DOMAIN','smtp:[localhost]:2500')" | sudo -u vmail sqlite3 /data/mail/config/vmail.db + +sudo systemctl enable inbucket +``` diff --git a/inbucket/inbucket.conf b/inbucket/inbucket.conf new file mode 100644 index 0000000..8a1817a --- /dev/null +++ b/inbucket/inbucket.conf @@ -0,0 +1,9 @@ +INBUCKET_LOGLEVEL=warn +INBUCKET_MAILBOXNAMING=full +INBUCKET_WEB_ADDR=0.0.0.0:8025 +INBUCKET_WEB_UIDIR=/usr/local/share/inbucket/ui +INBUCKET_WEB_GREETINGFILE=/usr/local/share/inbucket/ui/greeting.html +INBUCKET_STORAGE_TYPE=file +INBUCKET_STORAGE_PARAMS=path:/data/mail +INBUCKET_STORAGE_RETENTIONPERIOD=0 +INBUCKET_STORAGE_MAILBOXMSGCAP=0 diff --git a/inbucket/inbucket.service b/inbucket/inbucket.service new file mode 100644 index 0000000..5f1d255 --- /dev/null +++ b/inbucket/inbucket.service @@ -0,0 +1,11 @@ +[Unit] +Description=Inbucket +After=network.target + +[Service] +ExecStart=/usr/local/bin/inbucket +EnvironmentFile=/data/mail/config/inbucket.conf +User=vmail + +[Install] +WantedBy=multi-user.target diff --git a/inbucket/nginx.conf b/inbucket/nginx.conf new file mode 100644 index 0000000..ff52ffd --- /dev/null +++ b/inbucket/nginx.conf @@ -0,0 +1,20 @@ +server { + server_name mail.example.com; + + listen 443 ssl; + + auth_basic "Mail"; + auth_basic_user_file /data/mail/config/inbucket.htpasswd; + + location / { + proxy_pass http://localhost:8025; + include proxy_params; + } + + location /api { + proxy_pass http://localhost:8025; + include proxy_params; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } +} diff --git a/mail/README.md b/mail/README.md new file mode 100644 index 0000000..1119549 --- /dev/null +++ b/mail/README.md @@ -0,0 +1,49 @@ +# Mail with SQLite + +## Create User + +```sh +sudo sed -i '$ a vmail:*:2000:2000::/data/mail:/usr/sbin/nologin' /etc/passwd +sudo sed -i '$ a vmail:x:2000:' /etc/group + +sudo mkdir -p /data/mail/mail +sudo mkdir -p /data/mail/config +sudo chown vmail: /data/mail/* + +cat schema.sql | sudo -u vmail sqlite3 /data/mail/config/vmail.db +sudo chmod 640 /data/mail/config/vmail.db +``` + +## Install Software + +```sh +sudo apt install sqlite3 postfix postfix-sqlite dovecot-imapd dovecot-sqlite opendkim libopendbx1-sqlite3 +``` + +## Apply Configuration + +```sh +DOMAIN=example.com + +sudo cp -r postfix dovecot /etc +sudo sed -i '$ r opendkim/local.conf' /etc/opendkim.conf +sudo sed -i s/example.com/$DOMAIN/ /etc/postfix/main.cf /etc/dovecot/local.conf +sudo sed -i '/include auth-system/ s/.*/#&/' /etc/dovecot/conf.d/10-auth.conf + +sudo ln -s /data/mail/config/vmail.db /.opendkim-bug-241.db +sudo chown vmail:postfix /data/mail/config/vmail.db + +opendkim-genkey -d $DOMAIN -s s +chmod +r s.private +cat dkim.sql | sed s/DOMAIN/$DOMAIN/ | sudo -u vmail sqlite3 /data/mail/config/vmail.db +cat s.txt +rm s.private s.txt +``` + +## Notes + +* The `vmail.db` parent directory needs to be writeable by the user modifying the database +* The postfix process does not load the supplementary groups (`set_eugid` only sets one gid), + hence the vmail database needs to be readable by the postfix primary group +* The dovecot process runs as root and can access the database +* OpenDKIM's `dsn` parsing is broken and opens the database in the root directory diff --git a/mail/dkim.sql b/mail/dkim.sql new file mode 100644 index 0000000..c0e58e8 --- /dev/null +++ b/mail/dkim.sql @@ -0,0 +1,2 @@ +insert into dkim (match, key) values ("DOMAIN", "default"); +insert into dkim_key (key, domain, selector, private_key) values ("default", "DOMAIN", "s", readfile("s.private")); diff --git a/mail/dovecot/local-sql.conf.ext b/mail/dovecot/local-sql.conf.ext new file mode 100644 index 0000000..ee22dec --- /dev/null +++ b/mail/dovecot/local-sql.conf.ext @@ -0,0 +1,9 @@ +driver = sqlite +connect = /data/mail/config/vmail.db + +user_query = SELECT \ + REPLACE('/data/mail/mail/{dir}', '{dir}', maildir) AS home \ + , REPLACE('maildir:/data/mail/mail/{dir}:LAYOUT=fs', '{dir}', maildir) AS mail \ + FROM mailbox WHERE username = '%u' AND active = 1 + +password_query = SELECT password FROM mailbox WHERE username = '%u' diff --git a/mail/dovecot/local.conf b/mail/dovecot/local.conf new file mode 100644 index 0000000..fd9ce3e --- /dev/null +++ b/mail/dovecot/local.conf @@ -0,0 +1,23 @@ +protocols = imap +mail_uid = vmail +mail_gid = vmail + +ssl = required +ssl_key = Date: Sat, 22 Feb 2020 14:20:30 +0100 Subject: [PATCH 30/37] Add NetworkManager configuration --- network-manager/99-no-wifi-on-ethernet | 11 +++++++++++ network-manager/README.md | 13 +++++++++++++ 2 files changed, 24 insertions(+) create mode 100755 network-manager/99-no-wifi-on-ethernet create mode 100644 network-manager/README.md diff --git a/network-manager/99-no-wifi-on-ethernet b/network-manager/99-no-wifi-on-ethernet new file mode 100755 index 0000000..fa44a2f --- /dev/null +++ b/network-manager/99-no-wifi-on-ethernet @@ -0,0 +1,11 @@ +#!/bin/sh + +logger -t no-wifi-on-ethernet "Device $1 is $2" + +if [ "dev:$1:$2" = "dev:eth0:up" ]; then + nmcli r wifi off +fi + +if [ "dev:$1:$2" = "dev:eth0:down" ]; then + nmcli r wifi on +fi diff --git a/network-manager/README.md b/network-manager/README.md new file mode 100644 index 0000000..6e60a35 --- /dev/null +++ b/network-manager/README.md @@ -0,0 +1,13 @@ +# NetworkManager + +## Manage ethernet devices with NetworkManager + +```sh +touch /etc/NetworkManager/conf.d/10-globally-managed-devices.conf +``` + +## Automatically switch off wifi when ethernet is connected + +```sh +sudo cp 99-no-wifi-on-ethernet /etc/NetworkManager/dispatcher.d +``` From 7ad59d276e25045175b10fb55d671816b1156918 Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 26 Feb 2020 01:14:32 +0100 Subject: [PATCH 31/37] Add iptables, gitea, and iodine services --- gitea/README.md | 43 +++++++++++++++++++++++++++++++++++++++ gitea/gitea.service | 10 +++++++++ gitea/nginx.conf | 10 +++++++++ iodine/README.md | 36 ++++++++++++++++++++++++++++++++ iodine/my-iodined.conf | 2 ++ iodine/my-iodined.service | 11 ++++++++++ iptables/README.md | 33 ++++++++++++++++++++++++++++++ iptables/default.rules | 15 ++++++++++++++ iptables/empty.rules | 11 ++++++++++ iptables/iptables.service | 13 ++++++++++++ iptables/ratelimit.rules | 16 +++++++++++++++ 11 files changed, 200 insertions(+) create mode 100644 gitea/README.md create mode 100644 gitea/gitea.service create mode 100644 gitea/nginx.conf create mode 100644 iodine/README.md create mode 100644 iodine/my-iodined.conf create mode 100644 iodine/my-iodined.service create mode 100644 iptables/README.md create mode 100644 iptables/default.rules create mode 100644 iptables/empty.rules create mode 100644 iptables/iptables.service create mode 100644 iptables/ratelimit.rules diff --git a/gitea/README.md b/gitea/README.md new file mode 100644 index 0000000..6fbb691 --- /dev/null +++ b/gitea/README.md @@ -0,0 +1,43 @@ +# Gitea + +## Create User + +```sh +sudo sed -i '$ a git:*:2050:2050::/data/git:/bin/sh' /etc/passwd +sudo sed -i '$ a git:x:2050:' /etc/group + +sudo mkdir -p /data/git/gitea +sudo chown -R git: /data/git +``` + +## Install Software + +```sh +sudo apt install git +sudo -u git wget -O /data/git/gitea/gitea https://dl.gitea.io/gitea/... +sudo -u git chmod +x /data/git/gitea/gitea +``` + +## Apply Configuration + +```sh +DOMAIN=example.com + +sudo cp nginx.conf /etc/nginx/sites-available/git +sudo cp gitea.service /etc/systemd/system + +sudo systemctl enable gitea +sudo systemctl start gitea + +sudo sed -i s/example.com/$DOMAIN/ /etc/nginx/sites-available/git + +sudo ln -s ../sites-available/git /etc/nginx/sites-enabled +sudo nginx -s reload + + +sudo iptables -t nat -A PREROUTING -p tcp --dport 4986 -j REDIRECT --to-ports 22222 + +sudo -u git sed -i /MODE.*file/s/file/console/ /data/git/gitea/custom/conf/app.ini +sudo -u git sed -i /LEVEL.*info/s/info/warn/ /data/git/gitea/custom/conf/app.ini +sudo -u git /data/git/gitea/gitea admin create-user --username admin --password admin --admin --email admin +``` diff --git a/gitea/gitea.service b/gitea/gitea.service new file mode 100644 index 0000000..4bc4533 --- /dev/null +++ b/gitea/gitea.service @@ -0,0 +1,10 @@ +[Unit] +Description=Gitea +After=network.target + +[Service] +ExecStart=/data/git/gitea/gitea web +User=git + +[Install] +WantedBy=multi-user.target diff --git a/gitea/nginx.conf b/gitea/nginx.conf new file mode 100644 index 0000000..b0af6b5 --- /dev/null +++ b/gitea/nginx.conf @@ -0,0 +1,10 @@ +server { + server_name git.example.com; + + listen 443 ssl; + + location / { + proxy_pass http://localhost:3000; + include proxy_params; + } +} diff --git a/iodine/README.md b/iodine/README.md new file mode 100644 index 0000000..3c2d6bb --- /dev/null +++ b/iodine/README.md @@ -0,0 +1,36 @@ +# Iodine + +## Install Software + +```sh +sudo apt install iodine +``` + +## Apply Configuration + +```sh +EXTERNAL=eth0 +INTERNAL=dns0 + +echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward +echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/60-ipv4-forward.conf + +sudo iptables -t nat -A POSTROUTING -o $EXTERNAL -j MASQUERADE +sudo iptables -A INPUT -p udp --dport 5353 -j ACCEPT +sudo iptables -A INPUT -i $INTERNAL -j ACCEPT + +# Necessary only if default policy is not ACCEPT +sudo iptables -A FORWARD -i $EXTERNAL -o $INTERNAL -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i $INTERNAL -o $EXTERNAL -j ACCEPT + +# Adjust domain: +sudo iptables -t nat -A PREROUTING -p udp --dport 53 -m string --hex-string "|01|t|07|example|03|com|00|" --algo bm --from 20 --to 65535 -j REDIRECT --to-ports 5353 + +sudo cp my-iodined.service /etc/systemd/system +sudo cp my-iodined.conf /etc +sudo chmod 600 /etc/my-iodined.conf + +sudo editor /etc/my-iodined.conf +sudo systemctl enable my-iodined +sudo systemctl start my-iodined +``` diff --git a/iodine/my-iodined.conf b/iodine/my-iodined.conf new file mode 100644 index 0000000..d454d38 --- /dev/null +++ b/iodine/my-iodined.conf @@ -0,0 +1,2 @@ +IODINED_OPTS="-c -p 5353 192.168.100.1 t.example.com" +IODINED_PASS=secret diff --git a/iodine/my-iodined.service b/iodine/my-iodined.service new file mode 100644 index 0000000..953abfc --- /dev/null +++ b/iodine/my-iodined.service @@ -0,0 +1,11 @@ +[Unit] +Description=Iodine +After=network-online.target + +[Service] +EnvironmentFile=/etc/my-iodined.conf +ExecStartPre=mkdir -p /run/iodined +ExecStart=iodined -f -u nobody -t /run/iodined $IODINED_OPTS + +[Install] +WantedBy=multi-user.target diff --git a/iptables/README.md b/iptables/README.md new file mode 100644 index 0000000..3e2a65d --- /dev/null +++ b/iptables/README.md @@ -0,0 +1,33 @@ +# Iptables + +```sh +sudo cp *.rules /etc +sudo cp *.service /etc/systemd/system +sudo systemctl enable iptables +``` + +## Apply and Report Rate Limits + +The `ratelimit.rules` file adds new chains to rate limit subnets. + +```sh +sudo iptables-restore -n < ratelimit.rules + +# Common offenders +sudo iptables -t raw -A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_DEFAULT +sudo iptables -t raw -A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_DEFAULT +sudo iptables -t raw -A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_DEFAULT + +# Default action +sudo iptables -t raw -A RATELIMIT_DEFAULT -p tcp --tcp-flags SYN,ACK SYN \ + -m hashlimit --hashlimit-name drop_4h \ + --hashlimit-above 4/hour --hashlimit-burst 2 \ + --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j DROP + +# Log potential offenders +sudo iptables -t raw -A RATELIMIT_REPORT -p tcp --tcp-flags SYN,ACK SYN \ + -m hashlimit --hashlimit-name report1 \ + --hashlimit-above 1/second --hashlimit-burst 4 \ + --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j LOG \ + --log-level 5 --log-prefix "ratelimit report1 " +``` diff --git a/iptables/default.rules b/iptables/default.rules new file mode 100644 index 0000000..f6c250b --- /dev/null +++ b/iptables/default.rules @@ -0,0 +1,15 @@ +*filter +:INPUT DROP +:CONNECTION - +:SERVICE - +-A INPUT -j CONNECTION +-A INPUT -j SERVICE +-A CONNECTION -i lo -j ACCEPT +-A CONNECTION -m state --state RELATED,ESTABLISHED -j ACCEPT +-A SERVICE -p tcp --dport 25 -j ACCEPT +-A SERVICE -p tcp --dport 80 -j ACCEPT +-A SERVICE -p tcp --dport 143 -j ACCEPT +-A SERVICE -p tcp --dport 443 -j ACCEPT +-A SERVICE -p tcp --dport 22222 -j ACCEPT +-A SERVICE -p udp --dport 53 -j ACCEPT +COMMIT diff --git a/iptables/empty.rules b/iptables/empty.rules new file mode 100644 index 0000000..7a7d32c --- /dev/null +++ b/iptables/empty.rules @@ -0,0 +1,11 @@ +*filter +:INPUT ACCEPT +COMMIT +*nat +COMMIT +*mangle +COMMIT +*raw +COMMIT +*security +COMMIT diff --git a/iptables/iptables.service b/iptables/iptables.service new file mode 100644 index 0000000..45847f3 --- /dev/null +++ b/iptables/iptables.service @@ -0,0 +1,13 @@ +[Unit] +Description=iptables +Before=network-pre.target +Wants=network-pre.target + +[Service] +Type=oneshot +ExecStart=iptables-restore /etc/default.rules +ExecStop=iptables-restore /etc/empty.rules +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/iptables/ratelimit.rules b/iptables/ratelimit.rules new file mode 100644 index 0000000..e7dfdc9 --- /dev/null +++ b/iptables/ratelimit.rules @@ -0,0 +1,16 @@ +*raw +:RATELIMIT - +:RATELIMIT_REPORT - +:RATELIMIT_SUBNET - +:RATELIMIT_DEFAULT - + +-I PREROUTING -j RATELIMIT + +-A RATELIMIT -s 127.0.0.0/8 -j RETURN +-A RATELIMIT -s 10.0.0.0/8 -j RETURN +-A RATELIMIT -s 172.16.0.0/12 -j RETURN +-A RATELIMIT -s 192.168.0.0/16 -j RETURN +-A RATELIMIT -j RATELIMIT_SUBNET +-A RATELIMIT -j RATELIMIT_REPORT + +COMMIT From e60d9c0c59d2dc532dec89c785cf6dbb6451fe91 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sat, 7 Mar 2020 09:24:38 +0100 Subject: [PATCH 32/37] Add robots exception for gitea --- gitea/nginx.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gitea/nginx.conf b/gitea/nginx.conf index b0af6b5..56a0b41 100644 --- a/gitea/nginx.conf +++ b/gitea/nginx.conf @@ -7,4 +7,6 @@ server { proxy_pass http://localhost:3000; include proxy_params; } + + location = /robots.txt { return 200 "User-agent: *\nDisallow: */commit/*\n"; } } From 6f80b8345d5d3acd0dea01c4470e26a92e21bb80 Mon Sep 17 00:00:00 2001 From: Adrian Date: Sat, 7 Mar 2020 09:24:38 +0100 Subject: [PATCH 33/37] Update iptables --- iptables/README.md | 21 ++------------------- iptables/ratelimit.rules | 12 ++++++++++-- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/iptables/README.md b/iptables/README.md index 3e2a65d..fc67e5c 100644 --- a/iptables/README.md +++ b/iptables/README.md @@ -8,26 +8,9 @@ sudo systemctl enable iptables ## Apply and Report Rate Limits -The `ratelimit.rules` file adds new chains to rate limit subnets. +The `ratelimit.rules` file adds new chains to +limit the rate of new connections based on /16 subnets. ```sh sudo iptables-restore -n < ratelimit.rules - -# Common offenders -sudo iptables -t raw -A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_DEFAULT -sudo iptables -t raw -A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_DEFAULT -sudo iptables -t raw -A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_DEFAULT - -# Default action -sudo iptables -t raw -A RATELIMIT_DEFAULT -p tcp --tcp-flags SYN,ACK SYN \ - -m hashlimit --hashlimit-name drop_4h \ - --hashlimit-above 4/hour --hashlimit-burst 2 \ - --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j DROP - -# Log potential offenders -sudo iptables -t raw -A RATELIMIT_REPORT -p tcp --tcp-flags SYN,ACK SYN \ - -m hashlimit --hashlimit-name report1 \ - --hashlimit-above 1/second --hashlimit-burst 4 \ - --hashlimit-mode srcip,dstport --hashlimit-srcmask 16 -j LOG \ - --log-level 5 --log-prefix "ratelimit report1 " ``` diff --git a/iptables/ratelimit.rules b/iptables/ratelimit.rules index e7dfdc9..db4319f 100644 --- a/iptables/ratelimit.rules +++ b/iptables/ratelimit.rules @@ -1,10 +1,10 @@ *raw :RATELIMIT - +:RATELIMIT_ENFORCE - :RATELIMIT_REPORT - :RATELIMIT_SUBNET - -:RATELIMIT_DEFAULT - --I PREROUTING -j RATELIMIT +-I PREROUTING -p tcp --tcp-flags SYN,ACK SYN -j RATELIMIT -A RATELIMIT -s 127.0.0.0/8 -j RETURN -A RATELIMIT -s 10.0.0.0/8 -j RETURN @@ -13,4 +13,12 @@ -A RATELIMIT -j RATELIMIT_SUBNET -A RATELIMIT -j RATELIMIT_REPORT +-A RATELIMIT_ENFORCE -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 2 --hashlimit-mode srcip,dstport --hashlimit-name enforce --hashlimit-srcmask 16 -j DROP + +-A RATELIMIT_REPORT -m hashlimit --hashlimit-above 1/min --hashlimit-burst 6 --hashlimit-mode srcip,dstport --hashlimit-name report1 --hashlimit-srcmask 16 -j LOG --log-prefix "ratelimit report1 " --log-level 5 + +-A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_ENFORCE +-A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_ENFORCE +-A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_ENFORCE + COMMIT From adde853701aec0d11e171327f6f25f83a791b6dd Mon Sep 17 00:00:00 2001 From: Adrian Date: Mon, 13 Apr 2020 21:10:11 +0200 Subject: [PATCH 34/37] Add postfix SNI support --- mail/README.md | 12 ++++++++++-- mail/postfix/main.cf | 1 + mail/postfix/sni.cf | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 mail/postfix/sni.cf diff --git a/mail/README.md b/mail/README.md index 1119549..7945019 100644 --- a/mail/README.md +++ b/mail/README.md @@ -11,6 +11,7 @@ sudo mkdir -p /data/mail/config sudo chown vmail: /data/mail/* cat schema.sql | sudo -u vmail sqlite3 /data/mail/config/vmail.db +sudo chown vmail:postfix /data/mail/config/vmail.db sudo chmod 640 /data/mail/config/vmail.db ``` @@ -26,12 +27,13 @@ sudo apt install sqlite3 postfix postfix-sqlite dovecot-imapd dovecot-sqlite ope DOMAIN=example.com sudo cp -r postfix dovecot /etc +sudo chmod 600 /etc/postfix/sni.cf + sudo sed -i '$ r opendkim/local.conf' /etc/opendkim.conf -sudo sed -i s/example.com/$DOMAIN/ /etc/postfix/main.cf /etc/dovecot/local.conf +sudo sed -i s/example.com/$DOMAIN/ /etc/postfix/{main,sni}.cf /etc/dovecot/local.conf sudo sed -i '/include auth-system/ s/.*/#&/' /etc/dovecot/conf.d/10-auth.conf sudo ln -s /data/mail/config/vmail.db /.opendkim-bug-241.db -sudo chown vmail:postfix /data/mail/config/vmail.db opendkim-genkey -d $DOMAIN -s s chmod +r s.private @@ -40,6 +42,12 @@ cat s.txt rm s.private s.txt ``` +## Certificate Reload + +```sh +postmap -F /etc/postfix/sni.cf +``` + ## Notes * The `vmail.db` parent directory needs to be writeable by the user modifying the database diff --git a/mail/postfix/main.cf b/mail/postfix/main.cf index 4b2e97f..66b0ba0 100644 --- a/mail/postfix/main.cf +++ b/mail/postfix/main.cf @@ -14,6 +14,7 @@ smtp_tls_security_level = may smtpd_tls_security_level = may smtpd_tls_key_file = /data/ssl/certs/mail.example.com/privkey.pem smtpd_tls_cert_file = /data/ssl/certs/mail.example.com/fullchain.pem +tls_server_sni_maps = hash:/etc/postfix/sni.cf # Custom diff --git a/mail/postfix/sni.cf b/mail/postfix/sni.cf new file mode 100644 index 0000000..e9ae8a0 --- /dev/null +++ b/mail/postfix/sni.cf @@ -0,0 +1 @@ +mail.example.com /data/ssl/certs/mail.example.com/privkey.pem /data/ssl/certs/mail.example.com/fullchain.pem From f5c807633bd32e0824e506fee051b52accf96c46 Mon Sep 17 00:00:00 2001 From: Adrian Date: Tue, 14 Apr 2020 00:43:49 +0200 Subject: [PATCH 35/37] Improve iptables ratelimit rules --- iptables/ratelimit.rules | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/iptables/ratelimit.rules b/iptables/ratelimit.rules index db4319f..c5dc31a 100644 --- a/iptables/ratelimit.rules +++ b/iptables/ratelimit.rules @@ -1,24 +1,23 @@ *raw +:BLOCK - :RATELIMIT - -:RATELIMIT_ENFORCE - -:RATELIMIT_REPORT - -:RATELIMIT_SUBNET - +:WHITELIST - --I PREROUTING -p tcp --tcp-flags SYN,ACK SYN -j RATELIMIT +-A PREROUTING -j WHITELIST +-A PREROUTING -j BLOCK +-A PREROUTING -p tcp -m tcp --tcp-flags SYN,ACK SYN -j RATELIMIT --A RATELIMIT -s 127.0.0.0/8 -j RETURN --A RATELIMIT -s 10.0.0.0/8 -j RETURN --A RATELIMIT -s 172.16.0.0/12 -j RETURN --A RATELIMIT -s 192.168.0.0/16 -j RETURN --A RATELIMIT -j RATELIMIT_SUBNET --A RATELIMIT -j RATELIMIT_REPORT +-A BLOCK -s 46.229.160.0/20 -m comment --comment SEMrushBot -j DROP +-A BLOCK -s 114.119.160.0/21 -m comment --comment AspiegelBot -j DROP --A RATELIMIT_ENFORCE -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 2 --hashlimit-mode srcip,dstport --hashlimit-name enforce --hashlimit-srcmask 16 -j DROP +-A RATELIMIT -p tcp -m tcp --dport 22222 -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 2 --hashlimit-mode srcip --hashlimit-name ratelimit-ssh --hashlimit-srcmask 16 -j DROP +-A RATELIMIT -p tcp -m tcp --dport 25 -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 4 --hashlimit-mode srcip --hashlimit-name ratelimit-smtp --hashlimit-srcmask 16 -j DROP +-A RATELIMIT -p tcp -m tcp --dport 143 -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 4 --hashlimit-mode srcip --hashlimit-name ratelimit-imap --hashlimit-srcmask 16 -j DROP +-A RATELIMIT -m hashlimit --hashlimit-above 4/hour --hashlimit-burst 16 --hashlimit-mode srcip,dstport --hashlimit-name ratelimit-other --hashlimit-srcmask 16 -j DROP --A RATELIMIT_REPORT -m hashlimit --hashlimit-above 1/min --hashlimit-burst 6 --hashlimit-mode srcip,dstport --hashlimit-name report1 --hashlimit-srcmask 16 -j LOG --log-prefix "ratelimit report1 " --log-level 5 - --A RATELIMIT_SUBNET -s 185.0.0.0/8 -j RATELIMIT_ENFORCE --A RATELIMIT_SUBNET -s 45.0.0.0/8 -j RATELIMIT_ENFORCE --A RATELIMIT_SUBNET -s 193.0.0.0/8 -j RATELIMIT_ENFORCE +-A WHITELIST -s 127.0.0.0/8 -m comment --comment localhost -j ACCEPT +-A WHITELIST -s 10.0.0.0/8 -m comment --comment "RFC 1918" -j ACCEPT +-A WHITELIST -s 172.16.0.0/12 -m comment --comment "RFC 1918" -j ACCEPT +-A WHITELIST -s 192.168.0.0/16 -m comment --comment "RFC 1918" -j ACCEPT COMMIT From 06d05bc46fec31c611e7e64ba61efaf3e7d72943 Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 15 Apr 2020 23:22:14 +0200 Subject: [PATCH 36/37] Fix unprocessed index directives --- nextcloud/nginx.conf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nextcloud/nginx.conf b/nextcloud/nginx.conf index 15307c4..8030b02 100644 --- a/nextcloud/nginx.conf +++ b/nextcloud/nginx.conf @@ -9,7 +9,6 @@ server { client_max_body_size 0; location / { - index index.php; try_files $uri /index.php$request_uri; } @@ -26,6 +25,10 @@ server { include fastcgi.conf; } + location /updater { index index.php; } + location /ocm-provider { index index.php; } + location /ocs-provider { index index.php; } + location = /.well-known/carddav { return 301 $scheme://$host:$server_port/remote.php/dav; } From 8a751571b78096dac8c3cb69bd3f5be8de49ac7c Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 16 Apr 2020 23:45:18 +0200 Subject: [PATCH 37/37] Add dyndns and letsencrypt helpers --- dyndns/README.md | 16 +++++++++++++++ dyndns/dyndns-nsupdate | 10 +++++++++ dyndns/dyndns-update | 19 +++++++++++++++++ dyndns/example.com.nsupdate.txt | 12 +++++++++++ dyndns/tsig.example.com.conf | 4 ++++ dyndns/update-example.com.sh | 7 +++++++ letsencrypt/README.md | 36 +++++++++++++++++++++++++++++++++ letsencrypt/config | 5 +++++ letsencrypt/dehydrated-manual | 11 ++++++++++ letsencrypt/dehydrated-nsupdate | 24 ++++++++++++++++++++++ letsencrypt/example-hook | 7 +++++++ 11 files changed, 151 insertions(+) create mode 100644 dyndns/README.md create mode 100755 dyndns/dyndns-nsupdate create mode 100755 dyndns/dyndns-update create mode 100644 dyndns/example.com.nsupdate.txt create mode 100644 dyndns/tsig.example.com.conf create mode 100755 dyndns/update-example.com.sh create mode 100644 letsencrypt/README.md create mode 100644 letsencrypt/config create mode 100755 letsencrypt/dehydrated-manual create mode 100755 letsencrypt/dehydrated-nsupdate create mode 100644 letsencrypt/example-hook diff --git a/dyndns/README.md b/dyndns/README.md new file mode 100644 index 0000000..21e1264 --- /dev/null +++ b/dyndns/README.md @@ -0,0 +1,16 @@ +# Dynamic DNS + +Edit example files to match your needs. + +```sh +sudo mkdir /data/dns +cp *example* dyndns* /data/dns + +chmod 600 /data/dns/tsig* +``` + +## Cronjob + +```sh +/data/dns/update-example.com.sh +``` diff --git a/dyndns/dyndns-nsupdate b/dyndns/dyndns-nsupdate new file mode 100755 index 0000000..1876f7c --- /dev/null +++ b/dyndns/dyndns-nsupdate @@ -0,0 +1,10 @@ +#!/bin/sh + +DYN_DIR=/data/dns + +if test "x$DYN_TSIGKEY" = x; then DYN_TSIGKEY="$DYN_DIR/tsig.$DYN_DOMAIN.conf"; fi +if test "x$DYN_NSUPDATE" = x; then DYN_NSUPDATE="$DYN_DIR/$DYN_DOMAIN.nsupdate.txt"; fi + +if test "x$1" != x; then + cat "$DYN_NSUPDATE" | sed s/%IP%/$1/g | nsupdate -v -k "$DYN_TSIGKEY" +fi diff --git a/dyndns/dyndns-update b/dyndns/dyndns-update new file mode 100755 index 0000000..2eb07c8 --- /dev/null +++ b/dyndns/dyndns-update @@ -0,0 +1,19 @@ +#!/bin/sh + +if test "x$DYN_SERVER" = x; then echo export DYN_SERVER=ns.example.com; exit=1; fi +if test "x$DYN_DOMAIN" = x; then echo export DYN_DOMAIN=example.com; exit=1; fi +if test "x$DYN_SCRIPT" = x; then echo export DYN_SCRIPT=/path/to/script; exit=1; fi +if test "x$exit" = x1; then exit 1; fi + +if test "x$DYN_IPAPI" = x; then DYN_IPAPI=ifconfig.co; fi + +IPACTUAL=$(wget -qO - "$DYN_IPAPI") +IPSERVER=$(dig +short $DYN_DOMAIN @$DYN_SERVER) + +if test "x$IPSERVER" = x -o "x$IPACTUAL" = x; then + : # ERROR: IP unknown +elif test "x$IPSERVER" = "x$IPACTUAL"; then + : # INFO: IP not changed +else + "$DYN_SCRIPT" $IPACTUAL +fi diff --git a/dyndns/example.com.nsupdate.txt b/dyndns/example.com.nsupdate.txt new file mode 100644 index 0000000..8153944 --- /dev/null +++ b/dyndns/example.com.nsupdate.txt @@ -0,0 +1,12 @@ +server ns01.example.com +zone example.com + +update del example.com. TXT +update del example.com. A +update del *.example.com. A + +update add example.com. 86400 TXT "v=spf1 ip4:%IP%/32 -all" +update add example.com. 86400 A %IP% +update add *.example.com. 86400 A %IP% + +send diff --git a/dyndns/tsig.example.com.conf b/dyndns/tsig.example.com.conf new file mode 100644 index 0000000..1cea1d4 --- /dev/null +++ b/dyndns/tsig.example.com.conf @@ -0,0 +1,4 @@ +key "tsig.example.com." { + algorithm hmac-sha256; + secret "YWRyaXVtLmFkcml1bS4uCg=="; +}; diff --git a/dyndns/update-example.com.sh b/dyndns/update-example.com.sh new file mode 100755 index 0000000..e30dd4e --- /dev/null +++ b/dyndns/update-example.com.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +export DYN_DOMAIN=example.com +export DYN_SERVER=ns01.example.com +export DYN_SCRIPT=/data/dns/dyndns-nsupdate + +/data/dns/dyndns-update diff --git a/letsencrypt/README.md b/letsencrypt/README.md new file mode 100644 index 0000000..c1f3f51 --- /dev/null +++ b/letsencrypt/README.md @@ -0,0 +1,36 @@ +# Let's Encrypt + +Download Let's Encrypt client (only `dehydrated` needed): +https://github.com/dehydrated-io/dehydrated/releases/latest + +```sh +sudo mkdir -p /data/ssl/{configs,challenge} +sudo chown -R admin: /data/ssl + +cp config dehydrated-* /data/ssl + +# List all domains for automatic renewal +editor /data/ssl/domains.txt + +/data/ssl/dehydrated -r +``` + +To enable certificate renewal, +`include snippets/letsencrypt` or put `redirect-ssl-all` in sites-enabled. + +## Cronjob + +```sh +/data/ssl/dehydrated -c +``` + +## Wildcard Certificates + +```sh +echo "service.example.com *.service.example.com" >> /data/ssl/domains.txt +echo "CHALLENGETYPE=dns-01" >> /data/ssl/configs/service.example.com +echo "HOOK=/data/ssl/dehydrated-hook" >> /data/ssl/configs/service.example.com +``` + +There are manual and nsupdate hooks. +See [example-hook](example-hook) for an example nsupdate hook. diff --git a/letsencrypt/config b/letsencrypt/config new file mode 100644 index 0000000..8ddd42e --- /dev/null +++ b/letsencrypt/config @@ -0,0 +1,5 @@ +DOMAINS_D=/data/ssl/configs +WELLKNOWN=/data/ssl/challenge +PRIVATE_KEY_RENEW=no +KEYSIZE=2048 +# CONTACT_EMAIL=hostmaster@example.com diff --git a/letsencrypt/dehydrated-manual b/letsencrypt/dehydrated-manual new file mode 100755 index 0000000..0436362 --- /dev/null +++ b/letsencrypt/dehydrated-manual @@ -0,0 +1,11 @@ +#!/bin/sh + +if test "x$1" = xdeploy_challenge; then + echo "Add the following record and press enter to continue:" + echo "_acme-challenge.$2. TXT $4" + read dummy +elif test "x$1" = xclean_challenge; then + echo "Remove the record and press enter to continue:" + echo "_acme-challenge.$2. TXT $4" + read dummy +fi diff --git a/letsencrypt/dehydrated-nsupdate b/letsencrypt/dehydrated-nsupdate new file mode 100755 index 0000000..52fd241 --- /dev/null +++ b/letsencrypt/dehydrated-nsupdate @@ -0,0 +1,24 @@ +#!/bin/sh + +SCRIPT_TTL=30 + +if test "x$LE_SERVER" = x; then echo export LE_SERVER=ns.example.com; exit=1; fi +if test "x$LE_ZONE" = x; then echo export LE_ZONE=example.com; exit=1; fi +if test "x$LE_TSIGKEY" = x; then echo export LE_TSIGKEY=/path/to/key; exit=1; fi +if test "x$exit" = x1; then exit 1; fi + +if test "x$1" = xdeploy_challenge; then + nsupdate -v -k "$LE_TSIGKEY" <<- NSUPDATE + server $LE_SERVER + zone $LE_ZONE + update add _acme-challenge.$2. $SCRIPT_TTL TXT $4 + send + NSUPDATE +elif test "x$1" = xclean_challenge; then + nsupdate -v -k "$LE_TSIGKEY" <<- NSUPDATE + server $LE_SERVER + zone $LE_ZONE + update del _acme-challenge.$2. TXT + send + NSUPDATE +fi diff --git a/letsencrypt/example-hook b/letsencrypt/example-hook new file mode 100644 index 0000000..80a49ad --- /dev/null +++ b/letsencrypt/example-hook @@ -0,0 +1,7 @@ +#!/bin/sh + +export LE_TSIGKEY=/data/dns/tsig.example.com.conf +export LE_SERVER=ns01.example.com +export LE_ZONE=example.com + +/data/ssl/dehydrated-nsupdate "$@"