Remove appliance's hard-coded password in favor of ssh pub key

This removes the hard-coded password from the appliance VM's user-data
and replaces it with a SSH public key, which is read from a file whos
path is configured in rug.ini.

It also disables password logins for the user.  Another patch to
akanda-appliance-builder will allow developers to include a specified
debug user to allow debugging in dev environments.

Change-Id: I7db92bc7fd3743d89d73ab2a0b8da14685c30c69
This commit is contained in:
Adam Gandelman 2015-05-22 15:27:18 -07:00
parent 55666d9f15
commit a06dbe7ab3
5 changed files with 112 additions and 8 deletions

View File

@ -19,9 +19,19 @@ import logging
from novaclient.v1_1 import client
from oslo.config import cfg
LOG = logging.getLogger(__name__)
OPTIONS = [
cfg.StrOpt(
'router_ssh_public_key',
help="Path to the SSH public key for the 'akanda' user within "
"router appliance VMs",
default='/etc/akanda-rug/akanda.pub')
]
cfg.CONF.register_opts(OPTIONS)
class InstanceInfo(object):
def __init__(self, instance_id, name, management_port=None, ports=(),
@ -181,7 +191,7 @@ debug:
- verbose: true
bootcmd:
- /usr/local/bin/akanda-configure-management %s %s/64
- /usr/local/bin/akanda-configure-management %(mac_address)s %(ip_address)s/64
users:
- name: akanda
@ -189,12 +199,30 @@ users:
groups: users
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
passwd: $6$rounds=4096$zxaBh6omTayBSA$rI1.FNliuUl7R2SMdkj7zWv.FBhqGVd1lLYDatJd6MiE9WqEQx0M.o7bLyp5nA0CxV6ahoDb0m8Y5OQMDHx1V/
lock-passwd: false
lock-passwd: true
ssh-authorized-keys:
- %(ssh_public_key)s
final_message: "Akanda appliance is running"
""" # noqa
def _router_ssh_key():
key = cfg.CONF.router_ssh_public_key
if not key:
return ''
try:
with open(key) as out:
return out.read()
except IOError:
LOG.warning('Could not load router ssh public key from %s' % key)
return ''
def _format_userdata(mgt_port):
return TEMPLATE % (mgt_port.mac_address, mgt_port.fixed_ips[0].ip_address)
ctxt = {
'ssh_public_key': _router_ssh_key(),
'mac_address': mgt_port.mac_address,
'ip_address': mgt_port.fixed_ips[0].ip_address,
}
return TEMPLATE % ctxt

View File

@ -18,7 +18,7 @@
import datetime
import mock
import unittest2 as unittest
from six.moves import builtins as __builtins__
from akanda.rug.api import nova
@ -65,6 +65,40 @@ class FakeConf:
router_instance_flavor = 1
EXPECTED_USERDATA = """
#cloud-config
cloud_config_modules:
- emit_upstart
- set_hostname
- locale
- set-passwords
- timezone
- disable-ec2-metadata
- runcmd
output: {all: '| tee -a /var/log/cloud-init-output.log'}
debug:
- verbose: true
bootcmd:
- /usr/local/bin/akanda-configure-management aa:aa:aa:aa:aa:aa 192.168.1.1/64
users:
- name: akanda
gecos: Akanda
groups: users
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
lock-passwd: true
ssh-authorized-keys:
- fake_key
final_message: "Akanda appliance is running"
"""
def fake_make_ports_callback():
return (fake_mgt_port, [fake_ext_port, fake_int_port])
@ -149,3 +183,26 @@ class TestNovaWrapper(unittest.TestCase):
def test_destroy_router_instance(self):
self.nova.destroy_instance(self.INSTANCE_INFO)
self.client.servers.delete.assert_called_with(self.INSTANCE_INFO.id_)
@mock.patch.object(nova, '_router_ssh_key')
def test_format_userdata(self, fake_ssh_key):
fake_ssh_key.return_value = 'fake_key'
result = nova._format_userdata(fake_int_port)
self.assertEqual(result.strip(), EXPECTED_USERDATA.strip())
@mock.patch.object(__builtins__, 'open', autospec=True)
def test_router_ssh_key(self, fake_open):
mock_key_file = mock.MagicMock(spec=file)
mock_key_file.read.return_value = 'fake-key'
mock_key_file.__enter__.return_value = mock_key_file
fake_open.return_value = mock_key_file
result = nova._router_ssh_key()
self.assertEqual(result, 'fake-key')
@mock.patch.object(nova, 'LOG', autospec=True)
@mock.patch.object(__builtins__, 'open', autospec=True)
def test_router_ssh_key_not_found(self, fake_open, fake_log):
fake_open.side_effect = IOError
result = nova._router_ssh_key()
self.assertEqual(result, '')
self.assertTrue(fake_log.warning.called)

View File

@ -32,6 +32,10 @@ AKANDA_RUG_MANAGEMENT_PORT=${AKANDA_RUG_MANAGEMENT_PORT:-5000}
HORIZON_LOCAL_SETTINGS=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
# Path to public ssh key that will be added to the 'akanda' users authorized_keys
# within the appliance VM.
AKANDA_APPLIANCE_SSH_PUBLIC_KEY=${AKANDA_APPLIANCE_SSH_PUBLIC_KEY:-/home/$STACK_USER/.ssh/id_rsa.pub}
function configure_akanda() {
if [[ ! -d $AKANDA_CONF_DIR ]]; then
sudo mkdir -p $AKANDA_CONF_DIR
@ -59,6 +63,8 @@ function configure_akanda() {
if [[ "$Q_AGENT" == "linuxbridge" ]]; then
iniset $AKANDA_RUG_CONF DEFAULT interface_driver "akanda.rug.common.linux.interface.BridgeInterfaceDriver"
fi
iniset $AKANDA_RUG_CONF DEFAULT router_ssh_public_key $AKANDA_APPLIANCE_SSH_PUBLIC_KEY
}
function configure_akanda_nova() {
@ -172,9 +178,11 @@ function pre_start_akanda() {
# Point DIB at the devstack checkout of the akanda-appliance repo
DIB_REPOLOCATION_akanda=$AKANDA_APPLIANCE_DIR \
DIB_REPOREF_akanda="$(cd $AKANDA_APPLIANCE_DIR && git rev-parse HEAD)" \
DIB_AKANDA_APPLIANCE_DEBUG_USER=$ADMIN_USERNAME \
DIB_AKANDA_APPLIANCE_DEBUG_PASSWORD=$ADMIN_PASSWORD \
http_proxy=$AKANDA_DEV_APPLIANCE_BUILD_PROXY \
ELEMENTS_PATH=$AKANDA_APPLIANCE_BUILDER_DIR/diskimage-builder/elements \
DIB_RELEASE=wheezy DIB_EXTLINUX=1 disk-image-create debian vm akanda \
DIB_RELEASE=wheezy DIB_EXTLINUX=1 disk-image-create debian vm akanda debug-user \
-o $TOP_DIR/files/akanda
akanda_dev_image_src=$AKANDA_DEV_APPLIANCE_FILE
else
@ -250,11 +258,20 @@ function set_demo_tenant_sec_group_dhcp_rules() {
}
function check_prereqs() {
# Fail devstack as early as possible if system does not satisfy some known
# prerequisites
if [ ! -e "$AKANDA_APPLIANCE_SSH_PUBLIC_KEY" ]; then
die $LINENO "Public SSH key not found at $AKANDA_APPLIANCE_SSH_PUBLIC_KEY. Please copy one there or " \
"set AKANDA_APPLIANCE_SSH_PUBLIC_KEY accordingly."
fi
}
if is_service_enabled ak-rug; then
if [[ "$1" == "source" ]]; then
# no-op
:
check_prereqs
elif [[ "$1" == "stack" && "$2" == "install" ]]; then
echo_summary "Installing Akanda"

View File

@ -20,6 +20,7 @@ plug_external_port=True
router_image_uuid=1e9c16f3-e070-47b7-b49c-ffcf38df5f9a
router_instance_flavor=1
router_ssh_public_key=/etc/akanda/akanda.pub
# to plug in rug interface
interface_driver=akanda.rug.common.linux.interface.OVSInterfaceDriver

View File

@ -8,3 +8,4 @@ iso8601
mox==0.5.3
testtools
fixtures
six>=1.9.0