Using Amazon Cloudfront with Rails and Apache and https

Cloudfront is an easy way to cache assets from your Rails application. However there are several gotchas, so these are the steps I took.

Let’s say you have this website:

  • Your domain name is
  • You have an SSL cert so it is running at
  • You would like assets being served from /assets to be served from cloudfront
  1. Create a Web Distribution:
    Log into your Amazon AWS Console

2.  Distribution Settings

  • Origin Domain Name: This is the domain name of the assets you want to cache.   Since you want to cache assets (images, css, js) put in
  • Origin Protocol Policy: if you know you are using SSL, you can select it here

  • Forward Headers: One of the things to avoid problems with CORS is to forward headers with ‘origin’.  What this will do is forward your ‘Access-Control-Origin’ to cloudfront

Afterwards you can click save

3) Edit Distribution


You will see that now your distribution is:

  • name:
  • Status: In Progress

At this point you can continue, but all of your URLS will be\assets\main.css

We want to make it look a little prettier, so click into the distribution, click general, then click ‘edit’

4) Custom SSL

Now let’s say we want things mapped from to  The first thing is we need an SSL Cert, and we can get one through AWS.  Click Request or Import a Certificate

  • Enter the domain name ‘’.  What will happen is a series of validation steps to ensure you actually own it
  • Alternate Domain Names: Enter in  Later we will make a cname record for this
  • Custom SSL Certificate: Select the certificate
  • Custom SSL Client Support:  If you want to save money (like a LOT) then select the SNI support.  Most browsers support this anyways.

5) Create cname record

  • Create a cname record of cloudfront to –>

6) Rails configuration
In production.rb set

config.action_controller.asset_host = “”
And ensure your assets are using Rails helpers that point to the asset pipeline (like image_tag, etc).

7) Apache Vhost Configuration

If you don’t add any CORS configuration what will happen is that will access and in your browser console, you will see a bunch of CORS problems.

With the setting you specified earlier, cloudfront will read one of your original assets such as

  • Caches it, forwards the origin header
  • Then your rails site accesses it as

In your Apache vhost file add this setting

<VirtualHost *:443>
Header set Access-Control-Allow-Origin ""

If you open chrome and check, the response headers for any request should be

Response Headers:

So when Cloudfront pulls in the asset, it will also pull in that header.    An alternative method is to use rack-cors

Restart apache

8) Finally wait until your distribution says ‘deployed’

Deploy the new code with the production config, and if all goes well, you should be distributing from Cloudfront!




Security Metrics PCI Compliance Fix: SSL 64-bit Block Size Cipher Suites Supported (SWEET32)

Security Metrics recently tweaked their scan settings in 2017.  Recently this came up as a problem.

Problem: SSL 64-bit Block Size Cipher Suites Supported (SWEET32)
The remote service supports the use of 64-bit block ciphers.



First off, run the following command on your server
nmap --script ssl-enum-ciphers -p 443 SERVER_IP

It will return a list of ciphers, look to see if you have this in the list

|       TLS_RSA_WITH_3DES_EDE_CBC_SHA – strong

If you are running Apache, open your vhost file where you have your SSLCipherSuite defined.  Remove the line


And restart your apahce server
Run the command
nmap --script ssl-enum-ciphers -p 443 SERVER_IP

And ensure you don’t see this line

Rerun your security metrics scan and you should be okay.

Fixing InAppBrowser not being able to open ‘_system’ links (e.g. Facebook) in Cordova and Phonegap

InAppBrowser provides you the ability to open links in a custom browser in the app, or in an external browser.  In my case, dynamic content is coming into the app where a user can open external links.   All links would work, but for some reason, certain facebook links wouldn’t work such as'', '_system');

I performed these following tests:

Scenario 1:

  • When the Facebook app was installed on the iPhone, Facebook links wouldn’t work
  • When the Facebook app was removed the Facebook links would work.


If you take a look at

