コード例 #1
0
ファイル: website.py プロジェクト: wrestrtdr/applications
class Nextcloud(Site):
    addtoblock = [
        nginx.Key('error_page', '403 /core/templates/403.php'),
        nginx.Key('error_page', '404 /core/templates/404.php'),
        nginx.Key('client_max_body_size', '10G'),
        nginx.Key('fastcgi_buffers', '64 4K'),
        nginx.Key('fastcgi_buffer_size', '64K'),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location(
            '= /.well-known/carddav',
            nginx.Key('return', '301 $scheme://$host/remote.php/dav')),
        nginx.Location(
            '= /.well-known/caldav',
            nginx.Key('return', '301 $scheme://$host/remote.php/dav')),
        nginx.Location(
            '/',
            nginx.Key('rewrite', '^ /index.php$uri'),
        ),
        nginx.Location(
            '~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/',
            nginx.Key('deny', 'all')),
        nginx.Location('~ ^/(?:\.|autotest|occ|issue|indie|db_|console)',
                       nginx.Key('deny', 'all')),
        nginx.Location(
            '~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]'
            '|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/)',
            nginx.Key('include', 'fastcgi_params'),
            nginx.Key('fastcgi_split_path_info', '^(.+\.php)(/.+)$'),
            nginx.Key('fastcgi_param', 'SCRIPT_FILENAME '
                      '$document_root$fastcgi_script_name'),
            nginx.Key('fastcgi_param', 'PATH_INFO $fastcgi_path_info'),
            nginx.Key('fastcgi_param', 'modHeadersAvailable true'),
            nginx.Key('fastcgi_param', 'front_controller_active true'),
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_intercept_errors', 'on'),
            nginx.Key('fastcgi_read_timeout', '900s')),
        nginx.Location('~ ^/(?:updater|ocs-provider)(?:$|/)',
                       nginx.Key('try_files', '$uri/ =404'),
                       nginx.Key('index', 'index.php')),
        nginx.Location(
            '~* \.(?:css|js)$',
            nginx.Key('try_files', '$uri /index.php$uri$is_args$args'),
            nginx.Key('add_header', 'Cache-Control "public, max-age=7200"'),
            nginx.Key('add_header', 'X-Content-Type-Options nosniff'),
            nginx.Key('add_header', 'X-XSS-Protection "1; mode=block"'),
            nginx.Key('add_header', 'X-Frame-Options "SAMEORIGIN"'),
            nginx.Key('add_header', 'X-Robots-Tag none'),
            nginx.Key('add_header', 'X-Download-Options noopen'),
            nginx.Key('add_header', 'X-Permitted-Cross-Domain-Policies none'),
            nginx.Key('access_log', 'off')),
        nginx.Location(
            '~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$',
            nginx.Key('try_files', '$uri /index.php$uri$is_args$args'),
            nginx.Key('access_log', 'off'))
    ]

    def pre_install(self, extra_vars):
        pass

    def post_install(self, extra_vars, dbpasswd=""):
        php.open_basedir('add', '/dev')

        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        os.makedirs(os.path.join(self.path, "data"))
        os.chown(os.path.join(self.path, "data"), uid, gid)
        if self.data_path == self.path:
            self.data_path = os.path.join(self.path, "data")
        else:
            try:
                os.makedirs(os.path.join(self.data_path))
            except OSError as e:
                if e[0] == 17:
                    pass
                else:
                    raise
            os.chown(os.path.join(self.data_path), uid, gid)
            php.open_basedir('add', self.data_path)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('opcache', 'mysql', 'pdo_mysql', 'zip', 'gd', 'ldap',
                       'iconv', 'openssl', 'posix')
        php.enable_mod('apcu', 'apc', config_file="/etc/php/conf.d/apcu.ini")
        php.change_setting('apc.enable_cli',
                           '1',
                           config_file="/etc/php/conf.d/apcu.ini")

        # Make sure php-fpm has the correct settings,
        # otherwise Nextcloud breaks
        with open("/etc/php/php-fpm.conf", "r") as f:
            lines = f.readlines()
        with open("/etc/php/php-fpm.conf", "w") as f:
            for line in lines:
                if ";clear_env = " in line:
                    line = "clear_env = no\n"
                f.write(line)

        php.change_setting("always_populate_raw_post_data", "-1")
        mydir = os.getcwd()
        os.chdir(self.path)
        s = shell(('php occ maintenance:install '
                   '--database "mysql" --database-name "{}" '
                   '--database-user "{}" --database-pass "{}" '
                   '--admin-pass "{}" --data-dir "{}"').format(
                       self.db.id, self.db.id, dbpasswd, dbpasswd,
                       self.data_path))
        if s["code"] != 0:
            logger.critical("Nextcloud", s["stderr"])
            raise Exception("Nextcloud database population failed")
        s = shell("php occ app:enable user_ldap")
        if s["code"] != 0:
            logger.critical("Nextcloud", s["stderr"])
            raise Exception("Nextcloud LDAP configuration failed")
        os.chdir(mydir)
        os.chown(os.path.join(self.path, "config/config.php"), uid, gid)

        ldap_sql = ("REPLACE INTO oc_appconfig "
                    "(appid, configkey, configvalue) VALUES"
                    "('core', 'backgroundjobs_mode', 'cron'),"
                    "('user_ldap', 'ldap_uuid_attribute', 'auto'),"
                    "('user_ldap', 'ldap_host', 'localhost'),"
                    "('user_ldap', 'ldap_port', '389'),"
                    "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org'),"
                    "('user_ldap', 'ldap_base_users', "
                    "'dc=arkos-servers,dc=org'),"
                    "('user_ldap', 'ldap_base_groups', "
                    "'dc=arkos-servers,dc=org'),"
                    "('user_ldap', 'ldap_tls', '0'),"
                    "('user_ldap', 'ldap_display_name', 'cn'),"
                    "('user_ldap', 'ldap_userlist_filter', "
                    "'objectClass=mailAccount'),"
                    "('user_ldap', 'ldap_group_filter', "
                    "'objectClass=posixGroup'),"
                    "('user_ldap', 'ldap_group_display_name', 'cn'),"
                    "('user_ldap', 'ldap_group_member_assoc_attribute', "
                    "'uniqueMember'),"
                    "('user_ldap', 'ldap_login_filter', "
                    "'(&(|(objectclass=posixAccount))(|(uid=%uid)))'),"
                    "('user_ldap', 'ldap_quota_attr', 'mailQuota'),"
                    "('user_ldap', 'ldap_quota_def', ''),"
                    "('user_ldap', 'ldap_email_attr', 'mail'),"
                    "('user_ldap', 'ldap_cache_ttl', '600'),"
                    "('user_ldap', 'ldap_configuration_active', '1'),"
                    "('user_ldap', 'home_folder_naming_rule', ''),"
                    "('user_ldap', 'ldap_backup_host', ''),"
                    "('user_ldap', 'ldap_dn', ''),"
                    "('user_ldap', 'ldap_agent_password', ''),"
                    "('user_ldap', 'ldap_backup_port', ''),"
                    "('user_ldap', 'ldap_nocase', ''),"
                    "('user_ldap', 'ldap_turn_off_cert_check', ''),"
                    "('user_ldap', 'ldap_override_main_server', ''),"
                    "('user_ldap', 'ldap_attributes_for_user_search', ''),"
                    "('user_ldap', 'ldap_attributes_for_group_search', ''),"
                    "('user_ldap', 'ldap_expert_username_attr', 'uid'),"
                    "('user_ldap', 'ldap_expert_uuid_attr', '');")
        self.db.execute(ldap_sql, commit=True)
        self.db.execute("DELETE FROM oc_group_user;", commit=True)
        self.db.execute(
            "INSERT INTO oc_group_user VALUES ('admin','{0}');".format(
                extra_vars.get("nc-admin", "admin")),
            commit=True)

        if not os.path.exists("/etc/cron.d"):
            os.mkdir("/etc/cron.d")
        with open("/etc/cron.d/nc-{0}".format(self.id), "w") as f:
            f.write("*/15 * * * * http php -f {0} > /dev/null 2>&1".format(
                os.path.join(self.path, "cron.php")))

        with open(os.path.join(self.path, "config", "config.php"), "r") as f:
            data = f.read()
        while re.search("\n(\s*('|\")memcache.local.*?\n)", data, re.DOTALL):
            data = data.replace(
                re.search("\n(\s*('|\")memcache.local.*?\n)", data,
                          re.DOTALL).group(1), "")
        data = data.split("\n")
        with open(os.path.join(self.path, "config", "config.php"), "w") as f:
            for x in data:
                if not x.endswith("\n"):
                    x += "\n"
                if x.startswith(");"):
                    f.write("  'memcache.local' => '\OC\Memcache\APCu',\n")
                f.write(x)

        rootcerts = os.path.join(self.data_path,
                                 'data/files_external/rootcerts.crt')
        if os.path.exists(rootcerts):
            os.chown(os.path.join(rootcerts), uid, gid)

        self.site_edited()

    def pre_remove(self):
        datadir = ''
        config_file = os.path.join(self.path, 'config', 'config.php')
        autoconfig_file = os.path.join(self.path, 'config', 'autoconfig.php')
        if os.path.exists(config_file):
            with open(config_file, 'r') as f:
                for line in f.readlines():
                    if 'datadirectory' in line:
                        data = line.split("'")[1::2]
                        datadir = data[1]
        elif os.path.exists(autoconfig_file):
            with open(autoconfig_file, 'r') as f:
                for line in f.readlines():
                    if 'directory' in line:
                        data = line.split('"')[1::2]
                        datadir = data[1]
        if datadir:
            shutil.rmtree(datadir)
            php.open_basedir('del', datadir)

    def post_remove(self):
        cronfile = "/etc/cron.d/nc-{0}".format(self.id)
        if os.path.exists(cronfile):
            os.unlink(cronfile)

    def enable_ssl(self, cfile, kfile):
        # First, force SSL in Nextcloud's config file
        if os.path.exists(os.path.join(self.path, 'config', 'config.php')):
            px = os.path.join(self.path, 'config', 'config.php')
        else:
            px = os.path.join(self.path, 'config', 'autoconfig.php')
        with open(px, 'r') as f:
            ic = f.readlines()
        oc = []
        found = False
        for l in ic:
            if '"forcessl" =>' in l:
                l = '"forcessl" => true,\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found is False:
            for x in enumerate(oc):
                if '"dbhost" =>' in x[1]:
                    oc.insert(x[0] + 1, '"forcessl" => true,\n')
        with open(px, 'w') as f:
            f.writelines(oc)

    def disable_ssl(self):
        if os.path.exists(os.path.join(self.path, 'config', 'config.php')):
            px = os.path.join(self.path, 'config', 'config.php')
        else:
            px = os.path.join(self.path, 'config', 'autoconfig.php')
        with open(px, 'r') as f:
            ic = f.readlines()
        oc = []
        found = False
        for l in ic:
            if '"forcessl" =>' in l:
                l = '"forcessl" => false,\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found is False:
            for x in enumerate(oc):
                if '"dbhost" =>' in x[1]:
                    oc.insert(x[0] + 1, '"forcessl" => false,\n')
        with open(px, 'w') as f:
            f.writelines(oc)

    def site_edited(self):
        # Remove the existing trusted_sites array
        # then add a new one based on the new addr
        if os.path.exists(os.path.join(self.path, 'config', 'config.php')):
            path = os.path.join(self.path, 'config', 'config.php')
        else:
            raise errors.OperationFailedError(
                "Nextcloud config file not found")
        with open(path, "r") as f:
            data = f.read()
        while re.search("\n(\s*('|\")trusted_domains.*?\).*?\n)", data,
                        re.DOTALL):
            data = data.replace(
                re.search("\n(\s*('|\")trusted_domains.*?\).*?\n)", data,
                          re.DOTALL).group(1), "")
        data = data.split("\n")
        with open(path, "w") as f:
            for x in data:
                if not x.endswith("\n"):
                    x += "\n"
                if x.startswith(");"):
                    f.write("  'trusted_domains' => "
                            "array('localhost','{0}'),\n".format(self.domain))
                f.write(x)
