Skip to content
mateuszkwiatkowski edited this page Feb 20, 2013 · 30 revisions

This page will document all security concerns related to Archipel. It's a must-read if Archipel is going to be used by more people than just you.

This tutorial assumes you are running Archipel in production environment. Thus, each Archipel agent has got its own IP and real domain - no /etc/hosts hacking please. We assume XMPP server runs on a different machine.

If there's anything more that needs to be covered in this article, feel free to include it or contact Nowaker on freenode/#archipel.

"define" and "xmldesc" permissions on the virtual machine

Untrusted user should not be given the "define" permission. It allows user to edit the XML descriptor of the virtual machine where they can set all they want. In worst case, local disk on host (e.g. /dev/sda) can be mounted read-only to virtual machine and all the data can be read.

"xmldesc" permission is about reading the virtual machine XML descriptor. That is, user won't be able to access the "Definition" tab if not given an "xmldesc" permission.

  • "define" and "xmldesc" - user is able to define the virtual machine as they want
  • "xmldesc" only - user can access the Definition tab in read-only mode
  • "define" only - user can't access the Definition tab, as they can't access the XML

There is also enable_block_device_access setting in /etc/archipel/archipel.conf but it doesn't do anything useful while the user can edit the XML directly.

Encrypted XMPP

All XMPP traffic on ports 5222, 5269 and 5280 should be encrypted.

User needs to remember changing the BOSH proxy URL when accessing Archipel client for the first time. "https" should be used, not "http". (e.g. https://xmpp.example.com:5280/http-bind)

Use this draft ejabberd config to encrypt all channels. (This has not yet been confirmed by my security auditor, I will update when it's confirmed.)

{listen, [
  {4560, ejabberd_xmlrpc, []},

  {5222, ejabberd_c2s, [
    {access, c2s},
    starttls,
    {certfile, "/etc/ejabberd/cert.pem"},
    {max_stanza_size, 65536000}
  ]},

  {5269, ejabberd_s2s_in, [
    {max_stanza_size, 65536000}
  ]},

  {5280, ejabberd_http, [
    http_bind,
    http_poll,
    web_admin,
    tls,
    {certfile, "/etc/ejabberd/cert.pem"}
  ]}
]}.

{route_subdomains, s2s}.
{s2s_use_starttls, true}.
{s2s_default_policy, allow}.    
{s2s_certfile, "/etc/ejabberd/cert.pem"}.

Encrypted XML-RPC @ XMPP

If using ejabberd_xmlrpc and the hypervisors are not inside the trusted network, port 4560 should be encrypted as well. However, ejabberd_xmlrpc module does not support SSL yet so we must use some 3rd party software for proxying traffic, eg. nginx.

First, in listen section we set ejabberd_xmlrpc to listen on localhost only:

{listen, [
  {{4560, "127.0.0.1"}, ejabberd_xmlrpc},
(...)

Next, configure nginx to proxy all XML-RPC traffic to ejabbert_xmlrpc. Traffic from hypervisors will by encrypted.

http {
  server  {
    listen 1.2.3.4:4560;
    ssl on;
    ssl_certificate /etc/ejabberd/cert.pem;
    ssl_certificate_key /etc/ejabberd/cert.key;
    location / {
      proxy_pass http://localhost:4560;
      proxy_set_header  X-Real-IP  $remote_addr;
      }
  }
}

Finally, we can modify archipel-agent to support XML-RCP over SSL. Here comes the patch for archipelagentxmppserver/xmppserver_xmlrpc.py (on our servers in /usr/lib/python2.7/site-packages/):

46c46
<         self.xmlrpc_call        = "http://%s:%s@%s:%s/" % (self.xmlrpc_user, self.xmlrpc_password, self.xmlrpc_host, self.xmlrpc_port)
---
>         self.xmlrpc_call        = "https://%s:%s@%s:%s/" % (self.xmlrpc_user, self.xmlrpc_password, self.xmlrpc_host, self.xmlrpc_port)

And for archipel-testxmppserver (on our servers in /usr/bin/):

238c238
<     xmlrpc_call         = "http://%s:%s@%s:%s/" % (xmlrpc_user, xmlrpc_password, xmlrpc_host, xmlrpc_port)
---
>     xmlrpc_call         = "https://%s:%s@%s:%s/" % (xmlrpc_user, xmlrpc_password, xmlrpc_host, xmlrpc_port)
255c255
<     xmlrpc_call         = "http://%s:%s@%s:%s/" % (xmlrpc_user, xmlrpc_password, xmlrpc_host, xmlrpc_port)
---
>     xmlrpc_call         = "https://%s:%s@%s:%s/" % (xmlrpc_user, xmlrpc_password, xmlrpc_host, xmlrpc_port)

Encrypted VNC

KVM runs an unencrypted VNC for a virtual machine if told so in VM XML descriptor. That connections are unencrypted and you should not be exposed to the Internet, that is - listen on 127.0.0.1 only. Archipel agent runs an encrypted proxy for each VNC on a 69xx port. They should listen on 0.0.0.0 so it's open for connections from the browser. Every VNC should be password-protected as well.

VNC listen port

% netstat -ant | grep -i listen
tcp        0      0 127.0.0.1:5907          0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:6907            0.0.0.0:*               LISTEN     

Archipel agent is given a sample VNC certificate by default but you should not use it as everyone has got the same. Replace it with yours in /etc/archipel/archipel.conf for each agent and ensure only SSL is used:

vnc_certificate_file = /etc/archipel/your-cert.pem
vnc_only_ssl = True

When using a trusted certificate, make sure that the VNC URL Archipel client connects to matches the domain from certificate. While it doesn't cause any security holes, it will prevent any warnings about untrusted certificates from appearing. The easiest way is to check it in the web browser console (Ctrl+Shift+J in Chrome). If the domain is wrong, change it to machine_ip = example.com in archipel.conf (don't be fooled by the property name).

2013-02-17 13:01:49.721 Cappuccino [info]: VNC: connecting to example.com:6907  using SSL: true (checkRate: 217, FBURate: 1413)

Running Archipel agent as non-root

TBD. Please read page Installation-serviceuser for instructions.

Misc

  • StartSSL provides signed certificates free of charge.
Clone this wiki locally