Setup a Development Environment for CentOS using cPanel

Editing a website’s code is often needed to update a site, but doing this to the live website could create downtime and other unwanted effects. Instead, its ideal to create an environment especially for developing new ideas.  In this tutorial, we will explore creating a development site specifically for CentOS servers.

As a warning, this is advanced technical work. It’s possible to make mistakes and cause downtime on your live domain. If you are not 100% confident, it may be a good idea to hire a system admin or developer to copy the domain for you.

Pre-flight

Step 1: Continue on to back up the cPanel account, just in case you have any issues while creating your development environment:

/scripts/pkgacct [username] --backup /home/temp/

Step 2: After creating a backup, you will create a copy the database of the main domain, otherwise known as the primary domain.

mysqldump [database_name] > /home/temp/backup.[database_name].sql

Step 3: Create the new dev domain in WHM. This domain name will be a subdomain of the primary domain. Creating a subdomain is one of the first steps in designing your development environment. We prefer to use, dev.[domain].com, the same domain name but with “dev” in front of it for clarity. Do be sure to note all the information, like the username and password. If you are not familiar with how to create a new account, see the following tutorial.

Step 4: Once you’ve created the subdomain within your cPanel you’ll copy the files from the main document root to the newly created dev document root. The document root is the location where your website’s files.

Use the following command to find the document root for either domain. Replace “exampledomain.com” with the primary and development domains for determining the location of document root for each.

whmapi1 domainuserdata domain=[exampledomain.com] | grep -i documentroot

Step 5: After locating the document roots we will copy the files from the primary domain over to the development environment. Insert the document roots into this next command.

rsync -avh /document/root/of/the/primary/domain/ /document/root/of/the/new/dev/domain

Step 6: Next you will need to state the correct ownership of the dev domain’s files and directories, as the previous username will be in place. The ‘dev_username’ will be the given/chosen when you created the new account. The following command will change the ownership for you.

chown -R [dev_username]: /home/[dev_username]

Step 7: After changing file ownership, create a new database and database user for the dev domain. Be sure to notate this information including the password set. Our documentation on the creating a new database will walk you through this necessary process.

Step 8: Once you’ve created the new database its user, you can start copying the original database into the newly created database.

mysql [new_database_name] < /home/temp/backup.[database_name].sql

Step 9: Copying over the database is the bulk of the work, but you’ll still need to edit the configuration files for your domain. Typically, some files need to access the database and will accomplish this via the database user and password. The file that contains these credentials needs to be updated to have the database, database user, and password you created in step 8 of this tutorial. If unsure of the location of these files talking with a developer may be helpful. If you are working with a WordPress site, you can continue onto the next section. Otherwise, if you have updated your dev configuration files with your new database info continue onto step 10.

Editing WordPress Configurations
Fortunately, WordPress is one of the most commonly used content management systems. WordPress is easy to configure we’ll provide a short tutorial on how to change the database and database user in the wp-config.php. First, move to the new document root. cd /document/root/to/the/dev/domain

There you will edit the wp-config.php with your favorite text editor such as vim or nano. nano wp-config.php

