hainich: init limesurvey
Have I spent entirely too much time on this? Yes! Featuring: - a heavily modified version of the default limesurvey NixOS module - limesurvey 4.4 instead of the default limesurvey 3.23 - lots and lots of weird hacks - postgres instead of mysql - nginx instead of apache - slightly less weird module options (in my opinion) - /slightly/ fewer XSS vulnerabilities, I hope (this is still limesurvey) - kind of trivial limesurvey updates, unless upstream decides to break things again the way they did when jumping from v3 to v4 - a full copy of limesurvey in /var/lib/limesurvey, since limesurvey v4 won't run when it can write in its config dir, which is a well-defined path if and only if the entire rest of limesurvey is next to it, and the `configdir` var is NOT actually set in limesurvey's config file - no symlinks. limesurvey sees through these.
This commit is contained in:
parent
dbbdde76c7
commit
4e570fe5f2
3 changed files with 237 additions and 0 deletions
|
@ -19,6 +19,7 @@
|
|||
./services/syncthing.nix
|
||||
./services/monitoring.nix
|
||||
./services/workadventure.nix
|
||||
./services/limesurvey.nix
|
||||
];
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.version = 2;
|
||||
|
|
74
hosts/hainich/services/limesurvey.nix
Normal file
74
hosts/hainich/services/limesurvey.nix
Normal file
|
@ -0,0 +1,74 @@
|
|||
{config, pkgs, lib, ...}:
|
||||
|
||||
{
|
||||
|
||||
containers.limesurvey = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.40";
|
||||
localAddress = "192.168.100.41";
|
||||
|
||||
config = {config, pkgs, lib, ...}: {
|
||||
imports = [ ./../../../modules/limesurvey.nix ];
|
||||
|
||||
services.limesurvey-patched = {
|
||||
enable = true;
|
||||
domain = "localhost";
|
||||
|
||||
config = {
|
||||
name = "LimeSurvey";
|
||||
components = {
|
||||
db = {
|
||||
connectionString = "pgsql:dbname=limesurvey;host=localhost;port=5432;user=limesurvey";
|
||||
username = "limesurvey";
|
||||
tablePrefix = "limesurvey_";
|
||||
};
|
||||
assetManager.basePath = "/var/lib/limesurvey/tmp/assets";
|
||||
urlManager = {
|
||||
urlFormat = "path";
|
||||
showScriptName = false;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
siteadminemail = "info@infra4future.de";
|
||||
defaultlang = "de";
|
||||
};
|
||||
};
|
||||
|
||||
package = pkgs.limesurvey.overrideAttrs (old: rec {
|
||||
version = "4.4.12+210308";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "LimeSurvey";
|
||||
repo = "LimeSurvey";
|
||||
rev = version;
|
||||
sha256 = "0kjya8if751mh35symzas186ya27nq62adzp2j58agd5ssrb2a8f";
|
||||
};
|
||||
meta.knownVulnerabilities = [];
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ "limesurvey" ];
|
||||
ensureUsers = [ {
|
||||
name = "limesurvey";
|
||||
ensurePermissions = { "DATABASE limesurvey" = "ALL PRIVILEGES"; };
|
||||
} ];
|
||||
|
||||
authentication = lib.mkForce ''
|
||||
# Generated file; do not edit!
|
||||
local all all trust
|
||||
host limesurvey limesurvey ::1/128 trust
|
||||
'';
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."survey.infra4future.de" = {
|
||||
locations."/".proxyPass = "http://${config.containers.limesurvey.localAddress}";
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
}
|
162
modules/limesurvey.nix
Normal file
162
modules/limesurvey.nix
Normal file
|
@ -0,0 +1,162 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
|
||||
inherit (lib) mkDefault mkEnableOption mkForce mkIf mkMerge mkOption;
|
||||
inherit (lib) literalExample mapAttrs optional optionalString types;
|
||||
|
||||
cfg = config.services.limesurvey-patched;
|
||||
fpm = config.services.phpfpm.pools.limesurvey;
|
||||
|
||||
user = "limesurvey";
|
||||
group = config.services.nginx.group;
|
||||
stateDir = cfg.stateDir;
|
||||
|
||||
pkg = cfg.package;
|
||||
|
||||
configType = with types; oneOf [ (attrsOf configType) str int bool ] // {
|
||||
description = "limesurvey config type (str, int, bool or attribute set thereof)";
|
||||
};
|
||||
|
||||
limesurveyConfig = pkgs.writeText "config.php" ''
|
||||
<?php
|
||||
return json_decode('${builtins.toJSON cfg.config}', true);
|
||||
?>
|
||||
'';
|
||||
in
|
||||
{
|
||||
# interface
|
||||
|
||||
options.services.limesurvey-patched = {
|
||||
enable = mkEnableOption "Limesurvey web application.";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.limesurvey;
|
||||
description = "The Limesurvey package to use";
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "example.org";
|
||||
description = "the domain name of limesurvey";
|
||||
};
|
||||
|
||||
poolConfig = mkOption {
|
||||
type = with types; attrsOf (oneOf [ str int bool ]);
|
||||
default = {
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 4;
|
||||
"pm.max_requests" = 500;
|
||||
};
|
||||
description = ''
|
||||
Options for the LimeSurvey PHP pool. See the documentation on <literal>php-fpm.conf</literal>
|
||||
for details on configuration directives.
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = configType;
|
||||
default = {};
|
||||
description = ''
|
||||
LimeSurvey configuration. Refer to
|
||||
<link xlink:href="https://manual.limesurvey.org/Optional_settings"/>
|
||||
for details on supported values.
|
||||
'';
|
||||
};
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/limesurvey";
|
||||
description = ''
|
||||
LimeSurvey keeps its state in here. For a variety of stupid php reasons, it will also keep a complete
|
||||
copy of itself in here.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
# implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
services.limesurvey-patched.config = mapAttrs (name: mkDefault) {
|
||||
runtimePath = "${stateDir}/tmp/runtime";
|
||||
components = {
|
||||
assetManager.basePath = "${stateDir}/tmp/assets";
|
||||
urlManager = {
|
||||
urlFormat = "path";
|
||||
showScriptName = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.phpfpm.pools.limesurvey = {
|
||||
inherit user group;
|
||||
phpEnv.LIMESURVEY_CONFIG = "/var/lib/limesurvey/config/config.php";
|
||||
settings = {
|
||||
"listen.owner" = config.services.nginx.user;
|
||||
"listen.group" = config.services.nginx.group;
|
||||
} // cfg.poolConfig;
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
virtualHosts.${cfg.domain} = {
|
||||
root = stateDir;
|
||||
locations."/".tryFiles = "$uri /index.php?$args";
|
||||
|
||||
locations."~ [^/]\\.php(/|$)".extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) {
|
||||
return 404;
|
||||
}
|
||||
fastcgi_pass unix:${fpm.socket};
|
||||
fastcgi_index index.php;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"C ${stateDir} 0750 ${user} ${group} - ${pkg}/share/limesurvey"
|
||||
"d ${stateDir}/tmp 0750 ${user} ${group} - -"
|
||||
"d ${stateDir}/tmp/assets 0750 ${user} ${group} - -"
|
||||
"d ${stateDir}/tmp/runtime 0750 ${user} ${group} - -"
|
||||
"d ${stateDir}/tmp/upload 0750 ${user} ${group} - -"
|
||||
];
|
||||
|
||||
systemd.services.limesurvey-init = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "phpfpm-limesurvey.service" ];
|
||||
after = [ "postgresql.service" ];
|
||||
environment.LIMESURVEY_CONFIG = "/var/lib/limesurvey/config/config.php";
|
||||
script = ''
|
||||
|
||||
chmod -R +w ${stateDir}
|
||||
mkdir -p ${stateDir}/config
|
||||
cp -f ${limesurveyConfig} ${stateDir}/config/config.php
|
||||
|
||||
# update or install the database as required
|
||||
${pkgs.php}/bin/php /var/lib/limesurvey/application/commands/console.php updatedb || \
|
||||
${pkgs.php}/bin/php /var/lib/limesurvey/application/commands/console.php install admin password admin admin@example.com verbose
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = user;
|
||||
Group = group;
|
||||
Type = "oneshot";
|
||||
};
|
||||
};
|
||||
|
||||
#systemd.services.httpd.after = [ "postgresql.service" ];
|
||||
systemd.services.nginx.after = [ "postgresql.service" ];
|
||||
|
||||
users.users.${user} = {
|
||||
group = group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue