Commit 1ee608c4 authored by Stratos Psomadakis's avatar Stratos Psomadakis
Browse files

Encrypt instance ids in the stats URLs

parent 597404ab
......@@ -173,6 +173,14 @@ Cyclades
'service-export-cyclades'.
* Obsolete PUBLIC_USE_POOL setting, since Cyclades manages IP pool for all
type of networks.
* Encrypt / decrypt the instance id / hostname in the stats URL in
snf-cyclades-app and snf-stats-app, using the 'CYCLADES_STATS_SECRET_KEY'
and 'STATS_SECRET_KEY' respectively.
* Add support for snf-vncauthproxy-1.5 and the setting
'CYCLADES_VNCAUTHPROXY_OPTS', which configures the extra options / arguments
needed by the newer version of snf-vncauthproxy. Support for older versions
of snf-vncauthproxy has been dropped. See also the upgrade notes for Synnefo
and snf-vncauthproxy-1.5.
Pithos
------
......@@ -342,6 +350,7 @@ Cyclades
of the pool of Pithos backends that are used by plankton.
.. _Changelog-0.14:
v0.14
......
......@@ -161,6 +161,14 @@ For Pithos service we have to change the ``20-snf-pithos-app-settings.conf``
file in the same way as above.
v0.15 has also introduced the ``CYCLADES_STATS_SECRET_KEY`` and
``STATS_SECRET_KEY`` settings. ``CYCLADES_STATS_SECRET_KEY`` in
``20-snf-cyclades-app-api.conf`` is used by Cyclades to encrypt the instance id
/ hostname in the URLs serving the VM stats. You should set it to a random
value / string and make sure that it's the same as the ``STATS_SECRET_KEY``
setting (used to decrypt the instance hostname) in
``20-snf-stats-settings.conf`` on your Stats host.
3. Create floating IP pools
===========================
......
......@@ -85,13 +85,17 @@
#BACKEND_PER_USER = {}
#
#
## Encryption key for the instance hostname in the stat graphs URLs. Set it to
## a random string and update the STATS_SECRET_KEY setting in the snf-stats-app
## host (20-snf-stats-app-settings.conf) accordingly.
#CYCLADES_STATS_SECRET_KEY = "secret key"
#
## URL templates for the stat graphs.
## The API implementation replaces '%s' with the encrypted backend id.
## FIXME: For now we do not encrypt the backend id.
#CPU_BAR_GRAPH_URL = 'http://stats.synnefo.org/%s/cpu-bar.png'
#CPU_TIMESERIES_GRAPH_URL = 'http://stats.synnefo.org/%s/cpu-ts.png'
#NET_BAR_GRAPH_URL = 'http://stats.synnefo.org/%s/net-bar.png'
#NET_TIMESERIES_GRAPH_URL = 'http://stats.synnefo.org/%s/net-ts.png'
#CPU_BAR_GRAPH_URL = 'http://stats.example.synnefo.org/stats/v1.0/cpu-bar/%s'
#CPU_TIMESERIES_GRAPH_URL = 'http://stats.example.synnefo.org/stats/v1.0/cpu-ts/%s'
#NET_BAR_GRAPH_URL = 'http://stats.example.synnefo.org/net-bar/stats/v1.0/%s'
#NET_TIMESERIES_GRAPH_URL = 'http://stats.example.synnefo.org/stats/v1.0/net-ts/%s'
#
## Recommended refresh period for server stats
#STATS_REFRESH_PERIOD = 60
......
......@@ -687,8 +687,7 @@ def server_stats(request, server_id):
log.debug('server_stats %s', server_id)
vm = util.get_vm(server_id, request.user_uniq)
#secret = util.encrypt(vm.backend_vm_id)
secret = vm.backend_vm_id # XXX disable backend id encryption
secret = util.stats_encrypt(vm.backend_vm_id)
stats = {
'serverRef': vm.id,
......
......@@ -31,7 +31,8 @@
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from base64 import b64encode, b64decode
from base64 import urlsafe_b64encode, b64decode
from urllib import quote
from hashlib import sha256
from logging import getLogger
from random import choice
......@@ -118,13 +119,13 @@ def zeropad(s):
return s + '\x00' * npad
def encrypt(plaintext):
def stats_encrypt(plaintext):
# Make sure key is 32 bytes long
key = sha256(settings.SECRET_KEY).digest()
key = sha256(settings.CYCLADES_STATS_SECRET_KEY).digest()
aes = AES.new(key)
enc = aes.encrypt(zeropad(plaintext))
return b64encode(enc)
return quote(urlsafe_b64encode(enc))
def get_vm(server_id, user_id, for_update=False, non_deleted=False,
......
......@@ -84,13 +84,17 @@ DEFAULT_FIREWALL_PROFILE = 'DISABLED'
BACKEND_PER_USER = {}
# Encryption key for the instance hostname in the stat graphs URLs. Set it to
# a random string and update the STATS_SECRET_KEY setting in the snf-stats-app
# host (20-snf-stats-app-settings.conf) accordingly.
CYCLADES_STATS_SECRET_KEY = "secret_key"
# URL templates for the stat graphs.
# The API implementation replaces '%s' with the encrypted backend id.
# FIXME: For now we do not encrypt the backend id.
CPU_BAR_GRAPH_URL = 'http://stats.synnefo.org/%s/cpu-bar.png'
CPU_TIMESERIES_GRAPH_URL = 'http://stats.synnefo.org/%s/cpu-ts.png'
NET_BAR_GRAPH_URL = 'http://stats.synnefo.org/%s/net-bar.png'
NET_TIMESERIES_GRAPH_URL = 'http://stats.synnefo.org/%s/net-ts.png'
CPU_BAR_GRAPH_URL = 'http://stats.example.synnefo.org/stats/v1.0/cpu-bar/%s'
CPU_TIMESERIES_GRAPH_URL = 'http://stats.example.synnefo.org/stats/v1.0/cpu-ts/%s'
NET_BAR_GRAPH_URL = 'http://stats.example.synnefo.org/stats/v1.0/net-bar/%s'
NET_TIMESERIES_GRAPH_URL = 'http://stats.example.synnefo.org/stats/v1.0/net-ts/%s'
# Recommended refresh period for server stats
STATS_REFRESH_PERIOD = 60
......
......@@ -2,7 +2,12 @@
##
## Top-level URL for deployment.
#STATS_BASE_URL = "https://host:port/stats"
#
## This key is used to decrypt the instance id / hostname in tha stats graph
## URL. It should be set to the same value that is used by Cyclades to encrypt
## the hostname (CYCLADES_STATS_SECRET_KEY).
#STATS_SECRET_KEY = "secret key"
## Image properties
#IMAGE_WIDTH = 210
#WIDTH = 68
......
......@@ -59,6 +59,7 @@ INSTALL_REQUIRES = [
'py-rrdtool',
'Django>=1.4, <1.5',
'snf-django-lib',
'pycrypto>=2.1.0',
]
setup(
......
......@@ -43,6 +43,10 @@ from cStringIO import StringIO
import rrdtool
from Crypto.Cipher import AES
from base64 import urlsafe_b64decode
from hashlib import sha256
from synnefo_stats import settings
from synnefo.util.text import uenc
......@@ -196,10 +200,8 @@ def draw_net_ts(fname, outfname):
outfname += "-net.png"
rrdtool.graph(outfname, "-s", "-1d", "-e", "-20s",
#"-t", "Network traffic",
"--units", "si",
"-v", "Bits/s",
#"--lazy",
"COMMENT:\t\t\tAverage network traffic\\n",
"DEF:rx=%s:rx:AVERAGE" % fname,
"DEF:tx=%s:tx:AVERAGE" % fname,
......@@ -218,10 +220,8 @@ def draw_net_ts_w(fname, outfname):
outfname += "-net-weekly.png"
rrdtool.graph(outfname, "-s", "-1w", "-e", "-20s",
#"-t", "Network traffic",
"--units", "si",
"-v", "Bits/s",
#"--lazy",
"COMMENT:\t\t\tAverage network traffic\\n",
"DEF:rx=%s:rx:AVERAGE" % fname,
"DEF:tx=%s:tx:AVERAGE" % fname,
......@@ -235,6 +235,14 @@ def draw_net_ts_w(fname, outfname):
return read_file(outfname)
def decrypt(secret):
# Make sure key is 32 bytes long
key = sha256(settings.STATS_SECRET_KEY).digest()
aes = AES.new(key)
return aes.decrypt(urlsafe_b64decode(secret)).rstrip('\x00')
available_graph_types = {
'cpu-bar': draw_cpu_bar,
'net-bar': draw_net_bar,
......@@ -248,6 +256,7 @@ available_graph_types = {
@api_method(http_method='GET', token_required=False, user_required=False,
format_allowed=False, logger=log)
def grapher(request, graph_type, hostname):
hostname = decrypt(uenc(hostname))
fname = uenc(os.path.join(settings.RRD_PREFIX, hostname))
if not os.path.isdir(fname):
raise faults.ItemNotFound('No such instance')
......
## -*- coding: utf-8 -*-
from django.conf import settings
STATS_SECRET_KEY = getattr(settings, 'STATS_SECRET_KEY', "secret key")
# Image properties
IMAGE_WIDTH = getattr(settings, 'IMAGE_WIDTH', 210)
WIDTH = getattr(settings, 'WIDTH', 68)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment