Category Archives: Linux

Apache 2.2 + PHP-FPM on Centos

WITHOUT disabling MOD_PHP in Apache

>> Compile module:
yum -y install httpd-devel gcc
mkdir /tmp/fastcgi
cd /tmp/fastcgi
wget https://github.com/whyneus/magneto-ponies/raw/master/mod_fastcgi-SNAP-0910052141.tar.gz
tar -zxf mod_fastcgi*
cd mod_fastcgi-*
make -f Makefile.AP2 top_dir=/usr/lib64/httpd
cp .libs/mod_fastcgi.so /usr/lib64/httpd/modules/

>> Enable the module:
echo "LoadModule fastcgi_module /usr/lib64/httpd/modules/mod_fastcgi.so" > /etc/httpd/conf.d/fastcgi.conf


>> Install php-fpm and create pools like this:
[$USER]
listen = /dev/shm/$USER-php5-fpm.sock
user = $USER
group = $USER
listen.owner = $USER
listen.group = apache
listen.mode = 0666
pm = dynamic
pm.max_children = 35
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 25
slowlog = /var/log/php-fpm/$USER-slow.log
php_admin_value[error_log] = /var/log/php-fpm/$USER-error.log
php_admin_flag[log_errors] = on


>> Add this in the VHOST configuration (before the end of </VirtualHost>)
FastCGIExternalServer /dev/shm/$USER-php.fcgi -socket /dev/shm/$USER-php5-fpm.sock -flush -idle-timeout 1800
AddHandler php-fpm .php
Action php-fpm /php.fcgi
Alias /php.fcgi /dev/shm/$USER-php.fcgi
DirectoryIndex index.php
<FilesMatch "\.php$">
    SetHandler php-fpm
</FilesMatch>


>> Double check php.ini for 'session.save_path'. 
session.save_path = "/tmp"
;session.save_path = "/var/lib/php/session"

 

Linux Firewall notes

IPTABLES GENERIC

>> Allow port 80 ONLY to private interface for Cloud Load Balancer
-A INPUT -i eth1 -p tcp -m conntrack --ctstate NEW -m tcp --dport 80 -j ACCEPT

>> Block whole subnet
# iptables -I INPUT -s xxx.xxx.xxx.0/24 -j DROP

>> Allow specific IP only
iptables -I INPUT -p tcp -s YourIP --dport 22 -j ACCEPT

>> Delete rules

iptables -vnL --line-numbers

iptables -D <chain> /et<rule_number>
iptables -D INPUT 4

-A INPUT -s <SOURCE_NETWORK/32> -p tcp -m tcp --dport 21 -m comment --comment "FTP port open" -j ACCEPT
-A INPUT -s <SOURCE_NETWORK/32> -p tcp -m multiport --dports 60000:65000 -m comment --comment "FTP passive mode ports" -j ACCEPT

 


UBUNTU – UFW

service ufw status

ufw allow 80

ufw allow from <IP> to any port <port>

>> Allow network range
ufw allow 192.168.1.0/24

>> Delete rule
ufw status numbered
ufw delete <rule_number>

>> Allow port 80 only on eth1
ufw allow in on eth1 to [eth1 ip addr] port 80 proto tcp
# ufw allow from <SOURCE_IP>&nbsp;to any port 25
Rule added

# ufw delete allow from <SOURCE_IP> to any port 25
Rule deleted

ufw insert 1 allow from <ip address>

ufw deny from <ip address>
ufw deny from <ip address/24>

https://help.ubuntu.com/community/UFW

 


CENTOS / RH – Firewalld

Saved rules in: /etc/sysconfig/iptables

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="<SOURCE_IP>" port port="10000" protocol="tcp" accept'

firewall-cmd --reload

firewall-cmd --list-all

firewall-cmd --add-service http --permanent
firewall-cmd --add-service https --permanent
systemctl restart firewalld.service
firewall-cmd --list-services

>> Add manual rule in firewalld

firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -s 192.168.3.0/24 -m comment --comment "NFS Network" -j ACCEPT

>> Remove manual added rule in firewalld
vim /etc/firewalld/direct.xml

 

Linux ACL examples

Group permissions are NO LONGER related to group. It’s a MASK!

# setfacl -R -m u:apache:rwx html/
# getfacl html/
# file: html/
# owner: root
# group: root
user::rwx
user:alphausr:rwx
user:caesar:rwx
group::r-x
mask::rwx
other::r-x

To remove ACL as this is a temporary user and reinstate alphausr;

cd /var/www/; setfacl -R -b html/; setfacl -R -m u:alphausr:rwx html/