コード例 #2
0
class Website(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = []

    phpblock = [
        nginx.Location(
            '~ ^(.+?\.php)(/.*)?$',
            nginx.Key('include', 'fastcgi_params'),
            nginx.Key('fastcgi_param', 'SCRIPT_FILENAME $document_root$1'),
            nginx.Key('fastcgi_param', 'PATH_INFO $2'),
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_read_timeout', '900s'),
        )
    ]

    def pre_install(self, name, vars):
        if vars.getvalue('ws-dbsel', 'None') == 'None':
            if vars.getvalue('ws-dbname', '') != '':
                raise Exception(
                    'Must choose a database type if you want to create one')
            elif vars.getvalue('ws-dbpass', '') != '':
                raise Exception(
                    'Must choose a database type if you want to create one')
        if vars.getvalue('ws-dbsel', 'None') != 'None':
            if vars.getvalue('ws-dbname', '') == '':
                raise Exception(
                    'Must choose a database name if you want to create one')
            elif vars.getvalue('ws-dbpass', '') == '':
                raise Exception(
                    'Must choose a database password if you want to create one'
                )
            elif ' ' in vars.getvalue('ws-dbname') or '-' in vars.getvalue(
                    'ws-dbname'):
                raise Exception(
                    'Database name must not contain spaces or dashes')
            elif vars.getvalue('ws-dbname') > 16 and vars.getvalue(
                    'ws-dbsel') == 'MariaDB':
                raise Exception(
                    'Database name must be shorter than 16 characters')

    def post_install(self, name, path, vars):
        # Write a basic index file showing that we are here
        if vars.getvalue('php', '0') == '1':
            php = True
            path = os.path.join(path, 'htdocs')
            os.mkdir(path)
            c = nginx.loadf(os.path.join('/etc/nginx/sites-available', name))
            for x in c.servers:
                if x.filter('Key', 'root'):
                    x.filter('Key', 'root')[0].value = path
            nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', name))
        else:
            php = False

        # Create a database if the user wants one
        if php:
            phpctl = apis.langassist(self.app).get_interface('PHP')
        if vars.getvalue('ws-dbsel', 'None') != 'None':
            dbtype = vars.getvalue('ws-dbsel', '')
            dbname = vars.getvalue('ws-dbname', '')
            passwd = vars.getvalue('ws-dbpass', '')
            dbase = apis.databases(self.app).get_interface(dbtype)
            if hasattr(dbase, 'connect'):
                conn = apis.databases(self.app).get_dbconn(dbtype)
                dbase.add(dbname, conn)
                dbase.usermod(dbname, 'add', passwd, conn)
                dbase.chperm(dbname, dbname, 'grant', conn)
            else:
                dbase.add(dbname)
                dbase.usermod(dbname, 'add', passwd)
                dbase.chperm(dbname, dbname, 'grant')
            if php:
                phpctl.enable_mod('mysql')

        f = open(
            os.path.join(path, 'index.' + ('php' if php is True else 'html')),
            'w')
        f.write('<html>\n'
                '<body>\n'
                '<h1>Genesis - Custom Site</h1>\n'
                '<p>Your site is online and available at ' + path + '</p>\n'
                '<p>Feel free to paste your site files here</p>\n'
                '</body>\n'
                '</html>\n')
        f.close()

        # Give access to httpd
        shell('chown -R http:http ' + path)

        # Enable xcache if PHP is set
        if php:
            phpctl.enable_mod('xcache')

    def pre_remove(self, name, path):
        pass

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        pass

    def ssl_disable(self, path):
        pass

    def show_opts_add(self, ui):
        type_sel = [UI.SelectOption(text='None', value='None')]
        for x in sorted(apis.databases(self.app).get_dbtypes()):
            type_sel.append(UI.SelectOption(text=x[0], value=x[0]))
        ui.appendAll('ws-dbsel', *type_sel)
コード例 #3
0
class ownCloud(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = [
        nginx.Key('error_page', '403 = /core/templates/403.php'),
        nginx.Key('error_page', '404 = /core/templates/404.php'),
        nginx.Key('client_max_body_size', '10G'),
        nginx.Key('fastcgi_buffers', '64 4K'),
        nginx.Key('rewrite', '^/caldav(.*)$ /remote.php/caldav$1 redirect'),
        nginx.Key('rewrite', '^/carddav(.*)$ /remote.php/carddav$1 redirect'),
        nginx.Key('rewrite', '^/webdav(.*)$ /remote.php/webdav$1 redirect'),
        nginx.Location('= /robots.txt',
            nginx.Key('allow', 'all'),
            nginx.Key('log_not_found', 'off'),
            nginx.Key('access_log', 'off')
            ),
        nginx.Location('~ ^/(data|config|\.ht|db_structure\.xml|README)',
            nginx.Key('deny', 'all')
            ),
        nginx.Location('/',
            nginx.Key('rewrite', '^/.well-known/host-meta /public.php?service=host-meta last'),
            nginx.Key('rewrite', '^/.well-known/host-meta.json /public.php?service=host-meta-json last'),
            nginx.Key('rewrite', '^/.well-known/carddav /remote.php/carddav/ redirect'),
            nginx.Key('rewrite', '^/.well-known/caldav /remote.php/caldav/ redirect'),
            nginx.Key('rewrite', '^(/core/doc/[^\/]+/)$ $1/index.html'),
            nginx.Key('try_files', '$uri $uri/ index.php')
            ),
        nginx.Location('~ ^(.+?\.php)(/.*)?$',
            nginx.Key('try_files', '$1 = 404'),
            nginx.Key('include', 'fastcgi_params'),
            nginx.Key('fastcgi_param', 'SCRIPT_FILENAME $document_root$1'),
            nginx.Key('fastcgi_param', 'PATH_INFO $2'),
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_read_timeout', '900s')
            ),
        nginx.Location('~* ^.+\.(jpg|jpeg|gif|bmp|ico|png|css|js|swf)$',
            nginx.Key('expires', '30d'),
            nginx.Key('access_log', 'off')
            )
        ]

    def pre_install(self, name, vars):
        if vars.getvalue('oc-username', '') == '':
            raise Exception('Must choose an ownCloud username')
        elif vars.getvalue('oc-logpasswd', '') == '':
            raise Exception('Must choose an ownCloud password')
        elif '"' in vars.getvalue('oc-logpasswd', '') or "'" in vars.getvalue('oc-logpasswd', ''):
            raise Exception('Your ownCloud password must not include quotes')

    def post_install(self, name, path, vars, dbinfo={}):
        phpctl = apis.langassist(self.app).get_interface('PHP')
        datadir = ''
        secret_key = hashlib.sha1(str(random.random())).hexdigest()
        username = vars.getvalue('oc-username')
        logpasswd = vars.getvalue('oc-logpasswd')

        # Set ownership as necessary
        if not os.path.exists(os.path.join(path, 'data')):
            os.makedirs(os.path.join(path, 'data'))
        shell('chown -R http:http '+path)

        # If there is a custom path for the data directory, do the magic
        if vars.getvalue('oc-ddir', '') != '':
            datadir = vars.getvalue('oc-ddir')
            if not os.path.exists(os.path.join(datadir if datadir else path, 'data')):
                os.makedirs(os.path.join(datadir if datadir else path, 'data'))
            shell('chown -R http:http '+os.path.join(datadir if datadir else path, 'data'))
            phpctl.open_basedir('add', datadir)

        # Create ownCloud automatic configuration file
        f = open(os.path.join(path, 'config', 'autoconfig.php'), 'w')
        f.write(
            '<?php\n'
            '   $AUTOCONFIG = array(\n'
            '   "adminlogin" => "'+username+'",\n'
            '   "adminpass" => "'+logpasswd+'",\n'
            '   "dbtype" => "mysql",\n'
            '   "dbname" => "'+dbinfo['name']+'",\n'
            '   "dbuser" => "'+dbinfo['user']+'",\n'
            '   "dbpass" => "'+dbinfo['passwd']+'",\n'
            '   "dbhost" => "localhost",\n'
            '   "dbtableprefix" => "",\n'
            '   "directory" => "'+os.path.join(datadir if datadir else path, 'data')+'",\n'
            '   );\n'
            '?>\n'
            )
        f.close()
        shell('chown http:http '+os.path.join(path, 'config', 'autoconfig.php'))

        # Make sure that the correct PHP settings are enabled
        phpctl.enable_mod('mysql', 'pdo_mysql', 'zip', 'gd',
            'iconv', 'openssl', 'xcache')
        
        # Make sure xcache has the correct settings, otherwise ownCloud breaks
        f = open('/etc/php/conf.d/xcache.ini', 'w')
        oc = ['extension=xcache.so\n',
            'xcache.size=64M\n',
            'xcache.var_size=64M\n',
            'xcache.admin.enable_auth = Off\n',
            'xcache.admin.user = "******"\n',
            'xcache.admin.pass = "******"\n']
        f.writelines(oc)
        f.close()

        # Return an explicatory message
        if self.app.board in ['BeagleBone Black,' 'Raspberry Pi']:
            return ('ownCloud takes a long time to set up on this platform. '
            'Once you open the page for the first time, it may take 5-10 '
            'minutes for the content to appear. Please do not refresh the '
            'page.')

    def pre_remove(self, site):
        datadir = ''
        if os.path.exists(os.path.join(site.path, 'config', 'config.php')):
            f = open(os.path.join(site.path, 'config', 'config.php'), 'r')
            for line in f.readlines():
                if 'datadirectory' in line:
                    data = line.split("'")[1::2]
                    datadir = data[1]
            f.close()
        elif os.path.exists(os.path.join(site.path, 'config', 'autoconfig.php')):
            f = open(os.path.join(site.path, 'config', 'autoconfig.php'), 'r')
            for line in f.readlines():
                if 'directory' in line:
                    data = line.split('"')[1::2]
                    datadir = data[1]
            f.close()
        if datadir:
            shutil.rmtree(datadir)
            phpctl = apis.langassist(self.app).get_interface('PHP')
            phpctl.open_basedir('del', datadir)

    def post_remove(self, site):
        pass

    def ssl_enable(self, path, cfile, kfile):
        # First, force SSL in ownCloud's config file
        if os.path.exists(os.path.join(path, 'config', 'config.php')):
            px = os.path.join(path, 'config', 'config.php')
        else:
            px = os.path.join(path, 'config', 'autoconfig.php')
        ic = open(px, 'r').readlines()
        f = open(px, 'w')
        oc = []
        found = False
        for l in ic:
            if '"forcessl" =>' in l:
                l = '"forcessl" => true,\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found == False:
            for x in enumerate(oc):
                if '"dbhost" =>' in x[1]:
                    oc.insert(x[0] + 1, '"forcessl" => true,\n')
        f.writelines(oc)
        f.close()

        # Next, update the ca-certificates thing to include our cert
        # (if necessary)
        if not os.path.exists('/usr/share/ca-certificates'):
            try:
                os.makedirs('/usr/share/ca-certificates')
            except OSError, e:
                if e.errno == errno.EEXIST and os.path.isdir('/usr/share/ca-certificates'):
                    pass
                else:
                    raise
        shutil.copy(cfile, '/usr/share/ca-certificates/')
        fname = cfile.rstrip('/').split('/')[-1]
        ic = open('/etc/ca-certificates.conf', 'r').readlines()
        f = open('/etc/ca-certificates.conf', 'w')
        oc = []
        for l in ic:
            if l != fname+'\n':
                oc.append(l)
        oc.append(fname+'\n')
        f.writelines(oc)
        f.close()
        shell('update-ca-certificates')
コード例 #4
0
class ownCloud(Site):
    addtoblock = [
        nginx.Key('error_page', '403 = /core/templates/403.php'),
        nginx.Key('error_page', '404 = /core/templates/404.php'),
        nginx.Key('client_max_body_size', '10G'),
        nginx.Key('fastcgi_buffers', '64 4K'),
        nginx.Key('rewrite', '^/caldav(.*)$ /remote.php/caldav$1 redirect'),
        nginx.Key('rewrite', '^/carddav(.*)$ /remote.php/carddav$1 redirect'),
        nginx.Key('rewrite', '^/webdav(.*)$ /remote.php/webdav$1 redirect'),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location(
            '~ ^/(?:\.htaccess|data|config|db_structure\.xml|README)',
            nginx.Key('deny', 'all')),
        nginx.Location(
            '/',
            nginx.Key(
                'rewrite',
                '^/.well-known/host-meta /public.php?service=host-meta last'),
            nginx.Key(
                'rewrite',
                '^/.well-known/host-meta.json /public.php?service=host-meta-json last'
            ),
            nginx.Key('rewrite',
                      '^/.well-known/carddav /remote.php/carddav/ redirect'),
            nginx.Key('rewrite',
                      '^/.well-known/caldav /remote.php/caldav/ redirect'),
            nginx.Key('rewrite', '^(/core/doc/[^\/]+/)$ $1/index.html'),
            nginx.Key('try_files', '$uri $uri/ index.php')),
        nginx.Location(
            '~ \.php(?:$|/)',
            nginx.Key('fastcgi_split_path_info', '^(.+\.php)(/.+)$'),
            nginx.Key('include', 'fastcgi_params'),
            nginx.Key('fastcgi_param',
                      'SCRIPT_FILENAME $document_root$fastcgi_script_name'),
            nginx.Key('fastcgi_param', 'PATH_INFO $fastcgi_path_info'),
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_read_timeout', '900s')),
        nginx.Location('~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$',
                       nginx.Key('expires', '30d'),
                       nginx.Key('access_log', 'off'))
    ]

    def pre_install(self, vars):
        pass

    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()

        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        if not self.data_path.startswith(self.path):
            os.makedirs(os.path.join(self.path, "data"))
            os.chown(os.path.join(self.path, "data"), uid, gid)
            php.open_basedir('add', self.data_path)

        # Create ownCloud automatic configuration file
        with open(os.path.join(self.path, 'config', 'autoconfig.php'),
                  'w') as f:
            f.write('<?php\n'
                    '   $AUTOCONFIG = array(\n'
                    '   "adminlogin" => "admin",\n'
                    '   "adminpass" => "' + dbpasswd + '",\n'
                    '   "dbtype" => "mysql",\n'
                    '   "dbname" => "' + self.db.id + '",\n'
                    '   "dbuser" => "' + self.db.id + '",\n'
                    '   "dbpass" => "' + dbpasswd + '",\n'
                    '   "dbhost" => "localhost",\n'
                    '   "dbtableprefix" => "",\n'
                    '   "directory" => "' + self.data_path + '",\n'
                    '   );\n'
                    '?>\n')
        os.chown(os.path.join(self.path, 'config', 'autoconfig.php'), uid, gid)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql', 'pdo_mysql', 'zip', 'gd', 'ldap', 'iconv',
                       'openssl', 'xcache', 'posix')

        # Make sure xcache has the correct settings, otherwise ownCloud breaks
        with open('/etc/php/conf.d/xcache.ini', 'w') as f:
            f.writelines([
                'extension=xcache.so\n', 'xcache.size=64M\n',
                'xcache.var_size=64M\n', 'xcache.admin.enable_auth = Off\n',
                'xcache.admin.user = "******"\n',
                'xcache.admin.pass = "******"\n'
            ])

        php.change_setting("always_populate_raw_post_data", "-1")
        mydir = os.getcwd()
        os.chdir(self.path)
        s = shell("sudo -u http php index.php")
        if s["code"] != 0:
            raise Exception("ownCloud database population failed")
        s = shell("sudo -u http php occ app:enable user_ldap")
        if s["code"] != 0:
            raise Exception("ownCloud LDAP configuration failed")
        os.chdir(mydir)

        ldap_sql = (
            "REPLACE INTO appconfig (appid, configkey, configvalue) VALUES"
            "('user_ldap', 'ldap_uuid_attribute', 'auto'),"
            "('user_ldap', 'ldap_host', 'localhost'),"
            "('user_ldap', 'ldap_port', '389'),"
            "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_users', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_groups', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_tls', '0'),"
            "('user_ldap', 'ldap_display_name', 'cn'),"
            "('user_ldap', 'ldap_userlist_filter', 'objectClass=mailAccount'),"
            "('user_ldap', 'ldap_group_filter', 'objectClass=posixGroup'),"
            "('user_ldap', 'ldap_group_display_name', 'cn'),"
            "('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'),"
            "('user_ldap', 'ldap_login_filter', '(&(|(objectclass=posixAccount))(|(uid=%uid)))'),"
            "('user_ldap', 'ldap_quota_attr', 'mailQuota'),"
            "('user_ldap', 'ldap_quota_def', ''),"
            "('user_ldap', 'ldap_email_attr', 'mail'),"
            "('user_ldap', 'ldap_cache_ttl', '600'),"
            "('user_ldap', 'ldap_configuration_active', '1'),"
            "('user_ldap', 'home_folder_naming_rule', ''),"
            "('user_ldap', 'ldap_backup_host', ''),"
            "('user_ldap', 'ldap_dn', ''),"
            "('user_ldap', 'ldap_agent_password', ''),"
            "('user_ldap', 'ldap_backup_port', ''),"
            "('user_ldap', 'ldap_nocase', ''),"
            "('user_ldap', 'ldap_turn_off_cert_check', ''),"
            "('user_ldap', 'ldap_override_main_server', ''),"
            "('user_ldap', 'ldap_attributes_for_user_search', ''),"
            "('user_ldap', 'ldap_attributes_for_group_search', ''),"
            "('user_ldap', 'ldap_expert_username_attr', 'uid'),"
            "('user_ldap', 'ldap_expert_uuid_attr', '');")
        self.db.execute(ldap_sql, commit=True)
        # TODO set authed user name
        self.db.execute("INSERT INTO group_user VALUES ('admin','testuser');",
                        commit=True)

    def pre_remove(self):
        datadir = ''
        if os.path.exists(os.path.join(self.path, 'config', 'config.php')):
            with open(os.path.join(self.path, 'config', 'config.php'),
                      'r') as f:
                for line in f.readlines():
                    if 'datadirectory' in line:
                        data = line.split("'")[1::2]
                        datadir = data[1]
        elif os.path.exists(os.path.join(self.path, 'config',
                                         'autoconfig.php')):
            with open(os.path.join(self.path, 'config', 'autoconfig.php'),
                      'r') as f:
                for line in f.readlines():
                    if 'directory' in line:
                        data = line.split('"')[1::2]
                        datadir = data[1]
        if datadir:
            shutil.rmtree(datadir)
            php.open_basedir('del', datadir)

    def post_remove(self):
        pass

    def enable_ssl(self, cfile, kfile):
        # First, force SSL in ownCloud's config file
        if os.path.exists(os.path.join(self.path, 'config', 'config.php')):
            px = os.path.join(self.path, 'config', 'config.php')
        else:
            px = os.path.join(self.path, 'config', 'autoconfig.php')
        with open(px, 'r') as f:
            ic = f.readlines()
        oc = []
        found = False
        for l in ic:
            if '"forcessl" =>' in l:
                l = '"forcessl" => true,\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found == False:
            for x in enumerate(oc):
                if '"dbhost" =>' in x[1]:
                    oc.insert(x[0] + 1, '"forcessl" => true,\n')
        with open(px, 'w') as f:
            f.writelines(oc)

        # Next, update the ca-certificates thing to include our cert
        # (if necessary)
        if not os.path.exists('/usr/share/ca-certificates'):
            try:
                os.makedirs('/usr/share/ca-certificates')
            except OSError, e:
                if e.errno == errno.EEXIST and os.path.isdir(
                        '/usr/share/ca-certificates'):
                    pass
                else:
                    raise
        shutil.copy(cfile, '/usr/share/ca-certificates/')
        fname = cfile.rstrip('/').split('/')[-1]
        with open('/etc/ca-certificates.conf', 'r') as f:
            ic = f.readlines()
        oc = []
        for l in ic:
            if l != fname + '\n':
                oc.append(l)
        oc.append(fname + '\n')
        with open('/etc/ca-certificates.conf', 'w') as f:
            f.writelines(oc)
        shell('update-ca-certificates')
コード例 #5
0
class WordPress(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = [
        nginx.Location('= /favicon.ico', nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('/',
                       nginx.Key('try_files', '$uri $uri/ /index.php?$args')),
        nginx.Location(
            '~ \.php$',
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_index', 'index.php'),
            nginx.Key('include', 'fastcgi.conf')),
        nginx.Location('~* \.(js|css|png|jpg|jpeg|gif|ico)$',
                       nginx.Key('expires', 'max'),
                       nginx.Key('log_not_found', 'off'))
    ]

    def pre_install(self, name, vars):
        pass

    def post_install(self, name, path, vars, dbinfo={}):
        phpctl = apis.langassist(self.app).get_interface('PHP')
        secret_key = hashlib.sha1(str(random.random())).hexdigest()

        # Use the WordPress key generators as first option
        # If connection fails, use the secret_key as fallback
        try:
            keysection = urllib.urlopen(
                'https://api.wordpress.org/secret-key/1.1/salt/').read()
        except:
            keysection = ''
        if not 'define(\'AUTH_KEY' in keysection:
            keysection = ('define(\'AUTH_KEY\', \'' + secret_key + '\');\n'
                          'define(\'SECURE_AUTH_KEY\', \'' + secret_key +
                          '\');\n'
                          'define(\'LOGGED_IN_KEY\', \'' + secret_key +
                          '\');\n'
                          'define(\'NONCE_KEY\', \'' + secret_key + '\');\n')

        # Write a standard WordPress config file
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        f.write('<?php\n'
                'define(\'DB_NAME\', \'' + dbinfo['name'] + '\');\n'
                'define(\'DB_USER\', \'' + dbinfo['user'] + '\');\n'
                'define(\'DB_PASSWORD\', \'' + dbinfo['passwd'] + '\');\n'
                'define(\'DB_HOST\', \'localhost\');\n'
                'define(\'DB_CHARSET\', \'utf8\');\n'
                'define(\'SECRET_KEY\', \'' + secret_key + '\');\n'
                '\n'
                'define(\'WP_CACHE\', true);\n'
                'define(\'FORCE_SSL_ADMIN\', false);\n'
                '\n' + keysection + '\n'
                '$table_prefix = \'wp_\';\n'
                '\n'
                '/** Absolute path to the WordPress directory. */\n'
                'if ( !defined(\'ABSPATH\') )\n'
                '	define(\'ABSPATH\', dirname(__FILE__) . \'/\');\n'
                '\n'
                '/** Sets up WordPress vars and included files. */\n'
                'require_once(ABSPATH . \'wp-settings.php\');\n')
        f.close()

        # Make sure that the correct PHP settings are enabled
        phpctl.enable_mod('mysql', 'xcache')

        # Finally, make sure that permissions are set so that Wordpress
        # can make adjustments and save plugins when need be.
        shell('chown -R http:http ' + path)

    def pre_remove(self, site):
        pass

    def post_remove(self, site):
        pass

    def ssl_enable(self, path, cfile, kfile):
        ic = open(os.path.join(path, 'wp-config.php'), 'r').readlines()
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        oc = []
        found = False
        for l in ic:
            if 'define(\'FORCE_SSL_ADMIN\'' in l:
                l = 'define(\'FORCE_SSL_ADMIN\', false);\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found == False:
            oc.append('define(\'FORCE_SSL_ADMIN\', true);\n')
        f.writelines(oc)
        f.close()

    def ssl_disable(self, path):
        ic = open(os.path.join(path, 'wp-config.php'), 'r').readlines()
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        oc = []
        found = False
        for l in ic:
            if 'define(\'FORCE_SSL_ADMIN\'' in l:
                l = 'define(\'FORCE_SSL_ADMIN\', false);\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found == False:
            oc.append('define(\'FORCE_SSL_ADMIN\', false);\n')
        f.writelines(oc)
        f.close()
コード例 #6
0
def main():

    nginx_parameter_length_limit = 4000

    pythonhome_directory = ""
    flask_app_file_location = ""
    application_name = ""
    nginx_conf_location = ""
    nginx_include_location = ""

    module_usage_string = """
Usage: nginx_flaskapp_whitelister -r (optional) -p <pythonenvdirectory> -f <flaskappmodule> -a <flaskapplicationname> -c <nginxconfiglocation> -n <nginxincludelocation>
Flags:
        -h                              Help function to display functionality and guidance to use the nginx_flaskapp_whitelister module.
        -r                              Optional: Restart Nginx to reload added configuration and for white-listing to take immediate effect.
        -p <pythonenvdirectory>         The directory of the python environment that the Flask app is running in. The $PYTHONHOME variable.
        -f <flaskappmodule>             The python module from where the Flask app is served.
        -a <flaskapplicationname>       The physical name of the Flask application.
        -c <nginxconfiglocation>        The location of the current Nginx configuration that is used to serve the Flask application.
        -n <nginxincludelocation>       Optional: File path to where the 'include.whitelist' file will be included from within the Nginx configuration
                                        that is used to serve the Flask application. If no file path is provided, the default will be used as
                                        '/etc/nginx/'.
"""

    # Initial parameter/flag verification and extraction

    if not len(sys.argv) > 1:
        print(
            'No arguments supplied. For more information run: nginx_flaskapp_whitelister -h'
        )
        print(module_usage_string)
        sys.exit(2)

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hrp:f:a:c:n:", [
            "pythonenvdir=", "flaskappmodule=", "applicationname=",
            "nginxconfiglocation=", "nginxincludelocation="
        ])
    except getopt.GetoptError:
        print(module_usage_string)
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print(module_usage_string)
            sys.exit()
        elif opt in ("-p", "--pythonenvdir"):
            pythonhome_directory = arg
        elif opt in ("-f", "--flaskappmodule"):
            if "/" in arg:
                flask_app_file_location = arg.replace("/", ".")
                if flask_app_file_location.startswith("."):
                    flask_app_file_location = flask_app_file_location[1:]
            else:
                flask_app_file_location = arg
        elif opt in ("-a", "--applicationname"):
            application_name = arg
        elif opt in ("-c", "--nginxconfiglocation"):
            nginx_conf_location = arg
        elif opt in ("-n", "--nginxincludelocation"):
            nginx_include_location = arg

    required_arguments = [{
        'pythonenvdir': pythonhome_directory
    }, {
        'flaskappmodule': flask_app_file_location
    }, {
        'applicationname': application_name
    }, {
        'nginxconfiglocation': nginx_conf_location
    }]

    missing_arg = ""
    for argument in required_arguments:
        if argument.values()[0] == "":
            if missing_arg == "":
                missing_arg = argument.keys()[0]
            else:
                missing_arg = missing_arg + ", " + argument.keys()[0]
    if missing_arg != "":
        print(
            'Required arguments (' + missing_arg +
            ') are missing. For more information run: nginx_flaskapp_whitelister -h'
        )
        print(module_usage_string)
        sys.exit(2)

    # Setup the PYTHONPATH variable to point to the python home and import the requested Flask app from the specified module
    sys.path.append(pythonhome_directory)
    project = importlib.import_module(flask_app_file_location)
    app = getattr(project, application_name)

    # Extract all exposed flask endpoints from the specified app
    links = []
    for rule in app.url_map._rules:
        links.append(rule.rule)

    # Consolidate the retrieved rules from the flask app url map to only contain a list of allowed endpoints and strip
    # parameter sections (< >) from endpoints
    allowed_locations = []
    for endpoint in links:
        if endpoint != "/":
            allowed_locations.append(re.sub('<[^>]+>', '', endpoint))

    # Load the current NginX config used to serve the application into a config object
    config = nginx.loadf(nginx_conf_location)

    # Extract the keys and configuration from the config object that refers to the location directive that allows the access
    # to "location / {}" (presumed to be the most likely allowed full access route configured)
    original_location_object = []
    original_server_list = list(config.filter('Http')[0].filter('Server'))
    for server in original_server_list:
        if server.locations != []:
            original_location_object.extend(server.locations)

    current_locations = []
    for location in original_location_object:
        current_locations.append(location.as_dict)

    # Create a new NginX config object for the added included location directives for the whitelisted locations
    allowed_location_keys = []

    whitelist_location_conf = nginx.Conf()
    for location in current_locations:
        if location.keys()[0] == 'location /':
            for key in location['location /']:
                nested_key = []
                if "if (" in key.keys()[0]:
                    for x in key[key.keys()[0]]:
                        nested_key.append(
                            nginx.Key(x.keys()[0], x[x.keys()[0]]).as_strings)
                    allowed_location_keys.append(
                        nginx.Key(key.keys()[0],
                                  '{ ' + "".join(nested_key) + ' }'))
                else:
                    allowed_location_keys.append(
                        nginx.Key(key.keys()[0], key[key.keys()[0]]))

    # As Nginx has a parameter limit that caps the amount of characters allowed in a directive parameter,
    # the allowed location endpoints are chunked accordingly into as big as possible chunks within the limit
    dynamic_locations_write_variable = []
    for location in allowed_locations:
        if len("|".join(dynamic_locations_write_variable +
                        [location])) < nginx_parameter_length_limit:
            dynamic_locations_write_variable.append(location)
        else:
            dynamic_locations_write_variable.append(location)
            whitelist_location_conf.add(
                nginx.Location(
                    '~ (' + '|'.join(dynamic_locations_write_variable) + ')',
                    nginx.Key('include', 'shared.conf')))
            dynamic_locations_write_variable = []
    if dynamic_locations_write_variable != []:
        whitelist_location_conf.add(
            nginx.Location(
                '~ (' + '|'.join(dynamic_locations_write_variable) + ')',
                nginx.Key('include', 'shared.conf')))
        dynamic_locations_write_variable = []
    whitelist_location_conf.add(
        nginx.Location('= /', nginx.Key('include', 'shared.conf')))
    whitelist_location_conf.add(
        nginx.Location('~ /', nginx.Key('return', '404')))

    # Create a shared Nginx config object containing the keys and configurations shared and re-used
    # across various location directives. This shared.conf is then included per directive, instead
    # of repeating code
    shared_conf = nginx.Conf()
    shared_conf.add(*allowed_location_keys)
    shared_conf_tmp_file = tempfile.NamedTemporaryFile(dir='/tmp/').name
    nginx.dumpf(shared_conf, shared_conf_tmp_file)
    with open(shared_conf_tmp_file, 'r') as file:
        shared_conf_data = file.readlines()
        if any("if (" in string for string in shared_conf_data):
            for line in shared_conf_data:
                if "if (" in line:
                    shared_conf_data[shared_conf_data.index(
                        line)] = line.replace(') "{', ') {')
                if '}";' in line:
                    shared_conf_data[shared_conf_data.index(
                        line)] = line.replace('}";', '}')
            with open(shared_conf_tmp_file, 'w') as file:
                file.writelines(shared_conf_data)

    whitelist_location_conf_tmp_file = tempfile.NamedTemporaryFile(
        dir='/tmp/').name
    nginx.dumpf(whitelist_location_conf, whitelist_location_conf_tmp_file)

    # If a specific Nginx include location is specified, the generated configuration are moved to this location,
    # otherwise it is moved to a default location of (/etc/nginx/). This filepath should match the path of the
    # include directive inserted into the main nginx.conf for enabling the nginx whitelisting.
    if nginx_include_location != "":
        os.rename(whitelist_location_conf_tmp_file,
                  nginx_include_location + "/include.whitelist")
        os.rename(shared_conf_tmp_file,
                  nginx_include_location + "/shared.conf")
    else:
        os.rename(whitelist_location_conf_tmp_file,
                  "/etc/nginx/include.whitelist")
        os.rename(shared_conf_tmp_file, "/etc/nginx/shared.conf")

    # For the newly generated whitelisting config to take effect, the Nginx config should be reloaded and the
    # process restarted. If the restart flag was set by the user, Nginx will be attempted to restart as part
    # of the tool implementation
    for opt, arg in opts:
        if opt == '-r':
            nginx_restart = subprocess.check_output(
                ["service", "nginx", "restart"])
            print(nginx_restart)
コード例 #7
0
class Wallabag(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = [
        nginx.Location('~ /(db)', nginx.Key('deny', 'all'),
                       nginx.Key('return', '404')),
        nginx.Location('= /favicon.ico', nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('/',
                       nginx.Key('try_files', '$uri $uri/ /index.php?$args')),
        nginx.Location(
            '~ \.php$',
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_index', 'index.php'),
            nginx.Key('include', 'fastcgi.conf')),
        nginx.Location('~* \.(js|css|png|jpg|jpeg|gif|ico)$',
                       nginx.Key('expires', 'max'),
                       nginx.Key('log_not_found', 'off'))
    ]

    def pre_install(self, name, vars):
        pass

    def post_install(self, name, path, vars, dbinfo={}):
        phpctl = apis.langassist(self.app).get_interface('PHP')
        secret_key = hashlib.sha1(str(random.random())).hexdigest()
        dbengine = 'mysql' if dbinfo['engine'] == 'MariaDB' else 'sqlite'

        # Write a standard Wallabag config file
        shutil.copy(os.path.join(path, 'inc/poche/config.inc.default.php'),
                    os.path.join(path, 'inc/poche/config.inc.php'))
        ic = open(os.path.join(path, 'inc/poche/config.inc.php'),
                  'r').readlines()
        f = open(os.path.join(path, 'inc/poche/config.inc.php'), 'w')
        oc = []
        for l in ic:
            if 'define (\'SALT\'' in l:
                l = '@define (\'SALT\', \'' + secret_key + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE\'' in l:
                l = '@define (\'STORAGE\', \'' + dbengine + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_SQLITE\'' in l and dbengine == 'sqlite':
                l = '@define (\'STORAGE_SQLITE\', \'/var/lib/sqlite3/' + dbinfo[
                    'name'] + '.db\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_DB\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_DB\', \'' + dbinfo['name'] + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_USER\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_USER\', \'' + dbinfo['user'] + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_PASSWORD\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_PASSWORD\', \'' + dbinfo[
                    'passwd'] + '\');\n'
                oc.append(l)
            else:
                oc.append(l)
        f.writelines(oc)
        f.close()

        # Make sure that the correct PHP settings are enabled
        phpctl.enable_mod('mysql' if dbengine == 'mysql' else 'sqlite3',
                          'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite',
                          'zip', 'tidy', 'xcache', 'openssl')

        # Set up Composer and install the proper modules
        phpctl.composer_install(path)

        # Set up the database then delete the install folder
        if dbengine == 'mysql':
            dbase = apis.databases(self.app).get_interface(dbinfo['engine'])
            conn = apis.databases(self.app).get_dbconn(dbinfo['engine'])
            dbase.execute(dbinfo['name'],
                          open(os.path.join(path, 'install/mysql.sql')).read(),
                          conn)
        else:
            shutil.copy(os.path.join(path, 'install/poche.sqlite'),
                        '/var/lib/sqlite3/%s.db' % dbinfo['name'])
            phpctl.open_basedir('add', '/var/lib/sqlite3')
            shell('chown http:http /var/lib/sqlite3/%s.db' % dbinfo['name'])
            shell('chmod 755 /var/lib/sqlite3/%s.db' % dbinfo['name'])
        shutil.rmtree(os.path.join(path, 'install'))

        # Finally, make sure that permissions are set so that Wallabag
        # can make adjustments and save plugins when need be.
        shell('chmod -R 755 ' + os.path.join(path, 'assets/') + ' ' +
              os.path.join(path, 'cache/') + ' ' + os.path.join(path, 'db/'))
        shell('chown -R http:http ' + path)

    def pre_remove(self, site):
        pass

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        pass

    def ssl_disable(self, path):
        pass

    def update(self, path, pkg, ver):
        # General update procedure
        shell('tar xzf %s -C %s --strip 1' % (pkg, path))
        for x in os.listdir(os.path.join(path, 'cache')):
            if os.path.isdir(os.path.join(path, 'cache', x)):
                shutil.rmtree(os.path.join(path, 'cache', x))
            else:
                os.unlink(os.path.join(path, 'cache', x))
        shutil.rmtree(os.path.join(path, 'install'))
        shell('chmod -R 755 ' + os.path.join(path, 'assets/') + ' ' +
              os.path.join(path, 'cache/') + ' ' + os.path.join(path, 'db/'))
        shell('chown -R http:http ' + path)
コード例 #8
0
class Etherpad(Plugin):
    implements(apis.webapps.IWebapp)
    name = 'Etherpad'
    icon = 'gen-pen'

    addtoblock = [
        nginx.Location('/', nginx.Key('proxy_pass', 'http://127.0.0.1:2369'),
                       nginx.Key('proxy_set_header', 'X-Real-IP $remote_addr'),
                       nginx.Key('proxy_set_header', 'Host $host'),
                       nginx.Key('proxy_buffering', 'off'))
    ]

    def pre_install(self, name, vars):
        eth_name = vars.getvalue('ether_admin', '')
        eth_pass = vars.getvalue('ether_pass', '')
        if not (eth_name and eth_pass):
            raise Exception('You must enter an admin name AND password'
                            'in the App Settings tab!')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        apis.databases(self.app).get_interface('MariaDB').validate(
            name, name, eth_pass, conn)

    def post_install(self, name, path, vars, dbinfo={}):
        UsersBackend(self.app).add_user('etherpad')

        # Create/Edit the config file
        cfg = {
            "title":
            "Etherpad",
            "favicon":
            "favicon.ico",
            "ip":
            "127.0.0.1",
            "port":
            "2369",
            "sessionKey":
            hashlib.sha1(str(random.random())).hexdigest(),
            "dbType":
            "mysql",
            "dbSettings": {
                "user": dbinfo['user'],
                "host": "localhost",
                "password": dbinfo['passwd'],
                "database": dbinfo['name']
            },
            "defaultPadText":
            ("Welcome to Etherpad on arkOS!\n\nThis pad text is "
             "synchronized as you type, so that everyone viewing this page "
             "sees the same text. This allows you to collaborate seamlessly "
             "on documents!\n\nGet involved with Etherpad at "
             "http://etherpad.org, or with arkOS at http://arkos.io\n"),
            "requireSession":
            False,
            "editOnly":
            False,
            "minify":
            True,
            "maxAge":
            60 * 60 * 6,
            "abiword":
            None,
            "requireAuthentication":
            False,
            "requireAuthorization":
            False,
            "trustProxy":
            True,
            "disableIPlogging":
            False,
            "socketTransportProtocols":
            ["xhr-polling", "jsonp-polling", "htmlfile"],
            "loglevel":
            "INFO",
            "logconfig": {
                "appenders": [{
                    "type": "console"
                }]
            },
            "users": {
                vars.getvalue('ether_admin'): {
                    "password": vars.getvalue('ether_pass'),
                    "is_admin": True
                },
            },
        }
        with open(os.path.join(path, 'settings.json'), 'w') as f:
            json.dump(cfg, f, indent=4)

        # node-gyp needs the HOME variable to be set
        with open(os.path.join(path, 'bin/run.sh')) as f:
            run_script = f.readlines()
        run_script.insert(1, "export HOME=%s" % path)
        with open(os.path.join(path, 'bin/run.sh'), 'w') as f:
            f.writelines(run_script)

        # Install deps right away
        if not shell(os.path.join(path, 'bin/installDeps.sh') + ' || exit 1'):
            raise RuntimeError("Etherpad dependencies could not be installed.")

        # Install selected plugins
        mods = list(  # e.g. "ep_plugin/ep_adminpads"
            str(var).split("/")[1]  #                 ^^^^^^^^^^^^
            for var in vars
            if var.startswith('ep_plugin/') and int(vars.getvalue(var)))
        if mods:
            mod_inst_path = os.path.join(path, "node_modules")
            if not os.path.exists(mod_inst_path):
                os.mkdir(mod_inst_path)
            nodectl = apis.langassist(self.app).get_interface('NodeJS')
            nodectl.install(*mods, install_path=mod_inst_path)

        # Make supervisor entry
        s = self.app.get_backend(apis.services.IServiceManager)
        s.edit(
            'etherpad', {
                'stype': 'program',
                'directory': path,
                'user': '******',
                'command': os.path.join(path, 'bin/run.sh'),
                'autostart': 'true',
                'autorestart': 'true',
                'stdout_logfile': '/var/log/etherpad.log',
                'stderr_logfile': '/var/log/etherpad.log'
            })
        s.enable('etherpad', 'supervisor')

        # Change owner of everything in the etherpad path
        shell('chown -R etherpad ' + path)
        #TODO: user auth with nginx??

    def pre_remove(self, site):
        pass

    def post_remove(self, site):
        UsersBackend(self.app).del_user('etherpad')
        self.app.get_backend(apis.services.IServiceManager).delete(
            'etherpad', 'supervisor')

    def ssl_enable(self, path, cfile, kfile):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s' % name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                self.addtoblock[0].add(
                    nginx.Key('proxy_set_header',
                              'X-Forwarded-For $proxy_add_x_forwarded_for'),
                    nginx.Key('proxy_set_header', 'X-Forwarded-Proto $scheme'),
                )
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s' % name)

    def ssl_disable(self, path):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s' % name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s' % name)
コード例 #9
0
    def _install(self, extra_vars, enable, nthread):
        nthread.title = "Installing website"

        msg = Notification("info", "Webs", "Preparing to install...")
        nthread.update(msg)

        # Make sure the chosen port is indeed open
        if not tracked_services.is_open_port(self.port, self.domain):
            cname = "({0})".format(self.app.id)
            raise errors.InvalidConfigError(cname, nthread)\
                from tracked_services.PortConflictError(self.port, self.domain)

        # Set some metadata values
        specialmsg, dbpasswd = "", ""
        site_dir = config.get("websites", "site_dir")
        path = (self.path or os.path.join(site_dir, self.id))
        self.path = path
        self.php = extra_vars.get("php") or self.php \
            or self.app.uses_php or False
        self.version = self.app.version.rsplit("-", 1)[0] \
            if self.app.website_updates else None

        # Classify the source package type
        if not self.app.download_url:
            ending = ""
        elif self.app.download_url.endswith(".tar.gz"):
            ending = ".tar.gz"
        elif self.app.download_url.endswith(".tgz"):
            ending = ".tgz"
        elif self.app.download_url.endswith(".tar.bz2"):
            ending = ".tar.bz2"
        elif self.app.download_url.endswith(".zip"):
            ending = ".zip"
        elif self.app.download_url.endswith(".git"):
            ending = ".git"
        else:
            raise errors.InvalidConfigError(
                "Invalid source archive format in {0}".format(self.app.id))

        msg = "Running pre-installation..."
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        nthread.update(Notification("info", "Webs", msg))

        # Call website type's pre-install hook
        self.pre_install(extra_vars)

        # If needs DB and user didn't select an engine, choose one for them
        if len(self.app.database_engines) > 1 \
                and extra_vars.get("dbengine", None):
            self.app.selected_dbengine = extra_vars.get("dbengine")
        if not getattr(self.app, "selected_dbengine", None)\
                and self.app.database_engines:
            self.app.selected_dbengine = self.app.database_engines[0]

        # Create DB and/or DB user as necessary
        if getattr(self.app, "selected_dbengine", None):
            msg = "Creating database..."
            nthread.update(Notification("info", "Webs", msg))
            mgr = databases.get_managers(self.app.selected_dbengine)
            if not mgr:
                estr = "No manager found for {0}"
                raise errors.InvalidConfigError(
                    estr.format(self.app.selected_dbengine))
            # Make sure DB daemon is running if it has one
            if not mgr.state:
                svc = services.get(mgr.meta.database_service)
                svc.restart()
            self.db = mgr.add_db(self.id)
            if hasattr(self.db, "path"):
                os.chmod(self.db.path, 0o660)
                os.chown(self.db.path, -1, gid)
            # If multiuser DB type, create user
            if mgr.meta.database_multiuser:
                dbpasswd = random_string(16)
                db_user = mgr.add_user(self.id, dbpasswd)
                db_user.chperm("grant", self.db)

        # Make sure the target directory exists, but is empty
        pkg_path = os.path.join("/tmp", self.id + ending)
        if os.path.isdir(self.path):
            shutil.rmtree(self.path)
        os.makedirs(self.path)

        # Download and extract the source repo / package
        msg = "Downloading website source..."
        nthread.update(Notification("info", "Webs", msg))
        if self.app.download_url and ending == ".git":
            g = git.Repo.clone_from(self.app.download_url, self.path)
            if hasattr(self.app, "download_at_tag"):
                g = git.Git(self.path)
                g.checkout(self.app.download_git_tag)
        elif self.app.download_url:
            download(self.app.download_url, file=pkg_path, crit=True)

            # Format extraction command according to type
            msg = "Extracting source..."
            nthread.update(Notification("info", "Webs", msg))
            if ending in [".tar.gz", ".tgz", ".tar.bz2"]:
                arch = tarfile.open(pkg_path, "r:gz")
                r = (x for x in arch.getnames() if re.match("^[^/]*$", x))
                toplvl = next(r, None)
                if not toplvl:
                    raise errors.OperationFailedError(
                        "Malformed source archive")
                arch.extractall(site_dir)
                os.rename(os.path.join(site_dir, toplvl), self.path)
            else:
                arch = zipfile.ZipFile(pkg_path)
                r = (x for x in arch.namelist() if re.match("^[^/]*/$", x))
                toplvl = next(r, None)
                if not toplvl:
                    raise errors.OperationFailedError(
                        "Malformed source archive")
                arch.extractall(site_dir)
                os.rename(os.path.join(site_dir, toplvl.rstrip("/")),
                          self.path)
            os.remove(pkg_path)

        # Set proper starting permissions on source directory
        os.chmod(self.path, 0o755)
        os.chown(self.path, uid, gid)
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chmod(os.path.join(r, x), 0o755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0o644)
                os.chown(os.path.join(r, x), uid, gid)

        # If there is a custom path for the data directory, set it up
        if getattr(self.app, "website_datapaths", None) \
                and extra_vars.get("datadir"):
            self.data_path = extra_vars["datadir"]
            if not os.path.exists(self.data_path):
                os.makedirs(self.data_path)
            os.chmod(self.data_path, 0o755)
            os.chown(self.data_path, uid, gid)
        elif hasattr(self, "website_default_data_subdir"):
            self.data_path = os.path.join(self.path,
                                          self.website_default_data_subdir)
        else:
            self.data_path = self.path

        # Create the nginx serverblock
        addtoblock = self.addtoblock or []
        if extra_vars.get("addtoblock"):
            addtoblock += nginx.loads(extra_vars.get("addtoblock"), False)
        default_index = "index." + ("php" if self.php else "html")
        if hasattr(self.app, "website_root"):
            webroot = os.path.join(self.path, self.app.website_root)
        else:
            webroot = self.path
        block = nginx.Conf()
        server = nginx.Server(
            nginx.Key("listen", str(self.port)),
            nginx.Key("listen", "[::]:" + str(self.port)),
            nginx.Key("server_name", self.domain), nginx.Key("root", webroot),
            nginx.Key(
                "index",
                getattr(self.app, "website_index", None) or default_index),
            nginx.Location("/.well-known/acme-challenge/",
                           nginx.Key("root", self.path)))
        if addtoblock:
            server.add(*[x for x in addtoblock])
        block.add(server)
        nginx.dumpf(block, os.path.join("/etc/nginx/sites-available", self.id))
        challenge_dir = os.path.join(self.path, ".well-known/acme-challenge/")
        if not os.path.exists(challenge_dir):
            os.makedirs(challenge_dir)

        # Create arkOS metadata file
        meta = configparser.SafeConfigParser()
        meta.add_section("website")
        meta.set("website", "id", self.id)
        meta.set("website", "app", self.app.id)
        meta.set("website", "ssl",
                 self.cert.id if getattr(self, "cert", None) else "None")
        meta.set("website", "version", self.version or "None")
        if getattr(self.app, "website_datapaths", None) \
                and self.data_path:
            meta.set("website", "data_path", self.data_path)
        meta.set("website", "dbengine", "")
        meta.set("website", "dbengine",
                 getattr(self.app, "selected_dbengine", ""))
        with open(os.path.join(self.path, ".arkos"), "w") as f:
            meta.write(f)

        # Call site type's post-installation hook
        msg = "Running post-installation. This may take a few minutes..."
        nthread.update(Notification("info", "Webs", msg))
        specialmsg = self.post_install(extra_vars, dbpasswd)

        # Cleanup and reload daemons
        msg = "Finishing..."
        nthread.update(Notification("info", "Webs", msg))
        self.installed = True
        storage.websites[self.id] = self
        if self.port == 80:
            cleanup_acme_dummy(self.domain)
        signals.emit("websites", "site_installed", self)
        if enable:
            self.nginx_enable()
        if enable and self.php:
            php.open_basedir("add", "/srv/http/")
            php_reload()

        msg = "{0} site installed successfully".format(self.app.name)
        nthread.complete(Notification("success", "Webs", msg))
        if specialmsg:
            return specialmsg
コード例 #10
0
def start(args):
	
	global path
	global conPicDict
	global firstTimeNginx
	global firstTimeNetcat

	processDocker = subprocess.Popen(["docker", "start"]+ [args[1]], stdout = subprocess.PIPE)

	output = processDocker.communicate()

	#get the image_name and the Cmds
	processCmd = subprocess.Popen(["docker", "inspect" ,"-f","'{{.Config.Cmd}}'", ""+ args[1]], stdout = subprocess.PIPE)

	cmd = processCmd.communicate()[0]
	cmd = cmd.split("'")[1]
	processImageName = subprocess.Popen(["docker", "inspect" ,"-f","'{{.Config.Image}}'", ""+ args[1]], stdout = subprocess.PIPE)

	imageName = processImageName.communicate()[0]
	imageName = imageName.split("'")[1]

	#conPicDict[args[1]] = ["docker","start"] + [args[1]]
	conPicDict[args[1]] = [imageName,cmd] + [args[1]]
	#args[1] is gonna be the worker name, ex: worker1

	isNginx = False

	if(imageName == 'nginx:alpine'):

		isNginx = True

	#if both firstimes are false we add the server to both upstreams so it runs


	c = nginx.loadf(path+'/load-balancer/nginx.conf')
	HttpFilter = ((c.filter('Http')[0]))

	if(isNginx):

		if(firstTimeNginx == False):

			#make upstream make worker add worker to upstream add upstream
			#to the http
			nginxUpstream = nginx.Upstream('nginx')
			worker = nginx.Key('server', args[1]+":80")
			nginxUpstream.add(worker)
			HttpFilter.add(nginxUpstream)

			#when we make upstream for first time we also make server server
			s = nginx.Server()
			s.add(nginx.Key('listen','8100'),nginx.Location('/' , nginx.Key('proxy_pass','http://nginx'), nginx.Key('proxy_redirect','off'),nginx.Key('proxy_set_header','Host $host'), nginx.Key('proxy_set_header','X-Real_IP $remote_addr'), nginx.Key('proxy_set_header','X-Forwarded-For $proxy_add_x_forwarded_for'), nginx.Key('proxy_set_header','X-Forwarded-Host $server_name')))
			HttpFilter.add(s)
			#dumping
			firstTimeNginx = True

			nginx.dumpf(c, path+'/load-balancer/nginx.conf')
		else:
			
			upstreamSearch = HttpFilter.filter('Upstream')
			j = 0
			found = False
			for key in upstreamSearch:
				if(((key.as_dict).keys())[0] == 'upstream nginx'):
					found = True		
					break
				j = j + 1

			worker = nginx.Key('server', args[1]+":80")
			if(found):
				upstreamSearch[j].add(worker)

			nginx.dumpf(c, path+'/load-balancer/nginx.conf')

	else:

		if(firstTimeNetcat == False):

			#make upstream make worker add worker to upstream add upstream
			#to the http
			nginxUpstream = nginx.Upstream('netcat')
			worker = nginx.Key('server', args[1]+":80")
			nginxUpstream.add(worker)
			HttpFilter.add(nginxUpstream)

			#when we make upstream for first time we also make server server
			s = nginx.Server()
			s.add(nginx.Key('listen','8101'),nginx.Location('/' , nginx.Key('proxy_pass','http://netcat'), nginx.Key('proxy_redirect','off'),nginx.Key('proxy_set_header','Host $host'), nginx.Key('proxy_set_header','X-Real_IP $remote_addr'), nginx.Key('proxy_set_header','X-Forwarded-For $proxy_add_x_forwarded_for'), nginx.Key('proxy_set_header','X-Forwarded-Host $server_name')))
			HttpFilter.add(s)
			#dumping
			firstTimeNetcat = True

			nginx.dumpf(c, path+'/load-balancer/nginx.conf')
		else:
			
			upstreamSearch = HttpFilter.filter('Upstream')
			j = 0
			found = False
			for key in upstreamSearch:
				if(((key.as_dict).keys())[0] == 'upstream netcat'):
					found = True		
					break
				j = j + 1

			worker = nginx.Key('server', args[1]+":80")
			if(found):
				upstreamSearch[j].add(worker)

			nginx.dumpf(c, path+'/load-balancer/nginx.conf')

	#now kill,rm,build,run
	loadBalReset()
コード例 #11
0
def run(args):

	global conPicDict
	global workerCounter
	global firstTimeNginx
	global firstTimeNetcat
	global path

	#args[1] is image name
	#args[2] is container name
	#args[3]+ is the commands
	processDocker = subprocess.Popen(["docker","run","--name", "worker"+str(workerCounter)] + args[1:], stdout = subprocess.PIPE)

	output = processDocker.communicate()

	#connect container to network bridge conNet

	processNetConnect = subprocess.Popen(["docker","network","connect", "conNet","worker"+str(workerCounter)], stdout = subprocess.PIPE)

	output = processNetConnect.communicate()

	#get the image_name and the Cmds
	processCmd = subprocess.Popen(["docker", "inspect" ,"-f","'{{.Config.Cmd}}'", "worker"+str(workerCounter)], stdout = subprocess.PIPE)

	cmd = processCmd.communicate()[0]

	
	cmd = cmd.split("'")[1]
	processImageName = subprocess.Popen(["docker", "inspect" ,"-f","'{{.Config.Image}}'", "worker"+str(workerCounter)], stdout = subprocess.PIPE)

	imageName = processImageName.communicate()[0]
	imageName = imageName.split("'")[1]

	conPicDict["worker"+str(workerCounter)] = [imageName,cmd] + ["worker"+str(workerCounter)]

	conPicDict['count'] = workerCounter

	#everytime we run a container we add it to the load balancer by editing
	#the nginx.conf file then we have to kill, rm, rebuild and rerun loadBal


	#checks if its nginx or netcat(anything else)
	isNginx = False

	if(imageName == 'nginx:alpine'):

		isNginx = True

	#if both firstimes are false we add the server to both upstreams so it runs


	c = nginx.loadf(path+'/load-balancer/nginx.conf')
	HttpFilter = ((c.filter('Http')[0]))

	if(isNginx):

		if(firstTimeNginx == False):

			#make upstream make worker add worker to upstream add upstream
			#to the http
			nginxUpstream = nginx.Upstream('nginx')
			worker = nginx.Key('server', "worker"+str(workerCounter)+":80")
			nginxUpstream.add(worker)
			HttpFilter.add(nginxUpstream)

			#when we make upstream for first time we also make server server
			s = nginx.Server()
			s.add(nginx.Key('listen','8100'),nginx.Location('/' , nginx.Key('proxy_pass','http://nginx'), nginx.Key('proxy_redirect','off'),nginx.Key('proxy_set_header','Host $host'), nginx.Key('proxy_set_header','X-Real_IP $remote_addr'), nginx.Key('proxy_set_header','X-Forwarded-For $proxy_add_x_forwarded_for'), nginx.Key('proxy_set_header','X-Forwarded-Host $server_name')))
			HttpFilter.add(s)
			#dumping
			firstTimeNginx = True

			nginx.dumpf(c, path+'/load-balancer/nginx.conf')
		else:
			
			upstreamSearch = HttpFilter.filter('Upstream')
			j = 0
			found = False
			for key in upstreamSearch:
				if(((key.as_dict).keys())[0] == 'upstream nginx'):
					found = True		
					break
				j = j + 1

			worker = nginx.Key('server', "worker"+str(workerCounter)+":80")
			if(found):
				upstreamSearch[j].add(worker)

			nginx.dumpf(c, path+'/load-balancer/nginx.conf')

	else:

		if(firstTimeNetcat == False):

			#make upstream make worker add worker to upstream add upstream
			#to the http
			nginxUpstream = nginx.Upstream('netcat')
			worker = nginx.Key('server', "worker"+str(workerCounter)+":80")
			nginxUpstream.add(worker)
			HttpFilter.add(nginxUpstream)

			#when we make upstream for first time we also make server server
			s = nginx.Server()
			s.add(nginx.Key('listen','8101'),nginx.Location('/' , nginx.Key('proxy_pass','http://netcat'), nginx.Key('proxy_redirect','off'),nginx.Key('proxy_set_header','Host $host'), nginx.Key('proxy_set_header','X-Real_IP $remote_addr'), nginx.Key('proxy_set_header','X-Forwarded-For $proxy_add_x_forwarded_for'), nginx.Key('proxy_set_header','X-Forwarded-Host $server_name')))
			HttpFilter.add(s)
			#dumping
			firstTimeNetcat = True

			nginx.dumpf(c, path+'/load-balancer/nginx.conf')
		else:
			
			upstreamSearch = HttpFilter.filter('Upstream')
			j = 0
			found = False
			for key in upstreamSearch:
				if(((key.as_dict).keys())[0] == 'upstream netcat'):
					found = True		
					break
				j = j + 1

			worker = nginx.Key('server', "worker"+str(workerCounter)+":80")
			if(found):
				upstreamSearch[j].add(worker)

			nginx.dumpf(c, path+'/load-balancer/nginx.conf')



	#now kill,rm,build,run
	loadBalReset()

	#increment workerCounter
	workerCounter = workerCounter + 1
コード例 #12
0
import nginx
from settings import Settings

settings = Settings('settings.yml')

project_name = settings.get('project_name')

nginx_settings = settings.get('nginx')

listen = nginx_settings.get('listen')
server_name = nginx_settings.get('server_name')
location = nginx_settings.get('location')
include = nginx_settings.get('location_keys').get('include')
uwsgi_pass = nginx_settings.get('location_keys').get('uwsgi_pass')
uwsgi_pass = uwsgi_pass.replace('{{project_name}}', project_name)

c = nginx.Conf()
s = nginx.Server()
s.add(
    nginx.Key('listen', listen),
    #nginx.Comment('Yes, python-nginx can read/write comments!'),
    nginx.Key('server_name', server_name),
    nginx.Location(
        location,
        nginx.Key('include', include),
        nginx.Key('uwsgi_pass', uwsgi_pass),
    ))
c.add(s)
nginx.dumpf(c, 'test/' + project_name)
コード例 #13
0
ファイル: website.py プロジェクト: wrestrtdr/applications
class Paperword(Site):
    addtoblock = [
        nginx.Location('= /favicon.ico', nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Key('try_files', '$uri $uri/ @rewrite'),
        nginx.Location('@rewrite',
                       nginx.Key('rewrite', '^/(.*)$ /index.php?_url=/$1')),
        nginx.Location(
            '~ \.php$',
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_index', 'index.php'),
            nginx.Key('include', 'fastcgi_params'),
            nginx.Key('fastcgi_split_path_info', '^(.+\.php)(/.+)$'),
            nginx.Key('fastcgi_param', 'PATH_INFO $fastcgi_path_info'),
            nginx.Key('fastcgi_param', 'PATH_TRANSLATED '
                      '$document_root$fastcgi_path_info'),
            nginx.Key('fastcgi_param', 'SCRIPT_FILENAME '
                      '$document_root$fastcgi_script_name')),
        nginx.Location('~ /\.ht', nginx.Key('deny', 'all'))
    ]

    def pre_install(self, extra_vars):
        pass

    def post_install(self, extra_vars, dbpasswd=""):
        # Get around top-level zip restriction (FIXME 0.7.2)
        if "paperwork-master" in os.listdir(self.path):
            tmp_path = os.path.abspath(os.path.join(self.path, "../pwrk-tmp"))
            os.rename(os.path.join(self.path, "paperwork-master/frontend"),
                      tmp_path)
            os.rename(os.path.join(self.path, ".arkos"),
                      os.path.join(tmp_path, ".arkos"))
            shutil.rmtree(self.path)
            os.rename(tmp_path, self.path)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('gd', 'opcache', 'mysql', 'pdo_mysql', 'mcrypt')
        php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        dbstr = "mysql, localhost, 3389, {0}, {1}, {0}"\
            .format(self.id, dbpasswd)
        with open(os.path.join(self.path, 'app/storage/db_settings'),
                  'w') as f:
            f.write(dbstr)

        php.composer_install(self.path)
        nodejs.install("gulp", as_global=True)
        nodejs.install_from_package(self.path, stat=None)

        cwd = os.getcwd()
        os.chdir(self.path)
        s = shell("bower install --allow-root", stdin='y\n')
        if s["code"] != 0:
            raise Exception("Failed to run bower: {0}".format(s["stderr"]))
        s = shell("gulp")
        if s["code"] != 0:
            raise Exception("Failed to run gulp: {0}".format(s["stderr"]))
        s = shell("php artisan migrate --force")
        if s["code"] != 0:
            raise Exception("Failed to run artisan: {0}".format(s["stderr"]))
        os.chdir(cwd)

        # Make sure the webapps config points to the public directory.
        c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id))
        for x in c.servers:
            if x.filter('Key', 'root'):
                x.filter('Key', 'root')[0].value = \
                    os.path.join(self.path, 'public')
        nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id))
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(os.path.join(self.path, 'app')):
            for x in d:
                os.chmod(os.path.join(r, x), 0o755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0o644)
                os.chown(os.path.join(r, x), uid, gid)
        if os.path.exists(os.path.join(self.path, 'app/storage/setup')):
            os.unlink(os.path.join(self.path, 'app/storage/setup'))

    def pre_remove(self):
        pass

    def post_remove(self):
        pass

    def enable_ssl(self, cfile, kfile):
        pass

    def disable_ssl(self):
        pass

    def site_edited(self):
        pass

    def update(self, pkg, ver):
        pass
