This repository has been archived by the owner on Oct 2, 2022. It is now read-only.
generated from ContainerSSH/library-template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.go
202 lines (176 loc) · 7.48 KB
/
config.go
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package security
import (
"fmt"
)
// Config is the configuration structure for security settings.
type Config struct {
// DefaultMode sets the default execution policy for all other commands. It is recommended to set this to "disable"
// if for restricted setups to avoid accidentally allowing new features coming in with version upgrades.
DefaultMode ExecutionPolicy `json:"defaultMode" yaml:"defaultMode"`
// ForceCommand behaves similar to the OpenSSH ForceCommand option. When set this command overrides any command
// requested by the client and executes this command instead. The original command supplied by the client will be
// set in the `SSH_ORIGINAL_COMMAND` environment variable.
//
// Setting ForceCommand changes subsystem requests into exec requests for the backends.
ForceCommand string `json:"forceCommand" yaml:"forceCommand"`
// Env controls whether to allow or block setting environment variables.
Env EnvConfig `json:"env" yaml:"env"`
// Command controls whether to allow or block command ("exec") requests via SSh.
Command CommandConfig `json:"command" yaml:"command"`
// Shell controls whether to allow or block shell requests via SSh.
Shell ShellConfig `json:"shell" yaml:"shell"`
// Subsystem controls whether to allow or block subsystem requests via SSH.
Subsystem SubsystemConfig `json:"subsystem" yaml:"subsystem"`
// TTY controls how to treat TTY/PTY requests by clients.
TTY TTYConfig `json:"tty" yaml:"tty"`
// Signal configures how to handle signal requests to running programs.
Signal SignalConfig `json:"signal" yaml:"signal"`
// MaxSessions drives how many session channels can be open at the same time for a single network connection.
// -1 means unlimited. It is strongly recommended to configure this to a sane value, e.g. 10.
MaxSessions int `json:"maxSessions" yaml:"maxSessions" default:"-1"`
}
// Validate validates a shell configuration
func (c Config) Validate() error {
if err := c.DefaultMode.Validate(); err != nil {
return fmt.Errorf("invalid defaultMode configuration (%w)", err)
}
if err := c.Env.Validate(); err != nil {
return fmt.Errorf("invalid env configuration (%w)", err)
}
if err := c.Command.Validate(); err != nil {
return fmt.Errorf("invalid command configuration (%w)", err)
}
if err := c.Shell.Validate(); err != nil {
return fmt.Errorf("invalid shell configuration (%w)", err)
}
if err := c.Subsystem.Validate(); err != nil {
return fmt.Errorf("invalid subsystem configuration (%w)", err)
}
if err := c.TTY.Validate(); err != nil {
return fmt.Errorf("invalid TTY configuration (%w)", err)
}
if err := c.Signal.Validate(); err != nil {
return fmt.Errorf("invalid signal configuration (%w)", err)
}
if c.MaxSessions < -1 {
return fmt.Errorf("invalid maxSessions setting: %d", c.MaxSessions)
}
return nil
}
// EnvConfig configures setting environment variables.
type EnvConfig struct {
// Mode configures how to treat environment variable requests by SSH clients.
Mode ExecutionPolicy `json:"mode" yaml:"mode" default:""`
// Allow takes effect when Mode is ExecutionPolicyFilter and only allows the specified environment variables to be
// set.
Allow []string `json:"allow" yaml:"allow"`
// Allow takes effect when Mode is not ExecutionPolicyDisable and disallows the specified environment variables to
// be set.
Deny []string `json:"deny" yaml:"deny"`
}
// Validate validates a shell configuration
func (e EnvConfig) Validate() error {
if err := e.Mode.Validate(); err != nil {
return fmt.Errorf("invalid mode (%w)", err)
}
return nil
}
// CommandConfig controls command executions via SSH (exec requests).
type CommandConfig struct {
// Mode configures how to treat command execution (exec) requests by SSH clients.
Mode ExecutionPolicy `json:"mode" yaml:"mode" default:""`
// Allow takes effect when Mode is ExecutionPolicyFilter and only allows the specified commands to be
// executed. Note that the match an exact match is performed to avoid shell injections, etc.
Allow []string `json:"allow" yaml:"allow"`
}
// Validate validates a shell configuration
func (c CommandConfig) Validate() error {
if err := c.Mode.Validate(); err != nil {
return fmt.Errorf("invalid mode (%w)", err)
}
return nil
}
// ShellConfig controls shell executions via SSH.
type ShellConfig struct {
// Mode configures how to treat shell requests by SSH clients.
Mode ExecutionPolicy `json:"mode" yaml:"mode" default:""`
}
// Validate validates a shell configuration
func (s ShellConfig) Validate() error {
if err := s.Mode.Validate(); err != nil {
return fmt.Errorf("invalid mode (%w)", err)
}
return nil
}
// SubsystemConfig controls shell executions via SSH.
type SubsystemConfig struct {
// Mode configures how to treat subsystem requests by SSH clients.
Mode ExecutionPolicy `json:"mode" yaml:"mode" default:""`
// Allow takes effect when Mode is ExecutionPolicyFilter and only allows the specified subsystems to be
// executed.
Allow []string `json:"allow" yaml:"allow"`
// Allow takes effect when Mode is not ExecutionPolicyDisable and disallows the specified subsystems to be executed.
Deny []string `json:"deny" yaml:"deny"`
}
// Validate validates a subsystem configuration
func (s SubsystemConfig) Validate() error {
if err := s.Mode.Validate(); err != nil {
return fmt.Errorf("invalid mode (%w)", err)
}
return nil
}
// TTYConfig controls how to treat TTY/PTY requests by clients.
type TTYConfig struct {
// Mode configures how to treat TTY/PTY requests by SSH clients.
Mode ExecutionPolicy `json:"mode" yaml:"mode" default:""`
}
// Validate validates the TTY configuration
func (t TTYConfig) Validate() error {
if err := t.Mode.Validate(); err != nil {
return fmt.Errorf("invalid mode (%w)", err)
}
return nil
}
// SignalConfig configures how signal forwarding requests are treated.
type SignalConfig struct {
// Mode configures how to treat signal requests to running programs
Mode ExecutionPolicy `json:"mode" yaml:"mode" default:""`
// Allow takes effect when Mode is ExecutionPolicyFilter and only allows the specified signals to be forwarded.
Allow []string `json:"allow" yaml:"allow"`
// Allow takes effect when Mode is not ExecutionPolicyDisable and disallows the specified signals to be forwarded.
Deny []string `json:"deny" allow:"deny"`
}
// Validate validates the signal configuration
func (s SignalConfig) Validate() error {
if err := s.Mode.Validate(); err != nil {
return fmt.Errorf("invalid mode (%w)", err)
}
return nil
}
// ExecutionPolicy drives how to treat a certain request.
type ExecutionPolicy string
const (
// ExecutionPolicyUnconfigured falls back to the default mode. If unconfigured on a global level the default is to
// "allow".
ExecutionPolicyUnconfigured ExecutionPolicy = ""
// ExecutionPolicyEnable allows the execution of the specified method unless the specified option matches the
// "deny" list.
ExecutionPolicyEnable ExecutionPolicy = "enable"
// ExecutionPolicyFilter filters the execution against a specified allow list. If the allow list is empty or not
// supported this ootion behaves like "disable".
ExecutionPolicyFilter ExecutionPolicy = "filter"
// ExecutionPolicyDisable disables the specified method and does not take the allow or deny lists into account.
ExecutionPolicyDisable ExecutionPolicy = "disable"
)
// Validate validates the execution policy.
func (e ExecutionPolicy) Validate() error {
switch e {
case ExecutionPolicyUnconfigured:
case ExecutionPolicyEnable:
case ExecutionPolicyFilter:
case ExecutionPolicyDisable:
default:
return fmt.Errorf("invalid mode: %s", e)
}
return nil
}