root / doc / security.rst @ 995736c6
History | View | Annotate | Download (6.6 kB)
1 |
Security in Ganeti |
---|---|
2 |
================== |
3 |
|
4 |
Ganeti was developed to run on internal, trusted systems. As such, the |
5 |
security model is all-or-nothing. |
6 |
|
7 |
All the Ganeti code runs as root, because all the operations that Ganeti |
8 |
is doing require privileges: creating logical volumes, drbd devices, |
9 |
starting instances, etc. Running as root does not mean setuid, but that |
10 |
you need to be root to run the cluster commands. |
11 |
|
12 |
Host issues |
13 |
----------- |
14 |
|
15 |
For a host on which the Ganeti software has been installed, but not |
16 |
joined to a cluster, there are no changes to the system. |
17 |
|
18 |
For a host that has been joined to the cluster, there are very important |
19 |
changes: |
20 |
|
21 |
- The host will have its SSH host key replaced with the one of the |
22 |
cluster (which is the one the initial node had at the cluster |
23 |
creation) |
24 |
- A new public key will be added to root's authorized_keys file, |
25 |
granting root access to all nodes of the cluster. The private part of |
26 |
the key is also distributed to all nodes. Old files are renamed. |
27 |
- Communication between nodes is encrypted using SSL/TLS. A common key |
28 |
and certificate combo is shared between all nodes of the cluster. At |
29 |
this time, no CA is used. |
30 |
- The Ganeti node daemon will accept RPC requests from any host within |
31 |
the cluster with the correct certificate, and the operations it will |
32 |
do as a result of these requests are: |
33 |
|
34 |
- running commands under the /etc/ganeti/hooks directory |
35 |
- creating DRBD disks between it and the IP it has been told |
36 |
- overwrite a defined list of files on the host |
37 |
|
38 |
As you can see, as soon as a node is joined, it becomes equal to all |
39 |
other nodes in the cluster, and the security of the cluster is |
40 |
determined by the weakest node. |
41 |
|
42 |
Note that only the SSH key will allow other machines to run random |
43 |
commands on this node; the RPC method will run only: |
44 |
|
45 |
- well defined commands to create, remove, activate logical volumes, |
46 |
drbd devices, start/stop instances, etc; |
47 |
- run SSH commands on other nodes in the cluster, again well-defined |
48 |
- scripts under the /etc/ganeti/hooks directory |
49 |
|
50 |
It is therefore important to make sure that the contents of the |
51 |
/etc/ganeti/hooks directory is supervised and only trusted sources can |
52 |
populate it. |
53 |
|
54 |
Cluster issues |
55 |
-------------- |
56 |
|
57 |
As told above, there are multiple ways of communication between cluster |
58 |
nodes: |
59 |
|
60 |
- SSH-based, for high-volume traffic like image dumps or for low-level |
61 |
command, e.g. restarting the Ganeti node daemon |
62 |
- RPC communication between master and nodes |
63 |
- DRBD real-time disk replication traffic |
64 |
|
65 |
The SSH traffic is protected (after the initial login to a new node) by |
66 |
the cluster-wide shared SSH key. |
67 |
|
68 |
RPC communication between the master and nodes is protected using |
69 |
SSL/TLS encryption. Both the client and the server must have the |
70 |
cluster-wide shared SSL/TLS certificate and verify it when establishing |
71 |
the connection by comparing fingerprints. We decided not to use a CA to |
72 |
simplify the key handling. |
73 |
|
74 |
The DRBD traffic is not protected by encryption, as DRBD does not |
75 |
support this. It's therefore recommended to implement host-level |
76 |
firewalling or to use a separate range of IP addresses for the DRBD |
77 |
traffic (this is supported in Ganeti) which is not routed outside the |
78 |
cluster. DRBD connections are protected from connecting due to bugs to |
79 |
other machines, and from accepting connections from other machines, by |
80 |
using a shared secret, exchanged via RPC requests from the master to the |
81 |
nodes when configuring the device. |
82 |
|
83 |
Master daemon |
84 |
------------- |
85 |
|
86 |
The command-line tools to master daemon communication is done via an |
87 |
UNIX socket, whose permissions are reset to ``0600`` after listening but |
88 |
before serving requests. This permission-based protection is documented |
89 |
and works on Linux, but is not-portable; however, Ganeti doesn't work on |
90 |
non-Linux system at the moment. |
91 |
|
92 |
Remote API |
93 |
---------- |
94 |
|
95 |
Starting with Ganeti 2.0, Remote API traffic is encrypted using SSL/TLS |
96 |
by default. It supports Basic authentication as per :rfc:`2617`. |
97 |
|
98 |
Paths for certificate, private key and CA files required for SSL/TLS |
99 |
will be set at source configure time. Symlinks or command line |
100 |
parameters may be used to use different files. |
101 |
|
102 |
Inter-cluster instance moves |
103 |
---------------------------- |
104 |
|
105 |
To move instances between clusters, different clusters must be able to |
106 |
communicate with each other over a secure channel. Up to and including |
107 |
Ganeti 2.1, clusters were self-contained entities and had no knowledge |
108 |
of other clusters. With Ganeti 2.2, clusters can exchange data if tokens |
109 |
(an encryption certificate) was exchanged by a trusted third party |
110 |
before. |
111 |
|
112 |
KVM Security |
113 |
------------ |
114 |
|
115 |
When running KVM instances under Ganeti three security models ara |
116 |
available: 'none', 'user' and 'pool'. |
117 |
|
118 |
Under security model 'none' instances run by default as root. This means |
119 |
that, if an instance gets jail broken, it will be able to own the host |
120 |
node, and thus the ganeti cluster. This is the default model, and the |
121 |
only one available before Ganeti 2.1.2. |
122 |
|
123 |
Under security model 'user' an instance is run as the user specified by |
124 |
the hypervisor parameter 'security_domain'. This makes it easy to run |
125 |
all instances as non privileged users, and allows one to manually |
126 |
allocate specific users to specific instances or sets of instances. If |
127 |
the specified user doesn't have permissions a jail broken instance will |
128 |
need some local privilege escalation before being able to take over the |
129 |
node and the cluster. It's possible though for a jail broken instance to |
130 |
affect other ones running under the same user. |
131 |
|
132 |
Under security model 'pool' a global cluster-level uid pool is used to |
133 |
start each instance on the same node under a different user. The uids in |
134 |
the cluster pool can be set with ``gnt-cluster init`` and ``gnt-cluster |
135 |
modify``, and must correspond to existing users on all nodes. Ganeti |
136 |
will then allocate one to each instance, as needed. This way a jail |
137 |
broken instance won't be able to affect any other. Since the users are |
138 |
handed out by ganeti in a per-node randomized way, in this mode there is |
139 |
no way to make sure a particular instance is always run as a certain |
140 |
user. Use mode 'user' for that. |
141 |
|
142 |
In addition to these precautions, if you want to avoid instances sending |
143 |
traffic on your node network, you can use an iptables rule such as:: |
144 |
|
145 |
iptables -A OUTPUT -m owner --uid-owner <uid>[-<uid>] -j LOG \ |
146 |
--log-prefix "ganeti uid pool user network traffic" |
147 |
iptables -A OUTPUT -m owner --uid-owner <uid>[-<uid>] -j DROP |
148 |
|
149 |
This won't affect regular instance traffic (that comes out of the tapX |
150 |
allocated to the instance, and can be filtered or subject to appropriate |
151 |
policy routes) but will stop any user generated traffic that might come |
152 |
from a jailbroken instance. |
153 |
|
154 |
.. vim: set textwidth=72 : |
155 |
.. Local Variables: |
156 |
.. mode: rst |
157 |
.. fill-column: 72 |
158 |
.. End: |