Skip to content

Instantly share code, notes, and snippets.

@hex333ham
Last active August 1, 2019 23:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hex333ham/8c70fd1a318eb5ca50caca7223e6ace7 to your computer and use it in GitHub Desktop.
Save hex333ham/8c70fd1a318eb5ca50caca7223e6ace7 to your computer and use it in GitHub Desktop.
Centos 6/7 LAMP server setup

How to setup a Centos 6/7 LAMP server correctly (or at least how I do it, needs work).

To check the centos version and system info, do this:

hostnamectl

To check the full release version, do this:

rpm --query centos-release

Installing

I would suggest you secure SSH first, if you mess up here you won't waste hours of setup if your provider needs to reset the server.

  • Apache
  • /var/www permissions and ACL
  • EPEL, Remi & MariaDB repositories & yum utils
  • PHP 7.1, modules & composer
  • phpMyAdmin
  • MariaDB
  • Fail2ban
  • Ssh securing
  • Sftp users
  • Backups (rsync/rsnapshot)
  • SSL certificates
  • Virus scans
  • Mailx
  • Security (making a start)

Apache

As simple as:

yum install httpd

To modify the config:

/etc/httpd/conf/httpd.conf

Enabling

To start the server:

sudo systemctl start httpd

To load it on boot:

sudo systemctl enable httpd

Virtualhost sample config

<VirtualHost *:80>
    ServerAdmin admin@example.com
    ServerName www.example.com
    ServerAlias example.com
    DocumentRoot /var/www/example.com/public_html
    ErrorLog /var/log/httpd/example_com_error.log
    CustomLog /var/log/httpd/example_com_requests.log combined
   <Directory "/var/www/example.com/public_html">
        AllowOverride All
        php_value session.save_path "/var/www/example.com/phpsessions"
   </Directory>
</VirtualHost>

Symfony sample alias (can be placed in virtualhost)

    Alias /appname /var/www/appname/public
    <Directory "/var/www/appname/public">
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

Permissions

/var/www

Set the parent folder to:

chmod 755 /var/www
chown root:apache /var/www

This is done to allow additional SFTP users.

Set contents to:

chmod -R 775 /var/www/*
chown -R apache:apache /var/www/*

SELinux

Make sure selinux is on:

selinux 1

For details of settings see here:

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/managing_confined_services/sect-managing_confined_services-the_apache_http_server-types

Allow httpd access

sudo chcon -t httpd_sys_content_t /var/www -R

Allow write only to specific dirs

This will be required for folders like uploads or cache, allows httpd to read and write to files/directories.

sudo chcon -t httpd_sys_rw_content_t /var/www/[site-required-writes] -R

Repositories & yum-utils

EPEL & Remi

These are required to install PHP 7, fail2ban and other useful tools.

For CentOS 7:

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm

For CentOS 6:

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
yum install http://rpms.remirepo.net/enterprise/remi-release-6.rpm

yum-utils:

yum install yum-utils

MariaDB repository:

Create the repo file:

vi /etc/yum.repos.d/MariaDB.repo

Put this in the file for CentOS 7:

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.1/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

Put this in the file for CentOS 6:

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.1/centos6-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

PHP 7.1 & Modules

INSTALL REMI & EPEL FIRST

To install:

yum-config-manager --enable remi-php71
yum install php php-mysql php-common php-devel php-enchant php-intl php-gd php-zip php-mcrypt php-posix php-fpm php-opcache php-mbstring php-pdo php-pspell php-soap php-xml php-xmlrpc php-pecl-ssh2 php-sqlite3 php-sodium

Alternatively, for 7.2 on Ubuntu (my dev machine):

sudo apt install php7.2 php7.2-mysql php7.2-common php7.2-enchant php7.2-intl php7.2-gd php7.2-zip php7.2-posix php7.2-fpm php7.2-opcache php7.2-mbstring php7.2-pdo php7.2-pspell php7.2-soap php7.2-xml php7.2-xmlrpc php7.2-pear php7.2-curl php7.2-sqlite3

Check the version:

php -v

Edit the .ini:

sudo vi /etc/php.ini

Composer

To install composer:

yum install composer

This should be loaded from the epel repo, in order to get the latest version.

phpMyAdmin

Install

phpMyAdmin needs installing from remi to work with PHP 7.

To enable Remi and install phpMyAdmin, run this:

yum --enablerepo=remi install phpmyadmin

Secure

To secure, first open the config file:

sudo vi /etc/httpd/conf.d/phpMyAdmin.conf

Set the alias by modifying this line:

Alias /phpMyAdmin /usr/share/phpMyAdmin
Alias /phpmyadmin /usr/share/phpMyAdmin

Generate a random string from https://passwordsgenerator.net/

Modify those lines as follows (replacing [RANDOM STRING] with your generated string):

#Alias /phpMyAdmin /usr/share/phpMyAdmin
Alias /[RANDOM STRING] /usr/share/phpMyAdmin

Make a note of the string, this will be used to access phpMyAdmin.

To allow external access, modify these lines:

   <IfModule mod_authz_core.c>
     # Apache 2.4
     Require local
   </IfModule>
   <IfModule !mod_authz_core.c>
     # Apache 2.2
     Order Deny,Allow
     Deny from All
     Allow from 127.0.0.1
     Allow from ::1
   </IfModule>

Apache >= 2.4

Replace

Require local

With:

Order allow,deny
Allow from all
Require all granted

Apache 2.2

Replace:

Order Deny,Allow
Deny from All
Allow from 127.0.0.1
Allow from ::1

With:

Order allow,deny
Allow from All

Save file, restart apache:

sudo service httpd restart

You should now be able to access phpMyAdmin externally.

MariaDB

Check if installed:

rpm -qa | grep mariadb

INSTALL MARIADB REPOSITORY FIRST

To Install:

yum install MariaDB-server MariaDB-client -y

To Enable:

service mysqld start
chkconfig --level 35 mysqld on
service mysqld status

To setup (MAKE SURE TO RUN AS SUDO):

sudo mysql_secure_installation

Check version:

mysql -V
mysql --print-defaults
mysql -u root -p

Fail2ban

INSTALL REMI & EPEL FIRST

Install:

yum install fail2ban

Enable:

systemctl enable fail2ban

Configure:

vi /etc/fail2ban/jail.local

[DEFAULT]
# Ban hosts for one hour:
bantime = 3600

# Override /etc/fail2ban/jail.d/00-firewalld.conf:
banaction = iptables-multiport

[sshd]
enabled = true

Restart:

systemctl restart fail2ban

Status:

fail2ban-client status

SSH Securing

Create new root user

First, create a new user for root, set the password and add it to the sudoers file:

DO NOT SKIP THIS STEP OR YOU WILL BE LOCKED OUT

adduser username
passwd username

Add it to the sudoers group:

usermod -aG wheel username

Test sudo on user:

su - username
sudo ls -la /root

If the sudo command fails

Try modifying the sudoers file:

sudo vi /etc/sudoers

Add this line somewhere:

username ALL=(ALL) ALL

Re-check the user has sudo priviliges.

Secure SSH

Modify the ssh config:

sudo vi /etc/ssh/sshd_config

Modify the following line to prevent root login:

# Prevent root logins:
PermitRootLogin no

Add the following line to limit SSH to the new user you created:

AllowUsers username

Restart the ssh service:

service sshd restart

More methods to look into

https://wiki.centos.org/HowTos/Network/SecuringSSH

SFTP Users

Add and set a new users password:

adduser username
passwd username

Add this user to the Apache group:

usermod -a -G apache username

Set the users home to /var/www:

usermod -m -d /var/www username

Add the new user to those allowed to connect via SSH:

sudo vi /etc/ssh/sshd_config

AllowUsers [USERS] username

Restart the ssh service:

service sshd restart

Rsync/Rsnapshot Backups

Not going to go through setup for a backup machine, only how to get the backup machine baking your server up.

To setup a backup machine see here - https://www.howtoforge.com/installing-rsnapshot-on-centos

Install on local machine

yum install rsnapshot

Setup backups on backup machine

Login to your backup machine and open the config file:

vi /etc/rsnapshot.conf

Place the following in your config file (replace spaces with tabs):

backup [USER]@[SERVERIP]:/var/www/ [BACKUP_FOLDER_NAME]/

Then, generate an SSH key for you local machine using the user you defined as [ROOTUSER].

This is so your backup machine can connect without a password.

Create a key pair for your backup machines root user, don't use a passphrase and accept defaults:

ssh-keygen -t rsa

Copy this to your local machine:

ssh-copy-id -i ~/.ssh/id_rsa.pub [USER]@[SERVERIP]

Test it works:

ssh [USER]@[SERVERIP]

Setup cron, un-comment the bottom few lines (should look like code sample when done):

vi /etc/cron.d/rsnapshot

# This is a sample cron file for rsnapshot.
# The values used correspond to the examples in /etc/rsnapshot.conf.
# There you can also set the backup points and many other things.
#
# To activate this cron file you have to uncomment the lines below.
# Feel free to adapt it to your needs.
0 */4         * * *           root    /usr/bin/rsnapshot hourly
30 3          * * *           root    /usr/bin/rsnapshot daily
0  3          * * 1           root    /usr/bin/rsnapshot weekly
30 2          1 * *           root    /usr/bin/rsnapshot monthly