コード例 #14
0
class WordPress(Site):
    addtoblock = [
        nginx.Location(
            '= /favicon.ico',
            nginx.Key('log_not_found', 'off'),
            nginx.Key('access_log', 'off')
        ),
        nginx.Location(
            '= /robots.txt',
            nginx.Key('allow', 'all'),
            nginx.Key('log_not_found', 'off'),
            nginx.Key('access_log', 'off')
        ),
        nginx.Location(
            '/',
            nginx.Key('try_files', '$uri $uri/ /index.php?$args')
        ),
        nginx.Location(
            '~ \.php$',
            nginx.Key('fastcgi_pass',
                      'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_index', 'index.php'),
            nginx.Key('include', 'fastcgi.conf')
        ),
        nginx.Location(
            '~* \.(js|css|png|jpg|jpeg|gif|ico)$',
            nginx.Key('expires', 'max'),
            nginx.Key('log_not_found', 'off')
        )]

    def pre_install(self, extra_vars):
        pass

    def post_install(self, extra_vars, dbpasswd=""):
        secret_key = random_string()

        # Use the WordPress key generators as first option
        # If connection fails, use the secret_key as fallback
        try:
            keysection = requests.get(
                'https://api.wordpress.org/secret-key/1.1/salt/').text
        except:
            keysection = ''
        if 'define(\'AUTH_KEY' not in keysection:
            keysection = (
                'define(\'AUTH_KEY\', \'{0}\');\n'
                'define(\'SECURE_AUTH_KEY\', \'{0}\');\n'
                'define(\'LOGGED_IN_KEY\', \'{0}\');\n'
                'define(\'NONCE_KEY\', \'{0}\');\n'.format(secret_key)
                )

        # Write a standard WordPress config file
        with open(os.path.join(self.path, 'wp-config.php'), 'w') as f:
            f.write('<?php\n'
                    'define(\'DB_NAME\', \'{0}\');\n'
                    'define(\'DB_USER\', \'{0}\');\n'
                    'define(\'DB_PASSWORD\', \'{1}\');\n'
                    'define(\'DB_HOST\', \'localhost\');\n'
                    'define(\'DB_CHARSET\', \'utf8\');\n'
                    'define(\'SECRET_KEY\', \'{2}\');\n'
                    '\n'
                    'define(\'WP_CACHE\', true);\n'
                    'define(\'FORCE_SSL_ADMIN\', false);\n'
                    '\n'
                    '{3}'
                    '\n'
                    '$table_prefix = \'wp_\';\n'
                    '\n'
                    '/** Absolute path to the WordPress directory. */\n'
                    'if ( !defined(\'ABSPATH\') )\n'
                    '   define(\'ABSPATH\', dirname(__FILE__) . \'/\');\n'
                    '\n'
                    '/** Sets up WordPress vars and included files. */\n'
                    'require_once(ABSPATH . \'wp-settings.php\');\n'
                    .format(self.db.id, dbpasswd, secret_key, keysection)
                    )

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysqli', 'opcache')
        php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        # Finally, make sure that permissions are set so that Wordpress
        # can make adjustments and save plugins when need be.
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)

    def pre_remove(self):
        pass

    def post_remove(self):
        pass

    def enable_ssl(self, cfile, kfile):
        with open(os.path.join(self.path, 'wp-config.php'), 'r') as f:
            ic = f.readlines()
        oc = []
        found = False
        for l in ic:
            if 'define(\'FORCE_SSL_ADMIN\'' in l:
                l = 'define(\'FORCE_SSL_ADMIN\', false);\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found is False:
            oc.append('define(\'FORCE_SSL_ADMIN\', true);\n')
        with open(os.path.join(self.path, 'wp-config.php'), 'w') as f:
            f.writelines(oc)

    def disable_ssl(self):
        with open(os.path.join(self.path, 'wp-config.php'), 'r') as f:
            ic = f.readlines()
        oc = []
        found = False
        for l in ic:
            if 'define(\'FORCE_SSL_ADMIN\'' in l:
                l = 'define(\'FORCE_SSL_ADMIN\', false);\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found is False:
            oc.append('define(\'FORCE_SSL_ADMIN\', false);\n')
        with open(os.path.join(self.path, 'wp-config.php'), 'w') as f:
            f.writelines(oc)

    def site_edited(self):
        if not self.db:
            return
        url = "http"
        url += ("s://" if self.cert else "://")
        url += self.addr
        url += ((":"+str(self.port)) if self.port not in [80, 443] else "")
        self.db.execute("UPDATE wp_options SET option_value = '{0}' "
                        "WHERE option_name = 'siteurl';"
                        .format(url), commit=True)
        self.db.execute("UPDATE wp_options SET option_value = '{0}' "
                        "WHERE option_name = 'home';".format(url), commit=True)
