X Marks the Spot

random commentary on life, the universe, and anything

July 31, 2018
by puhfu
0 comments

Adding a subdomain to a LetsEncrypt certificate

So I needed to add a subdomain to an existing Let’s Encrypt certificate and you know, finding instructions was far harder than it was to actually do it.

Sources:
Certbot User Guide
How can I add more subdomains to my SSL Certificate?

I tried this:

$ cd /etc
$ sudo ./certbot-auto
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: domain.com
2: sub2.domain.com
3: sub1.domain.com
4: domain2.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 2
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for sub2.domain.com
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. sub2.domain.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://sub2.domain.com/.well-known/acme-challenge/ 
"<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p"


Which sent me down a hole learning about ACME challenges and where I created a new but separate cert for sub2.domain.com but did not add it to the original cert which is the goal.

$ sudo ./certbot-auto certonly --webroot -w /var/www/html/sub2 -d sub2.domain.com
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 sub2.domain.com
Using the webroot path /var/www/html/sub2 for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/sub2.domain.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/sub2.domain.com/privkey.pem
   Your cert will expire on 2018-10-29. 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"


Finally, stumbled on a Let’s Encrypt community forum page that allowed me to put it together.

$ sudo ./certbot-auto certonly --webroot -w /var/www/html --cert-name domain.com -d domain.com -d sub1.domain.com -d domain2.org -d sub2.domain.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
You are updating certificate fuweb.com to include new domain(s):
+ sub2.domain.com

You are also removing previously included domain(s):
(None)

Did you intend to make this change?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(U)pdate cert/(C)ancel: u
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for domain.com
http-01 challenge for domain2.org
http-01 challenge for sub2.domain.com
http-01 challenge for sub1.domain.com
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/domain.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/domain.com/privkey.pem
   Your cert will expire on 2018-10-29. 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"

The money command:

$ sudo ./certbot-auto certonly --webroot -w /var/www/html --cert-name domain.com -d domain.com -d sub1.domain.com -d domain2.org -d sub2.domain.com


Breaking it down:
certonly grabs the certificate only
--webroot uses the webroot plugin for http-01 authentication
-w (the same as --webroot-path) specifies the top-level directory containing files served by webserver
--cert-name is the domain name of the cert to use (if a single cert for multiple domains, use the primary domain)
-d specifies each of the domains you want to be included in the --cert-name cert

And added a renewal to the crontab

$ sudo crontab -e


Then add:

30 2 * * * /usr/bin/certbot renew >> /var/log/le-renew.log

July 3, 2018
by puhfu
0 comments

WordPress, pretty permalinks, and 404s (part 2)

As I noted back in September 2017, I switched from Rackspace to Amazon Lightsail for my personal website as well as for a learning management system I run for Harbor-UCLA Pediatrics.

I’m using apache virtual hosts run both in separate subdirectories. One problem I had, but didn’t have time to fix (and then forgot about), was that turning on pretty permalinks in WordPress broke the learning management system. I knew two things: 1) it was probably a .htaccess issue and 2) my VirtualHost config was probably making a mess of things.

So why now? I have this lovely short domain (fu.fyi) doing nothing, I thought I’d use it as a custom URL shortener through bit.ly. I can set a default 404 for bad links in bit.ly so I thought I’d just use the themed WP one. But then I realized that the 404 being shown was the default apache 404 page. Which meant that I had to figure out why missing pages were not being passed to the WP stack. Which meant fixing .htaccess and httpd.conf.

Sources:
Giving WordPress Its Own Directory
This is the .htaccess code in WordPress. Can someone explain how it works?
A really lovely online .htaccess checker: https://htaccess.madewithlove.be/

The WP default .htaccess is pretty straightforward.

# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# END WordPress

What they don’t tell you is that you break things when you duplicate RewriteRules in both VirtualHost configs and .htaccess. So cleaning httpd.conf up:

# lms hosting
<VirtualHost *:80>
   ServerName lms.domain2.com
# redirect all HTTP traffic to HTTPS
   RewriteEngine on
   RewriteCond %{SERVER_NAME} =lms.domain2.com
   RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<VirtualHost *:443>
   ServerName lms.domain2.com
   DocumentRoot "/var/www/html/lms"
   <Directory "/var/www/html/lms">
      Options -Indexes +FollowSymLinks
      Require all granted
   </Directory>
   Include /etc/letsencrypt/options-ssl-apache.conf
   SSLCertificateFile /etc/letsencrypt/live/domain1.com/fullchain.pem
   SSLCertificateKeyFile /etc/letsencrypt/live/domain1.com/privkey.pem
</VirtualHost>

And adding a catch-all to .htaccess before the WP default:


# Turn on rewrites
RewriteEngine On

