Twelve-Factor Apps

Cloud computing is one of the most rapidly evolving technologies. It promises many benefits, such as cost advantages, speed, agility, flexibility and elasticity.

But, how do we ensure an application can run seamlessly across multiple providers and take advantage of the different cloud services? This means that the application can work effectively in a cloud environment, and understand and utilize cloud behaviors, such as elasticity, utilization-based charging, fail aware, and so on.

It is important to follow certain factors while developing a cloud-native application. For this purpose, we have The Twelve-Factor App. The Twelve-Factor App is a methodology that describes the characteristics expected in a modern cloud-ready application.

The Twelve Factors

I. Codebase

This factor advices that each application should have a single code base with multiple instances of deployment of the same code base. For example, development, testing and production. The code is typically managed in a VCS (Version Control System) like Git, Subversion or other similar.

II. Dependencies

All applications should bundle their dependencies along with the application bundle, and all of them can be managed with build tools like Maven or Gradle. They will be using files to specify and manage these dependencies and linking them using build artifact repositories.

III. Config

All configurations should be externalized from the code. The code should not change among environments, just the properties in the system should change.

IV. Backing services

All backing services should be accessible through an addressable URL. All services should be reachable through a URL without complex communications requirements.

V. Build, release, run

This factor advocates strong isolation among the build stage, the release stage and the run stage. The build stage refers to compiling and producing binaries by including or assets required. The release stage refers to combining binaries with environments-specific configuration parameters. The run stage refers to running applications on a specific execution environment. This pipeline is unidirectional.

VI. Processes

 The factor suggests that processes should be stateless and share nothing. If the application is stateless, then it is fault tolerant and can be scaled out easily.

VII. Port binding

Applications develop following this methodology should be self-contained or standalone and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app exports HTTP as a service by binding to a port, and listening to requests coming in on that port.

VIII. Concurrency

This factor states that processes should be designed to scale about by replicating the processes. What it means, just spinning up another identical service instance.

IX. Disposability

This factor advocates to build applications with minimal startup and shutdown times. This will help us in automated deployment environments where we need to bring up and down instances as quickly as possible.

X. Dev/Prod parity

This factor establish the importance of keeping the development and the production environments as close as possible. Maybe to save costs, no the local environments where developers write their code, here they tend to run everything in one machine but, at least, we should have a non-production environments close enough to our production environment.

XI. Logs

This factor advocates for the use of a centralized logging framework to avoid I/Os in the systems locally. This is to prevent bottlenecks due to not fast enough I/Os.

XII. Admin processes

 This factor advices you to target the same release and an identical environment as the long running processes runs to perform admin tasks. The admin consoles should be packaged along with the application code.

I recommend you to read carefully the The Twelve-Factor App page and its different sections.

Advertisements
Twelve-Factor Apps

Exploring the logs

As a developers an important part of our job sometimes is to fix problems in the different environments where our applications are deployed. Usually, this means to deal with huge log files to find where errors occur, and their stacktraces to add some context to the problem. The problem is that usually log files are verbose and contain a lot of information.

A couple of useful command to deal with this can be:

  • grep
  • zgrep

Both have the same purpose the only difference it that “grep” works with normal files and “zgrep” works with compressed (.gz) files. Usualy files are compressed due to the logs rotation scheduled in the servers. Both commands have multiple options and flags but, I am going to expose here two flags that have been useful multiple times:

  • -E expr: Allow as to supply a pattern for the search.
  • -C num: Print num lines of leading and trailing output context.
  • –color: Shows the matched information in color in the terminal.

As an example we have:

zgrep --color -E '(Sending email)' myLog.log-20170621.gz
grep --color -E '(Sending email)' myLog.log
grep --color -C 25 -E '(Sending email)' myLog.log

As we can see, obviously, they can be combined.

 

Exploring the logs

Simplifiying SSH

Nowadays we are use to deploy code in the cloud and to have all our machines and servers in cloud environments. All of this, it has even made more important the use of ssh to connect remotely to our servers allocated in the cloud.

I have written multiple times in my console the commands to connect to one server or another but, as every developer, I am lazy and I try to simplify my life. In this case, we can do this with a simple lines in a couple of files:

  • ~/.ssh/config: We are going to configure the machines we want to connect or tunnels we wnat to create.
  • ~/.bashrc or ~/.bash_profile: Create some alias to easily connect to our servers

SSH config file

Server to connect

# MyServer-1
Host                    myServer1
HostName                myserver1.myorg.com
User                    username
IdentityFile            ~/.ssh/myCertificate.pem
PasswordAuthentication  no
StrictHostKeyChecking   no

Create tunnel

# MyServer-1 - myDb
Host                    myServer1Db
HostName                myserver1.myorg.com
User                    username
IdentityFile            ~/.ssh/myCertificate.pem
PasswordAuthentication  no
StrictHostKeyChecking   no
LocalForward            3307 myserver1.myorg.com:3306

Bash Config file

alias myserver1="ssh myServer1"
alias myserver1db="ssh myServer1Db"

Conclusion

After this, it will be enough to connect to our remote servers with executing our aliases in our console. No more remember commands.

 

Simplifiying SSH

Debugging JVM flags

Just a couple of interesting flags when we are executing/debugging a Java web based application.

First one, it is just to change the logging level without modifiying our properties file:

-Dlogging.level.com.wordpress.binarycoders=DEBUG

Second one, it is in case we are using Hibernate as ORM. It will allow us to see the executed SQL queries in the log:

-Dhibernate.show_sql=true

They just need to be added as a “VM Options” when the server is started or the JAR file is run.

Debugging JVM flags

Design patterns: Factory Method

