Compare commits

...

15 Commits

Author SHA1 Message Date
Izorkin fd75a7afb8 hyperscan: fix build 2022-01-05 15:28:43 +02:00
Izorkin 412d1a9851 enable modsecurity to nextcloud 2021-12-19 17:08:31 +02:00
Izorkin 9700b9c08d build nginx with custom modules 2021-12-19 17:03:32 +02:00
Izorkin f775c42454 pkgs: init modsecurity-crs at v3.3.2 2021-12-18 22:14:42 +02:00
Izorkin ced421eff4 pkgs: init libmodsecurity at v3.0.6 2021-12-18 22:11:24 +02:00
Izorkin 36e7cb8c5e update gitignore 2021-12-16 19:42:10 +02:00
Izorkin 8a341bf253 move users to generic subfolder 2021-12-16 19:42:10 +02:00
Izorkin b557482517 move files to generic subfolder 2021-12-16 19:42:10 +02:00
Izorkin b2659618aa move variables to generic subfolder 2021-12-16 19:42:10 +02:00
Izorkin ac9860453b move api to generic subfolder 2021-12-16 19:42:10 +02:00
Izorkin 8b10998cae move limits to generic subfolder 2021-12-16 19:42:10 +02:00
Izorkin 4dcbc6cd4e move all services to subfolder 2021-12-16 19:42:08 +02:00
Inex Code 1b8bdb013a Fix pleroma permissions 2021-12-16 16:58:26 +03:00
Inex Code 3f42ad5c68 Hotfix inability to build when custom user don't have ssh keys 2021-12-16 13:27:11 +03:00
Inex Code 63aaeec08c Remove PAM from mailserver and remove catchall 2021-12-15 17:42:47 +03:00
32 changed files with 266 additions and 39 deletions

6
.gitignore vendored
View File

@ -1,3 +1,7 @@
outputs
result
result-*
source
userdata/userdata.json
hardware-configuration.nix
networking.nix
networking.nix

View File