# Ruleset 1 - rewrite URI to wordpress subdir
# apply to URLs in this domain
RewriteCond %{HTTP_HOST} ^(www.)?fuweb.com$
# Don't apply (!) to URI with this subdirectory in the path
RewriteCond %{REQUEST_URI} !^/fuweb/
# Don't apply (!) to URLs that go to existing files (-f) or folders (-d)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Take (everything), call it $1, and remap URI to include /subdir
# ^ = beginning anchor
# (.*) = . [single character] * [wildcard]
# $ = end anchor
RewriteRule ^(.*)$ /fuweb/$1

# Ruleset 2 - rewrite any URI paths to wordpress index.php
# apply to URLs in this domain
RewriteCond %{HTTP_HOST} ^(www.)?fuweb.com$
# if the URI has a / then send to index.php
RewriteRule ^(/)?$ fuweb/index.php [L] 


And the best thing? I actually understand .htaccess better now.

Oh yeah. And it works.

October 21, 2017
by puhfu
0 comments

Adding a self-signed SSL certificate for UniFi on Mac OS X 10.12

Got tired of seeing the UniFi controller java service running https but not trusted on localhost. And almost have a solution. Found a solution, but it wasn’t easy.

Sources:
CertSimple: Never see localhost HTTPS warnings again
Ubiquiti Network Community: Installing an SSL Certificate

Follow the CertSimple instructions to use Mac OS X Keychain Access to generate self-signed certificates for localhost. In Step 3, make sure to export both the localhost certificate (as .pem) and the localhost private key (select .p12 from drop down and then convert as per the openssl command in Step 3 OR export as .pem) from within Keychain Access.

Keychain Access

Instead of service unifi stop as in the Ubiquiti Network Community instructions (which are for a linux system), for Mac OS X, simply quit the UniFi app in order to stop the service. Alternatively, from the command line:

$ java -jar /Applications/UniFi.app/Contents/Java/ace.jar stop

Here are the commands that I used based on the Community page. I put the files on the Desktop for easy finding (from the command line natch).

$ sudo openssl pkcs12 -export -passout pass:aircontrolenterprise \
 -in ~/Desktop/localhost-cert.pem -inkey ~/Desktop/localhost-key.pem \
 -out ~/Desktop/localhost -name unifi \
 -CAfile ~/Desktop/localhost_CAcert.pem -caname root

$ sudo keytool -delete -alias unifi \
 -keystore ~/Library/Application\ Support/UniFi/data/keystore \
 -deststorepass aircontrolenterprise

$ sudo keytool -trustcacerts -importkeystore \
 -deststorepass aircontrolenterprise -destkeypass aircontrolenterprise \
 -destkeystore ~/Library/Application\ Support/UniFi/data/keystore \
 -srckeystore ~/Desktop/localhost -srcstoretype PKCS12 \
 -srcstorepass aircontrolenterprise -alias unifi

Unfortunately, I’m running into an error where the certificate is not getting imported into the keystore.

$ sudo java -jar /Applications/UniFi.app/Contents/Java/ace.jar \
 import_cert ~/Desktop/localhost-cert.pem ~/Desktop/localhost-CAcert.pem \
 ~/Desktop/localhost
Unable to import the certificate into keystore 

Hurrah! Found the answer.

Source:
UBNT Support Page: UniFi – SSL certificate error upon opening controller page

Troubleshooting

If the error "Unable to import certificate into keystore" appears when importing the signed certificate & intermediate certs, try the following steps:

1. Edit the certificate file and remove any blank spaces after each line of the cert.

And that did it.

$ sudo java -jar /Applications/UniFi.app/Contents/Java/ace.jar import_cert ~/Desktop/localhost-cert.pem ~/Desktop/localhost-CAcert.pem ~/Desktop/localhost
parse localhost-CAcert.pem (PEM, 1 certs): CN=localhost Certification Authority
parse localhost, 0 certs found
parse localhost-cert.pem (PEM, 1 certs): CN=localhost
Importing signed cert[localhost]
Certificates successfuly imported. Please restart the UniFi Controller.

But still doesn’t work completely because it’s self-signed. I guess if I want that green lock then I’ll have to go get a real cert.

And for reference:

$ java -jar /Applications/UniFi.app/Contents/Java/ace.jar
Usage: java -jar lib/ace.jar  [...]
    start  : start the UniFi controller
    stop   : stop the UniFi controller
    info   : display some information
    installsvc/startsvc/uninstallsvc/stopsvc : install/start/stop as a Windows service
    new_cert      : create new certificate (with csr)
    import_cert  [...] : import the signed certificate and ca cert

September 4, 2017
by puhfu
0 comments

Amazon Lightsail, Let’s Encrypt, and SSL

I’m really happy having migrated to Amazon Lightsail so far. The documentation is good and it has a big enough user base so that there are plenty of others who have had the same issues as I am encountering. Sometimes though, it’s not quite the same.