Check it works:

rsnapshot -t hourly

If it looks ok, run your first backup:

rsnapshot hourly

MYSQL Backups

To create an SQL backup (using Connor's script), first create a user that can select, show view, trigger, lock and read databases on the target machine (not modify).

Make sure the user is only accessible from the backup machines IP address.

Append the following line to sql_list.sh:

sudo sh $1'scripts/sql.sh' [SERVER_IP] [SQL_USER] [SQL_PASS] [DB_NAME] $1

Job done.

SSL Certificates

Let's Encrypt

CentOS 7 - https://certbot.eff.org/lets-encrypt/centosrhel7-apache.html

CentOS 6 - https://certbot.eff.org/lets-encrypt/centos6-apache.html

Traditional

Generate a CSR:

https://support.rackspace.com/how-to/generate-a-csr-with-openssl/

Send the CSR to the SSL signing thing, get the certificates back.

Install said certificates:

Open httpd.conf:

/etc/httpd/conf/httpd.conf

Modify and paste the following code into your VirtualHost (or just in this file for the whole server):

SSLEngine on
SSLCertificateFile /etc/ssl/example.com.crt
SSLCertificateKeyFile /etc/ssl/example.com.key
SSLCertificateChainFile /etc/ssl/example.com.crt

Restart apache and test:

sudo service httpd restart

Virus Scans

Virus scans are handled by ClamAV at the moment (free and open source).

For clamd see this link for now - https://www.hostinger.com/tutorials/how-to-install-clamav-centos7

To have the logs mailed to you, make sure to install mailx

Install

yum install clamav-server clamav-data clamav-update clamav-filesystem clamav clamav-scanner-systemd clamav-devel clamav-lib clamav-server-systemd

Comment out example text:

sed -i -e "s/^Example/#Example/" /etc/freshclam.conf
sed -i -e "s/^Example/#Example/" /etc/clamd.d/scan.conf

Update database:

freshclam

First scan (test on home):

clamscan -r /home

Scanning

Update database:

freshclam

Scan entire system (only notify viruses, ring bell when found):

clamscan -r --bell -i /

Daily scans

First, we create the daily scan script (entire system, change DIRTOSCAN to narrow focus):

vi /root/clamscan_daily.sh

#!/bin/bash
LOGFILE="/var/log/clamav/clamav-$(date +'%Y-%m-%d').log";
EMAIL_MSG="Please see the log file attached.";
EMAIL_FROM="servername@domainname.com";
EMAIL_TO="webmaster@domainname.co.uk";
DIRTOSCAN="/var/www";

for S in ${DIRTOSCAN}; do
 DIRSIZE=$(du -sh "$S" 2>/dev/null | cut -f1);

 echo "Starting a daily scan of "$S" directory.
 Amount of data to be scanned is "$DIRSIZE".";

 freshclam

 clamscan -ri "$S" >> "$LOGFILE";

 # get the value of "Infected lines"
 MALWARE=$(tail "$LOGFILE"|grep Infected|cut -d" " -f3);

 # if the value is not equal to zero, send an email with the log file attached
 if [ "$MALWARE" -ne "0" ];then
 # using heirloom-mailx below
 echo "$EMAIL_MSG"|mail -a "$LOGFILE" -s "[sysnotif]Malware Found" -r "$EMAIL_FROM" "$EMAIL_TO";
 fi 
done

exit 0

Then we add the log file directory:

mkdir /var/log/clamav
chmod 755 /var/log/clamav

Change the script permissions:

chmod 0755 /root/clamscan_daily.sh

Add to crontab:

ln /root/clamscan_daily.sh /etc/cron.daily/clamscan_daily

Test the script:

/root/clamscan_daily.sh

Mailx

Install

yum install mailx

Then create a symbolic link for mail:

ln -s /bin/mailx /bin/email

Enable httpd to send mail in selinux:

setsebool httpd_can_sendmail 1

Then edit the config file to your requirements:

vi /etc/mail.rc

Sample usage

echo "Your message" | mail -v -s "Message Subject" email@address

Using SMTP with SSL (GMAIL etc.)

https://coderwall.com/p/ez1x2w/send-mail-like-a-boss

Security (making a start)

STSS

can cause issues if HTTPS is disabled, or non-HTTPS subdomains

https://stackoverflow.com/questions/24144552/how-to-set-hsts-header-from-htaccess-only-on-https

Apache/.htaccess headers

<IfModule mod_headers.c>
  Header set X-XSS-Protection "1; mode=block"
  Header set X-Content-Type-Options nosniff
</IfModule> 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment