Posted on Leave a comment

How to Ditch Google Email

This is really about how to get off of Gmail/Google Email for Domains/Gsuite. It is not difficult to get off of Google Drive, and Google Photos, as well as Google Docs and Google Sheets, and the like. But there are certain advatages of Gmail/Google Mail, and the free version of GSuite, which I've been using for ten years or so.

Continue reading How to Ditch Google Email

Posted on Leave a comment

Nginx and Letsencrypt SSL on Debian

It is a good idea to get PHP and MariaDB on Debian set up before Nginx (except the PhpMyAdmin which can come after).

Related Artices in Debian Services and Applications - Debian on AWS Lightsail - OpenVPN on Debian + UFW Firewall - Nginx and Letsencrypt on Debian - PHP & MariaDB on Debian

- Grav CMS on Debian

Install Nginx

Edit the /etc/apt/sources.list to add the Nginx repostitory

nano /etc/apt/sources.list

Add the following repository (currently for Debian 9/Stretch)

deb stretch nginx

Download and install the key for the repository

sudo apt-key add nginx_signing.key

Remove nginx-common, update apt and install nginx

sudo apt-get remove -y nginx-common
sudo apt-get update -y
sudo apt-get install -y nginx

Systemd / Nginx Race Condition

There is a known race condition, with a workaround as follows:

mkdir /etc/systemd/system/nginx.service.d
printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" > /etc/systemd/system/nginx.service.d/override.conf
systemctl daemon-reload

Edit /etc/nginx/sites-available/default

Note: these edits are not comprehensive, just to get certbot working. Uncomment the following lines:

listen 443 ssl default_server;
listen [::]:443 ssl default_server;
location / {
try_files $uri $uri/ =404;

Where it says server_name _; change _ to an appropriate fqdn that has an appropriate A record. Save and restart the nginx:

service nginx restart

Letsencrypt Certbot

sudo apt-get update
sudo apt-get install -y python-certbot-nginx certbot -t stretch-backports

Run letsencrypt (automatic)


Test access from a browser.

HSTS Preload

Browsers have a list of servers that require https/ssl. Add sites to the list. Two things are required: 80 to 443 redirect, and an hsts header. For the redirect, add this server configuration:

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        return 301 https://$host$request_uri;

For the HSTS header, this needs to be added to each server. Can simply be added after the listen 443 ssl; line:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

Nginx Info

Nginx has become the standard for much of the web, for the basic standard reason it is not creaky old (though of course still lovable) Apache. However, before we get too far ahead of ourselves, let's recall exactly what we need to know about Nginx in order for it to work as well as Apache:

  • Installation
  • Configuration files
  • Support of SSL / LetsEncrypt
  • SFTP/SCP access to file system (and file rights + ownership)
  • Multiple virtual servers / directories
  • Mimetypes
  • Support for PHP
  • Threading
  • .htaccess and related

Nginx and Related Files and Directories

Standard or default files and directories as follows:

  • /etc/nginx - application directory
  • /etc/nginx/nginx.conf - main configuration file
  • /usr/share/nginx/html - default website root directory - noted as html in nginx.conf
  • /var/log/nginx/error.log - error log
  • /var/log/nginx/access.log - access log
  • /etc/nginx/mime.types - mime types
  • /etc/php.ini - php configuration file

Nginx / PHP-FPM Security Issues

There are significant issues with PHP-FPM in terms of keeping site caching partitioned when using multiple websites/virtual sites. Opcache should be turned off and individual users should be in charge of a different php-fpm process for each site. How to do this is not listed here (just yet).

Posted on Leave a comment

Amazon Canada Incompetence

By Amazon Canada, I am referring to the Amazon Advantage Canada operation. Pure, unadulterated incompetence. Support requests go something like this: - Me: Here is my problem, with detail - AC: Request for information (which is already in the detail) - Me: Submission of requested info, again - AC: Thank you, please wait - AC: We are working on this, thank you for your patience - AC: We are working on this, thank you for your patience - AC: It is fixed now, please try again - Me: No, it is still broken - AC: Thank you, please wait - AC: We are working on this, thank you for your patience - AC: We are working on this, thank you for your patience - AC: It is fixed now, please try again - Me: No, it is still broken - AC: We tried to call you, please provide a time to discuss this isse - Me: No, we don't need to talk, please fix the problem - AC: Thank you, please wait - AC: We are working on this, thank you for your patience - AC: We are working on this, thank you for your patience - AC: It is fixed now, please try again - Me: No, it is still broken - AC: Please send screenshots with dates (obviously they don't believe me) - Me: Submission of requested info, again - AC: We tried to call you, please provide a time to discuss this isse - Me: No, we don't need to talk, please fix the problem - AC: Thank you, please wait Repeat with various slight modifications. This has happened to me twice now, with different issues, and it is completely maddening. First, they cannot update an item in inventory. After three months of this nonsense, I just removed/discontinued the item. The second time, most recently, they can't update my bank information and my account is locked and I can't update it myself. This has been the situation now for over a month. Well, bye bye Amazon Canada, incompetence par excellence.

