#!/usr/bin/env bash

# Version No. 1
# Last Update : 12/09/2025 (DD/MM/YYYY)

clear 

# --------------------------------------------------------------------------- #
# Prerequisites:

# Retrieve the server's IPv4 address
# If you have several IPv4, uncomment and specify the one you want GLPI to use.
# Then comment out the other line
# IPV4="12.23.34.45"  
IPV4=$(ipadm show-addr -p -o state,addr | awk -F: '$1=="ok"{split($2,a,"/"); if(a[1]!~/^127\./){print a[1]; exit}}')

# Check internet connectivity
check_glpi() {
  /usr/sbin/ping 1.1.1.1 2 >/dev/null 2>&1 || return 1           # IP OK ?
  /usr/bin/getent hosts glpi-project.org >/dev/null 2>&1 || return 2 # DNS OK ?
  curl -Is --max-time 5 https://github.com/glpi-project/glpi/releases/download/10.0.20/glpi-10.0.20.tgz >/dev/null 2>&1 || return 3 # HTTP OK ?
  return 0
}

if check_glpi; then
  echo "-----"
  echo "| OK: access to glpi-project.org is fine, I can get to work!" ; echo
else
  case $? in
    1) echo "KO: no IP access: I'm outta here!";;
    2) echo "KO: broken DNS: Ever heard of a directory?!";;
    3) echo "KO: glpi-project.org unreachable: What do you take me for, some kind of idiot ? You 23glzne'fzizvzmenv moron!! :-D";;
  esac
  exit 1
fi
check_glpi

# Retrieve the server's IPv4
# Determine the IP and the HTTPS URL
: "${IPV4:=$(ipadm show-addr -p -o state,addr | awk -F: '$1=="ok"{split($2,a,"/"); if(a[1]!~/^127\./){print a[1]; exit}}')}"
HOMEURL="https://$IPV4"


# --------------------------------------------------------------------------- #
# Install the packages

# Refresh the catalog
pkg refresh --full

# Install the required programs
pkg install \
  pkg:/web/server/apache-24 \
  pkg:/web/php-84 \
  pkg:/database/mariadb-114 \
  pkg:/database/mariadb-114/tests \
  pkg:/archiver/gnu-tar


# --------------------------------------------------------------------------- #
# MariaDB

glpidb=$(LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c 8; echo;)
glpidbuser=$(LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c 16; echo;)
glpidbuserpwd=$(LC_ALL=C tr -dc 'A-Za-z0-9!@#$%^*()_+=' </dev/urandom | head -c 32; echo)
MDBIN="/usr/mariadb/11.4/bin"
sock="${sock:-/tmp/mariadb114.sock}"

svcadm enable -s svc:/application/database/mariadb:version_114

MAX_WAIT=90

# Wait for the socket to be created
i=0; until [ -S "$sock" ] || [ $i -ge $MAX_WAIT ]; do sleep 1; ((i++)); done; [ $i -ge $MAX_WAIT ] && { echo "Timeout: $sock"; exit 1; }

# Wait for the server to respond via the socket
i=0; until "$MDBIN/mariadb-admin" --protocol=SOCKET --socket="$sock" -uroot ping --silent >/dev/null 2>&1; do ((i++)); [ $i -ge $MAX_WAIT ] && { echo "Timeout: mariadb, where are you ? $sock"; exit 1; }; sleep 1; done

