functional cloud-config-ssh.conf now
This fixes LP: #506599 , LP: #507070 . Also, here, we move config parsing out of the EC2Init class. Instead the parsing of /etc/ec2-init/ec2-init.cfg is now done in the CloudConfig class, and prepended to the cloud-config that comes in from user data. This means that values in user data will over-ride the settings in /etc/ec2-init. Still TODO is support reading the public and private key files from the cloud-config
This commit is contained in:
parent
a6b9c37d67
commit
5be0f941fc
@ -28,15 +28,42 @@ class CloudConfig():
|
||||
cfgfile = None
|
||||
handlers = { }
|
||||
cfg = None
|
||||
old_conffile = '/etc/ec2-init/ec2-config.cfg'
|
||||
|
||||
def __init__(self,cfgfile):
|
||||
import pprint; pprint.pprint(self.cfg)
|
||||
self.cfg=read_conf(cfgfile)
|
||||
self.cfg = self.get_config_obj(cfgfile)
|
||||
self.cloud = ec2init.EC2Init()
|
||||
self.cloud.get_data_source()
|
||||
self.add_handler('apt-update-upgrade', self.h_apt_update_upgrade)
|
||||
self.add_handler('config-ssh')
|
||||
|
||||
def get_config_obj(self,cfgfile):
|
||||
str=""
|
||||
# support reading the old ConfigObj format file and turning it
|
||||
# into a yaml string
|
||||
try:
|
||||
f = file(self.old_conffile)
|
||||
str+=file.read().replace('=',': ')
|
||||
f.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
f = file(cfgfile)
|
||||
cfg=yaml.load(str + f.read())
|
||||
f.close()
|
||||
return(cfg)
|
||||
|
||||
def convert_old_config(self):
|
||||
# support reading the old ConfigObj format file and turning it
|
||||
# into a yaml string
|
||||
try:
|
||||
f = file(self.conffile)
|
||||
str=file.read().replace('=',': ')
|
||||
f.close()
|
||||
return str
|
||||
except:
|
||||
return("")
|
||||
|
||||
def add_handler(self, name, handler=None, freq=None):
|
||||
if handler is None:
|
||||
try:
|
||||
@ -124,6 +151,29 @@ class CloudConfig():
|
||||
|
||||
def h_config_ssh(self,name,args):
|
||||
print "Warning, not doing anything for config %s" % name
|
||||
if False:
|
||||
# if there are keys in cloud-config, use them
|
||||
# TODO: need to get keys from cloud-config if present
|
||||
# and replace those in /etc/ssh
|
||||
pass
|
||||
else:
|
||||
# if not, generate them
|
||||
clean_and_gen='rm -f /etc/ssh/ssh_host_*_key*; ' + \
|
||||
'ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N ""; ' + \
|
||||
'ssh-keygen -f /etc/ssh/ssh_host_dsa_key -t rsa -N ""; '
|
||||
subprocess.call(('sh', '-c', clean_and_gen))
|
||||
|
||||
try:
|
||||
user = get_cfg_option_str(self.cfg,'user')
|
||||
disable_root = get_cfg_option_bool(self.cfg, "disable_root", True)
|
||||
keys = self.cloud.get_public_ssh_keys()
|
||||
apply_credentials(keys,user,disable_root)
|
||||
except:
|
||||
warn("applying credentials failed!\n")
|
||||
|
||||
send_ssh_keys_to_console()
|
||||
|
||||
subprocess.call(('restart', 'ssh'))
|
||||
|
||||
def h_ec2_ebs_mounts(self,name,args):
|
||||
print "Warning, not doing anything for config %s" % name
|
||||
@ -136,7 +186,6 @@ class CloudConfig():
|
||||
|
||||
|
||||
def get_cfg_option_bool(yobj, key, default=False):
|
||||
print "searching for %s" % key
|
||||
if not yobj.has_key(key): return default
|
||||
val = yobj[key]
|
||||
if yobj[key] in [ True, '1', 'on', 'yes', 'true']:
|
||||
@ -152,3 +201,53 @@ def read_conf(fname):
|
||||
conf = yaml.load(stream)
|
||||
stream.close()
|
||||
return conf
|
||||
|
||||
def apply_credentials(keys, user, disable_root):
|
||||
if user:
|
||||
setup_user_keys(keys, user, '')
|
||||
|
||||
if disable_root:
|
||||
key_prefix = 'command="echo \'Please login as the %s user rather than root user.\';echo;sleep 10" ' % user
|
||||
else:
|
||||
key_prefix = ''
|
||||
|
||||
setup_user_keys(keys, 'root', key_prefix)
|
||||
|
||||
def setup_user_keys(keys, user, key_prefix):
|
||||
import pwd
|
||||
saved_umask = os.umask(077)
|
||||
|
||||
pwent = pwd.getpwnam(user)
|
||||
|
||||
ssh_dir = '%s/.ssh' % pwent.pw_dir
|
||||
if not os.path.exists(ssh_dir):
|
||||
os.mkdir(ssh_dir)
|
||||
os.chown(ssh_dir, pwent.pw_uid, pwent.pw_gid)
|
||||
|
||||
authorized_keys = '%s/.ssh/authorized_keys' % pwent.pw_dir
|
||||
fp = open(authorized_keys, 'a')
|
||||
fp.write(''.join(['%s%s\n' % (key_prefix, key) for key in keys]))
|
||||
fp.close()
|
||||
|
||||
os.chown(authorized_keys, pwent.pw_uid, pwent.pw_gid)
|
||||
|
||||
os.umask(saved_umask)
|
||||
|
||||
def send_ssh_keys_to_console():
|
||||
send_keys_sh = """
|
||||
{
|
||||
echo
|
||||
echo "#############################################################"
|
||||
echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----"
|
||||
ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
|
||||
ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub
|
||||
echo "-----END SSH HOST KEY FINGERPRINTS-----"
|
||||
echo "#############################################################"
|
||||
} | logger -p user.info -s -t "ec2"
|
||||
"""
|
||||
subprocess.call(('sh', '-c', send_keys_sh))
|
||||
|
||||
|
||||
def warn(str):
|
||||
sys.stderr.write("Warning:%s\n" % str)
|
||||
|
||||
|
@ -43,7 +43,6 @@ import UserDataHandler
|
||||
class EC2Init:
|
||||
datasource_list = [ DataSourceEc2.DataSourceEc2 ]
|
||||
part_handlers = { }
|
||||
conffile = '/etc/ec2-init/ec2-config.cfg'
|
||||
|
||||
def __init__(self):
|
||||
self.part_handlers = {
|
||||
@ -53,8 +52,6 @@ class EC2Init:
|
||||
'text/part-handler' : self.handle_handler
|
||||
}
|
||||
|
||||
self.config = ConfigObj(self.conffile)
|
||||
|
||||
def restore_from_cache(self):
|
||||
try:
|
||||
f=open(data_source_cache, "rb")
|
||||
@ -97,15 +94,6 @@ class EC2Init:
|
||||
write_file(userdata_raw, self.datasource.get_userdata_raw(), 0644)
|
||||
write_file(userdata, self.datasource.get_userdata(), 0644)
|
||||
|
||||
def get_cfg_option_bool(self, key, default=None):
|
||||
val = self.config.get(key, default)
|
||||
if val.lower() in ['1', 'on', 'yes']:
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_cfg_option_str(self, key, default=None):
|
||||
return self.config.get(key, default)
|
||||
|
||||
def initctl_emit(self):
|
||||
subprocess.Popen(['initctl', 'emit', 'cloud-config',
|
||||
'%s=%s' % (cfg_env_name,cloud_config)]).communicate()
|
||||
@ -233,22 +221,6 @@ class EC2Init:
|
||||
def get_hostname(self):
|
||||
return(self.datasource.get_hostname())
|
||||
|
||||
def apply_credentials(self):
|
||||
user = self.get_cfg_option_str('user')
|
||||
disable_root = self.get_cfg_option_bool('disable_root', True)
|
||||
|
||||
keys = self.get_public_ssh_keys()
|
||||
|
||||
if user:
|
||||
setup_user_keys(keys, user, '')
|
||||
|
||||
if disable_root:
|
||||
key_prefix = 'command="echo \'Please login as the ubuntu user rather than root user.\';echo;sleep 10" '
|
||||
else:
|
||||
key_prefix = ''
|
||||
|
||||
setup_user_keys(keys, 'root', key_prefix)
|
||||
|
||||
def enable_swap(self):
|
||||
swaps=[]
|
||||
try:
|
||||
@ -302,22 +274,3 @@ def write_file(file,content,mode=0644):
|
||||
f.close()
|
||||
os.chmod(file,mode)
|
||||
|
||||
def setup_user_keys(keys, user, key_prefix):
|
||||
saved_umask = os.umask(077)
|
||||
|
||||
pwent = pwd.getpwnam(user)
|
||||
|
||||
ssh_dir = '%s/.ssh' % pwent.pw_dir
|
||||
if not os.path.exists(ssh_dir):
|
||||
os.mkdir(ssh_dir)
|
||||
os.chown(ssh_dir, pwent.pw_uid, pwent.pw_gid)
|
||||
|
||||
authorized_keys = '%s/.ssh/authorized_keys' % pwent.pw_dir
|
||||
fp = open(authorized_keys, 'a')
|
||||
fp.write(''.join(['%s%s\n' % (key_prefix, key) for key in keys]))
|
||||
fp.close()
|
||||
|
||||
os.chown(authorized_keys, pwent.pw_uid, pwent.pw_gid)
|
||||
|
||||
os.umask(saved_umask)
|
||||
|
||||
|
@ -4,9 +4,7 @@
|
||||
|
||||
description "Download preconfigured ssh keys"
|
||||
|
||||
start on (cloud-config
|
||||
and local-filesystems
|
||||
and net-device-ifup IFACE=eth0 and starting ssh)
|
||||
start on (cloud-config and local-filesystems)
|
||||
console output
|
||||
task
|
||||
|
Loading…
x
Reference in New Issue
Block a user