DEFAULT ACL
# setfacl -m d:u:apache:rwx html/

BACKUP
# getfacl -R /var/www/html/ > /root/html.perm

RESTORE (need to be in / )
# cd /
# setfacl –restore=/root/html.perm


ACL for WordPress

APACHE_ROOT=/var/www/vhosts/
SITE=mydomain.com
USERNAME=ftpuser

cd $APACHE_ROOT
setfacl -m d:u:apache:rwx .
setfacl -R -m u:apache:rwx .

find . -type d | xargs chmod 775
find . -type f | xargs chmod 664

chown -R $USERNAME $SITE

getfacl $SITE
# file: document_root
# owner: <username> <<<<<<< check this
# group: root
user::rwx <<<<<<< this
user:apache:rwx <<<<<<< and this 🙂
group::rwx
mask::rwx
other::r-x

PHPMyAdmin on Centos/Ubuntu

BASIC SETUP (Apache)

>> Set password authentication
/etc/httpd/conf.d/phpMyAdmin.conf (or apache.conf on Ubuntu)

<Directory /usr/share/phpMyAdmin/>
# <IfModule mod_authz_core.c>
# Apache 2.4
# <RequireAny>
# Require ip 127.0.0.1
# Require ip ::1
# </RequireAny>
# </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>
AuthUserFile /etc/httpd/.htpasswdfile
AuthName Restricted
AuthType Basic
require valid-user

</Directory>

>> Generate random password
PASS=$(tr -cd ‘[:alnum:]’ < /dev/urandom | fold -w12 | head -n1)

>> Set password automatically
htpasswd -bmc /etc/httpd/.htpasswdfile phpadminuser $PASS

>> Set password manually
htpasswd -c /etc/httpd/.htpasswdfile phpadminuser
(FYI ‘phpadminuser’ it’s the username)
>> To ADD users, just remove the -c flag

=====================================================================
Troubleshooting

curl -I http://<URL>/phpmyadmin/ –basic –user <username>:<password>

Example: (with error)
# curl -I http://<SERVERIP>/phpmyadmin/ –basic –user serverinfo:mxuYr35TTD5rgT3SR9ND
HTTP/1.1 500 Internal Server Error
Date: Thu, 25 Sep 2014 13:14:44 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=UTF-8

+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

UBUNTU
>> Install the package
# apt-get update && apt-get -y install phpmyadmin

# ln -s /etc/phpmyadmin/apache.conf phpmyadmin.conf
# a2enconf phpmyadmin

>> Open firewall
ufw allow 80

>> When/if it asks the following:
> Please choose the web server that should be automatically configured to run phpMyAdmin => select apache2
> Configure database for phpmyadmin with dbconfig-common? => NO!!!

>> Enable mcrypt
php5enmod mcrypt
service apache2 graceful

>> Create phpmyadmin database and pmaadmin user
cd /usr/share/doc/phpmyadmin/examples
gunzip create_tables.sql.gz
mysql < create_tables.sql
mysql -e “GRANT SELECT, INSERT, DELETE, UPDATE ON phpmyadmin.* TO ‘pmaadmin’@’%’ IDENTIFIED BY ‘<PASSWORD>'”

>> Configuration file for phpmyadmin /etc/dbconfig-common/phpmyadmin.conf

mv /etc/dbconfig-common/phpmyadmin.conf{,.orig} ; vim /etc/dbconfig-common/phpmyadmin.conf

dbc_install=’false’
dbc_upgrade=’true’
dbc_remove=”
dbc_dbtype=’mysql’
dbc_dbuser=’pmaadmin’
dbc_dbpass='<PASSWORD>’
dbc_dbserver='<CLOUD_DB_HOST>’
dbc_dbport=”
dbc_dbname=’phpmyadmin’
dbc_dbadmin=’pmaadmin’
dbc_basepath=”
dbc_ssl=”
dbc_authmethod_admin=”
dbc_authmethod_user=”

>> Apply configuration
/usr/sbin/dbconfig-generate-include/etc/dbconfig-common/phpmyadmin.conf -f php > /etc/phpmyadmin/config-db.php

>> Disable MySQL different library warning
echo “\$cfg[‘ServerLibraryDifference_DisableWarning’] = true;” >> /etc/phpmyadmin/config.inc.php

>> Fix DB table references
sed -i.orig ‘s/pma_/pma__/g’ /etc/phpmyadmin/config.inc.php

>> Secure the main page (this should be under SSL)
htpasswd -c /etc/phpmyadmin/htpasswd.setup phpadminuser

