This is a tutorial that covers the entire process of setting up
CentOS 6 and installing/configuring Apache, PHP, MySQL, SELinux and
iptables, as well as securing the server. This tutorial will give you a
base setup for running static as well as dynamic web sites using PHP and
MySQL. This tutorial suits VPS or other low-memory configuration as
well as dedicated servers.
Prequisites
This tutorial assumes basic knowledge of shell/console usage and knowledge of one text editor.
You need to have a freshly installed CentOS 6 system to proceed. Once you’re in a root shell, start reading below!
Step 1 – Choose a text editor
Nano is very simple to use and has on-screen help at all times.
Vim is a good editor, but has a slightly steeper learning curve. Here is a good tutorial.
If you find it hard to choose, install and try them both by installing thei via Yum, the CentOS package manager!
Since this is your first installation using Yum you may be prompted
about importing a GPG key. Enter Y followed by the Enter key to accept.
Step 2 – Configure your network
Attempt to ping an external server, such as google:
If you receive a response, skip the rest of this section as you have connectivity. If it fails, keep reading.
Not having connectivity is most often due to the lack of a DHCP server running on the network to issue an IP to your server. If that is the case, you need to configure the IP manually.
Here is a useful step-by-step tutorial for setting up static IP address on CentOS 6.
Step 3 – Update your system
After a fresh CentOS 6 install, run:
Select all updates and let it complete, now run:
You should see your CentOS version, at the time of writing this, that version is:
CentOS release 6.4 (Final)
Step 4 – Configure (or disable) SELinux
I usually disable SELinux as it makes for some cryptic errors when running the LAMP stack. If you would like to have a go at running SELinux enabled with LAMP, here is a good article to get you started.
To disable SELinux:
Change the SELINUX= line to disabled, like so:
Now reboot your machine
Step 5 – Add the EPEL repo
EPEL is an extra software repository with a lot of useful software that is not in the base repo. We will need it later, so let’s add it to our CentOS install! Go to this page to get the most up to date EPEL version. Copy the link from the text epel-release-6-x.noarch and use it in the command below:
Depending on the version of CentOS installed, you might need to change x86_64 to i386 in the URL to the repo.
Step 6 – Install Apache, MySQL and PHP
Issue the command:
Enable Apache and MySQL on startup
Start Apache and MySQL
After starting mysqld, you will receive a prompt to change your MySQL root user password. The dialogue will read…
…
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
…
Two commands will be presented to you, run them both. You will need to use your server name in the second command, as the help prompt instructs you. The base commands are:
Your web server should now be reachable via http://; in a web browser. If you have started Apache but the server is not visible, you probably need to configure iptables.
Step 7 – Configure iptables
Load up the iptables config file
Below the :OUTPUT ACCEPT [0:0] line, add
If you are going to be changing your SSH port (see separate section
below), now is a suitable step to allow connections to the new SSH port.
If we are changing SSH to port 4711, this line should also be added:
Step 8 – Change SSH port
Changing your SSH port makes it harder for hackers to find information about your server via port scanning. To change the port (in our case to 4711), open the sshd config file:
Search for the line “#Port 22″, change it to:
(Note the removal of the hash sign.)
Make sure you have added the iptables rules for your new port! (See section above.)
Restart sshd by issuing:
If you are currently on a SSH console, log out and log back on to your server using the new port.
Step 9 – Install extra “nice-to-have” packages if desired
This section is optional, go to Step 10 to continue if you don’t want any extra packages.
htop
Good replacement for top.
curl and wget
Simplifies file retrieval from the command line. You should install at least one of these. They are often included in your CentOS installation.
unzip
This package allows you to unzip files
man
Manuals for commands. Sometimes not included in minimal installations.
Step 10 – Reboot!
Now is a great time to reboot, issue the command
If your server is not accessible with SSH/HTTP after reboot, there might be something amiss with the iptables settings.
Step 11 – Install phpmyadmin
phpMyAdmin is a powerful tool for manipulating MySQL databases, let’s install it!
Now you can browse to:
http:///phpmyadmin
Add blowfish_secret for security
Add a secret key to $cfg['blowfish_secret'] so it looks like below:
According to this site, your password may contain up to 46 characters.
It’s also a good idea to protect phpMyAdmin behind another layer, HTTP authentication.
You can find out how to do that in this excellent tutorial.
Step 12 – Add extra users
Allow your new user to sudo
sudo allows a user to temporarily take on the role as root.
Note: If you are getting a blank text file (not found) in this step, install sudo with
yum install sudo
Find the line:
Under this line, add a new one to allow your newly created user to use sudo:
Save the file (it’s read-only, so you need to force the write using :wq! in Vim)
Step 13 – Configure Apache
Let’s make some sane modifications to the Apache configuration to improve default behaviour and lower the memory consumption. I am configuring this for a 512MB server, if you have more memory you may retain these values at their original settings or adjust them differently.
Allow for .htaccess overrides
Search for the AllowOverride directive in the configuration file.
Change the instances of:
to
You will also need to uncomment the general AllowOverride declaration by removing the hashtag (#) in front of it.
Before (commented out):
After (Correct version):
Change the amount of workers spawned
Find the IfModule prefork.c directive and change according to the example below.
This reduces the memory footprint of Apache, in exchange for slower responses under heavy load.
Enabling KeepAlive
Change the KeepAlive directive from Off to On.
Warning:
Enabling KeepAlive improves the speed at which pages load, but may make your server crash under heavy load. See this blog post for some interesting etails.
Step 14 – Configure PHP
Let’s edit the PHP configuration file:
Increase the maximum upload file size
I like to set this pretty high, as you can limit the upload filesize in a PHP script should you need it.
You will also need to change the post_max_size restriction:
Increase the memory limit of PHP
This limit controls the maximum amount of memory a single script is allowed to use. The default (128M) is sensible, but you can increase it if you have a good amount of memory.
Increase the maximum execution and input time
The default maximum script execution time is a measly 30 seconds. You can easily bump this to 300 seconds.
The default maximum time to wait for POST and GET data is 60 seconds.
File uploads are counted into this, so it is desirable to increase this
to avoid errors when uploading large files.
Enable the short_open_tag directive, to support shorthand syntax such as . Here’s how to enable it:
Now we can restart httpd and the changes will be active
Install opcode cache
Speed up your PHP applications by installing the Alternative PHP Cache (APC).
First we need to install some dependencies, then we will compile APC using PECL.
Press enter multiple times when prompted to select options (this will pick the defaults.).
Add the APC extension to the PHP configuration:
Under the line [PHP] add:
Adjust size of cache:
We are setting the cache to use 256MB:
(The file apc.ini does not exist at this point, simply write your changes and APC will pick up on it.)
Restart Apache and we’re done!
Optional: APC comes with a small web-based control panel. It’s
included in the installation but you need to copy it to your web root to
use it:
Now you can navigate to /apc.php on your server to see the cache stats.
Step 15 – Configure MySQL
Save your default password for mysqldump
To run mysqldump in a cron job (read more about cron jobs in Step 17), you need to set a username and password to the MySQL configuration file.
Add the following lines at the bottom of the file:
It is not advisable to use the root user here, instead, you may use an account with global read privileges.
(Optional) Disable InnoDB
If you want to use save memory (about 60-100 MB) and don’t need InnoDB tables, you may disable them by editing the MySQL configuration file.
Under the [mysqld] directive, add the following line:
Step 16 – Add virtual hosts to Apache
Virtual hosts allow multiple web sites to be served from a single Apache installation.
The virtual hosts can be added to the end of the Apache configuration file.
Here is an example configuration with two web hosts:
Step 17 – Set up cron jobs
Setting up cron jobs is useful for scheduling tasks. For this we’re going to install CRON and Crontab.
To see the local user crontab issue:
Here is a great resource for learning how to manipulate the crontab file.
Warning
Remember that the scheduled commands are run as the user whos crontab they are in. For cron jobs that require elevated privileges, using the root crontab or changing file permissions may be necessary.
Setting up a cron job to backup all mysql databases
First start editing the crontab:
Now add a new line, which will run our command:
This simple command will back up all databases to the file /root/sqldump.sql at midnight every day.
Note: This requires you to set a [mysqldump] user, as advised in Step 15.
You’re done!
Congratulations on setting up CentOS 6 with LAMP. The section below contains useful commands and other tweaks you can perform.
Test disk speed
Disk speed indicative of performance, different tests test different things, different on virtual environments (such as OpenVZ and KVM) and dedi, some tests might be better for some of them.
How to judge your result (note that this is only accurate for the exact test above)
Check disk usage
Disable or enable iptables
Dump all your MySQL databases to a file (suitable for backup, in crontab or similar)
In Step 15 we saved our MySQL username and password in the MySQL configuration file /etc/my.cnf
Now we can use mysqldump without a password. To dump all databases into a file, issue:
Listing services that automatically run at startup, and their runlevels
Miscellaneous: Setting appropriate file permissions for PHP sites
We’d like for Apache to have as little access to the files it serves as possible. This limits the effects PHP and Apache exploits.
To accomplish this, let’s run an example with a fictional site residing in the folder:
To secure this site we are going to put up the following restrictions:
Feedback
That’s it for this tutorial! I appreciate any feedback you might have, so if something is unclear or can be improved, feel free to leave a comment!
Sources and additional information
http://wiki.centos.org/HowTos/Network/SecuringSSH
http://www.linuxmail.info/add-epel-centos-6/
http://romanrm.ru/en/dd-benchmark
http://www.vectorns.com/blog/19-running-xampp-on-fedora-with-selinux-enabled
http://www.cyberciti.biz/faq/rhel-fedorta-linux-iptables-firewall-configuration-tutorial/
http://www.question-defense.com/tools/phpmyadmin-blowfish-secret-generator
http://www.reallylinux.com/docs/htaccess.shtml
Prequisites
This tutorial assumes basic knowledge of shell/console usage and knowledge of one text editor.
You need to have a freshly installed CentOS 6 system to proceed. Once you’re in a root shell, start reading below!
Step 1 – Choose a text editor
Nano is very simple to use and has on-screen help at all times.
Vim is a good editor, but has a slightly steeper learning curve. Here is a good tutorial.
If you find it hard to choose, install and try them both by installing thei via Yum, the CentOS package manager!
1
| yum install vim nano |
Step 2 – Configure your network
Attempt to ping an external server, such as google:
1
| ping google.com -c 4 |
Not having connectivity is most often due to the lack of a DHCP server running on the network to issue an IP to your server. If that is the case, you need to configure the IP manually.
Here is a useful step-by-step tutorial for setting up static IP address on CentOS 6.
Step 3 – Update your system
After a fresh CentOS 6 install, run:
1
| yum update |
1
| cat /etc/ *release* |
CentOS release 6.4 (Final)
Step 4 – Configure (or disable) SELinux
I usually disable SELinux as it makes for some cryptic errors when running the LAMP stack. If you would like to have a go at running SELinux enabled with LAMP, here is a good article to get you started.
To disable SELinux:
1
| vim /etc/selinux/config |
1
| SELINUX=disabled |
1
| shutdown -r now |
EPEL is an extra software repository with a lot of useful software that is not in the base repo. We will need it later, so let’s add it to our CentOS install! Go to this page to get the most up to date EPEL version. Copy the link from the text epel-release-6-x.noarch and use it in the command below:
1
| rpm -Uvh http: //download .fedoraproject.org /pub/epel/6/x86_64/epel-release-6-X .noarch.rpm |
Step 6 – Install Apache, MySQL and PHP
Issue the command:
1
| yum install mysql
mysql-server mysql-devel httpd php-common php-gd php-mcrypt php-pear
php-pecl-memcache php-mysql php-xml php php-mcrypt php-mbstring
php-devel gcc pcre-devel |
1
2
| chkconfig httpd on chkconfig mysqld on |
1
2
| service httpd start service mysqld start |
…
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
…
Two commands will be presented to you, run them both. You will need to use your server name in the second command, as the help prompt instructs you. The base commands are:
1
2
| /usr/bin/mysqladmin -u root password 'new-password' /usr/bin/mysqladmin -u root -h your- hostname password 'new-password' |
Step 7 – Configure iptables
Load up the iptables config file
1
| vim /etc/sysconfig/iptables |
1
| -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT |
If we are changing SSH to port 4711, this line should also be added:
1
| -A INPUT -m state --state NEW -m tcp -p tcp --dport 4711 -j ACCEPT |
Changing your SSH port makes it harder for hackers to find information about your server via port scanning. To change the port (in our case to 4711), open the sshd config file:
1
| vim /etc/ssh/sshd_config |
1
| Port 4711 |
Make sure you have added the iptables rules for your new port! (See section above.)
Restart sshd by issuing:
1
| service sshd restart |
Step 9 – Install extra “nice-to-have” packages if desired
This section is optional, go to Step 10 to continue if you don’t want any extra packages.
htop
Good replacement for top.
1
| yum install htop |
Simplifies file retrieval from the command line. You should install at least one of these. They are often included in your CentOS installation.
1
| yum install curl wget |
This package allows you to unzip files
1
| yum install unzip |
Manuals for commands. Sometimes not included in minimal installations.
1
| yum install man |
Now is a great time to reboot, issue the command
1
| shutdown -r now |
Step 11 – Install phpmyadmin
phpMyAdmin is a powerful tool for manipulating MySQL databases, let’s install it!
1
2
3
4
5
| cd /var/www/html wget http: //downloads .sourceforge.net /project/phpmyadmin/phpMyAdmin/4 .0.1 /phpMyAdmin-4 .0.1-english.zip?r=http%3A%2F%2Fwww.phpmyadmin.net%2Fhome_page%2Fdownloads.php&ts=1369351562&use_mirror=heanet unzip phpMyAdmin-3.5.6-english.zip mv phpMyAdmin-3.5.6-english phpmyadmin rm -f phpMyAdmin-3.5.6-english.zip |
http://
Add blowfish_secret for security
1
2
3
| cd phpmyadmin cp config.sample.inc.php config.inc.php vim config.inc.php |
1
| $cfg[ 'blowfish_secret' ] = 'your-secret-key' ; |
It’s also a good idea to protect phpMyAdmin behind another layer, HTTP authentication.
You can find out how to do that in this excellent tutorial.
Step 12 – Add extra users
1
2
| useradd username passwd username |
sudo allows a user to temporarily take on the role as root.
1
| vim /etc/sudoers |
yum install sudo
Find the line:
1
| root ALL=(ALL) ALL |
1
| username ALL=(ALL) ALL |
Step 13 – Configure Apache
Let’s make some sane modifications to the Apache configuration to improve default behaviour and lower the memory consumption. I am configuring this for a 512MB server, if you have more memory you may retain these values at their original settings or adjust them differently.
1
| vim /etc/httpd/conf/httpd .conf |
Search for the AllowOverride directive in the configuration file.
Change the instances of:
1
| AllowOverride None |
1
| AllowOverride All |
Before (commented out):
1
| # AllowOverride All |
1
| AllowOverride All |
Find the IfModule prefork.c directive and change according to the example below.
1
2
3
4
5
6
7
8
|
StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 256 MaxRequestsPerChild 4000 < /IfModule > |
Enabling KeepAlive
Change the KeepAlive directive from Off to On.
Warning:
Enabling KeepAlive improves the speed at which pages load, but may make your server crash under heavy load. See this blog post for some interesting etails.
Step 14 – Configure PHP
Let’s edit the PHP configuration file:
1
| vim /etc/php .ini |
I like to set this pretty high, as you can limit the upload filesize in a PHP script should you need it.
1
| upload_max_filesize = 128M |
1
| post_max_size = 128M |
This limit controls the maximum amount of memory a single script is allowed to use. The default (128M) is sensible, but you can increase it if you have a good amount of memory.
1
| memory_limit = 256M |
The default maximum script execution time is a measly 30 seconds. You can easily bump this to 300 seconds.
1
| max_execution_time = 300 |
1
| max_input_time = 300 |
1
| short_open_tag = On |
1
| service httpd restart |
Speed up your PHP applications by installing the Alternative PHP Cache (APC).
First we need to install some dependencies, then we will compile APC using PECL.
1
2
3
| yum install make pecl channel-update pecl.php.net pecl install apc-3.1.13 |
Add the APC extension to the PHP configuration:
1
| vim /etc/php .ini |
1
| extension=apc.so |
1
| vim /etc/php .d /apc .ini |
1
| apc.shm_size=256M |
Restart Apache and we’re done!
1
| service httpd restart |
1
| cp /usr/share/pear/apc .php /var/www/html |
Step 15 – Configure MySQL
Save your default password for mysqldump
To run mysqldump in a cron job (read more about cron jobs in Step 17), you need to set a username and password to the MySQL configuration file.
Add the following lines at the bottom of the file:
1
2
3
| [mysqldump] user = mysql-user password = your-password |
(Optional) Disable InnoDB
If you want to use save memory (about 60-100 MB) and don’t need InnoDB tables, you may disable them by editing the MySQL configuration file.
1
| vim /etc/my .cnf |
1
| skip-innodb |
Virtual hosts allow multiple web sites to be served from a single Apache installation.
The virtual hosts can be added to the end of the Apache configuration file.
Here is an example configuration with two web hosts:
1
2
3
4
5
6
7
8
9
10
11
12
| NameVirtualHost *:80
ServerName your-default-site.com DocumentRoot "/var/www/html" < /VirtualHost >
Servername your-second-site.com ServerAlias www.your-second-site.com DocumentRoot "/var/www/html/your-second-site.com" < /VirtualHost > |
Setting up cron jobs is useful for scheduling tasks. For this we’re going to install CRON and Crontab.
1
2
| yum install crontabs chkconfig crond on |
1
| crontab -e |
Warning
Remember that the scheduled commands are run as the user whos crontab they are in. For cron jobs that require elevated privileges, using the root crontab or changing file permissions may be necessary.
Setting up a cron job to backup all mysql databases
First start editing the crontab:
1
| crontab -e |
1
| 0 0 * * * mysqldump --all-databases > /root/sqldump .sql |
Note: This requires you to set a [mysqldump] user, as advised in Step 15.
You’re done!
Congratulations on setting up CentOS 6 with LAMP. The section below contains useful commands and other tweaks you can perform.
Test disk speed
Disk speed indicative of performance, different tests test different things, different on virtual environments (such as OpenVZ and KVM) and dedi, some tests might be better for some of them.
1
| dd if = /dev/zero of= test bs=64k count=16k conv=fdatasync |
- 0-25 MB/s -> Garbage
- 25-70 MB/s -> Acceptable
- 70-120 MB/s -> Good
- >120 MB/s -> Excellent
Check disk usage
1
| df -h |
1
| chkconfig iptables on /off |
In Step 15 we saved our MySQL username and password in the MySQL configuration file /etc/my.cnf
Now we can use mysqldump without a password. To dump all databases into a file, issue:
1
| mysqldump --all-databases > /root/sqldump .sql |
1
| chkconfig --list |
We’d like for Apache to have as little access to the files it serves as possible. This limits the effects PHP and Apache exploits.
To accomplish this, let’s run an example with a fictional site residing in the folder:
1
| /var/www/html/yoursite |
- Files can only be read
- Directories can only be read and executed (this is required for PHP to work)
- Apache is the owner of all files
1
2
3
| chown -R apache:apache /var/www/html/yoursite chmod -R 400 /var/www/html/yoursite chmod -R a+X /var/www/html/yoursite |
That’s it for this tutorial! I appreciate any feedback you might have, so if something is unclear or can be improved, feel free to leave a comment!
Sources and additional information
http://wiki.centos.org/HowTos/Network/SecuringSSH
http://www.linuxmail.info/add-epel-centos-6/
http://romanrm.ru/en/dd-benchmark
http://www.vectorns.com/blog/19-running-xampp-on-fedora-with-selinux-enabled
http://www.cyberciti.biz/faq/rhel-fedorta-linux-iptables-firewall-configuration-tutorial/
http://www.question-defense.com/tools/phpmyadmin-blowfish-secret-generator
http://www.reallylinux.com/docs/htaccess.shtml
No comments:
Post a Comment