# Create the database and the privileged user (still via the socket)
"$MDBIN/mariadb" --protocol=SOCKET --socket="$sock" -uroot <<SQL
CREATE DATABASE IF NOT EXISTS \`$glpidb\` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS '$glpidbuser'@'localhost' IDENTIFIED BY '$glpidbuserpwd';
GRANT ALL ON \`$glpidb\`.* TO '$glpidbuser'@'localhost';
FLUSH PRIVILEGES;
SQL

# Block MariaDB from listening on the network, restrict communication to the socket only
cat >/etc/mariadb/11.4/my.cnf.d/99-socket-only.cnf <<'EOF'
[mysqld]
skip-networking
EOF

cat >/etc/php/8.4/conf.d/99-mariadb-socket.ini <<'INI'
pdo_mysql.default_socket=/tmp/mariadb114.sock
mysqli.default_socket=/tmp/mariadb114.sock
INI

svcadm restart svc:/application/database/mariadb:version_114


# --------------------------------------------------------------------------- #
# GLPI

# Download and install into Apache's default DocumentRoot
curl --proto '=https' --tlsv1.2 -fSL --retry 3 --retry-connrefused \
  -o /tmp/glpi-10.0.20.tgz https://github.com/glpi-project/glpi/releases/download/10.0.20/glpi-10.0.20.tgz
gtar -xzf /tmp/glpi-*.tgz -C /tmp/
rm -r /var/apache2/2.4/htdocs/*
mv /tmp/glpi/* /var/apache2/2.4/htdocs/
rm /tmp/glpi-*.tgz
rm -r /tmp/glpi


# --------------------------------------------------------------------------- #
# PHP

# Enable classic extensions
# curl, mbstring, zip, exif, openssl, mysqli and opcache are already enabled

sed -i 's/session.cookie_httponly =/session.cookie_httponly = 1/' /etc/php/8.4/php.ini
sed -i 's/;session.cookie_secure =/session.cookie_secure = 1/' /etc/php/8.4/php.ini


# --------------------------------------------------------------------------- #
# Sécurisation de GLPI

cat >> /var/apache2/2.4/htdocs/inc/downstream.php << EOF
<?php
define('GLPI_CONFIG_DIR', '/etc/glpi/');
if (file_exists(GLPI_CONFIG_DIR . '/local_define.php')) {
   require_once GLPI_CONFIG_DIR . '/local_define.php';
}
?>
EOF

mkdir /etc/glpi

cat >> /etc/glpi/local_define.php << EOF
<?php
define('GLPI_VAR_DIR', '/var/lib/glpi');
define('GLPI_LOG_DIR', '/var/log/glpi');
?>
EOF

chown -R webservd:webservd /etc/glpi
mkdir /var/lib/glpi
cp -r /var/apache2/2.4/htdocs/files/* /var/lib/glpi/
chown -R webservd:webservd /var/lib/glpi
mkdir /var/log/glpi
chown -R webservd:webservd /var/log/glpi
rm -r /var/apache2/2.4/htdocs/files
rm -r /var/apache2/2.4/htdocs/config

# Durcir les droits sur le DocumentRoot
# Set properties & permissions
DOCROOT=/var/apache2/2.4/htdocs
chown -R webservd:webservd "$DOCROOT"
find "$DOCROOT" -type d -exec chmod 2755 {} \;
find "$DOCROOT" -type f -exec chmod 644 {} \;

# Faire l'initialisation de la base SQL en CLI
cd /var/apache2/2.4/htdocs
php -d pdo_mysql.default_socket=/tmp/mariadb114.sock \
    -d mysqli.default_socket=/tmp/mariadb114.sock \
  ./bin/console db:install \
    --db-host=localhost \
    --db-name="$glpidb" \
    --db-user="$glpidbuser" \
    --db-password="$glpidbuserpwd" \
    --no-telemetry --force --no-interaction
chown -R webservd:webservd /var/log/glpi
rm /var/apache2/2.4/htdocs/install/install.php


# --------------------------------------------------------------------------- #
# TLS

# Create the TLS certificate
umask 027
mkdir -p /etc/apache2/2.4/TLS/{private,certs}
openssl genrsa 4096 > /etc/apache2/2.4/TLS/private/apache.key
chmod 640 /etc/apache2/2.4/TLS/private/apache.key
chown root:webservd /etc/apache2/2.4/TLS/private/apache.key
openssl req -new -x509 -sha256 -days 365 -subj "/C=FR/O=Test/CN=$IPV4" -key /etc/apache2/2.4/TLS/private/apache.key -out /etc/apache2/2.4/TLS/certs/apache.crt
chmod 644 /etc/apache2/2.4/TLS/certs/apache.crt


# --------------------------------------------------------------------------- #
# Apache

# Fix permission issues on Apache logs
mkdir -p /var/apache2/2.4/logs && chown -R webservd:webservd /var/apache2/2.4/logs && chmod 0750 /var/apache2/2.4/logs
: >/var/apache2/2.4/logs/error_log; : >/var/apache2/2.4/logs/access_log; chown webservd:webservd /var/apache2/2.4/logs/error_log /var/apache2/2.4/logs/access_log

# Create a folder containing all the configuration
mkdir /etc/apache2/2.4/conf.d

cat >/etc/apache2/2.4/conf.d/00-load-ssl-fpm-headers.conf <<'EOF'
LoadModule socache_shmcb_module libexec/mod_socache_shmcb.so
LoadModule ssl_module           libexec/mod_ssl.so
LoadModule proxy_module         libexec/mod_proxy.so
LoadModule proxy_fcgi_module    libexec/mod_proxy_fcgi.so
LoadModule rewrite_module       libexec/mod_rewrite.so
LoadModule headers_module       libexec/mod_headers.so
EOF

cat >/etc/apache2/2.4/conf.d/redirect-https.conf <<'EOF'
<VirtualHost *:80>
    ServerName _default_
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^/(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</VirtualHost>
EOF

cat >/etc/apache2/2.4/conf.d/ssl.conf <<'EOF'
Listen 443
SSLCryptoDevice builtin
SSLSessionCache        "shmcb:/var/run/apache2/2.4/ssl_scache(512000)"
SSLSessionCacheTimeout 300

<VirtualHost *:443>
    ServerName localhost
    ServerAdmin you@example.com

    DocumentRoot "/var/apache2/2.4/htdocs/public"
    <Directory "/var/apache2/2.4/htdocs/public">
        Require all granted
		AllowOverride None
		Options FollowSymLinks

        # Configuration de réécriture directement dans le vhost
        <IfModule mod_rewrite.c>
            RewriteEngine On
            RewriteBase /
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^.*$ index.php [QSA,L]
        </IfModule>
    </Directory>

    ErrorLog  "/var/apache2/2.4/logs/error_log"
    CustomLog "/var/apache2/2.4/logs/ssl_access_log"   combined
    CustomLog "/var/apache2/2.4/logs/ssl_request_log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

    SSLEngine on
    SSLCertificateFile    "/etc/apache2/2.4/TLS/certs/apache.crt"
    SSLCertificateKeyFile "/etc/apache2/2.4/TLS/private/apache.key"

    SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite          HIGH:!aNULL:!eNULL:!MD5:!RC4:!3DES
    SSLProxyCipherSuite     HIGH:!aNULL:!eNULL:!MD5:!RC4:!3DES
    SSLHonorCipherOrder     off

    # PHP-FPM (FPM sur 127.0.0.1:9000)
    <FilesMatch \.php$>
        SetHandler "proxy:fcgi://127.0.0.1:9000"
    </FilesMatch>
    DirectoryIndex index.php index.html

    <IfModule mod_headers.c>
        Header always set X-Frame-Options "SAMEORIGIN"
        Header always set X-Content-Type-Options "nosniff"
        Header always set X-XSS-Protection "1; mode=block"
        Header always set Referrer-Policy "strict-origin-when-cross-origin"
        Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';"
    </IfModule>

</VirtualHost>
EOF


# --------------------------------------------------------------------------- #
# Start the services  

svcadm enable -s svc:/network/php-fpm-84:default
svcadm refresh svc:/network/http:apache24
svcadm enable -s svc:/network/http:apache24


# --------------------------------------------------------------------------- #
# Summary

clear
cat <<EOF
# --------------------------------------------------------------------------- #
# Summary  :

# The installation is complete!

# MariaDB database for GLPI	          : $glpidb
# Privileged user on the database     : $glpidbuser
# User's password                     : $glpidbuserpwd

# GLPI is accessible at               : https://$IPV4/

EOF

