nixfmt
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
{ lib, config, ... }:{
|
{ lib, config, ... }:
|
||||||
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./makeWrapper.nix
|
./makeWrapper.nix
|
||||||
];
|
];
|
||||||
|
@@ -4,55 +4,90 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) optionals optional mapAttrsFlatten concatMap escapeShellArg escapeShellArgs;
|
inherit (lib)
|
||||||
|
optionals
|
||||||
|
optional
|
||||||
|
mapAttrsFlatten
|
||||||
|
concatMap
|
||||||
|
escapeShellArg
|
||||||
|
escapeShellArgs
|
||||||
|
;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config.vacu.vaculib.makeWrapper = {
|
config.vacu.vaculib.makeWrapper =
|
||||||
original,
|
{
|
||||||
new,
|
original,
|
||||||
argv0 ? null,
|
new,
|
||||||
inherit_argv0 ? false,
|
argv0 ? null,
|
||||||
resolve_argv0 ? false,
|
inherit_argv0 ? false,
|
||||||
set ? {},
|
resolve_argv0 ? false,
|
||||||
set_default ? {},
|
set ? { },
|
||||||
unset ? [],
|
set_default ? { },
|
||||||
chdir ? null,
|
unset ? [ ],
|
||||||
run ? [],
|
chdir ? null,
|
||||||
prepend_flags ? [],
|
run ? [ ],
|
||||||
add_flags ? [],
|
prepend_flags ? [ ],
|
||||||
append_flags ? [],
|
add_flags ? [ ],
|
||||||
}@args: let
|
append_flags ? [ ],
|
||||||
prependFlags = prepend_flags ++ add_flags;
|
}@args:
|
||||||
escapeFlags = flags: builtins.concatStringsSep " " (map escapeShellArg flags);
|
let
|
||||||
originalBin = if lib.isDerivation original then lib.getExe original else original;
|
prependFlags = prepend_flags ++ add_flags;
|
||||||
makeWrapperFlags =
|
escapeFlags = flags: builtins.concatStringsSep " " (map escapeShellArg flags);
|
||||||
(optionals (argv0 != null) [ "--argv0" argv0]) ++
|
originalBin = if lib.isDerivation original then lib.getExe original else original;
|
||||||
(optional inherit_argv0 "--inherit-argv0") ++
|
makeWrapperFlags =
|
||||||
(optional resolve_argv0 "--resolve-argv0") ++
|
(optionals (argv0 != null) [
|
||||||
(mapAttrsFlatten (k: v: [ "--set" k v ] ) set) ++
|
"--argv0"
|
||||||
(mapAttrsFlatten (k: v: [ "--set-default" k v ] ) set_default) ++
|
argv0
|
||||||
(concatMap (k: [ "--unset" k ]) unset) ++
|
])
|
||||||
(optionals (chdir != null) [ "--chdir" chdir ]) ++
|
++ (optional inherit_argv0 "--inherit-argv0")
|
||||||
(concatMap (k: [ "--run" k ]) run) ++
|
++ (optional resolve_argv0 "--resolve-argv0")
|
||||||
(optionals (prependFlags != []) [ "--add-flags" (escapeFlags prependFlags) ]) ++
|
++ (mapAttrsFlatten (k: v: [
|
||||||
(optionals (append_flags != []) [ "--append-flags" (escapeFlags append_flags) ])
|
"--set"
|
||||||
;
|
k
|
||||||
in pkgs.stdenvNoCC.mkDerivation {
|
v
|
||||||
name = new;
|
]) set)
|
||||||
|
++ (mapAttrsFlatten (k: v: [
|
||||||
|
"--set-default"
|
||||||
|
k
|
||||||
|
v
|
||||||
|
]) set_default)
|
||||||
|
++ (concatMap (k: [
|
||||||
|
"--unset"
|
||||||
|
k
|
||||||
|
]) unset)
|
||||||
|
++ (optionals (chdir != null) [
|
||||||
|
"--chdir"
|
||||||
|
chdir
|
||||||
|
])
|
||||||
|
++ (concatMap (k: [
|
||||||
|
"--run"
|
||||||
|
k
|
||||||
|
]) run)
|
||||||
|
++ (optionals (prependFlags != [ ]) [
|
||||||
|
"--add-flags"
|
||||||
|
(escapeFlags prependFlags)
|
||||||
|
])
|
||||||
|
++ (optionals (append_flags != [ ]) [
|
||||||
|
"--append-flags"
|
||||||
|
(escapeFlags append_flags)
|
||||||
|
]);
|
||||||
|
in
|
||||||
|
pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
name = new;
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
|
|
||||||
phases = [ "installPhase" ];
|
phases = [ "installPhase" ];
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
runHook preInstall
|
runHook preInstall
|
||||||
|
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
makeWrapper ${escapeShellArg originalBin} $out/bin/${escapeShellArg new} ${escapeShellArgs makeWrapperFlags}
|
makeWrapper ${escapeShellArg originalBin} $out/bin/${escapeShellArg new} ${escapeShellArgs makeWrapperFlags}
|
||||||
|
|
||||||
runHook postInstall
|
runHook postInstall
|
||||||
'';
|
'';
|
||||||
|
|
||||||
meta.mainProgram = new;
|
meta.mainProgram = new;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,10 @@ let
|
|||||||
wrappedBashPkg = vaculib.makeWrapper {
|
wrappedBashPkg = vaculib.makeWrapper {
|
||||||
original = pkgs.bash;
|
original = pkgs.bash;
|
||||||
new = "vacuinit-bash";
|
new = "vacuinit-bash";
|
||||||
prepend_flags = [ "--init-file" vacuInitFile ];
|
prepend_flags = [
|
||||||
|
"--init-file"
|
||||||
|
vacuInitFile
|
||||||
|
];
|
||||||
};
|
};
|
||||||
wrappedBash = lib.getExe wrappedBashPkg;
|
wrappedBash = lib.getExe wrappedBashPkg;
|
||||||
in
|
in
|
||||||
|
@@ -9,36 +9,38 @@ let
|
|||||||
userKeys = lib.attrValues config.vacu.ssh.authorizedKeys;
|
userKeys = lib.attrValues config.vacu.ssh.authorizedKeys;
|
||||||
liamKey = config.vacu.ssh.knownHosts.liam.publicKey;
|
liamKey = config.vacu.ssh.knownHosts.liam.publicKey;
|
||||||
ssh-to-age = lib.getExe pkgs.ssh-to-age;
|
ssh-to-age = lib.getExe pkgs.ssh-to-age;
|
||||||
sopsConfig = pkgs.runCommand "sops.yaml" { env.sshUserKeys = lib.concatStringsSep "\n" userKeys; } ''
|
sopsConfig =
|
||||||
set -xe
|
pkgs.runCommand "sops.yaml" { env.sshUserKeys = lib.concatStringsSep "\n" userKeys; }
|
||||||
liamKey="$(echo "${liamKey}" | ${ssh-to-age})"
|
''
|
||||||
declare -a userKeys
|
set -xe
|
||||||
mapfile -t userKeys < <(echo "$sshUserKeys" | ${ssh-to-age})
|
liamKey="$(echo "${liamKey}" | ${ssh-to-age})"
|
||||||
declare -p userKeys
|
declare -a userKeys
|
||||||
cat <<END >> $out
|
mapfile -t userKeys < <(echo "$sshUserKeys" | ${ssh-to-age})
|
||||||
creation_rules:
|
declare -p userKeys
|
||||||
- path_regex: ^secrets/misc/
|
cat <<END >> $out
|
||||||
key_groups:
|
creation_rules:
|
||||||
- age:
|
- path_regex: ^secrets/misc/
|
||||||
END
|
key_groups:
|
||||||
for k in "''${userKeys[@]}"; do
|
- age:
|
||||||
echo " - $k" >> $out
|
END
|
||||||
done
|
for k in "''${userKeys[@]}"; do
|
||||||
cat <<END >> $out
|
echo " - $k" >> $out
|
||||||
- path_regex: ^secrets/liam/
|
done
|
||||||
key_groups:
|
cat <<END >> $out
|
||||||
- age:
|
- path_regex: ^secrets/liam/
|
||||||
- $liamKey
|
key_groups:
|
||||||
END
|
- age:
|
||||||
for k in "''${userKeys[@]}"; do
|
- $liamKey
|
||||||
echo " - $k" >> $out
|
END
|
||||||
done
|
for k in "''${userKeys[@]}"; do
|
||||||
cat <<END >> $out
|
echo " - $k" >> $out
|
||||||
- path_regex: ^tests/test_secrets
|
done
|
||||||
key_groups:
|
cat <<END >> $out
|
||||||
- age: age1eqv5759uknu7d46rqyyzsmgt43qumsge33yp2xygapprnt8zu3sqx6kt8w
|
- path_regex: ^tests/test_secrets
|
||||||
END
|
key_groups:
|
||||||
'';
|
- age: age1eqv5759uknu7d46rqyyzsmgt43qumsge33yp2xygapprnt8zu3sqx6kt8w
|
||||||
|
END
|
||||||
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.vacu.sopsConfig = mkOption {
|
options.vacu.sopsConfig = mkOption {
|
||||||
|
@@ -38,7 +38,7 @@ in
|
|||||||
#vacu.ssh.authorizedKeys = mkOption { type = types.listOf types.str; };
|
#vacu.ssh.authorizedKeys = mkOption { type = types.listOf types.str; };
|
||||||
vacu.ssh.authorizedKeys = mkOption {
|
vacu.ssh.authorizedKeys = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
default = {};
|
default = { };
|
||||||
};
|
};
|
||||||
vacu.ssh.config = mkOption { type = types.lines; };
|
vacu.ssh.config = mkOption { type = types.lines; };
|
||||||
# Straight copied from nixpkgs
|
# Straight copied from nixpkgs
|
||||||
|
14
flake.nix
14
flake.nix
@@ -99,11 +99,15 @@
|
|||||||
x86 = "x86_64-linux";
|
x86 = "x86_64-linux";
|
||||||
arm = "aarch64-linux";
|
arm = "aarch64-linux";
|
||||||
lib = import "${nixpkgs}/lib";
|
lib = import "${nixpkgs}/lib";
|
||||||
mkPkgs = arg:
|
mkPkgs =
|
||||||
|
arg:
|
||||||
let
|
let
|
||||||
argAttr = if builtins.isString arg then { system = arg; } else arg;
|
argAttr = if builtins.isString arg then { system = arg; } else arg;
|
||||||
config = { allowUnfree = true; } // (argAttr.config or {});
|
config = {
|
||||||
in import nixpkgs (argAttr // { inherit config; });
|
allowUnfree = true;
|
||||||
|
} // (argAttr.config or { });
|
||||||
|
in
|
||||||
|
import nixpkgs (argAttr // { inherit config; });
|
||||||
pkgs = mkPkgs x86;
|
pkgs = mkPkgs x86;
|
||||||
mkNixosConfig =
|
mkNixosConfig =
|
||||||
{
|
{
|
||||||
@@ -349,7 +353,9 @@
|
|||||||
# snmpb = pkgs.libsForQt5.callPackage ./packages/snmpb/package.nix { };
|
# snmpb = pkgs.libsForQt5.callPackage ./packages/snmpb/package.nix { };
|
||||||
# snmp-mibs-downloader = pkgs.callPackage ./packages/snmp-mibs-downloader.nix { };
|
# snmp-mibs-downloader = pkgs.callPackage ./packages/snmp-mibs-downloader.nix { };
|
||||||
authorizedKeys = pkgs.writeText "authorizedKeys" (
|
authorizedKeys = pkgs.writeText "authorizedKeys" (
|
||||||
lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${v} ${k}") plain.config.vacu.ssh.authorizedKeys)
|
lib.concatStringsSep "\n" (
|
||||||
|
lib.mapAttrsToList (k: v: "${v} ${k}") plain.config.vacu.ssh.authorizedKeys
|
||||||
|
)
|
||||||
);
|
);
|
||||||
sopsConfig = plain.config.vacu.sopsConfig;
|
sopsConfig = plain.config.vacu.sopsConfig;
|
||||||
nixvim = inputs.nixvim.legacyPackages.${system}.makeNixvimWithModule {
|
nixvim = inputs.nixvim.legacyPackages.${system}.makeNixvimWithModule {
|
||||||
|
@@ -4,7 +4,13 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib.strings) concatStringsSep splitString match replaceStrings concatStrings;
|
inherit (lib.strings)
|
||||||
|
concatStringsSep
|
||||||
|
splitString
|
||||||
|
match
|
||||||
|
replaceStrings
|
||||||
|
concatStrings
|
||||||
|
;
|
||||||
inherit (lib.lists) reverseList length elemAt;
|
inherit (lib.lists) reverseList length elemAt;
|
||||||
email_folders = [
|
email_folders = [
|
||||||
"24nm-domain@shelvacu.com"
|
"24nm-domain@shelvacu.com"
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
writers,
|
writers,
|
||||||
curl,
|
curl,
|
||||||
sops,
|
sops,
|
||||||
lib
|
lib,
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
sopsCommand = [
|
sopsCommand = [
|
||||||
@@ -21,7 +21,7 @@ let
|
|||||||
];
|
];
|
||||||
in
|
in
|
||||||
writers.writeScriptBin "update-gitea-keys" ''
|
writers.writeScriptBin "update-gitea-keys" ''
|
||||||
age_key=$(ssh-to-age -private-key -i $HOME/.ssh/id_ed25519)
|
age_key=$(ssh-to-age -private-key -i $HOME/.ssh/id_ed25519)
|
||||||
gitea_api_key="$(SOPS_AGE_KEY="$age_key" sops --config ${../.sops.yaml} --extract '["git.uninsane.org"]' -d ${../secrets/misc/git-keys.json})"
|
gitea_api_key="$(SOPS_AGE_KEY="$age_key" sops --config ${../.sops.yaml} --extract '["git.uninsane.org"]' -d ${../secrets/misc/git-keys.json})"
|
||||||
curl
|
curl
|
||||||
''
|
''
|
||||||
|
@@ -22,17 +22,17 @@ let
|
|||||||
(lib.filter (c: c.enable))
|
(lib.filter (c: c.enable))
|
||||||
];
|
];
|
||||||
serviceValidDomainAssertions = map (proxiedConfig: {
|
serviceValidDomainAssertions = map (proxiedConfig: {
|
||||||
assertion = lib.any (availableDomain:
|
assertion = lib.any (
|
||||||
(lib.hasSuffix ("." + availableDomain) proxiedConfig.domain) ||
|
availableDomain:
|
||||||
(proxiedConfig.domain == availableDomain)
|
(lib.hasSuffix ("." + availableDomain) proxiedConfig.domain)
|
||||||
|
|| (proxiedConfig.domain == availableDomain)
|
||||||
) domains;
|
) domains;
|
||||||
message = "proxiedService ${proxiedConfig.name}'s `domain` does not match any of the known domains";
|
message = "proxiedService ${proxiedConfig.name}'s `domain` does not match any of the known domains";
|
||||||
}) proxied;
|
}) proxied;
|
||||||
mapListToAttrs = f: list: lib.listToAttrs (map f list);
|
mapListToAttrs = f: list: lib.listToAttrs (map f list);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assertions = [ ]
|
assertions = [ ] ++ serviceValidDomainAssertions;
|
||||||
++ serviceValidDomainAssertions;
|
|
||||||
security.acme.acceptTerms = true;
|
security.acme.acceptTerms = true;
|
||||||
security.acme.defaults = {
|
security.acme.defaults = {
|
||||||
email = "nix-acme@shelvacu.com";
|
email = "nix-acme@shelvacu.com";
|
||||||
@@ -44,8 +44,8 @@ in
|
|||||||
postRun = "${pkgs.nixos-container}/bin/nixos-container run frontproxy -- systemctl reload haproxy";
|
postRun = "${pkgs.nixos-container}/bin/nixos-container run frontproxy -- systemctl reload haproxy";
|
||||||
};
|
};
|
||||||
|
|
||||||
security.acme.certs = mapListToAttrs (domain:
|
security.acme.certs = mapListToAttrs (
|
||||||
lib.nameValuePair domain { extraDomainNames = [ "*.${domain}" ]; }
|
domain: lib.nameValuePair domain { extraDomainNames = [ "*.${domain}" ]; }
|
||||||
) domains;
|
) domains;
|
||||||
|
|
||||||
users.groups.acme.gid = 993;
|
users.groups.acme.gid = 993;
|
||||||
@@ -69,10 +69,13 @@ in
|
|||||||
autoStart = true;
|
autoStart = true;
|
||||||
restartIfChanged = true;
|
restartIfChanged = true;
|
||||||
ephemeral = true;
|
ephemeral = true;
|
||||||
bindMounts = mapListToAttrs (d: lib.nameValuePair "/certs/${d}" {
|
bindMounts = mapListToAttrs (
|
||||||
hostPath = outer_config.security.acme.certs.${d}.directory;
|
d:
|
||||||
isReadOnly = true;
|
lib.nameValuePair "/certs/${d}" {
|
||||||
}) domains;
|
hostPath = outer_config.security.acme.certs.${d}.directory;
|
||||||
|
isReadOnly = true;
|
||||||
|
}
|
||||||
|
) domains;
|
||||||
config =
|
config =
|
||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
{
|
{
|
||||||
|
@@ -6,93 +6,103 @@
|
|||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
enableKeylog = false;
|
enableKeylog = false;
|
||||||
cleanName = name: lib.replaceStrings ["-" " "] [ "_" "_" ] name;
|
cleanName =
|
||||||
|
name:
|
||||||
|
lib.replaceStrings
|
||||||
|
[
|
||||||
|
"-"
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"_"
|
||||||
|
"_"
|
||||||
|
]
|
||||||
|
name;
|
||||||
aclName = config: "host_" + (cleanName config.name);
|
aclName = config: "host_" + (cleanName config.name);
|
||||||
backendName = config: "backend_" + (cleanName config.name);
|
backendName = config: "backend_" + (cleanName config.name);
|
||||||
concatMap = sep: f: list: lib.concatStringsSep sep (map f list);
|
concatMap =
|
||||||
|
sep: f: list:
|
||||||
|
lib.concatStringsSep sep (map f list);
|
||||||
mapLines = f: list: concatMap "\n" f list;
|
mapLines = f: list: concatMap "\n" f list;
|
||||||
certs = concatMap " " (d: "crt /certs/${d}/full.pem") domains;
|
certs = concatMap " " (d: "crt /certs/${d}/full.pem") domains;
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
${lib.optionalString enableKeylog ''
|
${lib.optionalString enableKeylog ''
|
||||||
# ssl keylogging
|
# ssl keylogging
|
||||||
|
global
|
||||||
|
tune.ssl.keylog on
|
||||||
|
lua-load ${./sslkeylog.lua}
|
||||||
|
''}
|
||||||
|
|
||||||
global
|
global
|
||||||
tune.ssl.keylog on
|
close-spread-time 1s
|
||||||
lua-load ${./sslkeylog.lua}
|
hard-stop-after 3s
|
||||||
''}
|
description "triple-dezert frontproxy"
|
||||||
|
no insecure-fork-wanted
|
||||||
global
|
log stdout format short daemon
|
||||||
close-spread-time 1s
|
numa-cpu-mapping
|
||||||
hard-stop-after 3s
|
tune.listener.default-shards by-thread
|
||||||
description "triple-dezert frontproxy"
|
tune.ssl.lifetime 24h
|
||||||
no insecure-fork-wanted
|
zero-warning
|
||||||
log stdout format short daemon
|
log 127.0.0.1 syslog debug
|
||||||
numa-cpu-mapping
|
|
||||||
tune.listener.default-shards by-thread
|
|
||||||
tune.ssl.lifetime 24h
|
|
||||||
zero-warning
|
|
||||||
log 127.0.0.1 syslog debug
|
|
||||||
|
|
||||||
|
|
||||||
defaults
|
defaults
|
||||||
# https://world.hey.com/goekesmi/haproxy-chrome-tcp-preconnect-and-error-408-a-post-preserved-from-the-past-2497d1f7
|
# https://world.hey.com/goekesmi/haproxy-chrome-tcp-preconnect-and-error-408-a-post-preserved-from-the-past-2497d1f7
|
||||||
timeout server 30s
|
timeout server 30s
|
||||||
timeout client 10s
|
timeout client 10s
|
||||||
timeout connect 10s
|
timeout connect 10s
|
||||||
option http-ignore-probes
|
option http-ignore-probes
|
||||||
|
|
||||||
timeout tunnel 1h
|
timeout tunnel 1h
|
||||||
log global
|
log global
|
||||||
mode http
|
|
||||||
option httplog
|
|
||||||
|
|
||||||
frontend main
|
|
||||||
bind :80
|
|
||||||
bind :443 ssl ${certs}
|
|
||||||
|
|
||||||
mode http
|
|
||||||
|
|
||||||
acl has_sni ssl_fc_sni -m found
|
|
||||||
acl has_host_hdr req.fhdr(host) -m found
|
|
||||||
|
|
||||||
http-request set-var(req.host) req.fhdr(host),host_only
|
|
||||||
# Check whether the client is attempting domain fronting.
|
|
||||||
acl ssl_sni_http_host_match ssl_fc_sni,strcmp(req.host) eq 0
|
|
||||||
|
|
||||||
${mapLines (c:
|
|
||||||
'' acl ${aclName c} var(req.host) -m str "${c.domain}"''
|
|
||||||
) proxied}
|
|
||||||
|
|
||||||
http-after-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" if { ssl_fc }
|
|
||||||
|
|
||||||
http-request deny status 400 if !{ req.fhdr_cnt(host) eq 1 }
|
|
||||||
http-request deny status 421 if has_sni has_host_hdr !ssl_sni_http_host_match
|
|
||||||
http-request return lf-string "%ci\n" content-type text/plain if { var(req.host) -m str "shelvacu.com" } { path /ip }
|
|
||||||
http-request redirect scheme https code 301 if !{ ssl_fc }
|
|
||||||
|
|
||||||
# garunteed ssl-only from here on
|
|
||||||
|
|
||||||
${mapLines (d:
|
|
||||||
'' http-request redirect location "https://${d}%[capture.req.uri]" code 301 if { var(req.host) -m str "www.${d}" }''
|
|
||||||
) domains}
|
|
||||||
http-request return string "Shelvacu is awesome" content-type text/plain if { path / } { var(req.host) -m str "shelvacu.com" }
|
|
||||||
http-request return string "Jean-luc is awesome" content-type text/plain if { path / } { var(req.host) -m str "jean-luc.org" }
|
|
||||||
|
|
||||||
${mapLines (c:
|
|
||||||
'' http-request allow if ${aclName c}''
|
|
||||||
) proxied}
|
|
||||||
http-request return status 404 string "not found" content-type text/plain
|
|
||||||
|
|
||||||
${mapLines (c:
|
|
||||||
'' use_backend ${backendName c} if ${aclName c}''
|
|
||||||
) proxied}
|
|
||||||
|
|
||||||
${concatMap "\n\n" (c:
|
|
||||||
''
|
|
||||||
backend ${backendName c}
|
|
||||||
mode http
|
mode http
|
||||||
${lib.optionalString c.forwardFor "option forwardfor"}
|
option httplog
|
||||||
server main ${c.name}:${builtins.toString c.port} check maxconn ${builtins.toString c.maxConnections} ${if c.useSSL then "ssl verify none ssl-reuse" else "proto h1"}
|
|
||||||
''
|
frontend main
|
||||||
) proxied}
|
bind :80
|
||||||
|
bind :443 ssl ${certs}
|
||||||
|
|
||||||
|
mode http
|
||||||
|
|
||||||
|
acl has_sni ssl_fc_sni -m found
|
||||||
|
acl has_host_hdr req.fhdr(host) -m found
|
||||||
|
|
||||||
|
http-request set-var(req.host) req.fhdr(host),host_only
|
||||||
|
# Check whether the client is attempting domain fronting.
|
||||||
|
acl ssl_sni_http_host_match ssl_fc_sni,strcmp(req.host) eq 0
|
||||||
|
|
||||||
|
${mapLines (c: ''acl ${aclName c} var(req.host) -m str "${c.domain}"'') proxied}
|
||||||
|
|
||||||
|
http-after-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" if { ssl_fc }
|
||||||
|
|
||||||
|
http-request deny status 400 if !{ req.fhdr_cnt(host) eq 1 }
|
||||||
|
http-request deny status 421 if has_sni has_host_hdr !ssl_sni_http_host_match
|
||||||
|
http-request return lf-string "%ci\n" content-type text/plain if { var(req.host) -m str "shelvacu.com" } { path /ip }
|
||||||
|
http-request redirect scheme https code 301 if !{ ssl_fc }
|
||||||
|
|
||||||
|
# garunteed ssl-only from here on
|
||||||
|
|
||||||
|
${
|
||||||
|
mapLines (
|
||||||
|
d:
|
||||||
|
''http-request redirect location "https://${d}%[capture.req.uri]" code 301 if { var(req.host) -m str "www.${d}" }''
|
||||||
|
) domains
|
||||||
|
}
|
||||||
|
http-request return string "Shelvacu is awesome" content-type text/plain if { path / } { var(req.host) -m str "shelvacu.com" }
|
||||||
|
http-request return string "Jean-luc is awesome" content-type text/plain if { path / } { var(req.host) -m str "jean-luc.org" }
|
||||||
|
|
||||||
|
${mapLines (c: ''http-request allow if ${aclName c}'') proxied}
|
||||||
|
http-request return status 404 string "not found" content-type text/plain
|
||||||
|
|
||||||
|
${mapLines (c: ''use_backend ${backendName c} if ${aclName c}'') proxied}
|
||||||
|
|
||||||
|
${concatMap "\n\n" (c: ''
|
||||||
|
backend ${backendName c}
|
||||||
|
mode http
|
||||||
|
${lib.optionalString c.forwardFor "option forwardfor"}
|
||||||
|
server main ${c.name}:${builtins.toString c.port} check maxconn ${builtins.toString c.maxConnections} ${
|
||||||
|
if c.useSSL then "ssl verify none ssl-reuse" else "proto h1"
|
||||||
|
}
|
||||||
|
'') proxied}
|
||||||
''
|
''
|
||||||
|
@@ -3,12 +3,14 @@ let
|
|||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
outerConfig = config;
|
outerConfig = config;
|
||||||
ip4Segment = ''[0-9]{1,3}'';
|
ip4Segment = ''[0-9]{1,3}'';
|
||||||
ip4Address = types.addCheck
|
ip4Address = types.addCheck (types.strMatching (
|
||||||
(types.strMatching (lib.concatStringsSep ''\.'' [ip4Segment ip4Segment ip4Segment ip4Segment]))
|
lib.concatStringsSep ''\.'' [
|
||||||
(s:
|
ip4Segment
|
||||||
lib.all (p: (lib.toInt p) < 255) (lib.splitString "." s)
|
ip4Segment
|
||||||
)
|
ip4Segment
|
||||||
;
|
ip4Segment
|
||||||
|
]
|
||||||
|
)) (s: lib.all (p: (lib.toInt p) < 255) (lib.splitString "." s));
|
||||||
# Note: This accepts plenty of strings that aren't valid ipv6 addresses, this is just to catch when you accidentally put an ipv4 or something else in
|
# Note: This accepts plenty of strings that aren't valid ipv6 addresses, this is just to catch when you accidentally put an ipv4 or something else in
|
||||||
ip6Address = types.strMatching ''([a-fA-F0-9]{4}::?){1,7}[a-fA-F0-9]{4}'';
|
ip6Address = types.strMatching ''([a-fA-F0-9]{4}::?){1,7}[a-fA-F0-9]{4}'';
|
||||||
ipAddress = types.either ip4Address ip6Address;
|
ipAddress = types.either ip4Address ip6Address;
|
||||||
@@ -16,41 +18,58 @@ in
|
|||||||
{
|
{
|
||||||
# vacu.proxiedServices.habitat
|
# vacu.proxiedServices.habitat
|
||||||
options.vacu.proxiedServices = mkOption {
|
options.vacu.proxiedServices = mkOption {
|
||||||
default = {};
|
default = { };
|
||||||
type = types.attrsOf (types.submodule ({name, config, ...}: {
|
type = types.attrsOf (
|
||||||
options = {
|
types.submodule (
|
||||||
enable = mkOption { type = types.bool; default = false; };
|
{ name, config, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
default = name;
|
default = name;
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
fromContainer = mkOption {
|
fromContainer = mkOption {
|
||||||
default = null;
|
default = null;
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
port = mkOption { type = types.port; };
|
port = mkOption { type = types.port; };
|
||||||
|
|
||||||
ipAddress = mkOption {
|
ipAddress = mkOption {
|
||||||
type = ipAddress;
|
type = ipAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
domain = mkOption { type = types.str; };
|
domain = mkOption { type = types.str; };
|
||||||
|
|
||||||
forwardFor = mkOption { type = types.bool; default = false; };
|
forwardFor = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
maxConnections = mkOption { type = types.int; default = 500; };
|
maxConnections = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 500;
|
||||||
|
};
|
||||||
|
|
||||||
useSSL = mkOption { type = types.bool; default = false; };
|
useSSL = mkOption {
|
||||||
};
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkMerge [
|
config = lib.mkMerge [
|
||||||
(lib.mkIf (config.fromContainer != null) {
|
(lib.mkIf (config.fromContainer != null) {
|
||||||
ipAddress = outerConfig.containers.${config.fromContainer}.localAddress;
|
ipAddress = outerConfig.containers.${config.fromContainer}.localAddress;
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
}));
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
{ ... }: {
|
{ ... }:
|
||||||
|
{
|
||||||
vacu.proxiedServices.habitat = {
|
vacu.proxiedServices.habitat = {
|
||||||
domain = "habitat.pwrhs.win";
|
domain = "habitat.pwrhs.win";
|
||||||
ipAddress = "10.78.79.114";
|
ipAddress = "10.78.79.114";
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
config, ...
|
config,
|
||||||
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
contain = config.containers.llm;
|
contain = config.containers.llm;
|
||||||
|
@@ -25,13 +25,12 @@
|
|||||||
isReadOnly = true;
|
isReadOnly = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
config =
|
config = {
|
||||||
{
|
system.stateVersion = "23.11";
|
||||||
system.stateVersion = "23.11";
|
networking.firewall.enable = false;
|
||||||
networking.firewall.enable = false;
|
|
||||||
|
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
services.nginx.virtualHosts."tulpaudcast.jean-luc.org".root = "/static-stuff/tulpaudcast.jean-luc.org";
|
services.nginx.virtualHosts."tulpaudcast.jean-luc.org".root = "/static-stuff/tulpaudcast.jean-luc.org";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user