1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.autossh;
8
9in
10
11{
12
13 ###### interface
14
15 options = {
16
17 services.autossh = {
18
19 sessions = mkOption {
20 type = types.listOf (types.submodule {
21 options = {
22 name = mkOption {
23 type = types.string;
24 example = "socks-peer";
25 description = "Name of the local AutoSSH session";
26 };
27 user = mkOption {
28 type = types.string;
29 example = "bill";
30 description = "Name of the user the AutoSSH session should run as";
31 };
32 monitoringPort = mkOption {
33 type = types.int;
34 default = 0;
35 example = 20000;
36 description = ''
37 Port to be used by AutoSSH for peer monitoring. Note, that
38 AutoSSH also uses mport+1. Value of 0 disables the keep-alive
39 style monitoring
40 '';
41 };
42 extraArguments = mkOption {
43 type = types.string;
44 example = "-N -D4343 bill@socks.example.net";
45 description = ''
46 Arguments to be passed to AutoSSH and retransmitted to SSH
47 process. Some meaningful options include -N (don't run remote
48 command), -D (open SOCKS proxy on local port), -R (forward
49 remote port), -L (forward local port), -v (Enable debug). Check
50 ssh manual for the complete list.
51 '';
52 };
53 };
54 });
55
56 default = [];
57 description = ''
58 List of AutoSSH sessions to start as systemd services. Each service is
59 named 'autossh-{session.name}'.
60 '';
61
62 example = [
63 {
64 name="socks-peer";
65 user="bill";
66 monitoringPort = 20000;
67 extraArguments="-N -D4343 billremote@socks.host.net";
68 }
69 ];
70
71 };
72 };
73
74 };
75
76 ###### implementation
77
78 config = mkIf (cfg.sessions != []) {
79
80 systemd.services =
81
82 lib.fold ( s : acc : acc //
83 {
84 "autossh-${s.name}" =
85 let
86 mport = if s ? monitoringPort then s.monitoringPort else 0;
87 in
88 {
89 description = "AutoSSH session (" + s.name + ")";
90
91 after = [ "network.target" ];
92 wantedBy = [ "multi-user.target" ];
93
94 # To be able to start the service with no network connection
95 environment.AUTOSSH_GATETIME="0";
96
97 # How often AutoSSH checks the network, in seconds
98 environment.AUTOSSH_POLL="30";
99
100 serviceConfig = {
101 User = "${s.user}";
102 PermissionsStartOnly = true;
103 # AutoSSH may exit with 0 code if the SSH session was
104 # gracefully terminated by either local or remote side.
105 Restart = "on-success";
106 ExecStart = "${pkgs.autossh}/bin/autossh -M ${toString mport} ${s.extraArguments}";
107 };
108 };
109 }) {} cfg.sessions;
110
111 environment.systemPackages = [ pkgs.autossh ];
112
113 };
114}