修改虚拟机镜像的root密码,虚拟机镜像root


      有时从网上下载的虚拟机镜像,没有root密码,必须通过秘钥登录,然后秘钥又需要麻烦的注入到里面去。想用,却无法登录,很头痛。本文提供一种通过修改虚拟机镜像里面的/etc/shadow文件,来设置镜像的root密码,当然也可以修改其它用户的密码。

      本文使用python-guestfs类库来操作虚拟机镜像,所以请安装python-guestfs及相关包。ubuntu系统执行:

sudo apt-get install python-guestfs 
      centos系统请执行:

sudo yum install python-libguestfs 

      给指定密码生成加密过后的密码:

def encrypt_passwd(admin_passwd):                                             
    algos = {'SHA-512': '$6$', 'SHA-256': '$5$', 'MD5': '$1$', 'DES': ''}          
    salt_set = ('abcdefghijklmnopqrstuvwxyz'                                    
                'ABCDEFGHIJKLMNOPQRSTUVWXYZ'                                    
                '0123456789./')                                                 
    salt = 16 * ' '                                                             
    salt = ''.join([random.choice(salt_set) for c in salt]) 
                                                                                                                   
    encrypted_passwd = crypt.crypt(admin_passwd, algos['MD5'] + salt)           
    if len(encrypted_passwd) == 13:                                             
        encrypted_passwd = crypt.crypt(admin_passwd, algos['DES'] + salt)          
                                                                                
    return encrypted_passwd
     使用guestfs将生成后的加密密码放到虚拟机镜像里面的/etc/shadow文件中:

image_file = "ubuntu.qcow2"
image_format = "qcow2"
password = "123456"
shadow_path = "/etc/shadow"

#调用encrypt_passwd()使用md5算法对密码进行加密,并返回加密后的密码
encrypted_passwd = encrypt_passwd(password)
#初始化一个GuestFS实例,用于后面对虚拟机镜像的操作
handle = guestfs.GuestFS(python_return_dict=False, close_on_exit=False)
#将虚拟机镜像文件及格式添加到handle中,用于后面操作         
handle.add_drive_opts(image_file, format=image_format)                         
handle.launch()                                   
#遍历虚拟机镜像中的系统分区,并返回。一般为[/dev/sda1]或[/dev/sda],使用该方法的一个好处是,你可以不指定甚至不用指定系统分区,guestfs就把活给干了
roots = handle.inspect_os()                                                     
#遍历系统分区中的挂载点,返回值一般为[['/','/etc/sda1']]
mounts = handle.inspect_get_mountpoints(root)                                   
mounts.sort(key=lambda mount: mount[0])                                         
                                                                                
for mount in mounts:                              
    #挂载系统分区,将‘/etc/sda1’挂载到‘/’,然后就可以通过handle访问sda1上的文件了                              
    handle.mount_options("", mount[1], mount[0])

#读取‘/etc/shadow'文件内容
shadow_data = handle.read_file(shadow_path)                           
           
s_file = shadow_data.split("\n")                                            
                                                                                
new_s_file = []                                                             
for entry in s_file:                                                        
split_entry = entry.split(":")                                          
if split_entry[0] == "root":
    #将root对应的行的密码设为加密密码                                            
    split_entry[1] = encrypted_passwd(password)                         
                                                                             
    new_s_file.append(':'.join(split_entry))                                
                                                                                
new_shadow_data = '\n'.join(new_s_file)
#写入修改过后的‘/etc/shadow’文件                                                                     
handle.write(path, new_shadow_data)
handle.shutdown()
handle.close()

      写了两个脚本,可用于修改虚拟机镜像文件的密码,使用较为方便,如有需要,请查看https://github.com/xuriwuyun/change-root-passwd。执行:

sudo bash changerootpasswd.sh ubuntu.qcow2 123456
     即可将ubuntu.qcow2镜像的root登录密码设定为123456.该脚本可支持多种镜像格式,经过验证的有raw\qcow2。



参考文献

1 http://libguestfs.org/guestfs-python.3.html

2 http://libguestfs.org/guestfs.3.html

相关内容