many changes
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
create_users = host: {
|
||||
users.users."${host.username}" = {
|
||||
createHome = false;
|
||||
home = "/home/chroot/" + host.username;
|
||||
isNormalUser = false;
|
||||
isSystemUser = true;
|
||||
group = "sftp_users";
|
||||
openssh.authorizedKeys.keys = [host.key];
|
||||
shell = null;
|
||||
};
|
||||
};
|
||||
|
||||
users = [
|
||||
{
|
||||
username = "notebook";
|
||||
key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDN/2SAFm50kraB1fepAizox/QRXxB7WbqVbH+5OPalDT47VIJGNKOKhixQoqhABHxEoLxdf/C83wxlCVlPV9poLfDgVkA3Lyt5r3tSFQ6QjjOJAgchWamMsxxyGBedhKvhiEzcr/Lxytnoz3kjDG8fqQJwEpdqMmJoMUfyL2Rqp16u+FQ7d5aJtwO8EUqovhMaNO7rggjPpV/uMOg+tBxxmscliN7DLuP4EMTA/FwXVzcFNbOx3K9BdpMRAaSJt4SWcJO2cS2KHA5n/H+PQI7nz5KN3Yr/upJN5fROhi/SHvK39QOx12Pv7FCuWlc+oR68vLaoCKYhnkl3DnCfc7A7";
|
||||
}
|
||||
];
|
||||
in {
|
||||
imports = builtins.map create_users users;
|
||||
|
||||
users.groups = {sftp_users = {};};
|
||||
|
||||
services.openssh.extraConfig = ''
|
||||
Match Group sftp_users
|
||||
X11Forwarding no
|
||||
AllowTcpForwarding no
|
||||
ChrootDirectory %h
|
||||
ForceCommand internal-sftp
|
||||
'';
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
ldapConfig = {
|
||||
vaultwarden_url = "https://bitwarden.cloonar.com";
|
||||
vaultwarden_admin_token = "@ADMIN_TOKEN@";
|
||||
ldap_host = "localhost";
|
||||
ldap_bind_dn = "cn=vmail,dc=cloonar,dc=com";
|
||||
ldap_bind_password = "@LDAP_PASSWORD@";
|
||||
ldap_search_base_dn = "dc=cloonar,dc=com";
|
||||
ldap_search_filter = "(&(objectClass=inetOrgPerson))";
|
||||
ldap_sync_interval_seconds = 3600;
|
||||
};
|
||||
|
||||
ldapConfigFile =
|
||||
pkgs.runCommand "config.toml"
|
||||
{
|
||||
buildInputs = [pkgs.remarshal];
|
||||
preferLocalBuild = true;
|
||||
} ''
|
||||
remarshal -if json -of toml \
|
||||
< ${pkgs.writeText "config.json" (builtins.toJSON ldapConfig)} \
|
||||
> $out
|
||||
'';
|
||||
in {
|
||||
packageOverrides = pkgs: {
|
||||
nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") {
|
||||
inherit pkgs;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
nur.repos.mic92.vaultwarden_ldap
|
||||
];
|
||||
|
||||
services.vaultwarden = {
|
||||
enable = true;
|
||||
dbBackend = "mysql";
|
||||
config = {
|
||||
domain = "https://bitwarden.cloonar.com";
|
||||
signupsAllowed = false;
|
||||
rocketPort = 3011;
|
||||
databaseUrl = "mysql://bitwarden:<${config.sops.secrets.bitwarden-db-password.path}@localhost/bitwarden";
|
||||
enableDbWal = "false";
|
||||
websocketEnabled = true;
|
||||
smtpHost = "smtp.cloonar.com";
|
||||
smtpFrom = "bitwarden@cloonar.com";
|
||||
smtpUsername = "bitwarden@cloonar.com";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.vaultwarden.serviceConfig = {
|
||||
EnvironmentFile = [config.sops.secrets.bitwarden-smtp-password.path];
|
||||
};
|
||||
|
||||
systemd.services.vaultwarden_ldap = {
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
||||
preStart = ''
|
||||
sed \
|
||||
-e "s=@LDAP_PASSWORD@=$(<${config.sops.secrets.bitwarden-ldap-password.path})=" \
|
||||
-e "s=@ADMIN_TOKEN@=$(<${config.sops.secrets.bitwarden-admin-token.path})=" \
|
||||
${ldapConfigFile} \
|
||||
> /run/vaultwarden_ldap/config.toml
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Restart = "on-failure";
|
||||
RestartSec = "2s";
|
||||
ExecStart = "${config.nur.repos.mic92.vaultwarden_ldap}/bin/vaultwarden_ldap";
|
||||
Environment = "CONFIG_PATH=/run/vaultwarden_ldap/config.toml";
|
||||
|
||||
RuntimeDirectory = ["vaultwarden_ldap"];
|
||||
User = "vaultwarden_ldap";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
virtualHosts."bitwarden.cloonar.com" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
extraConfig = ''
|
||||
client_max_body_size 128M;
|
||||
'';
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:3011";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
locations."/notifications/hub" = {
|
||||
proxyPass = "http://localhost:3012";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
locations."/notifications/hub/negotiate" = {
|
||||
proxyPass = "http://localhost:3011";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets = {
|
||||
bitwarden-admin-token.owner = "vaultwarden_ldap";
|
||||
bitwarden-ldap-password.owner = "vaultwarden_ldap";
|
||||
bitwarden-db-password.owner = "vaultwarden";
|
||||
bitwarden-smtp-password.owner = "vaultwarden";
|
||||
};
|
||||
|
||||
users.users.vaultwarden_ldap = {
|
||||
isSystemUser = true;
|
||||
group = "vaultwarden_ldap";
|
||||
};
|
||||
|
||||
users.groups.vaultwarden_ldap = {};
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
let
|
||||
# NixOS 22.11 as of 2023-01-12
|
||||
nixpkgs = builtins.getFlake "github:nixos/nixpkgs/54644f409ab471e87014bb305eac8c50190bcf48";
|
||||
|
||||
sys = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
({ config, pkgs, lib, modulesPath, ... }: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/netboot/netboot-minimal.nix")
|
||||
];
|
||||
config = {
|
||||
## Some useful options for setting up a new system
|
||||
# services.getty.autologinUser = lib.mkForce "root";
|
||||
# users.users.root.openssh.authorizedKeys.keys = [ ... ];
|
||||
# console.keyMap = "de";
|
||||
# hardware.video.hidpi.enable = true;
|
||||
|
||||
system.stateVersion = config.system.nixos.release;
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
run-pixiecore = let
|
||||
hostPkgs = if sys.pkgs.system == builtins.currentSystem
|
||||
then sys.pkgs
|
||||
else nixpkgs.legacyPackages.${builtins.currentSystem};
|
||||
build = sys.config.system.build;
|
||||
in hostPkgs.writers.writeBash "run-pixiecore" ''
|
||||
exec ${hostPkgs.pixiecore}/bin/pixiecore \
|
||||
boot ${build.kernel}/bzImage ${build.netbootRamdisk}/initrd \
|
||||
--cmdline "init=${build.toplevel}/init loglevel=4" \
|
||||
--debug --dhcp-no-bind \
|
||||
--port 64172 --status-port 64172 "$@"
|
||||
'';
|
||||
in
|
||||
run-pixiecore
|
||||
@@ -1,55 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
uuid = "";
|
||||
cfg = config.services.clevis;
|
||||
in
|
||||
{
|
||||
options.services.clevis = {
|
||||
uuid = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = lib.mdDoc ''
|
||||
UUID of device to decrypt with clevis.
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = {
|
||||
environment.systemPackages = with pkgs; [
|
||||
clevis
|
||||
];
|
||||
|
||||
boot.initrd.extraUtilsCommands = ''
|
||||
# clevis dependencies
|
||||
copy_bin_and_libs ${pkgs.curl}/bin/curl
|
||||
copy_bin_and_libs ${pkgs.bash}/bin/bash
|
||||
copy_bin_and_libs ${pkgs.jose}/bin/jose
|
||||
|
||||
# clevis scripts and binaries
|
||||
for i in ${pkgs.clevis}/bin/* ${pkgs.clevis}/bin/.clevis-wrapped; do
|
||||
copy_bin_and_libs "$i"
|
||||
done
|
||||
'';
|
||||
|
||||
boot.initrd.luks.devices."nixos-enc" = {
|
||||
device = "/dev/disk/by-uuid/${cfg.uuid}";
|
||||
preOpenCommands = with pkgs; ''
|
||||
# what would be a sensible way of automating this? at the very least the versions should not be hard coded
|
||||
ln -s ../.. /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${bash.name}
|
||||
ln -s ../.. /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${clevis.name}
|
||||
ln -s ../.. /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${coreutils.name}
|
||||
|
||||
# this runs in the background so that /crypt-ramfs/device gets set up, which implies crypt-askpass
|
||||
# is ready to receive an input which it will write to /crypt-ramfs/passphrase.
|
||||
# for some reason writing that file directly does not seem to work, which is why the pipe is used.
|
||||
# the clevis_luks_unlock_device function is equivalent to the clevis-luks-pass command but avoid
|
||||
# needing to pass the slot argument.
|
||||
# using clevis-luks-unlock directly can successfully open the luks device but requires the name
|
||||
# argument to be passed and will not be detected by the stage-1 luks root stuff.
|
||||
bash -e -c 'while [ ! -f /crypt-ramfs/device ]; do sleep 1; done; . /bin/clevis-luks-common-functions; clevis_luks_unlock_device "$(cat /crypt-ramfs/device)" | cryptsetup-askpass' &
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
hardware.pulseaudio.enable = false;
|
||||
|
||||
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
libinput.enable = true;
|
||||
displayManager.gdm.enable = true;
|
||||
displayManager.defaultSession = "sway";
|
||||
desktopManager.gnome = {
|
||||
enable = true;
|
||||
extraGSettingsOverrides = ''
|
||||
[org.gnome.desktop.interface]
|
||||
gtk-theme='Dracula'
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
dracula-theme
|
||||
gnome.gnome-tweaks
|
||||
gnome.dconf-editor
|
||||
gnomeExtensions.vitals
|
||||
gnomeExtensions.forge
|
||||
];
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
services.gogs = {
|
||||
enable = true;
|
||||
domain = "git.cloonar.com";
|
||||
rootUrl = "http://git.cloonar.com/";
|
||||
httpAddress = "git.cloonar.com";
|
||||
httpPort = 3000;
|
||||
extraConfig = ''
|
||||
[server]
|
||||
EXTERNAL_URL = http://git.cloonar.com/
|
||||
[auth]
|
||||
DISABLE_REGISTRATION = true
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.howdy;
|
||||
ircfg = config.services.ir-toggle;
|
||||
|
||||
# `dark_threshold` is required for X1 Carbon 7th to work
|
||||
configINI = pkgs.runCommand "config.ini" { } ''
|
||||
cat ${cfg.package}/lib/security/howdy/config.ini > $out
|
||||
substituteInPlace $out --replace 'device_path = none' 'device_path = ${cfg.device}'
|
||||
substituteInPlace $out --replace 'dark_threshold = 50' 'dark_threshold = ${
|
||||
toString cfg.dark-threshold
|
||||
}'
|
||||
substituteInPlace $out --replace 'certainty = 3.5' 'certainty = ${
|
||||
toString cfg.certainty
|
||||
}'
|
||||
'';
|
||||
pam-rule = pkgs.lib.mkDefault (pkgs.lib.mkBefore
|
||||
"auth sufficient ${pkgs.pam_python}/lib/security/pam_python.so ${config.services.howdy.package}/lib/security/howdy/pam.py");
|
||||
in {
|
||||
options = {
|
||||
services.ir-toggle = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable Chicony IR Emitter toggler.
|
||||
'';
|
||||
};
|
||||
};
|
||||
services.howdy = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable howdy and PAM module for face recognition.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.howdy;
|
||||
defaultText = "pkgs.howdy";
|
||||
description = ''
|
||||
Howdy package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
device = mkOption {
|
||||
type = types.path;
|
||||
default = "/dev/video0";
|
||||
description = ''
|
||||
Device file connected to the IR sensor.
|
||||
'';
|
||||
};
|
||||
|
||||
certainty = mkOption {
|
||||
type = types.int;
|
||||
default = 3.5;
|
||||
description = ''
|
||||
The certainty of the detected face belonging to the user of the account. On a scale from 1 to 10, values above 5 are not recommended.
|
||||
'';
|
||||
};
|
||||
|
||||
dark-threshold = mkOption {
|
||||
type = types.int;
|
||||
default = 50;
|
||||
description = ''
|
||||
Because of flashing IR emitters, some frames can be completely unlit. Skip the frame if the lowest 1/8 of the histogram is above this percentage of the total. The lower this setting is, the more dark frames are ignored.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package pkgs.ir_toggle ];
|
||||
environment.etc."howdy/config.ini".source = configINI;
|
||||
security.pam.services = {
|
||||
sudo.text = pam-rule; # Sudo
|
||||
login.text = pam-rule; # User login
|
||||
polkit-1.text = pam-rule; # PolKit
|
||||
i3lock.text = pam-rule; # i3lock
|
||||
};
|
||||
powerManagement.resumeCommands =
|
||||
"${pkgs.ir_toggle}/bin/chicony-ir-toggle on";
|
||||
services.udev.packages = [ pkgs.ir_toggle ];
|
||||
};
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
{
|
||||
core = {
|
||||
detection_notice = false;
|
||||
timeout_notice = true;
|
||||
no_confirmation = false;
|
||||
suppress_unknown = false;
|
||||
abort_if_ssh = true;
|
||||
abort_if_lid_closed = true;
|
||||
disabled = false;
|
||||
use_cnn = false;
|
||||
workaround = "off";
|
||||
};
|
||||
|
||||
video = {
|
||||
certainty = 3.5;
|
||||
timeout = 4;
|
||||
device_path = "/dev/video2";
|
||||
warn_no_device = true;
|
||||
max_height = 320;
|
||||
frame_width = -1;
|
||||
frame_height = -1;
|
||||
dark_threshold = 60;
|
||||
recording_plugin = "opencv";
|
||||
device_format = "v4l2";
|
||||
force_mjpeg = false;
|
||||
exposure = -1;
|
||||
rotate = 0;
|
||||
};
|
||||
|
||||
snapshots = {
|
||||
save_failed = false;
|
||||
save_successful = false;
|
||||
};
|
||||
|
||||
rubberstamps = {
|
||||
enabled = false;
|
||||
stamp_rules = "nod 5s failsafe min_distance=12";
|
||||
};
|
||||
|
||||
debug = {
|
||||
end_report = false;
|
||||
verbose_stamps = false;
|
||||
gtk_stdout = false;
|
||||
};
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
pam-rule = pkgs.lib.mkDefault (pkgs.lib.mkBefore
|
||||
''
|
||||
auth sufficient pam_unix.so try_first_pass nullok
|
||||
auth sufficient ${config.services.howdy.package}/lib/security/pam_howdy.so
|
||||
'');
|
||||
pam-sudo-rule = pkgs.lib.mkDefault (pkgs.lib.mkBefore
|
||||
''
|
||||
auth sufficient ${config.services.howdy.package}/lib/security/pam_howdy.so
|
||||
'');
|
||||
cfg = config.services.howdy;
|
||||
irCfg = config.services.linux-enable-ir-emitter;
|
||||
settingsType = pkgs.formats.ini { };
|
||||
in {
|
||||
options = {
|
||||
services.howdy = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable howdy and PAM module for face recognition.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.howdy;
|
||||
defaultText = "pkgs.howdy";
|
||||
description = ''
|
||||
Howdy package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
inherit (settingsType) type;
|
||||
default = import ./config.nix;
|
||||
description = mdDoc ''
|
||||
Howdy configuration file. Refer to
|
||||
<https://github.com/boltgolt/howdy/blob/beta/howdy/src/config.ini>
|
||||
for options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
services.linux-enable-ir-emitter = {
|
||||
enable = mkEnableOption (mdDoc "") // {
|
||||
description = mdDoc ''
|
||||
Whether to enable IR emitter hardware. Designed to be used with the
|
||||
Howdy facial authentication. After enabling the service, configure
|
||||
the emitter with `sudo linux-enable-ir-emitter configure`.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOptionMD pkgs "linux-enable-ir-emitter" {} // {
|
||||
description = mdDoc ''
|
||||
Package to use for the Linux Enable IR Emitter service.
|
||||
'';
|
||||
};
|
||||
|
||||
device = mkOption {
|
||||
type = types.str;
|
||||
default = "video2";
|
||||
description = mdDoc ''
|
||||
IR camera device to depend on. For example, for `/dev/video2`
|
||||
the value would be `video2`. Find this with the command
|
||||
{command}`realpath /dev/v4l/by-path/<generated-driver-name>`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# environment.systemPackages = [ cfg.package pkgs.ir_toggle ];
|
||||
# environment.etc."howdy/config.ini".source = configINI;
|
||||
# security.pam.services = {
|
||||
# sudo.text = pam-rule; # Sudo
|
||||
# login.text = pam-rule; # User login
|
||||
# polkit-1.text = pam-rule; # PolKit
|
||||
# i3lock.text = pam-rule; # i3lock
|
||||
# };
|
||||
# powerManagement.resumeCommands =
|
||||
# "${pkgs.ir_toggle}/bin/chicony-ir-toggle on";
|
||||
# services.udev.packages = [ pkgs.ir_toggle ];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
environment.systemPackages = [ cfg.package irCfg.package ];
|
||||
|
||||
security.pam.services = {
|
||||
sudo.text = pam-sudo-rule; # Sudo
|
||||
login.text = pam-rule; # User login
|
||||
polkit-1.text = pam-rule; # PolKit
|
||||
swaylock.text = pam-rule; # i3lock
|
||||
# gdm-password.text = pam-rule; # i3lock
|
||||
};
|
||||
|
||||
systemd.services.linux-enable-ir-emitter = rec {
|
||||
description = "Enable the infrared emitter";
|
||||
script = "${getExe irCfg.package} run";
|
||||
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
"suspend.target"
|
||||
"hybrid-sleep.target"
|
||||
"hibernate.target"
|
||||
"suspend-then-hibernate.target"
|
||||
];
|
||||
after = wantedBy ++ [ "dev-${irCfg.device}.device" ];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/lib/linux-enable-ir-emitter 0755 root root - -"
|
||||
];
|
||||
environment.etc."linux-enable-ir-emitter".source = "/var/lib/linux-enable-ir-emitter";
|
||||
environment.etc."howdy/config.ini".source = settingsType.generate "howdy-config.ini" cfg.settings;
|
||||
};
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{ config, pkgs, callPackage, ... }:
|
||||
|
||||
{
|
||||
environment.pathsToLink = [ "/libexec" ]; # links /libexec from derivations to /run/current-system/sw
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
|
||||
desktopManager = {
|
||||
xterm.enable = false;
|
||||
};
|
||||
|
||||
windowManager.i3 = {
|
||||
enable = true;
|
||||
extraPackages = with pkgs; [
|
||||
dmenu #application launcher most people use
|
||||
i3status # gives you the default i3 status bar
|
||||
i3lock #default i3 screen locker
|
||||
i3blocks #if you are planning on using i3blocks over i3status
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
{ config, ... }: {
|
||||
services.influxdb = {
|
||||
enable = true;
|
||||
extraConfig = {
|
||||
http = {
|
||||
auth-enabled = true;
|
||||
log-enabled = false;
|
||||
https-enabled = true;
|
||||
https-certificate = "/var/lib/acme/influxdb.cloonar.com/fullchain.pem";
|
||||
https-private-key = "/var/lib/acme/influxdb.cloonar.com/key.pem";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 8086 ];
|
||||
|
||||
security.acme.certs."influxdb.cloonar.com" = {
|
||||
postRun = "systemctl restart influxdb.service";
|
||||
group = "influxdb";
|
||||
};
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
mysqlCreateDatabase = pkgs.writeShellScriptBin "mysql-create-database" ''
|
||||
#!/usr/bin/env bash
|
||||
if [ $# -lt 2 ]
|
||||
then
|
||||
echo "Usage: $0 <database> <host>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DB="$1"
|
||||
HOST="$2"
|
||||
PASSWORD="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64 | xargs)"
|
||||
|
||||
cat <<EOF | mysql --host localhost --user root
|
||||
create database $DB;
|
||||
grant usage on $DB.* to '$DB'@'$HOST' identified by '$PASSWORD';
|
||||
grant all privileges on $DB.* to '$DB'@'$HOST';
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "Password for user $DB is:"
|
||||
echo
|
||||
echo $PASSWORD
|
||||
echo
|
||||
'';
|
||||
mysqlDeleteDatabase = pkgs.writeShellScriptBin "mysql-delete-database" ''
|
||||
#!/usr/bin/env bash
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "Usage: $0 <database>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DB="$1"
|
||||
PASSWORD="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64 | xargs)"
|
||||
|
||||
cat <<EOF | mysql --host localhost --user root
|
||||
drop database $DB;
|
||||
drop user '$DB';
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "Dropped database $DB!"
|
||||
echo
|
||||
'';
|
||||
in {
|
||||
environment.systemPackages = [
|
||||
mysqlCreateDatabase
|
||||
mysqlDeleteDatabase
|
||||
];
|
||||
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb;
|
||||
settings = {
|
||||
mysqld = {
|
||||
max_allowed_packet = "64M";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.mysqlBackup.enable = true;
|
||||
services.mysqlBackup.databases = [ "mysql" ];
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
mysql-scripts = pkgs.callPackage ./pkgs/mysql-scripts.nix {};
|
||||
in {
|
||||
environment.systemPackages = [
|
||||
mysql-scripts
|
||||
];
|
||||
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb;
|
||||
};
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
stdenv,
|
||||
lib,
|
||||
bash,
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
name = "mysql-scripts";
|
||||
src = ./scripts;
|
||||
buildInputs = [ bash ];
|
||||
#nativeBuildInputs = [lib.makeWrapper];
|
||||
installPhase = ''
|
||||
install -D --target $out/bin *
|
||||
'';
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "Usage: $0 <database>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DB="$1"
|
||||
PASSWORD="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64 | xargs)"
|
||||
|
||||
cat <<EOF | mysql --host localhost --user root
|
||||
create database $DB;
|
||||
grant usage on $DB.* to '$DB'@'%' identified by '$PASSWORD';
|
||||
grant all privileges on $DB.* to '$DB'@'%';
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "Password for user $DB is:"
|
||||
echo
|
||||
echo $PASSWORD
|
||||
echo
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "Usage: $0 <database>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DB="$1"
|
||||
PASSWORD="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64 | xargs)"
|
||||
|
||||
cat <<EOF | mysql --host localhost --user root
|
||||
drop database $DB;
|
||||
drop user '$DB';
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "Dropped database $DB!"
|
||||
echo
|
||||
@@ -1,135 +0,0 @@
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
domain = "cloonar.dev";
|
||||
dataDir = "/var/www/${domain}";
|
||||
in {
|
||||
systemd.services."phpfpm-${domain}".serviceConfig.ProtectHome = lib.mkForce false;
|
||||
|
||||
services.phpfpm.pools."${domain}" = {
|
||||
user = domain;
|
||||
settings = {
|
||||
"listen.owner" = config.services.nginx.user;
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.max_requests" = 500;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 5;
|
||||
"php_admin_value[error_log]" = "stderr";
|
||||
"php_admin_flag[log_errors]" = true;
|
||||
"catch_workers_output" = true;
|
||||
"access.log" = "/var/log/$pool.access.log";
|
||||
};
|
||||
phpPackage = pkgs.php81;
|
||||
phpEnv."PATH" = lib.makeBinPath [ pkgs.php81 ];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."cloonar.dev" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
root = "${dataDir}";
|
||||
|
||||
locations."/favicon.ico".extraConfig = ''
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
'';
|
||||
|
||||
# TYPO3 - Rule for versioned static files, configured through:
|
||||
# - $GLOBALS['TYPO3_CONF_VARS']['BE']['versionNumberInFilename']
|
||||
# - $GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename']
|
||||
|
||||
extraConfig = ''
|
||||
if (!-e $request_filename) {
|
||||
rewrite ^/(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ /$1.$3 last;
|
||||
}
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to composer files
|
||||
locations."~* composer\.(?:json|lock)".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
|
||||
# TYPO3 - Block access to flexform files
|
||||
locations."~* flexform[^.]*\.xml".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to language files
|
||||
locations."~* locallang[^.]*\.(?:xml|xlf)$".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to static typoscript files
|
||||
locations."~* ext_conf_template\.txt|ext_typoscript_constants\.txt|ext_typoscript_setup\.txt".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to miscellaneous protected files
|
||||
locations."~* /.*\.(?:bak|co?nf|cfg|ya?ml|ts|typoscript|tsconfig|dist|fla|in[ci]|log|sh|sql|sqlite)$".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to recycler and temporary directories
|
||||
locations."~ _(?:recycler|temp)_/".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to configuration files stored in fileadmin
|
||||
locations."~ fileadmin/(?:templates)/.*\.(?:txt|ts|typoscript)$".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
|
||||
# TYPO3 - Block access to libraries, source and temporary compiled data
|
||||
locations."~ ^(?:vendor|typo3_src|typo3temp/var)".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
|
||||
# TYPO3 - Block access to protected extension directories
|
||||
locations."~ (?:typo3conf/ext|typo3/sysext|typo3/ext)/[^/]+/(?:Configuration|Resources/Private|Tests?|Documentation|docs?)/".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
locations."/".extraConfig = ''
|
||||
index index.php index.html;
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
'';
|
||||
|
||||
# TYPO3 Backend URLs
|
||||
locations."/typo3".extraConfig = ''
|
||||
rewrite ^ /typo3/;
|
||||
'';
|
||||
|
||||
locations."/typo3/".extraConfig = ''
|
||||
try_files $uri /typo3/index.php$is_args$args;
|
||||
'';
|
||||
|
||||
locations."~ [^/]\.php(/|$)".extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) {
|
||||
return 404;
|
||||
}
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
fastcgi_buffer_size 32k;
|
||||
fastcgi_buffers 8 16k;
|
||||
fastcgi_connect_timeout 240s;
|
||||
fastcgi_read_timeout 240s;
|
||||
fastcgi_send_timeout 240s;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools."${domain}".socket};
|
||||
fastcgi_index index.php;
|
||||
'';
|
||||
};
|
||||
users.users."${domain}" = {
|
||||
isSystemUser = true;
|
||||
createHome = true;
|
||||
home = dataDir;
|
||||
homeMode= "770";
|
||||
#home = "/home/${domain}";
|
||||
group = "nginx";
|
||||
};
|
||||
users.groups.${domain} = {};
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
|
||||
imports = [
|
||||
./cloonar.dev.nix
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
imagemagick
|
||||
ghostscript
|
||||
];
|
||||
|
||||
systemd.services.nginx.serviceConfig.ProtectHome = "read-only";
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
||||
|
||||
commonHttpConfig = ''
|
||||
# Add HSTS header with preloading to HTTPS requests.
|
||||
# Adding this header to HTTP requests is discouraged
|
||||
map $scheme $hsts_header {
|
||||
https "max-age=31536000; includeSubdomains; preload";
|
||||
}
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
|
||||
# Enable CSP for your services.
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
|
||||
# Minimize information leaked to other domains
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
|
||||
# Disable embedding as a frame
|
||||
add_header X-Frame-Options DENY;
|
||||
|
||||
# Prevent injection of code in other mime types (XSS Attacks)
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
# Enable XSS protection of the browser.
|
||||
# May be unnecessary when CSP is configured properly (see above)
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# This might create errors
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
|
||||
imports = [
|
||||
./cloonar.dev.nix
|
||||
];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
||||
|
||||
commonHttpConfig = ''
|
||||
# Add HSTS header with preloading to HTTPS requests.
|
||||
# Adding this header to HTTP requests is discouraged
|
||||
map $scheme $hsts_header {
|
||||
https "max-age=31536000; includeSubdomains; preload";
|
||||
}
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
|
||||
# Enable CSP for your services.
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
|
||||
# Minimize information leaked to other domains
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
|
||||
# Disable embedding as a frame
|
||||
add_header X-Frame-Options DENY;
|
||||
|
||||
# Prevent injection of code in other mime types (XSS Attacks)
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
# Enable XSS protection of the browser.
|
||||
# May be unnecessary when CSP is configured properly (see above)
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# This might create errors
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
#(import <nixpkgs> {}).callPackage (builtins.fetchurl "https://raw.githubusercontent.com/delroth/infra.delroth.net/master/pkgs/parsec.nix") {}
|
||||
#(import <nixpkgs> {}).callPackage (builtins.fetchurl "https://raw.githubusercontent.com/delroth/infra.delroth.net/38a040e4bbfef7ee13c4b0a75dc79c77ddfdc759/pkgs/parsec.nix") {}
|
||||
@@ -1,112 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.room-assistant;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.room-assistant = {
|
||||
enable = mkEnableOption (lib.mdDoc "room-assistant");
|
||||
|
||||
name = mkOption {
|
||||
type = with types; uniq string;
|
||||
description = "
|
||||
...
|
||||
";
|
||||
default = "room";
|
||||
};
|
||||
|
||||
mqttHost = mkOption {
|
||||
type = with types; uniq string;
|
||||
description = "
|
||||
...
|
||||
";
|
||||
default = "";
|
||||
};
|
||||
|
||||
mqttUser = mkOption {
|
||||
type = with types; uniq string;
|
||||
description = "
|
||||
...
|
||||
";
|
||||
default = "espresense";
|
||||
};
|
||||
|
||||
mqttPassword = mkOption {
|
||||
type = with types; uniq string;
|
||||
description = "
|
||||
...
|
||||
";
|
||||
default = "insecure-password";
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
hardware = {
|
||||
bluetooth.enable = true;
|
||||
deviceTree.filter = "bcm2711-rpi-*.dtb";
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
btattach = {
|
||||
before = [ "bluetooth.service" ];
|
||||
after = [ "dev-ttyAMA0.device" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.bluez}/bin/btattach -B /dev/ttyAMA0 -P bcm -S 3000000";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation.docker.enable = true;
|
||||
|
||||
environment.etc."room-assistant.yml" = {
|
||||
text = ''
|
||||
global:
|
||||
instanceName: ${cfg.name}
|
||||
integrations:
|
||||
- homeAssistant
|
||||
- bluetoothClassic
|
||||
homeAssistant:
|
||||
mqttUrl: 'mqtt://${cfg.mqttHost}'
|
||||
mqttOptions:
|
||||
username: ${cfg.mqttUser}
|
||||
password: ${cfg.mqttPassword}
|
||||
bluetoothClassic:
|
||||
addresses:
|
||||
- A8:5B:B7:98:84:F0
|
||||
- 00:24:E4:E6:FE:AD
|
||||
|
||||
'';
|
||||
|
||||
# The UNIX file mode bits
|
||||
mode = "0440";
|
||||
};
|
||||
|
||||
systemd.services."room-assistant" = {
|
||||
description = "room-assistant";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "docker.service" "docker.socket" ];
|
||||
requires = [ "docker.service" "docker.socket" ];
|
||||
script = ''
|
||||
exec ${pkgs.docker}/bin/docker run \
|
||||
--rm \
|
||||
--name=room-assistant \
|
||||
--network=host \
|
||||
-v /var/run/dbus:/var/run/dbus \
|
||||
-v /etc/room-assistant.yml:/room-assistant/config/local.yml \
|
||||
--cap-add=NET_ADMIN \
|
||||
mkerix/room-assistant:2.20.0
|
||||
'';
|
||||
preStop = "${pkgs.docker}/bin/docker stop room-assistant";
|
||||
reload = "${pkgs.docker}/bin/docker restart room-assistant";
|
||||
serviceConfig = {
|
||||
ExecStartPre = "-${pkgs.docker}/bin/docker rm -f room-assistant";
|
||||
ExecStopPost = "-${pkgs.docker}/bin/docker rm -f room-assistant";
|
||||
TimeoutStartSec = 0;
|
||||
TimeoutStopSec = 120;
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
domain = "mail-test.cloonar.com";
|
||||
in
|
||||
{
|
||||
services.roundcube = {
|
||||
enable = true;
|
||||
hostName = "${domain}";
|
||||
extraConfig = ''
|
||||
$config['imap_host'] = 'tls://imap-test.cloonar.com';
|
||||
$config['smtp_server'] = "tls://mail-test.cloonar.com";
|
||||
$config['smtp_user'] = "%u";
|
||||
$config['smtp_pass'] = "%p";
|
||||
'';
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
};
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
domain = "self-service.cloonar.com";
|
||||
php = pkgs.php82;
|
||||
version = "1.5.2";
|
||||
dataDir = "/var/www/${domain}";
|
||||
in {
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
smarty3
|
||||
];
|
||||
|
||||
systemd.services."phpfpm-${domain}".serviceConfig.ProtectHome = lib.mkForce false;
|
||||
|
||||
systemd.services.selfservicepassword_setup = let
|
||||
overrideConfig = pkgs.writeText "nextcloud-config.php" ''
|
||||
<?php
|
||||
$ldap_url = "ldap://ldap-test.cloonar.com:389";
|
||||
$ldap_starttls = true;
|
||||
define("SMARTY", "Smarty.class.php");
|
||||
$use_tokens = false;
|
||||
$use_sms = false;
|
||||
'';
|
||||
in {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "phpfpm-${domain}.service" ];
|
||||
script = ''
|
||||
mkdir -p ${dataDir}/public
|
||||
curl -L https://github.com/ltb-project/self-service-password/archive/refs/tags/v${version}.tar.gz > ${dataDir}/package.tar.gz
|
||||
/run/current-system/sw/bin/tar xf ${dataDir}/package.tar.gz -C ${dataDir}
|
||||
mv ${dataDir}/self-service-password-${version}/* ${dataDir}/public/
|
||||
rm -rf ${dataDir}/self-service-password-${version}
|
||||
cp ${overrideConfig} ${dataDir}/public/conf/config.inc.local.php
|
||||
'';
|
||||
path = [ pkgs.gzip pkgs.curl ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.User = domain;
|
||||
};
|
||||
|
||||
services.phpfpm.pools."${domain}" = {
|
||||
user = domain;
|
||||
settings = {
|
||||
"listen.owner" = config.services.nginx.user;
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.max_requests" = 500;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 5;
|
||||
"php_flag[display_errors]" = "on";
|
||||
"php_admin_value[error_log]" = "/var/log/${domain}.error.log";
|
||||
"php_admin_flag[log_errors]" = "on";
|
||||
"php_value[include_path]" = ".:/usr/share/php:${pkgs.smarty3}";
|
||||
"catch_workers_output" = "yes";
|
||||
"access.log" = "/var/log/$pool.access.log";
|
||||
};
|
||||
phpPackage = php;
|
||||
phpEnv."PATH" = lib.makeBinPath [ php ];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
root = "${dataDir}/public/htdocs";
|
||||
|
||||
locations."/favicon.ico".extraConfig = ''
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
'';
|
||||
|
||||
# extraConfig = ''
|
||||
# if (!-e $request_filename) {
|
||||
# rewrite ^/(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ /$1.$3 last;
|
||||
# }
|
||||
# '';
|
||||
|
||||
locations."/".extraConfig = ''
|
||||
index index.php index.html;
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
'';
|
||||
|
||||
locations."~ [^/]\.php(/|$)".extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) {
|
||||
return 404;
|
||||
}
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
fastcgi_buffer_size 32k;
|
||||
fastcgi_buffers 8 16k;
|
||||
fastcgi_connect_timeout 240s;
|
||||
fastcgi_read_timeout 240s;
|
||||
fastcgi_send_timeout 240s;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools."${domain}".socket};
|
||||
fastcgi_index index.php;
|
||||
'';
|
||||
|
||||
# locations."~ /\.".extraConfig = ''
|
||||
# log_not_found off;
|
||||
# deny all;
|
||||
# '';
|
||||
#
|
||||
# locations."~ /scripts".extraConfig = ''
|
||||
# log_not_found off;
|
||||
# deny all;
|
||||
# '';
|
||||
};
|
||||
users.users."${domain}" = {
|
||||
#isSystemUser = true;
|
||||
isNormalUser = true;
|
||||
createHome = true;
|
||||
home = dataDir;
|
||||
homeMode= "770";
|
||||
group = "nginx";
|
||||
};
|
||||
users.groups.${domain} = {};
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
|
||||
# security.rtkit.enable = true;
|
||||
# services.pipewire = {
|
||||
# enable = true;
|
||||
# alsa.enable = true;
|
||||
# alsa.support32Bit = true;
|
||||
# pulse.enable = true;
|
||||
#
|
||||
# };
|
||||
sound.enable = true;
|
||||
hardware.pulseaudio.enable = true;
|
||||
hardware.pulseaudio.support32Bit = true;
|
||||
services.getty.autologinUser = "snapclient";
|
||||
|
||||
users.groups.snapclient = {};
|
||||
users.users.snapclient = {
|
||||
isNormalUser = true;
|
||||
group = "snapclient";
|
||||
extraGroups = [ "audio" "pipewire" ];
|
||||
};
|
||||
|
||||
systemd.user.services.snapclient = {
|
||||
wantedBy = [
|
||||
"default.target"
|
||||
];
|
||||
after = [
|
||||
"network.target"
|
||||
];
|
||||
serviceConfig = {
|
||||
# User = "snapclient";
|
||||
# Group = "snapclient";
|
||||
ExecStart = "${pkgs.snapcast}/bin/snapclient -h mopidy.cloonar.com -p 1704 --player pulse";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
user = "tang";
|
||||
group = "tang";
|
||||
in {
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
jose
|
||||
tang
|
||||
];
|
||||
|
||||
systemd.paths.tangd-update = {
|
||||
pathConfig = {
|
||||
PathChanged = "/var/db/tang";
|
||||
MakeDirectory = true;
|
||||
DirectoryMode = "0700";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.tangd-update = {
|
||||
description = "Tang update";
|
||||
path = [ pkgs.jose ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
StandardError = "journal";
|
||||
ExecStart = "${pkgs.tang}/libexec/tangd-update /var/db/tang /var/cache/tang";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.tangd-keygen = {
|
||||
description = "Tang keygen";
|
||||
documentation = [ "man:tang(8)" ];
|
||||
path = [ pkgs.jose ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
StandardError = "journal";
|
||||
ExecStart = "${pkgs.tang}/libexec/tangd-keygen /var/db/tang";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."tangd@" = {
|
||||
description = "Tang Server";
|
||||
documentation = [ "man:tang(8)" ];
|
||||
path = [ pkgs.jose ];
|
||||
serviceConfig = {
|
||||
|
||||
StandardInput = "socket";
|
||||
StandardOutput = "socket";
|
||||
StandardError = "journal";
|
||||
ExecStart = "${pkgs.tang}/libexec/tangd /var/cache/tang";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.sockets.tangd = {
|
||||
description = "Tang Server socket";
|
||||
documentation = [ "man:tang(8)" ];
|
||||
requires = [
|
||||
"tangd-keygen.service"
|
||||
"tangd-update.service"
|
||||
"tangd-update.path"
|
||||
];
|
||||
after = [
|
||||
"tangd-keygen.service"
|
||||
"tangd-update.service"
|
||||
];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
socketConfig = {
|
||||
ListenStream = 8000;
|
||||
Accept = true;
|
||||
};
|
||||
};
|
||||
|
||||
# users.groups.tang = {};
|
||||
# users.users.tang = {
|
||||
# isSystemUser = true;
|
||||
# group = "tang";
|
||||
# home = "/var/db/tang";
|
||||
# createHome = true;
|
||||
# description = "Tang system user";
|
||||
# };
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
tuxedo = import (builtins.fetchTarball "https://github.com/blitz/tuxedo-nixos/archive/master.tar.gz");
|
||||
in {
|
||||
|
||||
# ...
|
||||
|
||||
imports = [
|
||||
tuxedo.module
|
||||
];
|
||||
|
||||
hardware.tuxedo-control-center.enable = true;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
services.resolved.enable = true;
|
||||
services.openvpn.servers = {
|
||||
epicenterWorks = {
|
||||
config = ''
|
||||
config /etc/nixos/modules/vpn/epicenter.works/vpn.conf
|
||||
|
||||
script-security 2
|
||||
up ${pkgs.update-systemd-resolved}/libexec/openvpn/update-systemd-resolved
|
||||
up-restart
|
||||
down ${pkgs.update-systemd-resolved}/libexec/openvpn/update-systemd-resolved
|
||||
down-pre
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
networking.firewall = {
|
||||
allowedUDPPorts = [ 51820 ]; # Clients and peers can use the same port, see listenport
|
||||
};
|
||||
# Enable WireGuard
|
||||
networking.wireguard.interfaces = {
|
||||
# "wg0" is the network interface name. You can name the interface arbitrarily.
|
||||
wg0 = {
|
||||
# Determines the IP address and subnet of the client's end of the tunnel interface.
|
||||
ips = [ "10.50.60.6/24" ];
|
||||
listenPort = 51820; # to match firewall allowedUDPPorts (without this wg uses random port numbers)
|
||||
|
||||
privateKeyFile = "/run/secrets/wg_private_key";
|
||||
|
||||
postSetup = ''printf "search epicenter.works\nnameserver 10.25.0.10" | ${pkgs.openresolv}/bin/resolvconf -a wg0 -m 0'';
|
||||
|
||||
postShutdown = "${pkgs.openresolv}/bin/resolvconf -d wg0";
|
||||
|
||||
|
||||
peers = [
|
||||
# For a client configuration, one peer entry for the server will suffice.
|
||||
{
|
||||
# Public key of the server (not a file path).
|
||||
publicKey = "T7jPGSapSudtKyWwi2nu+2hjjse96I4U3lccRHZWd2s=";
|
||||
presharedKeyFile = "/run/secrets/wg_preshared_key";
|
||||
|
||||
allowedIPs = [ "10.50.60.0/24" "10.25.0.0/24" ];
|
||||
|
||||
# Set this to the server IP and port.
|
||||
endpoint = "5.9.131.17:51821"; # ToDo: route to endpoint not automatically configured https://wiki.archlinux.org/index.php/WireGuard#Loop_routing https://discourse.nixos.org/t/solved-minimal-firewall-setup-for-wireguard-client/7577
|
||||
|
||||
# Send keepalives every 25 seconds. Important to keep NAT tables alive.
|
||||
persistentKeepalive = 25;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
dev tun
|
||||
persist-tun
|
||||
persist-key
|
||||
cipher AES-128-GCM
|
||||
auth RSA-SHA256
|
||||
client
|
||||
resolv-retry infinite
|
||||
remote vpn.epicenter.works 1195 udp
|
||||
lport 0
|
||||
verify-x509-name "C=AT, ST=Vienna, L=Vienna, O=epicenter_works, emailAddress=team@epicenter.works, CN=epicenter.works VPN Server" subject
|
||||
remote-cert-tls server
|
||||
ca /run/secrets/epicenter_vpn_ca
|
||||
cert /run/secrets/epicenter_vpn_cert
|
||||
key /run/secrets/epicenter_vpn_key
|
||||
@@ -1,135 +0,0 @@
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
domain = "cloonar.dev";
|
||||
dataDir = "/var/www/${domain}";
|
||||
in {
|
||||
systemd.services."phpfpm-${domain}".serviceConfig.ProtectHome = lib.mkForce false;
|
||||
|
||||
services.phpfpm.pools."${domain}" = {
|
||||
user = domain;
|
||||
settings = {
|
||||
"listen.owner" = config.services.nginx.user;
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.max_requests" = 500;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 5;
|
||||
"php_admin_value[error_log]" = "stderr";
|
||||
"php_admin_flag[log_errors]" = true;
|
||||
"catch_workers_output" = true;
|
||||
"access.log" = "/var/log/$pool.access.log";
|
||||
};
|
||||
phpPackage = pkgs.php81;
|
||||
phpEnv."PATH" = lib.makeBinPath [ pkgs.php81 ];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
root = "${dataDir}";
|
||||
|
||||
locations."/favicon.ico".extraConfig = ''
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
'';
|
||||
|
||||
# TYPO3 - Rule for versioned static files, configured through:
|
||||
# - $GLOBALS['TYPO3_CONF_VARS']['BE']['versionNumberInFilename']
|
||||
# - $GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename']
|
||||
|
||||
extraConfig = ''
|
||||
if (!-e $request_filename) {
|
||||
rewrite ^/(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ /$1.$3 last;
|
||||
}
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to composer files
|
||||
locations."~* composer\.(?:json|lock)".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
|
||||
# TYPO3 - Block access to flexform files
|
||||
locations."~* flexform[^.]*\.xml".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to language files
|
||||
locations."~* locallang[^.]*\.(?:xml|xlf)$".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to static typoscript files
|
||||
locations."~* ext_conf_template\.txt|ext_typoscript_constants\.txt|ext_typoscript_setup\.txt".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to miscellaneous protected files
|
||||
locations."~* /.*\.(?:bak|co?nf|cfg|ya?ml|ts|typoscript|tsconfig|dist|fla|in[ci]|log|sh|sql|sqlite)$".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to recycler and temporary directories
|
||||
locations."~ _(?:recycler|temp)_/".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to configuration files stored in fileadmin
|
||||
locations."~ fileadmin/(?:templates)/.*\.(?:txt|ts|typoscript)$".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
|
||||
# TYPO3 - Block access to libraries, source and temporary compiled data
|
||||
locations."~ ^(?:vendor|typo3_src|typo3temp/var)".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
|
||||
# TYPO3 - Block access to protected extension directories
|
||||
locations."~ (?:typo3conf/ext|typo3/sysext|typo3/ext)/[^/]+/(?:Configuration|Resources/Private|Tests?|Documentation|docs?)/".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
locations."/".extraConfig = ''
|
||||
index index.php index.html;
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
'';
|
||||
|
||||
# TYPO3 Backend URLs
|
||||
locations."/typo3".extraConfig = ''
|
||||
rewrite ^ /typo3/;
|
||||
'';
|
||||
|
||||
locations."/typo3/".extraConfig = ''
|
||||
try_files $uri /typo3/index.php$is_args$args;
|
||||
'';
|
||||
|
||||
locations."~ [^/]\.php(/|$)".extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) {
|
||||
return 404;
|
||||
}
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
fastcgi_buffer_size 32k;
|
||||
fastcgi_buffers 8 16k;
|
||||
fastcgi_connect_timeout 240s;
|
||||
fastcgi_read_timeout 240s;
|
||||
fastcgi_send_timeout 240s;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools."${domain}".socket};
|
||||
fastcgi_index index.php;
|
||||
'';
|
||||
};
|
||||
users.users."${domain}" = {
|
||||
isSystemUser = true;
|
||||
createHome = true;
|
||||
home = dataDir;
|
||||
homeMode= "770";
|
||||
#home = "/home/${domain}";
|
||||
group = "nginx";
|
||||
};
|
||||
users.groups.${domain} = {};
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
|
||||
imports = [
|
||||
./cloonar.dev.nix
|
||||
./diabetes-austria.cloonar.dev.nix
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
imagemagick
|
||||
ghostscript
|
||||
];
|
||||
|
||||
systemd.services.nginx.serviceConfig.ProtectHome = "read-only";
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
||||
|
||||
commonHttpConfig = ''
|
||||
# Add HSTS header with preloading to HTTPS requests.
|
||||
# Adding this header to HTTP requests is discouraged
|
||||
map $scheme $hsts_header {
|
||||
https "max-age=31536000; includeSubdomains; preload";
|
||||
}
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
|
||||
# Enable CSP for your services.
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
|
||||
# Minimize information leaked to other domains
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
|
||||
# Disable embedding as a frame
|
||||
add_header X-Frame-Options DENY;
|
||||
|
||||
# Prevent injection of code in other mime types (XSS Attacks)
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
# Enable XSS protection of the browser.
|
||||
# May be unnecessary when CSP is configured properly (see above)
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# This might create errors
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
domain = "diabetes-austria.cloonar.dev";
|
||||
dataDir = "/var/www/${domain}";
|
||||
in {
|
||||
systemd.services."phpfpm-${domain}".serviceConfig.ProtectHome = lib.mkForce false;
|
||||
|
||||
services.phpfpm.pools."${domain}" = {
|
||||
user = domain;
|
||||
settings = {
|
||||
"listen.owner" = config.services.nginx.user;
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.max_requests" = 500;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 5;
|
||||
"php_admin_value[error_log]" = "stderr";
|
||||
"php_admin_flag[log_errors]" = true;
|
||||
"catch_workers_output" = true;
|
||||
"access.log" = "/var/log/$pool.access.log";
|
||||
};
|
||||
phpPackage = pkgs.php81;
|
||||
phpEnv."PATH" = lib.makeBinPath [ pkgs.php81 ];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
root = "${dataDir}";
|
||||
|
||||
locations."/favicon.ico".extraConfig = ''
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
'';
|
||||
|
||||
# TYPO3 - Rule for versioned static files, configured through:
|
||||
# - $GLOBALS['TYPO3_CONF_VARS']['BE']['versionNumberInFilename']
|
||||
# - $GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename']
|
||||
|
||||
extraConfig = ''
|
||||
if (!-e $request_filename) {
|
||||
rewrite ^/(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ /$1.$3 last;
|
||||
}
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to composer files
|
||||
locations."~* composer\.(?:json|lock)".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
|
||||
# TYPO3 - Block access to flexform files
|
||||
locations."~* flexform[^.]*\.xml".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to language files
|
||||
locations."~* locallang[^.]*\.(?:xml|xlf)$".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to static typoscript files
|
||||
locations."~* ext_conf_template\.txt|ext_typoscript_constants\.txt|ext_typoscript_setup\.txt".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to miscellaneous protected files
|
||||
locations."~* /.*\.(?:bak|co?nf|cfg|ya?ml|ts|typoscript|tsconfig|dist|fla|in[ci]|log|sh|sql|sqlite)$".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to recycler and temporary directories
|
||||
locations."~ _(?:recycler|temp)_/".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
# TYPO3 - Block access to configuration files stored in fileadmin
|
||||
locations."~ fileadmin/(?:templates)/.*\.(?:txt|ts|typoscript)$".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
|
||||
# TYPO3 - Block access to libraries, source and temporary compiled data
|
||||
locations."~ ^(?:vendor|typo3_src|typo3temp/var)".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
|
||||
# TYPO3 - Block access to protected extension directories
|
||||
locations."~ (?:typo3conf/ext|typo3/sysext|typo3/ext)/[^/]+/(?:Configuration|Resources/Private|Tests?|Documentation|docs?)/".extraConfig = ''
|
||||
deny all;
|
||||
'';
|
||||
|
||||
locations."/".extraConfig = ''
|
||||
index index.php index.html;
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
'';
|
||||
|
||||
# TYPO3 Backend URLs
|
||||
locations."/typo3".extraConfig = ''
|
||||
rewrite ^ /typo3/;
|
||||
'';
|
||||
|
||||
locations."/typo3/".extraConfig = ''
|
||||
try_files $uri /typo3/index.php$is_args$args;
|
||||
'';
|
||||
|
||||
locations."~ [^/]\.php(/|$)".extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) {
|
||||
return 404;
|
||||
}
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
fastcgi_buffer_size 32k;
|
||||
fastcgi_buffers 8 16k;
|
||||
fastcgi_connect_timeout 240s;
|
||||
fastcgi_read_timeout 240s;
|
||||
fastcgi_send_timeout 240s;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools."${domain}".socket};
|
||||
fastcgi_index index.php;
|
||||
'';
|
||||
};
|
||||
users.users."${domain}" = {
|
||||
isSystemUser = true;
|
||||
createHome = true;
|
||||
home = dataDir;
|
||||
homeMode= "770";
|
||||
#home = "/home/${domain}";
|
||||
group = "nginx";
|
||||
};
|
||||
users.groups.${domain} = {};
|
||||
}
|
||||
Reference in New Issue
Block a user