コード例 #15
0
ファイル: backend.py プロジェクト: ardnet/genesis
 def setup(self, addr, port):
     # Make sure Radicale is installed and ready
     pyctl = apis.langassist(self.app).get_interface('Python')
     users = UsersBackend(self.app)
     if not pyctl.is_installed('Radicale'):
         pyctl.install('radicale')
     # due to packaging bugs, make extra sure perms are readable
     st = os.stat('/usr/lib/python2.7/site-packages/radicale')
     for r, d, f in os.walk('/usr/lib/python2.7/site-packages/radicale'):
         for x in d:
             os.chmod(os.path.join(r, x),
                      st.st_mode | stat.S_IROTH | stat.S_IRGRP)
         for x in f:
             os.chmod(os.path.join(r, x),
                      st.st_mode | stat.S_IROTH | stat.S_IRGRP)
     if not os.path.exists('/etc/radicale/config'):
         if not os.path.isdir('/etc/radicale'):
             os.mkdir('/etc/radicale')
         open('/etc/radicale/config', 'w').write(self.default_config)
     if not os.path.isdir('/usr/lib/radicale'):
         os.mkdir('/usr/lib/radicale')
     # Add the site process
     users.add_user('radicale')
     users.add_group('radicale')
     users.add_to_group('radicale', 'radicale')
     wsgi_file = 'import radicale\n'
     wsgi_file += 'radicale.log.start()\n'
     wsgi_file += 'application = radicale.Application()\n'
     open('/etc/radicale/radicale.wsgi', 'w').write(wsgi_file)
     os.chmod('/etc/radicale/radicale.wsgi', 0766)
     s = self.app.get_backend(apis.services.IServiceManager)
     s.edit(
         'radicale', {
             'stype': 'program',
             'directory': '/etc/radicale',
             'user': '******',
             'command':
             'uwsgi -s /tmp/radicale.sock -C --plugin python2 --wsgi-file radicale.wsgi',
             'stdout_logfile': '/var/log/radicale.log',
             'stderr_logfile': '/var/log/radicale.log'
         })
     s.enable('radicale', 'supervisor')
     block = [
         nginx.Location(
             '/',
             nginx.Key('auth_basic',
                       '"Genesis Calendar Server (Radicale)"'),
             nginx.Key('auth_basic_user_file', '/etc/radicale/users'),
             nginx.Key('include', 'uwsgi_params'),
             nginx.Key('uwsgi_pass', 'unix:///tmp/radicale.sock'),
         )
     ]
     if not os.path.exists('/etc/radicale/users'):
         open('/etc/radicale/users', 'w').write('')
         os.chmod('/etc/radicale/users', 0766)
     WebappControl(self.app).add_reverse_proxy('radicale',
                                               '/usr/lib/radicale', addr,
                                               port, block)
     apis.networkcontrol(self.app).add_webapp(
         ('radicale', 'ReverseProxy', port))
     c = self.app.get_config(RadicaleConfig(self.app))
     c.first_run_complete = True
     c.save()
