Posted on

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.

Note: as of Sep 2020, Debian 10 is now available on Lightsail

I will update this soon (mid-2020) to Debian 10 - Bullseye (stable) on AWS and Debian testing on the desktop. I consider this combination to be very good for intermediate users as it keeps them up-to-date on the latest testing build (when things break, that is a learning opportunity), as well as having access to most recent versions of applications, utilities and support libraries. Debian is a huge linux ecosystem which is generally well-supported by a very large community. For one's production desktop environment, Debian testing is an excellent balance of up-to-date application availability and community supportiveness. Together with the extremely stable desktop environment using Openbox/LXDE, very low system requirements are needed.

To be honest, once getting the hang of Openbox/LXDE, I do not see any advantage to Linux Mint or Ubuntu, for that matter (besides the personal repositories). Cinnamon (available on other distributions than Mint) is buggy, memory hungry, and requires a bit of customization. Openbox/LXDE offers nearly the same kind of required customizations, but demands many fewer resources and is nearly crashproof. In my opinion, the good parts of Mint do not include cinnamon, rather applications such as Nemo and Pix, which can of course be installed and run without Mint or Cinnamon.

Continue reading Debian on AWS Lightsail

Posted on

Amazon Lightsail

Amazon Lightsail is a VPS services offered by Amazon that competes with the likes of Rackspace, DigitalOcean, Linode, etc.

Note: As of mid 2018 AWS effectively halved its prices on Lightsail. This means there is a $3.50 USD/mo. option and the $40 option listed below (4gb ram/2 cpu/60gb ssd/4tb xfer) is actually only $20 now.

Compared head-to-head the Lightsail option is a middle-of-the-road offering. However, compared with AWS and including the highly optimized nature of running Amazon Linux AMI (and not overselling with bullshit numbers like some providers), Amazon Lightsail is an extremely attractive VPS.

S3 snapshot backups and other aspects of high reliability make this a go-to package for the VPS market.

Lightsail Specifications

See the Amazon Lightsail FAQs

The various sizes of Lightsail are (as of July 2017):

  • $5/mo. - 512mb ram, 1 core, 20gb ssd, 1tb transfer
  • $10/mo. - 1gb ram, 1 core, 30gb ssd, 2tb transfer
  • $20/mo. - 2gb ram, 1 core, 40gb ssd, 3tb transfer
  • $40/mo. - 4gb ram, 2 core, 60gb ssd, 4tb transfer
  • $80/mo. - 8gb ram, 2 core, 80gb ssd, 5tb transfer

Note that transfer allowances are half of the above, for Mumbai and Sydney currently.

Lightsail vs. EC2 Pricing

The real genius in Lightsail is the pricing. Compared with a 1 year reserved T2.Nano instance, a $5 Lightsail would be as follows:

Total value of $8.13-$98.04 in value (depending mainly on data transfer).

However, if you had only a single zone, a single IP, 8gb of disk (smallest available), and under 1gb of data transfer, then the value is $4.74/mo., which is within 5% of the cost of a $5/mo. Lightsail.

That said, it is not clear how the vcpu works under Lightsail vs. EC2. However, since this is a single infrastructure, likely the performance is similar, and AWS is just going after a different segment of the market (one that is price-conscious).

Lightsail Docs and CLI

Lightsail has docs and a cli.

Lightsail Tasks

  • Create zone(s)
  • Create and download SSH Cert
  • Log in from command prompt with
    • ssh -i /path/to/.ssh/key.pem ec2-user@server.domain.tld
  • Operate under root rights with sudo su

Lightsail Control Panel

Lightsail is not integrated into the rest of AWS, though it is possible to see some aspects of it (perhaps storage?) from the console. Definitely it is managed separately from EC2 and Route53.

This lack of integration is a bit of a pain, but likely it will go away (slowly and partially) over time (perhaps).

Securing Lightsail

Depending upon one's security requirements, it might be useful to create a new user and disable or remove rights to the ec2-user account.

The steps to create a user with the same rights as ec2-user are:

  • create the account useradd username
  • set a password for the account passwd username
  • add the account to the sudo group usermod -aG wheel username
  • log in with the account su - username
  • create a .ssh directory mkdir .ssh
  • set security on the directory chmod 700 .ssh
  • log out of username exit
  • now back in root, copy the authorized_keys file to username
cp /home/ec2-user/.ssh/authorized_keys /home/username/.ssh/authorized_keys

Log all the way out of the system, and try and log in with the username, and same public key.

Once logged in invoke sudo su to ensure it has the correct rights. There should be an error message.

The last step is to replace ec2-user with username in the file: /etc/sudoers.d/cloud-init

If this works, then you have a new account with the same priviledges as the ec2-user (and you have also removed ec2-user from the ability to become root) and can safely delete (or ignore) that account.

Lightsail Limitations

Lightsail has a few limitations, including no tools for transfer or resizing, though in late 2018 an ability to export snapshots to EC2 was added. In addition, Lightsail cannot port filter at the IP address, only at the port level. And for DNS management, CAA records are not supported (as opposed to Route 53 where they are).

Posted on

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

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

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

Posted on

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

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

