1{ lib, ... }:
2
3let
4 successMessage = "Success 3333115147933743662";
5in
6{
7 name = "rathole";
8 meta.maintainers = with lib.maintainers; [ xokdvium ];
9 nodes = {
10 server = {
11 networking = {
12 useNetworkd = true;
13 useDHCP = false;
14 firewall.enable = false;
15 };
16
17 systemd.network.networks."01-eth1" = {
18 name = "eth1";
19 networkConfig.Address = "10.0.0.1/24";
20 };
21
22 services.rathole = {
23 enable = true;
24 role = "server";
25 settings = {
26 server = {
27 bind_addr = "0.0.0.0:2333";
28 services = {
29 success-message = {
30 bind_addr = "0.0.0.0:80";
31 token = "hunter2";
32 };
33 };
34 };
35 };
36 };
37 };
38
39 client =
40 { pkgs, ... }:
41 {
42 networking = {
43 useNetworkd = true;
44 useDHCP = false;
45 };
46
47 systemd.network.networks."01-eth1" = {
48 name = "eth1";
49 networkConfig.Address = "10.0.0.2/24";
50 };
51
52 services.nginx = {
53 enable = true;
54 virtualHosts."127.0.0.1" = {
55 root = pkgs.writeTextDir "success-message.txt" successMessage;
56 };
57 };
58
59 services.rathole = {
60 enable = true;
61 role = "client";
62 credentialsFile = pkgs.writeText "rathole-credentials.toml" ''
63 [client.services.success-message]
64 token = "hunter2"
65 '';
66 settings = {
67 client = {
68 remote_addr = "10.0.0.1:2333";
69 services.success-message = {
70 local_addr = "127.0.0.1:80";
71 };
72 };
73 };
74 };
75 };
76 };
77
78 testScript = ''
79 start_all()
80 server.wait_for_unit("rathole.service")
81 server.wait_for_open_port(2333)
82 client.wait_for_unit("rathole.service")
83 server.wait_for_open_port(80)
84 response = server.succeed("curl http://127.0.0.1/success-message.txt")
85 assert "${successMessage}" in response, "Got invalid response"
86 response = client.succeed("curl http://10.0.0.1/success-message.txt")
87 assert "${successMessage}" in response, "Got invalid response"
88 '';
89}