Let’s Encrypt on EC2

You can get free and valid SSL certificate from Let’s Encrypt. In this article, I will go through the steps to install Let’s Encrypt SSL certificate on Apache running on Amazon Linux.

Things you should know about Let’s Encrypt:
1. Let’s Encrypt’s certificates last for 90 days old.
2. Let’s Encrypt does not offer wild-card certificates.

Requirements:
1. An email address.
2. The domain pointing to a directory on the server, that’s accessible on the Internet. Let’s Encrypt servers will access a file on http://yourwebsite.com/some_secret_file_name to validate that you own the domain.

Installation steps:

1. Install some requirements for the following steps.

yum install python27-devel git

2. Clone the letsencrypt repository and run the installer.

git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
/opt/letsencrypt/letsencrypt-auto –debug

3. Create a config file that will be used for new certificates and renewals. It contains the private key size and your email address.

echo “rsa-key-size = 4096” >> /etc/letsencrypt/config.ini
echo “email = email@example.com” >> /etc/letsencrypt/config.ini

4. Request a certificate for your domain and it’s www subdomain. You must also specify the root directory of the domain.

/opt/letsencrypt/letsencrypt-auto certonly –webroot -w /var/www/yourdomainroot -d yourdomain.com -d http://www.yourdomain.com –config /etc/letsencrypt/config.ini –agree-tos

5. Remove the directory that was used for validation. This step is optional.

rmdir /var/www/yourdomainroot/.well-known

6. The certificates are located at /etc/letsencrypt/live/ and the last thing is to update your webserver’s configuration. For apache it will look like this:

Listen 443
<VirtualHost *:443>
ServerName yourdomain.com
DocumentRoot “/var/www/yourdomainroot”
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/yourdomain.com/chain.pem
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite “EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS”
</VirtualHost>

7. Be sure to add the renew command in a crontab. Refresing your webserver command should also be here.

/opt/letsencrypt/letsencrypt-auto renew –config /etc/letsencrypt/config.ini –agree-tos && apachectl graceful

 

This article is taken and modified from:
https://ivopetkov.com/b/let-s-encrypt-on-ec2/

Advertisements

Redirecting Uppercase to Lowercase in Apache

This should go at the very top of your .htaccess file. At least it should go above ANY other RewriteRules. That is because this uses a loop, until there are no more uppercase characters to convert, it will keep starting at the first HASCAPS:TRUE RewriteRule. Oh, and this is actually really quick and isn’t gonna slow down anything.

RewriteEngine On
RewriteBase /

# If there are caps, set HASCAPS to true and skip next rule
RewriteRule [A-Z] – [E=HASCAPS:TRUE,S=1]

# Skip this entire section if no uppercase letters in requested URL
RewriteRule ![A-Z] – [S=28]

# Replace single occurance of CAP with cap, then process next Rule.
RewriteRule ^([^A]*)A(.*)$ $1a$2
RewriteRule ^([^B]*)B(.*)$ $1b$2
RewriteRule ^([^C]*)C(.*)$ $1c$2
RewriteRule ^([^D]*)D(.*)$ $1d$2
RewriteRule ^([^E]*)E(.*)$ $1e$2
RewriteRule ^([^F]*)F(.*)$ $1f$2
RewriteRule ^([^G]*)G(.*)$ $1g$2
RewriteRule ^([^H]*)H(.*)$ $1h$2
RewriteRule ^([^I]*)I(.*)$ $1i$2
RewriteRule ^([^J]*)J(.*)$ $1j$2
RewriteRule ^([^K]*)K(.*)$ $1k$2
RewriteRule ^([^L]*)L(.*)$ $1l$2
RewriteRule ^([^M]*)M(.*)$ $1m$2
RewriteRule ^([^N]*)N(.*)$ $1n$2
RewriteRule ^([^O]*)O(.*)$ $1o$2
RewriteRule ^([^P]*)P(.*)$ $1p$2
RewriteRule ^([^Q]*)Q(.*)$ $1q$2
RewriteRule ^([^R]*)R(.*)$ $1r$2
RewriteRule ^([^S]*)S(.*)$ $1s$2
RewriteRule ^([^T]*)T(.*)$ $1t$2
RewriteRule ^([^U]*)U(.*)$ $1u$2
RewriteRule ^([^V]*)V(.*)$ $1v$2
RewriteRule ^([^W]*)W(.*)$ $1w$2
RewriteRule ^([^X]*)X(.*)$ $1x$2
RewriteRule ^([^Y]*)Y(.*)$ $1y$2
RewriteRule ^([^Z]*)Z(.*)$ $1z$2

