Skip to main content

Hardening guide for Drupal 7.7

·1508 words·8 mins
Eyal Estrin
Author
Eyal Estrin
Author of Cloud Security Handbook & Security for Cloud Native Applications. Cloud Adoption & Cybersecurity expert.

Pre-installation notes The guide bellow is based on CentOS 5.5 (i386), Apache 2.2.19, MySQL 5.5.15

The guide bellow is based on the previous guides:

PHP installation phase

  1. Login to the server using Root account.

  2. Before compiling the PHP environment, install the following RPM from the CentOS 5.5 DVD source folder: rpm -ivh kernel-headers-2.6.18-194.el5.i386.rpm rpm -ivh glibc-headers-2.5-49.i386.rpm rpm -ivh glibc-devel-2.5-49.i386.rpm rpm -ivh gmp-4.1.4-10.el5.i386.rpm rpm -ivh libgomp-4.4.0-6.el5.i386.rpm rpm -ivh gcc-4.1.2-48.el5.i386.rpm rpm -ivh libxml2-2.6.26-2.1.2.8.i386.rpm rpm -ivh zlib-devel-1.2.3-3.i386.rpm rpm -ivh libxml2-devel-2.6.26-2.1.2.8.i386.rpm rpm -ivh pkgconfig-0.21-2.el5.i386.rpm rpm -ivh libpng-devel-1.2.10-7.1.el5_3.2.i386.rpm rpm -ivh libjpeg-devel-6b-37.i386.rpm

  3. Download MySQL development RPM from: http://download.softagency.net/MySQL/Downloads/MySQL-5.5/

  4. Download PHP 5.3.8 source files from: http://php.net/downloads.php

  5. Download the latest libxml2 for PHP from: http://xmlsoft.org/sources/

  6. Copy the MySQL development RPM using PSCP (or SCP) into /tmp

  7. Copy the PHP 5.3.8 source files using PSCP (or SCP) into /tmp

  8. Move to /tmp cd /tmp

  9. Install the MySQL development RPM: rpm -ivh MySQL-devel-5.5.15-1.rhel5.i386.rpm

  10. Remove MySQL development RPM: rm -f MySQL-devel-5.5.15-1.rhel5.i386.rpm

  11. Extract the php-5.3.8.tar.gz file: tar -zxvf php-5.3.8.tar.gz

  12. Extract the libxml2 source file: tar -zxvf libxml2-2.7.7.tar.gz

  13. Move the libxml2-2.7.7 folder: cd /tmp/libxml2-2.7.7

  14. Run the commands bellow to compile the libxml2: ./configuremakemake install

  15. Move to the PHP source folder: cd /tmp/php-5.3.8

  16. Run the commands bellow to compile the PHP environment: `./configure --with-mysql=mysqlnd --with-libdir=lib --prefix=/usr/local/apache2 --with-apxs2=/usr/local/apache2/bin/apxs --with-openssl --with-zlib --with-gd --with-jpeg-dir=/usr/lib --with-png-dir=/usr/lib --enable-pdo --with-pdo-mysql=mysqlnd --enable-ftp`makemake install

  17. Edit using VI, the file /usr/local/apache2/conf/httpd.conf Add the following string, to the end of the AddType section: AddType application/x-httpd-php .php Replace the line from: DirectoryIndex index.htmlTo: DirectoryIndex index.php index.html index.htm Replace the value of the string, from: LimitRequestBody 10000To: LimitRequestBody 600000

  18. Copy the PHP.ini file cp /tmp/php-5.3.8/php.ini-development /etc/php.ini

  19. Change the permissions on the php.ini file: chmod 640 /etc/php.ini

  20. Edit using VI, the file /etc/php.ini Replace the value of the string, from: mysql.default_host =To: mysql.default_host = 127.0.0.1:3306Replace the value of the string, from: pdo_mysql.default_socket=To: pdo_mysql.default_socket=127.0.0.1Replace the value of the string, from: allow_url_fopen = OnTo: allow_url_fopen = OffReplace the value of the string, from: expose_php = OnTo: expose_php = OffReplace the value of the string, from: memory_limit = 128MTo: memory_limit = 64MReplace the value of the string, from: ;open_basedir =To: open_basedir = "/www"Replace the value of the string, from: post_max_size = 8MTo: post_max_size = 2MReplace the value of the string, from: disable_functions =To: disable_functions = fpassthru,crack_check,crack_closedict,crack_getlastmessage,crack_opendict, psockopen,php_ini_scanned_files,shell_exec,chown,hell-exec,dl,ctrl_dir,phpini,tmp,safe_mode,systemroot,server_software, get_current_user,HTTP_HOST,ini_restore,popen,pclose,exec,suExec,passthru,proc_open,proc_nice,proc_terminate, proc_get_status,proc_close,pfsockopen,leak,apache_child_terminate,posix_kill,posix_mkfifo,posix_setpgid, posix_setsid,posix_setuid,escapeshellcmd,escapeshellarg,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid, posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid, posix_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit,system,posix_getsid,posix_getuid,posix_isatty, posix_setegid,posix_seteuid,posix_setgid,posix_times,posix_ttyname,posix_uname,posix_access,posix_get_last_error,posix_mknod, posix_strerror,posix_initgroups,posix_setsidposix_setuidReplace the value of the string, from: ;include_path = ".:/php/includes"To: include_path = "/usr/local/lib/php;/usr/local/apache2/include/php"Replace the value of the string, from: display_errors = OnTo: display_errors = OffReplace the value of the string, from: display_startup_errors = OnTo: display_startup_errors = Off

    Replace the value of the string, from: ;gd.jpeg_ignore_warning = 0To: gd.jpeg_ignore_warning = 1

  21. Run the commands bellow to restart the Apache service: `/usr/local/apache2/bin/apachectl stop`/usr/local/apache2/bin/apachectl start

  22. Remove the PHP source and test files: rm -f /tmp/php-5.3.8.tar.gz rm -f /tmp/libxml2-2.7.7.tar.gz rm -rf /tmp/php-5.3.8 rm -rf /tmp/libxml2-2.7.7 rm -rf /tmp/pear rm -rf /usr/local/apache2/lib/php/test rm -rf /usr/local/lib/php/test