@ -6,27 +6,28 @@ in
{
imports = [
./hardware-configuration.nix
./variables-module.nix
./variables.nix
./files.nix
./users.nix
./mailserver/system/mailserver.nix
./mailserver/system/alps.nix
./vpn/ocserv.nix
./api/api.nix
./api/api-module.nix
./social/pleroma.nix
./letsencrypt/acme.nix
./letsencrypt/resolve.nix
./backup/restic.nix
./passmgr/bitwarden.nix
./webserver/nginx.nix
./webserver/memcached.nix
./nextcloud/nextcloud.nix
./resources/limits.nix
./videomeet/jitsi.nix
./git/gitea.nix
./generic/api/api.nix
./generic/modules/api.nix
./generic/modules/userdata.nix
./generic/overlays/default.nix
./generic/services/backup/restic.nix
./generic/services/cloud/nextcloud.nix
./generic/services/git/gitea.nix
./generic/services/letsencrypt/acme.nix
./generic/services/letsencrypt/resolve.nix
./generic/services/mail/alps.nix
./generic/services/mail/mailserver.nix
./generic/services/passmgr/bitwarden.nix
./generic/services/social/pleroma.nix
./generic/services/videomeet/jitsi.nix
./generic/services/vpn/ocserv.nix
./generic/services/webserver/modsecurity/default.nix
./generic/services/webserver/memcached.nix
./generic/services/webserver/nginx.nix
./generic/system/limits.nix
./generic/system/tmpfiles.nix
./generic/system/userdata.nix
./generic/system/users.nix
];
nixpkgs.overlays = [ (nix-overlay) ];

View File

@ -0,0 +1,31 @@
{ lib, pkgs, ... }:
{
nixpkgs.config.packageOverrides = pkgs: rec {
spdev = import ./../pkgs { inherit pkgs; };
};
nixpkgs.overlays = [
(self: super: {
nginx = super.nginxMainline.override {
withDebug = false;
withStream = false;
modules = [
pkgs.nginxModules.rtmp
pkgs.nginxModules.dav
pkgs.nginxModules.moreheaders
pkgs.nginxModules.modsecurity-nginx
];
};
hyperscan = super.hyperscan.overrideDerivation (oldAttr: {
patches = [
(super.fetchpatch {
# part of https://github.com/intel/hyperscan/pull/336
url = "https://github.com/intel/hyperscan/commit/e2c4010b1fc1272cab816ba543940b3586e68a0c.patch";
sha256 = "sha256-doVNwROL6MTcgOW8jBwGTnxe0zvxjawiob/g6AvXLak=";
})
];
});
})
];
}

5
generic/pkgs/default.nix Normal file
View File

@ -0,0 +1,5 @@
{ pkgs ? import <nixpkgs> { } }:
rec {
libmodsecurity = pkgs.callPackage ./libmodsecurity { };
modsecurity-crs = pkgs.callPackage ./modsecurity-crs { };
}

View File

@ -0,0 +1,70 @@
{ lib, stdenv, fetchFromGitHub
, autoreconfHook, bison, flex, pkg-config
, curl, geoip, libmaxminddb, libxml2, lmdb, lua, pcre
, ssdeep, valgrind, yajl
}:
stdenv.mkDerivation rec {
pname = "libmodsecurity";
version = "3.0.6";
src = fetchFromGitHub {
owner = "SpiderLabs";
repo = "ModSecurity";
rev = "v${version}";
sha256 = "sha256-V+NBT2YN8qO3Px8zEzSA2ZsjSf1pv8+VlLxYlrpqfGg=";
fetchSubmodules = true;
};
nativeBuildInputs = [ autoreconfHook bison flex pkg-config ];
buildInputs = [ curl geoip libmaxminddb libxml2 lmdb lua pcre ssdeep valgrind yajl ];
outputs = [ "out" "dev" ];
configureFlags = [
"--enable-parser-generation"
"--with-curl=${curl.dev}"
"--with-libxml=${libxml2.dev}"
"--with-lmdb=${lmdb.out}"
"--with-maxmind=${libmaxminddb}"
"--with-pcre=${pcre.dev}"
"--with-ssdeep=${ssdeep}"
];
postPatch = ''
substituteInPlace build/lmdb.m4 \
--replace "\''${path}/include/lmdb.h" "${lmdb.dev}/include/lmdb.h" \
--replace "lmdb_inc_path=\"\''${path}/include\"" "lmdb_inc_path=\"${lmdb.dev}/include\""
substituteInPlace build/ssdeep.m4 \
--replace "/usr/local/libfuzzy" "${ssdeep}/lib" \
--replace "\''${path}/include/fuzzy.h" "${ssdeep}/include/fuzzy.h" \
--replace "ssdeep_inc_path=\"\''${path}/include\"" "ssdeep_inc_path=\"${ssdeep}/include\""
substituteInPlace modsecurity.conf-recommended \
--replace "SecUnicodeMapFile unicode.mapping 20127" "SecUnicodeMapFile $out/share/modsecurity/unicode.mapping 20127"
'';
postInstall = ''
mkdir -p $out/share/modsecurity
cp ${src}/{AUTHORS,CHANGES,LICENSE,README.md,modsecurity.conf-recommended,unicode.mapping} $out/share/modsecurity
'';
enableParallelBuilding = true;
meta = with lib; {
homepage = "https://github.com/SpiderLabs/ModSecurity";
description = ''
ModSecurity v3 library component.
'';
longDescription = ''
Libmodsecurity is one component of the ModSecurity v3 project. The
library codebase serves as an interface to ModSecurity Connectors taking
in web traffic and applying traditional ModSecurity processing. In
general, it provides the capability to load/interpret rules written in
the ModSecurity SecRules format and apply them to HTTP content provided
by your application via Connectors.
'';
license = licenses.asl20;
platforms = platforms.all;
maintainers = with maintainers; [ izorkin ];
};
}

View File

@ -0,0 +1,42 @@
{ lib, stdenv, fetchFromGitHub }:
stdenv.mkDerivation rec {
version = "3.3.2";
pname = "modsecurity-crs";
src = fetchFromGitHub {
owner = "coreruleset";
repo = "coreruleset";
rev = "v${version}";
sha256 = "sha256-m/iVLhk2y5BpYu8EwC2adrrDnbaVCQ0SE25ltvMokCw=";
};
installPhase = ''
install -D -m444 -t $out/rules ${src}/rules/*.conf
install -D -m444 -t $out/rules ${src}/rules/*.data
install -D -m444 -t $out/share/doc/modsecurity-crs ${src}/*.md
install -D -m444 -t $out/share/doc/modsecurity-crs ${src}/{CHANGES,INSTALL,LICENSE}
install -D -m444 -t $out/share/modsecurity-crs ${src}/rules/*.example
install -D -m444 -t $out/share/modsecurity-crs ${src}/crs-setup.conf.example
cat > $out/share/modsecurity-crs/modsecurity-crs.load.example <<EOF
##
## This is a sample file for loading OWASP CRS's rules.
##
Include /etc/modsecurity/crs/crs-setup.conf
IncludeOptional /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
Include $out/rules/*.conf
IncludeOptional /etc/modsecurity/crs/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
EOF
'';
meta = with lib; {
homepage = "https://coreruleset.org";
description = ''
The OWASP ModSecurity Core Rule Set is a set of generic attack detection
rules for use with ModSecurity or compatible web application firewalls.
'';
license = licenses.asl20;
platforms = platforms.all;
maintainers = with maintainers; [ izorkin ];
};
}

View File

@ -13,11 +13,6 @@ in
})
];
services.dovecot2 = {
enablePAM = lib.mkForce true;
showPAMFailure = lib.mkForce true;
};
users.users = {
virtualMail = {
isNormalUser = false;
@ -34,7 +29,6 @@ in
loginAccounts = {
"${cfg.username}@${cfg.domain}" = {
hashedPassword = cfg.hashedMasterPassword;
catchAll = [ cfg.domain ];
sieveScript = ''
require ["fileinto", "mailbox"];
if header :contains "Chat-Version" "1.0"
@ -49,7 +43,6 @@ in
name = "${user.username}@${cfg.domain}";
value = {
hashedPassword = user.hashedPassword;
catchAll = [ cfg.domain ];
sieveScript = ''
require ["fileinto", "mailbox"];
if header :contains "Chat-Version" "1.0"

View File

@ -0,0 +1,74 @@
{config, pkgs, ... }:
{
environment.etc."modsecurity/modsecurity_includes.conf".text = ''
Include /etc/modsecurity/modsecurity.conf
Include /etc/modsecurity/crs-setup.conf
Include ${pkgs.spdev.modsecurity-crs}/rules/*.conf
'';
environment.etc."modsecurity/modsecurity.conf".text = ''
SecRuleEngine On
SecRequestBodyAccess On
SecRule REQUEST_HEADERS:Content-Type "(?:application(?:/soap\+|/)|text/)xml" \
"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
SecRule REQUEST_HEADERS:Content-Type "application/json" \
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyLimitAction Reject
SecRule REQBODY_ERROR "!@eq 0" \
"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_MISSING_SEMICOLON}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IP %{MULTIPART_INVALID_PART}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
SecRule MULTIPART_UNMATCHED_BOUNDARY "@eq 1" \
"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
SecPcreMatchLimit 1000
SecPcreMatchLimitRecursion 1000
SecRule TX:/^MSC_/ "!@streq 0" \
"id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml
SecResponseBodyLimit 524288
SecResponseBodyLimitAction ProcessPartial
SecTmpDir /tmp/
SecDataDir /tmp/
SecDebugLog /var/log/nginx/modsec_debug.log
SecDebugLogLevel 3
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLog /var/log/nginx/modsec_audit.log
SecAuditLogFormat Json
SecArgumentSeparator &
SecCookieFormat 0
SecUnicodeMapFile ${pkgs.spdev.libmodsecurity}/share/modsecurity/unicode.mapping 20127
SecStatusEngine On
'';
environment.etc."modsecurity/crs-setup.conf".text = ''
SecDefaultAction "phase:1,log,auditlog,pass"
SecDefaultAction "phase:2,log,auditlog,pass"
SecCollectionTimeout 600
SecAction \
"id:900990,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.crs_setup_version=332"
'';
}

View File

@ -1,11 +1,14 @@
{ pkgs, config, ... }:
{ lib, pkgs, config, ... }:
let
domain = config.services.userdata.domain;
in
{
systemd.services.nginx.serviceConfig.SystemCallFilter = lib.mkForce "~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid";
services.nginx = {
enable = true;
enableReload = true;
package = pkgs.nginx;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
@ -37,6 +40,10 @@ in
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
forceSSL = true;
extraConfig = ''
modsecurity on;
modsecurity_rules_file /etc/modsecurity/modsecurity_includes.conf;
'';
locations = {
"/" = {
proxyPass = "http://127.0.0.1:80/";

View File

@ -24,11 +24,11 @@ in
[
(if cfg.bitwarden.enable then "d /var/lib/bitwarden 0777 bitwarden_rs bitwarden_rs -" else "")
(if cfg.bitwarden.enable then "d /var/lib/bitwarden/backup 0777 bitwarden_rs bitwarden_rs -" else "")
(if cfg.pleroma.enable then "d /var/lib/pleroma 0600 pleroma pleroma - -" else "")
(if cfg.pleroma.enable then "d /var/lib/pleroma 0700 pleroma pleroma - -" else "")
"d /var/lib/restic 0600 restic - - -"
"f+ /var/lib/restic/pass 0400 restic - - ${resticPass}"
"f+ /root/.config/rclone/rclone.conf 0400 root root - ${rcloneConfig}"
(if cfg.pleroma.enable then "f+ /var/lib/pleroma/secrets.exs 0755 pleroma pleroma - -" else "")
(if cfg.pleroma.enable then "f /var/lib/pleroma/secrets.exs 0755 pleroma pleroma - -" else "")
"f+ /var/domain 0444 selfprivacy-api selfprivacy-api - ${domain}"
(if cfg.nextcloud.enable then "f+ /var/lib/nextcloud/db-pass 0440 nextcloud nextcloud - ${nextcloudDBPass}" else "")
(if cfg.nextcloud.enable then "f+ /var/lib/nextcloud/admin-pass 0440 nextcloud nextcloud - ${nextcloudAdminPass}" else "")

View File

@ -0,0 +1,6 @@
{ pkgs, ... }:
{
services = {
userdata = builtins.fromJSON (builtins.readFile ./../../userdata/userdata.json);
};
}

View File

@ -17,7 +17,7 @@ in
value = {
isNormalUser = true;
hashedPassword = user.hashedPassword;
openssh.authorizedKeys.keys = user.sshKeys;
openssh.authorizedKeys.keys = (if user ? sshKeys then user.sshKeys else []);
};
})
cfg.users);

View File

@ -1,6 +0,0 @@
{ pkgs, ... }:
{
services = {
userdata = builtins.fromJSON (builtins.readFile ./userdata/userdata.json);
};
}