# If there are any uppercase letters, restart at very first RewriteRule in file.
RewriteRule [A-Z] – [N]

RewriteCond %{ENV:HASCAPS} TRUE
RewriteRule ^/?(.*) /mb2/$1 [R=301,L]

Reference:
http://www.askapache.com/htaccess/rewrite-uppercase-lowercase.html

Apache Secure Default Configuration

The content of httpd.conf should have the following entries:

User apache
Group apache

ServerTokens Prod
ServerSignature Off

TraceEnable off
Timeout 45

FileETag None

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Header always append X-Frame-Options SAMEORIGIN
Header set X-XSS-Protection “1; mode=block”
Header set Cache-Control “max-age=290304000, public”

SetOutputFilter DEFLATE

SetEnvIfNoCase Request_URI \.(?:rar|zip)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:gif|jpg|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:avi|mov|mp4)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary

<Directory />
Options None
Order Deny,Allow
Deny from all
AllowOverride None
</Directory>

<Directory /opt/apache/htdocs>
Options -Indexes -ExecCGI -FollowSymLinks -Includes
Order allow,deny
Allow from all

RewriteEngine On
RewriteCond %{THE_REQUEST} !HTTP/1.1$
RewriteRule .* – [F]

<Files ~ “^\.ht”>
Order allow,deny
Deny from all
Satisfy All
</Files>

</Directory>

The content of ssl.conf should have the following entries:

SSLCipherSuite HIGH:!MEDIUM:!aNULL:!MD5:!RC4
SSLProtocol –SSLv2 -SSLv3

Apache Log Format for Web Servers Behind Load Balancer

If you are using a load balancer to balance the load to two or more web servers, usually only the IP address of the load balancer will be logged in the web logs instead of the visitor’s IP address.

To log visitor’s IP address, just create a custom log format with a new name , e.g. “lb_log” and used it in all the virtual host configured in Apache. Please always backup your original httpd.conf before you make any changes.

 
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
LogFormat “%{X-Forwarded-For}i %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-Agent}i\”” lg_log
#….
# START_HOST example.com
<virtualhost *:80>
    ServerName example.com
    DocumentRoot “/var/www/example.com/html”
    <directory “/var/www/example.com/html”>
        Options Includes FollowSymLinks  
        AllowOverride All
        Order allow,deny
        Allow from all
    </directory>
    CustomLog /var/www/logs/example.com/access_log lb_log
    ErrorLog /var/www/logs/example.com/error_log
</virtualhost>
# END_HOST example.com

Before you make any changes to httpd.conf please go through Apache log module .

 

Reference:
http://www.imthi.com/blog/linux/apache-log-format-for-amazon-ec2-with-elastic-load-balancer.php

Apache Redirection

There are times we need to do a redirect on the server side.
301 redirect is a preferred way of redirect for SEO sake.
I will show you 2 ways of configuring Apache HTTP Server to do redirect by modifying httpd.conf or .htaccess file:

1. Using mod_alias

Redirect permanent / http://www.your-new-website.com

2. Using mod_rewriteRewriteEngine on

RewriteCond %{HTTP_HOST} ^www.your-old-website.com
RewriteRule ^(.*)$ http://www.your-new-website.com$1 [R=permanent,L,NE]

Please remember to reload or restart Apache after that.

Reference:
http://www.yolinux.com/TUTORIALS/ApacheRedirect.html

How to Exclude Certain URLs from HTTP Authentication

A development server I was working on required HTTP authentication due to being public-facing. However a certain application inside can’t work with HTTP authentication so certain paths need to be excluded. Usually this can be done by placing HTTP authentication in the main Apache configuration file (httpd.conf) and put .htaccess file in the directory I want to exclude.  .htaccess file has the following content:

Order Deny,Allow
Allow from all
Satisfy any

Please note that this method can be used for physical path only. To exclude virtual path,  just add the following lines in Apache main configuration file (httpd.conf) instead:

# Require auth for all except API directory. Change API with your own.
<LocationMatch "(?i)^(?!/API/)[^\.]+$">
    AuthName "Restricted Area"
    AuthType Basic
    AuthUserFile /path/to/.htpasswd
    AuthGroupFile /dev/null
    require valid-user
</LocationMatch>

References:
How to Remove Basic Auth from a Protected Subdirectory (Apache)
Excluding HTTP Authentication Based On URL