This is a creational pattern, the factory method pattern is a design pattern that allows for the creation of objects without specifying the type of object that is to be created in code. A factory class contains a method that allows determination of the created type at run-time.

The factory pattern is used to replace class constructors, abstracting the process of object generation so that the type of the object instantiated can be determined at run-time.

Elements involved:

  • FactoryBase: This is an abstract base class for the concrete factory classes that will actually generate new objects.
  • ConcreteFactory: Inheriting from the FactoryBase class, the concrete factory classes inherit the actual factory method. This is overridden with the object generation code unless already implemented in full in the base class.
  • ProductBase: This abstract class is the base class for the types of object that the factory can create. It is also the return type for the factory method.
  • ConcreteProduct: Multiple subclasses of the Product class are defined, each containing specific functionality. Objects of these classes are generated by the factory method.

We should use the Factory Method design pattern when:

  • when a class can’t anticipate the type of the objects it is supposed to create.
  • when a class wants its subclasses to be the ones to specific the type of a newly created object.

Let´s see some code:

public abstract class FactoryBase {
    public abstract ProductBase build(int type);
}
public abstract class ProductBase {
    public abstract void whoIAm();
}
public class ConcreteFactory extends FactoryBase {

    @Override
    public ProductBase build(int type) {
        final ProductBase productBase;

        switch (type) {
            case 1:
                productBase = new ConcreteProduct1();
                break;

            case 2:
                productBase = new ConcreteProduct2();
                break;

            default:
                throw new IllegalArgumentException(String.format("Illegal type %s", type));
        }

        return productBase;
    }
}
public class ConcreteProduct1 extends ProductBase {

    @Override
    public void whoIAm() {
        System.out.println("I am ConcreteProduct1");
    }
}
public class ConcreteProduct2 extends ProductBase {

    @Override
    public void whoIAm() {
        System.out.println("I am ConcreteProduct2");
    }
}
public class Main {
    public static void main(String[] args) {
        final FactoryBase factoryBase = new ConcreteFactory();

        factoryBase.build(1).whoIAm();
        factoryBase.build(2).whoIAm();
    }
}

The output after the execution should be something like that:

I am ConcreteProduct1
I am ConcreteProduct2

You can find the code in my GitHub repository “design-apperns“.

Design patterns: Factory Method

OWASP Top 10

The OWASP project is an open source project related with the cyber security field. The project contains information about web application security, mobile security and, lately, IoT security. In addition, multiple back-end security information too, due to all the previous technologies use usually these systems to receive and process their information. If you do not know and you like cyber security, you should definitely take a look.

They have multiple projects like tools, methodologies, metrics, documentation but, one of the most known projects is the OWASP Top 10. The project is a document with the ten most critical web application security risks.

They have multiple versions of the document but, the last one was from 2013 (you can find it here). Obviously, this is a quite old version, not a lot of things has changed since them because, unfortunately, some of the vulnerabilities are still out there but, still, and old version. But, there are some good news, they released on the 10 of April the 2017 version. Right now, it is just a release candidate, the final version is scheduled for July or August this year. We can find this release version here.

These ten security risk are sorted by relevancy. Let’s take a look to them very quickly. We will go deeper in future articles.

A1 – Injection

The injection attacks, where we can find SQL injection, LDAP injection, XPath injection, command injection and some other, is still the most important. It has been in the first place since I remember and everyday we can see examples in the news about them.

A2 – Broken Authentication and Session Management

In second place, we can find the errors produced due to the wrong authentication management or wrong session management. Sessions that never expire, especially the ones used in GET requests that can be indexed in browser or proxies. Areas of the application where the session is not properly checked. We can find attacks like session fixation or session hijacking.

A3 – Cross-Site Scripting (XSS)

In third place, we can find the XSS attacks. Probably, together with the injection attacks the most well known attacks. We can see them everywhere, fun images inserted in government pages or hight traffic pages using scripting languages the browsers understand.

A4 – Broken Access Control

The fourth one, it is the broken access control risk, there are areas of our application that are not properly protected and non authenticated users can access them and do things they should not.

A5 – Security Misconfiguration

In the fifth place, we can find misconfiguration. It can be configuration errors in our servers, or even just error messages giving away more information about our systems than they should.

A6 – Sensitive Data Exposure

The sixth place is unfortunately one that should not exist but we can find too often. It is when sensitive data is exposed, like personal data, medical records or any other private and sensitive information the systems store and it is not properly protected. This information should be encrypted properly or it should be protected using second factor authentication systems or some other options to avoid leaks and, in case the bad guys access the information, make impossible to read it.

A7 – Insufficient Attack Protection

In the seventh place, we can find a new one. Insufficient attack protection, basically means that there are not enough measures, countermeasures o tools to prevent security incidents in place. Prevention: WAF, Anti-DDoS system, not periodic pentest, … Detection: logs, SIEM, IDS, IPS, … Response: backups, encrypted DB, …

A8 – Cross-Site Request Forgery (CSRF)

The eighth is old and well known where the victim sends its session cookie and/or any other automatically included authentication information, to a vulnerable web application through a malicious link.

A9 – Using Components with Known Vulnerabilities

The ninth is a basic one, all the applications have bugs and they need to receive updates and these updates need to be installed, if we or our security teams do not do this, we are going to be vulnerable.

A10 – Under-protected APIs

The last one is a new one, it has been there for a few years but I guess that it has been during the last years when the explosion about exposing APIs has arrived and, multiple back-end systems have hundreds if not thousands of APIs exposed to the world to be consumed and not all of them properly protected.

As we can see, the list does not change too much between version and we are having the same problems, risk and vulnerabilities we were having four years ago.

OWASP Top 10