Allowing Access to Vagrant Instances from the Internet

Allowing Access to Vagrant Instances from the Internet

aka: “how do I use Vagrant with ngrok”

I’ve been working with a client whose developers use both Vagrant and ngrok very heavily. Here is what the developers like about both of them:

Vagrant:

  1. provides ability to spin up/down local development instances very quickly and consistently.
  2. the vagrant instances also run configuration management (in this case, Puppet) ensuring that the configuration is production-like

Ngrok:

  1. tunnels ports from the public internet (typically ports 80 and 443) to a given port on your own host, allowing connectivity to development instances from other hosts and devices. An example would be connecting an iOS or Android device to a vagrant instance.

Problem: accessibility, efficiency and consistency

  1. The developers were running into problems connecting hosts (typically iPhones and Android devices) to their local vagrant development instances
  2. Although easy to use, ngrok configuration was performed manually and usage wasn’t consistent developer to developer

Solution: vagrant with foodshow plugin

I solved both of these problems using a the vagrant plugin vagrant-foodshow – this vagrant plugin modifies vagrant port forwarding so that the host port also becomes the destination port of an ngrok tunnel. As all of the developers share one vagrant file, this also had the benefit of automating ngrok configuration and ensuring consistency of ngrok use. A screenshot of the results are below:

vagrant-foodshow-ngrok - Running in Chrome
Connectivity to a vagrant virtual machine from the public internet.
vagrant-foodshow-ngrok - Bootup
vagrant bootup with foodshow plugin configured.

 

Solution: the code

The Vagrantfile used to accomplish this below, and has also been checked into my snippets GitHub repository at https://github.com/colinbjohnson/snippets:

vagrantfile_api_version = "2"
if Vagrant.has_plugin?('vagrant-foodshow')
 ngrok_enabled = true
else
 ngrok_enabled = false
end
Vagrant.configure(vagrantfile_api_version) do |config|
config.vm.network "private_network", ip: "192.168.2.2"

if ngrok_enabled == true
 print "Ngrok enabled.\n"
 config.foodshow.enabled = true
 # using config.foodshow.subdomain will host your vagrant instance at the
 # given subdomain - for instance, you could host at my_subdomain.ngrok.com
 # instead of 94f3bdd.ngrok.com
 # config.foodshow.subdomain = 'my_subdomain'
 # config.foodshow.authtoken is required if using config.foodshow.subdomain
 # add your authtoken below
 # config.foodshow.authtoken = 'my_authtoken'
 config.vm.network :forwarded_port, guest: 80, host: 8080, ngrok_proto: "http+https"
 else
 $stderr.print "Ngrok not enabled.\n"
 end
config.vm.box = "ubuntu/precise64"
end

Two final notes:

  1. The above configuration exposes your vagrant instance to the public instance. If this is a concern, ngrok supports authentication to protect the destination service.
  2. My hope is to find time to create a private network shared amongst only the host OS, guest OS and the additional host, if it is an iOS or Android device.

Configure Apache Authentication against Google Apps using OIDC – Implementation Details

This blog post will guide you through implementing Apache authentication against Google Apps using OpenID Connect. I’ll also describe (lightly) how OAuth 2.0 flows work, as OAUth 2.0 is leveraged by OpenID Connect.

How does the OAuth 2 flow work?

Once understood, the flow is fairly simple:

  1. User requests a URL: https://www.cloudavail.com/protected/, for example.
    • On this initial request the client does not send any authentication information, and the server is configured to require authentication
  2. The server redirects the user to a particular URL http://accounts.google.com/o/oauth2 for example. This URL is a parameter given to the mod_auth_openidc module.
  3. The user visits the particular URL at which they agree to share information with a third party. In this particular case, the user is authorizing google.com to share data with CloudAvail.
  4. Google then redirects the user back to a URL at CloudAvail. For example, the user would be redirected to the following URL: https://www.cloudavail.com/protected/oauth2callback – and this time, with a code provided in the query string. Example https://www.cloudavail.com/protected/oauth2callback?code=4im6WNBK5UF9. The code can then be used to request data from the Google API.
  5. When it is confirmed that the user exists (and is authorized to access a given resource) the user is the redirected to the originally requested page: https://www.cloudavail.com/protected/.

