···
3
3
imports = [
4
4
./hardware.nix
5
5
./packages.nix
6
6
-
./services/caddy.nix
7
6
8
7
../modules/basic.nix
8
8
+
../modules/caddy.nix
9
9
../modules/development/nix.nix
10
10
../modules/development/sh.nix
11
11
../modules/editor.nix
···
18
18
../modules/remoteBuildMachines.nix
19
19
../modules/sss.nix
20
20
21
21
-
../modules/services/caddy.nix
21
21
+
../modules/services/caddy
22
22
+
# ../modules/services/caddy/cp-certs.nix
23
23
+
../modules/services/caddy/matrix.nix
24
24
+
../modules/services/caddy/nextcloud.nix
25
25
+
../modules/services/caddy/pds.nix
26
26
+
../modules/services/caddy/soju.nix
27
27
+
../modules/services/caddy/tangled-knot.nix
28
28
+
../modules/services/caddy/websites/org-butwho.nix
29
29
+
# ../modules/services/caddy/xmpp.nix
22
30
../modules/services/openssh.nix
23
31
../modules/services/soju.nix
24
32
];
···
32
40
networking.hostName = "dandelion";
33
41
nix.settings.max-jobs = 0;
34
42
35
35
-
garden.info.host = {
36
36
-
sss-mount = true;
37
37
-
vps = true;
43
43
+
garden = {
44
44
+
caddy.package = {
45
45
+
plugins = [
46
46
+
"github.com/mholt/caddy-events-exec@v0.0.0-20231121214933-055bfd2e8b82"
47
47
+
"github.com/mholt/caddy-l4@v0.0.0-20250124234235-87e3e5e2c7f9"
48
48
+
];
49
49
+
hash = "sha256-ydan4Lqeh4eMCpuWryXSdcqQ3CBVCxVwPqUcVPedZy0=";
50
50
+
};
51
51
+
info.host = {
52
52
+
sss-mount = true;
53
53
+
vps = true;
54
54
+
};
38
55
};
39
56
40
57
# This option defines the first version of NixOS you have installed on this particular machine,
···
1
1
-
# TODO: Put the sss import in this directory since it makes direct use of it
2
2
-
# TODO: Separate caddy config into separate files
3
3
-
{ config, pkgs, ... }:
4
4
-
let
5
5
-
lily = config.garden.info.network.lily.netbird-ip;
6
6
-
cpCerts = pkgs.writeShellApplication {
7
7
-
name = "cpCerts";
8
8
-
runtimeInputs = with pkgs; [ coreutils ];
9
9
-
text = ''
10
10
-
prog_name=''${0##*/}
11
11
-
12
12
-
case $1 in
13
13
-
"proxy.butwho.org" | "conference.butwho.org" | "pubsub.butwho.org" | \
14
14
-
"upload.butwho.org" | "butwho.org" )
15
15
-
caddy_path="/var/lib/caddy/.local/share/caddy"
16
16
-
printf '%s\n' "$prog_name: Copying certs for '$1' to /sss/certs/$1"
17
17
-
18
18
-
mkdir -p "/sss/certs/$1"
19
19
-
cp -f "$caddy_path/$2" "/sss/certs/$1"
20
20
-
cp -f "$caddy_path/$3" "/sss/certs/$1"
21
21
-
22
22
-
# Read both the .crt file and the .key file to make a .pem
23
23
-
crt=$(cat "$caddy_path/$2")
24
24
-
key=$(cat "$caddy_path/$3")
25
25
-
printf '%s\n\n%s\n' "$crt" "$key" > "/sss/certs/$1/$1.pem"
26
26
-
27
27
-
printf '%s\n' "$prog_name: Copied certs for '$1'"
28
28
-
;;
29
29
-
* ) printf '%s\n' "$prog_name: Skipping $1" ;;
30
30
-
esac
31
31
-
'';
32
32
-
};
33
33
-
cpCertsCommand = "${cpCerts}/bin/cpCerts {event.data.identifier} {event.data.certificate_path} {event.data.private_key_path}";
34
34
-
in
35
35
-
{
36
36
-
environment.persistence."/data/persistent".directories = [
37
37
-
{
38
38
-
directory = "/var/www/org.butwho";
39
39
-
user = "mou";
40
40
-
group = "caddy";
41
41
-
mode = "0750";
42
42
-
}
43
43
-
];
44
44
-
45
45
-
networking.firewall.interfaces."enp1s0".allowedTCPPorts = [
46
46
-
22
47
47
-
6697
48
48
-
];
49
49
-
50
50
-
services.caddy = {
51
51
-
package = pkgs.caddy.withPlugins {
52
52
-
plugins = [
53
53
-
"github.com/mholt/caddy-events-exec@v0.0.0-20231121214933-055bfd2e8b82"
54
54
-
"github.com/mholt/caddy-l4@v0.0.0-20250124234235-87e3e5e2c7f9"
55
55
-
];
56
56
-
hash = "sha256-ydan4Lqeh4eMCpuWryXSdcqQ3CBVCxVwPqUcVPedZy0=";
57
57
-
};
58
58
-
globalConfig = ''
59
59
-
events {
60
60
-
on cert_obtained exec ${cpCertsCommand}
61
61
-
}
62
62
-
63
63
-
on_demand_tls {
64
64
-
ask http://${lily}:3000/tls-check
65
65
-
}
66
66
-
67
67
-
layer4 {
68
68
-
[::]:6697 {
69
69
-
route {
70
70
-
tls {
71
71
-
connection_policy {
72
72
-
alpn irc
73
73
-
default_sni soju.y6d.boo
74
74
-
}
75
75
-
}
76
76
-
proxy [::1]:6667
77
77
-
}
78
78
-
}
79
79
-
[::]:22 {
80
80
-
route {
81
81
-
proxy ${lily}:2222
82
82
-
}
83
83
-
}
84
84
-
}
85
85
-
'';
86
86
-
virtualHosts = {
87
87
-
"butwho.org".extraConfig = ''
88
88
-
encode zstd gzip
89
89
-
90
90
-
# Should I set this for all .well-known files?
91
91
-
# header /.well-known/* Access-Control-Allow-Origin *
92
92
-
93
93
-
# Unsure if this works without
94
94
-
# header /.well-known/host-meta* Access-Control-Allow-Origin *
95
95
-
96
96
-
# header /.well-known/host-meta Content-Type text/xml
97
97
-
# respond /.well-known/host-meta <<XML
98
98
-
# <?xml version='1.0' encoding='utf-8'?>
99
99
-
# <XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
100
100
-
# <Link rel="urn:xmpp:alt-connections:xbosh" href="https://butwho.org:5443/bosh" />
101
101
-
# <Link rel="urn:xmpp:alt-connections:websocket" href="wss://butwho.org:5443/ws" />
102
102
-
# </XRD>
103
103
-
# XML
104
104
-
105
105
-
# header /.well-known/host-meta.json Content-Type application/json
106
106
-
# respond /.well-known/host-meta.json <<JSON
107
107
-
# {
108
108
-
# "links": [
109
109
-
# { "rel": "urn:xmpp:alt-connections:xbosh", "href": "https://butwho.org:5443/bosh" },
110
110
-
# { "rel": "urn:xmpp:alt-connections:websocket", "href": "wss://butwho.org:5443/ws" }
111
111
-
# ]
112
112
-
# }
113
113
-
# JSON
114
114
-
115
115
-
header /.well-known/matrix/* Access-Control-Allow-Origin *
116
116
-
header /.well-known/matrix/* Content-Type application/json
117
117
-
respond /.well-known/matrix/client <<JSON
118
118
-
{
119
119
-
"m.homeserver": { "base_url": "https://matrix.butwho.org" }
120
120
-
}
121
121
-
JSON
122
122
-
respond /.well-known/matrix/server `{"m.server": "matrix.butwho.org:443"}`
123
123
-
124
124
-
root * /var/www/org.butwho
125
125
-
file_server {
126
126
-
hide .git readme.md license
127
127
-
}
128
128
-
129
129
-
handle_errors {
130
130
-
respond "{err.status_code} {err.status_text}"
131
131
-
}
132
132
-
'';
133
133
-
# "conference.butwho.org".extraConfig = ''
134
134
-
# redir https://butwho.org{uri}
135
135
-
# '';
136
136
-
"matrix.butwho.org".extraConfig = ''
137
137
-
encode zstd gzip
138
138
-
reverse_proxy ${lily}:8008
139
139
-
'';
140
140
-
"pds.butwho.org".extraConfig = ''
141
141
-
encode zstd gzip
142
142
-
tls {
143
143
-
on_demand
144
144
-
}
145
145
-
reverse_proxy ${lily}:3000
146
146
-
'';
147
147
-
"*.pds.butwho.org".extraConfig = ''
148
148
-
encode zstd gzip
149
149
-
tls {
150
150
-
on_demand
151
151
-
}
152
152
-
reverse_proxy ${lily}:3000
153
153
-
'';
154
154
-
"knot.butwho.org".extraConfig = ''
155
155
-
encode zstd gzip
156
156
-
reverse_proxy ${lily}:5555
157
157
-
'';
158
158
-
# "proxy.butwho.org".extraConfig = ''
159
159
-
# redir https://butwho.org{uri}
160
160
-
# '';
161
161
-
# "pubsub.butwho.org".extraConfig = ''
162
162
-
# redir https://butwho.org{uri}
163
163
-
# '';
164
164
-
# "upload.butwho.org".extraConfig = ''
165
165
-
# redir https://butwho.org{uri}
166
166
-
# '';
167
167
-
"cloud.lilac.pink".extraConfig = ''
168
168
-
encode zstd gzip
169
169
-
reverse_proxy ${lily}:80 {
170
170
-
# NixOS uses nginx as a webserver for NextCloud by default and nginx will send 301 redirects to the client
171
171
-
# using http as the protocol instead of https since it doesn't have SSL certs of its own.
172
172
-
# Because the redirect isn't also https, this can cause a Content-Security-Policy error on the client.
173
173
-
# In practice this prevents us from enabling apps on NextCloud without this line.
174
174
-
header_down Location http:// https://
175
175
-
}
176
176
-
'';
177
177
-
"soju.y6d.boo".extraConfig = ''
178
178
-
encode zstd gzip
179
179
-
reverse_proxy [::1]:8080
180
180
-
'';
181
181
-
};
182
182
-
};
183
183
-
}
···
62
62
]
63
63
},
64
64
"locked": {
65
65
-
"lastModified": 1744360457,
66
66
-
"narHash": "sha256-Rcd9KYFRYPkMfOsz6vzWosEfggJMGjb1/j9mnxC7q9s=",
65
65
+
"lastModified": 1744380363,
66
66
+
"narHash": "sha256-cXjAUuAfQDPSLSsckZuTioQ986iqSPTzx8D7dLAcC+Q=",
67
67
"owner": "nix-community",
68
68
"repo": "home-manager",
69
69
-
"rev": "da624eaad0fefd4dac002e1f09d300d150c20483",
69
69
+
"rev": "e43c6bcb101ba3301522439c459288c4a248f624",
70
70
"type": "github"
71
71
},
72
72
"original": {
···
159
159
},
160
160
"nixpkgs": {
161
161
"locked": {
162
162
-
"lastModified": 1744348691,
163
163
-
"narHash": "sha256-dIPrBepej1ebT1IaWEFLI5mpQO65+oM+SArkrNI9gjo=",
162
162
+
"lastModified": 1744371553,
163
163
+
"narHash": "sha256-KjvhD+DkQsOAggIFyuxSAZIs84UahDb/O9ojpvyFNe0=",
164
164
"owner": "NixOS",
165
165
"repo": "nixpkgs",
166
166
-
"rev": "6b93024f590b15b1f3888fcc6e56a0866e0c26c2",
166
166
+
"rev": "6f061f35682410185d9a1582601e9241bfa6ad96",
167
167
"type": "github"
168
168
},
169
169
"original": {
···
335
335
"yemou-dotfiles": {
336
336
"flake": false,
337
337
"locked": {
338
338
-
"lastModified": 1744136969,
339
339
-
"narHash": "sha256-Pv4OUJbopgHxW64DwFA/9RF69WicSLsA+Vfqd61ufBY=",
338
338
+
"lastModified": 1744381009,
339
339
+
"narHash": "sha256-N6FmFNELNT6bR6VyM7W2nU6PjKn011/uZsxRG65mXrY=",
340
340
"ref": "refs/heads/main",
341
341
-
"rev": "ed4446edcbe0787bdc43fff8fe4c9606698d47ce",
342
342
-
"revCount": 89,
341
341
+
"rev": "169fceb54947dfb8ed9a9e8bcdfa1638dd8806c0",
342
342
+
"revCount": 90,
343
343
"type": "git",
344
344
"url": "https://tangled.sh/@yemou.pink/dotfiles"
345
345
},
···
1
1
+
{
2
2
+
config,
3
3
+
lib,
4
4
+
pkgs,
5
5
+
...
6
6
+
}:
7
7
+
{
8
8
+
options.garden.caddy = {
9
9
+
package = {
10
10
+
plugins = lib.mkOption {
11
11
+
type = lib.types.listOf lib.types.str;
12
12
+
default = [ ];
13
13
+
description = "Caddy plugins to install";
14
14
+
};
15
15
+
hash = lib.mkOption {
16
16
+
type = lib.types.str;
17
17
+
default = lib.fakeSha256;
18
18
+
description = "Hash for Caddy plugins";
19
19
+
};
20
20
+
};
21
21
+
layer4 = lib.mkOption {
22
22
+
type = lib.types.lines;
23
23
+
default = "";
24
24
+
description = "Caddy-L4 configurations";
25
25
+
};
26
26
+
};
27
27
+
28
28
+
config = {
29
29
+
services.caddy = {
30
30
+
package = pkgs.caddy.withPlugins {
31
31
+
plugins = config.garden.caddy.package.plugins;
32
32
+
hash = config.garden.caddy.package.hash;
33
33
+
};
34
34
+
globalConfig = lib.mkIf (config.garden.caddy.layer4 != "") ''
35
35
+
layer4 {
36
36
+
${config.garden.caddy.layer4}
37
37
+
}
38
38
+
'';
39
39
+
};
40
40
+
};
41
41
+
}
···
8
8
9
9
services.caddy = {
10
10
enable = true;
11
11
-
email = "acme@lilac.pink";
11
11
+
email = "acme@mou.pink";
12
12
};
13
13
}
···
1
1
+
{ pkgs, ... }:
2
2
+
let
3
3
+
cpCerts = pkgs.writeShellApplication {
4
4
+
name = "cpCerts";
5
5
+
runtimeInputs = with pkgs; [ coreutils ];
6
6
+
text = ''
7
7
+
prog_name=''${0##*/}
8
8
+
9
9
+
case $1 in
10
10
+
"proxy.butwho.org" | "conference.butwho.org" | "pubsub.butwho.org" | \
11
11
+
"upload.butwho.org" | "butwho.org" )
12
12
+
caddy_path="/var/lib/caddy/.local/share/caddy"
13
13
+
printf '%s\n' "$prog_name: Copying certs for '$1' to /sss/certs/$1"
14
14
+
15
15
+
mkdir -p "/sss/certs/$1"
16
16
+
cp -f "$caddy_path/$2" "/sss/certs/$1"
17
17
+
cp -f "$caddy_path/$3" "/sss/certs/$1"
18
18
+
19
19
+
# Read both the .crt file and the .key file to make a .pem
20
20
+
crt=$(cat "$caddy_path/$2")
21
21
+
key=$(cat "$caddy_path/$3")
22
22
+
printf '%s\n\n%s\n' "$crt" "$key" > "/sss/certs/$1/$1.pem"
23
23
+
24
24
+
printf '%s\n' "$prog_name: Copied certs for '$1'"
25
25
+
;;
26
26
+
* ) printf '%s\n' "$prog_name: Skipping $1" ;;
27
27
+
esac
28
28
+
'';
29
29
+
};
30
30
+
cpCertsCommand = "${cpCerts}/bin/cpCerts {event.data.identifier} {event.data.certificate_path} {event.data.private_key_path}";
31
31
+
in
32
32
+
{
33
33
+
services.caddy.globalConfig = ''
34
34
+
events {
35
35
+
on cert_obtained exec ${cpCertsCommand}
36
36
+
}
37
37
+
'';
38
38
+
}
···
1
1
+
{ config, ... }:
2
2
+
{
3
3
+
services.caddy.virtualHosts = {
4
4
+
"butwho.org".extraConfig = ''
5
5
+
header /.well-known/matrix/* Access-Control-Allow-Origin *
6
6
+
header /.well-known/matrix/* Content-Type application/json
7
7
+
respond /.well-known/matrix/client <<JSON
8
8
+
{
9
9
+
"m.homeserver": { "base_url": "https://matrix.butwho.org" }
10
10
+
}
11
11
+
JSON
12
12
+
respond /.well-known/matrix/server `{"m.server": "matrix.butwho.org:443"}`
13
13
+
'';
14
14
+
"matrix.butwho.org".extraConfig = ''
15
15
+
encode
16
16
+
reverse_proxy ${config.garden.info.network.lily.netbird-ip}:8008
17
17
+
'';
18
18
+
};
19
19
+
}
···
1
1
+
{ config, ... }:
2
2
+
{
3
3
+
services.caddy.virtualHosts."cloud.lilac.pink".extraConfig = ''
4
4
+
encode
5
5
+
reverse_proxy ${config.garden.info.network.lily.netbird-ip}:80 {
6
6
+
# NixOS uses nginx as a webserver for NextCloud by default and nginx will send 301 redirects to the client
7
7
+
# using http as the protocol instead of https since it doesn't have SSL certs of its own.
8
8
+
# Because the redirect isn't also https, this can cause a Content-Security-Policy error on the client.
9
9
+
# In practice this prevents us from enabling apps on NextCloud without this line.
10
10
+
header_down Location http:// https://
11
11
+
}
12
12
+
'';
13
13
+
}
···
1
1
+
{ config, ... }:
2
2
+
{
3
3
+
services.caddy = {
4
4
+
globalConfig = ''
5
5
+
on_demand_tls {
6
6
+
ask http://${config.garden.info.network.lily.netbird-ip}:3000/tls-check
7
7
+
}
8
8
+
'';
9
9
+
virtualHosts = {
10
10
+
"pds.butwho.org".extraConfig = ''
11
11
+
tls {
12
12
+
on_demand
13
13
+
}
14
14
+
encode
15
15
+
reverse_proxy ${config.garden.info.network.lily.netbird-ip}:3000
16
16
+
'';
17
17
+
"*.pds.butwho.org".extraConfig = ''
18
18
+
tls {
19
19
+
on_demand
20
20
+
}
21
21
+
encode
22
22
+
reverse_proxy ${config.garden.info.network.lily.netbird-ip}:3000
23
23
+
'';
24
24
+
};
25
25
+
};
26
26
+
}
···
1
1
+
{ ... }:
2
2
+
{
3
3
+
networking.firewall.interfaces."enp1s0".allowedTCPPorts = [ 6697 ];
4
4
+
5
5
+
services.caddy.virtualHosts."soju.y6d.boo".extraConfig = ''
6
6
+
encode
7
7
+
reverse_proxy [::1]:8080
8
8
+
'';
9
9
+
10
10
+
garden.caddy.layer4 = ''
11
11
+
[::]:6697 {
12
12
+
route {
13
13
+
tls {
14
14
+
connection_policy {
15
15
+
alpn irc
16
16
+
default_sni soju.y6d.boo
17
17
+
}
18
18
+
}
19
19
+
proxy [::1]:6667
20
20
+
}
21
21
+
}
22
22
+
'';
23
23
+
}
···
1
1
+
{ config, ... }:
2
2
+
{
3
3
+
networking.firewall.interfaces."enp1s0".allowedTCPPorts = [ 22 ];
4
4
+
5
5
+
services.caddy.virtualHosts."knot.butwho.org".extraConfig = ''
6
6
+
encode
7
7
+
reverse_proxy ${config.garden.info.network.lily.netbird-ip}:5555
8
8
+
'';
9
9
+
10
10
+
garden.caddy.layer4 = ''
11
11
+
[::]:22 {
12
12
+
route {
13
13
+
proxy ${config.garden.info.network.lily.netbird-ip}:2222
14
14
+
}
15
15
+
}
16
16
+
'';
17
17
+
}
···
1
1
+
{ ... }:
2
2
+
{
3
3
+
environment.persistence."/data/persistent".directories = [
4
4
+
{
5
5
+
directory = "/var/www/org.butwho";
6
6
+
user = "mou";
7
7
+
group = "caddy";
8
8
+
mode = "0750";
9
9
+
}
10
10
+
];
11
11
+
12
12
+
services.caddy.virtualHosts."butwho.org".extraConfig = ''
13
13
+
encode
14
14
+
root * /var/www/org.butwho
15
15
+
file_server {
16
16
+
hide .git license
17
17
+
}
18
18
+
19
19
+
handle_errors {
20
20
+
respond "{err.status_code} {err.status_text}"
21
21
+
}
22
22
+
'';
23
23
+
}
···
1
1
+
{ ... }:
2
2
+
{
3
3
+
services.caddy.virtualHosts = {
4
4
+
"butwho.org".extraConfig = ''
5
5
+
header /.well-known/host-meta Content-Type text/xml
6
6
+
respond /.well-known/host-meta <<XML
7
7
+
<?xml version='1.0' encoding='utf-8'?>
8
8
+
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
9
9
+
<Link rel="urn:xmpp:alt-connections:xbosh" href="https://butwho.org:5443/bosh" />
10
10
+
<Link rel="urn:xmpp:alt-connections:websocket" href="wss://butwho.org:5443/ws" />
11
11
+
</XRD>
12
12
+
XML
13
13
+
14
14
+
header /.well-known/host-meta.json Content-Type application/json
15
15
+
respond /.well-known/host-meta.json <<JSON
16
16
+
{
17
17
+
"links": [
18
18
+
{ "rel": "urn:xmpp:alt-connections:xbosh", "href": "https://butwho.org:5443/bosh" },
19
19
+
{ "rel": "urn:xmpp:alt-connections:websocket", "href": "wss://butwho.org:5443/ws" }
20
20
+
]
21
21
+
}
22
22
+
JSON
23
23
+
'';
24
24
+
"conference.butwho.org".extraConfig = ''
25
25
+
encode
26
26
+
redir https://butwho.org{uri}
27
27
+
'';
28
28
+
"proxy.butwho.org".extraConfig = ''
29
29
+
encode
30
30
+
redir https://butwho.org{uri}
31
31
+
'';
32
32
+
"pubsub.butwho.org".extraConfig = ''
33
33
+
encode
34
34
+
redir https://butwho.org{uri}
35
35
+
'';
36
36
+
"upload.butwho.org".extraConfig = ''
37
37
+
encode
38
38
+
redir https://butwho.org{uri}
39
39
+
'';
40
40
+
};
41
41
+
}