diff --git a/.env.example b/.env.example index 6572978..5eff2e3 100644 --- a/.env.example +++ b/.env.example @@ -10,4 +10,11 @@ ip6='::1' # Mysql account with enought privileges to create users and DB mysqluser='root' -mysqlpassword='1 very long & secure password or passphrase!' \ No newline at end of file +mysqlpassword='1 very long & secure password or passphrase!' + +# Services +phpservice='php8.1-fpm' + +# Reserved names +maindomain='yeswiki.pro' +reservedsubdomains='www,stats,mail,sql,cron,modelesolo,modeleferme' \ No newline at end of file diff --git a/templates/nginx-yeswiki.pro.php b/templates/nginx-maindomain.php similarity index 69% rename from templates/nginx-yeswiki.pro.php rename to templates/nginx-maindomain.php index b2939ac..9924b96 100644 --- a/templates/nginx-yeswiki.pro.php +++ b/templates/nginx-maindomain.php @@ -5,11 +5,12 @@ server { listen [::]:80; listen 80; - server_name e($domain)?>; + server_name www.e($domain)?> e($domain)?>; return 301 https://e($domain)?>$request_uri; } + server { listen [::]:443 ssl http2; listen 443 ssl http2; @@ -22,11 +23,9 @@ server { return 301 $scheme://e($domain)?>$request_uri; } - + server { - # listen [::]:443 ssl http2 accept_filter=dataready; # for FreeBSD - # listen 443 ssl http2 accept_filter=dataready; # for FreeBSD listen [::]:443 ssl http2; listen 443 ssl http2; @@ -51,14 +50,17 @@ server { index index.php index.html index.htm; location / { - try_files $uri $uri/ /index.php$is_args$args; + + auth_basic "Accès restreint"; + auth_basic_user_file /home/e($user)?>/e($domain)?>/.htpasswd; + + try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { - fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass unix:/var/run/php-fpm-e($user)?>.sock; - fastcgi_index index.php; - include fastcgi.conf; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:/var/run/php-fpm-e($user)?>.sock; + fastcgi_index index.php; + include fastcgi.conf; } } - diff --git a/templates/php-fpm.php b/templates/php-fpm.php new file mode 100644 index 0000000..082e5d2 --- /dev/null +++ b/templates/php-fpm.php @@ -0,0 +1,12 @@ +[e($user)?>] +user = e($user)?> +group = e($user)?> +listen = /var/run/php-fpm-e($user)?>.sock +listen.owner = www-data +listen.group = www-data +pm = dynamic +pm.max_children = 75 +pm.start_servers = 10 +pm.min_spare_servers = 5 +pm.max_spare_servers = 20 +pm.process_idle_timeout = 10 \ No newline at end of file diff --git a/utils.inc.php b/utils.inc.php index 8b79ebf..b971c73 100644 --- a/utils.inc.php +++ b/utils.inc.php @@ -39,9 +39,9 @@ function generateUserFromDomain($domain, $recursive = null) if ($recursive == 100) { throw new Exception('Too much users found, 100 that is too much for '.$domain); } - $user = str_split(str_replace(['yeswiki.pro', '-', '.'], '', $domain), 30)[0].$recursive; + $user = str_split(str_replace([$_SERVER['maindomain'], '-', '.'], '', $domain), 30)[0].$recursive; // try anthor username if user exists or if reserved name - if (checkIfUserExist($user) || in_array($user, ['www', 'stats', 'mail', 'sql', 'cron', 'modelesolo', 'modeleferme'])) { + if (checkIfUserExist($user) || in_array($user, explode(',', $_SERVER['reservedsubdomains']))) { if ($recursive === null) { $recursive = 1; } @@ -104,21 +104,24 @@ function generatePassword($length = 32, $add_dashes = false, $available_sets = ' return $dash_str; } -function createSQLUserAndDatabase($user) +function createSQLUserAndDatabase($user, $type) { $pass = generatePassword(); - exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e \'CREATE DATABASE IF NOT EXISTS '.$user.';\'', $output); - exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "CREATE USER IF NOT EXISTS \''.$user.'\'@\'localhost\' IDENTIFIED BY \''.$pass.'\';"', $output); - exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "GRANT ALL PRIVILEGES ON '.$user.'.* TO \''.$user.'\'@\'localhost\';"', $output); - exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "FLUSH PRIVILEGES;"', $output); + exec('mysql -u '.$_SERVER['mysqluser'].' -p\''.$_SERVER['mysqlpassword'].'\' -e \'CREATE DATABASE IF NOT EXISTS '.$user.';\'', $output); + exec('mysql -u '.$_SERVER['mysqluser'].' -p\''.$_SERVER['mysqlpassword'].'\' -e "CREATE USER IF NOT EXISTS \''.$user.'\'@\'localhost\' IDENTIFIED BY \''.$pass.'\';"', $output); + exec('mysql -u '.$_SERVER['mysqluser'].' -p\''.$_SERVER['mysqlpassword'].'\' -e "GRANT ALL PRIVILEGES ON '.$user.'.* TO \''.$user.'\'@\'localhost\';"', $output); + exec('mysql -u '.$_SERVER['mysqluser'].' -p\''.$_SERVER['mysqlpassword'].'\' -e "FLUSH PRIVILEGES;"', $output); + $databaseModel = ($type === 'solo') ? $_SERVER['solomodel'] : $_SERVER['fermemodel']; + exec('mysqldump -u '.$_SERVER['mysqluser'].' -p\''.$_SERVER['mysqlpassword'].'\' -v '.$databaseModel.' | mysql -u '.$user.' -p\''.$pass.'\' -D '.$user, $output); + // TODO: add first user and make him admin return ['database' => $user, 'user' => $user, 'password' => $pass]; } function removeMySQLUserAndDatabase($user) { - exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e \'DROP DATABASE IF EXISTS '.$user.';\'', $output); - exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "DROP USER IF EXISTS \''.$user.'\'@\'localhost\';"', $output); - exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "FLUSH PRIVILEGES;"', $output); + exec('mysql -u '.$_SERVER['mysqluser'].' -p\''.$_SERVER['mysqlpassword'].'\' -e \'DROP DATABASE IF EXISTS '.$user.';\'', $output); + exec('mysql -u '.$_SERVER['mysqluser'].' -p\''.$_SERVER['mysqlpassword'].'\' -e "DROP USER IF EXISTS \''.$user.'\'@\'localhost\';"', $output); + exec('mysql -u '.$_SERVER['mysqluser'].' -p\''.$_SERVER['mysqlpassword'].'\' -e "FLUSH PRIVILEGES;"', $output); return; } @@ -140,28 +143,60 @@ function removeUnixUser($user) function createNginxConfig($domain, $user, $herseUser, $hersePass) { - // Create new Plates instance - $templates = new League\Plates\Engine('./templates'); - - // Render a template - echo $templates->render('nginx-yeswiki.pro', ['domain' => $domain, 'user' => $user]); - - addHerse($nginxFile, $herseUser, $hersePass); + $nginxFile = '/etc/nginx/conf.d/'.$domain.'.conf'; + if (empty($herseUser) && empty($hersePass)) { + // no herse needed + } elseif (empty($herseUser) || empty($hersePass)) { + throw new Exception('You need an username AND a password to add a herse.'); + } else { + // add password file to domain + file_put_contents( + '/home'.'/'.$user.'/'.$domain.'/.htpasswd', + $herseUser.':'.password_hash($hersePass, PASSWORD_BCRYPT) + ); + } + echo 'DIR:'.dirname(__FILE__); + $templates = new League\Plates\Engine(dirname(__FILE__).'/templates'); + file_put_contents( + $nginxFile, + $templates->render( + 'nginx-maindomain', + [ + 'domain' => $domain, + 'user' => $user, + 'herseUser' => $herseUser, + 'hersePass' => $hersePass, + ] + ) + ); + exec('service nginx force-reload', $output); } -function removeNginxConfig($domain, $user) +function removeNginxConfig($domain) { + $nginxFile = '/etc/nginx/conf.d/'.$domain.'.conf'; + unlink($nginxFile); + exec('service nginx force-reload', $output); } function createPhpFpmConfig($user) { + $phpVersion = str_replace(['php', '-fpm'], '', $_SERVER['phpservice']); + $phpConfFile = '/etc/php/'.$phpVersion.'/fpm/pool.d/'.$user.'.conf'; + $templates = new League\Plates\Engine(dirname(__FILE__).'/templates'); + file_put_contents($phpConfFile, $templates->render('php-fpm', ['user' => $user])); + exec('service '.$_SERVER['phpservice'].' reload', $output); } function removePhpFpmConfig($user) { + $phpVersion = str_replace(['php', '-fpm'], '', $_SERVER['phpservice']); + $phpConfFile = '/etc/php/'.$phpVersion.'/fpm/pool.d/'.$user.'.conf'; + unlink($phpConfFile); + exec('service '.$_SERVER['phpservice'].' reload', $output); } -function copyYesWikiFiles($domain, $user, $type) +function copyYesWikiFiles($domain, $user) { $destDir = '/home'.'/'.$user.'/'.$domain; exec('mkdir -p '.$destDir, $output); @@ -169,14 +204,6 @@ function copyYesWikiFiles($domain, $user, $type) return; } -function copyYesWikiDatabase($user, $type) -{ - $databaseModel = ($type === 'solo') ? $_SERVER['solomodel'] : $_SERVER['fermemodel']; - exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "DUPLICATE '.$databaseModel.' TO '.$user.';"', $output); - // TODO : handle errors - return; -} - function checkHerse($herseUser, $hersePass) { if (empty($herseUser) && empty($hersePass)) { @@ -186,22 +213,3 @@ function checkHerse($herseUser, $hersePass) } return true; // herse needed } - -function addHerse(&$nginxFile, $herseUser, $hersePass) -{ - if (empty($herseUser) && empty($hersePass)) { - return ; // no herse needed - } elseif (empty($herseUser) || empty($hersePass)) { - throw new Exception('You need an username AND a password to add a herse.'); - } else { - //add herse to the domain - echo $nginxFile; - } -} - -function removeYesWiki($domain, $user) -{ - // enlever la db et le user sql - // enlever la config nginx et la conf php-fpm - // enlever le user unix et son home -} diff --git a/yeswiki-installer.php b/yeswiki-installer.php index 3ad9662..950ae04 100755 --- a/yeswiki-installer.php +++ b/yeswiki-installer.php @@ -75,11 +75,10 @@ if (0 == posix_getuid()) { $input = $climate->confirm('Is it all good ?'); if ($confirm || $input->confirmed()) { $unixUser = createUnixUserWithQuota($user, $quota); - $dbUser = createSQLUserAndDatabase($user); + $dbUser = createSQLUserAndDatabase($user, $type); + copyYesWikiFiles($domain, $user); createNginxConfig($domain, $user, $herseUser, $hersePass); createPhpFpmConfig($user); - copyYesWikiFiles($domain, $user, $type); - copyYesWikiDatabase($user, $type); $climate->shout( 'The yeswiki was successfully installed on '.$domain.', congrats ! 🎉'."\n" .' Unix user : '.$unixUser['user'].' with password : '.$unixUser['password'].' was created.'."\n" diff --git a/yeswiki-remover.php b/yeswiki-remover.php index baf2096..25586b7 100755 --- a/yeswiki-remover.php +++ b/yeswiki-remover.php @@ -42,10 +42,15 @@ if (0 == posix_getuid()) { $climate->out('This will remove '.$domain.' with the user '.$user.''."\n"); $input = $climate->confirm('Shall we really do it ?'); if ($confirm || $input->confirmed()) { - removeUnixUser($user); - removeNginxConfig($domain, $user); - removePhpFpmConfig($user); + // enlever la db et le user sql removeMySQLUserAndDatabase($user); + + // enlever la config nginx et la conf php-fpm + removeNginxConfig($domain); + removePhpFpmConfig($user); + + // enlever le user unix et son home + removeUnixUser($user); $climate->shout( 'The yeswiki on '.$domain.' was successfully removed, congrats ! 🎉'."\n" );