Posted on Leave a comment

Kindle Paperwhite 4th Gen

I've used a Kindle since the Kindle Keyboard (3rd gen), and since then purchased and used the DX for a while (the much larger model). On 06 September 2012 the Kindle Paperwhite was released and I registered mine on 10 September. I broke that model within six months by wedging it in a bag that had too many objects in it, but Amazon sent out a replacement free-of-charge (which included free shipping, and I live outside the United States).

Continue reading Kindle Paperwhite 4th Gen

Posted on Leave a comment

Debian on AWS Lightsail

This is a setup of several items, starting with Debian 9 on Amazon AWS Lightsail. This has server basics and apt, and then follows with links to additional articles. In general, after several years of running CentOS on Linode, and then Amazon Linux AMI on EC2 and Lightsail, I find that Debian 9 is simply faster, just as secure, and at least slightly easier to use.

Continue reading Debian on AWS Lightsail

Posted on Leave a comment

AWS DHCP Options and Resolv.conf

AWS DHCP options are set on a per-VPC (Virtual Private Cloud) basis. By default, things like the search scope and DNS servers used by a given AWS Instance are set by DHCP which also provides the private IP address (but not any Elastic IP Addresses). Indeed, the Amazon Virtual Private Cloud is a fundamental core service that makes AWS very useful when managing complex and distinct instances and networks. VPCs include addressing, subnets, security, routing, and offer things like VPNs-as-a-service.

Setting AWS DHCP Options

Go to the VPC console in AWS. Note that DHCP Options cannot be edited, they can only be created, assigned, and deleted. Create a new one without the search scope and with preferred DNS servers. Then Assign to given instances. After assigning them, any DHCP Options that are not assigned to any VPC can be deleted.

Amazon Lightsail and VPCs

There seems to be no evidence that Amazon Lightsail offers any kind of VPC ifrastructure that can be managed (including DHCP Options) and likely each Lightsail instance is its own VPC with default DHCP settings (that cannot be set as above). In which case: Edit the file /etc/sysconfig/network-scripts/ifcfg-eth0 or otherwise appropriate configuration files for a network interface.

nano /etc/sysconfig/network-scripts/ifcfg-eth0

Change contents as such:


Change DNS entries to the desired.

Additional Resources and Implications, including a variety of DNS solutions

Posted on Leave a comment

cron and crontabs on Amazon Linux AMI

Two words time-based automation: cron and crontabs (and other apps such as anacron) are needed for so many things on a server. Here is how to use cron and crontabs on Amazon Linux AMI.

Install crontabs

This will in addition install several dependencies, including cron.

yum -y install crontabs
chkconfig crond on
service crond start
service crond status

Edit the crontabs

Remember to do this with su or root, otherwise there might be access issues with the actual items to run. vi is the default editor, but I like nano better, so:

export VISUAL=nano; crontab -e

Crontab syntax

Essentially there are numbers or asterisks for when things are run. From left to right: - Minute (0-59) - Hour of day (0-23) - Day of month (1-31) - Month (1-12) - Day of week (0-6, 0 = Sunday) An asterisk counts for every possible value, which means: > * * * * * = every minute > 0 1 * * * = 01:00 every day > 0 18 * * 0 = Every Sunday at 18:00 (6pm)

Crontab execution

Crontab executes from home directory of the user. It is best to use full paths for the location of scripts and the like

Example MySQL watchdog script

Crontab entry:

* * * * * /usr/local/bin/rsmy >> /var/log/mysqld.log

Script entry:

UP=$(/etc/init.d/mysqld status | grep running | grep -v not | wc -l);
if [ "$UP" -ne 1 ];
    echo "$(date) - MySQL is down - restarting now";
    /sbin/service mysqld start
    echo "$(date) - MySQL is running";
    /usr/bin/free -m


