server: reorganize
This commit is contained in:
parent
7535990be0
commit
598044863f
|
@ -102,6 +102,7 @@
|
|||
package = pkgs.gitAndTools.gitFull;
|
||||
delta.enable = true;
|
||||
extraConfig = {
|
||||
commit.gpgsign = true;
|
||||
# disable the atrocious gui password prompt
|
||||
core.askPass = "";
|
||||
# ...and prefer getting passwords from libsecret (and storing them there)
|
||||
|
|
|
@ -9,8 +9,11 @@ let
|
|||
tsja = callPackage ./tsja.nix { };
|
||||
};
|
||||
gen' = postgresql: builtins.mapAttrs (k: v: v.override { inherit postgresql; }) extraPackages;
|
||||
gen = ver: pkgs."postgresql${toString ver}Packages" // gen' pkgs."postgresql_${toString ver}";
|
||||
in {
|
||||
gen = ver: pkgs."postgresql${toString ver}Packages" // gen' pkgs."postgresql${if ver == "" then "" else "_" + toString ver}";
|
||||
psql = ver: let
|
||||
old = pkgs."postgresql${if ver == "" then "" else "_" + toString ver}";
|
||||
in old // { pkgs = old.pkgs // gen' old; };
|
||||
self = {
|
||||
mecab = pkgs.mecab.overrideAttrs (old: {
|
||||
postInstall = ''
|
||||
mkdir -p $out/lib/mecab/dic
|
||||
|
@ -20,10 +23,18 @@ in {
|
|||
'';
|
||||
});
|
||||
postgresqlPackages = gen "";
|
||||
postgresql = psql "";
|
||||
postgresql11Packages = gen 11;
|
||||
postgresql_11 = psql 11;
|
||||
postgresql12Packages = gen 12;
|
||||
postgresql_12 = psql 12;
|
||||
postgresql13Packages = gen 13;
|
||||
postgresql_13 = psql 13;
|
||||
postgresql14Packages = gen 14;
|
||||
postgresql_14 = psql 14;
|
||||
postgresql15Packages = gen 15;
|
||||
postgresql_15 = psql 15;
|
||||
postgresql16Packages = gen 16;
|
||||
}
|
||||
postgresql_16 = psql 16;
|
||||
};
|
||||
in self
|
||||
|
|
78
system/hosts/server/akkoma.nix
Normal file
78
system/hosts/server/akkoma.nix
Normal file
|
@ -0,0 +1,78 @@
|
|||
{ config
|
||||
, pkgs
|
||||
, ... }:
|
||||
|
||||
let
|
||||
cfg = config.server;
|
||||
in {
|
||||
# TODO: remove this in 2024
|
||||
services.nginx.virtualHosts."pleroma.${cfg.domainName}" = {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
addSSL = true;
|
||||
serverAliases = [ "akkoma.${cfg.domainName}" ];
|
||||
locations."/".return = "301 https://fedi.${cfg.domainName}$request_uri";
|
||||
};
|
||||
|
||||
services.postgresql.extraPlugins = with config.services.postgresql.package.pkgs; [ tsja ];
|
||||
|
||||
services.akkoma = {
|
||||
enable = true;
|
||||
dist.extraFlags = [
|
||||
"+sbwt" "none"
|
||||
"+sbwtdcpu" "none"
|
||||
"+sbwtdio" "none"
|
||||
];
|
||||
config.":pleroma"."Pleroma.Web.Endpoint" = {
|
||||
url = {
|
||||
scheme = "https";
|
||||
host = "fedi.${cfg.domainName}";
|
||||
port = 443;
|
||||
};
|
||||
secret_key_base._secret = "/secrets/akkoma/secret_key_base";
|
||||
signing_salt._secret = "/secrets/akkoma/signing_salt";
|
||||
live_view.signing_salt._secret = "/secrets/akkoma/live_view_signing_salt";
|
||||
};
|
||||
initDb = {
|
||||
enable = false;
|
||||
username = "akkoma";
|
||||
password._secret = "/secrets/akkoma/postgres_password";
|
||||
};
|
||||
config.":pleroma".":instance" = {
|
||||
name = cfg.domainName;
|
||||
description = "Insert instance description here";
|
||||
email = "webmaster-akkoma@${cfg.domainName}";
|
||||
notify_email = "noreply@${cfg.domainName}";
|
||||
limit = 5000;
|
||||
registrations_open = true;
|
||||
account_activation_required = true;
|
||||
account_approval_required = true;
|
||||
};
|
||||
config.":pleroma"."Pleroma.Repo" = {
|
||||
adapter = (pkgs.formats.elixirConf { }).lib.mkRaw "Ecto.Adapters.Postgres";
|
||||
username = "akkoma";
|
||||
password._secret = "/secrets/akkoma/postgres_password";
|
||||
database = "akkoma";
|
||||
hostname = "localhost";
|
||||
};
|
||||
config.":web_push_encryption".":vapid_details" = {
|
||||
subject = "mailto:webmaster-akkoma@${cfg.domainName}";
|
||||
public_key._secret = "/secrets/akkoma/push_public_key";
|
||||
private_key._secret = "/secrets/akkoma/push_private_key";
|
||||
};
|
||||
config.":joken".":default_signer"._secret = "/secrets/akkoma/joken_signer";
|
||||
nginx = {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
};
|
||||
systemd.services.akkoma = {
|
||||
path = [ pkgs.exiftool pkgs.gawk ];
|
||||
serviceConfig.Restart = "on-failure";
|
||||
unitConfig = {
|
||||
StartLimitIntervalSec = 60;
|
||||
StartLimitBurst = 3;
|
||||
};
|
||||
};
|
||||
}
|
44
system/hosts/server/certspotter.nix
Normal file
44
system/hosts/server/certspotter.nix
Normal file
|
@ -0,0 +1,44 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, ... }:
|
||||
|
||||
let
|
||||
cfg = config.server;
|
||||
in {
|
||||
security.acme.certs = lib.flip builtins.mapAttrs (lib.filterAttrs (k: v: v.enableACME) config.services.nginx.virtualHosts) (k: v: {
|
||||
postRun = let
|
||||
python = pkgs.python3.withPackages (p: with p; [ cryptography pyasn1 pyasn1-modules ]);
|
||||
tbs-hash = pkgs.writeScript "tbs-hash.py" ''
|
||||
#!${python}/bin/python3
|
||||
import hashlib
|
||||
from pyasn1.codec.der.decoder import decode
|
||||
from pyasn1.codec.der.encoder import encode
|
||||
from pyasn1_modules import rfc5280
|
||||
from cryptography import x509
|
||||
|
||||
with open('full.pem', 'rb') as f:
|
||||
cert = x509.load_pem_x509_certificate(f.read())
|
||||
tbs, _leftover = decode(cert.tbs_certificate_bytes, asn1Spec=rfc5280.TBSCertificate())
|
||||
precert_exts = [v.dotted_string for k, v in x509.ExtensionOID.__dict__.items() if k.startswith('PRECERT_')]
|
||||
exts = [ext for ext in tbs["extensions"] if str(ext["extnID"]) not in precert_exts]
|
||||
tbs["extensions"].clear()
|
||||
tbs["extensions"].extend(exts)
|
||||
print(hashlib.sha256(encode(tbs)).hexdigest())
|
||||
'';
|
||||
in ''
|
||||
${tbs-hash} > "/var/lib/certspotter/tbs-hashes/${k}"
|
||||
'';
|
||||
});
|
||||
services.certspotter = {
|
||||
enable = true;
|
||||
extraFlags = [ ];
|
||||
watchlist = [ ".pavluk.org" ];
|
||||
hooks = lib.toList (pkgs.writeShellScript "certspotter-hook" ''
|
||||
if [[ "$EVENT" == discovered_cert ]]; then
|
||||
${pkgs.gnugrep}/bin/grep -r "$TBS_SHA256" /var/lib/certspotter/tbs-hashes/ && exit
|
||||
fi
|
||||
(echo "Subject: $SUMMARY" && echo && cat "$TEXT_FILENAME") | /run/wrappers/bin/sendmail -i webmaster-certspotter@${cfg.domainName}
|
||||
'');
|
||||
};
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
let
|
||||
cfg = config.server;
|
||||
|
||||
hosted-domains =
|
||||
hostedDomains =
|
||||
builtins.concatLists
|
||||
(builtins.attrValues
|
||||
(builtins.mapAttrs
|
||||
|
@ -15,12 +15,16 @@ let
|
|||
in {
|
||||
imports = [
|
||||
./options.nix
|
||||
./matrix.nix
|
||||
./akkoma.nix
|
||||
./certspotter.nix
|
||||
./fdroid.nix
|
||||
./mumble.nix
|
||||
./mailserver.nix
|
||||
./files.nix
|
||||
./home.nix
|
||||
./keycloak.nix
|
||||
./mailserver.nix
|
||||
./matrix.nix
|
||||
./mumble.nix
|
||||
./searxng.nix
|
||||
];
|
||||
|
||||
system.stateVersion = "22.11";
|
||||
|
@ -77,12 +81,11 @@ in {
|
|||
};
|
||||
};
|
||||
# just in case
|
||||
networking.hosts."127.0.0.1" = hosted-domains;
|
||||
networking.hosts."::1" = hosted-domains;
|
||||
networking.hosts."127.0.0.1" = hostedDomains;
|
||||
networking.hosts."::1" = hostedDomains;
|
||||
|
||||
services.postgresql.enable = true;
|
||||
services.postgresql.package = pkgs.postgresql_13;
|
||||
services.postgresql.extraPlugins = with pkgs.postgresql13Packages; [ tsja ];
|
||||
|
||||
# SSH
|
||||
services.openssh.enable = true;
|
||||
|
@ -97,56 +100,6 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
# SEARXNG
|
||||
services.searx.enable = true;
|
||||
services.searx.package = pkgs.searxng;
|
||||
services.searx.runInUwsgi = true;
|
||||
services.searx.uwsgiConfig = let inherit (config.services.searx) settings; in {
|
||||
socket = "${lib.quoteListenAddr settings.server.bind_address}:${toString settings.server.port}";
|
||||
};
|
||||
services.searx.environmentFile = /var/lib/searx/searx.env;
|
||||
services.searx.settings = {
|
||||
use_default_settings = true;
|
||||
search = {
|
||||
safe_search = 0;
|
||||
autocomplete = "duckduckgo"; # dbpedia, duckduckgo, google, startpage, swisscows, qwant, wikipedia - leave blank to turn off
|
||||
default_lang = ""; # leave blank to detect from browser info or use codes from languages.py
|
||||
};
|
||||
|
||||
server = {
|
||||
port = 8888;
|
||||
bind_address = "::1";
|
||||
secret_key = "@SEARX_SECRET_KEY@";
|
||||
base_url = "https://search.${cfg.domainName}/";
|
||||
image_proxy = true;
|
||||
default_http_headers = {
|
||||
X-Content-Type-Options = "nosniff";
|
||||
X-XSS-Protection = "1; mode=block";
|
||||
X-Download-Options = "noopen";
|
||||
X-Robots-Tag = "noindex, nofollow";
|
||||
Referrer-Policy = "no-referrer";
|
||||
};
|
||||
};
|
||||
outgoing = {
|
||||
request_timeout = 5.0; # default timeout in seconds, can be override by engine
|
||||
max_request_timeout = 15.0; # the maximum timeout in seconds
|
||||
pool_connections = 100; # Maximum number of allowable connections, or null
|
||||
pool_maxsize = 10; # Number of allowable keep-alive connections, or null
|
||||
enable_http2 = true; # See https://www.python-httpx.org/http2/
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."search.${cfg.domainName}" = let inherit (config.services.searx) settings; in {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
# locations."/".proxyPass = "http://${lib.quoteListenAddr settings.server.bind_address}:${toString settings.server.port}";
|
||||
locations."/".extraConfig = ''
|
||||
uwsgi_pass "${lib.quoteListenAddr settings.server.bind_address}:${toString settings.server.port}";
|
||||
include ${config.services.nginx.package}/conf/uwsgi_params;
|
||||
'';
|
||||
};
|
||||
|
||||
# NGINX
|
||||
services.nginx.enable = true;
|
||||
services.nginx.enableReload = true;
|
||||
|
@ -212,188 +165,6 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
# GITEA
|
||||
services.nginx.virtualHosts."git.${cfg.domainName}" = let inherit (config.services.gitea) settings; in {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/".proxyPass = "http://${lib.quoteListenAddr settings.server.HTTP_ADDR}:${toString settings.server.HTTP_PORT}";
|
||||
};
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
package = pkgs.forgejo;
|
||||
database = {
|
||||
createDatabase = false;
|
||||
passwordFile = "/var/lib/gitea/db_password";
|
||||
type = "postgres";
|
||||
};
|
||||
settings = {
|
||||
federation.ENABLED = true;
|
||||
"git.timeout" = {
|
||||
DEFAULT = 6000;
|
||||
MIGRATE = 60000;
|
||||
MIRROR = 60000;
|
||||
GC = 120;
|
||||
};
|
||||
mailer = {
|
||||
ENABLED = true;
|
||||
FROM = "Forgejo <noreply@${cfg.domainName}>";
|
||||
PROTOCOL = "smtp";
|
||||
SMTP_ADDR = "mail.${cfg.domainName}";
|
||||
SMTP_PORT = 587;
|
||||
USER = "noreply@${cfg.domainName}";
|
||||
PASSWD = cfg.unhashedNoreplyPassword;
|
||||
FORCE_TRUST_SERVER_CERT = true;
|
||||
};
|
||||
session = {
|
||||
COOKIE_SECURE = true;
|
||||
};
|
||||
server = {
|
||||
ROOT_URL = "https://git.${cfg.domainName}";
|
||||
HTTP_ADDR = "::1";
|
||||
HTTP_PORT = 3310;
|
||||
DOMAIN = "git.${cfg.domainName}";
|
||||
# START_SSH_SERVER = true;
|
||||
# SSH_PORT = 2222;
|
||||
};
|
||||
service = {
|
||||
DISABLE_REGISTRATION = true;
|
||||
REGISTER_EMAIL_CONFIRM = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# NEXTCLOUD
|
||||
services.nginx.virtualHosts."cloud.${cfg.domainName}" = {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
enableBrokenCiphersForSSE = false;
|
||||
package = pkgs.nextcloud27;
|
||||
autoUpdateApps.enable = true;
|
||||
# TODO: use socket auth and remove the next line
|
||||
database.createLocally = false;
|
||||
config = {
|
||||
adminpassFile = "/var/lib/nextcloud/admin_password";
|
||||
dbpassFile = "/var/lib/nextcloud/db_password";
|
||||
dbtype = "pgsql";
|
||||
dbhost = "/run/postgresql";
|
||||
overwriteProtocol = "https";
|
||||
};
|
||||
hostName = "cloud.${cfg.domainName}";
|
||||
https = true;
|
||||
};
|
||||
|
||||
# AKKOMA
|
||||
# TODO: remove this in 2024
|
||||
services.nginx.virtualHosts."pleroma.${cfg.domainName}" = {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
addSSL = true;
|
||||
serverAliases = [ "akkoma.${cfg.domainName}" ];
|
||||
locations."/".return = "301 https://fedi.${cfg.domainName}$request_uri";
|
||||
};
|
||||
|
||||
services.akkoma = {
|
||||
enable = true;
|
||||
dist.extraFlags = [
|
||||
"+sbwt" "none"
|
||||
"+sbwtdcpu" "none"
|
||||
"+sbwtdio" "none"
|
||||
];
|
||||
config.":pleroma"."Pleroma.Web.Endpoint" = {
|
||||
url = {
|
||||
scheme = "https";
|
||||
host = "fedi.${cfg.domainName}";
|
||||
port = 443;
|
||||
};
|
||||
secret_key_base._secret = "/secrets/akkoma/secret_key_base";
|
||||
signing_salt._secret = "/secrets/akkoma/signing_salt";
|
||||
live_view.signing_salt._secret = "/secrets/akkoma/live_view_signing_salt";
|
||||
};
|
||||
initDb = {
|
||||
enable = false;
|
||||
username = "akkoma";
|
||||
password._secret = "/secrets/akkoma/postgres_password";
|
||||
};
|
||||
config.":pleroma".":instance" = {
|
||||
name = cfg.domainName;
|
||||
description = "Insert instance description here";
|
||||
email = "webmaster-akkoma@${cfg.domainName}";
|
||||
notify_email = "noreply@${cfg.domainName}";
|
||||
limit = 5000;
|
||||
registrations_open = true;
|
||||
account_activation_required = true;
|
||||
account_approval_required = true;
|
||||
};
|
||||
config.":pleroma"."Pleroma.Repo" = {
|
||||
adapter = (pkgs.formats.elixirConf { }).lib.mkRaw "Ecto.Adapters.Postgres";
|
||||
username = "akkoma";
|
||||
password._secret = "/secrets/akkoma/postgres_password";
|
||||
database = "akkoma";
|
||||
hostname = "localhost";
|
||||
};
|
||||
config.":web_push_encryption".":vapid_details" = {
|
||||
subject = "mailto:webmaster-akkoma@${cfg.domainName}";
|
||||
public_key._secret = "/secrets/akkoma/push_public_key";
|
||||
private_key._secret = "/secrets/akkoma/push_private_key";
|
||||
};
|
||||
config.":joken".":default_signer"._secret = "/secrets/akkoma/joken_signer";
|
||||
nginx = {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
};
|
||||
systemd.services.akkoma = {
|
||||
path = [ pkgs.exiftool pkgs.gawk ];
|
||||
serviceConfig.Restart = "on-failure";
|
||||
unitConfig = {
|
||||
StartLimitIntervalSec = 60;
|
||||
StartLimitBurst = 3;
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: calc tbs instead of pubkey hash?
|
||||
security.acme.certs = lib.flip builtins.mapAttrs (lib.filterAttrs (k: v: v.enableACME) config.services.nginx.virtualHosts) (k: v: {
|
||||
postRun = let
|
||||
python = pkgs.python3.withPackages (p: with p; [ cryptography pyasn1 pyasn1-modules ]);
|
||||
tbs-hash = pkgs.writeScript "tbs-hash.py" ''
|
||||
#!${python}/bin/python3
|
||||
import hashlib
|
||||
from pyasn1.codec.der.decoder import decode
|
||||
from pyasn1.codec.der.encoder import encode
|
||||
from pyasn1_modules import rfc5280
|
||||
from cryptography import x509
|
||||
|
||||
with open('full.pem', 'rb') as f:
|
||||
cert = x509.load_pem_x509_certificate(f.read())
|
||||
tbs, _leftover = decode(cert.tbs_certificate_bytes, asn1Spec=rfc5280.TBSCertificate())
|
||||
precert_exts = [v.dotted_string for k, v in x509.ExtensionOID.__dict__.items() if k.startswith('PRECERT_')]
|
||||
exts = [ext for ext in tbs["extensions"] if str(ext["extnID"]) not in precert_exts]
|
||||
tbs["extensions"].clear()
|
||||
tbs["extensions"].extend(exts)
|
||||
print(hashlib.sha256(encode(tbs)).hexdigest())
|
||||
'';
|
||||
in ''
|
||||
${tbs-hash} > "/var/lib/certspotter/tbs-hashes/${k}"
|
||||
'';
|
||||
});
|
||||
services.certspotter = {
|
||||
enable = true;
|
||||
extraFlags = [ ];
|
||||
watchlist = [ ".pavluk.org" ];
|
||||
hooks = lib.toList (pkgs.writeShellScript "certspotter-hook" ''
|
||||
if [[ "$EVENT" == discovered_cert ]]; then
|
||||
${pkgs.gnugrep}/bin/grep -r "$TBS_SHA256" /var/lib/certspotter/tbs-hashes/ && exit
|
||||
fi
|
||||
(echo "Subject: $SUMMARY" && echo && cat "$TEXT_FILENAME") | /run/wrappers/bin/sendmail -i webmaster-certspotter@${cfg.domainName}
|
||||
'');
|
||||
};
|
||||
|
||||
/*locations."/dns-query".extraConfig = ''
|
||||
grpc_pass grpc://127.0.0.1:53453;
|
||||
'';*/
|
||||
|
|
83
system/hosts/server/files.nix
Normal file
83
system/hosts/server/files.nix
Normal file
|
@ -0,0 +1,83 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, ... }:
|
||||
|
||||
let
|
||||
cfg = config.server;
|
||||
in {
|
||||
services.nginx.virtualHosts."git.${cfg.domainName}" = let inherit (config.services.forgejo) settings; in {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/".proxyPass = "http://${lib.quoteListenAddr settings.server.HTTP_ADDR}:${toString settings.server.HTTP_PORT}";
|
||||
};
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
database = {
|
||||
createDatabase = false;
|
||||
type = "postgres";
|
||||
user = "gitea";
|
||||
name = "gitea";
|
||||
passwordFile = "/secrets/forgejo_db_password";
|
||||
};
|
||||
lfs.enable = true;
|
||||
settings = {
|
||||
federation.ENABLED = true;
|
||||
"git.timeout" = {
|
||||
DEFAULT = 6000;
|
||||
MIGRATE = 60000;
|
||||
MIRROR = 60000;
|
||||
GC = 120;
|
||||
};
|
||||
mailer = {
|
||||
ENABLED = true;
|
||||
FROM = "Forgejo <noreply@${cfg.domainName}>";
|
||||
PROTOCOL = "smtp";
|
||||
SMTP_ADDR = "mail.${cfg.domainName}";
|
||||
SMTP_PORT = 587;
|
||||
USER = "noreply@${cfg.domainName}";
|
||||
PASSWD = cfg.unhashedNoreplyPassword;
|
||||
FORCE_TRUST_SERVER_CERT = true;
|
||||
};
|
||||
session = {
|
||||
COOKIE_SECURE = true;
|
||||
};
|
||||
server = {
|
||||
ROOT_URL = "https://git.${cfg.domainName}";
|
||||
HTTP_ADDR = "::1";
|
||||
HTTP_PORT = 3310;
|
||||
DOMAIN = "git.${cfg.domainName}";
|
||||
# START_SSH_SERVER = true;
|
||||
# SSH_PORT = 2222;
|
||||
};
|
||||
service = {
|
||||
DISABLE_REGISTRATION = true;
|
||||
REGISTER_EMAIL_CONFIRM = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."cloud.${cfg.domainName}" = {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
enableBrokenCiphersForSSE = false;
|
||||
package = pkgs.nextcloud27;
|
||||
autoUpdateApps.enable = true;
|
||||
# TODO: use socket auth and remove the next line
|
||||
database.createLocally = false;
|
||||
config = {
|
||||
adminpassFile = "/var/lib/nextcloud/admin_password";
|
||||
dbpassFile = "/var/lib/nextcloud/db_password";
|
||||
dbtype = "pgsql";
|
||||
dbhost = "/run/postgresql";
|
||||
overwriteProtocol = "https";
|
||||
};
|
||||
hostName = "cloud.${cfg.domainName}";
|
||||
https = true;
|
||||
};
|
||||
}
|
58
system/hosts/server/forgejo.nix
Normal file
58
system/hosts/server/forgejo.nix
Normal file
|
@ -0,0 +1,58 @@
|
|||
{ config
|
||||
, lib
|
||||
, ... }:
|
||||
|
||||
let
|
||||
cfg = config.server;
|
||||
in {
|
||||
services.nginx.virtualHosts."git.${cfg.domainName}" = let inherit (config.services.forgejo) settings; in {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/".proxyPass = "http://${lib.quoteListenAddr settings.server.HTTP_ADDR}:${toString settings.server.HTTP_PORT}";
|
||||
};
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
database = {
|
||||
createDatabase = false;
|
||||
user = "gitea";
|
||||
passwordFile = "/secrets/forgejo_db_password";
|
||||
type = "postgres";
|
||||
};
|
||||
lfs.enable = true;
|
||||
settings = {
|
||||
federation.ENABLED = true;
|
||||
"git.timeout" = {
|
||||
DEFAULT = 6000;
|
||||
MIGRATE = 60000;
|
||||
MIRROR = 60000;
|
||||
GC = 120;
|
||||
};
|
||||
mailer = {
|
||||
ENABLED = true;
|
||||
FROM = "Forgejo <noreply@${cfg.domainName}>";
|
||||
PROTOCOL = "smtp";
|
||||
SMTP_ADDR = "mail.${cfg.domainName}";
|
||||
SMTP_PORT = 587;
|
||||
USER = "noreply@${cfg.domainName}";
|
||||
PASSWD = cfg.unhashedNoreplyPassword;
|
||||
FORCE_TRUST_SERVER_CERT = true;
|
||||
};
|
||||
session = {
|
||||
COOKIE_SECURE = true;
|
||||
};
|
||||
server = {
|
||||
ROOT_URL = "https://git.${cfg.domainName}";
|
||||
HTTP_ADDR = "::1";
|
||||
HTTP_PORT = 3310;
|
||||
DOMAIN = "git.${cfg.domainName}";
|
||||
# START_SSH_SERVER = true;
|
||||
# SSH_PORT = 2222;
|
||||
};
|
||||
service = {
|
||||
DISABLE_REGISTRATION = false;
|
||||
REGISTER_MANUAL_CONFIRM = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
57
system/hosts/server/searxng.nix
Normal file
57
system/hosts/server/searxng.nix
Normal file
|
@ -0,0 +1,57 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, ... }:
|
||||
|
||||
let
|
||||
cfg = config.server;
|
||||
in {
|
||||
services.nginx.virtualHosts."search.${cfg.domainName}" = let inherit (config.services.searx) settings; in {
|
||||
quic = true;
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
# locations."/".proxyPass = "http://${lib.quoteListenAddr settings.server.bind_address}:${toString settings.server.port}";
|
||||
locations."/".extraConfig = ''
|
||||
uwsgi_pass "${lib.quoteListenAddr settings.server.bind_address}:${toString settings.server.port}";
|
||||
include ${config.services.nginx.package}/conf/uwsgi_params;
|
||||
'';
|
||||
};
|
||||
|
||||
services.searx.enable = true;
|
||||
services.searx.package = pkgs.searxng;
|
||||
services.searx.runInUwsgi = true;
|
||||
services.searx.uwsgiConfig = let inherit (config.services.searx) settings; in {
|
||||
socket = "${lib.quoteListenAddr settings.server.bind_address}:${toString settings.server.port}";
|
||||
};
|
||||
services.searx.environmentFile = /var/lib/searx/searx.env;
|
||||
services.searx.settings = {
|
||||
use_default_settings = true;
|
||||
search = {
|
||||
safe_search = 0;
|
||||
autocomplete = "duckduckgo"; # dbpedia, duckduckgo, google, startpage, swisscows, qwant, wikipedia - leave blank to turn off
|
||||
default_lang = ""; # leave blank to detect from browser info or use codes from languages.py
|
||||
};
|
||||
|
||||
server = {
|
||||
port = 8888;
|
||||
bind_address = "::1";
|
||||
secret_key = "@SEARX_SECRET_KEY@";
|
||||
base_url = "https://search.${cfg.domainName}/";
|
||||
image_proxy = true;
|
||||
default_http_headers = {
|
||||
X-Content-Type-Options = "nosniff";
|
||||
X-XSS-Protection = "1; mode=block";
|
||||
X-Download-Options = "noopen";
|
||||
X-Robots-Tag = "noindex, nofollow";
|
||||
Referrer-Policy = "no-referrer";
|
||||
};
|
||||
};
|
||||
outgoing = {
|
||||
request_timeout = 5.0; # default timeout in seconds, can be override by engine
|
||||
max_request_timeout = 15.0; # the maximum timeout in seconds
|
||||
pool_connections = 100; # Maximum number of allowable connections, or null
|
||||
pool_maxsize = 10; # Number of allowable keep-alive connections, or null
|
||||
enable_http2 = true; # See https://www.python-httpx.org/http2/
|
||||
};
|
||||
};
|
||||
}
|
|
@ -75,6 +75,8 @@ in {
|
|||
{ directory = /var/db/dhcpcd; user = "root"; group = "root"; mode = "0755"; }
|
||||
] ++ lib.optionals config.services.gitea.enable [
|
||||
{ directory = /var/lib/gitea; user = "gitea"; group = "gitea"; mode = "0755"; }
|
||||
] ++ lib.optionals config.services.forgejo.enable [
|
||||
{ directory = /var/lib/forgejo; user = "forgejo"; group = "forgejo"; mode = "0755"; }
|
||||
] ++ lib.optionals config.services.matrix-synapse.enable [
|
||||
{ directory = /var/lib/matrix-synapse; user = "matrix-synapse"; group = "matrix-synapse"; mode = "0700"; }
|
||||
] ++ lib.optionals config.services.heisenbridge.enable [
|
||||
|
|
Loading…
Reference in a new issue