-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
192 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
{ config, lib, pkgs, ... }: | ||
|
||
with lib; | ||
|
||
let | ||
cfg = config.services.molly-brown; | ||
|
||
settingsType = with types; | ||
attrsOf (oneOf [ | ||
int | ||
str | ||
(listOf str) | ||
(attrsOf (oneOf [ int str (listOf str) (attrsOf str) ])) | ||
]) // { | ||
description = "primitive expression convertable to TOML"; | ||
}; | ||
|
||
configFile = pkgs.runCommand "molly-brown.toml" { | ||
buildInputs = [ pkgs.remarshal ]; | ||
preferLocalBuild = true; | ||
passAsFile = [ "settings" ]; | ||
settings = builtins.toJSON cfg.settings; | ||
} "remarshal -if json -of toml < $settingsPath > $out"; | ||
in { | ||
|
||
options.services.molly-brown = { | ||
|
||
enable = mkEnableOption "Molly-Brown Gemini server"; | ||
|
||
port = mkOption { | ||
default = 1965; | ||
type = types.port; | ||
description = '' | ||
TCP port for molly-brown to bind to. | ||
''; | ||
}; | ||
|
||
hostName = mkOption { | ||
type = types.str; | ||
example = literalExample "config.networking.hostName"; | ||
default = config.networking.hostName; | ||
description = '' | ||
The hostname to respond to requests for. Requests for URLs with | ||
other hosts will result in a status 53 (PROXY REQUEST REFUSED) | ||
response. | ||
''; | ||
}; | ||
|
||
certPath = mkOption { | ||
type = types.path; | ||
example = "/var/lib/acme/example.com/cert.pem"; | ||
description = '' | ||
Path to TLS certificate. An ACME certificate and key may be | ||
shared with an HTTP server, but only if molly-brown has | ||
permissions allowing it to read such keys. | ||
As an example: | ||
<programlisting> | ||
security.acme.certs."example.com".allowKeysForGroup = true; | ||
systemd.services.molly-brown.serviceConfig.SupplementaryGroups = | ||
[ config.security.acme.certs."example.com".group ]; | ||
</programlisting> | ||
''; | ||
}; | ||
|
||
keyPath = mkOption { | ||
type = types.path; | ||
example = "/var/lib/acme/example.com/key.pem"; | ||
description = "Path to TLS key. See <option>CertPath</option>."; | ||
}; | ||
|
||
docBase = mkOption { | ||
type = types.path; | ||
example = "/var/lib/molly-brown"; | ||
description = "Base directory for Gemini content."; | ||
}; | ||
|
||
settings = mkOption { | ||
type = settingsType; | ||
default = { }; | ||
description = '' | ||
molly-brown configuration. Refer to | ||
<link xlink:href="https://tildegit.org/solderpunk/molly-brown/src/branch/master/example.conf"/> | ||
for details on supported values. | ||
''; | ||
}; | ||
|
||
}; | ||
|
||
config = mkIf cfg.enable { | ||
|
||
services.molly-brown.settings = let logDir = "/var/log/molly-brown"; | ||
in { | ||
Port = cfg.port; | ||
Hostname = cfg.hostName; | ||
CertPath = cfg.certPath; | ||
KeyPath = cfg.keyPath; | ||
DocBase = cfg.docBase; | ||
AccessLog = "${logDir}/access.log"; | ||
ErrorLog = "${logDir}/error.log"; | ||
}; | ||
|
||
systemd.services.molly-brown = { | ||
description = "Molly Brown gemini server"; | ||
after = [ "network.target" ]; | ||
wantedBy = [ "multi-user.target" ]; | ||
serviceConfig = { | ||
DynamicUser = true; | ||
LogsDirectory = "molly-brown"; | ||
ExecStart = "${pkgs.molly-brown}/bin/molly-brown -c ${configFile}"; | ||
Restart = "always"; | ||
}; | ||
}; | ||
|
||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import ./make-test-python.nix ({ pkgs, ... }: | ||
|
||
let testString = "NixOS Gemini test successful"; | ||
in { | ||
|
||
name = "molly-brown"; | ||
meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ ehmry ]; }; | ||
|
||
nodes = { | ||
|
||
geminiServer = { config, pkgs, ... }: | ||
let | ||
inherit (config.networking) hostName; | ||
cfg = config.services.molly-brown; | ||
in { | ||
|
||
environment.systemPackages = [ | ||
(pkgs.writeScriptBin "test-gemini" '' | ||
#!${pkgs.python3}/bin/python | ||
import socket | ||
import ssl | ||
import tempfile | ||
import textwrap | ||
import urllib.parse | ||
url = "gemini://geminiServer/init.gmi" | ||
parsed_url = urllib.parse.urlparse(url) | ||
s = socket.create_connection((parsed_url.netloc, 1965)) | ||
context = ssl.SSLContext() | ||
context.check_hostname = False | ||
context.verify_mode = ssl.CERT_NONE | ||
s = context.wrap_socket(s, server_hostname=parsed_url.netloc) | ||
s.sendall((url + "\r\n").encode("UTF-8")) | ||
fp = s.makefile("rb") | ||
print(fp.readline().strip()) | ||
print(fp.readline().strip()) | ||
print(fp.readline().strip()) | ||
'') | ||
]; | ||
|
||
networking.firewall.allowedTCPPorts = [ cfg.settings.Port ]; | ||
|
||
services.molly-brown = { | ||
enable = true; | ||
docBase = "/tmp/docs"; | ||
certPath = "/tmp/cert.pem"; | ||
keyPath = "/tmp/key.pem"; | ||
}; | ||
|
||
systemd.services.molly-brown.preStart = '' | ||
${pkgs.openssl}/bin/openssl genrsa -out "/tmp/key.pem" | ||
${pkgs.openssl}/bin/openssl req -new \ | ||
-subj "/CN=${config.networking.hostName}" \ | ||
-key "/tmp/key.pem" -out /tmp/request.pem | ||
${pkgs.openssl}/bin/openssl x509 -req -days 3650 \ | ||
-in /tmp/request.pem -signkey "/tmp/key.pem" -out "/tmp/cert.pem" | ||
mkdir -p "${cfg.settings.DocBase}" | ||
echo "${testString}" > "${cfg.settings.DocBase}/test.gmi" | ||
''; | ||
}; | ||
}; | ||
testScript = '' | ||
geminiServer.wait_for_unit("molly-brown") | ||
geminiServer.wait_for_open_port(1965) | ||
geminiServer.succeed("test-gemini") | ||
''; | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters