root / doc / security.rst @ f1d243bd
History | View | Annotate | Download (6.9 kB)
1 |
Security in Ganeti |
---|---|
2 |
================== |
3 |
|
4 |
Documents Ganeti version 2.6 |
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 |
|
54 |
It is therefore important to make sure that the contents of the |
55 |
``/etc/ganeti/hooks`` directory is supervised and only trusted sources |
56 |
can populate it. |
57 |
|
58 |
Cluster issues |
59 |
-------------- |
60 |
|
61 |
As mentioned above, there are multiple ways of communication between |
62 |
cluster nodes: |
63 |
|
64 |
- SSH-based, for high-volume traffic like image dumps or for low-level |
65 |
command, e.g. restarting the Ganeti node daemon |
66 |
- RPC communication between master and nodes |
67 |
- DRBD real-time disk replication traffic |
68 |
|
69 |
The SSH traffic is protected (after the initial login to a new node) by |
70 |
the cluster-wide shared SSH key. |
71 |
|
72 |
RPC communication between the master and nodes is protected using |
73 |
SSL/TLS encryption. Both the client and the server must have the |
74 |
cluster-wide shared SSL/TLS certificate and verify it when establishing |
75 |
the connection by comparing fingerprints. We decided not to use a CA to |
76 |
simplify the key handling. |
77 |
|
78 |
The DRBD traffic is not protected by encryption, as DRBD does not |
79 |
support this. It's therefore recommended to implement host-level |
80 |
firewalling or to use a separate range of IP addresses for the DRBD |
81 |
traffic (this is supported in Ganeti through the use of a secondary |
82 |
interface) which is not routed outside the cluster. DRBD connections are |
83 |
protected from erroneous connections to other machines (as may happen |
84 |
due to software issues), and from accepting connections from other |
85 |
machines, by using a shared secret, exchanged via RPC requests from the |
86 |
master to the nodes when configuring the device. |
87 |
|
88 |
Master daemon |
89 |
------------- |
90 |
|
91 |
The command-line tools to master daemon communication is done via a |
92 |
UNIX socket, whose permissions are reset to ``0660`` after listening but |
93 |
before serving requests. This permission-based protection is documented |
94 |
and works on Linux, but is not-portable; however, Ganeti doesn't work on |
95 |
non-Linux system at the moment. |
96 |
|
97 |
Remote API |
98 |
---------- |
99 |
|
100 |
Starting with Ganeti 2.0, Remote API traffic is encrypted using SSL/TLS |
101 |
by default. It supports Basic authentication as per :rfc:`2617`. Users |
102 |
can be granted different capabilities. Details can be found in the |
103 |
:ref:`RAPI documentation <rapi-users>`. |
104 |
|
105 |
Paths for certificate, private key and CA files required for SSL/TLS |
106 |
will be set at source configure time. Symlinks or command line |
107 |
parameters may be used to use different files. |
108 |
|
109 |
Inter-cluster instance moves |
110 |
---------------------------- |
111 |
|
112 |
To move instances between clusters, different clusters must be able to |
113 |
communicate with each other over a secure channel. Up to and including |
114 |
Ganeti 2.1, clusters were self-contained entities and had no knowledge |
115 |
of other clusters. With Ganeti 2.2, clusters can exchange data if tokens |
116 |
(an encryption certificate) was exchanged by a trusted third party |
117 |
before. |
118 |
|
119 |
KVM Security |
120 |
------------ |
121 |
|
122 |
When running KVM instances under Ganeti three security models ara |
123 |
available: "none", "user" and "pool". |
124 |
|
125 |
Under security model "none" instances run by default as root. This means |
126 |
that, if an instance gets jail broken, it will be able to own the host |
127 |
node, and thus the ganeti cluster. This is the default model, and the |
128 |
only one available before Ganeti 2.1.2. |
129 |
|
130 |
Under security model "user" an instance is run as the user specified by |
131 |
the hypervisor parameter "security_domain". This makes it easy to run |
132 |
all instances as non privileged users, and allows one to manually |
133 |
allocate specific users to specific instances or sets of instances. If |
134 |
the specified user doesn't have permissions a jail broken instance will |
135 |
need some local privilege escalation before being able to take over the |
136 |
node and the cluster. It's possible though for a jail broken instance to |
137 |
affect other ones running under the same user. |
138 |
|
139 |
Under security model "pool" a global cluster-level uid pool is used to |
140 |
start each instance on the same node under a different user. The uids in |
141 |
the cluster pool can be set with ``gnt-cluster init`` and ``gnt-cluster |
142 |
modify``, and must correspond to existing users on all nodes. Ganeti |
143 |
will then allocate one to each instance, as needed. This way a jail |
144 |
broken instance won't be able to affect any other. Since the users are |
145 |
handed out by ganeti in a per-node randomized way, in this mode there is |
146 |
no way to make sure a particular instance is always run as a certain |
147 |
user. Use mode "user" for that. |
148 |
|
149 |
In addition to these precautions, if you want to avoid instances sending |
150 |
traffic on your node network, you can use an iptables rule such as:: |
151 |
|
152 |
iptables -A OUTPUT -m owner --uid-owner <uid>[-<uid>] -j LOG \ |
153 |
--log-prefix "ganeti uid pool user network traffic" |
154 |
iptables -A OUTPUT -m owner --uid-owner <uid>[-<uid>] -j DROP |
155 |
|
156 |
This won't affect regular instance traffic (that comes out of the tapX |
157 |
allocated to the instance, and can be filtered or subject to appropriate |
158 |
policy routes) but will stop any user generated traffic that might come |
159 |
from a jailbroken instance. |
160 |
|
161 |
.. vim: set textwidth=72 : |
162 |
.. Local Variables: |
163 |
.. mode: rst |
164 |
.. fill-column: 72 |
165 |
.. End: |