preload
Авг 14

Хочу поделиться маленьким скриптиком на питоне, облегчающим мне жизнь. Код, конечно, не самый лучший, заготовки конфигов можно вынести в отдельные файлы и читать оттуда, то же самое можно сделать и с классами но мне было так удобнее. Так же можно логировать действия скрипта, но с этим вполне справляется перенаправление вывод скрипта в файл. Предполагается, что у вас настроены bind и apache, а также установлена утилита apg для генерации паролей.

#!/usr/bin/env python

import string, sys, os, time
from subprocess import *

class User:
    """Class to create a FreeBSD system account"""

    def __init__(self, login, shell = "/usr/sbin/nologin", mode = '711'):
        """Initialize"""
        self.login = login
        self.shell = shell
        self.mode = mode
        self.password = self.get_password()
        self.create()

    def get_password(self):
        """Get a random password"""
        args = ['apg', '-n', '1']
        output = Popen(args, stdout = PIPE).communicate()[0]
        return string.strip(output)

    def create(self):
        """Method to create an account"""
        args = ['echo', self.password]
        echo = Popen(args, stdout = PIPE)
        args = [
            '/usr/sbin/pw', 'useradd',
            '-n', self.login,
            '-s', self.shell,
            '-m', '-M', self.mode, #create user's home directory
            '-h', '0'
        ]
        pw = Popen(args, stdin = echo.stdout, stdout = PIPE)
        print pw.communicate()[0]
        print "#######################################"
        print "Username:" + self.login
        print "Password:" + self.password
        print "#######################################"

class VirtualHost:
    """Class to create Apache's virtualhost and DNS zone"""

    def __init__(self, user, domain):
        self.user, self.domain = user, domain
        self.create_dirs_and_files()
        self.create_dns_zone()
        self.restart_named()
        self.create_vhost()
        self.restart_httpd()

    def create_dirs_and_files(self):
        homedir = "/home/" + self.user
        wwwdir = homedir + "/public_html"
        error_log  = homedir + "/error_log"
        access_log = homedir + "/access_log"
        print "Creating Web directory"
        uid = self.get_uid(self.user)
        gid = self.get_gid('www')
        os.mkdir(wwwdir, 0770)
        os.chown(wwwdir, uid, gid)
        print "Creating log files"
        Popen(['touch', error_log], stdout = PIPE).communicate()[0]
        Popen(['touch', access_log], stdout = PIPE).communicate()[0]
        os.chmod(error_log, 0660)
        os.chmod(access_log, 0660)
        os.chown(error_log, uid, gid)
        os.chown(access_log, uid, gid)

    def create_dns_zone(self):
        """Creates specified DNS record"""

        import datetime
        date = datetime.date.today()
        version = date.strftime('%Y%m%d') + '01'
        zone = """
$TTL 3600
@       86400   IN       SOA    ns1.domain.net. root.domain.net. (
                                                        %VERSION%; Serial
                                                        10800           ; Refresh
                                                                3600            ; Retry
                                                        604800          ; Expire
                                                        86400           ; Minimum TTL

                                        )
; Serial, Refresh, Retry, Expire, Neg. cache TTL

;DNS Servers
%DOMAIN%.       IN              NS      ns1.domain.net.
%DOMAIN%.       IN              NS      ns2.domain.net.

%DOMAIN%.   IN  A       123.456.789.1
localhost.domain.net.    IN      A       127.0.0.1

%DOMAIN%.   IN MX 0     %DOMAIN%.
; Machine names
mail            IN      CNAME   @

www             IN      CNAME   @
"""
        zone = string.replace(zone, '%VERSION%', version)
        zone = string.replace(zone, '%DOMAIN%', self.domain)

        zone_file = '/etc/namedb/master/' + self.domain + '.db'
        print "Creating DNS record"
        f = file(zone_file, 'w')
        f.write(zone)
        f.close()

        named_conf_string = """
        zone "%DOMAIN%" {
        type master;
        file "%ZONE%";
        allow-update { none; };
        allow-transfer {
            123.456.789.2;
        };
        notify no;
        };
        """
        named_conf_string = string.replace(named_conf_string,
                                           '%DOMAIN%', self.domain)
        named_conf_string = string.replace(named_conf_string,
                                           '%ZONE%', zone_file)

        print "Adding DNS record to the named.conf"
        f = file('/etc/namedb/named.conf', 'a')
        f.write(named_conf_string)
        f.close()

    def create_vhost(self):
        """Creates Apache's virtual host"""

        vhost = """
<virtualhost 123.456.789.1:80>
    ServerAdmin webmaster@domain.net
    DocumentRoot "/usr/home/%USER%/public_html"
    ServerName %DOMAIN%
    ServerAlias www.%DOMAIN%
    ErrorLog "/usr/home/%USER%/error_log"
    CustomLog "/usr/home/%USER%/access_log" common
    <directory "/usr/home/%USER%/public_html>
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </directory>
</virtualhost>
"""
        print "Creating VirtualHost"

        vhost = string.replace(vhost, "%USER%", self.user)
        vhost = string.replace(vhost, "%DOMAIN%", self.domain)

        f = file('/usr/local/etc/apache22/vhosts/' + self.domain, 'w')
        f.write(vhost)
        f.close()

    def restart_named(self):
        """Restarts named"""

        print "Restarting named"
        args = ['killall', 'named']
        print Popen(args, stdout = PIPE).communicate()[0]
        time.sleep(7)
        args =['/etc/rc.d/named', 'forcestart']
        print Popen(args, stdout = PIPE).communicate()[0]

    def restart_httpd(self):
        """Restarts httpd"""

        print "Restarting httpd"
        args = ['/usr/local/etc/rc.d/apache22', 'restart']
        print Popen(args, stdout = PIPE).communicate()[0]

    def get_uid(self, user):
        import re
        output = Popen(['id', user], stdout = PIPE).communicate()[0]
        matches = re.search('(?< =uid=)\d+', output)
        return int(matches.group(0))

    def get_gid(self, group):
        import re
        output = Popen(['id', group], stdout = PIPE).communicate()[0]
        matches = re.search('(?<=gid=)\d+', output)
        return int(matches.group(0))

if __name__ == "__main__":
    import sys
    if len(sys.argv) < 3:
        sys.exit("Usage: %s username domain" % sys.argv[0])

    user, domain = sys.argv[1], sys.argv[2]
    u = User(user)
    host = VirtualHost(user, domain)

Скрипт запускается так:

vhost.py имя_системного_пользователя домен

Перед использованием скрипта, естественно, нужно заменить доменное имя и ip-адрес на свои.

Связанные записи

Отзывов (2) на «Скрипт для создания виртуальных хостов Apache на FreeBSD»

  1. ffsdmad пишет:

    Аа, упёр идею :) http://breys.ru/blog/388.html
    но ваш скрипт круче, так как видимо рассчитан не на домашний хостинг
    а для дома думаю в нём смысла нет

    [Ответить]

  2. 0utPunk пишет:

    Да, вот такой я нехороший :) Скрипт используется уже около года на боевых серверах, и в последнее время научился еще кое-чему :) Кто у кого спер – неясно. Но, признаюсь, запостил я это, когда увидел у вас похожую заметку:)

    [Ответить]

Ваш отзыв