setup_testenv_ubuntu.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #!/bin/bash
  2. #
  3. # setup_testenv_ubuntu.sh — General PHP development environment setup for Ubuntu
  4. # Usage: bash setup_testenv_ubuntu.sh
  5. # Sets up Apache (apache2) with PHP to serve /home/josef/Code on localhost
  6. # Requires sudo privileges for package installation and service management
  7. #
  8. # PRIVILEGE SEPARATION: This script must NOT be run as root.
  9. # The running user should not have direct rights to install packages
  10. # (i.e., must use sudo which requires authentication).
  11. #
  12. set -euo pipefail
  13. # ── Configuration ─────────────────────────────────────────────────────────
  14. DOCROOT="/var/www/html"
  15. APACHE_USER="www-data"
  16. APACHE_GROUP="www-data"
  17. APACHE_CONF="/etc/apache2/conf-available/dev.conf"
  18. # ── Colors for output ─────────────────────────────────────────────────────
  19. RED='\033[0;31m'
  20. GREEN='\033[0;32m'
  21. YELLOW='\033[1;33m'
  22. NC='\033[0m' # No Color
  23. # ── Check for privilege separation ─────────────────────────────────────────
  24. echo "→ Checking user privileges..."
  25. CURRENT_USER=$(whoami)
  26. # Check if running as root (violates privilege separation)
  27. if [[ $EUID -eq 0 ]]; then
  28. echo -e "${RED}ERROR: This script should not be run as root directly.${NC}"
  29. echo " Please run as a normal user with sudo privileges."
  30. echo " This ensures proper separation of privileges."
  31. exit 1
  32. fi
  33. echo -e "${GREEN}✓${NC} Not running as root (good for privilege separation)"
  34. # Check if user has sudo privileges (Ubuntu uses sudo group for sudo access)
  35. if groups | grep -qw sudo; then
  36. echo -e "${GREEN}✓${NC} User '$CURRENT_USER' is in sudo group (has sudo privileges)"
  37. else
  38. echo -e "${YELLOW}WARNING:${NC} User '$CURRENT_USER' is not in the sudo group."
  39. echo " This user may not have sudo privileges required for this script."
  40. echo " The script will attempt to use sudo, which may prompt for a password."
  41. echo ""
  42. read -p " Continue anyway? (y/N) " -n 1 -r
  43. echo
  44. if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  45. echo "Aborting."
  46. exit 1
  47. fi
  48. fi
  49. echo ""
  50. echo "Note: sudo commands will prompt for your password if required."
  51. # ── 1. Install Apache, PHP, and required modules ──────────────────────────
  52. echo ""
  53. echo "→ Installing Apache (apache2), PHP, and required modules..."
  54. sudo apt-get update
  55. sudo apt-get install -y apache2 php libapache2-mod-php php-mbstring php-xml php-cli jq acl
  56. echo -e "${GREEN}✓${NC} Packages installed"
  57. # ── 2. Ensure document root exists ────────────────────────────────────────
  58. echo ""
  59. echo "→ Ensuring document root exists: $DOCROOT"
  60. sudo mkdir -p "$DOCROOT"
  61. echo -e "${GREEN}✓${NC} Document root ready"
  62. # ── 3. Set ownership and permissions for Apache + current user ────────────
  63. echo ""
  64. echo "→ Setting permissions for user '$CURRENT_USER' and Apache user '$APACHE_USER'..."
  65. # Ensure ACL support is available (should be installed now)
  66. if ! command -v setfacl &>/dev/null; then
  67. echo " Installing ACL tools..."
  68. sudo apt-get install -y acl
  69. fi
  70. # Set ownership to current user (so user can easily create files)
  71. sudo chown -R "$CURRENT_USER:$CURRENT_USER" "$DOCROOT"
  72. # Set base permissions
  73. sudo chmod 0755 "$DOCROOT"
  74. # Set ACLs so both the current user and Apache can read/write
  75. sudo setfacl -R -m u:"$CURRENT_USER":rwx,u:"$APACHE_USER":rwx "$DOCROOT"
  76. sudo setfacl -R -d -m u:"$CURRENT_USER":rwx,u:"$APACHE_USER":rwx "$DOCROOT"
  77. # Also allow the apache group to access
  78. sudo setfacl -R -m g:"$APACHE_GROUP":r-x "$DOCROOT"
  79. sudo setfacl -R -d -m g:"$APACHE_GROUP":r-x "$DOCROOT"
  80. echo -e "${GREEN}✓${NC} Permissions configured (ACLs set for $CURRENT_USER and $APACHE_USER)"
  81. # Grant traverse-only (--x) access on every ancestor directory above DOCROOT
  82. # (e.g. /home/josef) so Apache can reach it. This is required when DOCROOT
  83. # lives under a user's home directory, since home dirs are typically 750 and
  84. # ACLs on DOCROOT itself don't help if a parent blocks the path.
  85. echo ""
  86. echo "→ Ensuring '$APACHE_USER' can traverse into $DOCROOT..."
  87. PARENT_DIR="$(dirname "$DOCROOT")"
  88. while [[ "$PARENT_DIR" != "/" && -n "$PARENT_DIR" ]]; do
  89. if ! sudo -u "$APACHE_USER" test -x "$PARENT_DIR" 2>/dev/null; then
  90. sudo setfacl -m u:"$APACHE_USER":--x "$PARENT_DIR"
  91. echo " Granted traverse (--x) access on $PARENT_DIR"
  92. fi
  93. PARENT_DIR="$(dirname "$PARENT_DIR")"
  94. done
  95. echo -e "${GREEN}✓${NC} Traverse access confirmed for $APACHE_USER"
  96. # ── 4. Create/update Apache configuration ─────────────────────────────────
  97. echo ""
  98. echo "→ Creating Apache configuration: $APACHE_CONF"
  99. sudo tee "$APACHE_CONF" > /dev/null << EOF
  100. # Development environment - serve /home/josef/Code on localhost
  101. <Directory "$DOCROOT">
  102. Options Indexes FollowSymLinks
  103. AllowOverride All
  104. Require all granted
  105. # Enable directory listing if no index file found
  106. DirectoryIndex index.php index.html index.htm
  107. </Directory>
  108. # Ensure PHP files are processed
  109. <FilesMatch \.php$>
  110. SetHandler application/x-httpd-php
  111. </FilesMatch>
  112. EOF
  113. sudo a2enconf dev > /dev/null
  114. echo -e "${GREEN}✓${NC} Apache configuration written and enabled"
  115. # ── 5. Configure PHP for development ──────────────────────────────────────
  116. echo ""
  117. echo "→ Configuring PHP for development..."
  118. PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
  119. PHP_INI="/etc/php/$PHP_VERSION/apache2/php.ini"
  120. if [[ -f "$PHP_INI" ]]; then
  121. # Backup original
  122. sudo cp "$PHP_INI" "$PHP_INI.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true
  123. # Enable error display for development
  124. sudo sed -i 's/^display_errors = .*/display_errors = On/' "$PHP_INI" 2>/dev/null || true
  125. sudo sed -i 's/^display_startup_errors = .*/display_startup_errors = On/' "$PHP_INI" 2>/dev/null || true
  126. sudo sed -i 's/^error_reporting = .*/error_reporting = E_ALL/' "$PHP_INI" 2>/dev/null || true
  127. echo -e "${GREEN}✓${NC} PHP configured for development (errors displayed)"
  128. else
  129. echo -e "${YELLOW}WARNING:${NC} PHP ini not found at $PHP_INI, skipping PHP configuration"
  130. fi
  131. # ── 6. Configure mail sending (msmtp) ──────────────────────────────────────
  132. echo ""
  133. echo "→ Installing and configuring msmtp for outgoing mail..."
  134. sudo apt-get install -y msmtp msmtp-mta
  135. MSMTP_CONF="/etc/msmtprc"
  136. sudo tee "$MSMTP_CONF" > /dev/null << 'EOF'
  137. defaults
  138. auth off
  139. tls on
  140. tls_certcheck off
  141. port 25
  142. host mailpit.medowar.de
  143. account default
  144. from josef@dev-framework13.med0.de
  145. EOF
  146. # World-readable: no credentials stored, and PHP's mail() (running as
  147. # www-data) needs to read this file when invoking msmtp as sendmail.
  148. sudo chown root:root "$MSMTP_CONF"
  149. sudo chmod 644 "$MSMTP_CONF"
  150. echo -e "${GREEN}✓${NC} msmtp installed and configured ($MSMTP_CONF)"
  151. # ── 7. Enable and start apache2 ────────────────────────────────────────────
  152. echo ""
  153. echo "→ Enabling and starting apache2..."
  154. sudo systemctl enable apache2
  155. sudo systemctl restart apache2
  156. echo -e "${GREEN}✓${NC} Apache (apache2) is running"
  157. # ── 8. Configure AppArmor permissions ──────────────────────────────────────
  158. echo ""
  159. echo "→ Checking AppArmor permissions..."
  160. if command -v aa-status &>/dev/null; then
  161. if sudo aa-status --enabled 2>/dev/null; then
  162. echo " AppArmor is enabled. The default apache2 profile permits"
  163. echo " read/write access under $DOCROOT, so no changes are needed."
  164. echo " If you see denials, check: sudo aa-status | grep apache2"
  165. echo -e "${GREEN}✓${NC} AppArmor check complete"
  166. else
  167. echo " AppArmor is installed but not enabled, skipping"
  168. fi
  169. else
  170. echo " (AppArmor tools not found, skipping AppArmor configuration)"
  171. fi
  172. # ── 9. Open firewall for HTTP ─────────────────────────────────────────────
  173. echo ""
  174. echo "→ Configuring firewall for HTTP..."
  175. if command -v ufw &>/dev/null; then
  176. if sudo ufw status | grep -qw active; then
  177. sudo ufw allow "Apache" 2>/dev/null || sudo ufw allow 80/tcp 2>/dev/null || true
  178. echo -e "${GREEN}✓${NC} Firewall updated (HTTP allowed)"
  179. else
  180. echo " ufw is installed but not active, skipping firewall rule"
  181. fi
  182. else
  183. echo " (ufw not found, skipping firewall configuration)"
  184. fi
  185. # ── 10. Create a test PHP file ─────────────────────────────────────────────
  186. echo ""
  187. echo "→ Creating test PHP file..."
  188. TEST_FILE="$DOCROOT/info.php"
  189. sudo tee "$TEST_FILE" > /dev/null << 'EOF'
  190. <?php
  191. phpinfo();
  192. ?>
  193. EOF
  194. # Set proper ownership on the test file
  195. sudo chown "$CURRENT_USER:$CURRENT_USER" "$TEST_FILE"
  196. sudo setfacl -m u:"$APACHE_USER":r "$TEST_FILE"
  197. echo -e "${GREEN}✓${NC} Test file created: $TEST_FILE"
  198. # ── Done ───────────────────────────────────────────────────────────────────
  199. echo ""
  200. echo -e "${GREEN}========================================${NC}"
  201. echo -e "${GREEN} Setup complete!${NC}"
  202. echo -e "${GREEN}========================================${NC}"
  203. echo ""
  204. echo " Document root : $DOCROOT"
  205. echo " Served at : http://localhost/"
  206. echo " Test page : http://localhost/info.php"
  207. echo ""
  208. echo " Next steps:"
  209. echo " 1. Open http://localhost/ in your browser"
  210. echo " 2. Place your PHP files in $DOCROOT"
  211. echo " 3. Check apache2 status: sudo systemctl status apache2"
  212. echo " 4. View PHP errors: sudo tail -f /var/log/apache2/error.log"
  213. echo " 5. Check AppArmor denials: sudo journalctl -k | grep -i apparmor"
  214. echo " 6. Test mail sending: echo 'test' | msmtp your@address"
  215. echo ""
  216. echo -e "${YELLOW}Note:${NC} Files created in $DOCROOT will be owned by $CURRENT_USER"
  217. echo " and accessible by Apache. Use standard file permissions"
  218. echo " or ACLs if you need to adjust access for specific files."
  219. echo ""