In the wp-config.php file, you will see a section that looks like the below. From there you will edit the highlighted characters with the information you used to create the database in the tutorial. // ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'new_database_name');
/** MySQL database username */
define('DB_USER', ‘new_database_user');
/** MySQL database password */
define('DB_PASSWORD', 'password');

In the database, clear all mentions of the original domain and replace them with the dev domain. For example with WordPress, in the _options table you need to change two entries of ‘home’ and ‘siteurl’. These can be quickly changed using WP-ClI, which is a is a command line tool for interacting with and managing WordPress sites. To install WP-CLI follow these instructions and continue onto the next step. If you do have a WordPress website, once you have installed WP-CLI you will want to run the following commands: su - [dev_username] cp public_html
wp option update siteurl https://dev.domain.com
wp option update home https://dev.domain.com
exit

Sometimes plugins or themes mention the original domain in the database. If some parts of the dev domain are not working, particularly plugins or themes, you may need to contact a developer to see if the original domain name is still active in the database. After replacing the names using WP-CLI, you’ll have officially created a dev domain.

Step 10: To complete this tutorial you have two choices: add an A record to your DNS view your dev site online or edit your local hosts file to view solely on your computer. For our Liquid Web customers feel free to contact The Most Helpful Humans™ with questions you may have in setting up a development environment.

 

 

Setup a Development Environment in Ubuntu

Often we want to edit our domain’s code, but on a production website, this can be dangerous. Making changes to the production site would not only allow all of the Internet to see unfinished changes but could also cause errors to display. As a workaround, we’ll create a testing domain or “dev” domain to work out any bugs and changes to the site.

As a warning, this is advanced technical work. It’s possible to make mistakes and cause downtime on your live domain. If you are not 100% confident, it may be a good idea to hire a system admin or developer to copy the domain for you.

Pre-flight

Step 1: After logging in as root, back up the domain using the command below to save a compressed version. It’s essential to have a copy of your site just in case you run into any issues. Replace the brackets and the “domainname” with your site’s name.

tar cfv backup.[domainname].tar /document/root/of/the/domain/

 

Step 2: We will be moving our backup file, .tar, somewhere off that document root, This way we can still access the data while keeping it safe.

mv backup.[domainname].tar /another/location/on/the/server

 

Step 3: The tar command created a file that comprises only half of the site, which holds the files. Next, you will want to copy the database for the primary site.

mysqldump [database_name] > /another/location/on/the/server/backup.[database_name].sql

 

Step 4: Create the new dev account, just like you were adding a new domain to your server. However, you will be creating a subdomain which you can name as dev.[domain].com.

 

Step 5: Once you’ve created the dev subdomain, copy the files from the main document root to the newly created dev document root. The document root is the location of the files housing your domain, also known as the “path”.

To find the document root location, for either domain, run the following command. Find the document root by replacing “exampledomain.com” for each both the live and dev domain.

conf=$(apache2ctl -S | grep exampledomain.com | perl -n -e '/\((\/.*)\:/ && print "$1\n"'); grep -i documentroot $conf

 

Step 6: After you have found the document roots for both the domain and dev domain, you will need to copy the files. With the output of the last command, you’ll insert the path for the document roots.

rsync -avh /document/root/of/the/domain/ /document/root/of/the/new/dev/domain

 

Step 7: Give the correct ownership to the dev domain, as the previous username remains in place. The ‘dev_username’ is a default user, one generated by creating the new account. The following command will change the ownership for you.

chown -R [dev_username]: /document/root/of/the/new/domain

 

Step 8: After you have done this you will need to create a new database and database user for the dev domain, be sure to keep all this information including the password you set. First, enter the mysql command prompt by running the command:

mysql

Next, create the database itself.

CREATE DATABASE [new_database_name];

In our next command, we create the user and their password. Be sure this is a unique username, unused up till now.

CREATE USER '[select_new_username]'@'localhost' IDENTIFIED BY '[password]';

 

Step 9: Grant privileges for the user on the database.

GRANT ALL PRIVILEGES ON [new_database_name] TO '[new_username]'@'localhost' WITH GRANT OPTION;

Then exit out of mysql by typing “quit” and hitting enter:

quit

 

Step 10: Once back at the root command prompt, you can start copying the original database into the new database.

mysqldump [new_database_name] < /home/temp/backup.[database_name].sql

With the database dumped you will still need to edit the configuration files for your domain. Typically, there are files which need to access the database and will reference the database, database user, and password. These credentials need updating to the ones created earlier in step 8 of this tutorial. If you are unsure of where these files contact a developer. If you are working with a WordPress site continue on to the next section.  Otherwise, if you have updated your dev configuration files with your new database info continue onto step 11.

Editing WordPress Configurations

Fortunately, WordPress is one of the most commonly used content management systems. WordPress is easy to configure we’ll provide a short tutorial on how to change the database and database user in the wp-config.php. First, move to the new document root.

cd /document/root/to/the/dev/domain

There you will edit the wp-config.php with your favorite text editor such as vim or nano.

nano wp-config.php

In the wp-config.php file, you will see a section that looks like the below. From there you will edit the highlighted characters with the information you used to create the database in the tutorial.

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'new_database_name');
/** MySQL database username */
define('DB_USER', ‘new_database_user');
/** MySQL database password */
define('DB_PASSWORD', 'password');

In the database, clear all mentions of the original domain and replace them with the dev domain. For example with WordPress, in the _options table you need to change two entries of ‘home’ and ‘siteurl’. These can be quickly changed using WP-ClI, which is a is a command line tool for interacting with and managing WordPress sites.  To install WP-CLI follow these instructions and continue onto the next step.

If you do have a WordPress website, once you have installed WP-CLI you will want to run the following commands:

su - [dev_username] cp public_html
wp option update siteurl https://dev.domain.com
wp option update home https://dev.domain.com
exit

Sometimes plugins or themes mention the original domain in the database. If some parts of the dev domain are not working, particularly plugins or themes, you may need to contact a developer to see if the original domain name is still active in the database.

After replacing the names using WP-CLI, you’ll have officially created a dev domain.

Step 11: To complete this tutorial you have two choices: add an A record to your DNS to view your dev site online or edit your local hosts file to view solely on your computer. For our Liquid Web customers feel free to contact The Most Helpful Humans™ with questions you may have in setting up a development environment.

SSL vs TLS

You may have first heard about TLS because your Apache service needed to be secured using TLS for a PCI scan (Payment Card Industry: PCI scans are a standard to ensure server security for credit card transactions). Or maybe you noticed that your SSL also mentions TLS when you are ordering the certificate. Beyond where you heard the names, the question is, what is this mysterious TLS in relation to SSL and which of the two should you be using?

So what is the difference between SSL and TLS? Surprisingly not much. Most of us are familiar with SSL (Secure Socket Layer) but not TLS (Transport Layer Security), yet they are both protocols used to send data online securely. SSL is older than TLS, but all SSL certificates can use both SSL and TLS encryption. Indeed SSL certificates are appropriately called SSL/TLS certificates, but that becomes a mouthful. Thus the industry has stuck with calling them SSLs. From here on out I will break from convention and call the actual certificate an “SSL certificate” to distinguish the encryption type from the certificate. SSL has its origins in the early 1990s. The mention of Netscape and AOL should date how old these protocols are as they are the first to coin the term SSL.

 

Green Lock On Webpage

If you look up to the upper left corner of this webpage, you may see a very tiny lock and the word “Secure” written in green. While that doesn’t look like much, it plays a critical part of security. The SSL is what your web browser uses to show that data sent from your computer is safe. SSL certificates create a secure tunnel for HTTPS communication. HTTPS stands for Hyper Text Transfer Protocol Secure, differentiating from HTTP, (Hyper Text Transfer Protocol) which has no SSL present. If you see a red lock or a caution sign in the corner of your web browser, that indicates that the connection is not encrypted. Meaning a malicious third party could read any data sent on that webpage.

A secure connection happens via what is called a “handshake” between your browser and the web server. A simplified explanation of this is that the server and your browser agree on a literal “secret” handshake between each other based upon the type of encryption (SSL/TLS) and the SSL certificate itself. This handshake forms its encoding from the interaction of the public and private certificate key. From that point onward they use this secret handshake to confirm the information sent back and forth is from the authentic source.

This handshake and the accompanying SSL certificate helps prevent a man in the middle attack between customers and a server-side business. A man in the middle attack is where a malicious entity intercepts communication between a server and your computer. The man in the middle receives requests from the user and passes along the information to the server and back again. Data between the end user and the server are read, hence “man in the middle” phrase. If attacked, the Man in the Middle technique will show passwords and other sensitive information. As terrifying as that sounds this attack is only possible if there is no SSL certificate on the site.

As you may have heard, Google and FireFox are phasing out non-SSL/TLS encrypted websites. The change will soon show an explicit warning with the browsers for any site that is not covered by an SSL certificate. The browsers will force an acknowledgment that you want to proceed with an insecure website before showing any content.

For business owners who accept online payments, it is even more critical to not only have an SSL certificate but also enforces the latest TLS versions on the server. In a PCI compliance scan, it requires that the domain only use specific TLS versions.

SSL and TLS each have specific versions which relate to the type of encryption that the SSL certificate will use in the previously mentioned handshake.

The SSL versions are:

  • SSL v1
  • SSL v2
  • SSL v3

Never released to the public but still notated is SSL v1; SSL v2 was an improvement upon SSL v1 but still problematic; SSL v3 fixed some of these initial bugs but is open to attacks through vulnerabilities like POODLE or DROWN (read more on those vulnerabilities here). SSL v3 was at the End of Life in 2015, forever ago regarding the internet.

Modern TLS encryptions cover:

  • TLS v1.0
  • TLS v1.1
  • TLS v1.2
  • TLS v1.3

Each of which addresses flaws from one version to the next. The newer encryptions are just that, more modern and more secure ways to encrypt data for security. The later the release, the better the encoding and the more difficult it is to decrypt by malicious third parties. Conversely, the older versions, like with SSL, have vulnerabilities which can be exploited to collect private data. In many ways, you can think of TLS as the newer version of SSL. Some refer to TLS v1.0 as TLS v 1.0/SSL v3.1.

For the interested technophile, as it relates to the handshake example, we break down the first connection process. The first connection deals with the browser, and a “browserhello” is the first exchange in the handshake. The browser then states the version of TLS they accept, say, for example, everything up to TLS v1.1. The server then replies with a “serverhello,” which is the second exchange in the handshake. The server states the version of encryption that is for the rest of the interaction based upon the first connection.

This interaction should force the newest version of SSL/TLS that both the server and browser are capable of handling. Some outdated browsers do not use the latest versions of TLS. The server is also capable of disabling specific TLS/SSL versions, ensuring all the connections to the server are safer. In this way, new servers should disable the use of all SSL versions and even some of the TLS versions. For example, as of September 2018, PCI certification require all SSL versions and TLS v1.0 disabled.

So back to our original question, what is the difference between SSL and TLS? In sum, TLS is the logical progression of SSL and the safer of the two by that fact. Beyond this, they work in the same fashion, but the newer versions use stronger types of encryption.

If you are interested in getting an SSL for your website, check out our blog to help you make an informed decision on what kind of SSL to purchase.

Whitelisting in ModSecurity

Broken down into two parts our article’s first section hits on “how to whitelist IPs or URIs,” for people who are somewhat familiar with ModSecurity but want to know further about the process. Our second section examines why we configure ModSecurity and how to prevent the security of the server from getting in the way of our work. If you have a Fully Managed Liquid Web server reach out to our Heroic Support team for assistance with whitelisting!

How to Whitelist IPs or URIs

“ModSecurity is a toolkit for real-time web application monitoring, logging, and access control.” (modsecurity.org).  In simple terms, this means that ModSec, also called mod_security or ModSecurity, is a web application firewall that can actively look for attacks to the system and stop malicious activity. However, sometimes these rules trigger when legitimate work is taking place, blocking your IP and stopping you or your developer’s until you can remove the IP block. The way around for being blocked is known as whitelisting, which essentially allows for a specific IP to access the server.   There are a few ways to whitelist a request in ModSec, either by IP or by URI (URIs are specific pages on the website). 

Getting Started

  1. Find your IP or ask your developer for theirs. (You can find this by going to ip.liquidweb.com)If you or your developer have a static IP (one that will not change), one way you can whitelist the ModSec rules is by IP.
  2. Find the ModSec error in the Apache error logs with the following command (Be sure to modify the command with your IP in place of “IP here.”):
    grep ModSec /usr/local/apache/logs/error_log | grep “IP here”.
  3. The output of this command will give you a list of hits for ModSecurity from you or your developer’s IP, which you can see below. While this looks intimidating, you will only want to pay attention to 3 bits of information highlighted.  Please note, the output will not show these colors when you are viewing the files.
Note
Blue = client, the IP which tripped the rule
Red
= ID number of tripped rule within ModSec
Green = URI, the location where the error started from

[Fri May 25 23:07:04.178701 2018] [:error] [pid 78007:tid 139708457686784] [client 61.14.210.4:30095] [client 61.14.210.4] ModSecurity: Access denied with code 406 (phase 2). Pattern match "Mozilla/(4|5)\\\\.0$" at REQUEST_HEADERS:User-Agent. [file "/etc/apache2/conf.d/modsec2.liquidweb.conf"] [line "109"] [id "20000221"] [hostname "67.227.209.163"] [uri "/db/index.php"] [unique_id "WwjPWChxvG1CO4kz-D55eQAAACU"]

 

Whitelist By IP:

1. Once you have the correct ModSec error, you will need to edit the ModSec configuration. If you are using Easy Apache 4 you will find the configuration file with this path:
/etc/apache2/conf.d/modsec2/whitelist.conf

2. Open the file with your favorite text editor, such as vim, nano, or file manager like so:

vim /etc/apache2/conf.d/whitelist.conf

3.  The blue text above will be the IP address that you are whitelisting from the original error. You must keep the backslashes (\) and up-carrot (^) in order for the IP to be read correctly. Thus it will always look something like:

“^192\.168\.896\.321”

For for the id, noted in red, you will change the number after the colon, which will be the Apache error log like we saw above. This will look similar to:

Id:2000221

Add the following code with the colored sections edited to match your intended IP.

SecRule REMOTE_ADDR "^64\.14\.210\.4"
"phase:1,nolog,allow,ctl:ruleEngine=off,id:20000221"

 

Whitelist By URI:

If your IP is dynamic (changing) and you keep getting blocked in the firewall, it is best to whitelist it via URI, the yellow item in the ModSec error.

1. Begin by opening the Easy Apache 4 configuration file:

vim /etc/apache2/conf.d/whitelist.conf

2. Add the following text to the configuration. Remember to pay attention to the highlighted parts.  Change the yellow “/db/index.php” to match your URI and the red id to match the id of your error (Do not use the colon in this one).

<LocationMatch "/db/index.php">
SecRuleRemoveById 20000221
</LocationMatch>

3. The final step for whitelisting, before you finalize the process, is to ensure you have correctly set up the whitelist. For Easy Apache 4 you will run the command:
apachectl -t

As long as the command returns “Syntax Ok” you are safe to make the whitelist active by restarting Apache. Otherwise, review the whitelists to make sure the syntax matches up correctly with the above directions.

4. Lastly, restart Apache with the following command.

/scripts/restartsrv_httpd

You have successfully whitelisted yourself in ModSec!

 

Using ModSec

Cyber Security is a hydra; once one threat is cut off, two more grow back. While this is not a new analogy, it’s important to understand as we battle threats to our network, computers, and servers. With all the complexities that come with security, I want to talk about adequately configuring ModSec to deter threats while still allowing you to work on your websites. Often, when it comes to server security, too much protection can hinder effectiveness.

For example, say you have the following set up on your server:

  • You do not allow root SSH login to the server
  • utilize dual-factor authentication for any SSH logins
  • use an SSH key for the sudo user and require other security safeguards

While this type of configuration is secure, it takes longer to log into your system to make a quick edit to your settings, a double-edged sword; how can you keep the server safe while not tying your own hands?  A great example of how this plays out is using ModSec.

ModSec can block your IP if it falsely flags your work. While this module improves system security, you’ll need to be aware of properly implementing and “scoping” the technology. Scoping in this sense means to manage risks, the focus of what is important for security while still allowing work on the server with minimal interference. To tune out legitimate requests to your server, such as when you are editing your website’s code via a plugin, ModSec has the options to whitelist rules or IPs and keep your work on track.

Whitelisting an IP from the rules that ModSec follows is a great option so long as the IP never changes (i.e. a static IP, see article here to learn more https://support.google.com/fiber/answer/3547208?hl=en) and is limited to only people you trust. This method prevents ModSec from viewing your requests as malicious and blocking your IP. This practice has the drawback that if someone (say an unhappy employee) has access to your network, they now have a way around ModSec to attack your server.

With non-static (dynamic) IPs the problems of whitelisting an IP are readily apparent. With the continual change of a dynamic IP, it creates the potential of exploiting your server, as someone could use an old IP to access the server. Whitelisting specific rules comes to save the day! When you whitelist by rules, you can edit with granularity and limit the rules to particular domains and URIs, protecting the rest of the server from attacks related to that same rule!

Example of ModSecurity

ModSec reads a series of rules and applies them to incoming requests being made to the web server. An example of what a block looks like is:

[Sat Jun 30 02:21:56.013837 2018] [:error] [pid 79577:tid 139862413879040] [client 120.27.217.223:24397] [client 120.27.217.223] ModSecurity: Access denied with code 406 (phase 2). Pattern match "Mozilla/(4|5)\\\\.0$" at REQUEST_HEADERS:User-Agent. [file "/etc/apache2/conf.d/modsec2.liquidweb.conf"] [line "109"] [id "2000064"] [hostname "67.227.192.139"] [uri "/mysql/index.php"] [unique_id "WzchhAjuZ6wPAzo9AwW1WwAAAE8"]

This error shows Apache stopped a potential attack on a file at /mysql/index.php. This is an error similar to what appears when the code is being written or edited within programs like Drupal or WordPress.

Evaluating ModSecurity

If you are persistently being blocked in your firewall while working on your code, ModSec is the likely culprit. The ModSec errors can be found in the Apache error log (in cPanel the path is /usr/local/apache/logs/error_log). The phrase “ModSec” can be quickly isolated from the log (via the command ‘grep “ModSec” /usr/local/apache/logs/error_log’). By comparing you or your developer(s) IP to the log, you’ll be able to identify stopped requests that are legitimate. Verify these are valid requests by double-checking that someone in your organization made them. Once you have done so, you can move forward in setting up a whitelist for the error, per the steps above.

Again, we want to scope to allow the least amount of wiggle room for an attack and ensure we can keep working. If you are unable to have a trusted static IP, you’ll need to use the whitelist URI  method, providing the specific page as an exemption. Once completed, remove both whitelisted items from the configuration file, in case of a genuine attack.

On a parting note, I encourage you to explore ModSec and learn more of the ins and outs of the software. Exploring different methods of whitelisting can be a lot of for to learn and most importantly helps to tighten server security. As always, our Fully Supported Customers can contact our Helpful Human Support team for assistance. Check out articles on security in our Knowledge Base, like this one on Maldet! It’s another excellent way to learn about your server and develop an understanding of server security.