Vladimir's Bauble

TypeTango on AWS

This is how to set up a LAMP web server on Amazon EC2. I covered how to set up a new VPC on another page. This is focused on the server. Window translation should be UTF-8 to avoid misinterpreted characters. Log in and create a personal user (a sudoer in root group who can log in via ssh)
Using username "ec2-user". Authenticating with public key "imported-openssh-key" Last login: Sat Oct 21 22:39:19 2017 from 98.15.124.244 __| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/ No packages needed for security; 5 packages available Run "sudo yum update" to apply all updates. [ec2-user@ip-10-0-0-127 ~]$ sudo useradd vlad [ec2-user@ip-10-0-0-127 ~]$ sudo passwd vlad Changing password for user vlad. ... passwd: all authentication tokens updated successfully. [ec2-user@ip-10-0-0-127 ~]$ sudo usermod -a -G root vlad [ec2-user@ip-10-0-0-127 ~]$ sudo usermod -g root vlad [ec2-user@ip-10-0-0-127 ~]$ sudo cat /etc/sudoers.d/cloud-init ec2-user ALL = NOPASSWD: ALL # User rules for ec2-user ec2-user ALL=(ALL) NOPASSWD:ALL [ec2-user@ip-10-0-0-127 ~]$ sudo cp /etc/sudoers.d/cloud-init /etc/sudoers.d/vlad [ec2-user@ip-10-0-0-127 ~]$ sudo nano /etc/sudoers.d/vlad [ec2-user@ip-10-0-0-127 ~]$ sudo cat /etc/sudoers.d/vlad vlad ALL = NOPASSWD: ALL # User rules for vlad vlad ALL=(ALL) NOPASSWD:ALL [ec2-user@ip-10-0-0-127 ~]$ sudo cp -R .ssh /home/vlad [ec2-user@ip-10-0-0-127 ~]$ sudo chown -R vlad /home/vlad/.ssh [ec2-user@ip-10-0-0-127 ~]$ sudo chgrp -R vlad /home/vlad/.ssh
Using username "vlad". Authenticating with public key "imported-openssh-key" __| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/ No packages needed for security; 5 packages available Run "sudo yum update" to apply all updates. [vlad@ip-10-0-0-127 ~]$ sudo yum update ... Updated: amazon-ssm-agent.x86_64 0:2.2.16.0-1.amzn1 aws-cfn-bootstrap.noarch 0:1.4-24.16.amzn1 curl.x86_64 0:7.53.1-10.77.amzn1 krb5-libs.x86_64 0:1.15.1-8.43.amzn1 libcurl.x86_64 0:7.53.1-10.77.amzn1 Complete! [vlad@ip-10-0-0-127 ~]$ [vlad@ip-10-0-0-127 ~]$ sudo yum install mlocate ... Installed: mlocate.x86_64 0:0.22.2-4.10.amzn1 Complete! [vlad@ip-10-0-0-127 ~]$ sudo updatedb [vlad@ip-10-0-0-127 ~]$ locate httpd /usr/share/doc/jpackage-utils-1.7.5/httpd-javadoc.conf [vlad@ip-10-0-0-127 ~]$ [vlad@ip-10-0-0-127 ~]$ locate mysql /usr/lib/python2.7/dist-packages/boto/pyami/installers/ubuntu/mysql.py /usr/lib/python2.7/dist-packages/boto/pyami/installers/ubuntu/mysql.pyc /usr/lib/python2.7/dist-packages/boto/pyami/installers/ubuntu/mysql.pyo /usr/share/doc/rsyslog-5.8.10/ommysql.html /usr/share/doc/rsyslog-5.8.10/rsyslog_mysql.html /usr/share/vim/vim80/syntax/mysql.vim [vlad@ip-10-0-0-127 ~]$ [vlad@ip-10-0-0-127 ~]$ locate php /etc/sysconfig/modules/acpiphp.modules /lib/modules/4.9.51-10.52.amzn1.x86_64/kernel/drivers/pci/hotplug/acpiphp_ibm.ko /usr/share/doc/rsyslog-5.8.10/rsyslog_php_syslog_ng.html /usr/share/mime/application/x-php.xml /usr/share/nano/php.nanorc /usr/share/vim/vim80/autoload/phpcomplete.vim /usr/share/vim/vim80/compiler/php.vim /usr/share/vim/vim80/ftplugin/php.vim /usr/share/vim/vim80/indent/php.vim /usr/share/vim/vim80/syntax/php.vim
Install MySQL:
[vlad@ip-10-0-0-127 ~]$ sudo yum install mysql57 ... Installed: mysql57.x86_64 0:5.7.18-2.3.amzn1 Dependency Installed: mysql-config.x86_64 0:5.5.57-1.18.amzn1 mysql57-common.x86_64 0:5.7.18-2.3.amzn1 Complete! [vlad@ip-10-0-0-127 ~]$ sudo yum install mysql57-server ... Installed: mysql57-server.x86_64 0:5.7.18-2.3.amzn1 Dependency Installed: mysql57-errmsg.x86_64 0:5.7.18-2.3.amzn1 Complete! [vlad@ip-10-0-0-127 ~]$ sudo chkconfig mysqld on [vlad@ip-10-0-0-127 ~]$ sudo shutdown -r now [vlad@ip-10-0-0-127 ~]$ sudo service mysqld status mysqld (pid 2853) is running... [vlad@ip-10-0-0-127 ~]$ mysql -uroot Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.7.18 MySQL Community Server (GPL) Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> exit Bye
Install Apache:
[vlad@ip-10-0-0-127 ~]$ sudo yum install httpd24 ... Installed: httpd24.x86_64 0:2.4.27-3.75.amzn1 Dependency Installed: apr.x86_64 0:1.5.1-1.12.amzn1 apr-util.x86_64 0:1.4.1-4.17.amzn1 httpd24-tools.x86_64 0:2.4.27-3.75.amzn1 Complete! [vlad@ip-10-0-0-127 ~]$ cat /etc/httpd/conf.modules.d/00-mpm.conf # Select the MPM module which should be used by uncommenting exactly # one of the following LoadModule lines: # prefork MPM: Implements a non-threaded, pre-forking web server # See: http://httpd.apache.org/docs/2.4/mod/prefork.html LoadModule mpm_prefork_module modules/mod_mpm_prefork.so # worker MPM: Multi-Processing Module implementing a hybrid # multi-threaded multi-process web server # See: http://httpd.apache.org/docs/2.4/mod/worker.html # #LoadModule mpm_worker_module modules/mod_mpm_worker.so # event MPM: A variant of the worker MPM with the goal of consuming # threads only for connections with active processing # See: http://httpd.apache.org/docs/2.4/mod/event.html # #LoadModule mpm_event_module modules/mod_mpm_event.so [vlad@ip-10-0-0-127 ~]$ sudo apachectl configtest AH00557: httpd: apr_sockaddr_info_get() failed for ip-10-0-0-127 AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message Syntax OK [vlad@ip-10-0-0-127 ~]$ sudo mkdir /our [vlad@ip-10-0-0-127 ~]$ sudo chmod g+w /our [vlad@ip-10-0-0-127 ~]$ mkdir /our/conf [vlad@ip-10-0-0-127 ~]$ echo "ServerName localhost" > /our/conf/global-httpd.conf [vlad@ip-10-0-0-127 ~]$ sudo ln -s /our/conf/global-httpd.conf /etc/httpd/conf.d/aa_global-httpd.conf [vlad@ip-10-0-0-127 ~]$ sudo apachectl configtest Syntax OK [vlad@ip-10-0-0-127 ~]$ sudo chkconfig httpd on [vlad@ip-10-0-0-127 ~]$ shutdown -r now [vlad@ip-10-0-0-127 ~]$ sudo service httpd status httpd (pid 2603) is running... [vlad@ip-10-0-0-127 ~]$ sudo yum install mod24_ssl ... Installed: mod24_ssl.x86_64 1:2.4.27-3.75.amzn1 Complete!
Make some symlinks to help us remember what we did.
[vlad@ip-10-0-0-127 ~]$ ln -s /etc/httpd/conf.d /our/conf [vlad@ip-10-0-0-127 ~]$ ln -s /etc/httpd/conf.modules.d/00-mpm.conf /our/conf [vlad@ip-10-0-0-127 ~]$ ln -s /etc/sudoers.d/vlad /our/conf/vlad-sudoers [vlad@ip-10-0-0-127 ~]$ ln -s /home/vlad/.ssh/authorized_keys /our/conf/vlad-authorized_keys
Create our directory structure.
[vlad@ip-10-0-0-127 ~]$ cd /our [vlad@ip-10-0-0-127 our]$ mkdir -p sites/adchorus/docroots/dev [vlad@ip-10-0-0-127 our]$ mkdir -p logs/adchorus [vlad@ip-10-0-0-127 our]$ mkdir -p bin [vlad@ip-10-0-0-127 our]$ mkdir -p ssl-certs [vlad@ip-10-0-0-127 our]$ mkdir -p mysql-dumps [vlad@ip-10-0-0-127 our]$ mkdir -p git-repos [vlad@ip-10-0-0-127 our]$ cd /our/sites/adchorus/docroots [vlad@ip-10-0-0-127 docroots]$ ln -s dev test [vlad@ip-10-0-0-127 docroots]$ ln -s dev live [vlad@ip-10-0-0-127 docroots]$ find /our /our /our/conf /our/conf/global-httpd.conf /our/conf/vlad-authorized_keys /our/conf/conf.d /our/conf/vlad-sudoers /our/conf/00-mpm.conf /our/ssl-certs /our/git-repos /our/bin /our/mysql-dumps /our/sites /our/sites/adchorus /our/sites/adchorus/docroots /our/sites/adchorus/docroots/dev /our/sites/adchorus/docroots/test /our/sites/adchorus/docroots/live /our/logs /our/logs/adchorus
Create our httpd conf files. Let's start with globals.
[vlad@ip-10-0-0-127 ~]$ nano /our/conf/global-httpd.conf [vlad@ip-10-0-0-127 ~]$ cat /our/conf/global-httpd.conf ServerName localhost <Directory /our/sites> Options -Indexes +FollowSymLinks DirectorySlash Off RewriteOptions AllowNoSlash AllowOverride All Require all granted </Directory> [vlad@ip-10-0-0-127 ~]$ sudo apachectl configtest Syntax OK
Site-specific conf. This must be configured in stages because it is tied in with generating SSL certs. Eventually we will be redirecting HTTP to HTTPS and adchorus.com to www.adchorus.com, but we must do none of that yet because in order to generate certs we need all our domains to answer via HTTP. Why we prend filesnames with `aa_`.
[vlad@ip-10-0-0-127 ~]$ mkdir /our/logs/adchorus/{dev,test,live} [vlad@ip-10-0-0-127 ~]$ nano /our/conf/adchorus-httpd.conf [vlad@ip-10-0-0-127 ~]$ sudo ln -s /our/conf/adchorus-httpd.conf /etc/httpd/conf.d/aa_adchorus-httpd.conf [vlad@ip-10-0-0-127 ~]$ cat /etc/httpd/conf.d/aa_adchorus-httpd.conf <VirtualHost *:80> ServerName dev.adchorus.com DocumentRoot /our/sites/adchorus/docroots/dev SetEnv SERVER_ROLE dev CustomLog /our/logs/adchorus/dev/access_log-dev common ErrorLog /our/logs/adchorus/dev/error_log-dev </VirtualHost> <VirtualHost *:80> DocumentRoot /our/sites/adchorus/docroots/test SetEnv SERVER_ROLE test ServerName test.adchorus.com CustomLog /our/logs/adchorus/test/access_log-test common ErrorLog /our/logs/adchorus/test/error_log-test </VirtualHost> <VirtualHost *:80> ServerName www.adchorus.com ServerAlias adchorus.com ServerAlias live.adchorus.com DocumentRoot /our/sites/adchorus/docroots/live SetEnv SERVER_ROLE live CustomLog /our/logs/adchorus/live/access_log-live common ErrorLog /our/logs/adchorus/live/error_log-live </VirtualHost> [vlad@ip-10-0-0-127 ~]$ sudo apachectl configtest Syntax OK [vlad@ip-10-0-0-127 ~]$ sudo apachectl restart [vlad@ip-10-0-0-127 ~]$ sudo chmod g+rx /var/log/httpd [vlad@ip-10-0-0-127 ~]$ ln -s /var/log/httpd /our/logs [vlad@ip-10-0-0-127 ~]$ echo 'Hello, World.' > /our/sites/adchorus/docroots/dev/index.html
Change the shell prompt:
[vlad@ip-10-0-0-127 ~]$ PS1="[\u in \w]$ " [vlad in ~]$ echo 'PS1="[\u in \w]$ "' >> ~/.bashrc
Create a backup: Letsencrypt
[vlad in ~]$ cd /our/bin [vlad in /our/bin]$ wget https://dl.eff.org/certbot-auto ... 2017-10-23 11:54:06 (62.1 MB/s) - ‘certbot-auto’ saved [57312/57312] [vlad in /our/bin]$ chmod a+x certbot-auto [vlad in /our/bin]$ PATH=$PATH:/our/bin [vlad in /our/bin]$ echo 'export PATH=$PATH:/our/bin' >> ~/.bash_profile
We must always include --staging while tinkering with certbot, because we can only request 5 real certs per week. certbot-command-line-options See which version of certbot we have.
[vlad in /our/bin]$ sudo ./certbot-auto --version --debug Bootstrapping dependencies for Amazon... (you can skip this with --no-bootstrap) yum is /usr/bin/yum Loaded plugins: priorities, update-motd, upgrade-helper ... Installed: augeas-libs.x86_64 0:1.0.0-5.7.amzn1 gcc.noarch 0:4.8.5-1.22.amzn1 libffi-devel.x86_64 0:3.0.13-16.5.amzn1 openssl-devel.x86_64 1:1.0.2k-7.103.amzn1 python27-tools.x86_64 0:2.7.12-2.120.amzn1 system-rpm-config.noarch 0:9.0.3-42.28.amzn1 Dependency Installed: cpp48.x86_64 0:4.8.5-11.135.amzn1 gcc48.x86_64 0:4.8.5-11.135.amzn1 glibc-devel.x86_64 0:2.17-196.172.amzn1 glibc-headers.x86_64 0:2.17-196.172.amzn1 kernel-headers.x86_64 0:4.9.51-10.52.amzn1 keyutils-libs-devel.x86_64 0:1.5.8-3.12.amzn1 krb5-devel.x86_64 0:1.15.1-8.43.amzn1 libcom_err-devel.x86_64 0:1.42.12-4.40.amzn1 libgcc48.x86_64 0:4.8.5-11.135.amzn1 libgomp.x86_64 0:6.4.1-1.45.amzn1 libkadm5.x86_64 0:1.15.1-8.43.amzn1 libmpc.x86_64 0:1.0.1-3.3.amzn1 libselinux-devel.x86_64 0:2.1.10-3.22.amzn1 libsepol-devel.x86_64 0:2.1.7-3.12.amzn1 libverto-devel.x86_64 0:0.2.5-4.9.amzn1 mpfr.x86_64 0:3.1.1-4.14.amzn1 zlib-devel.x86_64 0:1.2.8-7.18.amzn1 Complete! Creating virtual environment... Installing Python packages... Installation succeeded. certbot 0.19.0
These commands are complicated so lets save them to files for future reference and run those files.
[vlad in /our/bin]$ vim our-first-certbot-staging-run [vlad in /our/bin]$ cat our-first-certbot-staging-run certbot-auto certonly --staging --debug --agree-tos --no-eff-email --email webmaster@adchorus.com --cert-name 34.205.128.170 --webroot -w /our/sites/adchorus/docroots/live -d www.adchorus.com,adchorus.com,live.adchorus.com -w /our/sites/adchorus/docroots/dev -d dev.adchorus.com -w /our/sites/adchorus/docroots/test -d test.adchorus.com -w /our/sites/adchorus/docroots/live [vlad in /our/bin]$ chmod a+x our-first-certbot-staging-run [vlad in /our/bin]$ our-first-certbot-staging-run Requesting to rerun /our/bin/certbot-auto with root privileges... Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Obtaining a new certificate Performing the following challenges: http-01 challenge for www.adchorus.com http-01 challenge for adchorus.com http-01 challenge for live.adchorus.com http-01 challenge for dev.adchorus.com http-01 challenge for test.adchorus.com Using the webroot path /our/sites/adchorus/docroots/live for all unmatched domains. Waiting for verification... Cleaning up challenges Unable to clean up challenge directory /our/sites/adchorus/docroots/live/.well-known/acme-challenge Unable to clean up challenge directory /our/sites/adchorus/docroots/test/.well-known/acme-challenge IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/34.205.128.170/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/34.205.128.170/privkey.pem Your cert will expire on 2018-01-21. To obtain a new or tweaked version of this certificate in the future, simply run certbot-auto again. To non-interactively renew *all* of your certificates, run "certbot-auto renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.
"Unable to clean up challenge directory" is because `test` and `live` are symlinks to `dev`, harmless. Symlinks to certs and make logs readable without sudo:
[vlad in /our/bin]$ sudo chmod g+rx /var/log/letsencrypt [vlad in /our/bin]$ ln -s /var/log/letsencrypt /our/logs [vlad in /our/bin]$ sudo chmod g+rx `find /etc/letsencrypt -type d` -R find: `/etc/letsencrypt/keys': Permission denied find: `/etc/letsencrypt/live': Permission denied find: `/etc/letsencrypt/accounts': Permission denied find: `/etc/letsencrypt/archive': Permission denied [vlad in /our/bin]$ sudo chmod g+rx `find /etc/letsencrypt -type d` -R [vlad in /our/bin]$ cd /our/ssl-certs [vlad in /our/ssl-certs]$ ln -s /etc/letsencrypt/live/34.205.128.170/*.pem . [vlad in /our/ssl-certs]$ find /our/ssl-certs /our/ssl-certs /our/ssl-certs/cert.pem /our/ssl-certs/chain.pem /our/ssl-certs/privkey.pem /our/ssl-certs/fullchain.pem
Add HTTPS config to httpd.
[vlad in /our/bin]$ cd /our/conf [vlad in /our/conf]$ mv adchorus-httpd.conf adchorus-httpd-before-ssl.conf [vlad in /our/conf]$ nano adchorus-httpd.conf [vlad in /our/conf]$ cat adchorus-httpd.conf # Redirect HTTP traffic to HTTPS <VirtualHost *:80> ServerName dev.adchorus.com RedirectMatch permanent "(.*)" "https://dev.adchorus.com$1" </VirtualHost> <VirtualHost *:80> ServerName test.adchorus.com RedirectMatch permanent "(.*)" "https://test.adchorus.com$1" </VirtualHost> <VirtualHost *:80> ServerName www.adchorus.com ServerAlias adchorus.com live.adchorus.com RedirectMatch permanent "(.*)" "https://www.adchorus.com$1" </VirtualHost> # site-specific config <VirtualHost *:443> ServerName dev.adchorus.com SetEnv SERVER_ROLE dev ServerAdmin webmaster@adchorus.com DocumentRoot /our/sites/adchorus/docroots/dev ErrorLog /our/logs/adchorus/dev/error_log-dev CustomLog /our/logs/adchorus/dev/access_log-dev common SSLEngine on SSLCertificateFile /our/ssl-certs/fullchain.pem SSLCertificateKeyFile /our/ssl-certs/privkey.pem SSLCertificateChainFile /our/ssl-certs/chain.pem </VirtualHost> <VirtualHost *:443> ServerName test.adchorus.com SetEnv SERVER_ROLE test ServerAdmin webmaster@adchorus.com DocumentRoot /our/sites/adchorus/docroots/test ErrorLog /our/logs/adchorus/test/error_log-test CustomLog /our/logs/adchorus/test/access_log-test common SSLEngine on SSLCertificateFile /our/ssl-certs/fullchain.pem SSLCertificateKeyFile /our/ssl-certs/privkey.pem SSLCertificateChainFile /our/ssl-certs/chain.pem </VirtualHost> <VirtualHost *:443> ServerName www.adchorus.com SetEnv SERVER_ROLE live ServerAdmin webmaster@adchorus.com DocumentRoot /our/sites/adchorus/docroots/live ErrorLog /our/logs/adchorus/live/error_log-live CustomLog /our/logs/adchorus/live/access_log-live common SSLEngine on SSLCertificateFile /our/ssl-certs/fullchain.pem SSLCertificateKeyFile /our/ssl-certs/privkey.pem SSLCertificateChainFile /our/ssl-certs/chain.pem </VirtualHost> # Redirect aliases to canonical domain <VirtualHost *:443> ServerName adchorus.com ServerAlias live.adchorus.com RedirectMatch permanent "(.*)" "https://www.adchorus.com$1" SSLEngine on SSLCertificateFile /our/ssl-certs/fullchain.pem SSLCertificateKeyFile /our/ssl-certs/privkey.pem SSLCertificateChainFile /our/ssl-certs/chain.pem </VirtualHost> [vlad in /our/conf]$ sudo apachectl configtest Syntax OK [vlad in /our/conf]$ sudo apachectl restart
Create the various certbot files and install a cert:
[vlad in /our/bin]$ cp our-first-certbot-staging-run test-certbot-staging-renewal [vlad in /our/bin]$ vim test-certbot-staging-renewal [vlad in /our/bin]$ cat test-certbot-staging-renewal certbot-auto certonly --staging --debug --cert-name 34.205.128.170 --webroot -w /our/sites/adchorus/docroots/live -d www.adchorus.com,adchorus.com,live.adchorus.com -w /our/sites/adchorus/docroots/dev -d dev.adchorus.com -w /our/sites/adchorus/docroots/test -d test.adchorus.com -w /our/sites/adchorus/docroots/live [vlad in /our/bin]$ test-certbot-staging-renewal Requesting to rerun /our/bin/certbot-auto with root privileges... Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Cert not yet due for renewal You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry. (ref: /etc/letsencrypt/renewal/34.205.128.170.conf) What would you like to do? ------------------------------------------------------------------------------- 1: Keep the existing certificate for now 2: Renew & replace the cert (limit ~5 per 7 days) ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2 Renewing an existing certificate Performing the following challenges: http-01 challenge for www.adchorus.com http-01 challenge for adchorus.com http-01 challenge for live.adchorus.com http-01 challenge for dev.adchorus.com http-01 challenge for test.adchorus.com Using the webroot path /our/sites/adchorus/docroots/live for all unmatched domains. Waiting for verification... Cleaning up challenges Unable to clean up challenge directory /our/sites/adchorus/docroots/live/.well-known/acme-challenge Unable to clean up challenge directory /our/sites/adchorus/docroots/test/.well-known/acme-challenge IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/34.205.128.170/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/34.205.128.170/privkey.pem Your cert will expire on 2018-01-21. To obtain a new or tweaked version of this certificate in the future, simply run certbot-auto again. To non-interactively renew *all* of your certificates, run "certbot-auto renew" [vlad in /our/bin]$ cp test-certbot-staging-renewal test-certbot-staging-renewal-non-interactive [vlad in /our/bin]$ vim test-certbot-staging-renewal-non-interactive [vlad in /our/bin]$ cat test-certbot-staging-renewal-non-interactive certbot-auto certonly --staging --debug --cert-name 34.205.128.170 --webroot -w /our/sites/adchorus/docroots/live -d www.adchorus.com,adchorus.com,live.adchorus.com -w /our/sites/adchorus/docroots/dev -d dev.adchorus.com -w /our/sites/adchorus/docroots/test -d test.adchorus.com -w /our/sites/adchorus/docroots/live --noninteractive [vlad in /our/bin]$ test-certbot-staging-renewal-non-interactive Requesting to rerun /our/bin/certbot-auto with root privileges... Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Cert not yet due for renewal Keeping the existing certificate ------------------------------------------------------------------------------- Certificate not yet due for renewal; no action taken. ------------------------------------------------------------------------------- [vlad in /our/bin]$ cp our-first-certbot-staging-run our-first-real-certbot-run [vlad in /our/bin]$ vim our-first-real-certbot-run [vlad in /our/bin]$ cat our-first-real-certbot-run certbot-auto certonly --debug --agree-tos --no-eff-email --email webmaster@adchorus.com --cert-name 34.205.128.170 --webroot -w /our/sites/adchorus/docroots/live -d www.adchorus.com,adchorus.com,live.adchorus.com -w /our/sites/adchorus/docroots/dev -d dev.adchorus.com -w /our/sites/adchorus/docroots/test -d test.adchorus.com -w /our/sites/adchorus/docroots/live [vlad in /our/bin]$ sudo rm -rf /etc/letsencrypt [vlad in /our/bin]$ our-first-real-certbot-run Requesting to rerun /our/bin/certbot-auto with root privileges... Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Obtaining a new certificate Performing the following challenges: http-01 challenge for www.adchorus.com http-01 challenge for adchorus.com http-01 challenge for live.adchorus.com http-01 challenge for dev.adchorus.com http-01 challenge for test.adchorus.com Using the webroot path /our/sites/adchorus/docroots/live for all unmatched domains. Waiting for verification... Cleaning up challenges Unable to clean up challenge directory /our/sites/adchorus/docroots/live/.well-known/acme-challenge Unable to clean up challenge directory /our/sites/adchorus/docroots/test/.well-known/acme-challenge IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/34.205.128.170/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/34.205.128.170/privkey.pem Your cert will expire on 2018-01-21. To obtain a new or tweaked version of this certificate in the future, simply run certbot-auto again. To non-interactively renew *all* of your certificates, run "certbot-auto renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le [vlad in /our/bin]$ sudo chmod g+rx `find /etc/letsencrypt -type d` -R find: `/etc/letsencrypt/keys': Permission denied find: `/etc/letsencrypt/live': Permission denied find: `/etc/letsencrypt/accounts': Permission denied find: `/etc/letsencrypt/archive': Permission denied [vlad in /our/bin]$ sudo chmod g+rx `find /etc/letsencrypt -type d` -R [vlad in /our/bin]$ cp test-certbot-staging-renewal-non-interactive certbot-renew-noninteractive [vlad in /our/bin]$ vim certbot-renew-noninteractive [vlad in /our/bin]$ cat certbot-renew-noninteractive certbot-auto certonly --debug --cert-name 34.205.128.170 --webroot -w /our/sites/adchorus/docroots/live -d www.adchorus.com,adchorus.com,live.adchorus.com -w /our/sites/adchorus/docroots/dev -d dev.adchorus.com -w /our/sites/adchorus/docroots/test -d test.adchorus.com -w /our/sites/adchorus/docroots/live --noninteractive [vlad in /our/bin]$ certbot-renew-noninteractive Requesting to rerun /our/bin/certbot-auto with root privileges... Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Cert not yet due for renewal Keeping the existing certificate ------------------------------------------------------------------------------- Certificate not yet due for renewal; no action taken. ------------------------------------------------------------------------------- [vlad in /our/bin]$ cp certbot-renew-noninteractive certbot-renew-quietly [vlad in /our/bin]$ vim certbot-renew-quietly [vlad in /our/bin]$ cat certbot-renew-quietly certbot-auto certonly --debug --cert-name 34.205.128.170 --webroot -w /our/sites/adchorus/docroots/live -d www.adchorus.com,adchorus.com,live.adchorus.com -w /our/sites/adchorus/docroots/dev -d dev.adchorus.com -w /our/sites/adchorus/docroots/test -d test.adchorus.com -w /our/sites/adchorus/docroots/live --quiet [vlad in /our/bin]$ certbot-renew-quietly Requesting to rerun /our/bin/certbot-auto with root privileges... [vlad in /our/bin]$ sudo apachectl configtest Syntax OK [vlad in /our/bin]$ sudo apachectl restart
Add our cert renewal to daily cron.
[vlad in ~]$ crontab -e no crontab for vlad - using an empty one crontab: installing new crontab [vlad in ~]$ crontab -l # renew our letsencrypt cert if it is close to expiry at 4:37 AM on Sundays 37 4 * * 7 /our/bin/certbot-renew-quietly
Install PHP.
[vlad in ~]$ sudo yum install php71 ... Installed: php71.x86_64 0:7.1.7-1.27.amzn1 Dependency Installed: php71-cli.x86_64 0:7.1.7-1.27.amzn1 php71-common.x86_64 0:7.1.7-1.27.amzn1 php71-json.x86_64 0:7.1.7-1.27.amzn1 php71-process.x86_64 0:7.1.7-1.27.amzn1 php71-xml.x86_64 0:7.1.7-1.27.amzn1 Complete! [vlad in ~]$ php -v PHP 7.1.7 (cli) (built: Oct 11 2017 18:23:26) ( NTS ) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies [vlad in ~]$ echo '<?php echo "Hello, World from PHP.";' > /our/sites/adchorus/docroots/dev/index.php [vlad in ~]$ rm /our/sites/adchorus/docroots/dev/index.html [vlad in ~]$ sudo apachectl restart
Install git.
[vlad in /our/git-repos]$ sudo yum install git ... Installed: git.x86_64 0:2.13.6-1.55.amzn1 Dependency Installed: perl-Error.noarch 1:0.17020-2.9.amzn1 perl-Git.noarch 0:2.13.6-1.55.amzn1 perl-TermReadKey.x86_64 0:2.30-20.9.amzn1 Complete!
Next bring in the git repo. Although the domain so far has been adchorus.com, this is only because newtypetango.com is already set up on another server, and I didn't want to change its DNS until this new server was up. So we'll actually be setting up "/our/sites/newtypetango/docroots/dev". This involves manually copying the git repo from the old server to the new server. In the future we can look into sharing git repos across different machines in our VPC, but in this case the two servers are in different VPCs. As it happens, there is uncommitted code in the working directory for the existing newtypetango.com site, so first we're creating a separate branch called `transition` and committing the code in the working directory as `incomplete`. Once we've moved the repo to the new server, we can switch back to master and bring in the code from `transition` into the current working directory.
[vlad in /our/git-repos]$ unzip newtypetango.zip Archive: newtypetango.zip creating: newtypetango.git/ [vlad in /our/git-repos]$ mkdir -p /our/sites/newtypetango/docroots/dev [vlad in /our/git-repos]$ cd /our/sites/newtypetango/docroots/dev [vlad in /our/sites/newtypetango/docroots/dev]$ git clone /our/git-repos/newtypetango.git . Cloning into '.'... done. [vlad in /our/sites/newtypetango/docroots/dev]$ git checkout transition Branch transition set up to track remote branch transition from origin. Switched to a new branch 'transition' [vlad in /our/sites/newtypetango/docroots/dev]$ cd /our/sites/adchorus/docroots [vlad in /our/sites/adchorus/docroots]$ rm -rf dev [vlad in /our/sites/adchorus/docroots]$ ln -s /our/sites/newtypetango/docroots/dev [vlad in /our/sites/adchorus/docroots]$ sudo yum install php7-pear ... Installed: php7-pear.noarch 1:1.10.1-1.24.amzn1 Complete! [vlad in /our/sites/adchorus/docroots]$ sudo pear7 install mail Did not download optional dependencies: pear/Net_SMTP, use --alldeps to download automatically pear/Mail can optionally use package "pear/Net_SMTP" (version >= 1.4.1) downloading Mail-1.4.1.tgz ... Starting to download Mail-1.4.1.tgz (21,756 bytes) ........done: 21,756 bytes install ok: channel://pear.php.net/Mail-1.4.1
Install Swift mailer.
[vlad in /our/sites/adchorus/docroots]$ sudo pear7 channel-discover pear.swiftmailer.org Adding Channel "pear.swiftmailer.org" succeeded Discovery of channel "pear.swiftmailer.org" succeeded [vlad in /our/sites/adchorus/docroots]$ sudo pear7 remote-list -c swift Channel swift Available packages: ================================= Package Version Swift 5.1.0 [vlad in /our/sites/adchorus/docroots]$ sudo pear7 info swift/swift About pear.swiftmailer.org/Swift-5.1.0 ====================================== Release Type PEAR-style PHP-based Package Name Swift Channel pear.swiftmailer.org Summary Free Feature-rich PHP Mailer. Description Swift Mailer integrates into any web app written in PHP 5, offering a flexible and elegant object-oriented approach to sending emails with a multitude of features. Maintainers Fabien Potencier <fabien.potencier@symfony-project.org> (lead) Chris Corbyn <> (lead, inactive) Release Date 2014-03-18 09:05:25 Release Version 5.1.0 (stable) API Version 5.1.0 (stable) License MIT (http://opensource.org/licenses/mit-license.php) Release Notes - Required Dependencies PHP version 5.2.4 PEAR installer version 1.4.0 or newer package.xml version 2.0 Last Modified 2017-10-24 20:02 Previous Installed - None - Version [vlad in /our/sites/adchorus/docroots]$ sudo pear7 install swift/swift downloading Swift-5.1.0.tgz ... Starting to download Swift-5.1.0.tgz (113,740 bytes) .........................done: 113,740 bytes install ok: channel://pear.swiftmailer.org/Swift-5.1.0
[vlad in /our/sites/adchorus/docroots]$ sudo yum info php71-mysqlnd Loaded plugins: priorities, update-motd, upgrade-helper Available Packages Name : php71-mysqlnd Arch : x86_64 Version : 7.1.7 Release : 1.27.amzn1 Size : 335 k Repo : amzn-updates/latest Summary : A module for PHP applications that use MySQL databases URL : http://www.php.net/ License : PHP Description : The php-mysqlnd package contains a dynamic shared object that will add : MySQL database support to PHP. MySQL is an object-relational database : management system. PHP is an HTML-embeddable scripting language. If : you need MySQL support for PHP applications, you will need to install : this package and the php package. : : This package use the MySQL Native Driver [vlad in /our/sites/adchorus/docroots]$ sudo yum install php71-mysqlnd Installed: php71-mysqlnd.x86_64 0:7.1.7-1.27.amzn1 Dependency Installed: php71-pdo.x86_64 0:7.1.7-1.27.amzn1 Complete!
Create the MySQL database and give access to the appropriate user.
[vlad in /our/sites/adchorus/docroots]$ mysql -uroot Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 Server version: 5.7.18 MySQL Community Server (GPL) Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> create database newtypetango; Query OK, 1 row affected (0.01 sec) mysql> create user newtypetango@127.0.0.1 identified by 'mypassword'; Query OK, 0 rows affected (0.00 sec) mysql> grant all on newtypetango.* to newtypetango@127.0.0.1; Query OK, 0 rows affected (0.00 sec)
GD image library
[vlad in /our/sites/adchorus/docroots/dev]$ sudo yum install php71-gd Installed: php71-gd.x86_64 0:7.1.7-1.27.amzn1 Dependency Installed: libXpm.x86_64 0:3.5.10-2.9.amzn1 libwebp.x86_64 0:0.3.0-3.5.amzn1 Complete! [vlad in /our/sites/adchorus/docroots/dev]$ mkdir images/profile-photos [vlad in /our/sites/adchorus/docroots/dev]$ sudo chgrp apache images/profile-photos [vlad in /our/sites/adchorus/docroots/dev]$ sudo chmod g+w images/profile-photos
Configure git:
[vlad in /our/sites/newtypetango/docroots/dev]$ git config --global user.email "vladkornea@gmail.com" [vlad in /our/sites/newtypetango/docroots/dev]$ git config --global user.name "Vladimir Kornea"
Point test and live to empty directory. This matters because live doesn't require basic HTTP auth to view pages (and whether test should is a judgment call and might change). Those symlinks should be made to point at the correct places once the correct places have been created. Meanwhile we can just drop a list of links to our various web sites into `empty`.
[vlad in /our/sites/adchorus/docroots]$ mkdir empty [vlad in /our/sites/adchorus/docroots]$ ln -snf empty live [vlad in /our/sites/adchorus/docroots]$ ln -snf empty test [vlad in /our/sites/adchorus/docroots]$ cd empty [vlad in /our/sites/adchorus/docroots/empty]$ nano index.html [vlad in /our/sites/adchorus/docroots/empty]$ cat index.html <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>Under Construction</title> <meta name="author" content="Vladimir Kornea"> </head> <body> <ul> <li><a href="https://www.kornea.com">www.kornea.com</a></li> <li><a href="https://dosadi-list.org">dosadi-list.org</a></li> <li><a href="http://www.typetango.com">www.typetango.com</a></li> <li><a href="http://www.decigrade.com">www.decigrade.com</a></li> <li><a href="http://www.eq-inventory.com">www.eq-inventory.com</a></li> <li><a href="https://www.adchorus.com">www.adchorus.com</a></li> </ul> </body> </html>
[vlad in /our/sites/adchorus/docroots/dev]$ pear7 remote-info Mail_Mime Package details: ================ Latest 1.10.1 Installed - no - Package Mail_Mime License BSD Style Category Mail Summary Mail_Mime provides classes to create MIME messages. Description Mail_Mime provides classes to deal with the creation and manipulation of MIME messages. It allows people to create e-mail messages consisting of: * Text Parts * HTML Parts * Inline HTML Images * Attachments * Attached messages It supports big messages, base64 and quoted-printable encodings and non-ASCII characters in filenames, subjects, recipients, etc. encoded using RFC2047 and/or RFC2231. [vlad in /our/sites/adchorus/docroots/dev]$ sudo pear7 install Mail_Mime downloading Mail_Mime-1.10.1.tgz ... Starting to download Mail_Mime-1.10.1.tgz (36,336 bytes) ..........done: 36,336 bytes install ok: channel://pear.php.net/Mail_Mime-1.10.1
Add apache to sendmail trusted users to get rid of "X-Authentication-Warning" email header1.
[vlad in ~]$ sudo nano /etc/mail/trusted-users [vlad in ~]$ cat /etc/mail/trusted-users # trusted-users - users that can send mail as others without a warning # apache, mailman, majordomo, uucp, are good candidates apache
Set up email forwarding.
[vlad in ~]$ sudo su [root@ip-10-0-0-127 vlad]# echo 'vlad' > ~/.forward [root@ip-10-0-0-127 vlad]# exit exit [vlad in ~]$ echo 'vladkornea@gmail.com' > ~/.forward [vlad in ~]$ sudo su ec2-user [ec2-user@ip-10-0-0-127 vlad]$ echo 'vlad' > ~/.forward [ec2-user@ip-10-0-0-127 vlad]$ exit exit
Set cron time zone.
[vlad in ~]$ crontab -l CRON_TZ=America/New_York
Copyright Vladimir Kornea