Last active
November 12, 2019 09:36
-
-
Save othercodes/9deff8dd4c39376c2bbb5c8e43960b0d to your computer and use it in GitHub Desktop.
Apache virtual host generator.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# Virtual Host Generator | |
# | |
# Apache virtual host generator. | |
# | |
# Tested on: | |
# - CentOS Linux release 7.5.1804 (Core) | |
# - Ubuntu 16.04.3 LTS | |
# | |
# Execution: | |
# $ sudo bash vhost.sh [-s] [-f] [domain] [username] | |
# | |
# You can also move the script into the /usr/local/bin directory | |
# $ mv vhost.sh /usr/local/bin/vhost | |
# $ chmod +x /usr/local/bin/vhost | |
# $ sudo vhost [-s] [-f] [domain] [username] | |
# | |
# Options | |
# -s Deploy virtual host with SSL. | |
# -f Add domain entries to /etc/hosts file | |
# -v Display current version. | |
# -h Display help information. | |
# | |
# Changelog | |
# v1.0.0 | |
# - Initial release. | |
# | |
# v1.1.0 | |
# - Now the new users are creaded with /usr/sbin/nologin|/sbin/nologin as shell. | |
# | |
if [[ "$EUID" -ne 0 ]]; then | |
echo "PermissionError: Please run as root or with sudo." | |
exit 1 | |
fi | |
if [[ ! -f /etc/os-release ]]; then | |
echo "UndefinedOSError: Unable to determine the OS version." | |
exit 2 | |
fi | |
source /etc/os-release | |
case "$ID" in | |
centos) | |
APACHE_SERVICE_UNIT="httpd.service" | |
APACHE_SITES_AVAILABLE_DIR="/etc/httpd/conf.d" | |
APACHE_SITES_ENABLED_DIR="/etc/httpd/conf.d" | |
APACHE_GROUP_NAME="apache" | |
NOLOGIN_PATH="/sbin/nologin" | |
;; | |
ubuntu) | |
APACHE_SERVICE_UNIT="apache2.service" | |
APACHE_SITES_AVAILABLE_DIR="/etc/apache2/sites-available" | |
APACHE_SITES_ENABLED_DIR="/etc/apache2/sites-enabled" | |
APACHE_GROUP_NAME="www-data" | |
NOLOGIN_PATH="/usr/sbin/nologin" | |
;; | |
*) echo "Unsupported OS: $ID." ;; | |
esac | |
SITES_DIR="/var/www" | |
SITE_PUBLIC_DIR="public" | |
SITE_PRIVATE_DIR="private" | |
SITE_LOG_DIR="log" | |
SITE_CRT_DIR="crt" | |
SITE_CGI_DIR="cgi-bin" | |
VHOSTS_VERSION=1.1.0 | |
VHOST_WITH_SSL="NO" | |
ADD_TO_HOSTS_FILE="NO" | |
CFG_CHANGED="NO" | |
VHOST_SSL_INSTALLED="NO" | |
C="US" | |
ST="California" | |
L="Los Angeles" | |
O="Tyrell Corporation" | |
OU="Development" | |
CN=$(hostname) | |
while getopts svfh options; do | |
case $options in | |
s) VHOST_WITH_SSL="YES" ;; | |
f) ADD_TO_HOSTS_FILE="YES" ;; | |
v) | |
echo "v${VHOSTS_VERSION}" | |
exit 0 | |
;; | |
?) | |
printf "Create a new virtual host for the given domain.\n\n" | |
printf "Usage: %s: [-v] [-s] [domain] [username]\n $0" | |
printf " -s Deploy virtual host with SSL.\n" | |
printf " -f Add domain entries to /etc/hosts file.\n" | |
printf " -v Display current version.\n" | |
printf " -p Configure the vhost to work with " | |
printf " -h Display help information.\n\n" | |
exit 2 | |
;; | |
esac | |
done | |
shift $((OPTIND - 1)) | |
if [[ -n "$1" ]] && [[ $(echo "$1" | grep -cP '(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)') -gt 0 ]]; then | |
DOMAIN_NAME="$1" | |
else | |
echo "Name of the Virtual Host (domain: example.com) to create: " | |
read -r DOMAIN_NAME | |
echo "The following URL will be set: $DOMAIN_NAME and www.$DOMAIN_NAME (y/n): " | |
read -r CONFIRMATION | |
if [[ ! $CONFIRMATION =~ ^[Yy]$ ]]; then | |
echo "Installation aborted!" | |
exit 0 | |
fi | |
fi | |
if [[ $(echo "$DOMAIN_NAME" | grep -ciE '\.') -eq 0 ]]; then | |
echo "TLD has not being specified in the domain name, please provide one without dot (es, com, net): " | |
read -r TLD | |
if [[ $(echo "$TLD" | grep -cP '[a-zA-Z]{2,}') -eq 0 ]]; then | |
echo "Invalid TLD, aborting." | |
exit 0 | |
fi | |
DOMAIN_NAME="$DOMAIN_NAME.$TLD" | |
fi | |
if [[ -n "$2" ]] && [[ "$2" =~ ^[a-zA-Z][a-zA-Z0-9_]*$ ]]; then | |
USER_NAME="$2" | |
else | |
echo "Set a username to create for the new virtual host: " | |
read -r USER_NAME | |
if [[ ! "$USER_NAME" =~ ^[a-zA-Z][a-zA-Z0-9_]*$ ]]; then | |
echo "The $USER_NAME does not fit the standard way, and it may cause you problems in the future." | |
echo "Are you sure you want to create this user? (only if you know what you are doing) [y/n]: " | |
read -r CONFIRMATION | |
if [[ ! $CONFIRMATION =~ ^[Yy]$ ]]; then | |
echo "Installation aborted!" | |
exit 0 | |
fi | |
fi | |
fi | |
if [[ $(getent group "$USER_NAME" | grep -c "$USER_NAME") -eq 0 ]]; then | |
echo "Adding new group $USER_NAME." | |
groupadd "$USER_NAME" | |
fi | |
if [[ $(getent passwd "$USER_NAME" | grep -c "$USER_NAME") -eq 0 ]]; then | |
echo "Adding new user $USER_NAME." | |
useradd -M -g "$USER_NAME" -s $NOLOGIN_PATH "$USER_NAME" | |
fi | |
if [[ $(getent group "$USER_NAME" | grep -c "$APACHE_GROUP_NAME") -eq 0 ]]; then | |
echo "Adding new user $USER_NAME to $APACHE_GROUP_NAME group." | |
usermod -a -G "$USER_NAME" $APACHE_GROUP_NAME | |
fi | |
VHOST_FILE="$APACHE_SITES_AVAILABLE_DIR/$DOMAIN_NAME.conf" | |
if [[ ! -f $VHOST_FILE ]]; then | |
echo "Creating directory structure." | |
mkdir -p "$SITES_DIR"/"$DOMAIN_NAME"/{$SITE_PUBLIC_DIR,$SITE_PRIVATE_DIR,$SITE_LOG_DIR,$SITE_CRT_DIR,$SITE_CGI_DIR} | |
chown -R "$USER_NAME":"$USER_NAME" "$SITES_DIR/$DOMAIN_NAME" | |
chmod 775 -R "$SITES_DIR/$DOMAIN_NAME" | |
echo "Generating apache virtual host configuration." | |
echo " | |
<VirtualHost *:80> | |
ServerAdmin webmaster@$DOMAIN_NAME | |
ServerName $DOMAIN_NAME | |
ServerAlias www.$DOMAIN_NAME | |
DocumentRoot $SITES_DIR/$DOMAIN_NAME/$SITE_PUBLIC_DIR | |
ErrorLog $SITES_DIR/$DOMAIN_NAME/$SITE_LOG_DIR/error.log | |
CustomLog $SITES_DIR/$DOMAIN_NAME/$SITE_LOG_DIR/access.log combined | |
<Directory $SITES_DIR/$DOMAIN_NAME/$SITE_PUBLIC_DIR> | |
Options Indexes FollowSymLinks | |
AllowOverRide All | |
IndexIgnore * | |
Require all granted | |
Order Allow,Deny | |
Allow from all | |
</Directory> | |
</VirtualHost> | |
" >>"$VHOST_FILE" | |
chown "$USER_NAME" "$VHOST_FILE" | |
CFG_CHANGED="YES" | |
else | |
echo "The virtual host $DOMAIN_NAME already exists." | |
fi | |
if [[ $(grep -c '443' "$VHOST_FILE") -gt 0 ]]; then | |
VHOST_SSL_INSTALLED="YES" | |
fi | |
if [[ $VHOST_SSL_INSTALLED == "NO" ]] && [[ $VHOST_WITH_SSL == "YES" ]]; then | |
echo "Generating SSL Certificates." | |
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ | |
-subj "/C=$C/ST=$ST/L=$L/O=$O/OU=$OU/CN=$CN" \ | |
-keyout "$SITES_DIR/$DOMAIN_NAME/$SITE_CRT_DIR/$DOMAIN_NAME.key" \ | |
-out "$SITES_DIR/$DOMAIN_NAME/$SITE_CRT_DIR/$DOMAIN_NAME.crt" 2>/dev/null | |
echo " | |
<VirtualHost *:443> | |
ServerAdmin webmaster@$DOMAIN_NAME | |
ServerName $DOMAIN_NAME | |
ServerAlias www.$DOMAIN_NAME | |
DocumentRoot $SITES_DIR/$DOMAIN_NAME/$SITE_PUBLIC_DIR | |
ErrorLog $SITES_DIR/$DOMAIN_NAME/$SITE_LOG_DIR/ssl-error.log | |
CustomLog $SITES_DIR/$DOMAIN_NAME/$SITE_LOG_DIR/ssl-access.log combined | |
<Directory $SITES_DIR/$DOMAIN_NAME/$SITE_PUBLIC_DIR> | |
Options Indexes FollowSymLinks | |
AllowOverRide All | |
IndexIgnore * | |
Require all granted | |
Order Allow,Deny | |
Allow from all | |
</Directory> | |
SSLEngine on | |
SSLCertificateFile $SITES_DIR/$DOMAIN_NAME/$SITE_CRT_DIR/$DOMAIN_NAME.crt | |
SSLCertificateKeyFile $SITES_DIR/$DOMAIN_NAME/$SITE_CRT_DIR/$DOMAIN_NAME.key | |
</VirtualHost> | |
" >>"$VHOST_FILE" | |
VHOST_SSL_INSTALLED="YES" | |
CFG_CHANGED="YES" | |
fi | |
if [[ ! -f "$APACHE_SITES_ENABLED_DIR/$DOMAIN_NAME.conf" ]]; then | |
case "$ID" in | |
ubuntu) | |
echo "Activating virtual host." | |
a2ensite "$DOMAIN_NAME" 2>/dev/null | |
;; | |
esac | |
fi | |
if [[ $CFG_CHANGED == "YES" ]]; then | |
echo "Reloading $APACHE_SERVICE_UNIT." | |
systemctl reload $APACHE_SERVICE_UNIT | |
fi | |
if [[ $ADD_TO_HOSTS_FILE == "YES" ]] && [[ $(grep -c "$DOMAIN_NAME" "/etc/hosts") -eq 0 ]]; then | |
echo "Adding domain entries to /etc/hosts file." | |
for IP in $(hostname -I); do | |
echo -e "$IP\t$DOMAIN_NAME " >>/etc/hosts | |
done | |
echo -e "127.0.0.1\t$DOMAIN_NAME " >>/etc/hosts | |
fi | |
echo "============================ SUMMARY ============================" | |
echo "Domain: $DOMAIN_NAME" | |
echo "User: $USER_NAME" | |
echo "VHost File: $VHOST_FILE" | |
echo "VHost Directory: $SITES_DIR/$DOMAIN_NAME" | |
echo "SSL Support: $VHOST_SSL_INSTALLED" | |
if [[ $VHOST_SSL_INSTALLED == "YES" ]]; then | |
echo "SSL Key File: $SITES_DIR/$DOMAIN_NAME/$SITE_CRT_DIR/$DOMAIN_NAME.key" | |
echo "SSL Cert File: $SITES_DIR/$DOMAIN_NAME/$SITE_CRT_DIR/$DOMAIN_NAME.crt" | |
fi | |
echo "Server Name: $(hostname)" | |
echo "Server IP: $(hostname -I)" | |
echo "=================================================================" | |
echo "Add following lines to /etc/hosts file if no DNS server available" | |
for IP in $(hostname -I); do | |
if [[ -n "$SSH_CONNECTION" ]]; then | |
if [[ $(echo "$SSH_CONNECTION" | cut -d " " -f 3) == "$IP" ]]; then | |
echo -e "$IP\t$DOMAIN_NAME" | |
fi | |
else | |
echo -e "$IP\t$DOMAIN_NAME" | |
fi | |
done | |
echo "=================================================================" | |
echo "Have a nice day ;)" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment