]> ruderich.org/simon Gitweb - safcm/safcm.git/blob - README.adoc
README: mention why YAML was chosen
[safcm/safcm.git] / README.adoc
1 = README
2
3 Simple and fast configuration management (safcm) is written in Go and licensed
4 under GPLv3+. It is:
5
6 - *simple*: to use and implement, obvious concepts and less bugs
7 - *fast*: to learn and to use, quickly apply new configurations to your hosts
8 - *configuration management*: sync files, packages, services and run commands
9   on remote hosts
10
11 The goal is that even unexperienced users (with safcm or configuration
12 management in general) should be able to apply configuration with safcm
13 quickly. This means all key concepts of safcm must be easy to grasp and for
14 each task there should be one obvious way.
15
16 It can also be read as "saf(e) configuration management" as it combines
17 simplicity and safety in the following principles:
18
19 - *fail fast*: catch (user) errors as soon as possible; host configuration
20   (including templates) evaluated locally to prevent partial configuration;
21   errors immediately abort the synchronization
22 - *remote hosts untrusted*: clear security boundary between local and remote
23   host; data used from remote hosts is marked (detected groups); all output
24   from remote hosts is escaped to prevent terminal injection attacks; each
25   host only receives its configuration and no data from other hosts
26 - *safety and security*: create files with "write to temporary file", "sync",
27   "rename", "sync directory" for atomicity and durability; guard against
28   symlink and other TOCTOU attacks; extensive test suite
29
30
31 == Overview
32
33 This section describes the general concepts, behavior and terminology of
34 safcm.
35
36 Safcm _synchronizes_ _files_, _packages_, _services_ and _commands_ to remote
37 _hosts_. All hosts are explicitly configured. Hosts can be put into _groups_
38 to apply the same configuration to multiple hosts. The host itself is also
39 considered a group for host-specific configuration. In addition to manual
40 group assignment _detected groups_ assign hosts to groups depending on the
41 output of custom commands on the remote host. The configuration for a group
42 contains the files, packages, services and commands which should be applied to
43 all hosts which are members of this group.
44
45 The configuration of all managed hosts is stored in a directory on the local
46 host. Safcm uses https://yaml.org/[YAML] for all configuration files for its
47 natural syntax. Strict type checks prevent potential pitfalls of more complex
48 YAML syntax. Tasks like copying a file require no explicit configuration (see
49 the documentation for details).
50
51 Files consist of a tree of files (regular files and symbolic links) and
52 directories with permissions, user/group and content. Files can use
53 _templates_ for dynamic content depending on the host or its groups. Each path
54 can have _trigger_ commands which are executed when the path itself or any
55 sub-paths are modified during synchronization. Packages are package names of
56 the remote operating system. Services are service names of the remote
57 operating system. Commands are shell commands passed to `/bin/sh`.
58
59 When files with the same path are present in multiple groups of a host an
60 explicit _group order_ must be configured to resolve the conflict. Conflicts
61 do not apply to packages and services which are simply merged from all groups.
62 Commands are appended so that the same command can be executed multiple times.
63
64 To sync the configuration to a remote host the local `safcm` binary connects
65 to it via `ssh`. It then copies a _remote helper_ binary to `/tmp` on the
66 remote host to later perform the actual sync. If the remote helper is already
67 present, has the proper checksum, permissions and user then the copy is
68 skipped. `safcm` then queries the remote host for information, including
69 operating system, architecture and detected groups. With all relevant data
70 collected it assigns the host its groups, evaluates the configuration
71 including templates and finally sends it to the remote helper which then
72 applies it to the remote host.
73
74 The synchronization happens in the following order which cannot be changed:
75
76 . Collect information from remote helper including detected groups
77 . Build configuration for the host and send it to the remote helper
78 . Apply the configuration using the remote helper
79 .. Synchronize files
80 .. Install packages
81 .. Enable/Start services
82 .. Run triggers
83 .. Run commands
84
85 After the synchronization is complete (or on the first error) the applied
86 changes are displayed. Multiple hosts are synchronized in parallel.
87
88
89 == Limitations & Gotchas
90
91 Besides some obvious limitations due to the simplicity of safcm there are a
92 few issues the user should be aware of. Some of these might get fixed in the
93 future, others are due to the design of safcm.
94
95 - Commands are executed with `/bin/sh -c` on the remote host which might leak
96   sensitive information to other users via the command line (unless `/proc` is
97   mounted with `hidepid=`). Store sensitive data in a file and execute or
98   source it as a workaround.
99
100 - Permissions of existing files and directories will be overwritten with the
101   default (root/root, 0644 for files, 0755 for directories) unless manually
102   configured via `permissions.yaml`. This includes important paths like
103   `/root` which often have strict permissions by default, so carefully check
104   the diff output for unwanted changes.
105
106 - Full file content of all files is sent to the remote during synchronization.
107   This makes it impractical to synchronize large files with safcm. As most
108   configuration files are small this shouldn't be an issue for common
109   scenarios.
110
111 - Quoted strings in the output are quoted using Go's `%q` format string. The
112   result is similar -- but not identical -- to quoted strings in regular shell
113   scripts which can be confusing.
114
115 - Permissions of symlinks are ignored on BSD systems. They are always shown to
116   have `0777` as permissions even though the current umask controls the actual
117   permissions when creating new symlinks. Existing symlinks with different
118   permissions are not updated. Most BSDs ignore the permissions when following
119   symlinks which should reduce the impact of this limitation.
120
121
122 == Requirements
123
124 - build the `safcm` binary and remote helper:
125   * Go >= 1.16
126   * GNU make
127
128 - local host:
129   * Go support for architecture and operating system, see the "$GOOS and
130     $GOARCH" section in the official
131     https://golang.org/doc/install/source#environment[Go installation guide]
132
133 - *remote hosts*:
134   * Go support for architecture and operating system
135   * Supported operating system:
136     ** GNU/Linux with common commands (`uname`, `id`, `stat`, `sha512sum`,
137        `cat`, `mktemp`, `rm`, `ln`, `chmod`)
138     ** FreeBSD (same commands, but uses `sha512`)
139     ** OpenBSD (same commands, but uses `sha512`)
140   * SSH server
141   * to install packages:
142     ** `apt-get` (Debian or derivative)
143   * to sync services:
144     ** `systemd`
145
146 Adding support for other operating systems (e.g. BSDs) or distributions
147 including package managers (e.g. Arch, Gentoo) is easy. Please send patches.
148
149
150 == Authors
151
152 Written by Simon Ruderich <simon@ruderich.org>.
153
154
155 == License
156
157 This program is licensed under GPL version 3 or later.
158
159 Copyright (C) 2021  Simon Ruderich
160
161 This program is free software: you can redistribute it and/or modify
162 it under the terms of the GNU General Public License as published by
163 the Free Software Foundation, either version 3 of the License, or
164 (at your option) any later version.
165
166 This program is distributed in the hope that it will be useful,
167 but WITHOUT ANY WARRANTY; without even the implied warranty of
168 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
169 GNU General Public License for more details.
170
171 You should have received a copy of the GNU General Public License
172 along with this program.  If not, see <http://www.gnu.org/licenses/>.