ADD this into Directory for /usr/share/phpmyadmin

<IfModule mod_authn_file.c>
AuthType Basic
AuthName “phpMyAdmin Setup”
AuthUserFile /etc/phpmyadmin/htpasswd.setup
</IfModule>
Require valid-user
————————————————————–
-> Example:
<Directory /usr/share/phpmyadmin>
Options FollowSymLinks
DirectoryIndex index.php

<IfModule mod_php5.c>
AddType application/x-httpd-php .php

php_flag magic_quotes_gpc Off
php_flag track_vars On
php_flag register_globals Off
php_admin_flag allow_url_fopen Off
php_value include_path .
php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/javascript/
</IfModule>
<IfModule mod_authn_file.c>
AuthType Basic
AuthName “phpMyAdmin Setup”
AuthUserFile /etc/phpmyadmin/htpasswd.setup
</IfModule>
Require valid-user

</Directory>
————————————————————–

====================================================================

Multiple DBs (Ubuntu) => /etc/phpmyadmin/config-db.php

/* Servers configuration */
$i = 0;

/* Server: db01 [1] */
$i++;
$cfg[‘Servers’][$i][‘verbose’] = ‘db01’;
$cfg[‘Servers’][$i][‘host’] = ‘<DB_IP/FQDN>’;
$cfg[‘Servers’][$i][‘port’] = ”;
$cfg[‘Servers’][$i][‘socket’] = ”;
$cfg[‘Servers’][$i][‘connect_type’] = ‘tcp’;
$cfg[‘Servers’][$i][‘extension’] = ‘mysqli’;
$cfg[‘Servers’][$i][‘auth_type’] = ‘cookie’;
$cfg[‘Servers’][$i][‘user’] = ”;
$cfg[‘Servers’][$i][‘password’] = ”;

/* Server: db02 [2] */
$i++;
$cfg[‘Servers’][$i][‘verbose’] = ‘db02’;
$cfg[‘Servers’][$i][‘host’] = ‘<DB_IP/FQDN>’;
$cfg[‘Servers’][$i][‘port’] = ”;
$cfg[‘Servers’][$i][‘socket’] = ”;
$cfg[‘Servers’][$i][‘connect_type’] = ‘tcp’;
$cfg[‘Servers’][$i][‘extension’] = ‘mysqli’;
$cfg[‘Servers’][$i][‘auth_type’] = ‘cookie’;
$cfg[‘Servers’][$i][‘user’] = ”;
$cfg[‘Servers’][$i][‘password’] = ”;

====================================================================
PHP-FPM (Ubuntu):

vim /etc/apache2/conf-enabled/phpmyadmin.conf

ProxyPassMatch ^/phpmyadmin/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9001/usr/share/phpmyadmin/$1
ProxyPassMatch ^/phpmyadmin/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9001/usr/share/phpmyadmin$1index.php

Multiple DBs (Ubuntu) /etc/phpmyadmin/config-db.php
/* Servers configuration */
$i = 0;

/* Server: db01 [1] */
$i++;
$cfg[‘Servers’][$i][‘verbose’] = ‘db01’;
$cfg[‘Servers’][$i][‘host’] = ‘<DB_IP/FQDN>’;
$cfg[‘Servers’][$i][‘port’] = ”;
$cfg[‘Servers’][$i][‘socket’] = ”;
$cfg[‘Servers’][$i][‘connect_type’] = ‘tcp’;
$cfg[‘Servers’][$i][‘extension’] = ‘mysqli’;
$cfg[‘Servers’][$i][‘auth_type’] = ‘cookie’;
$cfg[‘Servers’][$i][‘user’] = ”;
$cfg[‘Servers’][$i][‘password’] = ”;

/* Server: db02 [2] */
$i++;
$cfg[‘Servers’][$i][‘verbose’] = ‘db02’;
$cfg[‘Servers’][$i][‘host’] = ‘<DB_IP/FQDN>’;
$cfg[‘Servers’][$i][‘port’] = ”;
$cfg[‘Servers’][$i][‘socket’] = ”;
$cfg[‘Servers’][$i][‘connect_type’] = ‘tcp’;
$cfg[‘Servers’][$i][‘extension’] = ‘mysqli’;
$cfg[‘Servers’][$i][‘auth_type’] = ‘cookie’;
$cfg[‘Servers’][$i][‘user’] = ”;
$cfg[‘Servers’][$i][‘password’] = ”;

=====================================================================
Error: The mcrypt extension is missing. Please check your PHP configuration.