Thoughts on Amazon Echo Show

The new Amazon Echo Show looks great. Watching the video, it is striking that the interface appears so clean. This is obvious when using voice, since buttons don't really count. Also, the fact that this is not just a piece of hardware and natural language interface, these are applications being shown. In terms of video/voice calls, there is quite a bit of competition, including Facebook, Whatsapp (Facebook again), Viber, Line, Telegram, etc. Oh, and don't forget about Nucleus who seemed to have the idea before Amazon (who is an investor). The fact that the Echo dominates the smart speaker market should be a cause for concern by the likes of the slower-moving Google (who bought Nest years ago), not to mention molassas-like Apple has HomeKit, though that requires that OEMs actually buy Apple chips and integrate them into their devices. Amazon's open approach to connected devices is a repetition of Android vs. IOS. Sure, there are a lot of iphones and even ipads, but the notion that this same rather small minority share will be able to co-opt the vast other connected devices, not really thought out very well. The interaction with other Echo Show devices and other smart devices shows off what is at stake here: Echo as a platform for the home.

Missing from Amazon Echo Show, Release 1.0

My first few thoughts about using this new device in the home are what is missing. - There is no video output, but definitely connecting to a monitor or a TV screen makes a lot of sense (that is, it could perform the function of a FireStick). - There is no keyboard input (but it is a touchscreen, of course), perhaps bluetooth mice/keyboards will work? Not a real deal-breaker - Generic browser user included? We did not see anything resembling such. I get it. This is not meant to become a computer. Rather as its' own unique platform, it will be the heart of the connected home. Which leads to the following significant motivation.

The Future Home will require Echo-integrated Devices and Services

Apparently there are an ever increasing number of devices available to Echo. Certain smart hubs can act as extenders, such as the Almond+ which happens to be our Wifi for the first floor. This is an insight for anyone making buying decisions regarding any kind of home device. Even moreso, those software services which Echo can interact with will have an additional layer of functionality based on that fact alone. This means, for example, that my music cannot be stored only in Google Music (where it reposes for free) but I will need to also ship over the 11,000 songs into Amazon Music (for $25/year), and only then will that become available on the Echo platform. That said, there will be ways of doing some DIY integration, such as using Alexa to interact with Foscam cameras via IFTTT:

Posted on

AMI on EC2 vs. CentOS on Linode

What I learned in migrating from CentOS on Linode to Amazon AMI Linux on EC2. Note: Amazon Lightsail is probably a better comparison, but it is not available in the region we need it in, so EC2 is required for now. Update: Lightsail is now available in more regions.

VPS Hosting and Operating System

A change of VPS providers is generally not such a big deal, unless one is dependent on proprietary tools of the previous provider. In the case of Linode, there are some nice graphs, and they have the Linode Shell (Lish) that is handy when things go south. But moving to Amazon is like entering a different galaxy, one that has alien technology. Sure, in the end you've got a web server, an email server, a vpn, etc., but configuration tools and where things go can be a bit of a learning curve.

Linode to AWS

I've been aware of Linode for a decade, but first started seriously kickin the tires in April, 2014. In November, it was time and I began installation, configuration, and testing, with production sites up in early December, 2014. At 2.5 years, this is the approximate time span for moving to a different platform (in terms of my Sysops habits). Actually, though, I have been content with Linode. The precipitating event to migration was a requirement for a location in Canada, and also an unacceptable amount of downtime on a different VPS host located there. Taking a closer look at AWS offerings, and especially getting a better understanding of billing, convinced me this is viable platform for my price/performance needs.

CentOS vs. AMI

Amazon Linux AMI is more or less a fork of RHEL and/or CentOS, depending on whom one reads. The main points are: - AMI lags a bit behind CentOS, which lags a bit behind Fedora - AMI may or may not yet have systemd (as of June 2017 it does not, treat the system as CentOS 6.x) - firewalld may or may not work on AMI, some reports are it does not yet (more on this) - systemctl does not function out of the box, instead use service and chkconfig


AWS Security Groups as configured in EC2 are managed in a GUI that is akin to iptables/firewalld.

IP Addressing

Unlike most VPS hosts, public IP addresses are not doled out automatically, at least not permanent ones. For that, one needs to provision an elastic ip address. A small number are available per account per region (5), but there are charges for outbound traffic. Also, it is important not to have elastic ip addresses assigned to unactive instances, as there are additional charges, as well as if multiple elastic ip addresses are assigned to a single instance. - EC2 Instance IP Addresses - VPC IP Addressing Guide

EB vs. EC2 vs. Lambda

There are other options to explore with AWS (just to mention): - Elastic Beanstalk, which is kind of self-provisioning (but need stateless design) - Lambda which is a truly serverless environment - Note that Lambda can now run on IOT as Greengrass Core with Lambda Functions

AWS Billing

It is vital to understand how Amazon bills out various services. Not paying attention can easily mean a lot higher costs, without necessarily more services. Another aspect of billing is the apparent greater efficiency of Amazon Linux AMI on EC2, which means that greater resources are not needed (and as is the case with much of the rest of the hosting universe, those numbers that are provided are not real, due to oversubscription.