-
Notifications
You must be signed in to change notification settings - Fork 0
/
SPECIFICATIONS
201 lines (169 loc) · 8.03 KB
/
SPECIFICATIONS
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
factotum - a simple http REST like server for pre-configured commands
Copyright (C) 2014-2015 Michael Rice <michael at riceclan dot org>
fac·to·tum
/fakˈtōtəm/
noun
an employee who does all kinds of work.
"he was employed as the general factotum"
synonyms: handyman, jack of all trades; assistant, man Friday, gal/girl
Friday; gofer; informal Mr./Ms. Fix-It
factotum is conceived as a simple service that can run on any python
platform. It will provide a HTTP interface to run commands on the
machine it is running on, as the user it is running as. The commands
have to be configured into the service itself, to simplify security.
This could be used, for example, to let a service account on one machine
hand off a task to a service account on a different machine.
Originally we targeted this as a mechanism where a git trigger that can
cause a remote server to perform a git pull as a completely different
user. This is to avoid the classic solution using a password-less SSH
with a password-less SUDO command.
It has expanded to allow Jira, Jenkins, and other services run across
privilege and platform boundaries.
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
=SPECIFICATIONS=
factotum is a program that when launched will:
0 do some basic things
0.1 check/set daemon working directory (so as not to hold NFS shares open
unnecessarily -- shall we run with cwd set to / or /tmp or /var/run or
some other?)
0.2 check/set daemon uid/euid (are we valid, do we allow root?)
0.3 check/set argv (can we modify what ps sees this way?)
0.4 background ourselves (daemonize)
0.5 don't do 0.4 if we were passed -d
0.6 since we haven't loaded our config file yet, scream on stderr if we fail
any part of this
1 read a config file
1.1 passed by command line argument
1.2 yaml formatted
1.3 load the config via rtyaml, a package that preserves a leading comment
1.4 optionally automatically fetched from a URL
1.5 a default be automatically determined and loaded if one is not given
1.5.1 for example sys.argv[0].rstrip('.py') + ".conf" in the directory
where we were started (requires that we remember that directory
before changing it in 0.1)
1.6 validate the config file
2 based on that config file do several things
2.1 listen on a port given in the config file
2.1.1 optionally listen on specific interfaces given in the config file
2.1.2 by name or IP
2.2 on connection to the port print a banner
2.3 on receiving data on that port
2.3.1 fork to process
2.3.2 protect from forking too fast or too many
2.3.3 validate the data (length, type, content)
2.3.4 look for keywords (action tags)
2.3.5 provide status on a pre-configured status keyword
3 on receiving a validated action tag
3.1 change to a directory specified in the action configuration section
3.2 run a command specified in the action configuration section
3.3 return value(s)
3.3.1 return code from the command
3.3.2 stdout from the command
3.3.3 stdin from the command
3.3.4 any combination of these (yaml, json, xml, html)
3.4 If environment variables are to be passed, they should be called out
in the config, otherwise they should not be passed
4 additional features for a proposed version 2
4.1 accept additional arguments or data structures on the port
4.2 validate that additional information
4.2.1 have to determine how to validate, where the validator comes from
4.3 pass validated information to the executed command
4.3.1 on the commandline
4.3.1.1 vi some kind of template
4.3.2 via stdin
4.3.3 via some other mechanism (RPC-like or network protocol like)
4.4 add a modification to the keyword to select the return_format instead
of the return_format in the config file. This way different clients
can use the same keyword to get the same information in formats other
than YAML (suggest XML, JSON, HTML)
4.5 use performance indicators from the config file (per keyword) to
establish that the runtime is within acceptable parameters (mem,cpu,time,output)
4.6 track performance indicators and runtime metrics in a database, provide "built in"
keyword to fetch metrics.
5 Sample configuration file
This config file is in yaml format with a leading comment block (# delimited).
Using the python package 'rtyaml' will preserve this leading comment block
when writing the config file. Other libraries do not preserve this block.
rtyaml will not preserve any other comments.
# configuration file for 'factotum' -- a small python daemon that
# serves relatively arbitrary commandline tasks via HTTP
#
# Security: Make sure you understand your inputs and outputs, especially
# if you run this command as a privileged user.
#
# Configuration Elements:
# commandfile: a file to load commands from (also yaml)
# banner: a string to print when anything connects
# interface: list of IP addresses that this service listens on. (0.0.0.0 - means all interfaces)
# logging: is a list of configuration elements to control logging
# facility: one of the syslog facility names
# type: 'file' or 'syslog'
# file: path to the logging file if type='file'
# level: syslog priority and to choose what messages to print
# port: the TCP port to listen on
# version: gives the version of factotum for clients to verify
# client: list of verification settings
# version: client version string regular expression (match == pass) (null == auto-pass)
# verify: turn on/off client verification
# ip: client ip address regular expression (match == pass) (null == auto-pass)
# debug: turns on various messages and Flask debug if True
#
# Python YAML via rtyaml only preserves comments at the beginning of the file.
commandfile: commands.conf
banner: Factotum test
interface: 0.0.0.0
logging:
facility: user
file: not used unless type = file
level: debug
type: syslog
port: 9000
version: 1.0
client:
version: /[10].[0-9]/
verify: false
ip: ~
debug: True
6 Sample commands.conf file
# This file contains some trivial examples, the keyword is the
# part expected in the URL like
# http://localhost:9000/LSSYSLOG
# ^^^^^^^^
#
# then the program changes directory to the 'chdir' value and
# executes the 'exec' value. These are trivial examples,
# with some validation additional parameters can be accepted and
# passed to the exec line.
#
# The following keywords are reserved:
# /commands
# /config
# /env
# /id
# /status
LSSYSLOG:
chdir: /var/log
exec: /bin/ls -al system.log
MOTD:
chdir: /
exec: /bin/cat /etc/motd
SIGH:
chdir: /
exec: /bin/echo Sighed, Yes!
7 Sample commandline specification
factotum [-d] [-v...] [-c file|url]
-d : debugging mode, don't fork into a daemon
-v : verbose mode, print out additional logging to stderr
specify multiple times to increase verbosity
-c : a file or url specifying where the configuration file is
If given as a url, we expect to fetch YAML directly from that URL
and process it identically as if it came from a file.