In this post, I’ll detail a step by step process to set up WordPress on a fresh install of CentOS 7. SELinux will be enabled and in a virtual host.
After changing providers, I had to migrate my site and couldn’t find a guide that I was happy with. Some were not complete, some directly disabled SELinux, … so I chose to write my own. Also, disabling SELinux is a big NO-NO in my book.
The steps to follow are:
- Add users
- Install Apache
- Check and configure the firewall
- Install MySQL and PHP
- Create virtual hosts
- Configure SELinux
- Install WordPress
First things first, we’ll add a user and add him to the
sudoers. This way, we won’t need to be root.
As root user:
# adduser dummyuser # passwd dummyuser
Add dummyuser to sudoers:
Find the following part:
## Allow root to run any commands anywhere root ALL=(ALL) ALL
Add the following line after that:
dummyuser ALL=(ALL) ALL
Log off and log in again as dummyuser, and go on.
sudo yum install httpd
After the installation is complete, start Apache and check if it’s working or not.
sudo systemctl start httpd.service
Launch a browser and visit the root page of the server. You should see a welcome page.
SETTING UP THE FIREWALL
Whether it worked or not, it’s time to check firewall status:
If the result is
running and you can see apache’s test site, you can skip the following steps up to the next section. Otherwise, we’ll have to configure and enable it.
A little safeguard in case we do something wrong and end up locked out of our server (can be safely skipped when working locally)
sudo shutdown -r 30
This will reboot the server in 30 minutes, losing every change that wasn’t permanent. In case you mess up and get locked out, go grab a coffe and carry on later. To cancel the reboot:
sudo shutdown -c
This safeguard is not strictly necessary, but I prefer to be safe when working remotely, and a reboot is allowed. You should be careful with timing. When it runs out, the server will reboot losing not saved changes. Adjust the timing to your needs or refresh the timing by cancelling the reboot and programming a new one.
I’ve taken up this practice when working with remote equipment (not your typical server room) Being looked out means someone commutes for 2 hours to work revert changes. Better safe than sorry.
If the firewall service was not running, we’ll check again with it running:
sudo systemctl start firewalld.service firewall-cmd --state
Now we should have it in a
public which is fine, as it’s the least trustworthy zone that actually allows some connections from the outside.
Returns the services allowed, that on a fresh install shoudl be few.
Now we’ll add http service:
sudo firewall-cmd --zone=public --add-service=http
This command should return
Just to recheck, if we repeat
firewall-cmd --list-all, it should have added http service.
As a bonus,
firewall-cmd --get-services lists currently predefined services
Once tested that the configuration is correct, make all changes permanent so they’ll remain after a reboot:
sudo firewall-cmd --permanent --zone=public --add-service=http
This command should return
Finally, enable the firewall so it starts on boot:
sudo systemctl enable firewalld
ENABLE APACHE ON BOOT
Now that apache is finaly working and accesible from the outside, enable it so it starts on boot:
sudo systemctl enable httpd.service
INSTALL MYSQL AND PHP
Now we’ll install the database and PHP.
sudo yum install mariadb-server mariadb sudo systemctl start mariadb mysql_secure_installation
This last step takes care of securing some defaults.
As it’s freshly installled, mysql will probably not have a password for it’s user root.
Let’s enable mysql on system start:
sudo systemctl enable mariadb.service
Now we’ll install PHP;
sudo yum install php php-cli php-common php-gd php-intl php-mbstring php-mysql php-pear php-pdo php-pecl-memcache php-xml
And restart apache:
systemctl restart httpd.service
CHECK IF PHP IS WORKING
Time to check if PHP is working correctly. Create a simple page with your editor of choice:
And the actual content:
<?php phpinfo(); ?>
Browse test page, and check whether mod_rewrite is enabled or not (it will come handy later)
After checking everythings working, remove the test file:
CREATE APACHE VIRTUAL HOSTS
Create directory structure for Virtual Hosts:
sudo mkdir -p /var/www/vhosts/itanddevelopment.com/public_html sudo mkdir -p /var/www/vhosts/example.com/public_html sudo mkdir -p /var/www/vhosts/example2.com/public_html
Set up permissions:
sudo chown -R $USER:$USER /var/www/vhosts/itanddevelopment.com/public_html sudo chown -R $USER:$USER /var/www/vhosts/example.com/public_html sudo chown -R $USER:$USER /var/www/vhosts/example2.com/public_html
$USER will take the currently logged user value (no need to change it)
sudo chmod -R 755 /var/www
TEST VIRTUAL HOSTS
Time to test Virtual Hosts:
Create a demo page for each virtual host
A simple demo page:
<html> <head> <title>Virtual Host for itanddevelopment.com!</title> </head> <body> <h1>The itanddevelopment.com virtual host is working!</h1> </body> </html>
Create a different file for each virtualhost you want to create, replace the name accordingly.
sudo mkdir /etc/httpd/sites-available sudo mkdir /etc/httpd/sites-enabled sudo vi /etc/httpd/sites-available/itanddevelopment.com.conf
As a simple example, this
.conf could look like:
<VirtualHost *:80> ServerName www.itanddevelopment.com ServerAlias itanddevelopment.com DocumentRoot /var/www/vhosts/itanddevelopment.com/public_html ErrorLog /var/www/vhosts/itanddevelopment.com/logs/error.log CustomLog /var/www/vhosts/itanddevelopment.com/logs/requests.log combined </VirtualHost>
For each virtual host, add the corresponding
ENABLING VIRTUAL HOSTS
To enable virtual hosts:
sudo vi /etc/httpd/conf/httpd.conf
Add at the end:
# Include virtual hosts IncludeOptional sites-enabled/*.conf
To make a site go live, make a link from sites-available to sites-enabled:
sudo ln -s /etc/httpd/sites-available/itanddevelopment.com.conf /etc/httpd/sites-enabled/itanddevelopment.com.conf
And restart Apache:
sudo systemctl restart httpd.service
For disabling a site, just remove the link and restart Apache.
SELINUX CONFIGURATION FOR VIRTUAL HOSTS
SELinux won’t allow httpd to write in our custom log location. Now we’ll configure it properly:
sudo yum install setools setroubleshoot sudo semanage fcontext -a -t httpd_sys_content_t "itanddevelopment.com(/.*)?" sudo semanage fcontext -a -t httpd_log_t "itanddevelopment.com/logs(/.*)?" sudo restorecon -Rv itanddevelopment.com sudo semanage fcontext -a -t httpd_sys_content_t "example.com(/.*)?" sudo semanage fcontext -a -t httpd_log_t "example.com/logs(/.*)?" sudo restorecon -Rv example.com sudo semanage fcontext -a -t httpd_sys_content_t "example2(/.*)?" sudo semanage fcontext -a -t httpd_log_t "example2/logs(/.*)?" sudo restorecon -Rv example2.com
If there’s any problem with SELinux policies
sealert -a /var/log/audit/audit.log
will parse the log and provide hints at problems and possible solutions.
If you are note sure whether the problem is SELinux related or not, the policy can be set to permissive, so the system will not enforce the SE policies but will log them.
sudo setenforce permissive
To check those logs:
sealert -a /var/log/audit/audit.log
will parse SELinux related problems and propose solutions.
Finally, remember to ALWAYS set to enforcing mode.
sudo setenforce enforcing
Finally, it’s time to install WordPress. The first step will be to create the database:
mysql -u root -p CREATE DATABASE wordpress; CREATE USER wordpressuser@localhost IDENTIFIED BY 'wpuserpassword'; GRANT ALL PRIVILEGES ON wordpress.* TO wordpressuser@localhost IDENTIFIED BY 'wpuserpassword'; FLUSH PRIVILEGES; EXIT;
This will ask for root password that was set up while securing the database.
wordpress wordpressuser wpuserpassword can should be changed to your needs.
Now, we’ll download the latest WordPress version:
cd wget http://wordpress.org/latest.tar.gz tar -zxvf latest.tar.gz
Next, create the final directory, copy WordPress and create Uploads directory:
sudo mkdir /var/www/vhosts/itanddevelopment.com/blog.itanddevelopment.com sudo chown dummyuser:apache blog.itanddevelopment.com sudo rsync -avP /home/dummyuser/wordpress/ /var/www/vhosts/itanddevelopment.com/blog.itanddevelopment.com/ mkdir /var/www/html/wp-content/uploads
FINAL TOUCHES TO CONFIGURATION
cd /var/www/vhosts/itanddevelopment.com/blog.itanddevelopment.com cp wp-config-sample.php wp-config.php vi wp-config.php
DB_NAME DB_USER DB_PASSWORD to your version of
wordpress wordpressuser wpuserpassword
Change the authentication keys and salts to the values you get in: WordPress API Salt
$table_prefix can be modified. It will usually not be neccesary, but if you intend on sharing the same database with multiple wordpress installations, this identifier must be unique and different for all of them.
Apache should be allowed to write on wp-content so SELinux context should be modified:
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/vhosts/itanddevelopment.com/blog.itanddevelopment.com/wp-content(/.*)?" sudo restorecon -Rv ./itanddevelopment.com
During the installation, Apache should be able to modify
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/vhosts/itanddevelopment.com/blog.itanddevelopment.com/wp-config.php" sudo restorecon -Rv ./itanddevelopment.com
Now, WordPress should be up and running, ready to configure from the web interface with your preferred theme, plugins, users, … Hint: If an error appears asking for FTP user / password credentials when installing new plugins or themes, modify
wp-config.php and add the following:
/** Error installing plugins and themes. System asks for FTP user / password */ define('FS_METHOD', 'direct');
Optionally (but I would recommend it), after your changes have taken place, you should return
wp-config.php to it’s previous context, so no writing will happen without your knowledge.
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/vhosts/itanddevelopment.com/blog.itanddevelopment.com/wp-config.php" sudo restorecon -Rv ./itanddevelopment.com
Did you find the post useful? Would you invite me to a nice coffe or offer some help running the site ad-free?