Hi Hiroki, We should not override the ssh key pair provided in the deployVM API with the ssh key in template metadata. I just able to reproduce this. Please create a ticket for this issue.
Thanks Harikrishna On 06-Jun-2014, at 5:18 pm, Hiroki Ohashi <hiroki.s...@gmail.com> wrote: > 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