コード例 #16
0
    def _ssl_enable(self):
        # Get server-preferred ciphers
        if config.get("certificates", "ciphers"):
            ciphers = config.get("certificates", "ciphers")
        else:
            config.set("certificates", "ciphers", ciphers)
            config.save()

        block = nginx.loadf(
            os.path.join("/etc/nginx/sites-available/", self.id))

        # If the site is on port 80, setup an HTTP redirect to new port 443
        server = block.server
        listens = server.filter("Key", "listen")
        for listen in listens:
            httport = "80"
            sslport = "443"
            if listen.value.startswith("[::]"):
                # IPv6
                httport = "[::]:80"
                sslport = "[::]:443"
            if listen.value == httport:
                listen.value = (sslport + " ssl http2")
                block.add(
                    nginx.Server(
                        nginx.Key("listen", httport),
                        nginx.Key("server_name", self.domain),
                        nginx.Location(
                            "/",
                            nginx.Key("return",
                                      "301 https://$host$request_uri")),
                        nginx.Location("/.well-known/acme-challenge/",
                                       nginx.Key("root", self.path))))
                for x in block.servers:
                    if " ssl" in x.filter("Key", "listen")[0].value:
                        server = x
                        break
            else:
                listen.value = listen.value.split(" ssl")[0] + " ssl http2"

        # Clean up any pre-existing SSL directives that no longer apply
        to_remove = [x for x in server.keys if x.name.startswith("ssl_")]
        server.remove(*to_remove)

        # Add the necessary SSL directives to the serverblock and save
        server.add(
            nginx.Key("ssl_certificate", self.cert.cert_path),
            nginx.Key("ssl_certificate_key", self.cert.key_path),
            nginx.Key("ssl_protocols", "TLSv1 TLSv1.1 TLSv1.2"),
            nginx.Key("ssl_ciphers", ciphers),
            nginx.Key("ssl_session_timeout", "5m"),
            nginx.Key("ssl_prefer_server_ciphers", "on"),
            nginx.Key("ssl_dhparam", "/etc/arkos/ssl/dh_params.pem"),
            nginx.Key("ssl_session_cache", "shared:SSL:50m"),
        )
        nginx.dumpf(block, os.path.join("/etc/nginx/sites-available/",
                                        self.id))

        # Set the certificate name in the metadata file
        if not os.path.exists(os.path.join(self.path, ".arkos")):
            raise errors.InvalidConfigError("Could not find metadata file")
        meta = configparser.SafeConfigParser()
        meta.read(os.path.join(self.path, ".arkos"))
        meta.set("website", "ssl", self.cert.id)
        with open(os.path.join(self.path, ".arkos"), "w") as f:
            meta.write(f)

        # Call the website type's SSL enable hook
        self.enable_ssl(self.cert.cert_path, self.cert.key_path)