Documentation:
Tutorial: Configure Apache Web Server on Amazon Linux to Use SSL/TLS
Appendix: Let’s Encrypt with Certbot on Amazon Linux

Able to follow the first steps:

$ sudo yum-config-manager --enable epel
$ wget https://dl.eff.org/certbot-auto
$ chmod a+x certbot-auto
$ sudo ./certbot-auto --debug

As a sidenote, certbot-auto is located in /etc.

Anyway, after running through the certbot-auto steps, it fails with the following message:

Incorrect validation certificate for tls-sni-01 challenge. Requested 6e9f679b4c7458baae91e229b3352d33.6e3c653d675dfdf58604b4b049566594.acme.invalid from xxx.xxx.xxx.xxx:443. Received 1 certificate(s), first certificate had names \"ip-yyy-yyy-yyy-yyy, ip-yyy-yyy-yyy-yyy.us-west-2.compute.internal, localhost, localhost.localdomain\"

The certbot documentation for Apache on CentOS/RHEL 7 shows a certificate only process, instead of the automated installation of the certificate and key into the right locations.

The certificates are located in /etc/pki/tls/certs/
The private keys are located in /etc/pki/tls/private/

$ sudo certbot-auto --apache certonly

Running Certbot generates the certificate and key and puts them into /etc/letsencrypt/live/domain.com/

From there, it is just a quick ln -s to the right directories and boom. SSL works.

September 4, 2017
by puhfu
0 comments

Goodbye Rackspace; Hello Amazon Lightsail

Some of the documentation I used:

1. Getting ssh to work from Mac OS X terminal. Lightsail uses ssh keys for access. They also have a web-based ssh session which is pretty good but it has a short time-out. Plus, I like my terminal.

How do I set or change the root password for my EC2 Linux instance?
Amazon EC2 Key Pairs – Retrieving the Public Key
Set up SSH in Amazon Lightsail
Log in with an SSH private key on Linux and Mac
Tutorial: Installing a LAMP Web Server on Amazon Linux

2. Now I need vsftpd

$ sudo yum install vsftpd 

How to Setup FTP (SFTP) on an AWS EC2 Instance

3. Wait, no iptables?

That’s right. With LightSail, it’s in the Networking tab on the Lightsail dashboard and you use that to open up ports, in this case, ftp 20-21, 1024-1048

4. SSL!
Tutorial: Configure Apache Web Server on Amazon Linux to Use SSL/TLS
Appendix: Let’s Encrypt with Certbot on Amazon Linux

Yikes. I can’t do SSL until the site is migrated over. Oh well. Let’s do that.

5. Migrate WordPress files, export/import the database. Needed to change wp_options siteurl and home from http://domain.com to http://x.y.z.a After using the IP address in the URL, I can get pages to load. Whoo hoo!

6. Migrated the DNS

7. Hm. Why is /html not directing to subdirectory/ and why and why am I getting 500 errors? Well, I can get WP to work now but by manually adding the subdirectory in the URL which means that mod_rewrite isn’t working.

Enable mod_rewrite on Apache EC2 Linux Server

Hm. check php.ini. Well, mod_rewrite is installed. So what’s up then?

/var/log/httpd/error_log is showing something funky in .htaccess. Weird control characters? Oh man, I must have introduced them in a copy/paste. Once retyped, it works.

Except non-default Permalinks. Argh.

September 3, 2017
by puhfu
0 comments

Open source projects have the craziest names – Wazuh

Decided I was unhappy with the unsupported, very old school visualization OSSEC-WUI. It’s been unsupported for a while. There must be something new out there.

Lo an behold. Wazuh open source host and endpoint security

Great documentation:
Migrating OSSEC manager installed from packages
Install Wazuh server with RPM packages

In general, the step-by-step instructions are clear and explicit. I had do some steps manually though.

1. Created the wazuh.repo repository file /etc/yum.repos.d/wazuh.repo

[wazuh_repo]
gpgcheck=1
gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH
enabled=1
name=CentOS-$releasever - Wazuh
baseurl=https://packages.wazuh.com/yum/el/$releasever/$basearch
protect=1

2. For NodeJS install, had to add ‘sudo’ in order for bash to run correctly

$ curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash -

3. And I need Python 2.7. Python 2.6 is installed already for yum, but Wazuh wants 2.8.

$ yum install -y centos-release-scl
$ yum install -y python27

4. Also had to create the elastic.repo repository file /etc/yum.repos.d/elastic.repo

[elastic-5.x]
name=Elastic repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

But uh oh. I can’t run elasticsearch. Not enough memory. Hm.

So far, I have installed:

wazuh-manager
wazuh-api
filebeat
elastisearch

Hm. Maybe it’s time to admit that I’m overpaying for hosting with Rackspace – well, overpaying for what I need.

Time for another rabbit hole.