I decided to create a new test server for my PHP projects building the latest versions of Apache and PHP from source. And it occurred to me there are few (if any) all-in-one guides on how to do this out there. Most just tell you to use package managers and install whichever version is in your distro’s repository. Please note that I was not concerned too much about security or performance since this is only used for internal testing purposes so this is not optimized for production use.
I am designing this guide for Linux noobs. Those who are mostly familiar with Windows systems. For that reason I will be spelling out every single command you need to type in the Linux server, but not necessarily detailing every step on the host machine (assuming it is Windows).
Here is a quick overview of the software we will be using:
- Oracle VirtualBox—a free open-source hypervisor we will use to install our server as a virtual machine.
- CentOS 7—one of the most popular Linux distributions in the world, especially for web servers.
- Apache HTTP Server 2.4.16—the most popular web server in the world.
- MySQL Community Server—we will be using one or more versions since MySQL is probably the most popular database for web applications.
- MariaDB—optional, but recommended. It is a good replacement for MySQL which is quickly gaining popularity.
- Various other databases as needed.
- PHP—we will be using several versions for testing our projects.
Estimated time (for entire guide): 3-9 hours
* differs greatly depending on how much you want/need to install
Estimated time (this post only): 45 minutes
First of all, obviously you have to download and install VirtualBox on your host machine if it isn’t installed already. This is a straight-forward process so I won’t bore you with the details. Once installed and running, just click the “New” button to create your new VM and follow the steps (CentOS 64-bit is the same as RedHat 64-bit).
Setting Up the Virtual Machine
How much RAM and disc space to allocate to your VM depends on how much in this guide you intend to install. If you want to install absolutely everything and have all the databases running simultaneously, 2 GB RAM and 50 GB HDD are the minimum required (though this bare minimum may require adjustments to the swap space, so more RAM and/or larger hard drive are recommended). If you are just going with the bare minimum of Apache, one instance of PHP, and one database, you could get away with less RAM. Obviously, the more of each you can spare the better.
You can set up the virtual network in several ways, but the two main ones are:
- Adapter 1 using NAT, Adapter 2 using Host-only Adapter:
- Pros: great for laptops since the NAT adapter will work on different networks without having to reconfigure the IP settings. Very secure since only the host system can access the VM.
- Cons: no computers on your network besides the host can access the VM.
- Single adapter using Bridged Mode:
- Pros: VM can be accessed from any computer on your network just as if you had attached another physical computer.
- Cons: you need to setup the interface with a static IP address, which means if you attach your host to a different network, the VM will be inaccessible unless you reconfigure your IP settings.
For the purposes of this guide, I will be choosing the first option since I was doing this on a laptop and had no need for other systems to access the VM, but you can easily use the second method.
We want a minimal installation. No need for the overhead of a desktop environment. So download the minimal ISO from one of the mirrors found on the CentOS website and mount it to your virtual machine. Then start the VM. The installation is pretty straight-forward.
Be sure you enable both network adapters before setting your time-zone. And set a static IP address for your host-only adapter, adjusting the IP settings for your host-only adapter if it is not set to defaults (see screenshots below for an example). If you instead chose a single adapter in bridged mode, you will need to give it a static IP address, gateway, and DNS server settings which are valid for your network. Pay special attention to the name you assign to the system (“lamp” in my case as seen in these screen shots).
During installation you will have the option of setting a root password and user account, which you should do:
After completion of the CentOS installation, you will have to reboot. Then log in using the username and password you created above.
Before we do anything else, we need to setup SUDO. For those unfamiliar with the concept, SUDO is a lot like UAC (User Account Control) in Windows. In previous versions of CentOS, you needed to install and configure SUDO, but it now comes enabled by default; all you have to do is add your user to the group “wheel.” So type the following commands (replacing “jdoe” with your user name), responding with the root password created earlier when prompted:
su -c "usermod -a -G wheel jdoe" logout
Log back in again. From now on, you can run root commands without logging in as root, simply by preceding them with “sudo” and typing your own user password (not the root password) when prompted.
It is a good idea to add the local host name to the “hosts” file, which isn’t done by the CentOS installer. The default text editor is vi, which is very powerful, but may be intimidating for some users. Let’s install something simpler, then open up that file for editing:
sudo yum install nano sudo nano /etc/hosts
Future versions of CentOS will likely be using dnf instead of yum since that is what Fedora started using a few months ago. So if you don’t have yum, just replace it with dnf for the above command and all others in this guide. It is used exactly the same way as yum (for the most part, but the differences aren’t likely to be ones we will encounter here).
There should be two lines here, one for the IPv4 loopback and the other for the IPv6 loopback. You will want to add both the host name and it’s FQDN to both lines. For example: if your host name during install was lamp.localdomain, it should look like this:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 lamp lamp.localdomain ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 lamp lamp.localdomain
Use CTRL+X to exit nano and save the file.
By default, SSH is already installed and configured on current versions of CentOS, so there is nothing to do on the server side. Technically, you don’t need to use it since you can just type commands directly into the console on the VM. But by using SSH instead, you can just copy/paste (with a right-click) the commands in this guide, which will come in very handy. There are several clients available, depending on your host operating system. I’ve been using Bitvise SSH Client for years and I highly recommend it. Although not open-source, the client (all you need) is free and appears to be based on the popular open-source SSH client PuTTY. Choose whichever you prefer, but what I like about Bitvise is the built-in file manager, which would technically mean you wouldn’t need to use folder sharing via the Guest Additions as mentioned below if you don’t wish to. For those running Windows on their desktops, this is highly useful when managing Linux servers. Just download and install it and enter the host-only IP address you set up above to connect (if it doesn’t connect right now, don’t worry; we will address the firewall further on in this tutorial).
Install Guest Additions
One of the first things I do on a new VM is install the VirtualBox Guest Additions. This isn’t strictly necessary since many of the guest additions enhancements only apply when using a desktop like Gnome, but it is useful for sharing files with the host operating system.
Before we can install the Guest Additions, we need some prerequisites, including the kernel headers. But first, update the kernel and any other packages that have updates available. Afterwards, we need to restart the system:
sudo yum update kernel sudo yum upgrade reboot
After logging back on, go ahead and install the prerequisites:
sudo yum install bzip2 gcc kernel-devel perl make
Make is probably already installed, so don’t be surprised if it says it is only going to install four packages.
Load the Guest Additions virtual CD-ROM in VirtualBox:
Now mount it and run the installer:
sudo mkdir /mnt/cdrom sudo mount /dev/cdrom /mnt/cdrom sudo sh /mnt/cdrom/VBoxLinuxAdditions.run
If you get an error about missing headers, just follow the instructions on the screen before running the installer again. For example, it might ask for the following:
sudo yum install kernel-devel-3.10.0-229.el7.x86_64
And reboot to make sure everything loads properly:
Although we aren’t completely focused on security, there are a few steps you should take with any Linux server. More recent versions of CentOS come with many security features enabled by default, but there are still a few changes to make.
Because sudo has already been configured for your user account, there should be no reason to ever log in directly as root (the Linux equivalent of the Administrator account in Windows). For this reason, many people like to lock that account entirely as follows:
sudo passwd -l root
It may be a good idea to prevent remote logins for any member of the “wheel” group (anyone who can use sudo in other words) unless you need to be able to do this for some reason:
sudo nano /etc/security/access.conf
At the end of this file add a line like the following (changing the network/mask if needed and adding other networks as desired):
-:wheel:ALL EXCEPT LOCAL 192.168.56.0/24
Ensure SSH will follow the login restrictions we just set by doing the following:
sudo nano /etc/pam.d/sshd
Insert the following line immediately after the first line “#%PAM-1.0” (it is important you do not place this at the bottom of the file):
auth required pam_access.so
FirewallD is installed and enabled by default in CentOS. This is a major change from older versions of Fedora/RedHat/CentOS which used iptables. Though FirewallD is based on iptables, you can’t use the handy graphical configuration utility system-config-firewall from the console anymore, and since we didn’t install a desktop, we can’t use the new firewall-config utility either. This leaves us with the command-line utility firewall-cmd. I will try to simplify this as much as possible. Advanced users can use man or check out this link as a starting point. But for the purposes of this guide, we only need to do a few things for now. First, check the zones of your interfaces:
Assuming you followed the above instructions when configuring your network interfaces, you may be surprised to see there is only one interface appearing in the “public” zone and the other interface is missing (in my case the interface that appeared was named “enp0s3”). This happened to me even though I was certain I had enabled both interfaces during installation. To double-check your settings and be sure you know which interface is which, run the following:
Choose “Edit a connection” and you will see all your interfaces here and can view the IP settings for each to ensure you know which interface is which. Be sure both (all) are set to automatically connect then save your settings and quit.
Although understandable that our public interface would be locked down (as it is by default), we may still want restrictions for the private one. After all, you can never be too secure. This is a good way to learn some of the basics of configuring FirewallD via the console. Let’s start by adding the host-only interface to the built-in “work” zone. Note that in my case the host-only adapter was named “enp0s8” as viewed in nmtui above, but you may have to change this for your system.
sudo firewall-cmd --zone=work --add-interface=enp0s8 --permanent
But this isn’t always enough to permanently add the interface to the zone. Others have run into this same issue and it is mentioned on several forums. The first time the firewall restarts or you restart the system, this setting may be lost (even though you used the “–permanent” switch). So you need to edit the configuration file for the interface (again change the interface name as needed):
sudo nano /etc/sysconfig/network-scripts/ifcfg-enp0s8
At the end of this file add the following line:
FirewallD comes with many pre-configured services and for now we don’t need to add any custom ones (we may later, but we will cover that as necessary). To list these services:
For now, let’s just open up access to the HTTP/HTTPS services only for those interfaces in the work zone. Of course, you could add other services, or even open these in the public zone if you want to allow access to these services on all interfaces.
sudo firewall-cmd --zone=work --add-service=http --add-service=https --permanent sudo firewall-cmd --reload
To make sure everything worked, type the following:
firewall-cmd --list-all firewall-cmd --zone=work --list-all
Many Apache/PHP tutorials out there will tell you to disable SELinux. This is a security risk, however, and a lazy workaround. For now we will not change any of its settings. Any issues which may arise from the default SELinux settings in CentOS 7 will be addressed further on.
There are a couple more things that will come in handy throughout this guide.
We will need to install several things from the EPEL repository, so do:
sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
You know that shared folder we set up above? Mine was named “Temp” but yours may be different. You can check the mount point by typing:
And look for a mount type of “vboxsf.” Mine is “/media/sf_Temp” but yours will likely differ. We will be using this a lot from here on out.