コード例 #17
0
ファイル: main.py プロジェクト: tewe/genesis
class Wallabag(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = [
        nginx.Location('~ /(db)', nginx.Key('deny', 'all'),
                       nginx.Key('return', '404')),
        nginx.Location('= /favicon.ico', nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('/',
                       nginx.Key('try_files', '$uri $uri/ /index.php?$args')),
        nginx.Location(
            '~ \.php$',
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_index', 'index.php'),
            nginx.Key('include', 'fastcgi.conf')),
        nginx.Location('~* \.(js|css|png|jpg|jpeg|gif|ico)$',
                       nginx.Key('expires', 'max'),
                       nginx.Key('log_not_found', 'off'))
    ]

    def pre_install(self, name, vars):
        dbname = vars.getvalue('wb-dbname', '')
        dbpasswd = vars.getvalue('wb-dbpasswd', '')
        if dbname and dbpasswd:
            apis.databases(self.app).get_interface('MariaDB').validate(
                dbname, dbname, dbpasswd)
        elif dbname:
            raise Exception(
                'You must enter a database password if you specify a database name!'
            )
        elif dbpasswd:
            raise Exception(
                'You must enter a database name if you specify a database password!'
            )

    def post_install(self, name, path, vars):
        # Get the database object, and determine proper values
        phpctl = apis.langassist(self.app).get_interface('PHP')
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        if vars.getvalue('wb-dbname', '') == '':
            dbname = name
        else:
            dbname = vars.getvalue('wb-dbname')
        secret_key = hashlib.sha1(str(random.random())).hexdigest()
        if vars.getvalue('wb-dbpasswd', '') == '':
            passwd = secret_key[0:8]
        else:
            passwd = vars.getvalue('wb-dbpasswd')

        # Request a database and user to interact with it
        dbase.add(dbname, conn)
        dbase.usermod(dbname, 'add', passwd, conn)
        dbase.chperm(dbname, dbname, 'grant', conn)

        # Write a standard Wallabag config file
        shutil.copy(os.path.join(path, 'inc/poche/config.inc.php.new'),
                    os.path.join(path, 'inc/poche/config.inc.php'))
        ic = open(os.path.join(path, 'inc/poche/config.inc.php'),
                  'r').readlines()
        f = open(os.path.join(path, 'inc/poche/config.inc.php'), 'w')
        oc = []
        for l in ic:
            if 'define (\'SALT\'' in l:
                l = 'define (\'SALT\', \'' + secret_key + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE\'' in l:
                l = 'define (\'STORAGE\', \'mysql\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_DB\'' in l:
                l = 'define (\'STORAGE_DB\', \'' + dbname + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_USER\'' in l:
                l = 'define (\'STORAGE_USER\', \'' + dbname + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_PASSWORD\'' in l:
                l = 'define (\'STORAGE_PASSWORD\', \'' + passwd + '\');\n'
                oc.append(l)
            else:
                oc.append(l)
        f.writelines(oc)
        f.close()

        # Make sure that the correct PHP settings are enabled
        phpctl.enable_mod('mysql', 'pdo_mysql', 'zip', 'tidy', 'xcache',
                          'openssl')

        # Set up Composer and install the proper modules
        phpctl.composer_install(path)

        # Finish setting up the database then delete the install folder
        dbase.execute(dbname,
                      open(os.path.join(path, 'install/mysql.sql')).read(),
                      conn)
        shutil.rmtree(os.path.join(path, 'install'))

        # Finally, make sure that permissions are set so that Poche
        # can make adjustments and save plugins when need be.
        shell('chmod -R 755 ' + os.path.join(path, 'assets/') + ' ' +
              os.path.join(path, 'cache/') + ' ' + os.path.join(path, 'db/'))
        shell('chown -R http:http ' + path)

    def pre_remove(self, name, path):
        f = open(os.path.join(path, 'inc/poche/config.inc.php'), 'r')
        for line in f.readlines():
            if 'STORAGE_DB' in line:
                data = line.split('\'')[1::2]
                dbname = data[1]
                break
        f.close()
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        dbase.remove(dbname, conn)
        dbase.usermod(dbname, 'del', '', conn)

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        pass

    def ssl_disable(self, path):
        pass
コード例 #18
0
    def _edit(self, newname):
        site_dir = config.get("websites", "site_dir")
        block = nginx.loadf(os.path.join("/etc/nginx/sites-available",
                                         self.id))

        # If SSL is enabled and the port is changing to 443,
        # create the port 80 redirect
        server = block.server
        if self.cert and self.port == 443:
            for x in block.servers:
                if "443 ssl" in x.filter("Key", "listen")[0].value:
                    server = x
            if self.port != 443:
                for x in block.servers:
                    if "ssl" not in x.filter("Key", "listen")[0].value\
                            and x.filter("key", "return"):
                        block.remove(x)
        elif self.port == 443:
            block.add(
                nginx.Server(
                    nginx.Key("listen", "80"), nginx.Key("listen", "[::]:80"),
                    nginx.Key("server_name", self.domain),
                    nginx.Location(
                        "/",
                        nginx.Key("return", "301 https://$host$request_uri")),
                    nginx.Location("/.well-known/acme-challenge/",
                                   nginx.Key("root", self.path))))

        # If the name was changed...
        if newname and self.id != newname:
            # rename the folder and files...
            self.path = os.path.join(site_dir, newname)
            if os.path.exists(self.path):
                shutil.rmtree(self.path)
            self.nginx_disable(reload=False)
            shutil.move(os.path.join(site_dir, self.id), self.path)
            os.unlink(os.path.join("/etc/nginx/sites-available", self.id))
            signals.emit("websites", "site_removed", self)
            self.id = newname

            # then update the site's arkOS metadata file with the new name
            meta = configparser.SafeConfigParser()
            meta.read(os.path.join(self.path, ".arkos"))
            meta.set("website", "id", self.id)
            with open(os.path.join(self.path, ".arkos"), "w") as f:
                meta.write(f)
            self.nginx_enable(reload=False)

        # Pass any necessary updates to the nginx serverblock and save
        port = "{0} ssl".format(self.port) if self.cert else str(self.port)
        for listen in server.filter("Key", "listen"):
            if listen.value.startswith("[::]:"):
                listen.value = "[::]:" + str(port)
            else:
                listen.value = str(port)
        if hasattr(self.app, "website_root") and self.app.website_root:
            webroot = os.path.join(self.path, self.app.website_root)
        else:
            webroot = self.path
        server.filter("Key", "server_name")[0].value = self.domain
        server.filter("Key", "root")[0].value = webroot
        server.filter("Key", "index")[0].value = "index.php" \
            if getattr(self, "php", False) else "index.html"
        nginx.dumpf(block, os.path.join("/etc/nginx/sites-available", self.id))

        # Call the site's edited hook, if it has one, then reload nginx
        signals.emit("websites", "site_loaded", self)
        if hasattr(self, "site_edited"):
            self.site_edited()
        nginx_reload()
コード例 #19
0
class WordPress(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = [
        nginx.Location('= /favicon.ico', nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('/',
                       nginx.Key('try_files', '$uri $uri/ /index.php?$args')),
        nginx.Location(
            '~ \.php$',
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_index', 'index.php'),
            nginx.Key('include', 'fastcgi.conf')),
        nginx.Location('~* \.(js|css|png|jpg|jpeg|gif|ico)$',
                       nginx.Key('expires', 'max'),
                       nginx.Key('log_not_found', 'off'))
    ]

    def pre_install(self, name, vars):
        dbname = vars.getvalue('wp-dbname', '')
        dbpasswd = vars.getvalue('wp-dbpasswd', '')
        if dbname and dbpasswd:
            apis.databases(self.app).get_interface('MariaDB').validate(
                dbname, dbname, dbpasswd)
        elif dbname:
            raise Exception(
                'You must enter a database password if you specify a database name!'
            )
        elif dbpasswd:
            raise Exception(
                'You must enter a database name if you specify a database password!'
            )

    def post_install(self, name, path, vars):
        # Get the database object, and determine proper values
        phpctl = apis.langassist(self.app).get_interface('PHP')
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        if vars.getvalue('wp-dbname', '') == '':
            dbname = name
        else:
            dbname = vars.getvalue('wp-dbname')
        secret_key = hashlib.sha1(str(random.random())).hexdigest()
        if vars.getvalue('wp-dbpasswd', '') == '':
            passwd = secret_key[0:8]
        else:
            passwd = vars.getvalue('wp-dbpasswd')

        # Request a database and user to interact with it
        dbase.add(dbname, conn)
        dbase.usermod(dbname, 'add', passwd, conn)
        dbase.chperm(dbname, dbname, 'grant', conn)

        # Use the WordPress key generators as first option
        # If connection fails, use the secret_key as fallback
        try:
            keysection = urllib.urlopen(
                'https://api.wordpress.org/secret-key/1.1/salt/').read()
        except:
            keysection = ''
        if not 'define(\'AUTH_KEY' in keysection:
            keysection = ('define(\'AUTH_KEY\', \'' + secret_key + '\');\n'
                          'define(\'SECURE_AUTH_KEY\', \'' + secret_key +
                          '\');\n'
                          'define(\'LOGGED_IN_KEY\', \'' + secret_key +
                          '\');\n'
                          'define(\'NONCE_KEY\', \'' + secret_key + '\');\n')

        # Write a standard WordPress config file
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        f.write('<?php\n'
                'define(\'DB_NAME\', \'' + dbname + '\');\n'
                'define(\'DB_USER\', \'' + dbname + '\');\n'
                'define(\'DB_PASSWORD\', \'' + passwd + '\');\n'
                'define(\'DB_HOST\', \'localhost\');\n'
                'define(\'DB_CHARSET\', \'utf8\');\n'
                'define(\'SECRET_KEY\', \'' + secret_key + '\');\n'
                '\n'
                'define(\'WP_CACHE\', true);\n'
                'define(\'FORCE_SSL_ADMIN\', false);\n'
                '\n' + keysection + '\n'
                '$table_prefix = \'wp_\';\n'
                '\n'
                '/** Absolute path to the WordPress directory. */\n'
                'if ( !defined(\'ABSPATH\') )\n'
                '	define(\'ABSPATH\', dirname(__FILE__) . \'/\');\n'
                '\n'
                '/** Sets up WordPress vars and included files. */\n'
                'require_once(ABSPATH . \'wp-settings.php\');\n')
        f.close()

        # Make sure that the correct PHP settings are enabled
        phpctl.enable_mod('mysql', 'xcache')

        # Finally, make sure that permissions are set so that Wordpress
        # can make adjustments and save plugins when need be.
        shell('chown -R http:http ' + path)

    def pre_remove(self, name, path):
        f = open(os.path.join(path, 'wp-config.php'), 'r')
        for line in f.readlines():
            if 'DB_NAME' in line:
                data = line.split('\'')[1::2]
                dbname = data[1]
                break
        f.close()
        dbase = apis.databases(self.app).get_interface('MariaDB')
        conn = apis.databases(self.app).get_dbconn('MariaDB')
        dbase.remove(dbname, conn)
        dbase.usermod(dbname, 'del', '', conn)

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        ic = open(os.path.join(path, 'wp-config.php'), 'r').readlines()
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        oc = []
        found = False
        for l in ic:
            if 'define(\'FORCE_SSL_ADMIN\'' in l:
                l = 'define(\'FORCE_SSL_ADMIN\', false);\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found == False:
            oc.append('define(\'FORCE_SSL_ADMIN\', true);\n')
        f.writelines(oc)
        f.close()

    def ssl_disable(self, path):
        ic = open(os.path.join(path, 'wp-config.php'), 'r').readlines()
        f = open(os.path.join(path, 'wp-config.php'), 'w')
        oc = []
        found = False
        for l in ic:
            if 'define(\'FORCE_SSL_ADMIN\'' in l:
                l = 'define(\'FORCE_SSL_ADMIN\', false);\n'
                oc.append(l)
                found = True
            else:
                oc.append(l)
        if found == False:
            oc.append('define(\'FORCE_SSL_ADMIN\', false);\n')
        f.writelines(oc)
        f.close()
コード例 #20
0
    def _install(self, extra_vars, enable, nthread):
        # Set metadata values
        site_dir = config.get("websites", "site_dir")
        path = (self.path or os.path.join(site_dir, self.id))
        self.path = path

        if os.path.isdir(self.path):
            shutil.rmtree(self.path)
        os.makedirs(self.path)

        # If extra data is passed in, set up the serverblock accordingly
        uwsgi_block = [
            nginx.Location(
                extra_vars.get("lregex", "/"),
                nginx.Key("{0}_pass".format(extra_vars.get("type")),
                          extra_vars.get("pass", "")),
                nginx.Key("include",
                          "{0}_params".format(extra_vars.get("type"))))
        ]
        default_block = [
            nginx.Location(extra_vars.get("lregex", "/"),
                           nginx.Key("proxy_pass", extra_vars.get("pass", "")),
                           nginx.Key("proxy_redirect", "off"),
                           nginx.Key("proxy_buffering", "off"),
                           nginx.Key("proxy_set_header", "Host $host"))
        ]
        if extra_vars:
            if not extra_vars.get("type") or not extra_vars.get("pass"):
                raise errors.InvalidConfigError(
                    "Must enter ReverseProxy type and location to pass to")
            elif extra_vars.get("type") in ["fastcgi", "uwsgi"]:
                self.block = uwsgi_block
            else:
                self.block = default_block
            if extra_vars.get("xrip"):
                self.block[0].add(
                    nginx.Key("proxy_set_header", "X-Real-IP $remote_addr"))
            if extra_vars.get("xff") == "1":
                xff_key = "X-Forwarded-For $proxy_add_x_forwarded_for"
                self.block[0].add(nginx.Key("proxy_set_header", xff_key))

        # Create the nginx serverblock and arkOS metadata files
        block = nginx.Conf()
        server = nginx.Server(
            nginx.Key("listen", self.port),
            nginx.Key("listen", "[::]:" + str(self.port)),
            nginx.Key("server_name", self.domain),
            nginx.Key("root", self.base_path or self.path),
            nginx.Location("/.well-known/acme-challenge/",
                           nginx.Key("root", self.path)))
        server.add(*[x for x in self.block])
        block.add(server)
        nginx.dumpf(block, os.path.join("/etc/nginx/sites-available", self.id))
        challenge_dir = os.path.join(self.path, ".well-known/acme-challenge/")
        if not os.path.exists(challenge_dir):
            os.makedirs(challenge_dir)
        meta = configparser.SafeConfigParser()
        ssl = self.cert.id if getattr(self, "cert", None) else "None"
        meta.add_section("website")
        meta.set("website", "id", self.id)
        meta.set("website", "app", self.app.id if self.app else "None")
        meta.set("website", "version", "None")
        meta.set("website", "ssl", ssl)
        with open(os.path.join(self.path, ".arkos"), "w") as f:
            meta.write(f)

        # Track port and reload daemon
        self.installed = True
        storage.websites[self.id] = self
        signals.emit("websites", "site_installed", self)
        self.nginx_enable()
コード例 #21
0
ファイル: website.py プロジェクト: wrestrtdr/applications
class Wallabag(Site):
    addtoblock = [
        nginx.Location("/", nginx.Key("try_files",
                                      "$uri /app.php$is_args$args")),
        nginx.Location(
            "~ ^/app\.php(/|$)",
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_split_path_info', "^(.+\.php)(/.*)$"),
            nginx.Key('include', 'fastcgi.conf'),
            nginx.Key('fastcgi_param',
                      'SCRIPT_FILENAME $realpath_root$fastcgi_script_name'),
            nginx.Key('fastcgi_param', 'DOCUMENT_ROOT $realpath_root'))
    ]

    def pre_install(self, extra_vars):
        pass

    def post_install(self, extra_vars, dbpasswd=""):
        secret_key = random_string()
        dbengine = 'mysql' \
            if self.app.selected_dbengine == 'db-mariadb' \
            else 'sqlite'

        # Write a standard Wallabag config file
        config_file = os.path.join(self.path, 'app/config/parameters.yml')
        with open(config_file + ".dist", 'r') as f:
            ic = f.readlines()
        with open(config_file, 'w') as f:
            for l in ic:
                if "database_driver: " in l:
                    pdo = "pdo_mysql" if dbengine == "mysql" else "pdo_sqlite"
                    l = "    database_driver: {0}\n".format(pdo)
                elif "database_path: " in l and dbengine == 'sqlite':
                    l = "    database_path: {0}\n".format(self.db.path)
                elif "database_name: " in l and dbengine == 'mysql':
                    l = "    database_name: {0}\n".format(self.db.id)
                elif "database_user: "******"    database_user: {0}\n".format(self.db.id)
                elif "database_password: "******"{0}"\n'.format(dbpasswd)
                elif "secret: " in l:
                    l = "    secret: {0}\n".format(secret_key)
                f.write(l)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('sqlite3', 'bcmath',
                       'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite',
                       'zip', 'tidy')
        php.open_basedir('add', '/usr/bin/php')

        uid, gid = users.get_system("http").uid, groups.get_system("http").gid

        # Set up the database then delete the install folder
        if dbengine == 'sqlite3':
            php.open_basedir('add', '/var/lib/sqlite3')

        cwd = os.getcwd()
        os.chdir(self.path)
        s = shell("php bin/console wallabag:install --env=prod -n")
        if s["code"] != 0:
            logger.error("Websites", s["stderr"].decode())
            raise errors.OperationFailedError(
                "Failed to populate database. See logs for more info")
        os.chdir(cwd)

        if dbengine == 'sqlite3':
            os.chown("/var/lib/sqlite3/{0}.db".format(self.db.id), -1, gid)
            os.chmod("/var/lib/sqlite3/{0}.db".format(self.db.id), 0o660)

        # Finally, make sure that permissions are set so that Wallabag
        # can make adjustments and save plugins when need be.
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)

    def pre_remove(self):
        pass

    def post_remove(self):
        pass

    def enable_ssl(self, cfile, kfile):
        pass

    def disable_ssl(self):
        pass

    def update(self, pkg, ver):
        # General update procedure
        if semver.Version.coerce(ver) > semver.Version('2.0.0'):
            raise Exception(
                "Cannot automatically update from 1.x to 2.x. Please see "
                "Wallabag documentation for more information.")
        os.rename(os.path.join(self.path, 'app/config/parameters.yml'),
                  '/tmp/_wb_parameters.yml')
        shell('tar xzf {0} -C {1} --strip 1'.format(pkg, self.path))
        os.rename('/tmp/_wb_parameters.yml',
                  os.path.join(self.path, 'app/config/parameters.yml'))
        cachepath = os.path.join(self.path, 'var/cache')
        for x in os.listdir(cachepath):
            fpath = os.path.join(cachepath, x)
            if os.path.isdir(fpath):
                shutil.rmtree(fpath)
            else:
                os.unlink(fpath)
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
コード例 #22
0
ファイル: __init__.py プロジェクト: mmspide/Prism
    def rebuild_sites(self):
        """ Turns jack's site json files into useable nginx configuration files """

        for uuid, site_config in self.configs.items():
            maintenance_mode = 'maintenance' in site_config and site_config['maintenance']

            nginx_config = nginx.Conf()

            # Add some comments so anyone who looks in the nginx config
            # knows what's going on
            nginx_config.add(nginx.Comment('Generated by Prism CP. Any changes will be overwritten!'))
            nginx_config.add(nginx.Comment('Site ID: %s' % site_config['id']))

            server_block = nginx.Server()

            if 'listen' in site_config:
                for port in site_config['listen']:
                    server_block.add(nginx.Key('listen', port))
            if 'hostname' in site_config:
                server_block.add(nginx.Key('server_name', site_config['hostname']))

            site_folder = os.path.join(self._jack_plugin.site_files_location, uuid)

            # Sets the root and logs to the site's folder
            server_block.add(nginx.Key('access_log', os.path.join(site_folder, 'access.log')))
            server_block.add(nginx.Key('error_log', os.path.join(site_folder, 'error.log')))

            if 'root' in site_config:
                root_folder = os.path.join(site_folder, site_config['root'])
                if not os.path.exists(root_folder):
                    os.makedirs(root_folder)
                server_block.add(nginx.Key('root', root_folder))

            if 'index' in site_config:
                server_block.add(nginx.Key('index', site_config['index']))

            # If the site is in maintenance mode, redirect everything to 503
            if maintenance_mode:
                server_block.add(nginx.Location('/',
                                    nginx.Key('return', 503)))
            else:
                for path, items in site_config['locations'].items():
                    location_items = []
                    for item, content in items.items():
                        if isinstance(content, tuple) or isinstance(content, list):
                            for c in content:
                                location_items.append(nginx.Key(item, c))
                        else:
                            location_items.append(nginx.Key(item, content))
                    server_block.add(nginx.Location(path, *location_items))

            # Error page blocks
            server_block.add(nginx.Key('error_page', '400 /error/400.html'))
            server_block.add(nginx.Key('error_page', '403 /error/403.html'))
            server_block.add(nginx.Key('error_page', '404 /error/404.html'))
            server_block.add(nginx.Key('error_page', '408 /error/408.html'))
            server_block.add(nginx.Key('error_page', '500 /error/500.html'))
            server_block.add(nginx.Key('error_page', '502 /error/502.html'))
            server_block.add(nginx.Key('error_page', '503 /error/503.html'))
            server_block.add(nginx.Location('^~ /error/',
                        nginx.Key('root', self.sites_default),
                        nginx.Key('internal', '')))

            nginx_config.add(server_block)

            # Dump to nginx's config location
            nginx.dumpf(nginx_config, os.path.join(self.config_location, site_config['uuid'] + '.conf'))

        # Reload nginx so it picks up the changes
        prism.os_command('systemctl reload nginx.service')
コード例 #23
0
ファイル: main.py プロジェクト: ardnet/genesis
class Ghost(Plugin):
    implements(apis.webapps.IWebapp)
    name = 'Ghost'
    icon = 'gen-earth'

    addtoblock = [
        nginx.Location('/', nginx.Key('proxy_pass', 'http://127.0.0.1:2368'),
                       nginx.Key('proxy_set_header', 'X-Real-IP $remote_addr'),
                       nginx.Key('proxy_set_header', 'Host $host'),
                       nginx.Key('proxy_buffering', 'off'))
    ]

    def pre_install(self, name, vars):
        pass

    def post_install(self, name, path, vars, dbinfo={}):
        nodectl = apis.langassist(self.app).get_interface('NodeJS')
        users = UsersBackend(self.app)

        if not os.path.exists('/usr/bin/python') and os.path.exists(
                '/usr/bin/python'):
            os.symlink('/usr/bin/python2', '/usr/bin/python')

        d = json.loads(open(os.path.join(path, 'package.json'), 'r').read())
        del d['dependencies']['bcryptjs']
        d['dependencies']['bcrypt'] = '0.7.8'
        open(os.path.join(path, 'package.json'), 'w').write(json.dumps(d))
        d = open(os.path.join(path, 'core/server/models/user.js'), 'r').read()
        d = d.replace('bcryptjs', 'bcrypt')
        open(os.path.join(path, 'core/server/models/user.js'), 'w').write(d)

        nodectl.install_from_package(path, 'production', {
            'sqlite': '/usr/bin',
            'python': '/usr/bin/python2'
        })
        users.add_user('ghost')

        s = self.app.get_backend(apis.services.IServiceManager)
        s.edit(
            'ghost', {
                'stype': 'program',
                'directory': path,
                'user': '******',
                'command': 'node %s' % os.path.join(path, 'index.js'),
                'autostart': 'true',
                'autorestart': 'true',
                'environment': 'NODE_ENV="production"',
                'stdout_logfile': '/var/log/ghost.log',
                'stderr_logfile': '/var/log/ghost.log'
            })
        s.enable('ghost', 'supervisor')

        addr = vars.getvalue('addr', 'localhost')
        port = vars.getvalue('port', '80')

        # Get Mail settings
        mail_settings = {
            'transport': vars.getvalue('ghost-transport', ''),
            'service': vars.getvalue('ghost-service', ''),
            'mail_user': vars.getvalue('ghost-mail-user', ''),
            'mail_pass': vars.getvalue('ghost-mail-pass', ''),
            'from_address': vars.getvalue('ghost-from-address', '')
        }

        # Create/Edit the Ghost config file
        f = open(os.path.join(path, 'config.example.js'), 'r').read()
        with open(os.path.join(path, 'config.js'), 'w') as config_file:
            f = f.replace(
                'http://my-ghost-blog.com',
                'http://' + addr + (':' + port if port != '80' else ''))
            if len(set(mail_settings.values())) != 1 and\
               mail_settings['transport'] != '':
                # If the mail settings exist, add them
                f = f.replace(
                    "mail: {},",\
                    'mail: {\n'
                    "\tfromaddress: '" + mail_settings['from_address'] + "',\n"
                    "\ttransport: '" + mail_settings['transport'] + "',\n"
                    "\t\toptions: {\n"
                    "\t\t\tservice: '" + mail_settings['service'] + "',\n"
                    "\t\t\tauth: {\n"
                    "\t\t\t\tuser: '******'mail_user'] + "',\n"
                    "\t\t\t\tpass: '******'mail_pass'] + "'\n"
                    "\t\t\t}\n"
                    "\t\t}\n"
                    "},\n"
                )
            config_file.write(f)
            config_file.close()

        # Finally, make sure that permissions are set so that Ghost
        # can make adjustments and save plugins when need be.
        shell('chown -R ghost ' + path)

    def pre_remove(self, site):
        pass

    def post_remove(self, site):
        users = UsersBackend(self.app)
        users.del_user('ghost')
        s = self.app.get_backend(apis.services.IServiceManager)
        s.delete('ghost', 'supervisor')

    def ssl_enable(self, path, cfile, kfile):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s' % name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                self.addtoblock[0].add(
                    nginx.Key('proxy_set_header',
                              'X-Forwarded-For $proxy_add_x_forwarded_for'),
                    nginx.Key('proxy_set_header', 'X-Forwarded-Proto $scheme'),
                )
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s' % name)
        f = open(os.path.join(path, 'config.js'), 'r').read()
        with open(os.path.join(path, 'config.js'), 'w') as config_file:
            f = f.replace('production: {\n        url: \'http://',
                          'production: {\n        url: \'https://')
            config_file.write(f)
            config_file.close()
        s = self.app.get_backend(apis.services.IServiceManager)
        s.restart('ghost', 'supervisor')

    def ssl_disable(self, path):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s' % name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s' % name)
        f = open(os.path.join(path, 'config.js'), 'r').read()
        with open(os.path.join(path, 'config.js'), 'w') as config_file:
            f = f.replace('production: {\n        url: \'https://',
                          'production: {\n        url: \'http://')
            config_file.write(f)
            config_file.close()
        s = self.app.get_backend(apis.services.IServiceManager)
        s.restart('ghost', 'supervisor')
コード例 #24
0
def setup(addr, port):
    # Make sure Radicale is installed and ready
    if not python.is_installed('Radicale'):
        python.install('radicale')
    # due to packaging bugs, make extra sure perms are readable
    pver = "{0}.{1}".format(sys.version_info.major, sys.version_info.minor)
    raddir = '/usr/lib/python{0}/site-packages/radicale'.format(pver)
    st = os.stat(raddir)
    for r, d, f in os.walk(raddir):
        for x in d:
            os.chmod(os.path.join(r, x),
                     st.st_mode | stat.S_IROTH | stat.S_IRGRP)
        for x in f:
            os.chmod(os.path.join(r, x),
                     st.st_mode | stat.S_IROTH | stat.S_IRGRP)
    if not os.path.exists('/etc/radicale/config'):
        if not os.path.isdir('/etc/radicale'):
            os.mkdir('/etc/radicale')
        with open('/etc/radicale/config', 'w') as f:
            f.write(default_config)
    if not os.path.isdir('/usr/lib/radicale'):
        os.mkdir('/usr/lib/radicale')
    # Add the site process
    u = users.SystemUser("radicale")
    u.add()
    g = groups.SystemGroup("radicale", users=["radicale"])
    g.add()
    wsgi_file = 'import radicale\n'
    wsgi_file += 'radicale.log.start()\n'
    wsgi_file += 'application = radicale.Application()\n'
    with open('/etc/radicale/radicale.wsgi', 'w') as f:
        f.write(wsgi_file)
    os.chmod('/etc/radicale/radicale.wsgi', 0o766)
    cfg = {
        'directory': '/etc/radicale',
        'user': '******',
        'command': 'uwsgi -s /tmp/radicale.sock -C '
        '--plugin python --wsgi-file radicale.wsgi',
        'stdout_logfile': '/var/log/radicale.log',
        'stderr_logfile': '/var/log/radicale.log'
    }
    s = services.Service("radicale", "supervisor", cfg=cfg)
    s.add()
    block = [
        nginx.Location(
            '/',
            nginx.Key('include', 'uwsgi_params'),
            nginx.Key('uwsgi_pass', 'unix:///tmp/radicale.sock'),
        )
    ]
    s = websites.get("radicale")
    if s:
        s.remove()
    a = applications.get('radicale')
    s = websites.ReverseProxy(app=a,
                              id="radicale",
                              domain=addr,
                              port=int(port),
                              base_path="/usr/lib/radicale",
                              block=block)
    s.install()
コード例 #25
0
 def BuildNginxConfiguration(self, server, api_services, clients,
                             identity_services):
     print("Configuring Nginx Server")
     serverConfig = server['config']
     config = nginx.Conf()
     # Add Root Configurations
     for key, value in serverConfig.items():
         if (not isinstance(value, dict)):
             config.add(nginx.Key(key, value))
     events = nginx.Events()
     httpConf = nginx.Http()
     # Add Event Configurations
     if ('events' in serverConfig):
         for key, value in serverConfig['events'].items():
             events.add(nginx.Key(key, value))
     config.add(events)
     # Add Http Configurations
     if ('http' in serverConfig):
         for key, value in serverConfig['http'].items():
             httpConf.add(nginx.Key(key, value))
     # Add Services To Http
     for api_service in api_services:
         nginxServer = nginx.Server(
             nginx.Key('listen', '80'),
             nginx.Key('server_name',
                       str.lower(api_service['name']) + '.localhost'),
         )
         proxy_pass = '******' + api_service['name'] + ':' + str(
             api_service['port']) + '/'
         location = nginx.Location(
             '/', nginx.Key('proxy_http_version', '1.1'),
             nginx.Key('proxy_set_header', 'Upgrade $http_upgrade'),
             nginx.Key('proxy_set_header', 'Connection keep-alive'),
             nginx.Key('proxy_set_header',
                       'X-Forwarded-For $proxy_add_x_forwarded_for'),
             nginx.Key('proxy_set_header', 'Host $host'),
             nginx.Key('proxy_set_header', 'X-NginX-Proxy true'),
             nginx.Key('proxy_pass', proxy_pass))
         nginxServer.add(location)
         httpConf.add(nginxServer)
     for i_service in identity_services:
         nginxServer = nginx.Server(
             nginx.Key('listen', '80'),
             nginx.Key('server_name',
                       str.lower(i_service['name']) + '.localhost'),
         )
         #pylint: disable-msg=E1121
         proxy_pass = '******' + i_service['name'] + ':' + str(
             i_service['port']) + '/'
         location = nginx.Location(
             '/', nginx.Key('proxy_http_version', '1.1'),
             nginx.Key('proxy_set_header', 'Upgrade $http_upgrade'),
             nginx.Key('proxy_set_header', 'Connection keep-alive'),
             nginx.Key('proxy_set_header',
                       'X-Forwarded-For $proxy_add_x_forwarded_for'),
             nginx.Key('proxy_set_header', 'Host $host'),
             nginx.Key('proxy_set_header', 'X-NginX-Proxy true'),
             nginx.Key('proxy_pass', proxy_pass))
         nginxServer.add(location)
         httpConf.add(nginxServer)
     for client in clients:
         nginxServer = nginx.Server(
             nginx.Key('listen', '80'),
             nginx.Key('server_name',
                       str.lower(client['name']) + '.localhost'),
         )
         #pylint: disable-msg=E1121
         proxy_pass = '******' + client['name'] + ':' + str(
             client['port']) + '/'
         location = nginx.Location(
             '/', nginx.Key('proxy_http_version', '1.1'),
             nginx.Key('proxy_set_header', 'Upgrade $http_upgrade'),
             nginx.Key('proxy_set_header', 'Connection keep-alive'),
             nginx.Key('proxy_set_header',
                       'X-Forwarded-For $proxy_add_x_forwarded_for'),
             nginx.Key('proxy_set_header', 'Host $host'),
             nginx.Key('proxy_set_header', 'X-NginX-Proxy true'),
             nginx.Key('proxy_pass', proxy_pass))
         nginxServer.add(location)
         httpConf.add(nginxServer)
     config.add(httpConf)
     return config
コード例 #26
0
class Wallabag(Site):
    addtoblock = [
        nginx.Location('~ /(db)', nginx.Key('deny', 'all'),
                       nginx.Key('return', '404')),
        nginx.Location('= /favicon.ico', nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('= /robots.txt', nginx.Key('allow', 'all'),
                       nginx.Key('log_not_found', 'off'),
                       nginx.Key('access_log', 'off')),
        nginx.Location('/',
                       nginx.Key('try_files', '$uri $uri/ /index.php?$args')),
        nginx.Location(
            '~ \.php$',
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
            nginx.Key('fastcgi_index', 'index.php'),
            nginx.Key('include', 'fastcgi.conf')),
        nginx.Location('~* \.(js|css|png|jpg|jpeg|gif|ico)$',
                       nginx.Key('expires', 'max'),
                       nginx.Key('log_not_found', 'off'))
    ]

    def pre_install(self, vars):
        if not vars.get('wb-username'):
            raise Exception('Must choose a Wallabag username')
        elif not vars.get('wb-passwd'):
            raise Exception('Must choose a Wallabag password')
        elif '"' in vars.get('wb-passwd') or "'" in vars.get('wb-passwd'):
            raise Exception('Your Wallabag password must not include quotes')

    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()
        dbengine = 'mysql' if self.meta.selected_dbengine == 'db-mariadb' else 'sqlite'

        username = vars.get("wb-username")
        passwd = vars.get("wb-passwd") + username + secret_key
        passwd = hashlib.sha1(passwd).hexdigest()

        # Write a standard Wallabag config file
        shutil.copy(
            os.path.join(self.path, 'inc/poche/config.inc.default.php'),
            os.path.join(self.path, 'inc/poche/config.inc.php'))
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'),
                  'r') as f:
            ic = f.readlines()
        oc = []
        for l in ic:
            if 'define (\'SALT\'' in l:
                l = '@define (\'SALT\', \'' + secret_key + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE\'' in l:
                l = '@define (\'STORAGE\', \'' + dbengine + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_SQLITE\'' in l and dbengine == 'sqlite':
                l = '@define (\'STORAGE_SQLITE\', \'/var/lib/sqlite3/' + self.db.id + '.db\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_DB\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_DB\', \'' + self.db.id + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_USER\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_USER\', \'' + self.db.id + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_PASSWORD\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_PASSWORD\', \'' + dbpasswd + '\');\n'
                oc.append(l)
            else:
                oc.append(l)
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'),
                  'w') as f:
            f.writelines(oc)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql' if dbengine == 'mysql' else 'sqlite3',
                       'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite',
                       'zip', 'tidy', 'xcache', 'openssl')

        # Set up Composer and install the proper modules
        php.composer_install(self.path)

        uid, gid = users.get_system("http").uid, groups.get_system("http").gid

        # Set up the database then delete the install folder
        if dbengine == 'mysql':
            with open(os.path.join(self.path, 'install/mysql.sql')) as f:
                self.db.execute(f.read())
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');"
                % (username, passwd, username),
                commit=True)
            lid = int(self.db.manager.connection.insert_id())
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'pager', '10');"
                % lid,
                commit=True)
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'language', 'en_EN.UTF8');"
                % lid,
                commit=True)
        else:
            shutil.copy(os.path.join(self.path, 'install/poche.sqlite'),
                        '/var/lib/sqlite3/%s.db' % self.db.id)
            php.open_basedir('add', '/var/lib/sqlite3')
            os.chown("/var/lib/sqlite3/%s.db" % self.db.id, -1, gid)
            os.chmod("/var/lib/sqlite3/%s.db", 0664)
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');"
                % (username, passwd, username))
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'pager', '10');"
            )
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'language', 'en_EN.UTF8');"
            )
        shutil.rmtree(os.path.join(self.path, 'install'))

        # Finally, make sure that permissions are set so that Wallabag
        # can make adjustments and save plugins when need be.
        for r, d, f in os.walk(self.path):
            for x in d:
                if d in ["assets", "cache", "db"]:
                    os.chmod(os.path.join(r, d), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)

    def pre_remove(self):
        pass

    def post_remove(self):
        pass

    def enable_ssl(self, cfile, kfile):
        pass

    def disable_ssl(self):
        pass

    def update(self, pkg, ver):
        # General update procedure
        shell('tar xzf %s -C %s --strip 1' % (pkg, self.path))
        for x in os.listdir(os.path.join(self.path, 'cache')):
            if os.path.isdir(os.path.join(self.path, 'cache', x)):
                shutil.rmtree(os.path.join(self.path, 'cache', x))
            else:
                os.unlink(os.path.join(self.path, 'cache', x))
        shutil.rmtree(os.path.join(self.path, 'install'))
        shell('chmod -R 755 ' + os.path.join(self.path, 'assets/') + ' ' +
              os.path.join(self.path, 'cache/') + ' ' +
              os.path.join(self.path, 'db/'))
        shell('chown -R http:http ' + self.path)