php5enmod mcrypt

sudo updatedb
locate mcrypt.ini

>> Verify that new files exists here (they should be auto created from the issue above)

ls -al /etc/php5/cli/conf.d/20-mcrypt.ini
ls -al /etc/php5/apache2/conf.d/20-mcrypt.ini

>> Otherwise… create symbol links now

ln -s /etc/php5/mods-available/mcrypt.ini/etc/php5/cli/conf.d/20-mcrypt.ini
ln -s /etc/php5/mods-available/mcrypt.ini/etc/php5/apache2/conf.d/20-mcrypt.ini

>> Restart Apacahe

service apache2 restart

+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

CENTOS

>>Install right RH repositories (if not present):
yum install epel-release
yum install httpd php php-mycrypt phpmyadmin

> Centos 5/6
chkconfig httpd on
service httpd start
-> open port 80 in /etc/sysconfig/iptables

> Centos 7
systemctl enable httpd.service
systemctl start httpd.service

firewall-cmd –add-service http –permanent
firewall-cmd –list-services
firewall-cmd –permanent –zone=public –add-service=http
firewall-cmd –reload

cd /usr/share/doc/phpMyAdmin-4.0.10.9/examples/
mysql < create_tables.sql

mysql -e “GRANT SELECT, INSERT, DELETE, UPDATE ON phpmyadmin.* TO ‘pmaadmin’@’%’ IDENTIFIED BY ‘<PASSWORD>'”

cp config.sample.inc.php /etc/phpMyAdmin/config.inc.php

>> Change these accordingly
$cfg[‘Servers’][$i][‘host’] = ‘<DB_IP/FQDN>’;
/* User used to manipulate with storage */
$cfg[‘Servers’][$i][‘controlhost’] = ‘<DB_IP/FQDN>’;
$cfg[‘Servers’][$i][‘controluser’] = ‘pmaadmin’;
$cfg[‘Servers’][$i][‘controlpass’] = ‘<PASSWORD>’;

/* Storage database and tables */
$cfg[‘Servers’][$i][‘pmadb’] = ‘phpmyadmin’;
$cfg[‘Servers’][$i][‘bookmarktable’] = ‘pma__bookmark’;
$cfg[‘Servers’][$i][‘relation’] = ‘pma__relation’;
$cfg[‘Servers’][$i][‘table_info’] = ‘pma__table_info’;
$cfg[‘Servers’][$i][‘table_coords’] = ‘pma__table_coords’;
$cfg[‘Servers’][$i][‘pdf_pages’] = ‘pma__pdf_pages’;
$cfg[‘Servers’][$i][‘column_info’] = ‘pma__column_info’;
$cfg[‘Servers’][$i][‘history’] = ‘pma__history’;
$cfg[‘Servers’][$i][‘table_uiprefs’] = ‘pma__table_uiprefs’;
$cfg[‘Servers’][$i][‘tracking’] = ‘pma__tracking’;
$cfg[‘Servers’][$i][‘designer_coords’] = ‘pma__designer_coords’;
$cfg[‘Servers’][$i][‘userconfig’] = ‘pma__userconfig’;
$cfg[‘Servers’][$i][‘recent’] = ‘pma__recent’;

>> Add these two lines at the bottom of /etc/phpMyAdmin/config.inc.php to disable the remaining 2 warnings

>> MySQL different library warning
$cfg[‘ServerLibraryDifference_DisableWarning’] = true;

>> A newer version of phpMyAdmin is available and you should consider upgrading
$cfg[‘VersionCheck’] = false;

=====================================================================
Multiple DBs (Centos) =>/etc/phpMyAdmin/config.inc.php
(example of 2 servers – comment out the below lines)

// Server db01
$i++;
/* Authentication type */
$cfg[‘Servers’][$i][‘auth_type’] = ‘cookie’;
/* Server parameters */
$cfg[‘Servers’][$i][‘host’] = ‘<DB_IP/FQDN>’;
$cfg[‘Servers’][$i][‘connect_type’] = ‘tcp’;
$cfg[‘Servers’][$i][‘compress’] = false;

// Server db02
$i++;
/* Authentication type */
$cfg[‘Servers’][$i][‘auth_type’] = ‘cookie’;
/* Server parameters */
$cfg[‘Servers’][$i][‘host’] = ‘<DB_IP/FQDN>’;
$cfg[‘Servers’][$i][‘connect_type’] = ‘tcp’;
$cfg[‘Servers’][$i][‘compress’] = false;

