#!/usr/bin/php
<?php
/**
* Create Website
*
* Entirely in house, very system dependent. Works on an Ubuntu installation with Apache and Mysql at pretty much default preferences.
* If you're moving this to a new server you will very likely have to re-write parts of it (paths etc)
*
* @license Public Domain
* @author Sid Karunaratne
*/
error_reporting(0);
// Options: user, website, has_ssh, has_ftp, has_db
$opts = getopt('u:w:sfdhi:');
$user = $opts['u'];
$website = $opts['w'];
$ip = array_key_exists('i',$opts) ? $opts['i'] : get_ip();
$has_ssh = (bool) array_key_exists('s',$opts);
$has_ftp = (bool) array_key_exists('f',$opts);
$has_db = (bool) array_key_exists('d',$opts);
$help = (bool) array_key_exists('h',$opts);
$err = fopen('php://stderr','w');
$out = fopen('php://stdout','w');
$db = null;
if ($help || (!$user || !$website))
{
display_help();
exit;
}
if (posix_getuid() !== 0)
{
_err('I need to be run as root');
exit(1);
}
if (site_exists($website))
{
_err('The website already exists, if you want to add more users to control this site you are going to have to do it manually');
exit(1);
}
# Check with the user we are doing the right thing
_err("About to create the account $user with the website $website with the virtual host listening on $ip");
$str = $has_ssh ? '' : 'NOT ';
_err($str. "allowing SSH login");
$str = $has_ftp ? '' : 'NOT ';
_err($str. "allowing FTP login");
$str = $has_db ? '' : 'NOT ';
_err($str. "creating a database");
_err("Press y/n to confirm action: ", false);
if (!in_array(_in(), array('y', 'Y', 'yes', 'true')))
{
_err('Exiting');
exit(1);
}
require('/etc/.create-website');
connect_db();
if (!user_exists($user))
{
_out("User '$user' does not exist and will be created");
`adduser --gecos "" $user`;
}
if ($has_ssh && !user_has_ssh($user))
{
_out("User '$user' is being given SSH access");
`echo 'AllowUsers $user' >> /etc/ssh/sshd_config`;
}
if ($has_ftp && !user_has_ftp($user))
{
_out("User '$user' is being given chrooted FTP access");
`echo $user >> /etc/vsftpd.user_list`;
}
if ($has_db)
{
# Create DB
global $db;
_out("Database being created (or already exists), user being created and access to database being given");
$mysql_password = prompt_silent("Please enter a MySQL password: ");
$db_name = str_replace('.', '_', $website);
mysql_query("CREATE DATABASE IF NOT EXISTS `$db_name`");
mysql_query("CREATE USER '$user'@'%' IDENTIFIED BY '".mysql_real_escape_string($mysql_password)."'");
mysql_query("GRANT USAGE ON * . * TO '$user'@'%' IDENTIFIED BY '".mysql_real_escape_string($mysql_password)."'");
mysql_query("GRANT ALL PRIVILEGES ON `$db_name` . * TO '$user'@'%'");
mysql_query("FLUSH PRIVILEGES");
}
_out("Virtual host for $website is being created");
# Create vhost
mkdir("/home/$user/$website", 0755, true);
chown("/home/$user/$website", $user);
chgrp("/home/$user/$website", $user);
mkdir("/home/$user/log/www/$website", 0755, true);
chown("/home/$user/log/www/$website", $user);
chgrp("/home/$user/log/www/$website", $user);
$vhost = "<VirtualHost {$ip}:80>
ServerAdmin $user@keepthinking.it
DocumentRoot /home/$user/$website
ServerName $website
ServerAlias www.$website
ErrorLog /home/$user/log/www/$website/error.log
CustomLog /home/$user/log/www/$website/access.log combined
</VirtualHost>";
file_put_contents("/etc/apache2/sites-available/$website", $vhost);
symlink("/etc/apache2/sites-available/$website", "/etc/apache2/sites-enabled/$website");
_out("Configuration for the logrotation are being put in place");
# Adding logrotate
$logrotate = "/home/$user/log/www/$website/*.log {
weekly
missingok
rotate 52
compress
notifempty
copytruncate
}
";
file_put_contents("/etc/logrotate.d/apache2_{$user}_{$website}", $logrotate);
_err("Services are being reloaded for the changes to take effect");
`service apache2 reload`;
`service vsftpd reload`;
`service ssh reload`;
/**************************
/* HERE ARE THE FUNCTION THAT YOU SHOULDN'T NEED TO TOUCH
**************************/
function user_exists($user)
{
$users = file('/etc/passwd', FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
foreach ($users as $line)
{
$components = explode(':', $line);
if ($components[0] === $user)
return true;
}
return false;
}
function site_exists($website)
{
return file_exists("/etc/apache2/sites-enabled/$website");
}
function user_has_ssh($user)
{
$config = file('/etc/ssh/sshd_config', FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
foreach ($config as $line)
{
if (strncasecmp($line, 'AllowUsers', 10) === 0)
if (in_array($user, explode(' ', $line)))
return true;
}
return false;
}
function user_has_ftp($user)
{
$users = file('/etc/vsftpd.user_list', FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
foreach ($users as $line)
{
if ($line === $user)
return true;
}
return false;
}
function connect_db()
{
global $db;
global $config;
$db = mysql_connect($config['mysql_host'], $config['mysql_username'], $config['mysql_password']);
mysql_select_db('mysql', $db);
echo mysql_error();
}
function display_help()
{
$help = "
SYNOPSIS:
create-website -u USER -w WEBSITE [-s|-f|-d|-h|-i <ip>]
DESCRIPTION:
Creates a new web site for a new user on the system. This
ncludes creating the user, the FTP account, the Database and
the virtual host
USER is the username of the owner of the web site. If the
account name doesn't exist it will be created. Must be a valid
UNIX and MySQL username
WEBSITE is the url of the site to be created. Must be a FQDN,
should not include the www prefix. Preferably should be lower-
case.
-s Allow SSH based logins for the user [default = false]
-f Allow FTP based logins for the user [default = false]
-d Create a database for the user [default = false]
-i The IP the virtual host will listen on, by default the IP of eth0
-h Show this help message";
_err($help);
}
/**
* Interactively prompts for input without echoing to the terminal.
* Requires a bash shell and won't work with safe_mode settings (Uses `shell_exec`)
* from: http://www.sitepoint.com/blogs/2009/05/01/interactive-cli-password-prompt-in-php/
*/
function prompt_silent($prompt = "Enter Password:")
{
$command = "/usr/bin/env bash -c 'echo OK'";
if (rtrim(shell_exec($command)) !== 'OK')
{
trigger_error("Can't invoke bash");
return;
}
$command = "/usr/bin/env bash -c 'read -s -p \"" . addslashes($prompt) . "\" mypassword && echo \$mypassword'";
$password = rtrim(shell_exec($command));
_out('');
return $password;
}
function get_ip()
{
return substr(`ifconfig | grep 'addr:' | head -n1 | awk '{print $2}' | sed 's/addr://'`, 0, -1);
}
function _err($msg, $nl=true) { global $err; if($nl) $msg.=PHP_EOL; fwrite($err, $msg); }
function _out($msg) { global $out; fwrite($out, $msg . PHP_EOL); }
function _in() { return trim(fgets(STDIN)); }
?>