Tuesday, October 9, 2018

CentOS 7 Apache, Nginx, PHP-FPM, PrestaShop

OS related

Install CentOS7
Create admin user and add make it Administrator (group=wheel)
Give a root-password

I assume that your server IP address is 192.168.1.1

setenforce 0
getenforce
sed -i 's/enforcing/permissive/' /etc/sysconfig/selinux
sed -i 's/enforcing/permissive/' /etc/selinux/config
reboot
yum -y install wget unzip epel-release mlocate
updatedb
yum clean all
yum update -y
reboot

Install Apache & test default page

yum install httpd
sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf
systemctl start httpd.service
systemctl enable httpd.service
systemctl status httpd
httpd -S
ss -tlpn | grep 8080
firewall-cmd --zone=public --permanent --add-port=8080/tcp
firewall-cmd --reload
192.168.1.1:8080 - test Apache welcome page
Disallow Apache to display directories and files within the web root directory /var/www/html:
sudo sed -i "s/Options Indexes FollowSymLinks/Options FollowSymLinks/" /etc/httpd/conf/httpd.conf
systemctl restart httpd

Install MariaDB

Choose database-name, user-name and pasword for your PrestaShop DB

Install MariaDB and set it to automatically start after system reboot:
yum install mariadb mariadb-server -y
systemctl start mariadb.service
systemctl enable mariadb.service
Execute the secure MySQL installation process:
/usr/bin/mysql_secure_installation
Go through the process in accordance with the instructions below:
Enter current password for root (enter for none): Press the Enter key
Set root password? [Y/n]: Input Y, then press the Enter key
New password: Input a new root password, then press the Enter key
Re-enter new password: Input the same password again, then press the Enter key
Remove anonymous users? [Y/n]: Input Y, then press the Enter key
Disallow root login remotely? [Y/n]: Input Y, then press the Enter key
Remove test database and access to it? [Y/n]: Input Y, then press the Enter key
Reload privilege tables now? [Y/n]: Input Y, then press the Enter key
Now, log into the MySQL shell so that you can create a dedicated database for PrestaShop:
mysql -u root -p
CREATE DATABASE pshop-db-name;
GRANT ALL PRIVILEGES ON pshop-db-name.* TO 'pshop-db-username'@'localhost' IDENTIFIED BY 'pshop-db-password' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;

Install PHP