#$i++;
#$cfg[‘Servers’][$i][‘host’] = ‘localhost’; // MySQL hostname or IP address
$cfg[‘Servers’][$i][‘port’] = ”; // MySQL port – leave blank for default port
$cfg[‘Servers’][$i][‘socket’] = ”; // Path to the socket – leave blank for default socket

#$cfg[‘Servers’][$i][‘connect_type’] = ‘tcp’; // How to connect to MySQL server (‘tcp’ or ‘socket’)
$cfg[‘Servers’][$i][‘extension’] = ‘mysqli’; // The php MySQL extension to use (‘mysql’ or ‘mysqli’)
#$cfg[‘Servers’][$i][‘compress’] = FALSE; // Use compressed protocol for the MySQL connection
// (requires PHP >= 4.3.0)

 


If you’d like to install this from source, use this link.

Apache loop with WordPress and SSL cert installed on a Cloud Load Balancer

  • Terminate SSL onto the CLB
  • Change the main site URL to use HTTPS in the WordPress configuration
  • Add “SetEnvIf x-forwarded-proto https HTTPS=on” in the vhost configuration
  • add these in wp-config: [OPTIONAL]
    define(‘FORCE_SSL_ADMIN’, false);define(‘FORCE_SSL_LOGIN’, false);
    if (strpos($_SERVER[‘HTTP_X_FORWARDED_PROTO’], ‘https’) !== false)
    $_SERVER[‘HTTPS’]=’on’;


  • a good test to make sure PHP is receiving HTTPS are these lines in a test.php file. If should return “on” if PHP is getting HTTPS properly, or if it returns no value, PHP is not aware it’s being called over HTTPS.
    <?php
    printf($_SERVER['HTTPS'])
    ?>

     

PHP test pages

Basic PHP page

cat > test.php <<EOF
<?php
  echo "<h1>This is a test page</h1>";
?>
EOF

 

PHPinfo page

<?php
// Show all information, defaults to INFO_ALL
phpinfo();
?>

(command line)

php -r "phpinfo();"

php-fpm/users php page check

cat > test.php <<EOF
<?php
  echo '<br><br>This website is running as: <b>' . exec('/usr/bin/whoami') . '</b>';
  echo '<br><br>From path: <b><i>' . getcwd() . '</i></b><br><br>';
  echo '<br><b><font size="5" color="red">DELETE THIS ONCE TESTED!</font></b>' . "\n";
?>

 

 

MySQL – How much memory for InnoDB buffer?

Use this to find out how much storage each engine uses:

mysql -e "select engine, SUM(DATA_LENGTH)/1024 as data_size, SUM(INDEX_LENGTH)/1024 as index_size, ((sum(DATA_LENGTH)+sum(INDEX_LENGTH))/1024) as total_size from information_schema.tables group by engine;"
+--------------------+-----------+------------+------------+
| engine | data_size | index_size | total_size |
+--------------------+-----------+------------+------------+
| CSV | 0.0000 | 0.0000 | 0.0000 |
| InnoDB | 480.0000 | 0.0000 | 480.0000 |
| MEMORY | 0.0000 | 0.0000 | 0.0000 |
| MyISAM | 0.0000 | 1.0000 | 1220.5859 |
| PERFORMANCE_SCHEMA | 0.0000 | 0.0000 | 0.0000 |
+--------------------+-----------+------------+------------+

From the data above, it may seem like a good idea to keep innodb_buffer_pool low, because we have so much MyISAM data.
BUT if I get one query a minute against that MyISAM data, and 500 queries per second against the considerably smaller InnoDB data-set, that doesn’t make sense anymore.
Then we’d want all of the InnoDB data in memory, hence a buffer pool of 512M+

It’s down to data usage and where the hotspots are!


Percona Toolkit to ‘get the hotspots’

wget http://www.percona.com/downloads/percona-toolkit/2.2.12/tarball/percona-toolkit-2.2.12.tar.gz
tar -zxvf percona-toolkit-2.2.12.tar.gz -C /opt/ 
cd /opt/percona-toolkit-2.2.12/ 
perl Makefile.PL 
make

Get the hotspots:
you can set NUMPACKETS or keep the tcpdump running for 20 minutes. JUST keep an eye on the file size!

NUMPACKETS=1000
tcpdump -s 65535 -x -nn -q -tttt -i any -c $NUMPACKETS port 3306 > /tmp/mysql.tcp.txt 

bin/pt-query-digest --type tcpdump /tmp/mysql.tcp.txt

FYI: https://bugs.launchpad.net/percona-toolkit/+bug/1402776  official bug for that database being wrong thing