commit 05e695df5b1efa63d53a5043e0d73985d2304fca Author: Simon Vieille Date: Tue Jul 30 23:34:41 2019 +0200 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..97fe706 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/helpers/crypt diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0b9b535 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ + + +build-crypt: + gcc -lcrypt ./src/crypt/crypt.c -o ./helpers/crypt diff --git a/bin/vhost-add b/bin/vhost-add new file mode 100755 index 0000000..4cecc28 --- /dev/null +++ b/bin/vhost-add @@ -0,0 +1,130 @@ +#!/bin/sh + +export SCRIPT_NAME="$(realpath "$0")" +export SCRIPT_PATH="$(dirname "$SCRIPT_NAME")" +export PATH="$SCRIPT_PATH/../helpers/:$PATH" + +cd "$SCRIPT_PATH/../" + +. ./etc/config + +exit_if_empty() { + if [ -z "$1" ]; then + if [ -n "$2" ]; then + printf "$2\n" + fi + + exit 1 + fi +} + +########################## +# Collect of information # +########################## + +TITLE="Deblan network - New website" + +DOMAIN="$(form_input -t "$TITLE" -l "Domain" -r)" + +exit_if_empty "$DOMAIN" "Aborded! (DOMAIN_EMPTY)" + +DOMAIN_ALIASES="$(form_input -t "$TITLE" -l "Aliase(s)")" + +WEB_HTTP="$(form_yes_no -t "$TITLE" -l "Support of HTTP (recommanded)")" +WEB_HTTPS="$(form_yes_no -t "$TITLE" -l "Support of HTTPS (recommanded)")" + +if [ "$WEB_HTTP" = "yes" -a "$WEB_HTTPS" = "yes" ]; then + WEB_HTTPS_FORCE="$(form_yes_no -t "$TITLE" -l "Redirect HTTP to HTTPS (recommanded)")" +fi + +#if [ "$WEB_HTTPS" = "yes" ]; then +# WEB_HTTPS_GENERATE_CERTIFICATE="$(form_yes_no -t "$TITLE" -l "Retrieve certificate using LE")" +#fi + +DOCUMENT_ROOT="$(form_input -t "$TITLE" -l "Document Root" -d "/var/www/service-web/www/$DOMAIN/web")" + +PHP_ENABLED="$(form_yes_no -t "$TITLE" -l "Support of PHP")" + +exit_if_empty "$DOCUMENT_ROOT" "Aborded! (SYSTEM_USERNAME_EMPTY)" + +if [ "$PHP_ENABLED" = "yes" ]; then + PHP_VERSION="$(form_choices -t "$TITLE" -l "Version of PHP" \ + "7.3" "PHP 7.3 (recommanded)" \ + "7.2" "PHP 7.2" \ + "7.1" "PHP 7.1" \ + "5.6" "PHP 5.6 (not recommanded)")" + + exit_if_empty "$PHP_VERSION" "Aborded! (PHP_VERSION_EMPTY)" +fi + +USER_PASSWORD="$(tr -dc "12345!@#$%qwertQWERTasdfgASDFGzxcvbZXCVB" < /dev/urandom | head -c 16)" + +SYSTEM_USER_USERNAME="$(form_input -t "$TITLE" -l "System username" -d "web" -r)" +SYSTEM_USER_GROUP="webgroup" +SYSTEM_USER_PASSWORD=$(export PASSWORD="$USER_PASSWORD"; export SALT=$(date +'%S'); crypt) + +exit_if_empty "$SYSTEM_USER_USERNAME" "Aborded! (SYSTEM_USERNAME_EMPTY)" + +############################### +# User and directory creation # +############################### + +useradd -G "$SYSTEM_USER_GROUP" -s /bin/zsh -m -p "$SYSTEM_USER_PASSWORD" -d "/services/web/www/$DOMAIN" "$SYSTEM_USER_USERNAME" -k /etc/skel/ +chgrp www-data "/services/web/www/$DOMAIN" +chmod o-r "/services/web/www/$DOMAIN" + +####################### +# Make configurations # +####################### + +SERVICES_TO_RELOAD="apache2" + +SYSTEM_USER_ID="$(id -u "$SYSTEM_USER_USERNAME")" +PHP_FPM_PORT=$(($SYSTEM_USER_ID + 12000)) + +export DOMAIN +export DOMAIN_ALIASES +export DOCUMENT_ROOT +export SYSTEM_USER_USERNAME +export SYSTEM_USER_GROUP +export PHP_ENABLED +export PHP_FPM_PORT +export WEB_HTTPS_FORCE + +if [ "$WEB_HTTP" = "yes" ]; then + VHOST_FILE_SA="/etc/apache2/sites-available/${DOMAIN}.${WEB_HTTP_PORT}.conf" + VHOST_FILE_SE="/etc/apache2/sites-enabled/${DOMAIN}.${WEB_HTTP_PORT}.conf" + PORT=$WEB_HTTP_PORT template vhost-http > "$VHOST_FILE_SA" + + ln -rs "$VHOST_FILE_SA" "$VHOST_FILE_SE" +fi + +if [ "$WEB_HTTPS" = "yes" ]; then + VHOST_FILE_SA="/etc/apache2/sites-available/${DOMAIN}.${WEB_HTTPS_PORT}.conf" + VHOST_FILE_SE="/etc/apache2/sites-enabled/${DOMAIN}.${WEB_HTTP_PORT}.conf" + + PORT=$WEB_HTTPS_PORT template vhost-https > "$VHOST_FILE_SA" + + ln -rs "$VHOST_FILE_SA" "$VHOST_FILE_SE" +fi + +if [ "$PHP_ENABLED" = "yes" ]; then + if [ "$PHP_VERSION" = "5.6" ]; then + SERVICES_TO_RELOAD="$SERVICES_TO_RELOAD php5-fpm" + PHP_FPM_FILE="/etc/php5/fpm/pool.d/${SYSTEM_USER_USERNAME}.conf" + else + SERVICES_TO_RELOAD="$SERVICES_TO_RELOAD php${PHP_VERSION}-fpm" + PHP_FPM_FILE="/etc/php/$PHP_VERSION/fpm/pool.d/${SYSTEM_USER_USERNAME}.conf" + fi + + template php-fpm > "$PHP_FPM_FILE" +fi + +for SERVICE in $SERVICES_TO_RELOAD; do + service $SERVICE reload +done + +printf ",------------------------------------------,\n" +printf "| Nom d'utilisateur : %-20s |\n" "$SYSTEM_USER_USERNAME" +printf "| Mot de passe : %-25s |\n" "$USER_PASSWORD" +printf "'------------------------------------------'\n" diff --git a/etc/config b/etc/config new file mode 100644 index 0000000..8bfa32c --- /dev/null +++ b/etc/config @@ -0,0 +1,3 @@ +WEB_HTTP_PORT=81 +WEB_HTTPS_PORT=444 +PHP_BIN=/usr/bin/php7.1 diff --git a/helpers/form_choices b/helpers/form_choices new file mode 100755 index 0000000..e522481 --- /dev/null +++ b/helpers/form_choices @@ -0,0 +1,30 @@ +#!/bin/sh + +TITLE= +LABEL= +ERROR=0 +HEIGHT=25 +MENU_HEIGHT=16 +WIDTH=50 + +PARAMS= + +while getopts "t:l:d:h:w:m:r" option; do + case "$option" in + l) LABEL="$OPTARG";; + t) TITLE="$OPTARG";; + h) HEIGHT="$OPTARG";; + m) MENU_HEIGHT="$OPTARG";; + w) WIDTH="$OPTARG";; + :) ERROR=1;; + ?) ERROR=1;; + esac +done + +if [ $ERROR -eq 1 ]; then + exit 1 +fi + +shift $((OPTIND-1)) + +echo "$(whiptail --title "$TITLE" --menu "$LABEL" $HEIGHT $WIDTH $MENU_HEIGHT "$@" 3>&1 1>&2 2>&3)" diff --git a/helpers/form_input b/helpers/form_input new file mode 100755 index 0000000..8305480 --- /dev/null +++ b/helpers/form_input @@ -0,0 +1,46 @@ +#!/bin/sh + +TITLE= +LABEL= +DEFAULT= +REQUIRED=0 +ERROR=0 +HEIGHT=8 +WIDTH=50 + +while getopts "t:l:d:h:w:r" option; do + case "$option" in + t) TITLE="$OPTARG";; + l) LABEL="$OPTARG";; + d) DEFAULT="$OPTARG";; + h) HEIGHT="$OPTARG";; + w) WIDTH="$OPTARG";; + r) REQUIRED=1;; + :) ERROR=1;; + ?) ERROR=1;; + esac +done + +if [ $ERROR -eq 1 ]; then + exit 1 +fi + +VALUE= +DO_ASK=1 + +while [ $DO_ASK -eq 1 ]; do + VALUE="$(whiptail --title "$TITLE" --inputbox "$LABEL" $HEIGHT $WIDTH "$DEFAULT" 3>&1 1>&2 2>&3)" + STATUS=$? + + if [ $STATUS -eq 0 ]; then + if [ $REQUIRED -eq 1 -a -z "$VALUE" ]; then + DO_ASK=1 + else + DO_ASK=0 + fi + else + exit $STATUS + fi +done + +echo "$VALUE" diff --git a/helpers/form_yes_no b/helpers/form_yes_no new file mode 100755 index 0000000..524de92 --- /dev/null +++ b/helpers/form_yes_no @@ -0,0 +1,28 @@ +#!/bin/sh + +TITLE= +LABEL= +ERROR=0 +HEIGHT=8 +WIDTH=50 + +while getopts "t:l:d:h:w:r" option; do + case "$option" in + l) LABEL="$OPTARG";; + t) TITLE="$OPTARG";; + h) HEIGHT="$OPTARG";; + w) WIDTH="$OPTARG";; + :) ERROR=1;; + ?) ERROR=1;; + esac +done + +if [ $ERROR -eq 1 ]; then + exit 1 +fi + +if (whiptail --title "$TITLE" --yesno "$LABEL" $HEIGHT $WIDTH 3>&1 1>&2 2>&3) then + printf "yes" +else + printf "no" +fi diff --git a/helpers/template b/helpers/template new file mode 100755 index 0000000..5823f22 --- /dev/null +++ b/helpers/template @@ -0,0 +1,5 @@ +#!/bin/sh + +. ./etc/config + +$PHP_BIN -dvariables_order=EGPCS ./helpers/twigc -E -d ./src/templates/ < "src/templates/${1}.twig" diff --git a/helpers/twigc b/helpers/twigc new file mode 100755 index 0000000..67d6a3b Binary files /dev/null and b/helpers/twigc differ diff --git a/src/crypt/crypt.c b/src/crypt/crypt.c new file mode 100644 index 0000000..5d0562a --- /dev/null +++ b/src/crypt/crypt.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + char* password; + char* salt; + + if (argc == 3) { + password = argv[1]; + salt = argv[2]; + } else { + password = getenv("PASSWORD"); + salt = getenv("SALT"); + } + + if (password == NULL) { + password = ""; + } + + if (salt == NULL) { + salt = ""; + } + + size_t password_length = strlen(password); + size_t salt_length = strlen(salt); + + if (password_length == 0 || salt_length == 0) { + printf("Usage:\n"); + printf(" %s \n", argv[0]); + printf(" PASSWORD= SALT= %s\n", argv[0]); + + return 1; + } + + printf("%s\n", crypt(password, salt)); + + return 0; +} diff --git a/src/templates/php-fpm.twig b/src/templates/php-fpm.twig new file mode 100644 index 0000000..8770be5 --- /dev/null +++ b/src/templates/php-fpm.twig @@ -0,0 +1,20 @@ +[{{ SYSTEM_USER_USERNAME }}] +user = {{ SYSTEM_USER_USERNAME }} +group = {{ SYSTEM_USER_GROUP }} +listen = 127.0.0.1:{{ PHP_FPM_PORT }} +listen.owner = {{ SYSTEM_USER_USERNAME }} +listen.group = {{ SYSTEM_USER_GROUP }} +;listen.mode = 0660 +listen.allowed_clients = 127.0.0.1 +pm = dynamic +pm.max_children = 5 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +;pm.max_requests = 500 +pm.process_idle_timeout = 250s +php_value[upload_max_filesize] = 300M +php_value[post_max_size] = 300M +php_value[max_execution_time] = 250 +php_value[memory_limit] = 250M +chdir = / diff --git a/src/templates/vhost-http.twig b/src/templates/vhost-http.twig new file mode 100644 index 0000000..4dc6f3c --- /dev/null +++ b/src/templates/vhost-http.twig @@ -0,0 +1,34 @@ +{% block body %} + + ServerName {{ DOMAIN }} +{% if DOMAIN_ALIASES is not empty %} + ServerAlias {{ DOMAIN_ALIASES }} +{% endif %} + + DocumentRoot {{ DOCUMENT_ROOT }} + SuexecUserGroup {{ SYSTEM_USER_USERNAME }} {{ SYSTEM_USER_GROUP }} + ErrorLog /services/web/logs/{{ DOMAIN }}.log + CustomLog /services/web/logs/{{ DOMAIN }}.log combined +{% if WEB_HTTPS_FORCE = "yes" %} + + Redirect permanent / https://{{ DOMAIN }}/ +{% endif %} + + + Options -Indexes +FollowSymLinks +MultiViews + AllowOverride All + Order allow,deny + allow from all + Options +ExecCGI + +{% if PHP_ENABLED == "yes" %} + + + ' + SetHandler "proxy:fcgi://127.0.0.1:{{ PHP_FPM_PORT }}/" + ' + +{% endif %} +{% block extra %}{% endblock %} + +{% endblock %} diff --git a/src/templates/vhost-https.twig b/src/templates/vhost-https.twig new file mode 100644 index 0000000..1947427 --- /dev/null +++ b/src/templates/vhost-https.twig @@ -0,0 +1,23 @@ +{% extends "vhost-http.twig" %} + +{% block body %} + +{{ parent()|trim }} + +{% endblock %} + +{% block extra %} +{{ parent() ? (parent() ~ "\n") : '' }} + SSLEngine on + + SSLCertificateFile /etc/letsencrypt/live/deblan.org/cert.pem + SSLCertificateKeyFile /etc/letsencrypt/live/deblan.org/privkey.pem + SSLCACertificateFile /etc/letsencrypt/live/deblan.org/chain.pem + + # SSLCertificateFile /etc/letsencrypt/live/{{ DOMAIN }}/cert.pem + # SSLCertificateKeyFile /etc/letsencrypt/live/{{ DOMAIN }}/privkey.pem + # SSLCACertificateFile /etc/letsencrypt/live/{{ DOMAIN }}/chain.pem + + BrowserMatch "MSIE [2-6]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0 + BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown +{% endblock %}