Install PHP and required extensions using YUM:
yum -y install php php-fpm php-mysql php-gd php-ldap php-odbc php-pear php-xml php-xmlrpc php-mbstring php-snmp php-soap php-mcrypt php-curl php-cli curl zlib
Editing php.ini for optimal performance.
sed -i '/memory_limit/c\memory_limit = 128M' /etc/php.ini
sed -i '/upload_max_filesize/c\upload_max_filesize = 16M' /etc/php.ini 
sed -i '/max_execution_time/c\max_execution_time = 60' /etc/php.ini
vi /var/www/html/info.php add: <?php phpinfo(); ?>
systemctl restart httpd
192.168.1.1:8080/info.php review:
Server API Apache 2.0 Handler
_SERVER["SERVER_SOFTWARE"] Apache/2.4.6 (CentOS) PHP/5.4.16
grep -E "mod_proxy.so|mod_proxy_fcgi.so" /etc/httpd/conf.modules.d/* => if no result:
vi /etc/httpd/conf/httpd.conf => find LoadModule and add:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

Adding PHP-FPM (FastCGI Process Manager) support to Apache (all php scripts will be processed by PHP-FPM):
vi /etc/httpd/conf.d/php.conf find <FilesMatch \.php$> change:
#SetHandler application/x-httpd-php
 SetHandler "proxy:fcgi://127.0.0.1:9000" #PHP-FPM uses port 9000
systemctl start php-fpm.service
systemctl enable php-fpm.service
systemctl status php-fpm.service -l
systemctl restart httpd
192.168.1.1:8080/info.php review:
Server API FPM/FastCGI
rm /var/www/html/info.php
systemctl restart httpd

Creating PrestaShop Virtual Host for Apache

Disable (comment all lines) Apache's default welcome page:
sed -i 's/^/#&/g' /etc/httpd/conf.d/welcome.conf
Change "pshop-domain-name" to the name you bought:
mkdir -v /var/www/pshop-domain-name 
Create index.html test page:
echo "<h1 style='color: green;'>Presta Shop</h1>" | sudo tee /var/www/pshop-domain-name/index.html
Then create a phpinfo() file for each site so we can test PHP is configured properly:
echo "<?php phpinfo(); ?>" | sudo tee /var/www/pshop-domain-name/info.php
Make directory for available sites (sites configs will be here):
mkdir /etc/httpd/sites-available
This directory will contain links to the active sites (links to the files in sites-available):
mkdir /etc/httpd/sites-enabled
vi /etc/httpd/conf/httpd.conf
Add this line to the end of the file (this will allow us to quickly enable 
and disable sites by adding and removing links to their config files):
IncludeOptional sites-enabled/*.conf
vi /etc/httpd/sites-available/pshop-domain-name.conf
<VirtualHost *:8080>
    ServerName pshop-domain-name
    ServerAlias www.pshop-domain-name
    DocumentRoot /var/www/pshop-domain-name
    <Directory /var/www/pshop-domain-name>
        AllowOverride All
    </Directory>
</VirtualHost>
AllowOverride All enables .htaccess support
Make site available:
ln -s /etc/httpd/sites-available/pshop-domain-name.conf /etc/httpd/sites-enabled/pshop-domain-name.conf
Execute below to check that httpd.conf files are ok (for now AH00558 warning is ok):
apachectl -t
systemctl restart httpd
Check that green "Presta Shop" string is displayed (if you don't use Public DNS
add server IP with the corresponding site name to the /etc/hosts file): 
http://pshop-domain-name:8080/ 
Check that php uses FPM/FastAGI:
http://pshop-domain-name:8080/info.php

Installing and Configuring Nginx

yum install nginx
systemctl start nginx
systemctl status nginx -l
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --reload
Test nginx deafult page:
http://192.16.8.1.1/
systemctl enable nginx
vi /etc/nginx/nginx.conf and comment all lines between "server {" and closing "}"
systemctl restart nginx -l
Check that default site is unavailable:
http://192.168.1.1/

mkdir /etc/nginx/sites-available
mkdir /etc/nginx/sites-enabled
vi /etc/nginx/nginx.conf 
find "http {" block
Add these lines to the end of the http {} block, then save the file:
include /etc/nginx/sites-enabled/*.conf;
server_names_hash_bucket_size 64;

Create nginx test site:
mkdir -v /usr/share/nginx/sample.org
As we did with Apache's virtual hosts, we'll again create 
index and phpinfo() files for testing after setup is complete:
echo "<h1 style='color: red;'>Sample.org</h1>" | sudo tee /usr/share/nginx/sample.org/inde
echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/sample.org/info.php
Now create a virtual host file for the domain sample.org
Nginx calls server {. . .} areas of a configuration file server blocks. 
Create a server block for the primary virtual host, sample.org. 
The default_server configuration directive makes this the default
virtual host which processes HTTP requests that do not match any other virtual host:
vi /etc/nginx/sites-available/sample.org.conf
server {
    listen 80 default_server;

    root /usr/share/nginx/sample.org;
    index index.php index.html index.htm;

    server_name www.sample.org;
    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        # if the file is not there show a error : mynonexistingpage.php -> 404
        try_files $uri =404;
        
        # pass to the php-fpm server
        fastcgi_pass 127.0.0.1:9000;
        # also for fastcgi try index.php
        fastcgi_index index.php;
        # some tweaking
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 16k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        include fastcgi_params;
    }
}

Enable sample.org site:
ln -s /etc/nginx/sites-available/sample.org.conf /etc/nginx/sites-enabled/sample.org.conf
Check nginx config files for syntax:
nginx -t
systemctl reload nginx -l
Check that sample.org is working:
sample.org

Check nginx is working:
sample.org/info.php
_SERVER["SERVER_SOFTWARE"] nginx/1.12.2
_SERVER["DOCUMENT_ROOT"] /usr/share/nginx/sample.org
Disable sample.org :
rm /etc/nginx/sites-enabled/sample.org.conf
nginx -t
systemctl reload nginx -l

Configuring Nginx for Apache's Virtual Hosts (Proxy to Apache then to FPM)

Let's create an additional Nginx virtual host with multiple domain names
in the server_name directives. Requests for these domain names will be proxied to Apache:
vi /etc/nginx/sites-available/apache.conf
Add the code block below. The try_files directive makes Nginx look for files in the document root and directly serve them. If the file has a .php extension, the request is passed to Apache. Even if the file is not found in the document root, the request is passed on to Apache so that application features like permalinks work without problems:
server {
        listen   80; 

        root /var/www/pshop-domain-name; 
        index index.php index.html index.htm;

        server_name pshop-domain-name www.pshop-domain-name; 

        location / {
        try_files $uri $uri/ /index.php;
        }

        location ~ \.php$ {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:8080;
        }

         location ~ /\.ht {
                deny all;
        }
}
ln -s /etc/nginx/sites-available/apache.conf /etc/nginx/sites-enabled/apache.org.conf
nginx -t
systemctl -l reload nginx

Make Apache pshop-domain-name accessible only from localhost:
vi /etc/httpd/sites-enabled/pshop-domain-name.conf
<VirtualHost 127.0.0.1:8080>
    ServerName pshop-domain-name
    ServerAlias www.pshop-domain-name
    DocumentRoot /var/www/pshop-domain-name
    <Directory /var/www/pshop-domain-name>
        AllowOverride All
    </Directory>
</VirtualHost>
systemctl restart httpd

Configuring Nginx for Apache's Virtual Hosts (Proxy to FPM, no Apache)

systemctl stop httpd
systemctl disable httpd
firewall-cmd --zone=public --remove-port=8080/tcp
firewall-cmd --reload

Warning: The location ~ /\. directive is very important; this prevents Nginx from printing the contents of files like .htaccess and .htpasswd which contain sensitive information.
vi /etc/nginx/sites-available/pshop-domain-name.conf
server {
    listen 80 default_server;

    root /var/www/pshop-domain-name;
    index index.php index.html index.htm;

    server_name www.pshop-domain-name pshop-domain-name;
    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        # if the file is not there show a error : mynonexistingpage.php -> 404
        try_files $uri =404;

        # pass to the php-fpm server
        fastcgi_pass 127.0.0.1:9000;
        # also for fastcgi try index.php
        fastcgi_index index.php;
        # some tweaking
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 16k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        include fastcgi_params;
    }

    location ~ /\. {
        deny all;
    }
}
rm /var/www/pshop-domain-name/info.php
systemctl restart nginx

Installing PHP7 after installing old PHP

yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm -y
yum install yum-utils -y
yum-config-manager --enable remi-php72
yum update php php-zip
yum update
reboot

Installing PrestaShop

Download the latest stable version of PrestaShop from prestashop.com:
mkdir prestashop
Extract all to the prestashop directory:
unzip prestashop_1.7.4.3.zip -d prestashop
mv prestashop/* /var/www/pshop-domain-name/

Check user name used in pshop-domain-name (it must be apache):
echo "<?php echo exec('whoami'); ?>" | sudo tee /var/www/pshop-domain-name/whoami.php
192.168.1.1/whoami.php
rm /var/www/pshop-domain-name/whoami.php
chown -R apache: /var/www/pshop-domain-name/prestashop/
systemctl restart nginx

I don't know why but I couldn't install PrestaShop using GoogleChrome, so use MozillaFirefox (I didn't try other browser) to install PrestaShop:
192.168.1.1/prestashop

If you have any troubles accessing 192.168.1.1/prestashop , you can use file which comes with PrestaShop (vi docs/server_config/nginx.conf.dist) - change content of your /etc/nginx/sites-available/pshop-domain-name.conf to the content of /var/www/pshop-domain-name/docs/server_config/nginx.conf.dist and making changes appropriate to you shop:

  • server_name 
  • root
  • fastcgi_pass 127.0.0.1:9000;
  • #fastcgi_pass unix:/run/php/php7.0-fpm.sock;
systemctl restart nginx

After progress bar goes from 0% to 100%, you'll see 192.168.1.1/install
Now if you want, you can switch to the Chrome:
192.168.1.1/install
chown -R apache: /var/www/pshop-domain-name/


systemctl restart nginx
After several steps you'll be suggested to install php-intl (PHP internationalization) 
and PHP accelerator:
yum install php-intl
Check that php-intl is enabled:
php --ri intl
systemctl restart php-fpm

To view all components needed by PrestaShop or suggested to be installed on the server:
wget https://github.com/PierreRambaud/phppsinfo/archive/master.zip
unzip master.zip
cp phppsinfo-master/phppsinfo.php /var/www/pshop-domain-name/
chown -R apache: /var/www/pshop-domain-name/
systemctl restart nginx -l
login/pass are the same - prestashop
http://192.168.1.1/phppsinfo.php
Change all you find to the recomended values (vi /etc/php.ini) and install additional PHP extensions (yum install php-NeededExtensionName)

systemctl restart php-fpm
systemctl restart nginx -l

check all parameters again:
http://192.168.1.1/phppsinfo.php
If everything is ok:
rm /var/www/pshop-domain-name/phppsinfo.php
systemctl restart php-fpm
systemctl restart nginx -l

http://192.168.1.1/install/index.php :
Installation is very straight-forward, the only note - use previously created database credentials when specifying database related stuff.

rm -rf /var/www/pshop-domain-name/install/
rm -f /var/www/pshop-domain-name/Install_PrestaShop.html
rm -f /var/www/pshop-domain-name/INSTALL.txt
ll /var/www/pshop-domain-name/ | grep admin
Enter admin panel with the found name:
192.168.1.1/admin985ftb6s2

Monday, October 8, 2018

Cisco ASA logging to CentOS 7 rsyslog & logrotate

First of all install CentOS 7 and yum update it.
systemctl status rsyslog.service

If rsyslog is not installed:
yum install rsyslog

Edit rsyslog config (we'll use UDP for messages logging):
vi /etc/rsyslog.conf
search for imudp and uncomment:
$ModLoad imudp
$UDPServerRun 514

systemctl restart rsyslog
systemctl status rsyslog.service

For SELinux semanage packet:
yum install policycoreutils-python

To view which port are allowed by SELinux:
semanage port -l | grep syslog

See if rsyslog is listening to any ports:
ss -nlp | grep rsyslog

firewall-cmd --list-all # find zone name (mine is public)
Allow traffic for rsyslog in that zone:
firewall-cmd --permanent --zone=public --add-port=514/udp
systemctl restart firewalld.service
firewall-cmd --list-all

Creating files for ASA log:
cd /var/log
touch asa.log
vi /etc/syslog.conf 

Log severity levels 
There are eight in total as per Cisco’s definitions below: 
  • 0 = Emergencies => Extremely critical “system unusable” messages 
  • 1 = Alerts => Messages that require immediate administrator action 
  • 2 = Critical => A critical condition 
  • 3 = Errors => An error message (also the level of many access list deny messages) 
  • 4 = Warnings => A warning message (also the level of many other access list deny messages) 
  • 5 = Notifications => A normal but significant condition (such as an interface coming online) 
  • 6 = Informational => An informational message (such as a session being created or torn down) 
  • 7 = Debugging => A debug message or detailed accounting message
Facility - term used to properly identify devices syslog messages. To find ASA facility:
sh log set | grep Fac|fac

Default ASA facility is 20, which is corresponding to rsyslog local4 facility (facility 21 = syslog local5, facility 22 = syslog local6 etc.).

Create a new comment that fits your needs (below lines must be inserted right after #### RULES #### in rsyslog.conf otherwise all messages will be duplicated into messages and boot.log):
# Logs sent from the ASA  IP 10.10.10.10 are saved to /var/log/asa.log file here we have 2 options:
# 1 Use facility to identify message (each equipment has predefined log facility, for example :
local4.info /var/log/asa.log
# 2 Use an IP address to identify message:
if $fromhost-ip=='10.10.10.10' then /var/log/asa.log
        {
         /var/log/asa.log
         stop
        }
# you can use any of two, but only one of them, otherwise all messages will be written twice to the same file

In order for the changes to take effect we need to restart the syslog service. 
systemctl restart rsyslog

Configure clock on an ASA (NTP or manual):
clock timezone AZS 4
clock set 12:33:00 10 Sep 2018
show clock

ASA logging destinations (ASA CLI parameters to logging command): 
  • console – logs are viewed in realtime while connecteng via Serial console 
  • asdm – logs can be viewed in the ASDM GUI. 
  • monitor – logs to a Telnet or SSH session.
  • buffered – this is the internal memory buffer 
  • host – a remote syslog server IP and interface
  • trap – severity for remote syslog
  • mail – send generated logs via SMTP 
  • flow-export-syslogs – send event messages via NetFlow v9

Configure ASA logging to remote rsyslog server (also configuring buffer):
  1. enabling logging:
    1. logging enable 
  2. enable timestamping of log messages:
    1. logging timestamp 
  3. confgure buffer (when buffer filled up - oldest messages are overwritten):
    1. logging buffer-size 128000 
  4. severity level for buffered logging:
    1. logging buffered warnings 
  5. using informational severity:
    1. logging trap informational 
  6. IP of the rsyslog server:
    1. logging host inside 10.10.10.20 
  7. Verify logging settings:
    1. show logging setting
  8. Set up message logging queue (default is 512 messages, max queue size on ASA-5505 is 1024, on ASA-5510 is 2048 and 8192 on all other platforms):
    1. logging queue 1024
    2. show logging queue
Configure logrotate for asa.log:
cat /etc/logrotate.d/rotate_asa_log.conf
 # name of the log-file :
/var/log/asa.log {
    # rotate log daily :
    daily
    # keep 400 old log-files :
    rotate 400
    # compress old log-file after postscript execution :
    compress
    # rotate if log-file size equals or larger than 2GB :
    size 2G
    # add %Y%m%d to the end of the old log-file :
    dateext
    # use -%d%m%Y instead of the default %Y%m%d :
    dateformat -%d%m%Y
    # create empty asa.log file  :
    create 0644 root root
    # don't issue an error if the log-file is missing :
    missingok
    # don't rotate if log-file is empty :
    notifempty
    # use one postrotate script for all log-files (if more than one) :
    sharedscripts
    # start of the postrotate script :
    postrotate
        # HUP signal to rsyslogd PID (read from syslogd.pid file)
        # (actually bug > must be rsyslogd.pid instead of syslogd.pid)
        # makes rsyslog close all open files and restart
        # HUP signal make restart or just reread configs
        # (it's based on daemon's itself behaviour)
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    # end of the postrotate script :
    endscript
}

Test logrotate script without actually rotating anything (-d is debug option and it implies -v verbose option):
logrotate -d /etc/logrotate.d/rotate_asa_log.conf

After testing you can force logrotate to rotate logs:
logrotate -f /etc/logrotate.d/rotate_asa_log.conf

To see last rotation of the log-file:
cat /var/lib/logrotate/logrotate.status | grep asa
"/var/log/asa.log" 2018-10-4-19:9:35

So the nex rotation will be done at time in logrotate.status + specified rotation interval (in out case it's "daily").