Skip to content

Commit e5b993c

Browse files
authored
allow the use of nodesets in 'sources' key (#58)
1 parent ca332a5 commit e5b993c

File tree

6 files changed

+39
-156
lines changed

6 files changed

+39
-156
lines changed

config/sshproxy.yaml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@
122122
# exe: ssh
123123
# args: ["-q", "-Y"]
124124

125-
# Maximum number of connections allowed per user. Connections are counted in
125+
# Maximum number of connections allowed per user. Connections are counted in
126126
# the etcd database. If set to 0, there is no limit number of connections per
127127
# user. Default is 0.
128128
#max_connections_per_user: 0
@@ -141,7 +141,7 @@
141141
# can be "ordered" (the default), "random", "connections" or "bandwidth". If
142142
# "ordered", the hosts are tried in the order listed until a successful
143143
# connection is made. The list is first randomly sorted if "random" is
144-
# specified (i.e. a poor-man load-balancing algorithm). If "connections", the
144+
# specified (i.e. a poor-man load-balancing algorithm). If "connections", the
145145
# hosts with less connections from the user have priority, then the hosts with
146146
# less global connections, and in case of a draw, the selection is random. For
147147
# "bandwidth", it's the same as "connections", but based on the bandwidth used,
@@ -170,14 +170,16 @@
170170

171171
# Each option can be overridden for specific sources (IP address or DNS name of
172172
# the listening SSH daemon, with an optional port), for specific users and/or
173-
# Unix groups of users (eg. for debugging purpose). Multiple sources, users
174-
# and/or groups can be defined. Each element of the "match" array is treated as
175-
# an "or" statement. If an element of the "match" array contains multiple
176-
# keys, they are treated as an "and" statement. If multiple overrides match,
177-
# they will be applied in the order they are defined. In the following example:
178-
# alice, bob and any user in the group foo will have the debug set to true. But
179-
# if any of those are also in the groups bar AND baz, debug will be set to
180-
# false, as the last override takes precedence.
173+
# Unix groups of users (eg. for debugging purpose). Each source can be a
174+
# nodeset (eg. "host[5-6]"). If libnodeset.so is available, clustershell groups
175+
# can also be used (eg. "@hosts"). Multiple sources, users and/or groups can
176+
# be defined. Each element of the "match" array is treated as an "or"
177+
# statement. If an element of the "match" array contains multiple keys, they
178+
# are treated as an "and" statement. If multiple overrides match, they will be
179+
# applied in the order they are defined. In the following example: alice, bob
180+
# and any user in the group foo will have the debug set to true. But if any of
181+
# those are also in the groups bar AND baz, debug will be set to false, as the
182+
# last override takes precedence.
181183
#overrides:
182184
# - match:
183185
# - sources: [192.168.0.1]

doc/sshproxy.yaml.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,17 @@ For example if we want to save debug messages for the 'foo' group we define:
239239
- groups: [foo]
240240
debug: true
241241

242+
Each source can be a nodeset. If libnodeset.so is available, clustershell
243+
groups can also be used (eg. "@hosts").
244+
245+
For example if we want to save debug messages for connections on SSH daemon's
246+
listening IPs 192.168.0.1 and 192.168.0.2:
247+
248+
overrides:
249+
- match:
250+
- sources: ['192.168.0.[1-2]']
251+
debug: true
252+
242253
It is possible to override the same options for multiple groups and users.
243254

244255
For example, if we want to save debug messages if the user is 'alice' or if

pkg/utils/config.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,11 @@ func LoadConfig(filename, currentUsername, sid string, start time.Time, groups m
360360
return nil, err
361361
}
362362

363+
// prepare nodesetExpand function
364+
nodesetComment, nodesetDlclose, nodesetExpand := nodesets.InitExpander()
365+
defer nodesetDlclose()
366+
cachedConfig.Nodeset = nodesetComment
367+
363368
for _, override := range cachedConfig.Overrides {
364369
for _, conditions := range override.Match {
365370
match := true
@@ -383,7 +388,11 @@ func LoadConfig(filename, currentUsername, sid string, start time.Time, groups m
383388
if sshdHostPort != "" {
384389
// sshdHostPort is empty when sshproxyctl is called
385390
// without the --source option
386-
for _, source := range cValue {
391+
sources, err := nodesetExpand(strings.Join(cValue, ","))
392+
if err != nil {
393+
return nil, fmt.Errorf("invalid nodeset for sources match: %s", err)
394+
}
395+
for _, source := range sources {
387396
match, err = MatchSource(source, sshdHostPort)
388397
if err != nil {
389398
return nil, err
@@ -457,9 +466,6 @@ func LoadConfig(filename, currentUsername, sid string, start time.Time, groups m
457466
}
458467

459468
// expand destination nodesets
460-
nodesetComment, nodesetDlclose, nodesetExpand := nodesets.InitExpander()
461-
defer nodesetDlclose()
462-
cachedConfig.Nodeset = nodesetComment
463469
dsts, err := nodesetExpand(strings.Join(cachedConfig.Dest, ","))
464470
if err != nil {
465471
return nil, fmt.Errorf("invalid nodeset for service '%s': %s", cachedConfig.Service, err)

pkg/utils/config_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ var loadConfigTests = []struct {
101101
{"../../test/configLogStatsIntervalError.yaml", "alice", []string{}, `time: invalid duration "not a duration"`},
102102
{"../../test/configLogStatsIntervalNotString.yaml", "alice", []string{}, "log_stats_interval: 10 is not a string"},
103103
{"../../test/configMatchSourceError.yaml", "alice", []string{}, "source: invalid address: address 127.0.0.1:abcd: invalid port"},
104+
{"../../test/configMatchSourceNodesetError.yaml", "alice", []string{}, "invalid nodeset for sources match: unbalanced '[' found while parsing 127.0.0.[1- - nodeset parse error"},
104105
{"../../test/configRouteSelectError.yaml", "alice", []string{}, "invalid value for `route_select` option of service 'default': notarouteselect"},
105106
{"../../test/configModeError.yaml", "alice", []string{}, "invalid value for `mode` option of service 'default': notamode"},
106107
// yes, "cannont" is an upstream typo

test/config.yaml

Lines changed: 1 addition & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,13 @@
11
---
2-
# Debug mode
32
debug: true
4-
5-
# Where logs will be written.
6-
# Default is empty but it can either be "syslog" if you want to use syslog or a
7-
# filename where the pattern '{user}' which will be replaced by the user login
8-
# (e.g. "/var/log/sshproxy/{user}.log").
93
log: "/var/log/sshproxy/{user}.log"
10-
11-
# Minimum interval for checking if an host is alive.
12-
# Empty by default (i.e. always check host).
13-
# The string can contain a unit suffix such as 'h', 'm' and 's' (e.g. "2m30s").
144
check_interval: "2m30s"
15-
16-
# Banner displayed to the client when no backend can be reached (more
17-
# precisely, when all backends are either down or disabled in etcd). This
18-
# message can be multiline.
195
error_banner: "an error banner"
20-
21-
# Where raw dumps are written. Only interactive sessions are dumped.
22-
# Default is empty.
23-
# It can be a path which can (and should) contain one or more of the following
24-
# patterns:
25-
# - '{user}' replaced by the user login
26-
# - '{sid}' replaced by the unique session id
27-
# - '{time}' replaced by the connection starting time (e.g.
28-
# "2006-01-02T15:04:05.999999999Z07:00").
29-
# The subdirectories will be created if needed.
30-
# For example: "/var/lib/sshproxy/dumps/{user}/{time}-{sid}.dump"
31-
# It can also be "etcd", in order to store stats into etcd.
32-
# It can also be a network address where to send dumps if specified as
33-
# 'TCP:host:port' (the TCP is case sensitive), e.g. 'TCP:collector:5555'.
346
dump: "/var/lib/sshproxy/dumps/{user}/{time}-{sid}.dump"
35-
36-
# Maximum amount of bytes of a dump. Setting the 'dump_limit_window' option
37-
# will limit the amount of bytes per window. This option is only useful if the
38-
# 'dump' option is set to a file or to a network address. Defaults to 0 (no
39-
# limit).
407
dump_limit_size: 10
41-
42-
# Duration of a dump measurement window. "0" by default, the string can contain
43-
# a unit suffix such as 'h', 'm' and 's' (e.g. "2m30s"). When set to "0", a
44-
# dump will stop once it's too big (and the dump's file descriptor will be
45-
# closed. When set to a duration, the dump will pause when there is too much
46-
# data transferred in the current window (or the previous), and will resume
47-
# when few enough data are transferred during the previous window and the
48-
# current one. This option is only useful when the 'dump_limit_size' option is
49-
# set.
508
dump_limit_window: "2m31s"
51-
52-
# Interval at which basic statistics of transferred bytes are logged.
53-
# "0" by default (i.e. disabled), the string can contain a unit suffix such as
54-
# 'h', 'm' and 's' (e.g. "2m30s"). These statistics are only available when the
55-
# 'dump' option is set.
569
log_stats_interval: "2m32s"
57-
58-
# Interval at which bandwidth is updated in etcd. "0" by default (i.e.
59-
# disabled), the string can contain a unit suffix such as 'h', 'm' and 's'
60-
# (e.g. "2m30s"). These statistics are only available when the 'dump' option is
61-
# set.
6210
etcd_stats_interval: "2m33s"
63-
64-
# Commands can be translated between what is received by sshproxy and what is
65-
# executed by the ssh forked by sshproxy. The keys are strings containing the
66-
# exact user command. ssh_args contains an optional list of options that will
67-
# be passed to ssh. command is a mandatory string, the actual executed command.
68-
# disable_dump is false by default. If true, no dumps will be done for this
69-
# command.
7011
translate_commands:
7112
"internal-sftp":
7213
ssh_args:
@@ -78,27 +19,6 @@ translate_commands:
7819
- "-s"
7920
command: "sftp"
8021
disable_dump: true
81-
82-
# A command can be launched before the bg_command and before connecting to the
83-
# destination. The standard and error outputs are displayed to the user. If the
84-
# return code of the blocking command is not 0, sshproxy will abort the
85-
# session.
86-
#blocking_command: ""
87-
88-
# A command can be launched in the background for the session duration.
89-
# The standard and error outputs are only logged in debug mode.
90-
#bg_command: ""
91-
92-
# etcd configuration. Associative array whose keys are:
93-
# - endpoints: a list of etcd endpoints. Default is determined by the
94-
# underlying library.
95-
# - tls: TLS configuration if enabled on etcd endpoints. Default is no TLS.
96-
# - username: username if basic authentication is enabled.
97-
# - password: password if basic authentication is enabled.
98-
# - keyttl: time to live in second for a connection stored in etcd after it has
99-
# ended. Default is 5 seconds.
100-
# - mandatory: if true, connections will be allowed only if etcd is available.
101-
# Default is false.
10222
etcd:
10323
endpoints:
10424
- "host1:port1"
@@ -111,76 +31,15 @@ etcd:
11131
password: "pass"
11232
keyttl: 5
11333
mandatory: true
114-
115-
# Environment variables can be set if needed. The '{user}' pattern will be
116-
# replaced with the user login.
11734
environment:
11835
XAUTHORITY: /tmp/.Xauthority_{user}
119-
120-
# Global SSH options.
121-
#ssh:
122-
# exe: ssh
123-
# args: ["-q", "-Y"]
124-
125-
# Maximum number of connections allowed per user. Connections are counted in
126-
# the etcd database. If set to 0, there is no limit number of connections per
127-
# user. Default is 0.
12836
max_connections_per_user: 50
129-
130-
# The service name is used for display. It's also used as a key in order to
131-
# check in etcd if a user already has active connections. The default service
132-
# name is "default".
133-
#service: default
134-
135-
# The dest value is an array of destination hosts (with an optional port). Each
136-
# host can be a nodeset (eg. "host[5-6]"). If libnodeset.so is available,
137-
# clustershell groups can also be used (eg. "@hosts").
13837
dest: ["host5:4222"]
139-
140-
# The route_select value defines how the host destination will be chosen. It
141-
# can be "ordered" (the default), "random", "connections" or "bandwidth". If
142-
# "ordered", the hosts are tried in the order listed until a successful
143-
# connection is made. The list is first randomly sorted if "random" is
144-
# specified (i.e. a poor-man load-balancing algorithm). If "connections", the
145-
# hosts with less connections from the user have priority, then the hosts with
146-
# less global connections, and in case of a draw, the selection is random. For
147-
# "bandwidth", it's the same as "connections", but based on the bandwidth used,
148-
# with a rollback on connections (which is frequent for new simultaneous
149-
# connections).
150-
#route_select: ordered
151-
152-
# The mode value defines the stickiness of a connection. It can be "sticky" or
153-
# "balanced" (defaults to sticky). If "sticky", then all connections of a user
154-
# will be made on the same destination host. If "balanced", the route_select
155-
# algorithm will be used for every connection.
156-
#mode: sticky
157-
158-
# The force_command can be set to override the command asked by the user.
159-
#force_command: "internal-sftp"
160-
161-
# If command_must_match is set to true, then the connection is closed if the
162-
# original command is not the same as the force_command. command_must_match
163-
# defaults to false.
16438
command_must_match: true
165-
166-
# etcd_keyttl defaults to
167-
# 0. If a value is set (in seconds), the chosen backend will be remembered for
168-
# this amount of time.
16939
etcd_keyttl: 3600
170-
171-
# Each option can be overridden for specific sources (IP address or DNS name of
172-
# the listening SSH daemon, with an optional port), for specific users and/or
173-
# Unix groups of users (eg. for debugging purpose). Multiple sources, users
174-
# and/or groups can be defined. Each element of the "match" array is treated as
175-
# an "or" statement. If an element of the "match" array contains multiple
176-
# keys, they are treated as an "and" statement. If multiple overrides match,
177-
# they will be applied in the order they are defined. In the following example:
178-
# alice, bob and any user in the group foo will have the debug set to true. But
179-
# if any of those are also in the groups bar AND baz, debug will be set to
180-
# false, as the last override takes precedence.
18140
overrides:
18241
- match:
183-
- sources: [127.0.0.1]
42+
- sources: ['127.0.0.[1-3]']
18443
environment:
18544
XAUTHORITY: /dev/shm/.Xauthority_{user}
18645
- match:
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dest: [127.0.0.1]
2+
overrides:
3+
- match:
4+
- sources: ["127.0.0.[1-"]

0 commit comments

Comments
 (0)