#!/bin/bash
#
# setup_testenv_ubuntu.sh — General PHP development environment setup for Ubuntu
# Usage: bash setup_testenv_ubuntu.sh
# Sets up Apache (apache2) with PHP to serve /home/josef/Code on localhost
# Requires sudo privileges for package installation and service management
#
# PRIVILEGE SEPARATION: This script must NOT be run as root.
# The running user should not have direct rights to install packages
# (i.e., must use sudo which requires authentication).
#
set -euo pipefail
# ── Colors for output ─────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# ── Check for privilege separation ─────────────────────────────────────────
echo "→ Checking user privileges..."
CURRENT_USER=$(whoami)
# Check if running as root (violates privilege separation)
if [[ $EUID -eq 0 ]]; then
echo -e "${RED}ERROR: This script should not be run as root directly.${NC}"
echo " Please run as a normal user with sudo privileges."
echo " This ensures proper separation of privileges."
exit 1
fi
echo -e "${GREEN}✓${NC} Not running as root (good for privilege separation)"
# Check if user has sudo privileges (Ubuntu uses sudo group for sudo access)
if groups | grep -qw sudo; then
echo -e "${GREEN}✓${NC} User '$CURRENT_USER' is in sudo group (has sudo privileges)"
else
echo -e "${YELLOW}WARNING:${NC} User '$CURRENT_USER' is not in the sudo group."
echo " This user may not have sudo privileges required for this script."
echo " The script will attempt to use sudo, which may prompt for a password."
echo ""
read -p " Continue anyway? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Aborting."
exit 1
fi
fi
echo ""
echo "Note: sudo commands will prompt for your password if required."
# ── Configuration ─────────────────────────────────────────────────────────
DOCROOT="/home/josef/Code"
APACHE_USER="www-data"
APACHE_GROUP="www-data"
APACHE_CONF="/etc/apache2/conf-available/dev.conf"
# ── 1. Install Apache, PHP, and required modules ──────────────────────────
echo ""
echo "→ Installing Apache (apache2), PHP, and required modules..."
sudo apt-get update
sudo apt-get install -y apache2 php libapache2-mod-php php-mbstring php-xml php-cli jq acl
echo -e "${GREEN}✓${NC} Packages installed"
# ── 2. Ensure document root exists ────────────────────────────────────────
echo ""
echo "→ Ensuring document root exists: $DOCROOT"
sudo mkdir -p "$DOCROOT"
echo -e "${GREEN}✓${NC} Document root ready"
# ── 3. Set ownership and permissions for Apache + current user ────────────
echo ""
echo "→ Setting permissions for user '$CURRENT_USER' and Apache user '$APACHE_USER'..."
# Ensure ACL support is available (should be installed now)
if ! command -v setfacl &>/dev/null; then
echo " Installing ACL tools..."
sudo apt-get install -y acl
fi
# Set ownership to current user (so user can easily create files)
sudo chown -R "$CURRENT_USER:$CURRENT_USER" "$DOCROOT"
# Set base permissions
sudo chmod 0755 "$DOCROOT"
# Set ACLs so both the current user and Apache can read/write
sudo setfacl -R -m u:"$CURRENT_USER":rwx,u:"$APACHE_USER":rwx "$DOCROOT"
sudo setfacl -R -d -m u:"$CURRENT_USER":rwx,u:"$APACHE_USER":rwx "$DOCROOT"
# Also allow the apache group to access
sudo setfacl -R -m g:"$APACHE_GROUP":r-x "$DOCROOT"
sudo setfacl -R -d -m g:"$APACHE_GROUP":r-x "$DOCROOT"
echo -e "${GREEN}✓${NC} Permissions configured (ACLs set for $CURRENT_USER and $APACHE_USER)"
# ── 4. Create/update Apache configuration ─────────────────────────────────
echo ""
echo "→ Creating Apache configuration: $APACHE_CONF"
sudo tee "$APACHE_CONF" > /dev/null << EOF
# Development environment - serve /home/josef/Code on localhost
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
# Enable directory listing if no index file found
DirectoryIndex index.php index.html index.htm
# Ensure PHP files are processed
SetHandler application/x-httpd-php
EOF
sudo a2enconf dev > /dev/null
echo -e "${GREEN}✓${NC} Apache configuration written and enabled"
# ── 5. Configure PHP for development ──────────────────────────────────────
echo ""
echo "→ Configuring PHP for development..."
PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
PHP_INI="/etc/php/$PHP_VERSION/apache2/php.ini"
if [[ -f "$PHP_INI" ]]; then
# Backup original
sudo cp "$PHP_INI" "$PHP_INI.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true
# Enable error display for development
sudo sed -i 's/^display_errors = .*/display_errors = On/' "$PHP_INI" 2>/dev/null || true
sudo sed -i 's/^display_startup_errors = .*/display_startup_errors = On/' "$PHP_INI" 2>/dev/null || true
sudo sed -i 's/^error_reporting = .*/error_reporting = E_ALL/' "$PHP_INI" 2>/dev/null || true
echo -e "${GREEN}✓${NC} PHP configured for development (errors displayed)"
else
echo -e "${YELLOW}WARNING:${NC} PHP ini not found at $PHP_INI, skipping PHP configuration"
fi
# ── 6. Configure mail sending (msmtp) ──────────────────────────────────────
echo ""
echo "→ Installing and configuring msmtp for outgoing mail..."
sudo apt-get install -y msmtp msmtp-mta
MSMTP_CONF="/etc/msmtprc"
sudo tee "$MSMTP_CONF" > /dev/null << 'EOF'
defaults
auth off
tls on
tls_certcheck off
port 25
host mailpit.medowar.de
account default
from josef@dev-framework13.med0.de
EOF
# World-readable: no credentials stored, and PHP's mail() (running as
# www-data) needs to read this file when invoking msmtp as sendmail.
sudo chown root:root "$MSMTP_CONF"
sudo chmod 644 "$MSMTP_CONF"
echo -e "${GREEN}✓${NC} msmtp installed and configured ($MSMTP_CONF)"
# ── 7. Enable and start apache2 ────────────────────────────────────────────
echo ""
echo "→ Enabling and starting apache2..."
sudo systemctl enable apache2
sudo systemctl restart apache2
echo -e "${GREEN}✓${NC} Apache (apache2) is running"
# ── 8. Configure AppArmor permissions ──────────────────────────────────────
echo ""
echo "→ Checking AppArmor permissions..."
if command -v aa-status &>/dev/null; then
if sudo aa-status --enabled 2>/dev/null; then
echo " AppArmor is enabled. The default apache2 profile permits"
echo " read/write access under $DOCROOT, so no changes are needed."
echo " If you see denials, check: sudo aa-status | grep apache2"
echo -e "${GREEN}✓${NC} AppArmor check complete"
else
echo " AppArmor is installed but not enabled, skipping"
fi
else
echo " (AppArmor tools not found, skipping AppArmor configuration)"
fi
# ── 9. Open firewall for HTTP ─────────────────────────────────────────────
echo ""
echo "→ Configuring firewall for HTTP..."
if command -v ufw &>/dev/null; then
if sudo ufw status | grep -qw active; then
sudo ufw allow "Apache" 2>/dev/null || sudo ufw allow 80/tcp 2>/dev/null || true
echo -e "${GREEN}✓${NC} Firewall updated (HTTP allowed)"
else
echo " ufw is installed but not active, skipping firewall rule"
fi
else
echo " (ufw not found, skipping firewall configuration)"
fi
# ── 10. Create a test PHP file ─────────────────────────────────────────────
echo ""
echo "→ Creating test PHP file..."
TEST_FILE="$DOCROOT/info.php"
sudo tee "$TEST_FILE" > /dev/null << 'EOF'
EOF
# Set proper ownership on the test file
sudo chown "$CURRENT_USER:$CURRENT_USER" "$TEST_FILE"
sudo setfacl -m u:"$APACHE_USER":r "$TEST_FILE"
echo -e "${GREEN}✓${NC} Test file created: $TEST_FILE"
# ── Done ───────────────────────────────────────────────────────────────────
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Setup complete!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo " Document root : $DOCROOT"
echo " Served at : http://localhost/"
echo " Test page : http://localhost/info.php"
echo ""
echo " Next steps:"
echo " 1. Open http://localhost/ in your browser"
echo " 2. Place your PHP files in $DOCROOT"
echo " 3. Check apache2 status: sudo systemctl status apache2"
echo " 4. View PHP errors: sudo tail -f /var/log/apache2/error.log"
echo " 5. Check AppArmor denials: sudo journalctl -k | grep -i apparmor"
echo " 6. Test mail sending: echo 'test' | msmtp your@address"
echo ""
echo -e "${YELLOW}Note:${NC} Files created in $DOCROOT will be owned by $CURRENT_USER"
echo " and accessible by Apache. Use standard file permissions"
echo " or ACLs if you need to adjust access for specific files."
echo ""