- (void)openInSystem:(NSURL*)url
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url];
    } else { // handle any custom schemes to plugins
        [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];

InAppBrowser eventually calls canOpenURL on the links.  When reading the api docs canOpenURL checks to see if the link is openable by any app.

Now if you notice on the iPhone, when you click on a link like it opens the Google Maps.  This is because when the Google App is installed, it registers a a URL Scheme.

Doing a little Googling yields a page about IOS9 and Facebook.

The docs aren’t exactly clear, but what is that Cordova can’t open the Facebook links because it is missing a schema


For Phonegap there was this post describing a fix to the problem.

Add this to config.xml and you should be good

 <gap:config-file platform="ios" parent="NSAppTransportSecurity" mode="replace">
    <gap:config-file platform="ios" parent="LSApplicationQueriesSchemes" mode="replace">

Series: Ionic 2 App, Part 2: Set-up, Configuration, and Tabs Overview

In part 1 we learned a little bit about the basics of a mobile hybrid app.  Now let’s get to the details of how to set up our environment.  You can also follow this link:

Some prerequisities:

  • Mac or ubuntu (you can use brew if you are using a mac)
  • npm installed
npm install -g ionic@beta
npm install -g phonegap [for phonegap]
npm install -g cordova@latest [for phonegap

Note that Ionic is still in beta, so some of the cli auto generation doesn’t come out quite correctly.

To start off run

ionic serve

//which outputs
Cordova CLI: 6.0.0
Ionic Version: 2.0.0-beta.3
Ionic CLI Version: 2.0.0-beta.22
Ionic App Lib Version: 2.0.0-beta.12
OS: Distributor ID: Ubuntu Description: Ubuntu 14.04.3 LTS 
Node Version: v5.4.1

ionic serve is useful when you need to submit a bug via github or ask for help on the Ionic Slack Forums.

Create a project by running

ionic start tutorial --v2

and then run

ionic serve

On your browser you should now be able to see:

Let’s take a look at the project structure:


  • Root – the root folder is tutorial and there is config.xml.  That will be important later for testing on your phone and deploys
  • app.js – This is where the app starts initializing
  • providers folder – this doesn’t exist yet, but will be where your data mappings will be
  • pages folder – This is where all of your pages will live.

Before that, let’s take a look at the main file app.js


import {App, Platform} from 'ionic-angular';
import {StatusBar} from 'ionic-native';
import {TabsPage} from './pages/tabs/tabs';

  template: '<ion-nav [root]="rootPage"></ion-nav>',
  config: {} //
export class MyApp {
  static get parameters() {
    return [[Platform]];

  constructor(platform) {
    this.rootPage = TabsPage;

    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.

There is a lot going on here, so let us break things into sections

Tabs and Imports

  • Lines 1-3 the import lines import the class so you can use it the current class.  If you have coded Java before, this may seem very familiar to you.  You can read more from this blog.
  • In particular let us focus on line 3 which states
    import {TabsPage} from './pages/tabs/tabs';

What this is saying is it is importing the ‘TabsPage’ class from the location ‘pages/tabs/tabs’.  Even though it doesn’t state it, it is implicilty referring to tabs.js

If you open up tabs.js you will see

export class TabsPage

Notice that the import ‘TabsPage’ matches the name of the import.

Root Page

Now if you take a look at line 16, this is setting the rootPage of your app to the TabsPage.  Note that it can be any arbitrary page.

Tabs Page.js

import {Page} from 'ionic-angular';
import {Page1} from '../page1/page1';
import {Page2} from '../page2/page2';
import {Page3} from '../page3/page3';

  templateUrl: 'build/pages/tabs/tabs.html'
export class TabsPage {
  constructor() {
    // this tells the tabs component which Pages
    // should be each tab's root Page
    this.tab1Root = Page1;
    this.tab2Root = Page2;
    this.tab3Root = Page3;

  • In the tabs.js you will note a bunch of new imports.
  • In line one, you have an import from a core class
  • In lines 2-4, you have imports for other pages
  • And if you notice in lines 14-16 variable instances on the TabsPage are being set to the pages.


  <ion-tab [root]="tab1Root" tabTitle="Tab 1" tabIcon="pulse"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="Tab 2" tabIcon="chatbubbles"></ion-tab>
  <ion-tab [root]="tab3Root" tabTitle="Tab 3" tabIcon="cog"></ion-tab>

Here you see that in the ion-tabs element, it is being set to ‘tab1Root’.  tab1Root is mapped to ‘Page1’ so when you click on the ‘Tab 1’ page it loads.

Here ionic defines special ‘ion-tabs’ tags (which is described on the api here).



  • When ‘ionic serve’ is run app.js loads
  • In this scenario, TabsPage is instantiated (e.g. new TabsPage() )
  • When the constructor runs in TabsPage, any class variables are set
  • In the tabs.html, those variables are implicitly available without references ‘this.’

To Do:

  • Open page1.html and change some text
  • Open page2.html and change some text
  • Open tabs.html and change the ‘tabTitle’

Get a feel of what is changing

Next Post:

  • Stay tuned for a post of how to render data and use providers.


Subscribe to our newsletter to get notified of new articles in the Ionic 2/Tutorial Series!

[mc4wp_form id=”47″]

Adding Cordova Facebook SDK 4 Plugin to a Phonegap Project

Recently I had a need to install the Facebook SDK to help Facebook keep track of app installs.

When reading this documentation:

Running this command
cordova plugin add cordova-plugin-facebook4 --save --variable APP_ID="123456789" --variable APP_NAME="myApplication"

Doesn’t quite generate the right edits to config.xml.  If you are using phonegap, use these settings for config.xml

<gap:preference name="android-build-tool" value="gradle" />
<gap:plugin name="cordova-plugin-admobpro" source="npm" />

<gap:plugin name="cordova-plugin-facebook4" source="npm" spec="1.7.0">
<gap:param name="APP_ID" value="app_id_value" />
<gap:param name="APP_NAME" value="app_name" />

And you should be good to go.

Series: Creating Hybrid Mobile Apps, Part 1: Introduction

In 2o16, you have many options of creating mobile apps.  To me there pretty much are only two options:

  • Native (xcode/swift/java)
  • Hybrid Mobile Apps (write once, cross deploy)

Making a native app makes sense if you are doing something fairly custom with UI or creating a game.  But hybrid mobile apps might make more sense if you are doing something simple like consuming data and displaying it.  Note that I am not an expert in this field, so I’ll try to do the best to convey what I’ve learned from research and recently making an app.

For this tutorial series, we will use Ionic 2 Beta which uses Angular 2 Beta.  Things aren’t quite 100% with Ionic 2, but it is actually good enough to launch a production app.

Another reason I think Ionic 2 is good is their extensive component UI.  This means I don’t need to build tabs, cards, menus, etc.  Check out their offerings at their components page.

Before starting we assume you are familiar with:

  • HTML
  • CSS
  • Consuming APIs
  • Experience in at least one programming language.

Simulator Screen Shot Mar 2, 2016, 4.59.43 PM
In this snapshot example, Ionic comes out of the bat with support of tabs, and cards.


What is a hybrid mobile app?

At a high level, instead of coding with a native language, you code mainly in html, css, javascript, and configuration files.  There is a compilation process that takes place (which can be local or remote, but we’ll get into that later) which gives you two assets:

  • Android apk.  You can use this and install it directly on your device and then upload it to the Google Play Store.
  • IOS .ipa file.  You can install the .ipa to your iPhone or iPad on iTunes for testing then upload it via ‘Application Coder’ on the mac.


Platform Requirements:

When developing, you have two options:

I think a mac is probably the best options.  The reason is that you can generate the apk and ipa locally and run emulation to test the apps.

If you have Windows, I recommend that you run Ubuntu to run your development.  From there, what you can do is use Phonegap to remotely compile your code.  From there you can download your .apk and .ipa.

Note that if you have a PC, you do need a Mac to take screen snapshots for each platform and submit your .ipa via ‘Application Loader’.  If you don’t have a Mac available, you could use mac in cloud.


Developing a hybrid app is a little bit different than doing a full stack like Ruby on Rails.


  • Text Editor – All your work starts off with your standard text editor.  You could use anything like Eclipse, but for this example I have been using Sublime .
  • Compile and test on browser – Similar to running ‘rails s’, you can run ‘ionic serve’.  What this does is transplies (not compilation as it doesn’t go into a vm) and binds port 8100 to a webserver.  What you can now do is test your app in the browser.  However you won’t have access to native features such as the camera, uuid, etc.
  • Emulator – If you are running on a Mac, you can run ‘ionic emulate ios’ which launches an emulator.  This is a little better than running it in a browser, but still misses some native functionality.
  • Build – Here you actually generate the .ipa or .apk to load on your native device.  You can build it locally or use Phonegap.

When developing, my advice is to not wait until the very last minute to test your app on an iPhone and android device.  There are often weird things that happen and you don’t want to get hit last minute with weird errors.



Most likely your mobile app will fall into one of two situations

  • No API Access – This is an app which is completely offline and can rely on all of the local storage (SQlite, etc).
  • API Access – This is the most common scenario where an app hits an API to get data.

For this tutorial, we will assume you have an API already that works.  My only recommendation is to have two environments for your API.  Development and production.

Here is part 2 where we will start installing the environment and create a new project.




Subscribe to our newsletter to get notified of new articles in the Ionic 2/Tutorial Series!

[mc4wp_form id=”47″]

Security Metrics PCI Compliance Changes and Fixes

Back in 2015, I did a Security Metrics scan on my site for PCI compliance, and noticed I had 3 new failures when they rescanned my site in early 2016.  What I suspect is that these tests were added:

Problem 1: TLS Version 1.0 Protocol Detection (PCI DSS)


Security Metrics is basically saying that having TLS Version 1.0 is a security vulnerability.

The remote service encrypts traffic using a protocol with known weaknesses.  The remote service accepts connections encrypted using TLS 1.0.

If you are running apache, you might have a configuration parameter like this.
SSLProtocol all -SSLv2 -SSLv3

If you take a look at the docs here

It says that ‘all’ is a shortcut for “+SSLv2 +SSLv3 +TLSv1” or – when using OpenSSL 1.0.1 and later – “+SSLv2 +SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2”, respectively.

Change your apache config to
SSLProtocol all -SSLv2 -SSLv3 -TLSv1

Restart your server and run
sudo service apache2 reload

Verify TLS 1.0 says ‘no’ and you are good to go

Problem 2: SSH Diffie-Hellman Modulus <= 1024 Bits (Logjam)Rest


Security Metrics is saying here that your server connection is accepting SSH connections with a diffie-hellman group 1 of 1024 bits.

The remote host allows SSH connections with one or more Diffie-Hellman moduli less than or equal to 1024 bits. The remote SSH server allows connections with one or more Diffie-Hellman moduli less than or equal to 1024 bits

First run this command on your server to verify the problem

nmap –Pn [domain/ip] –p [port] –script ssh2-enum-algos

|   kex_algorithms (8)
|       ecdh-sha2-nistp256
|       ecdh-sha2-nistp384
|       ecdh-sha2-nistp521
|       diffie-hellman-group-exchange-sha256
|       diffie-hellman-group-exchange-sha1
|       diffie-hellman-group14-sha1
|       diffie-hellman-group1-sha1

Note here that the server is returning

  • diffie-hellman-group-exchange-sha1
  • diffie-hellman-group1-sha1

You can read these two links for more info

To fix it go into



and run sudo restart ssh

Outside the box rerun the command and note that the kex algorithms are returning a smaller set.


nmap –Pn [domain/ip] –p [port] --script ssh2-enum-algos
| kex_algorithms (2)
| diffie-hellman-group-exchange-sha256

Problem 3: Web Application Potentially Vulnerable to Clickjacking

The remote web server may fail to mitigate a class of web application vulnerabilities.

The remote web server does not set an X-Frame-Options response header in all content responses

The fix for this is pretty easy as specified by

In apache put in apache2.conf


restart your server, and verify by going to

Ensure X-Frame-Options gets returned

Rescan your site and you should be good to go for security metrics pci compliance!