zoukankan      html  css  js  c++  java
  • vsftpd 自动安装脚本

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    __author__ = 'cpy'
    
    import os
    import re
    import sys
    import logging
    
    '''
            @desc : install vsftpd software and configure
            @time : 2018-07-02
    '''
    
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    
    class Config(object):
            """VSFTPD BASE CONFIG"""
            VFTP_CONF = '/etc/vsftpd/vsftpd.conf'
            VIR_CONF = '/etc/vsftpd/vconf'
            VUSER = '/etc/vsftpd/vusers'
            PAMFILE = '/etc/pam.d/vsftpd'
            LOGFILE = '/etc/vsftpd/logs'
            SYSUSER = '/etc/passwd'
            DENYUSER = '/etc/vsftpd/user_list'
    
            VCONF_CONTENT_TMP = '''anonymous_enable=NO
            #设成YES,允许匿名用户登陆
            allow_writeable_chroot=YES
            #vsftpd 2.3.5之后增强了安全检查,不允许限定在主目录下的用户具有写权限,该命令声明可以具有写权限。
            local_enable=YES
            #允许/禁止本地用户登陆 注意:主要是为虚拟宿主用户,如果该项目设定为NO那么所有虚拟用户将无法访问。
            write_enable=YES
            #设定可以进行写操作。
            local_umask=022
            #设定上传后文件的权限掩码,文件644,文件夹755
            dirmessage_enable=YES
            #设定开启目录标语功能
            xferlog_enable=YES
            #设定开启日志记录功能。
            connect_from_port_20=YES
            #设定端口20进行数据连接
            xferlog_std_format=YES
            #设定日志使用标准的记录格式
            listen=YES
            #开启独立进程vsftpd,不使用超级进程xinetd。设定该Vsftpd服务工作在StandAlone模式下。
            pam_service_name=vsftpd
            #设定,启用pam认证,并指定认证文件名/etc/pam.d/vsftpd
            userlist_enable=YES
            #设定userlist_file中的用户将不得使用FTP
            tcp_wrappers=YES
            #设定支持TCP Wrappers
            chroot_local_user=YES
            #限制所有用户在主目录
            #以下这些是关于Vsftpd虚拟用户支持的重要配置项目。默认Vsftpd.conf中不包含这些设定项目,需要自己手动添加配置
            guest_enable=YES
            #设定启用虚拟用户功能
            guest_username=www
            #指定虚拟用户的宿主用户
            virtual_use_local_privs=YES
            #设定虚拟用户的权限符合他们的宿主用户 
            user_config_dir=/etc/vsftpd/vconf
            #设定虚拟用户个人Vsftp的配置文件存放路径'''
    
            PAM_CONTENT_TMP = '''auth    sufficient      /lib64/security/pam_userdb.so    db=/etc/vsftpd/virtusers
            account sufficient      /lib64/security/pam_userdb.so    db=/etc/vsftpd/virtusers'''
    
            VUSER_CONF_CONTENT_TMP = '''local_root=/data/www/virtual/
            #指定虚拟用户的具体主路径
            anonymous_enable=NO
            #设定不允许匿名用户访问
            write_enable=YES
            #设定允许写操作
            local_umask=022
            #设定上传文件权限掩码
            anon_upload_enable=NO
            #设定不允许匿名用户上传
            anon_mkdir_write_enable=NO
            #设定不允许匿名用户建立目录
            idle_session_timeout=600
            #设定空闲连接超时时间
            data_connection_timeout=120
            #设定单次连续传输最大时间
            max_clients=10
            #设定并发客户端访问个数
            max_per_ip=5
            #设定单个客户端的最大线程数,这个配置主要来照顾Flashget、迅雷等多线程下载软件
            local_max_rate=50000
            #设定该用户的最大传输速率,单位b/s'''
    
    
    class InitLogging(object):
            """ 初始化日志输出配置 """
    
            def __init__(self):
                    self.LOG = Config.LOGFILE
    
            def logconfig(self):
                    if not os.path.exists(self.LOG):
                            BASE_VSFTP_PATH = os.path.split(self.LOG)[0]
                            os.makedirs(BASE_VSFTP_PATH)
                            f = open(self.LOG, 'w')
                            f.close()
                    logging.basicConfig(level=logging.INFO, filename=self.LOG, filemode='a',
                                        format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
    
    
    class ProgressBar(object):
            def __flush_screen(self, string=''):
                    sys.stdout.write(string)
                    sys.stdout.flush()
    
            def progress(self, tasklist=[], width=100):
                    # 开始执行
                    for taskindex, task in enumerate(tasklist):
                            # 获取每个任务占用的进度条个数
                            scale = int(width / len(tasklist))
                            # 获取每个任务占用任务总数的百分比
                            score = int(100 / len(tasklist))
    
                            if taskindex == 0:
                                    executestring = '
    {0:>2}% [{1}]{2}'.format(0, ' ' * width, os.linesep)
                                    self.__flush_screen(string=executestring)
                            else:
                                    executestring = '
    {0:>2}% [{1}{2}]{3}'.format(taskindex * score, '=' * taskindex * scale,
                                                                                   ' ' * (width - taskindex * scale), os.linesep)
                                    self.__flush_screen(string=executestring)
                            eval(task)
                    # 执行结束
                    endstring = '
    {0:>2}% [{1}] 完成{2}'.format(100, '=' * width, os.linesep)
                    self.__flush_screen(string=endstring)
    
    
    class Install(object):
            """INSTALL VSFTPD AND CONFIGURE"""
    
            def __init__(self):
                    pass
    
            def __checkvsftp_version(self):
                    """check vsftpd version add configuration"""
                    faildmsg = u'vsftpd 版本获取失败'
                    vsftp_version = os.popen('rpm -qa |grep vsftpd').read().split('-')[1].split('.')
                    if vsftp_version:
                            l = [int(i) for i in vsftp_version]
                            if l[0] > 2 or (l[0] == 2 and l[1] > 3) or (l[0] == 2 and l[1] == 3 and l[2] >= 5):
                                    return True
                            else:
                                    return False
                    else:
                            raise RuntimeError(faildmsg)
    
            def __checkuser(self, username):
                    """ Check whether the input mapping user exists in the system  """
                    with open(Config.SYSUSER, 'r') as f:
                            list = [username for line in f.readlines() if username == line.split(':')[0]]
                            if list:
                                    return True
                            else:
                                    return False
    
            def __deny_users(self):
                    """return /etc/vsftpd/user_list deny users"""
                    with open(Config.DENYUSER, 'r') as f:
                            denyusers = [line for line in f.readlines() if not re.match('^s*#.+.*$', line)]
                            return denyusers
    
            def rollback(self, *args):
                    """UNINSTALL VSFTPD AND CONFIGURE"""
                    if len(args) > 0:
                            if self.__checkuser(username=args[0]):
                                    uninstall_command = 'yum -y remove vsftpd && userdel -r %s && rm -rf %s* && rm -rf /etc/vsftpd' % (
                                            args[0], Config.PAMFILE)
                            else:
                                    uninstall_command = 'yum -y remove vsftpd && rm -rf %s* && rm -rf /etc/vsftpd' % Config.PAMFILE
                    else:
                            uninstall_command = 'yum -y remove vsftpd && rm -rf %s* && rm -rf /etc/vsftpd' % Config.PAMFILE
    
                    if os.system(uninstall_command) != 0:
                            msg = u'卸载vsftpd 发生错误,请手动清除,以免产生垃圾文件'
                            print msg
                            logging.info(msg)
                            raise Exception(msg)
    
            def input_vuserinfo(self, numbers):
                    """Trapping the virtual user information input"""
                    vuser_dict = {}
                    v_user = raw_input(u'请输入第%d个虚拟用户名:' % numbers)
                    v_pass = raw_input(u'请输入第%d个虚拟用户密码:' % numbers)
                    vuser_dict['username'] = v_user
                    vuser_dict['password'] = v_pass
                    return vuser_dict
    
            def install_vsftpd(self, username):
                    install_vsftpd_command = 'yum -y install pam pam-devel db4 db4-tcl vsftpd >>%s' % Config.LOGFILE
                    actionmsg = u'开始安装vsftp服务...'
                    errormsg = u'vsftpd 或其他依赖项安装失败。'
    
                    logging.info(actionmsg)
                    if os.system(install_vsftpd_command) != 0:
                            logging.error(errormsg)
                            self.rollback(username)
                            raise Exception(errormsg)
    
            def deploy(self, username, parentpath):
                    """configure the vsftpd"""
                    sucessfulmsg = u'配置成功。'
                    msg = u'配置错误,请检查是否已经存在或不允许的参数'
                    denyusers = self.__deny_users()
                    if username in denyusers:
                            logging.error(msg)
                            self.rollback(username)
                            raise Exception(msg)
                    if not self.__checkuser(username=username):
                            os.makedirs(parentpath)
                            os.rmdir(parentpath)
                            create_user_command = 'useradd %s -d %s -s /sbin/nologin >> %s' % (username, parentpath, Config.LOGFILE)
                            if os.system(create_user_command) != 0:
                                    logging.error(msg)
                                    self.rollback(username)
                                    raise Exception(msg)
                    else:
                            logging.warning(msg)
                            self.rollback(username)
                            raise Exception(msg)
    
                    back_conf_command = 'cp %s %s.bak >> %s' % (Config.VFTP_CONF, Config.VFTP_CONF, Config.LOGFILE)
                    if os.system(back_conf_command) != 0:
                            logging.error(msg)
                            self.rollback(username)
                            raise Exception(msg)
                    else:
                            logging.info(sucessfulmsg)
    
                    f = open(Config.VFTP_CONF, 'w')
                    f.close()
    
                    list_vconf_content = Config.VCONF_CONTENT_TMP.split(os.linesep)
    
                    for line in list_vconf_content:
                            if re.match('^guest_username=.+$', line.strip()):
                                    line = 'guest_username=%s' % username
                            if re.match('^user_config_dir=.+$', line.strip()):
                                    line = 'user_config_dir=%s' % Config.VIR_CONF
                            if not self.__checkvsftp_version():
                                    if re.match('^allow_writeable_chroot=YES$', line.strip()):
                                            line = '#%s' % line.strip()
    
                            with open(Config.VFTP_CONF, 'a') as f:
                                    f.write(line.strip() + os.linesep)
                    logging.info(sucessfulmsg)
    
            def deploy_vritual_user(self, username, vuser):
                    """config vritual users"""
                    sucessfulmsg = u'创建虚拟用户配置目录成功'
                    faildmsg = u'创建虚拟用户配置目录失败'
                    dbsucessfulmsg = u'生成虚拟用户数据文件成功'
                    dbfaildmsg = u'生成虚拟用户数据文件失败'
    
                    if not os.path.exists(Config.VIR_CONF):
                            try:
                                    os.makedirs(Config.VIR_CONF)
                                    logging.info(sucessfulmsg)
                            except Exception:
                                    self.rollback(username)
                                    raise Exception(faildmsg)
                    f = open(Config.VUSER, 'w')
                    f.close()
    
                    for v_user in vuser:
                            with open(Config.VUSER, 'a') as f:
                                    f.write(v_user.get('username') + os.linesep)
                                    f.write(v_user.get('password') + os.linesep)
    
                    create_db_command = 'db_load -T -t hash -f %s %s.db' % (Config.VUSER, Config.VUSER)
    
                    if os.path.exists("%s.db" % Config.VUSER):
                            os.remove('%s.db' % Config.VUSER)
    
                    if os.system(create_db_command) != 0:
                            logging.error(dbfaildmsg)
                            self.rollback(username)
                            raise Exception(dbfaildmsg)
                    else:
                            logging.info(dbsucessfulmsg)
    
            def deploy_pam(self):
                    """config virtual user by pam"""
                    baksucessfulmsg = u'备份成功'
                    bakfaildmssg = u'备份失败'
                    msg = u'开始配置pam认证...'
                    endmsg = u'配置pam认证完成'
                    logging.info(msg)
                    back_pam_command = 'cp %s %s.back' % (Config.PAMFILE, Config.PAMFILE)
    
                    if os.path.exists('%s.back' % Config.PAMFILE):
                            os.remove('%s.back' % Config.PAMFILE)
    
                    if os.system(back_pam_command) != 0:
                            logging.warning(bakfaildmssg)
                    else:
                            logging.info(baksucessfulmsg)
    
                    f = open(Config.PAMFILE, 'w')
                    f.close()
    
                    list_pam_content = Config.PAM_CONTENT_TMP.split(os.linesep)
    
                    for line in list_pam_content:
                            p = re.compile(r'(?P<auth>.+s+.+s+.+s+db=)(?P<vuserfile>.+)')
                            for dt in p.finditer(line):
                                    line = dt.groupdict().get('auth') + Config.VUSER
    
                            with open(Config.PAMFILE, 'a') as f:
                                    f.write(line.strip() + os.linesep)
                            logging.info(endmsg)
    
            def deploy_virtual_config(self, username, parentpath, vuser):
                    """config virtual user Configure"""
                    sucessfulmsg = u'创建虚拟用户目录或配置成功'
                    faildmsg = u'创建虚拟用户目录或配置错误'
                    existsmsg = u'已存在,正在尝试删除...'
    
                    list_vuser_config_content = Config.VUSER_CONF_CONTENT_TMP.split(os.linesep)
                    for v_user in vuser:
                            vuser_path = os.path.join(parentpath, v_user.get('username'))
                            if os.path.exists(vuser_path):
                                    logging.warning(existsmsg)
                                    os.rmdir(vuser_path)
    
                            try:
                                    os.makedirs(vuser_path)
                                    uid = int(os.popen('id %s -u' % username).read().strip())
                                    gid = int(os.popen('id %s -g' % username).read().strip())
                                    os.chown(vuser_path, uid, gid)
                                    if not os.path.exists(vuser_path):
                                            logging.error(faildmsg)
                                            raise Exception(faildmsg)
                                    logging.info(sucessfulmsg)
                            except Exception:
                                    logging.error(faildmsg)
                                    self.rollback(username)
                                    raise Exception(faildmsg)
    
                            vuser_config = os.path.join(Config.VIR_CONF, v_user.get('username'))
                            if os.path.exists(vuser_path):
                                    f = open(vuser_config, 'w')
                                    f.close()
                            else:
                                    os.makedirs(Config.VIR_CONF)
                                    f = open(vuser_config, 'w')
                                    f.close()
    
                            for line in list_vuser_config_content:
                                    if re.match('^local_root=.+$', line.strip()):
                                            line = 'local_root=%s' % vuser_path
                                    with open(vuser_config, 'a') as f:
                                            f.write(line.strip() + os.linesep)
                    logging.info(sucessfulmsg)
    
            def start_server(self, parentpath):
                    start_vsftpd_command = 'service vsftpd start'
                    if os.system(start_vsftpd_command) != 0:
                            logging.error(u'启动vsftpd服务失败')
                            raise Exception(u'启动vsftpd服务失败')
                    else:
                            logging.info(u'启动vsftpd服务成功')
    
                    print ''
                    print u"安装vsftpd 完成!"
                    print ''
                    print ''
                    print u'-----' * 15
                    print u'1. 请在%s文件中查看登录的用户名和密码,一行用户名,一行密码' % Config.VUSER
                    print u'2. ftp数据存放在%s中' % parentpath
                    print u'3. 若FTP无法登陆,请检查主机防火墙是否关闭'
                    print u'-----' * 15
    
    
    if __name__ == '__main__':
            '''初始化日志输出'''
            LOG = InitLogging()
            LOG.logconfig()
    
            '''安装vsftpd服务'''
            IS = Install()
            username = raw_input(u'请输入vsftp的映射宿主用户名(本机账号):')
            parentpath = raw_input(u'请输入用于存放ftp数据的目录:')
            usercount = raw_input(u'您需要添加几个虚拟用户:')
            vuserlist = []
            if usercount.isdigit():
                    num = 0
                    for i in range(int(usercount)):
                            num += 1
                            vd = IS.input_vuserinfo(numbers=num)
                            vuserlist.append(vd)
            else:
                    raise RuntimeError(u'您输入的参数不是整型')
    
            # IS.install_vsftpd(username=username)
            # IS.deploy(username=username, parentpath=parentpath)
            # IS.deploy_vritual_user(username=username, vuser=vuserlist)
            # IS.deploy_pam()
            # IS.deploy_virtual_config(username=username, parentpath=parentpath, vuser=vuserlist)
            # IS.start_server(parentpath=parentpath)
    
            PB = ProgressBar()
            tasks = ['IS.install_vsftpd(username=username)', 'IS.deploy(username=username, parentpath=parentpath)',
                     'IS.deploy_vritual_user(username=username, vuser=vuserlist)', 'IS.deploy_pam()',
                     'IS.deploy_virtual_config(username=username, parentpath=parentpath, vuser=vuserlist)',
                     'IS.start_server(parentpath=parentpath)']
            PB.progress(tasklist=tasks, width=50)
    

      

  • 相关阅读:
    IDEA设置类级注释和方法级注释
    简单的后台管理系统demo(基于Spring Boot)
    MyBatis中if test传入0值时不识别
    MySQL插入时间数据与系统时间差8小时
    MySQL按字符串中部分数值排序
    二叉查找树
    40个提升网站用户体验的jQuery插件推荐 40个提升网站用户体验的jQuery插件推荐
    纯CSS3实现的8种Loading动画效果
    Web前端框架汇总
    最大公约数 最小公倍数
  • 原文地址:https://www.cnblogs.com/cpy-devops/p/9283562.html
Copyright © 2011-2022 走看看