Drupal installation phase

  1. Login to the server using Root account.

  2. Run the command bellow to login to the MySQL: /usr/bin/mysql -uroot -pnew-passwordNote: Replace the string “new-password” with the actual password for the root account.

  3. Run the following commands from the MySQL prompt: CREATE USER 'blgusr'@'localhost' IDENTIFIED BY 'password2'; SET PASSWORD FOR 'blgusr'@'localhost' = OLD_PASSWORD('password2'); CREATE DATABASE Z5J6Dw1; GRANT ALL PRIVILEGES ON Z5J6Dw1.* TO "blgusr"@"localhost" IDENTIFIED BY "password2"; FLUSH PRIVILEGES; quitNote 1: Replace “blgusr” with your own MySQL account to access the database. Note 2: Replace “password2” with complex password (at least 14 characters). Note 3: Replace “Z5J6Dw1” with your own Drupal database name.

  4. Download Drupal 7.7 from: http://drupal.org/project/drupal

  5. Copy the Drupal 7.7 source files using PSCP (or SCP) into /www

  6. Move to /www cd /www

  7. Extract the file bellow: tar -zxvf drupal-7.7.tar.gz

  8. Remove Drupal source file: rm -f /www/drupal-7.7.tar.gz

  9. Rename the Drupal folder: mv /www/drupal-7.7 /www/drupal

  10. Remove default content: rm -f /www/drupal/CHANGELOG.txt rm -f /www/drupal/COPYRIGHT.txt rm -f /www/drupal/INSTALL.pgsql.txt rm -f /www/drupal/LICENSE.txt rm -f /www/drupal/UPGRADE.txt rm -f /www/drupal/INSTALL.mysql.txt rm -f /www/drupal/INSTALL.sqlite.txt rm -f /www/drupal/INSTALL.txt rm -f /www/drupal/MAINTAINERS.txt rm -f /www/drupal/sites/example.sites.php

  11. Edit using VI, the file /usr/local/apache2/conf/httpd.conf Replace the line from: DocumentRoot "/www"To: DocumentRoot "/www/drupal"

  12. Run the commands bellow to restart the Apache service: `/usr/local/apache2/bin/apachectl stop`/usr/local/apache2/bin/apachectl start

  13. Create the following folders: mkdir /www/drupal/sites/default/filesmkdir /www/private

  14. Copy the settings.php file: cp /www/drupal/sites/default/default.settings.php /www/drupal/sites/default/settings.php

  15. Change permissions on the settings.php file: chmod a+w /www/drupal/sites/default/settings.phpchmod -R 777 /www/drupal/sites/default/fileschmod -R 777 /www/private

  16. Open a web browser from a client machine, and enter the URL bellow: http://Server_FQDN/install.php

  17. Select “Standard” installation and click “Save and continue”.

  18. Choose the default “English” and click “Save and continue”.

  19. Specify the following details:

    • Database type: MySQL
    • Database name: Z5J6Dw1
    • Database username: blgusr
    • Database password: password2
    • Click on Advanced Options
    • Database host: 127.0.0.1
    • Table prefix: Z5J6Dw1_

    Note 1: Replace “Z5J6Dw1” with your own Drupal database name. Note 2: Replace “blgusr” with your own MySQL account to access the database. Note 3: Replace “password2” with complex password (at least 14 characters).

  20. Click “Save and Continue”.

  21. Specify the following information:

    • Site name
    • Site e-mail address (for automated e-mails, such as registration information)
    • Username (for the default administrator account)
    • E-mail address
    • Password
  22. Select “Default country” and “Default time zone”.

  23. Unselect the “Update Notifications” checkboxes.

  24. Click “Save and Continue”.

  25. Close the web browser.

  26. Create using VI the file /www/config.php with the following content: <?php $databases = array ( 'default' => array ( 'default' => array ( 'driver' => 'mysql', 'database' => 'Z5J6Dw1', 'username' => 'blgusr', 'password' => 'password2', 'host' => '127.0.0.1', 'port' => '', 'prefix' => 'Z5J6Dw1_', ), ), ); ?>Note 1: Make sure there are no spaces, newlines, or other strings before an opening ‘< ?php’ tag or after a closing ‘?>’ tag. Note 2: Replace “blgusr” with your own MySQL account to access the database. Note 3: Replace “password2” with complex password (at least 14 characters). Note 4: Replace “Z5J6Dw1” with your own Drupal database name.

  27. Edit using VI, the file /www/drupal/sites/default/settings.php Add the following line: include('/www/config.php');Remove the following section: $databases = array ( 'default' => array ( 'default' => array ( 'driver' => 'mysql', 'database' => 'Z5J6Dw1', 'username' => 'blgusr', 'password' => 'password2', 'host' => '127.0.0.1', 'port' => '', 'prefix' => 'Z5J6Dw1_', ), ), );Replace the string from: ini_set('session.cookie_lifetime', 2000000);To: ini_set('session.cookie_lifetime', 0);

  28. Change permissions on the settings.php file: chmod a-w /www/drupal/sites/default/settings.php

  29. Add the following lines to the /www/drupal/.htaccess file: # Block any file that starts with "." <FilesMatch "^\..*$"> Order allow,deny </FilesMatch> <FilesMatch "^.*\..*$"> Order allow,deny </FilesMatch> # Allow "." files with safe content types <FilesMatch "^.*\.(css|html?|txt|js|xml|xsl|gif|ico|jpe?g|png)$"> Order deny,allow </FilesMatch>

  30. Run the command bellow to change permissions on the /www/drupal/.htaccess file: chmod 444 /www/drupal/.htaccess

  31. Download into /www/drupal/sites/all/modulesthe latest build of the modules bellow:

  32. From SSH session, move to the folder /www/drupal/sites/all/modules.

  33. Extract the downloaded above modules: `tar zxvf dfw-7.x-1.1.tar.gz`tar zxvf spamspan-7.x-1.1-beta1.tar.gztar zxvf content_security_policy-7.x-1.x-dev.tar.gztar zxvf goaway-7.x-1.2.tar.gztar zxvf ip_anon-7.x-1.0.tar.gztar zxvf flood_control-7.x-1.0.tar.gztar zxvf password_policy-7.x-1.0-beta1.tar.gztar zxvf persistent_login-7.x-1.x-dev.tar.gztar zxvf secure_permissions-7.x-1.5.tar.gztar zxvf security_review-7.x-1.x-dev.tar.gztar zxvf system_perm-7.x-1.x-dev.tar.gztar zxvf blockanonymouslinks-7.x-1.1.tar.gz

  34. Remove the modules source files: `rm -f /www/drupal/sites/all/modules/dfw-7.x-1.1.tar.gz`rm -f /www/drupal/sites/all/modules/spamspan-7.x-1.1-beta1.tar.gzrm -f /www/drupal/sites/all/modules/content_security_policy-7.x-1.x-dev.tar.gzrm -f /www/drupal/sites/all/modules/goaway-7.x-1.2.tar.gzrm -f /www/drupal/sites/all/modules/ip_anon-7.x-1.0.tar.gzrm -f /www/drupal/sites/all/modules/flood_control-7.x-1.0.tar.gzrm -f /www/drupal/sites/all/modules/password_policy-7.x-1.0-beta1.tar.gzrm -f /www/drupal/sites/all/modules/persistent_login-7.x-1.x-dev.tar.gzrm -f /www/drupal/sites/all/modules/secure_permissions-7.x-1.5.tar.gzrm -f /www/drupal/sites/all/modules/security_review-7.x-1.x-dev.tar.gzrm -f /www/drupal/sites/all/modules/system_perm-7.x-1.x-dev.tar.gz

    rm -f /www/drupal/sites/all/modules/blockanonymouslinks-7.x-1.1.tar.gz

  35. Open a web browser from a client machine, and enter the URL bellow: [http://Server_FQDN/?q=user/login](http://Server_FQDN/?q=user/login)

  36. From the upper menu, click on Configuration -> People -> Account Settings -> “Who can register accounts”: select Administrators only -> click on “Save configuration”.

  37. From the upper menu, click on Configuration -> Media -> File system -> “Private file system path”: specify /www/private -> click on “Save configuration”.

  38. From the upper menu, click on Configuration -> Development -> Logging and errors -> “Error messages to display”: select None -> click on “Save configuration”.

  39. From the upper menu, click on Modules -> from the list of modules, select “Update manager” -> click on “Save configuration”.

  40. From the upper menu, click on Modules -> from the main page, select the following modules:

    • Drupal firewall
    • SpamSpan
    • Content Security Policy
    • Content Security Policy Reporting
    • GoAway
    • IP anonymize
    • Flood control
    • Password change tab
    • Password policy
    • Persistent Login
    • Secure Permissions
    • Security Review
    • System Perms
    • BlockAnonymousLinks
  41. Click on Save configuration.

Drupal SSL configuration phase

  1. Add the following line to the /www/drupal/sites/default/settings.php file: $conf['https'] = TRUE;
  2. Download into /www/drupal/sites/all/modulesthe latest build of the modules bellow:
  3. From SSH session, move to the folder /www/drupal/sites/all/modules.
  4. Extract the downloaded above modules: tar zxvf securepages-7.x-1.x-dev.tar.gztar zxvf securelogin-7.x-1.2.tar.gz
  5. Remove the modules source files: `rm -f /www/drupal/sites/all/modules/securepages-7.x-1.x-dev.tar.gz`rm -f /www/drupal/sites/all/modules/securelogin-7.x-1.2.tar.gz
  6. Open a web browser from a client machine, and enter the URL bellow: [https://Server_FQDN/?q=user/login](https://Server_FQDN/?q=user/login)
  7. From the upper menu, click on Modules -> from the main page, select the following modules:
    • Secure Login
    • Secure Pages
  8. Click on Save configuration.
  9. From the upper menu, click on Configuration -> from the main page, click on the link Secure Pages -> under Enable Secure Pages -> choose Enabled -> click on Save configuration.