How to implement ?

As of this writing mod_auth_openidc is the only OpenID Connect module for Apache. I implemented using the mod_auth_openidc using Apache 2.7.4 on Ubuntu 14.0.4.

Create a Google Project:

  1. Go to https://console.developers.google.com/project
  2. Select “Create Project” and provide a project name and project ID.

Configure the Google Project:

  1. In “APIs” you will need to enable the “Google+ API.” See screenshot below:
    Google API - APIs - Enable Google Plus API
  2. In “Credentials” you will need to create a new OAuth key.
  3. You’ll want to select the “Web application” type
    1. for the “Authorized Redirect URI” you’ll want to provide a URL that is resolvable but does not serve content – this URL is used to receive the code that will be returned by the Google API. See screenshot below:
      Google API - Credentials - OAuth 2 Client
  4. Configure a “Consent Screen” (note that a “Product Name” is required for use of OAuth 2.0)
    1. In “APIs & auth” enter a “Product Name” and/or Logo. This will be displayed to users who are accessed to allow your application to access data stored in Google Apps.

Download and Install the mod_auth_openidc Module

# download the mod_auth_openidc Module
wget https://github.com/pingidentity/mod_auth_openidc/releases/download/v1.4/libapache2-mod-auth-openidc_1.4_amd64.deb
# enable the mod_auth_openidc Module
sudo dpkg -i libapache2-mod-auth-openidc_1.4_amd64.deb

Configure Apache to utilize the mod-auth-openidc Module

The documentation in https://github.com/pingidentity/mod_auth_openidc/blob/master/README for Google Apps is correct. One note:
OIDCRedirectURI must match exactly to the Authorized Redirect URI of your project.

Enable the mod_auth_openidc module and restart Apache

# Enable the mod_auth_openidc Connect Module
sudo a2enmod auth_openidc
# Restart Apache with the mod_auth_openidc Module Enabled
sudo service apache2 restart

Questions or Comments?

Please feel free to post either questions or comments.

Configure Apache Authentication against Google Apps using OIDC – Overview

Apache Authentication using OpenID Connect and Google Apps – an Overview

Why authenticate using Google Apps (or another OpenID Connect provider)?

Using Google Apps or another OpenID Connect provider for an authentication will:

  • allow you to use individual usernames/passwords instead of shared usernames/passwords
  • reduce the number of usernames/passwords that users must remember (see “password fatigue“). Users will instead be logged in automatically using their Google Account
  • improve security through the use of Multi-Factor Authentication if you have enabled Multi-Factor Authentication for Google Accounts
  • reduce the administrative support burden on Ops/IT staff through centralizing administration of users

Why use Apache authentication and authorization instead of application-based authentication?

Using Apache authentication and authorization instead of application-based authentication will provide two benefits:

  • eliminate the need for implementing an authentication and authorization method within each application – instead you define protected URLs within Apache directives
  • management of usernames/passwords outside of code

Why to avoid Apache authentication with OpenID Connect?

  • complexity – Open ID Connect and Oauth 2.0 can be complex, particularly when compared to file or database authentication and authorization
  • evolving standard – although I have not encountered this, I do know that different OpenID Connect providers implement parameters and access expiration differently
  • reliance on third parties – in this case, your application will rely on the availability of Google’s APIs for user authentication and authorization, as compared to a file or database
  • time to implement – you should estimate a half day of effort for implementation and testing of Apache and OpenID Connect. Add an additional half-day of effort for understanding Oauth 2.0 (which OpenID Connect relies on) if you haven’t worked with the Oauth 2.0 before.