#!/usr/bin/python
# Description : Virtual Host Manage Script
# Below is the json format description:
# 1. Add new user
# {"website":"www.baidu.com", "ftp":["user","passwd"], "mysql":["db_name","m_user","m_passwd"]}
# 2. Enable/Disable 1 (0=disable, 1=enable)
# {"manage":{"website":["www.baidu.com",0], "ftp":["user",1], "mysql":["m_user", "db_name",1]}}
# 3. Modify password for [ftp/mysql] (if you only modify ftp,then set mysql items "")
# {"ftp":["789","789", "new_passwd"], "mysql":["","","", ""]}
# 4. Restart Service for apache/ftp/mysql 1 (0=stop,1=start,2=restart)
# {"service":{"apache":1, "ftp":0, "mysql":0}}
# 5. Add/Delete/Modify/Query apache ServerAlias (Add=1,Delete=2,Modify=3,Query=4)
# {"alias":["zhuzusong.com","1","www.baidu.com www.iciba.com"]}
import os
import time
import subprocess
import SocketServer
import MySQLdb
import simplejson as json
class Add_User(SocketServer.StreamRequestHandler):
def setup(self):
self.connection = self.request
self.rfile = self.connection.makefile('rb', self.rbufsize)
self.wfile = self.connection.makefile('wb', self.wbufsize)
self.Error = []
self.Error_log = '/tmp/Add_User_%s.log' %(time.strftime('%Y%m%d'))
self.apache_document_root = '/data/www'
self.vhost_conf = '/etc/httpd/conf.d'
self.vuser_list = '/etc/vsftpd/vsftpd_login.txt'
self.vuser_conf = '/etc/vsftpd/vuser_conf'
def add_mysql_account(self, mysql_db, mysql_user, mysql_passwd):
try:
conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
cursor = conn.cursor()
rownumber = cursor.execute('select User from mysql.user where User="%s"' %mysql_user)
# make sure the mysql login username is unique !
assert cursor.rowcount == 0, 'mysql account %s is exist' %mysql_user
cursor.execute('create database %s' %mysql_db)
cursor.execute('grant all privileges on %s.* to "%s"@"%%" identified by "%s"' \
%(mysql_db, mysql_user, mysql_passwd))
cursor.close()
conn.close()
except Exception, error:
self.Error.append("Function(add_mysql_account) Error : %s" %error)
def del_mysql_account(self, mysql_db, mysql_user):
try:
conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
cursor = conn.cursor()
cursor.execute('drop database %s' %mysql_db)
cursor.execute('DELETE FROM mysql.user WHERE USER="%s" AND HOST="%%"' %mysql_user)
cursor.execute('DELETE FROM mysql.db WHERE USER="%s" AND db="%s"' %(mysql_user, mysql_db))
cursor.execute('flush privileges')
cursor.close()
conn.close()
except Exception, error:
self.Error.append("Function(del_mysql_account) Error : %s" %error)
def add_apache_vhost(self, website):
apache_document_root = self.apache_document_root
vhost_conf = self.vhost_conf
vhost_conf_template = '''<VirtualHost *:80>
ServerName %s
DocumentRoot %s/%s
ServerAlias %s
DirectoryIndex default.htm default.html default.php index.htm index.html index.php
php_admin_value open_basedir "%s/%s:/tmp"
<IfModule bw_mod.c>
BandWidthModule On
BandWidth all 4194304
MaxConnection all 500
</IfModule>
<Directory %s/%s>
AllowOverride All
Options +Includes
</Directory>
</VirtualHost>''' %(website, apache_document_root, website, website, apache_document_root, website, apache_document_root, website)
if os.path.isfile('%s/%s' %(vhost_conf, website)):
self.Error.append("vhost %s is exist" %website)
else:
try:
fd_vhost = open('%s/%s' %(vhost_conf, website), 'w')
fd_vhost.writelines(vhost_conf_template)
fd_vhost.close()
os.system('service httpd reload > /dev/null')
except Exception, error:
self.Error.append("Function(add_apache_vhost) Error : %s" %error)
def del_apache_vhost(self, website):
try:
vhost_conf = self.vhost_conf
os.remove('%s/%s' %(vhost_conf, website))
except OSError,error:
self.Error.append("Function(del_apache_vhost) Error:" %error)
def add_ftp_account(self, website, ftp_user, ftp_passwd):
vuser_list = self.vuser_list
vuser_conf = '%s/%s' %(self.vuser_conf, ftp_user)
apache_document_root = self.apache_document_root
vuser_conf_template = '''guest_enable=YES
guest_username=vuser
local_root=%s/%s
write_enable=yes
anon_world_readable_only=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES''' %(apache_document_root, website)
if os.path.isfile(vuser_conf):
self.Error.append("FTP account %s is exist" %ftp_user)
else:
try:
fd1 = open(vuser_conf,'w')
fd1.writelines(vuser_conf_template)
os.system('mkdir -p %s/%s' %(apache_document_root, website))
os.system('chmod 570 %s/%s' %(apache_document_root, website))
os.system('chown apache:vuser %s/%s' %(apache_document_root, website))
fd1.flush()
fd1.close()
fd2 = open(vuser_list, 'a')
fd2.write(ftp_user + '\n')
fd2.write(ftp_passwd + '\n')
fd2.flush()
fd2.close()
cmd = '/usr/bin/db_load -T -t hash -f %s "/etc/vsftpd/vsftpd_login.db"' %(vuser_list)
status = subprocess.Popen(cmd, shell=True,stderr = subprocess.PIPE)
except Exception,error:
self.Error.append("Function(add_ftp_account) Error : %s" %error)
def del_ftp_account(self, ftp_user, ftp_passwd):
vuser_list = self.vuser_list
vuser_conf = '%s/%s' %(self.vuser_conf, ftp_user)
os.remove(vuser_conf)
os.system("/bin/sed -i 'N;/%s\n%s/d' %s" %(ftp_user, ftp_passwd, vuser_list))
def enable_website(self, website):
vhost_conf = self.vhost_conf
cmd = 'mv %s/../disabled_website/%s %s/' %(vhost_conf, website, vhost_conf)
os.system(cmd)
os.system('service httpd reload > /dev/null')
def disable_website(self, website):
vhost_conf = self.vhost_conf
cmd = 'mv %s/%s %s/../disabled_website/' %(vhost_conf, website, vhost_conf)
os.system(cmd)
os.system('service httpd reload > /dev/null')
def enable_ftp(self,ftp_user):
cmd = 'mv %s/../vuser_disable/%s %s' %(self.vuser_conf, ftp_user, self.vuser_conf)
os.system(cmd)
def disable_ftp(self,ftp_user):
vuser_conf = '%s/%s' %(self.vuser_conf, ftp_user)
cmd = 'mv %s %s/../vuser_disable/' %(vuser_conf, self.vuser_conf)
os.system(cmd)
def enable_mysql(self, mysql_db, mysql_user):
conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
cursor = conn.cursor()
sql1 = 'update mysql.user set host="%%" where user="%s"' %(mysql_user)
sql2 = 'update mysql.db set host="%%" where user="%s" and db="%s"' %(mysql_user, mysql_db)
sql3 = 'flush privileges'
ret = cursor.execute(sql1)
ret = cursor.execute(sql2)
ret = cursor.execute(sql3)
cursor.close()
conn.close()
def disable_mysql(self, mysql_db, mysql_user):
conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
cursor = conn.cursor()
sql1 = 'update mysql.user set host="localhost" where user="%s"' %(mysql_user)
sql2 = 'update mysql.db set host="localhost" where user="%s" and db="%s"' %(mysql_user, mysql_db)
sql3 = 'flush privileges'
ret = cursor.execute(sql1)
ret = cursor.execute(sql2)
ret = cursor.execute(sql3)
cursor.close()
conn.close()
def modify_ftp_passwd(self, ftp_user, old_passwd, new_passwd):
check_passwd = 'no'
vuser_list = self.vuser_list
f = open(vuser_list)
while True:
f_ftp_user = f.readline().strip('\n')
f_old_passwd = f.readline().strip('\n')
if f_ftp_user != '' or f_old_passwd != '':
if ftp_user == f_ftp_user:
if old_passwd == f_old_passwd:
check_passwd = 'yes'
break
else:
self.Error.append("ftp password does not match: %s" %ftp_user)
else:
break
f.close()
if check_passwd == 'yes':
cmd1 = "/bin/sed -i '/%s/{n;s/%s/%s/}' %s" %(f_ftp_user, f_old_passwd, new_passwd, vuser_list)
cmd2 = '/usr/bin/db_load -T -t hash -f %s "/etc/vsftpd/vsftpd_login.db"' %(vuser_list)
os.system(cmd1)
os.system(cmd2)
def modify_mysql_passwd(self, mysql_db, mysql_user, old_passwd, new_passwd):
try:
# verify mysql_user passwd
conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
cursor = conn.cursor()
sql1 = 'select password from mysql.user where user="%s"' %mysql_user
sql2 = 'select password("%s")' %old_passwd
cursor.execute(sql1)
store_password = cursor.fetchall()[0][0]
cursor.execute(sql2)
old_passwd = cursor.fetchall()[0][0]
if old_passwd == store_password:
# verified ok then modify the passwd
sql3 = 'update mysql.user set password=PASSWORD("%s") where user="%s"' %(new_passwd, mysql_user)
sql4 = 'flush privileges'
ret = cursor.execute(sql3)
ret = cursor.execute(sql4)
cursor.close()
conn.close()
else:
self.Error.append("mysql password does not match: %s" %mysql_user)
except Exception, error:
self.Error.append("Function(modify_mysql_passwd) Error: %s" %error)
def handle(self):
self.data = self.rfile.readline().strip()
if self.data:
try:
recv_data = json.loads(self.data)
except Exception,error:
self.Error.append("Json Error : %s" %error)
if len(recv_data) == 3:
# for add_function
try:
website = recv_data['website']
ftp_user = recv_data['ftp'][0]
ftp_passwd = recv_data['ftp'][1]
mysql_db = recv_data['mysql'][0]
mysql_user = recv_data['mysql'][1]
mysql_passwd = recv_data['mysql'][2]
self.add_mysql_account(mysql_db, mysql_user, mysql_passwd)
self.add_apache_vhost(website)
self.add_ftp_account(website, ftp_user, ftp_passwd)
except Exception,error:
self.Error.append('handle(add) error: %s' %error)
# when the three function add_* run error, then clean data
if self.Error:
n = 0
for e in self.Error:
if e.find('add_mysql_account') > 0:
n += 1
if n == 0:
self.del_mysql_account(mysql_db, mysql_user)
self.del_apache_vhost(website)
self.del_ftp_account(ftp_user, ftp_passwd)
else:
self.del_apache_vhost(website)
self.del_ftp_account(ftp_user, ftp_passwd)
elif len(recv_data) == 2:
# for modify ftp/mysql passwd
try:
ftp_user = recv_data['ftp'][0]
ftp_old_passwd = recv_data['ftp'][1]
ftp_new_passwd = recv_data['ftp'][2]
mysql_db = recv_data['mysql'][0]
mysql_user = recv_data['mysql'][1]
mysql_old_passwd = recv_data['mysql'][2]
mysql_new_passwd = recv_data['mysql'][3]
if ftp_user != '':
self.modify_ftp_passwd(ftp_user, ftp_old_passwd, ftp_new_passwd)
if mysql_db != '':
self.modify_mysql_passwd(mysql_db, mysql_user, mysql_old_passwd, mysql_new_passwd)
except Exception,error:
self.Error.append('handle(modify) error: %s' %error)
elif len(recv_data) == 1:
if recv_data.keys() == ['manage']:
# for manage [website,ftp,mysql] [enable,disable]
try:
m_data = recv_data['manage']
website = m_data['website'][0]
website_stats = m_data['website'][1]
ftp_user = m_data['ftp'][0]
ftp_stats = m_data['ftp'][1]
mysql_user = m_data['mysql'][0]
mysql_db = m_data['mysql'][1]
mysql_stats = m_data['mysql'][2]
if website_stats == 0:
self.disable_website(website)
elif website_stats == 1:
self.enable_website(website)
if ftp_stats == 0:
self.disable_ftp(ftp_user)
elif ftp_stats == 1:
self.enable_ftp(ftp_user)
if mysql_stats == 0:
self.disable_mysql(mysql_db, mysql_user)
elif mysql_stats == 1:
self.enable_mysql(mysql_db, mysql_user)
except Exception,error:
self.Error.append('handle(manage) error: %s' %error)
elif recv_data.keys() == ['service']:
# for service [ftp/mysql/apache] [start/stop/restart]
try:
s_data = recv_data['service']
apache_status = s_data['apache']
ftp_status = s_data['ftp']
mysql_status = s_data['mysql']
if apache_status == 0:
os.system('service httpd stop > /dev/null')
elif apache_status == 1:
os.system('service httpd start > /dev/null')
elif apache_status == 2:
os.system('service httpd restart > /dev/null')
if ftp_status == 0:
os.system('service vsftpd stop > /dev/null')
elif ftp_status == 1:
os.system('service vsftpd start > /dev/null')
elif ftp_status == 2:
os.system('service vsftpd restart > /dev/null')
if mysql_status == 0:
os.system('service mysqld stop > /dev/null')
elif mysql_status == 1:
os.system('service mysqld start > /dev/null')
elif mysql_status == 2:
os.system('service mysqld restart > /dev/null')
except Exception,error:
self.Error.append('handle(service) error: %s' %error)
elif recv_data.keys() == ['alias']:
# for add/delete/modify/query apache ServerAlias
try:
alias_data = recv_data['alias']
website = alias_data[0]
signal = int(alias_data[1])
server_alias = alias_data[2]
website_path = self.vhost_conf + '/' + website
if os.path.isfile(website_path):
if signal == 4:
cmd = "/bin/egrep '#?ServerAlias' %s" %website_path
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
result = p.stdout.read()
# return ServerAlias
self.Error.append(' '.join(result.split()[1:]))
else:
cmd = "/bin/sed -i '/#\{0,1\}ServerAlias/c\ServerAlias %s' %s" %(server_alias, website_path)
os.system(cmd)
else:
self.Error.append('handle(alias) error: no such website %s' %website)
except Exception,error:
self.Error.append('handle(alias) error: %s' %error)
else:
self.Error.append('Json data error')
self.wfile.write(json.dumps(self.Error))
fd = open(self.Error_log,'a')
fd.write('%s %s %s\n' %(time.strftime('%Y-%m-%d %H:%M:%S'), self.data, self.Error))
fd.close()
if __name__ == '__main__':
HOST, PORT = '', 4444
server = SocketServer.ThreadingTCPServer((HOST, PORT),Add_User)
server.serve_forever()