コード例 #27
0
def _execute(command):
    config = FileUtils.get_instance('config.ini')
    nginx_conf_dir = config.get_prop("nginx-config", "nginx_conf_dir")
    nginx_conf_dir_bak = config.get_prop("nginx-config", "nginx_conf_dir_bak")
    os.system('mkdir -p ' + nginx_conf_dir)
    os.system('cp -r ' + nginx_conf_dir + nginx_conf_dir_bak)
    os.system('rm -rf ' + nginx_conf_dir + '*')
    state = '0'
    try:
        for k1 in command:
            upstreamName = k1["upstreamName"]
            upstreamNode = json.loads(k1["upstreamNode"])
            fileName = nginx_conf_dir + upstreamName + '.conf'
            os.system('touch ' + fileName)
            c = nginx.Conf()
            LogUtil.info("Node信息:%s" % (upstreamNode))
            t = ''
            for k2 in range(len(upstreamNode)):
                if (k2 == 0):
                    t = 'server' + ' ' + upstreamNode[k2][
                        "ipAdress"] + ' ' + upstreamNode[k2]["strategy"] + ';\n'
                if (0 < k2 < len(upstreamNode) - 1):
                    t = t + '     ' + 'server' + ' ' + upstreamNode[k2][
                        "ipAdress"] + ' ' + upstreamNode[k2]["strategy"] + ';\n'
                if (k2 == len(upstreamNode) - 1):
                    t = t + '     ' + 'server' + ' ' + upstreamNode[k2][
                        "ipAdress"] + ' ' + upstreamNode[k2]["strategy"]
            ipHash = k1["ipHash"]
            if (ipHash == '1'):
                u = nginx.Upstream(upstreamName, nginx.Key('', t),
                                   nginx.Key('', 'ip_hash'))
                c.add(u)
            if (ipHash == '0'):
                u = nginx.Upstream(upstreamName, nginx.Key('', t))
                c.add(u)
            s = nginx.Server()
            s.add(
                nginx.Key('listen', k1["nginxListenPort"]),
                nginx.Key('server_name', k1["nginxServerName"]),
                nginx.Key('access_log', k1["accessLog"]),
                nginx.Location(
                    '= /',
                    nginx.Key('proxy_pass', 'http://' + k1["upstreamName"]),
                    nginx.Key('proxy_redirect', 'off'),
                    nginx.Key('proxy_set_header', 'Host    $host'),
                    nginx.Key('proxy_set_header', 'X-Real-IP  $remote_addr'),
                    nginx.Key('proxy_set_header',
                              'X-Forwarded-For   $proxy_add_x_forwarded_for')))
            c.add(s)
            nginx.dumpf(c, fileName)
        LogUtil.info("完成Nginx配置")
        output = os.popen('service nginx restart').read()
        state = '1'
        param = [
            "{\"mac\":\"" + MachineUtil.get_mac_address() + "\",\"state\":\"" +
            state + "\",\"msg\":\"" + output + "\"}"
        ]
        os.system('rm -rf ' + nginx_conf_dir_bak)
        AosServerService.route_service("ThriftApiService", "nginxLog", param)
    except Exception, ex:
        LogUtil.error(ex)
        os.system('rm -rf ' + nginx_conf_dir)
        os.system('mv ' + nginx_conf_dir_bak + nginx_conf_dir)
        os.system('service nginx restart')
        output = ex.message
        state = '2'
        param = [
            "{\"mac\":\"" + MachineUtil.get_mac_address() + "\",\"state\":\"" +
            state + "\",\"msg\":\"" + output + "\"}"
        ]
        AosServerService.route_service("ThriftApiService", "nginxLog", param)