Posted on Leave a comment

WordPress Multisite on Amazon Linux

This assumes a current configuration of: - Amazon Linux (6.x RHEL series) - Apache 2.4 - PHP 5.6 + Opcache - Oracle MySQL 5.7 Installation up to this point is encompassed by: - OpenVPN on Amazon Linux EC2, basic configuration and securing an EC2 instance - Amazon Linux, Apache, MySQL, and PHP, installing and configuring

Install WordPress from Subversion

This is the standard quick install. It is advised to do the most recent stable version, and not the main branch, which can break (more) things. First, install subversion:

yum -y install svn

For Debian:

apt-get install -y subversion

Visit Installing WordPress with Subversion, and look for a command line that looks like the following.

svn co .

The final number will change over time. Currently the options for GIT are a bit malnourished.

Create Database and User

Log into mysql

sudo mysql -u root -p

Create database


Create user and grant access to the database (change username and password as appropriate).

CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
GRANT ALL on database.* to 'user'@'localhost';
flush privileges;

Create wp-config.php

First, copy the sample file into a config file

cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php

Next edit the four parts of the file:

nano /var/www/classic/wp-config.php

Change these: - Database Name - User Name - Password - Table prefix Also add the following at the end

/** to set update method, rather than changing file access */

Save and restart /index.php


WordPress Multisite has advantages (and some disadvantages). The process to change a single site into multisite has several steps. - Disable all plugins - edit wp-config.php to include the following

sudo nano /var/www/html/wp-config.php

Add the following:

/* Multisite */
define( 'WP_ALLOW_MULTISITE', true );

Note that this will then allow you to take the next steps. - Administration > Tools > Network Setup - Configure for subdomains - Once completed, copy the text for .htaccess into httpd.conf (usually this redirection is safe for single site domains as well.

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]
  • Comment out the above item entered into wp-config.php, and instead replace with:
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', true);
define('DOMAIN_CURRENT_SITE', '');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);
define( 'SUNRISE', 'on' );

Note: It is very important to place this where it indicates, just before stop editing below - copy the sunrise.php file to /wp-content/. - restart Apache - Install and enable WordPress MU Domain Mapping - change the settings in > Network Admin > Settings > Domain Mapping to 2,5 (the opposite of the default) - Add domains to the mapping as desired - Set redirections and site defaults to their desired domain name

Reset Filesystem Security Script

Filesystem security can get wonky especially with WordPress plugin and theme updates and manual file copying and editing. There are two things to do: - Make a script that backs up essential configuration files - Make a script that resets all the security in the file paths This is an example of the second:

chown -R username:apache /var/www
find /var/www/html -type d -exec chmod 2775 {} \;
find /var/www/html -type d -exec chmod g+s {} \;
find /var/www/html -type f -exec chmod 0664 {} \;
chown username:username /var/www/html/.b*
chmod 700 /var/www/html/.b*
chown username:username /var/www/html/.profile
chown username:username /var/www/html/.ssh
chmod 1700 /var/www/html/.ssh
chmod 600 /var/www/html/.ssh/authorized_keys
echo ' ';
echo '***************************************************';
echo 'changed ownership and security on wordpress install';
echo '***************************************************';
echo ' ';

PHP Session Handling

WordPress does not use PHP Sessions, and plugins need not, therefore: - Eradicate plugins which use @session_start(); which includes (as per latest scan): - wp-affiliate-platform, - wp-spamshield, - woocommerce-amazon-s3-storage, and - php-compatibility-checker (which is only needed for testing, in any case)

cd /var/www/html
grep -r 'session_start'

Caching Configuration in WordPress

W3 Total Cache

General Settings - Page Cache, Disk: Enhanced - Minify (disabled) - Database Cache, Disk - Object Cache (disabled) - Browser Cache (disabled, we do this manually in httpd.conf) - CDN (disabled) - Use single network configuration file - Purge Policy: Posts page, Post page Page Cache - Cache posts, SSL, Don't cache logged in - Prime page cache, 900, 10 - Preload post cache upon publish - Sitemaps regular expression [a-z0-9_\-]*sitemaps\/[a-z0-9_\-]*\.(xml|xsl|html?)(\.gz)? - Rejected Cookies:

  • Never Cache the Following Pages
  • Note: must include any changes to permalinks and the pages above Database Cache
  • Don't cache for logged in
  • Ignore Query Stems


  • Optimize HTML, Keep HTML Comments
  • Optimize Javascript, aggregate inline JS
  • Optimize CSS, Remove Google Fonts
  • Save aggregated as static files = uncheck

