I am using Amazon web services for a while now. And using it allowed me to have hands dirty on various services. In AWS AMI’s(Amazon Machine Image) provides the information like operating system, application server, and applications to launch into the virtual server(or can be called as an instance) in the cloud. There are lots of options for selecting AMIs provided by AWS or by the community. You can choose the preferred AMI that can meet your requirements. You can customize the instance that you have launched from the AMIs provided by AWS and can create your own AMI from that.All the AMIs created by you are private by default.
Interestingly the instances launched with Public AMIs in AWS comes with default user-name and no password authenticated which sometimes I don’t like. For example, Instances launched with Amazon Linux will have default user-name ec2-user and for Ubuntu instance default user-name is Ubuntu.
Instance launched with Public AMIs also does not allow you change the hostname on flight using user-data. Hostname for any instance launched with Public AMI looks something like
ip-<Private-IPv4>
Example: ip-172-1-20-201
So I have decided to create an AMI which will have default user as Naveen and password as *****. And I would like to have my instance named as myhostname.com i.e hostname. I will use a cloud config script to do that.
cloud-init is a multi-distribution package that handles early initialization of cloud instances.More information can be found at Cloud-Init. Some of the tasks performed by cloud-init are
- Set hostname
- Set the default Locale (default user)
- Generate host private ssh keys
- Parse and handle user-data
Custom AMI
For creating my Custom AMI with above-mentioned changes I have followed the below steps:
1. I have launched a t2.micro instance with Amazon Linux AMI ‘ami-4fffc834’. You can launch the instance using AWS management console or be using AWS command line(aws-cli). I have used the aws-cli to launch the instance.
aws ec2 run-instances --image-id ami-4fffc834 --count 1 --instance-type t2.micro --key-name Naveen
The above command will launch one t2.micro instance with the key name ‘Naveen’.
2. As I have launched the instance using Amazon Linux, the default user-name is ec2-user. Amazon Linux does setting default user using cloud-init. The configuration file for setting default user can be found in /etc/cloud/cloud.cfg.d/00_default.cfg. The config file looks something like below
system_info: # This will affect which distro class gets used distro: amazon distro_short: amzn # Default user name + that default users groups (if added/used) default_user: name: ec2-user lock_passwd: true gecos: EC2 Default User groups: [ wheel ] sudo: [ "ALL=(ALL) NOPASSWD:ALL" ] shell: /bin/bash # Other config here will be given to the distro class and/or path classes paths: cloud_dir: /var/lib/cloud/ templates_dir: /etc/cloud/templates/ upstart_dir: /etc/init/ package_mirrors: - arches: [ i386, x86_64 ] search: regional: - repo.%(ec2_region)s.%(services_domain)s - repo.%(ec2_region)s.amazonaws.com ssh_svcname: sshd
The 00_default.cfg contains other things as well but I have posted only the one which needed to be changed. As we can see the default username for this distro is ec2-user. lock_passwd: true means the user who is trying to log in with the username ec2-user is not allowed to authenticate using a password.
3. I have changed the user-name to Naveen and lock_passwd: false in the config file. But this config file does not allow entering the normal password as part of the config file. You need to give the password for the user in the hash. So to do that I have used the following commands in Ubuntu machine
# mkpasswd comes with whois package
sudo ap-get install whois
#To Generate hash using mkpasswd mkpasswd –method=SHA-512 #This will prompt to enter password #After entering password, mkpasswd will generate hash and output on console Ex: $6$G0Vu5qLWx4cZSHBx$0VYLSoIQxpLKVhlU.oBJdVSW7Ellswerdf.r/ZqWRuijiyTjPAXJzeGwYe1D/f94tt/tf
Copy the above-generated hash and add it to ‘passwd’ key in the above config file. After making final changes in the config file
system_info: # This will affect which distro class gets used distro: amazon distro_short: amzn # Default user name + that default users groups (if added/used) default_user: name: Naveen lock_passwd: false passwd: $6$G0Vu5qLWx4cZSHBx$0VYLSoIQxpLKVhlU.oBJdVSW7Elwerfwq.r/ZqWRuijiyTjPAXJzeGwYe1D/f94tt/tf1lXQYJtMtQLpvAqE1 gecos: Modified Default User name groups: [ wheel ] sudo: [ “ALL=(ALL:ALL) ALL” ] shell: /bin/bash # Other config here will be given to the distro class and/or path classes paths: cloud_dir: /var/lib/cloud/ templates_dir: /etc/cloud/templates/ upstart_dir: /etc/init/ package_mirrors: – arches: [ i386, x86_64 ] search: regional: – repo.%(ec2_region)s.%(services_domain)s – repo.%(ec2_region)s.amazonaws.com ssh_svcname: sshd
4. Finally, i have made the following changes in rc.local which will change the behavior of ssh service to accept password authentication. And change the preserve_hostname to false in /etc/cloud.cfg
if grep -Fxq “PasswordAuthentication no” /etc/ssh/sshd_config then sed -i ‘s/^PasswordAuthentication.*/PasswordAuthentication yes/’ /etc/ssh/sshd_config /etc/init.d/sshd restart fi
With these changes above I have achieved adding default user-name with Naveen and with the default password. With changes above to the instance above I have created an AMI from the instance using aws-cli
aws ec2 create-image --instance-id i-09ebf4e320b0cadca --name "ONE_AMI"
Output:
{
"ImageId": "ami-ebec0c91"
}
#Cloud-config for setting hostname
With the Customized i can launch the instance with user-name Naveen but still, the hostname will be in the format like IP-<Private-IPv4>. So I have used the below cloud-config script to change the hostname.
#cloud-config
#set the hostmachine name
fqdn: myhostname.com
#Add additional users for the machine
users:
- name: sysadmin
groups: [root,wheel]
passwd: $6$G0Vu5qLWx4cZSHBx$0VYLSoIQxpLKVhlU.oBJdVSW7EllsvFybq.r/ZqWRuijiyTjPAXJzeGwYe1D/f94tt/tf1lXQYJtMtQLpvAqE1
sudo: ALL=(ALL:ALL) ALL
#Final Message
final_message: "The system is finally up xcvxxxxxxxxxxxccccccccccccccccccccccc, after $UPTIME seconds"
The above script will create the instance with hostname myhostname.com and create a user sysadmin. The above script will be passed as part of user-data when launching an instance
aws ec2 run-instance --image-id ami-4240a138 --count 1 --intance-type t2.micro --user-data file://cloud.cfg
The above launch an instance without Key pair which means I can only log into the instance using the default user Naveen or using a username we have created in cloud configuration script that was passed a user-data.
Finally with this i have the instance with my custom default user-name and password, and a hostname with myhostname.com.