#!/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 ""