Further Security and Performance Optimization

Exotic Performance Tuning

Testing Tools

Code Cleanup

A good part of speed issues is the actual site code (php/js/css/html) and when it comes to WordPress, especially WordPress plugins, there are a lot of potential conflicts. Blocking JS and CSS is a big part of the problem, as well as removing all the default crap that is not needed (such as various webfonts). - Clean up nonblocking Javascript and CSS - Too many CSS files and embedded CSS in HTML, and too many JS files - Google's Accelerated Mobile Pages - Cache-aware websites

Posted on Leave a comment

Amazon Linux (CentOS), Apache, MySQL, PHP

Note: Amazon Linux AMI is essentially CentOS 6.x. Everything below works on CentOS as well.

Preparation for Amazon LAMP

The OpenVPN on Amazon Linux AMI is a good place to start in preping the L for the AMP part of the lamp stack. Lots of good stuff there. A followup is WordPress Multisite on Amazon Linux AMI.

The Order of Things with Amazon Linux AMI

Amazon Linux AMI is a bit picky about the order of things. Otherwise there will be dependency conflicts, which is a rife problem. Also, make sure to disable (at least temporarily) other repositories, otherwise there can be even more dependency conflicts. Here is a handy script to ensure that an upgrade (or fresh install) will go well, starting with Apache httpd, php, and ssl:

service httpd stop
yum -y erase httpd httpd-tools apr apr-util
yum -y remove php*
yum -y install php56
yum -y install php56-xml php56-xmlrpc php56-soap php56-gd php56-mbstring
yum -y install php56-cli php56-common php56-pdo
yum -y install php56-mysqlnd
yum -y install php56-opcache
yum -y install mod24_ssl
sed -i -e 's/SSLMutex/Mutex/g' /etc/httpd/conf.d/ssl.conf
service httpd start
service httpd restart

Source: Gist Note that this is PHP 5.6, not the vaunted 7.x version. Version 5.6 is (as of July, 2017) the most popular PHP version, and (in a recent study) is installed on 22.4% of all servers whose server-side programming languages are known, compared with 5.4% of all 7.x versions.

Enable httpd Service and Check if Enabled

Enable httpd as a service to startup

chkconfig httpd on

Check the configuration status of httpd

chkconfig --list httpd

Set User and Group Rights

This is especially useful when using sftp.

usermod -a -G apache USERNAME
chown -R USERNAME:apache /var/www
chmod 2775 /var/www
find /var/www -type d -exec chmod 2775 {} \;
find /var/www -type f -exec chmod 0664 {} \;

Create and Test PHP Info Page

echo "" > /var/www/html/phpinfo.php

Note that there are at least three command-line ways of figuring out things such as which php.ini file am I using: - php --ini, - php -i | grep "Configuration File", and - apachectl -S

Copy opcache.php OpCache Status Page

cd /root/temp
mv opcache.php /var/www/html/opcache.php

Test at:


Apache Configuration

Spend time on the following files (shortcut scripts are shown after filename): - nano /etc/httpd/conf/httpd.conf - eap - nano /etc/httpd/conf.d/ssl.conf - essl - nano /etc/httpd/conf.modules.d/00-mpm.conf - empm - sudo nano /etc/httpd/conf.modules.d/00-base.conf - ebase

/etc/httpd/conf/httpd.conf Modifications

