forked from NixOS/nixops
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathssh-tunnel.nix
78 lines (66 loc) · 2.49 KB
/
ssh-tunnel.nix
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
{ config, pkgs, ... }:
with pkgs.lib;
{
###### interface
options = {
networking.p2pTunnels = mkOption {
default = { };
example =
{ tunnel1 =
{ target = "192.0.2.1";
privateKey = "/root/.ssh/id_vpn";
localTunnel = 0;
remoteTunnel = 1;
localIPv4 = "172.16.12.1";
remoteIPv4 = "172.16.12.2";
};
};
type = types.attrsOf types.optionSet;
options = {
target = mkOption {
type = types.uniq types.string;
description = "Host name or IP address of the remote machine.";
};
privateKey = mkOption {
type = types.uniq types.path;
description = "Path to the private key file used to connect to the remote machine.";
};
localTunnel = mkOption {
type = types.uniq types.int;
description = "Local tunnel device number.";
};
remoteTunnel = mkOption {
type = types.uniq types.int;
description = "Remote tunnel device number.";
};
localIPv4 = mkOption {
type = types.uniq types.string;
description = "IPv4 address of the local endpoint of the tunnel.";
};
remoteIPv4 = mkOption {
type = types.uniq types.string;
description = "IPv4 address of the remote endpoint of the tunnel.";
};
};
description = ''
A set of peer-to-peer tunnels set up automatically over SSH.
'';
};
};
###### implementation
config = {
jobs = flip mapAttrs' config.networking.p2pTunnels (n: v: nameValuePair "ssh-tunnel-${n}" {
startOn = "started network-interfaces";
stopOn = "stopping network-interfaces";
path = [ pkgs.nettools pkgs.openssh ];
preStart = "sleep 1"; # FIXME: hack to work around Upstart
# FIXME: ensure that the remote tunnel device is free
exec =
"ssh -i ${v.privateKey} -x"
+ " -o StrictHostKeyChecking=no -o PermitLocalCommand=yes"
+ " -o LocalCommand='ifconfig tun${toString v.localTunnel} ${v.localIPv4} pointopoint ${v.remoteIPv4} netmask 255.255.255.255; route add ${v.remoteIPv4}/32 dev tun${toString v.localTunnel}'"
+ " -w ${toString v.localTunnel}:${toString v.remoteTunnel} ${v.target}"
+ " 'ifconfig tun${toString v.remoteTunnel} ${v.remoteIPv4} pointopoint ${v.localIPv4} netmask 255.255.255.255; route add ${v.localIPv4}/32 dev tun${toString v.remoteTunnel}'";
});
};
}