Dear guys
I encountered a problem that a ssh public key of ssh_keypairs for a
newly created instance is overridden by another ssh key in template
meta data. I think this leads to security vulnerability because a
template owner can login to other user's instance created from the
template. So, could you fix this issue?
This behavior is caused by meta data import at commitUserVm method. A
ssh key value specified by an instance owner is set to a UserVmVO
object at line 2986-2988 of
server/src/com/cloud/vm/UserVmManagerImpl.java in 4.3 branch [1], but
this value is overridden at line 3035-3038 by template meta data.
Please note a database contains meta data entries related to a
template which you created from an instance in cloud.template_view
like [2]. 2nd row has detail_name and detail_value about ssh key and
CloudStack override the user specified ssh key value by the owner's
detail value in this situation. It results in delivery of the template
owner's ssh key for the instance created from the template to virtual
router inspite of specification of instance owner's ssh key.
You can reproduce this phenomenon like below.
1. Deploy an instance with a ssh key A by specifying 'keypair'
value.
2. Create a template from this instance.
3. Deploy an instance with another ssh key B by specifying
'keypair' value.
[1] server/src/com/cloud/vm/UserVmManagerImpl.java
2971 private UserVmVO commitUserVm(final DataCenter zone, final
VirtualMachineTemplate template, final String hostName, final String
displayName, final Account owner,
2972 final Long diskOfferingId, final Long diskSize, final
String userData, final HypervisorType hypervisor, final Account
caller, final Boolean isDisplayVmEnabled,
2973 final String keyboard, final long accountId, final
ServiceOfferingVO offering, final boolean isIso, final String
sshPublicKey,
2974 final LinkedHashMap<String, NicProfile> networkNicMap,
final long id, final String instanceName, final String uuidName, final
HypervisorType hypervisorType,
2975 final Map<String, String> customParameters) throws
InsufficientCapacityException {
2976 return Transaction.execute(new
TransactionCallbackWithException<UserVmVO,
InsufficientCapacityException>() {
2977 @Override
2978 public UserVmVO doInTransaction(TransactionStatus
status) throws InsufficientCapacityException {
2979 UserVmVO vm = new UserVmVO(id, instanceName,
displayName,
2980 template.getId(), hypervisorType,
template.getGuestOSId(),
2981 offering.getOfferHA(),
offering.getLimitCpuUse(),
2982 owner.getDomainId(), owner.getId(),
offering.getId(), userData,
2983 hostName, diskOfferingId);
2984 vm.setUuid(uuidName);
2985
vm.setDynamicallyScalable(template.isDynamicallyScalable());
2986 if (sshPublicKey != null) {
2987 vm.setDetail("SSH.PublicKey", sshPublicKey);
2988 }
2989
2990 if (keyboard != null && !keyboard.isEmpty())
2991 vm.setDetail(VmDetailConstants.KEYBOARD, keyboard);
2992
2993 if (isIso) {
2994 vm.setIsoId(template.getId());
2995 }
2996
2997 if(isDisplayVmEnabled != null){
2998 if(!_accountMgr.isRootAdmin(caller.getType())){
2999 throw new PermissionDeniedException(
"Cannot update parameter displayvm, only admin permitted ");
3000 }
3001 vm.setDisplayVm(isDisplayVmEnabled);
3002 }else {
3003 vm.setDisplayVm(true);
3004 }
3005
3006 // If hypervisor is vSphere, check for clone
type setting.
3007 if (hypervisorType.equals(HypervisorType.VMware)) {
3008 // retrieve clone flag.
3009 UserVmCloneType cloneType = UserVmCloneType.linked;
3010 String value =
_configDao.getValue(Config.VmwareCreateFullClone.key());
3011 if (value != null) {
3012 if (Boolean.parseBoolean(value) == true)
3013 cloneType = UserVmCloneType.full;
3014 }
3015 UserVmCloneSettingVO vmCloneSettingVO =
new UserVmCloneSettingVO(id, cloneType.toString());
3016 _vmCloneSettingDao.persist(vmCloneSettingVO);
3017 }
3018
3019 long guestOSId = template.getGuestOSId();
3020 GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
3021 long guestOSCategoryId = guestOS.getCategoryId();
3022 GuestOSCategoryVO guestOSCategory =
_guestOSCategoryDao.findById(guestOSCategoryId);
3023
3024
3025 // If hypervisor is vSphere and OS is OS X,
set special settings.
3026 if (hypervisorType.equals(HypervisorType.VMware)) {
3027 if
(guestOS.getDisplayName().toLowerCase().contains("apple mac os")){
3028 vm.setDetail("smc.present", "TRUE");
3029
vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, "scsi");
3030 vm.setDetail("firmware", "efi");
3031 s_logger.info("guestOS is OSX :
overwrite root disk controller to scsi, use smc and efi");
3032 }
3033 }
3034
3035 Map<String, String> details = template.getDetails();
3036 if ( details != null && !details.isEmpty() ) {
3037 vm.details.putAll(details);
3038 }
3039
3040 _vmDao.persist(vm);
3041 if (customParameters != null &&
customParameters.size() > 0) {
3042 for (String key : customParameters.keySet()) {
3043 vm.setDetail(key, customParameters.get(key));
3044 }
3045 }
3046 _vmDao.saveDetails(vm);
[2] database example
mysql> select * from cloud.template_view where id=207 \G;
*************************** 1. row ***************************
id: 207
uuid: c96f0d9a-0a56-4d30-af73-fe8b31ae37c3
unique_name: 2219faa5a-4e7b-3425-b6e6-135ab210422b
name: cluster_frontend-20140520.2
public: 1
featured: 0
type: USER
hvm: 1
bits: 64
url: NULL
format: QCOW2
created: 2014-05-20 09:33:47
checksum: NULL
display_text: Cluster Frontend VM CentOS 6.5 ver.20140520.2
enable_password: 1
dynamically_scalable: 0
template_state: Active
guest_os_id: 182
guest_os_uuid: 9d3c42d8-caab-11e3-9125-001e679910a0
guest_os_name: CentOS 6.4 (64-bit)
bootable: 1
prepopulate: 0
cross_zones: 0
hypervisor_type: KVM
extractable: 0
template_tag: NULL
sort_key: 0
removed: NULL
enable_sshkey: 0
source_template_id: 205
source_template_uuid: c131680c-3e0e-4d7c-b554-02dabc10ade1
account_id: 3
account_uuid: f9e4e1ca-69fd-4ae3-b70c-15bbcc13406e
account_name: sgcadm
account_type: 0
domain_id: 2
domain_uuid: 84dd635d-fb99-4895-b199-7d777aa144d5
domain_name: default
domain_path: /default/
project_id: NULL
project_uuid: NULL
project_name: NULL
data_center_id: NULL
data_center_uuid: NULL
data_center_name: NULL
lp_account_id: NULL
store_id: 3
store_scope: REGION
state: Ready
download_state: DOWNLOADED
download_pct: 100
error_str: NULL
size: 18465816576
destroyed: 0
created_on_store: 2014-05-20 09:33:47
detail_name: Message.ReservedCapacityFreed.Flag
detail_value: false
tag_id: NULL
tag_uuid: NULL
tag_key: NULL
tag_value: NULL
tag_domain_id: NULL
tag_account_id: NULL
tag_resource_id: NULL
tag_resource_uuid: NULL
tag_resource_type: NULL
tag_customer: NULL
temp_zone_pair: 207_0
*************************** 2. row ***************************
id: 207
uuid: c96f0d9a-0a56-4d30-af73-fe8b31ae37c3
unique_name: 2219faa5a-4e7b-3425-b6e6-135ab210422b
name: cluster_frontend-20140520.2
public: 1
featured: 0
type: USER
hvm: 1
bits: 64
url: NULL
format: QCOW2
created: 2014-05-20 09:33:47
checksum: NULL
display_text: Cluster Frontend VM CentOS 6.5 ver.20140520.2
enable_password: 1
dynamically_scalable: 0
template_state: Active
guest_os_id: 182
guest_os_uuid: 9d3c42d8-caab-11e3-9125-001e679910a0
guest_os_name: CentOS 6.4 (64-bit)
bootable: 1
prepopulate: 0
cross_zones: 0
hypervisor_type: KVM
extractable: 0
template_tag: NULL
sort_key: 0
removed: NULL
enable_sshkey: 0
source_template_id: 205
source_template_uuid: c131680c-3e0e-4d7c-b554-02dabc10ade1
account_id: 3
account_uuid: f9e4e1ca-69fd-4ae3-b70c-15bbcc13406e
account_name: sgcadm
account_type: 0
domain_id: 2
domain_uuid: 84dd635d-fb99-4895-b199-7d777aa144d5
domain_name: default
domain_path: /default/
project_id: NULL
project_uuid: NULL
project_name: NULL
data_center_id: NULL
data_center_uuid: NULL
data_center_name: NULL
lp_account_id: NULL
store_id: 3
store_scope: REGION
state: Ready
download_state: DOWNLOADED
download_pct: 100
error_str: NULL
size: 18465816576
destroyed: 0
created_on_store: 2014-05-20 09:33:47
detail_name: SSH.PublicKey
detail_value: ssh-rsa ...(snip)
tag_id: NULL
tag_uuid: NULL
tag_key: NULL
tag_value: NULL
tag_domain_id: NULL
tag_account_id: NULL
tag_resource_id: NULL
tag_resource_uuid: NULL
tag_resource_type: NULL
tag_customer: NULL
temp_zone_pair: 207_0
*************************** 3. row ***************************
id: 207
uuid: c96f0d9a-0a56-4d30-af73-fe8b31ae37c3
unique_name: 2219faa5a-4e7b-3425-b6e6-135ab210422b
name: cluster_frontend-20140520.2
public: 1
featured: 0
type: USER
hvm: 1
bits: 64
url: NULL
format: QCOW2
created: 2014-05-20 09:33:47
checksum: NULL
display_text: Cluster Frontend VM CentOS 6.5 ver.20140520.2
enable_password: 1
dynamically_scalable: 0
template_state: Active
guest_os_id: 182
guest_os_uuid: 9d3c42d8-caab-11e3-9125-001e679910a0
guest_os_name: CentOS 6.4 (64-bit)
bootable: 1
prepopulate: 0
cross_zones: 0
hypervisor_type: KVM
extractable: 0
template_tag: NULL
sort_key: 0
removed: NULL
enable_sshkey: 0
source_template_id: 205
source_template_uuid: c131680c-3e0e-4d7c-b554-02dabc10ade1
account_id: 3
account_uuid: f9e4e1ca-69fd-4ae3-b70c-15bbcc13406e
account_name: sgcadm
account_type: 0
domain_id: 2
domain_uuid: 84dd635d-fb99-4895-b199-7d777aa144d5
domain_name: default
domain_path: /default/
project_id: NULL
project_uuid: NULL
project_name: NULL
data_center_id: NULL
data_center_uuid: NULL
data_center_name: NULL
lp_account_id: NULL
store_id: 3
store_scope: REGION
state: Ready
download_state: DOWNLOADED
download_pct: 100
error_str: NULL
size: 18465816576
destroyed: 0
created_on_store: 2014-05-20 09:33:47
detail_name: Encrypted.Password
detail_value: ...(snip)
tag_id: NULL
tag_uuid: NULL
tag_key: NULL
tag_value: NULL
tag_domain_id: NULL
tag_account_id: NULL
tag_resource_id: NULL
tag_resource_uuid: NULL
tag_resource_type: NULL
tag_customer: NULL
temp_zone_pair: 207_0
3 rows in set (0.00 sec)
ERROR:
No query specified
mysql>
Best Regards
--
Hiroki Ohashi