blob: eb21abcdb63b6876f666dc847c116314e500d624 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
{
config,
lib,
pkgs,
masterDomain,
securityTemplates,
...
}:
let
cfg = config.os.srv.monero;
banlist1 = pkgs.fetchurl {
url = "https://gui.xmr.pm/files/block.txt";
hash = "sha256-0ik4d66js6wvrvciza0li6bsajj8dvxsqlf09hcz7hg610szdxcw";
};
banlist2 = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/Boog900/monero-ban-list/refs/heads/main/ban_list.txt";
hash = "sh256-01z4wm2mp4z1wq2wdkrm66j50gwk3r82m2ml4n0pwjcbajxkdc87";
};
combinedBanlist = pkgs.writeText "combined-monero-banlist.txt" ''
${builtins.readFile banlist1}
${builtins.readFile banlist2}
'';
in
{
options.os.srv.monero = {
wallet.enable = lib.mkEnableOption "enables the monero wallet";
service = {
enable = lib.mkEnableOption "enables hosting a monero node";
public = lib.mkEnableOption "makes the RPC node public (disables authentication for general wallet syncing)";
tor.enable = lib.mkEnableOption "exposes monero RPC via Tor Onion Service";
i2p.enable = lib.mkEnableOption "exposes monero RPC via I2P Tunnel";
};
};
config = lib.mkMerge [
(lib.mkIf cfg.wallet.enable {
environment.systemPackages = [ pkgs.monero-cli ];
})
(lib.mkIf cfg.service.enable {
assertions = [
{
assertion = if (!cfg.service.public) then config.os.srv.sops.enable else true;
message = "sops must be enabled";
}
{
assertion = if cfg.service.tor.enable then config.os.srv.tor.enable else true;
message = "tor must be enabled";
}
{
assertion = if cfg.service.i2p.enable then config.os.srv.i2p.enable else true;
message = "i2p must be enabled";
}
];
sops.secrets."monero/rpc-password" = {
owner = "monero";
restartUnits = [ "monero.service" ];
};
services.monero = {
enable = true;
prune = true;
banlist = combinedBanlist;
limits = {
upload = 1250;
download = 12500;
threads = 8;
};
rpc = {
address = "0.0.0.0";
}
// lib.optionalAttrs (!cfg.service.public) {
restricted = true;
user = "admin";
password = config.sops.secrets."monero/rpc-password".path;
};
};
services.tor = lib.mkIf cfg.service.tor.enable {
# onionServices."xmr-rpc" = {
# to = [
# {
# port = 18081;
# address = config.os.core.network.ips.relay-vm;
# }
# ];
# };
};
services.i2pd = lib.mkIf cfg.service.i2p.enable {
# tunnels.server."xmr-rpc" = {
# port = 18081;
# address = config.os.core.network.ips.relay-vm;
# keys = "xmr-rpc-key.dat";
# inbound.length = 3;
# outbound.length = 3;
# };
};
os.cluster.nginxProxies."xmr.${masterDomain}" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${config.os.core.network.ips.relay-vm}:18081";
extraConfig = ''
proxy_read_timeout 600s;
proxy_send_timeout 600s;
client_max_body_size 50m;
${securityTemplates.restrictToInternal}
'';
};
};
# Left open for P2P syncing
networking.firewall.allowedTCPPorts = [ 18080 ];
})
];
}
|