## Modifications at Top of File ##
RewriteEngine On
ServerTokens Prod
ServerSignature Off
TraceEnable off
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Header always append X-Frame-Options DENY
Header set X-XSS-Protection "1; mode=block"
Header unset ETag
Header set Cache-Control "max-age=604800, must-revalidate"
FileETag None
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
Header append Vary User-Agent
RewriteRule ^.* - [F]
HostnameLookups Off
RequestHeader unset Proxy early
ServerTokens ProductOnly
## End Modifications ##
## Modifications inside directory ##
# Strip all subdomains not including status.
# NOTE: Disable this while subdomains help get to sites
#RewriteCond %{HTTP_HOST} !^status\.(.*)\.(.*) [NC]
#RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*) [NC]
#RewriteRule ^(.*) https://%2.%3/$1 [R=301,L]
# Require SSL (site-wide)
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R=301,L]
# Redirect Alias Domains (after SSL rewrite)
RewriteCond %{HTTP_HOST} ^domain.tld$ [NC]
RewriteRule ^(.*)$ https://domain2.tld2/$1 [R=301,L]
# WordPress
RewriteBase /
RewriteRule ^index\.php$ - [L]
# Obfuscate the /admin/ and wp-login.php stuff
RewriteRule ^(/)?SoMeWeIrDsHiT/?$ /wp-login.php [QSA,L]
RewriteRule ^(/)?wp-register-php/?$ /wplogin?action=register [QSA,L]
# Add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
# More WordPress Multisite
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]
## End Modifications ##
## Modification after files section ##
# Disable XML-RPC

        Require all denied

        Order allow,deny
        Deny from all

## End Modifications ##
## Modification inside mime_module ##
AddType text/plain .txt
AddType text/html .html
AddType text/xml .xml
AddType text/css .css
AddType application/x-javascript .js
AddType image/x-icon .ico
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE image/x-icon
## End Modification ##
## Modification at End of File ##
#ErrorDocument 500 "The server made a boo boo."
#ErrorDocument 404 /missing.html

  StartServers            2
  MinSpareServers         4
  MaxSpareServers         8
  MaxClients             64
  MaxRequestsPerChild  2560

## End Modification ##

MPM Prefork rule of thumb is ram/15 for max clients, but test that out. The above is for a server with 1gb ram, though with a database on the same server, may need to throttle this back. From another server (with Apache installed), test with Apache Bench (ab), for example:

ab -n 2000 -c 200 https://host.domain.tld:443/info.php

/etc/httpd/conf.d/ssl.conf Modifications

## Modifications at Top ##
SSLStrictSNIVHostCheck  off
SSLUseStapling                   on
SSLStaplingResponderTimeout  5
SSLStaplingReturnResponderErrors off
SSLStaplingCache                 shmcb:/run/ocsp(128000)
## End of Modifications ##
## VirtualHost Modifications ##
SSLCipherSuite         ALL:+HIGH:+TLSv1:!ADH:!EXP:!SSLv2:!MEDIUM:!LOW:!NULL:!aNULL
SSLCompression off
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
SSLVerifyClient none
## End of Modifications ##

Install apachetop for Amazon Linux

Because Amazon Linux AMI is still basically a CentOS 6.x base, and most repositories have a CentOS 7.x version of apachetop, it is important to download and install locally as follows:

mkdir /root/temp
cd /root/temp
yum -y localinstall apachetop-0.15.6-1.el6.i686.rpm

OpCache Configuration

First, comment out the opcache from /etc/php.ini

nano /etc/php.ini

As follows:

;declared in opcache.ini
;zend_extension =

Next, configure the opcache.ini file:

nano /etc/php-5.6.d/10-opcache.ini

Configure as follows:
;128 is for 1gb ram

PHP.INI Configuration

;already declared in opcache.ini
;zend_extension =
engine = On
;for piwik
short_open_tag = Off
asp_tags = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
;unserialize_callback_func =
serialize_precision = 17
;open_basedir =
;disable_functions =
;disable_classes =
zend.enable_gc = On
;zend.multibyte = Off
;zend.script_encoding =
expose_php = Off
max_execution_time = 30
max_input_time = 60
memory_limit = 256M
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
html_errors = On
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 8M
;auto_prepend_file =
;auto_append_file =
default_mimetype = "text/html"
;default_charset = "UTF-8"
;doc_root =
;user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 20M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
; Module Settings ;
[CLI Server]
cli_server.color = On
date.timezone = Asia/Tokyo
pdo_mysql.cache_size = 2000
[mail function]
smtp_port = 25
; For Unix only. You may supply arguments as well (default: "sendmail -t -i").
; sendmail_path = "/usr/sbin/sendmail -t -i"
; Force the addition of the specified parameters to be passed as extra parameters
; to the sendmail binary. These parameters will always replace the value of
; the 5th parameter to mail(), even in safe mode.
;mail.force_extra_parameters =
; Add X-PHP-Originating-Script: that will include uid of the script followed by the filname
mail.add_x_header = On
; The path to a log file that will log all mail() calls. Log entries include
; the full path of the script, line number, To address and headers.
;mail.log =
sql.safe_mode = Off
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"
mysql.allow_local_infile = On
mysql.allow_persistent = On
mysql.cache_size = 2000
mysql.max_persistent = -1
mysql.max_links = -1
mysql.default_port =
mysql.default_socket =
mysql.default_host =
mysql.default_user =
mysql.default_password =
mysql.connect_timeout = 60
mysql.trace_mode = Off
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0
sybct.allow_persistent = On
sybct.max_persistent = -1
sybct.max_links = -1
sybct.min_server_severity = 10
sybct.min_client_severity = 10
bcmath.scale = 0
session.save_handler = files
session.save_path = "/var/lib/php/session"
session.use_cookies = 1
session.use_only_cookies = 1 = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.bug_compat_42 = Off
session.bug_compat_warn = Off
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
mssql.allow_persistent = On
mssql.max_persistent = -1
mssql.max_links = -1
mssql.min_error_severity = 10
mssql.min_message_severity = 10
mssql.compatability_mode = Off
mssql.secure_connection = Off
tidy.clean_output = Off
soap.wsdl_cache_limit = 5
ldap.max_links = -1

