root / doc / security.rst @ 33c730a2
History | View | Annotate | Download (8.9 kB)
1 |
Security in Ganeti |
---|---|
2 |
================== |
3 |
|
4 |
Documents Ganeti version 2.7 |
5 |
|
6 |
Ganeti was developed to run on internal, trusted systems. As such, the |
7 |
security model is all-or-nothing. |
8 |
|
9 |
Up to version 2.3 all Ganeti code ran as root. Since version 2.4 it is |
10 |
possible to run all daemons except the node daemon as non-root users by |
11 |
specifying user names and groups at build time. The node daemon |
12 |
continues to require root privileges to create logical volumes, DRBD |
13 |
devices, start instances, etc. Cluster commands can be run as root or by |
14 |
users in a group specified at build time. |
15 |
|
16 |
Host issues |
17 |
----------- |
18 |
|
19 |
For a host on which the Ganeti software has been installed, but not |
20 |
joined to a cluster, there are no changes to the system. |
21 |
|
22 |
For a host that has been joined to the cluster, there are very important |
23 |
changes: |
24 |
|
25 |
- The host will have its SSH host key replaced with the one of the |
26 |
cluster (which is the one the initial node had at the cluster |
27 |
creation) |
28 |
- A new public key will be added to root's ``authorized_keys`` file, |
29 |
granting root access to all nodes of the cluster. The private part of |
30 |
the key is also distributed to all nodes. Old files are renamed. |
31 |
- Communication between nodes is encrypted using SSL/TLS. A common key |
32 |
and certificate combo is shared between all nodes of the cluster. At |
33 |
this time, no CA is used. |
34 |
- The Ganeti node daemon will accept RPC requests from any host within |
35 |
the cluster with the correct certificate, and the operations it will |
36 |
do as a result of these requests are: |
37 |
|
38 |
- running commands under the ``/etc/ganeti/hooks`` directory |
39 |
- creating DRBD disks between it and the IP it has been told |
40 |
- overwrite a defined list of files on the host |
41 |
|
42 |
As you can see, as soon as a node is joined, it becomes equal to all |
43 |
other nodes in the cluster, and the security of the cluster is |
44 |
determined by the weakest node. |
45 |
|
46 |
Note that only the SSH key will allow other machines to run any command |
47 |
on this node; the RPC method will run only: |
48 |
|
49 |
- well defined commands to create, remove, activate logical volumes, |
50 |
drbd devices, start/stop instances, etc; |
51 |
- run well-defined SSH commands on other nodes in the cluster |
52 |
- scripts under the ``/etc/ganeti/hooks`` directory |
53 |
- scripts under the ``/etc/ganeti/restricted-commands`` directory, if |
54 |
this feature has been enabled at build time (see below) |
55 |
|
56 |
It is therefore important to make sure that the contents of the |
57 |
``/etc/ganeti/hooks`` and ``/etc/ganeti/restricted-commands`` |
58 |
directories are supervised and only trusted sources can populate them. |
59 |
|
60 |
Restricted commands |
61 |
~~~~~~~~~~~~~~~~~~~ |
62 |
|
63 |
The restricted commands feature is new in Ganeti 2.7. It enables the |
64 |
administrator to run any commands in the |
65 |
``/etc/ganeti/restricted-commands`` directory, if the feature has been |
66 |
enabled at build time, subject to the following restrictions: |
67 |
|
68 |
- No parameters may be passed |
69 |
- No absolute or relative path may be passed, only a filename |
70 |
- The ``/etc/ganeti/restricted-commands`` directory must |
71 |
be owned by root:root and have mode 0755 or stricter |
72 |
- Executables must be regular files or symlinks, and must be executable |
73 |
by root:root |
74 |
|
75 |
Note that it's not possible to list the contents of the directory, and |
76 |
there is an intentional delay when trying to execute a non-existing |
77 |
command (to slow-down dictionary attacks). |
78 |
|
79 |
Since for Ganeti itself this functionality is not needed, and is only |
80 |
provided as a way to help administrate or recover nodes, it is a local |
81 |
site decision whether to enable or not the restricted commands feature. |
82 |
|
83 |
By default, this feature is disabled. |
84 |
|
85 |
|
86 |
Cluster issues |
87 |
-------------- |
88 |
|
89 |
As mentioned above, there are multiple ways of communication between |
90 |
cluster nodes: |
91 |
|
92 |
- SSH-based, for high-volume traffic like image dumps or for low-level |
93 |
command, e.g. restarting the Ganeti node daemon |
94 |
- RPC communication between master and nodes |
95 |
- DRBD real-time disk replication traffic |
96 |
|
97 |
The SSH traffic is protected (after the initial login to a new node) by |
98 |
the cluster-wide shared SSH key. |
99 |
|
100 |
RPC communication between the master and nodes is protected using |
101 |
SSL/TLS encryption. Both the client and the server must have the |
102 |
cluster-wide shared SSL/TLS certificate and verify it when establishing |
103 |
the connection by comparing fingerprints. We decided not to use a CA to |
104 |
simplify the key handling. |
105 |
|
106 |
The DRBD traffic is not protected by encryption, as DRBD does not |
107 |
support this. It's therefore recommended to implement host-level |
108 |
firewalling or to use a separate range of IP addresses for the DRBD |
109 |
traffic (this is supported in Ganeti through the use of a secondary |
110 |
interface) which is not routed outside the cluster. DRBD connections are |
111 |
protected from erroneous connections to other machines (as may happen |
112 |
due to software issues), and from accepting connections from other |
113 |
machines, by using a shared secret, exchanged via RPC requests from the |
114 |
master to the nodes when configuring the device. |
115 |
|
116 |
Master daemon |
117 |
------------- |
118 |
|
119 |
The command-line tools to master daemon communication is done via a |
120 |
UNIX socket, whose permissions are reset to ``0660`` after listening but |
121 |
before serving requests. This permission-based protection is documented |
122 |
and works on Linux, but is not-portable; however, Ganeti doesn't work on |
123 |
non-Linux system at the moment. |
124 |
|
125 |
Conf daemon |
126 |
----------- |
127 |
|
128 |
In Ganeti 2.7, the ``confd`` daemon (if enabled at build time), serves |
129 |
both network-originated queries (about the static configuration) and |
130 |
local (UNIX socket) queries (about the run-time configuration; answering |
131 |
these means talking to other cluster nodes, which makes use of the |
132 |
internal RPC SSL certificate). This makes it a bit more sensitive to |
133 |
bugs (a remote attacker could get direct access to the intra-cluster |
134 |
RPC), so to harden security it's recommended to: |
135 |
|
136 |
- disable confd at build time if it's not needed in your setup |
137 |
- otherwise, configure Ganeti (at build time) to use separate users, so |
138 |
that the confd daemon doesn't also have access to the server SSL/TLS |
139 |
certificates |
140 |
|
141 |
It is planned to split the two functionalities (local/remote querying) |
142 |
of confd into two separate daemons in a future Ganeti version. |
143 |
|
144 |
Remote API |
145 |
---------- |
146 |
|
147 |
Starting with Ganeti 2.0, Remote API traffic is encrypted using SSL/TLS |
148 |
by default. It supports Basic authentication as per :rfc:`2617`. Users |
149 |
can be granted different capabilities. Details can be found in the |
150 |
:ref:`RAPI documentation <rapi-users>`. |
151 |
|
152 |
Paths for certificate, private key and CA files required for SSL/TLS |
153 |
will be set at source configure time. Symlinks or command line |
154 |
parameters may be used to use different files. |
155 |
|
156 |
Inter-cluster instance moves |
157 |
---------------------------- |
158 |
|
159 |
To move instances between clusters, different clusters must be able to |
160 |
communicate with each other over a secure channel. Up to and including |
161 |
Ganeti 2.1, clusters were self-contained entities and had no knowledge |
162 |
of other clusters. With Ganeti 2.2, clusters can exchange data if tokens |
163 |
(an encryption certificate) was exchanged by a trusted third party |
164 |
before. |
165 |
|
166 |
KVM Security |
167 |
------------ |
168 |
|
169 |
When running KVM instances under Ganeti three security models ara |
170 |
available: "none", "user" and "pool". |
171 |
|
172 |
Under security model "none" instances run by default as root. This means |
173 |
that, if an instance gets jail broken, it will be able to own the host |
174 |
node, and thus the ganeti cluster. This is the default model, and the |
175 |
only one available before Ganeti 2.1.2. |
176 |
|
177 |
Under security model "user" an instance is run as the user specified by |
178 |
the hypervisor parameter "security_domain". This makes it easy to run |
179 |
all instances as non privileged users, and allows one to manually |
180 |
allocate specific users to specific instances or sets of instances. If |
181 |
the specified user doesn't have permissions a jail broken instance will |
182 |
need some local privilege escalation before being able to take over the |
183 |
node and the cluster. It's possible though for a jail broken instance to |
184 |
affect other ones running under the same user. |
185 |
|
186 |
Under security model "pool" a global cluster-level uid pool is used to |
187 |
start each instance on the same node under a different user. The uids in |
188 |
the cluster pool can be set with ``gnt-cluster init`` and ``gnt-cluster |
189 |
modify``, and must correspond to existing users on all nodes. Ganeti |
190 |
will then allocate one to each instance, as needed. This way a jail |
191 |
broken instance won't be able to affect any other. Since the users are |
192 |
handed out by ganeti in a per-node randomized way, in this mode there is |
193 |
no way to make sure a particular instance is always run as a certain |
194 |
user. Use mode "user" for that. |
195 |
|
196 |
In addition to these precautions, if you want to avoid instances sending |
197 |
traffic on your node network, you can use an iptables rule such as:: |
198 |
|
199 |
iptables -A OUTPUT -m owner --uid-owner <uid>[-<uid>] -j LOG \ |
200 |
--log-prefix "ganeti uid pool user network traffic" |
201 |
iptables -A OUTPUT -m owner --uid-owner <uid>[-<uid>] -j DROP |
202 |
|
203 |
This won't affect regular instance traffic (that comes out of the tapX |
204 |
allocated to the instance, and can be filtered or subject to appropriate |
205 |
policy routes) but will stop any user generated traffic that might come |
206 |
from a jailbroken instance. |
207 |
|
208 |
.. vim: set textwidth=72 : |
209 |
.. Local Variables: |
210 |
.. mode: rst |
211 |
.. fill-column: 72 |
212 |
.. End: |