fixed cl-gemini on procul

This commit is contained in:
root@procul 2021-04-16 00:15:31 -05:00
parent 145996cf38
commit 8cac965a21
20 changed files with 383 additions and 159 deletions

View File

@ -47,7 +47,7 @@
local-networks = [ ];
local-users = [ "niten" "viator" ];
local-groups = [ "admin" ];
local-groups = [ "admin" "informis" ];
local-admins = [ "niten" ];
admin-email = "viator@informis.land";
gssapi-realm = "INFORMIS.LAND";

View File

@ -75,5 +75,14 @@
"xiaoxuan"
];
};
informis = {
gid = 1003;
description = "Informis User Group";
members = [
"niten"
"viator"
];
};
};
}
}

View File

@ -50,7 +50,27 @@ in {
};
};
informis.cl-gemini = {
enable = true;
hostname = "gemini.informis.land";
server-ip = host-ipv4;
document-root = "/srv/gemini/root";
textfiles-archive = "${pkgs.textfiles}";
slynk-port = 4005;
feeds = {
viator = {
title = "viator's phlog";
path = "/home/viator/gemini-public/feed/";
url = "gemini://informis.land/user/viator/feed/";
};
};
};
fudo = {
hosts.procul.external-interfaces = [ "extif0" ];
client.dns = {
enable = true;
ipv4 = true;
@ -80,20 +100,6 @@ in {
allowed-networks = [ "1.1.1.1/32" "1.0.0.1/32" "localhost" "link-local" ];
};
# networks."informis.land" = {
# hosts = {
# procul = {
# ipv4-address = host-ipv4;
# };
# };
# verbatim-dns-records = [
# ''_kerberos IN TXT "INFORMIS.LAND"''
# ''@ IN TXT "v=spf1 mx ip4:${host-ipv4}/29 -all"''
# ''@ IN SPF "v=spf1 mx ip4:${host-ipv4}/29 -all"''
# ];
# };
dns = {
enable = true;
identity = "procul.informis.land";

View File

@ -14,4 +14,5 @@
profile = "server";
ssh-pubkey =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKEsvl1mTSWJJrqXbYrc8wYdlOiW5gNg4Nzf2QCxB6XW";
tmp-on-tmpfs = false;
}

View File

@ -120,6 +120,11 @@ in {
};
config = mkIf cfg.enable {
networking.firewall = {
allowedTCPPorts = [ 53 ];
allowedUDPPorts = [ 53 ];
};
services.nsd = {
enable = true;
identity = cfg.identity;
@ -135,9 +140,9 @@ in {
@ IN SOA ns1.${dom}. hostmaster.${dom}. (
${toString builtins.currentTime}
5m
30m
2m
6w
3w
5m)
${optionalString (dom-cfg.default-host != null)

View File

@ -120,15 +120,15 @@ in {
enable = true;
clonePort = cfg.ssh.listen-port;
};
# settings = mkIf (cfg.ssh != null) {
# server = {
# START_SSH_SERVER = true;
# SSH_DOMAIN = cfg.hostname;
# SSH_PORT = cfg.ssh.listen-port;
# SSH_LISTEN_PORT = cfg.ssh.listen-port;
# SSH_LISTEN_HOST = cfg.ssh.listen-ip;
# };
# };
settings = mkIf (cfg.ssh != null) {
server = {
START_SSH_SERVER = true;
SSH_DOMAIN = cfg.hostname;
# SSH_PORT = cfg.ssh.listen-port;
SSH_LISTEN_PORT = cfg.ssh.listen-port;
SSH_LISTEN_HOST = cfg.ssh.listen-ip;
};
};
};
nginx = {

View File

@ -32,7 +32,7 @@ let
pkgs.writeShellScript "initialize-kdc-db.sh" ''
if [ ! -e ${key-file} ]; then
${pkgs.heimdalFull}/bin/kstash --key-file=${key-file} --random-key
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- init --realm-max-ticket-life="${max-lifetime}" --realm-max-renewable-life="${max-renewal}" RUS.SELBY.CA
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- init --realm-max-ticket-life="${max-lifetime}" --realm-max-renewable-life="${max-renewal}" ${realm}
${add-hosts-principals realm kdc-conf}
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${primary-keytab} */${local-hostname}@${realm}
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${kadmin-keytab} kadmin/admin@${realm}

View File

@ -177,6 +177,10 @@ in {
];
config = mkIf cfg.enable {
networking.firewall = {
allowedTCPPorts = [ 25 110 143 587 993 995 ];
};
users = {
users = {
mailuser = {

View File

@ -4,43 +4,7 @@ with lib;
let
cfg = config.informis.cl-gemini;
lisp-libs = with pkgs.lispPackages; [
asdf-package-system
asdf-system-connections
alexandria
asdf-package-system
asdf-system-connections
cl_plus_ssl
cl-ppcre
quicklisp
quri
uiop
usocket
];
launchServer = ip: port: root: public-dir: key: cert: slynk-port: feeds-string: textfiles-archive:
pkgs.writeText "launch-server.lisp" ''
(load (merge-pathnames "quicklisp/setup.lisp" (user-homedir-pathname)))
(ql:quickload :slynk)
(ql:quickload :cl-gemini)
${optionalString (slynk-port != null) "(slynk:create-server :port ${toString slynk-port} :dont-close t)"}
${feeds-string}
(cl-gemini:start-gemini-server "${ip}" "${key}" "${cert}"
:port ${toString port}
:document-root "${root}"
:textfiles-root "${textfiles-archive}"
:file-cmd "${pkgs.file}/bin/file"
:log-stream *standard-output*
:threaded t
:separate-thread t)
(loop (sleep 60))
'';
sbcl-with-ssl = pkgs.sbcl.overrideAttrs (oldAttrs: rec {
extraLibs = with pkgs; [
openssl_1_1.dev
];
});
lisp-helper = import ../lisp.nix { inherit pkgs; };
feedOpts = with types; {
options = {
@ -71,6 +35,19 @@ let
concatStringsSep "\n"
(mapAttrsToList register-feed feeds);
ensure-certificates = hostname: user: key: cert: pkgs.writeShellScript "ensure-gemini-certificates.sh" ''
if [[ ! -e ${key} ]]; then
TARGET_CERT_DIR=$(${pkgs.coreutils}/bin/dirname ${cert})
TARGET_KEY_DIR=$(${pkgs.coreutils}/bin/dirname ${key})
if [[ ! -d $TARGET_CERT_DIR ]]; then mkdir -p $TARGET_CERT_DIR; fi
if [[ ! -d $TARGET_KEY_DIR ]]; then mkdir -p $TARGET_KEY_DIR; fi
${pkgs.openssl}/bin/openssl req -new -subj "/CN=.${hostname}" -addext "subjectAltName = DNS:${hostname}, DNS:.${hostname}" -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -days 3650 -nodes -out ${cert} -keyout ${key}
${pkgs.coreutils}/bin/chown -R ${user}:nogroup ${cert}
${pkgs.coreutils}/bin/chown -R ${user}:nogroup ${key}
${pkgs.coreutils}/bin/chmod 0444 ${cert}
${pkgs.coreutils}/bin/chmod 0400 ${key}
fi
'';
in {
options.informis.cl-gemini = with types; {
@ -82,6 +59,18 @@ in {
default = 1965;
};
hostname = mkOption {
type = str;
description = "Hostname at which the server is available (for generating the SSL certificate).";
example = "my.hostname.com";
};
user = mkOption {
type = str;
description = "User as which to run the cl-gemini server.";
default = "cl-gemini";
};
server-ip = mkOption {
type = str;
description = "IP on which to serve Gemini traffic.";
@ -101,15 +90,17 @@ in {
};
ssl-private-key = mkOption {
type = path;
type = str;
description = "Path to the pem-encoded server private key.";
example = /path/to/secret/key.pem;
example = "/path/to/secret/key.pem";
default = "${config.users.users.cl-gemini.home}/private/server-key.pem";
};
ssl-certificate = mkOption {
type = path;
type = str;
description = "Path to the pem-encoded server public certificate.";
example = /path/to/cert.pem;
example = "/path/to/cert.pem";
default = "${config.users.users.cl-gemini.home}/private/server-cert.pem";
};
slynk-port = mkOption {
@ -140,73 +131,49 @@ in {
config = mkIf cfg.enable {
environment.systemPackages = with pkgs; [
cl-gemini
];
networking.firewall.allowedTCPPorts = [ cfg.port ];
users.users = {
cl-gemini = {
${cfg.user} = {
isSystemUser = true;
group = "nogroup";
createHome = true;
home = "/var/lib/cl-gemini";
home = "/var/lib/${cfg.user}";
};
};
environment.etc = {
"cl-gemini/key.pem" = {
mode = "0400";
user = "cl-gemini";
source = cfg.ssl-private-key;
systemd.services = {
cl-gemini = {
description = "cl-gemini Gemini server (https://gemini.circumlunar.space/)";
serviceConfig = {
ExecStartPre = "${ensure-certificates cfg.hostname cfg.user cfg.ssl-private-key cfg.ssl-certificate}";
ExecStart = "${pkgs.cl-gemini}/bin/launch-server.sh";
Restart = "on-failure";
PIDFile = "/run/cl-gemini.$USERNAME.uid";
User = cfg.user;
};
environment = {
GEMINI_SLYNK_PORT = mkIf (cfg.slynk-port != null) (toString cfg.slynk-port);
GEMINI_LISTEN_IP = cfg.server-ip;
GEMINI_PRIVATE_KEY = cfg.ssl-private-key;
GEMINI_CERTIFICATE = cfg.ssl-certificate;
GEMINI_LISTEN_PORT = toString cfg.port;
GEMINI_DOCUMENT_ROOT = cfg.document-root;
GEMINI_TEXTFILES_ROOT = cfg.textfiles-archive;
CL_SOURCE_REGISTRY = lisp-helper.lisp-source-registry pkgs.cl-gemini;
};
path = with pkgs; [
gcc
file
getent
];
wantedBy = [ "multi-user.target" ];
};
"cl-gemini/cert.pem" = {
mode = "0444";
user = "cl-gemini";
source = cfg.ssl-certificate;
};
};
systemd.services.cl-gemini = {
description = "cl-gemini Gemini server (https://gemini.circumlunar.space/)";
serviceConfig = let
feed-registrations = register-feeds cfg.feeds;
in {
ExecStartPre = "${pkgs.lispPackages.quicklisp}/bin/quicklisp init";
ExecStart = "${sbcl-with-ssl}/bin/sbcl --load ${
launchServer
cfg.server-ip
cfg.port
cfg.document-root
cfg.user-public
"/etc/cl-gemini/key.pem"
"/etc/cl-gemini/cert.pem"
cfg.slynk-port
feed-registrations
cfg.textfiles-archive
}";
Restart = "on-failure";
PIDFile = "/run/cl-gemini.$USERNAME.uid";
User = "cl-gemini";
};
environment = {
LD_LIBRARY_PATH = "${pkgs.openssl_1_1.out}/lib";
CL_SOURCE_REGISTRY = concatStringsSep ":"
(["${config.users.users.cl-gemini.home}/quicklisp/quicklisp"] ++
(map
(pkg: "${pkg}//")
(lisp-libs ++ [pkgs.cl-gemini])));
};
path = with pkgs; [
gcc
file
getent
];
wantedBy = [ "default.target" ];
};
};
}

9
lib/lisp.nix Normal file
View File

@ -0,0 +1,9 @@
{ pkgs, ... }:
with pkgs.lib;
let
in rec {
gather-dependencies = pkg: unique (pkg.propagatedBuildInputs ++ (concatMap gather-dependencies pkg.propagatedBuildInputs));
lisp-source-registry = pkg: concatStringsSep ":" (map (p: "${p}//") (gather-dependencies pkg));
}

View File

@ -1,24 +1,62 @@
{ stdenv, fetchgit, pkgs }:
{ pkgs, localLispPackages, ... }:
with pkgs.lib;
let
url = "https://git.informis.land/viator/cl-gemini.git";
url = "https://git.informis.land/informis/cl-gemini.git";
version = "0.1";
in stdenv.mkDerivation {
server-launcher = pkgs.writeText "launch-cl-gemini.lisp" ''
(defun getenv-or-fail (env-var &optional default)
(let ((value (uiop:getenv env-var)))
(if (null value)
(if default
default
(uiop:die 1 "unable to find required env var: ~A" env-var))
value)))
(require :asdf)
(asdf:load-system :cl-gemini)
(let ((slynk-port (uiop:getenv "GEMINI_SLYNK_PORT")))
(when slynk-port
(asdf:load-system :slynk)
(slynk:create-server :port (parse-integer slynk-port) :dont-close t)))
(cl-gemini:start-gemini-server
(getenv-or-fail "GEMINI_LISTEN_IP")
(getenv-or-fail "GEMINI_PRIVATE_KEY")
(getenv-or-fail "GEMINI_CERTIFICATE")
:port (parse-integer (getenv-or-fail "GEMINI_LISTEN_PORT"))
:document-root (getenv-or-fail "GEMINI_DOCUMENT_ROOT")
:textfiles-root (getenv-or-fail "GEMINI_TEXTFILES_ROOT")
:log-stream *standard-output*
:threaded t
:separate-thread t)
(loop (sleep 10))
'';
server-wrapper = pkgs.writeShellScript "launch-server.sh" ''
${pkgs.lispPackages.clwrapper}/bin/common-lisp.sh --load ${server-launcher}
'';
sbcl-with-ssl = pkgs.sbcl.overrideAttrs (oldAttrs: rec {
buildInputs = oldAttrs.buildInputs ++ [
pkgs.openssl_1_1.dev
];
});
in pkgs.stdenv.mkDerivation {
name = "cl-gemini-${version}";
src = fetchgit {
url = "https://git.informis.land/viator/cl-gemini.git";
rev = "3de4d1945fc91d0c9f8f65a5d4b0d3f39fbdaa80";
sha256 = "1xzfsp5vp36a3yas5pnhj2a1dd72r72fw3l49ah19hvbapaikhsw";
fetchSubmodules = false;
};
propagatedBuildInputs = with pkgs; [
asdf
sbcl-with-ssl
localLispPackages.cl-gemini
];
phases = ["installPhase"];
installPhase = ''
mkdir -p "$out/lib/common-lisp/cl-gemini"
cp "$src/cl-gemini.asd" "$out/lib/common-lisp/cl-gemini"
cp -R "$src/src" "$out/lib/common-lisp/cl-gemini"
mkdir -p $out/bin
cp "${server-wrapper}" "$out/bin/launch-server.sh"
'';
}

View File

@ -66,9 +66,6 @@ in {
buildInputs = oldAttrs.buildInputs ++ [ pkgs.krb5 ];
});
gtk3-x11 = pkgs.gtk3.overrideAttrs
(oldAttrs: rec { buildInputs = oldAttrs.buildInputs ++ [ pkgs.cmake ]; });
hll2380dw-cups = import ./hll2380dw-cups.nix {
inherit (pkgs)
stdenv fetchurl makeWrapper cups dpkg a2ps ghostscript gnugrep gnused
@ -83,9 +80,7 @@ in {
};
cl-gemini = import ./cl-gemini.nix {
pkgs = pkgs;
stdenv = pkgs.stdenv;
fetchgit = pkgs.fetchgit;
inherit pkgs localLispPackages;
};
fudo-service = import ./fudo-service.nix {
@ -145,9 +140,8 @@ in {
'';
localLispPackages = (import ./lisp {
inherit lib;
pkgs = unstablePkgs;
}) // unstablePkgs.lispPackages;
inherit pkgs localLispPackages;
}) // pkgs.lispPackages;
backplane-dns-server = import ./backplane-dns-server.nix {
inherit localLispPackages;
@ -167,5 +161,11 @@ in {
rev = "5b7dd0ca9014e642e1f2d0aa3154b5da869911d3";
sha256 = "061k0f0jgm5k81djslb172xk0wkis0m878izgisyj2qgg3wf1awh";
};
textfiles = pkgs.fetchgit {
url = "https://git.informis.land/informis/textfiles.git";
rev = "278a90f7ce219e36e5de0a80b540e469a9bce912";
sha256 = "06qns3ayc84mamdgn0jw652rvx60wy9km1vxm2361mzmx2zk89iw";
};
};
}

View File

@ -0,0 +1,42 @@
{ pkgs, localLispPackages, ... }:
let
url = "https://git.informis.land/informis/cl-gemini.git";
rev = "1d5075c23237deec536f62ed5dc06f3845eacf6b";
sha256 = "0j7gz3c83cgishsraqvm1dw42x5c1ydx26jrmkvykljyfhisyjpm";
in pkgs.lispPackages.buildLispPackage {
baseName = "cl-gemini";
packageName = "cl-gemini";
description = "Gemini server written in Common Lisp.";
buildSystems = [ "cl-gemini" ];
src = pkgs.fetchgit {
url = url;
rev = rev;
sha256 = sha256;
fetchSubmodules = false;
};
deps = with localLispPackages; [
alexandria
arrows
asdf-package-system
asdf-system-connections
cl_plus_ssl
cl-ppcre
fare-mop
file-types
inferior-shell
local-time
osicat
quicklisp
quri
uiop
usocket-server
xml-emitter
];
asdFilesToKeep = [ "cl-gemini.asd" ];
}

View File

@ -1,14 +1,17 @@
{ pkgs, lib, ... }:
{ pkgs, localLispPackages, ... }:
rec {
arrows = import ./arrows.nix { inherit pkgs; };
cl-sasl = import ./cl-sasl.nix { inherit pkgs; };
cl-xmpp = import ./cl-xmpp.nix { inherit pkgs cl-sasl; };
backplane-dns = import ./backplane-dns.nix {
inherit pkgs arrows backplane-server ip-utils;
};
backplane-server = import ./backplane-server.nix {
inherit pkgs lib arrows cl-xmpp;
};
ip-utils = import ./ip-utils.nix { inherit pkgs; };
arrows = import ./arrows.nix { inherit pkgs localLispPackages; };
cl-gemini = import ./cl-gemini.nix { inherit pkgs localLispPackages; };
cl-sasl = import ./cl-sasl.nix { inherit pkgs localLispPackages; };
cl-xmpp = import ./cl-xmpp.nix { inherit pkgs localLispPackages; };
backplane-dns = import ./backplane-dns.nix { inherit pkgs localLispPackages; };
backplane-server = import ./backplane-server.nix { inherit pkgs localLispPackages; };
fare-mop = import ./fare-mop.nix { inherit pkgs localLispPackages; };
file-types = import ./file-types.nix { inherit pkgs localLispPackages; };
inferior-shell = import ./inferior-shell.nix { inherit pkgs localLispPackages; };
ip-utils = import ./ip-utils.nix { inherit pkgs localLispPackages; };
osicat = import ./osicat.nix { inherit pkgs localLispPackages; };
usocket-server = import ./usocket-server.nix { inherit pkgs localLispPackages; };
xml-emitter = import ./xml-emitter.nix { inherit pkgs localLispPackages; };
}

View File

@ -0,0 +1,23 @@
{ pkgs, localLispPackages, ... }:
pkgs.lispPackages.buildLispPackage {
baseName = "fare-mop";
packageName = "fare-mop";
description = "fare-mop has a few simple utilities relying on the MOP.";
buildSystems = [ "fare-mop" ];
deps = with localLispPackages; [
closer-mop
fare-utils
];
src = pkgs.fetchgit {
url = "https://github.com/fare/fare-mop.git";
rev = "538aa94590a0354f382eddd9238934763434af30";
sha256 = "0maxs8392953fhnaa6zwnm2mdbhxjxipp4g4rvypm06ixr6pyv1c";
fetchSubmodules = false;
};
asdFilesToKeep = [ "fare-mop.asd" ];
}

View File

@ -0,0 +1,20 @@
{ pkgs, ... }:
pkgs.lispPackages.buildLispPackage {
baseName = "file-types";
packageName = "file-types";
description = "Simple scheme to classify file types in a hierarchical fashion. Includes support for associating and querying MIME types.";
buildSystems = [ "file-types" ];
deps = [];
src = pkgs.fetchgit {
url = "https://github.com/eugeneia/file-types.git";
rev = "6f5676b2781f617b6009ae4ce001496ea43b6fac";
sha256 = "09l67gzjwx7kx237grm709dsj9rkmmm8s3ya6irmcw8nh587inbs";
fetchSubmodules = false;
};
asdFilesToKeep = [ "file-types.asd" ];
}

View File

@ -0,0 +1,28 @@
{ pkgs, localLispPackages, ... }:
pkgs.lispPackages.buildLispPackage {
baseName = "inferior-shell";
packageName = "inferior-shell";
description = "This CL library allows you to spawn local or remote processes and shell pipes.";
buildSystems = [ "inferior-shell" ];
deps = with localLispPackages; [
pkgs.asdf
alexandria
fare-mop
fare-quasiquote-extras
fare-utils
trivia
trivia_dot_quasiquote
];
src = pkgs.fetchgit {
url = "https://github.com/fare/inferior-shell.git";
rev = "15c2d04a7398db965ea1c3ba2d49efa7c851f2c2";
sha256 = "02qx37zzk5j4xmwh77k2qa2wvnzvaj6qml5dh2q7b6b1ljvgcj4m";
fetchSubmodules = false;
};
asdFilesToKeep = [ "inferior-shell.asd" ];
}

24
packages/lisp/osicat.nix Normal file
View File

@ -0,0 +1,24 @@
{ pkgs, localLispPackages, ... }:
pkgs.lispPackages.buildLispPackage {
baseName = "osicat";
packageName = "osicat";
description = "Osicat is a lightweight operating system interface for Common Lisp on Unix-platforms.";
buildSystems = [ "osicat" ];
deps = with localLispPackages; [
alexandria
cffi-grovel
trivial-features
];
src = pkgs.fetchgit {
url = "https://github.com/osicat/osicat.git";
rev = "e635611710fe053b4bbb7e8cc950a524f6061562";
sha256 = "1lib65qkwkywmnkgnnbqvfypv82rds7cdaygjmi32d337f82ljzg";
fetchSubmodules = false;
};
asdFilesToKeep = [ "osicat.asd" ];
}

View File

@ -0,0 +1,23 @@
{ pkgs, localLispPackages, ... }:
pkgs.lispPackages.buildLispPackage {
baseName = "usocket-server";
packageName = "usocket-server";
description = "This is the usocket Common Lisp sockets library: a library to bring sockets access to the broadest of common lisp implementations as possible.";
buildSystems = [ "usocket" "usocket-server" ];
deps = with localLispPackages; [
bordeaux-threads
split-sequence
];
src = pkgs.fetchgit {
url = "https://github.com/usocket/usocket.git";
rev = "0e2c23192a74bd654b43528f41b62ee69a06b821";
sha256 = "18z49j9hdazvy1bf0hc4w4k9iavm1nagfbrbbp8ry1r3y7np6by6";
fetchSubmodules = false;
};
asdFilesToKeep = [ "usocket.asd" "usocket-server.asd" ];
}

View File

@ -0,0 +1,22 @@
{ pkgs, localLispPackages, ... }:
pkgs.lispPackages.buildLispPackage {
baseName = "xml-emitter";
packageName = "xml-emitter";
description = "Map Lisp to XML.";
buildSystems = [ "xml-emitter" ];
deps = with localLispPackages; [
cl-utilities
];
src = pkgs.fetchgit {
url = "https://github.com/VitoVan/xml-emitter.git";
rev = "1a93a5ab084a10f3b527db3043bd0ba5868404bf";
sha256 = "1w9yx8gc4imimvjqkhq8yzpg3kjrp2y37rjix5c1lnz4s7bxvhk9";
fetchSubmodules = false;
};
asdFilesToKeep = [ "xml-emitter.asd" ];
}