Install LetsEncrypt SSL Certs

If OpenSSL is installed and the default settings are in httpd.conf and ssl.conf, then LetsEncrypt should work in a straightforward way. Do add the various virtual server and virtual aliases in both files, and for the ./letsencrypt-auto command, include all hosts adding on -d host.domain.tld one after the other. Also, for Amazon Linux AMI have to include the --debug flag.

yum -y install git
git clone /opt/letsencrypt
cd /opt/letsencrypt
./letsencrypt-auto --debug --apache -d

Note: Use the staging environment for testing before doing a live run. It can save you an hour's wait, if there are things to work out.

Get the Certs into the HSTS Preload List

PHP Configuration

php.ini - stuff - more stuff ... MORE ...

MySQL 5.6 vs. MySQL 5.7

As of mid-July, 2017 there are two main options for MySQL: version 5.6 or version 5.7. MySQL 5.6 is available from the AMI repository, but 5.7 only from Oracle's community repository. Many people have complained about this, as they well should. MariaDB 10.x is a competitor, but without much adoption. The speed and functionality improvements of 5.7 make it the desired distribution release. The issue with the community repository is that it is unclear which distribution to use on Amazon Linux AMI. The standard redhat and fedora distributions don't work because they assume systemd (e.g., RHEL/CentOS 7.x). Some sources suggest using the generic linux distribution. Another option is the RHEL/CentOS 6.x build. Both seem viable, as long as 7.x repositories and distributions are disabled.

RDS with MySQL and Aurora

Besides installing and configuring a database on an EC2 or Lightsail instance (same thing), there are other Amazon database server options. The Amazon Relaltional Database Service (RDS), supports multiple engines including: - RDS for MySQL - RDS for Aurora Note that along with these there are other options such as nosql, redis, etc., and also various caching options.

For a basic MySQL installation (not on RDS, a separate database server), installing via a yum repository makes a shortcut.

MySQL 5.7 on Amazon Linux AMI standard installation

Install some new dependencies, if not present:

yum -y install libaio
yum -y install numactl

Download the repository (see latest version numbers here):

yum -y localinstall mysql57-community-release-el6-11.noarch.rpm

Check to see if repo is installed, which ones are installed, and which available:

yum repolist | grep mysql

Read more about installing and enabling these MySQL repositories. Run the installation command, which will also install various common, libs, client, and server packages.

yum -y install mysql-community-server

Start the service

service mysqld start

Grep the error log which will have the generated password

grep 'temporary password' /var/log/mysqld.log

Login with that password

mysql –u root –p

Type in the password Then, change password

ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPassword';

Check to see if the password is hashed in the database, and also the version of MySQL installed.

select user,host,authentication_string from mysql.user;
select @@version,@@basedir,@@datadir;

Exit out of mysqld


Set mysqld to start on boot, and see if it is set correctly:

chkconfig mysqld on
chkconfig --list mysqld

PhpMyAdmin on Amazon Linux

Install PhpMyAdmin from the Amazon EPEL Repository:

yum -y install phpmyadmin

Edit the file /etc/httpd/conf.d/phpMyAdmin.conf and replace with the ip address of the client.

nano /etc/httpd/conf.d/phpMyAdmin.conf

Restart the web server and database server (to be safe)

service httpd restart
service mysqld restart

Test to see if it works