コード例 #28
0
ファイル: nginx.py プロジェクト: aiminickwong/tyger
def set_conf(request, proxy):
    config = nginx.Conf()
    serverHTTP = nginx.Server()
    serverHTTPS = nginx.Server()
    print(proxy.domain)
    print(proxy.ssl)
    print(proxy.letsencrypt)
    print(proxy.rewriteHTTPS)
    print(proxy.proxypass)

    serverHTTP.add(
        nginx.Key('listen', '*:80'),
        nginx.Key('server_name', proxy.domain),

    )

    if proxy.rewriteHTTPS:
        serverHTTP.add(
            nginx.Key('return', '302 https://$server_name$request_uri'),

        )
    else:
        serverHTTP.add(
            nginx.Location(
                '/',
                nginx.Key('proxy_set_header', 'Host $host'),
                nginx.Key('proxy_set_header', 'X-Real-IP $remote_addr'),
                nginx.Key('proxy_set_header', 'X-Forwarded-For $proxy_add_x_forwarded_for'),
                nginx.Key('proxy_set_header', 'Upgrade $http_upgrade'),
                nginx.Key('proxy_set_header', 'Connection '"upgrade"),
                nginx.Key('proxy_http_version', '1.1'),
                nginx.Key('proxy_pass', proxy.proxypass),
            )
        )

    if proxy.ssl:
        letsencrypt.generate_cert(request, proxy)
        serverHTTPS.add(
            nginx.Key('server_name', proxy.domain),
            nginx.Key('listen', '*:443 ssl'),
            nginx.Key('ssl_protocols', 'TLSv1 TLSv1.1 TLSv1.2'),
            nginx.Key('ssl_certificate', '/etc/letsencrypt/live/'+proxy.domain+'/fullchain.pem'),
            nginx.Key('ssl_certificate_key', '/etc/letsencrypt/live/'+proxy.domain+'/privkey.pem'),

        )

    serverHTTPS.add(
        nginx.Location(
            '/',

            nginx.Key('proxy_set_header', 'Host $host'),
            nginx.Key('proxy_set_header', 'X-Real-IP $remote_addr'),
            nginx.Key('proxy_set_header', 'X-Forwarded-For $proxy_add_x_forwarded_for'),
            nginx.Key('proxy_set_header', 'Upgrade $http_upgrade'),
            nginx.Key('proxy_set_header', 'Connection '"upgrade"),
            nginx.Key('proxy_http_version', '1.1'),
            nginx.Key('proxy_pass', proxy.proxypass),


        )
    )
    config.add(serverHTTP)
    config.add(serverHTTPS)
    nginx.dumpf(config, '/etc/nginx/conf.d/' + proxy.domain + '.conf')

    shell.restart_nginx(request)

    return True
コード例 #29
0
class Gitweb(Plugin):
    implements(apis.webapps.IWebapp)

    addtoblock = [
        nginx.Location('/',
            nginx.Key('index', 'gitweb.cgi'),
            nginx.Key('include', 'fastcgi_params'),
            nginx.Key('gzip', 'off'),
            nginx.Key('fastcgi_param', 'GITWEB_CONFIG /etc/conf.d/gitweb.conf'),
            nginx.If('($uri ~ "/gitweb.cgi")',
                nginx.Key('fastcgi_pass', 'unix:/var/run/fcgiwrap.sock')
            )
        )
    ]

    def pre_install(self, name, vars):
        # Write a standard Gitweb config file
        if not os.path.exists('/etc/conf.d'):
            os.makedirs('/etc/conf.d')
        f = open('/etc/conf.d/gitweb.conf', 'w')
        oc = ['our $git_temp = "/tmp";\n',
            'our $projectroot = "'+vars.getvalue('gw-proot', '')+'";\n',
            'our @git_base_url_list = qw(git://'+vars.getvalue('hostname', '')+' http://git@'+vars.getvalue('hostname', '')+');\n'
        ]
        f.writelines(oc)
        f.close()

    def post_install(self, name, path, vars, dbinfo={}):
        svc = self.app.get_backend(apis.services.IServiceManager)

        f = open('/usr/lib/systemd/system/fcgiwrap.service', 'w')
        oc = ['[Unit]\n',
            'Description=Simple server for running CGI applications over FastCGI\n',
            'After=syslog.target network.target\n',
            '\n',
            '[Service]\n',
            'Type=forking\n',
            'Restart=on-abort\n',
            'PIDFile=/var/run/fcgiwrap.pid\n',
            'ExecStart=/usr/bin/spawn-fcgi -s /var/run/fcgiwrap.sock -P /var/run/fcgiwrap.pid -u http -g http -- /usr/sbin/fcgiwrap\n',
            'ExecStop=/usr/bin/kill -15 $MAINPID\n',
            '\n',
            '[Install]\n',
            'WantedBy=multi-user.target\n'
        ]
        f.writelines(oc)
        f.close()

        svc.enable('fcgiwrap')
        svc.start('fcgiwrap')

        if os.path.exists(os.path.join('/srv/http/webapps', name)):
            if os.path.isdir(os.path.join('/srv/http/webapps', name)):
                shutil.rmtree(os.path.join('/srv/http/webapps', name))
            else:
                os.unlink(os.path.join('/srv/http/webapps', name))
        os.symlink('/usr/share/gitweb', 
            os.path.join('/srv/http/webapps', name))

    def pre_remove(self, site):
        pass

    def post_remove(self, name):
        pass

    def ssl_enable(self, path, cfile, kfile):
        pass

    def ssl_disable(self, path):
        pass

    def update(self, path, pkg, ver):
        pass
コード例 #30
0
class DokuWiki(Site):
    addtoblock = [
        nginx.Location(
            '/',
            nginx.Key('try_files', '$uri $uri/ @dokuwiki'),
        ),
        nginx.Location('~ /(data|conf|bin|inc)/', nginx.Key('deny', 'all')),
        nginx.Location(r'~ /\.ht', nginx.Key('deny', 'all')),
        nginx.Location(
            '@dokuwiki',
            nginx.Key('rewrite',
                      '^/_media/(.*) /lib/exe/fetch.php?media=$1 last'),
            nginx.Key('rewrite',
                      '^/_detail/(.*) /lib/exe/detail.php?media=$1 last'),
            nginx.Key(
                'rewrite',
                '^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2 last'),
            nginx.Key('rewrite', '^/(.*) /doku.php?id=$1 last'),
        ),
        nginx.Location(
            r'~ \.php$',
            nginx.Key('include', 'fastcgi_params'),
            nginx.Key('fastcgi_param',
                      'SCRIPT_FILENAME $document_root$fastcgi_script_name'),
            nginx.Key('fastcgi_pass', 'unix:/run/php-fpm/php-fpm.sock'),
        ),
    ]

    def pre_install(self, name, vars):
        pass

    def post_install(self, name, path, vars, dbinfo={}):
        # UPDATE: Config DB info and enable modules
        index_php = os.path.join(path, 'index.php')
        os.remove(index_php)
        with open(index_php, "w") as f:
            f.write(switching_index)  # see below
        shell('chown -R http ' + path)

    def pre_remove(self, site):
        pass

    def post_remove(self, site):
        pass

    def ssl_enable(self, path, cfile, kfile):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s' % name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                self.addtoblock[0].add(
                    nginx.Key('proxy_set_header',
                              'X-Forwarded-For $proxy_add_x_forwarded_for'),
                    nginx.Key('proxy_set_header', 'X-Forwarded-Proto $scheme'),
                )
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s' % name)

    def ssl_disable(self, path):
        name = os.path.basename(path)
        n = nginx.loadf('/etc/nginx/sites-available/%s' % name)
        for x in n.servers:
            if x.filter('Location', '/'):
                x.remove(x.filter('Location', '/')[0])
                x.add(self.addtoblock[0])
                nginx.dumpf(n, '/etc/nginx/sites-available/%s' % name)

    def update(self, path, pkg, ver):
        pass