Getting Started

Initial steps to deploy and configure the software

5 minute read

To ensure the properly level of security within the platform, there are in place two pieces of software:

  • Nginx: It is an open-source multi-purpose software, that in this case works as a reverse proxy. A reverse proxy is a software dedicated to analyse the incoming traffic to an IP or a rage of IPs, that is usually located between the Internet and the servers, acting like a firewall, among other things.
  • Keycloak: It is an open-source Identity and Access Management (IAM) solution. An IAM is a software whose main function is to authenticate the users, to restrict access and to manage permission within the platform. All request to the APIs must contain an authorisation token provided by Keycloak in order to be validated by the API Gateway in place.

The platform’s components and apps are deployed using dockers, which facilitates managing the overall security of the system and its deployment due to dockers are independent of the environment where are deployed. This way is also facilitated the automation of deployment and recovery of services if there are any interruptions.

So in order to install the previous softwares described, it is mandatory to have the following prerrequisites:

Prerrequisites

Required libraries and frameworks for installing the software and the specific versions:

  • Python 3.7 or higher
  • A running Docker distribution with docker-compose

Configuration (Optional)

In order to deploy the security software necessary, it must be defined their configuration files:

Nginx - nginx.conf

Note: fields between <> symbols represents parameters that users must replace with their own values to correctly configure and deploy the reverse proxy.

server{     
  listen 80;
  server_name _;
  
	# Fix 'upstream sent too big header while reading response header from upstream' during refresh
  proxy_buffer_size         128k;
	proxy_buffers           4 256k;
  proxy_busy_buffers_size   256k;


	location /oauth2/ {
    proxy_pass                               http://proxy:4180;
    proxy_set_header Host 		               $host;
    proxy_set_header X-Real-IP	             $remote_addr;
    proxy_set_header X-Scheme                $scheme;
    proxy_set_header X-Auth-Request-Redirect $request_uri;
		
    # or, if you are handling multiple domains: 
	  proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
	}
  
  location /oauth2/auth {
    internal;                                                                             
	  proxy_pass       		            http://proxy:4180;
    proxy_set_header Host           $host;
    proxy_set_header X-Real-IP      $remote_addr;
    proxy_set_header X-Scheme       $scheme;
        
    # nginx auth_request includes headers but not body

	  proxy_set_header Content-Length   "";
    proxy_pass_request_body           off;
  }                                                                                                                                     
	
  location / {
	  auth_request /oauth2/auth;
    error_page 401 = /oauth2/sign_in;
	
	  # pass information via X-User and X-Email headers to backend,
    # requires running with --set-xauthrequest flag
	  auth_request_set $user   $upstream_http_x_auth_request_user;
	  auth_request_set $email  $upstream_http_x_auth_request_email;
	  proxy_set_header X-User  $user;
	  proxy_set_header X-Email $email;

    # if you enabled --pass-access-token, this will pass the token to the backend

	  auth_request_set $token  $upstream_http_x_auth_request_access_token;
    proxy_set_header X-Access-Token $token;

	  # if you enabled --cookie-refresh, this is needed for it to work with auth_request
	  auth_request_set $auth_cookie $upstream_http_set_cookie;
	  add_header Set-Cookie $auth_cookie;
	
	  # When using the --set-authorization-header flag, some provider's cookies can exceed the 4kb
    # limit and so the OAuth2 Proxy splits these into multiple parts.
	  # Nginx normally only copies the first `Set-Cookie` header from the auth_request to the response,
	  # so if your cookies are larger than 4kb, you will need to extract additional cookies manually.
	  auth_request_set $auth_cookie_name_upstream_1 $upstream_cookie_auth_cookie_name_1;

	  # Extract the Cookie attributes from the first Set-Cookie header and append them
	  # to the second part ($upstream_cookie_* variables only contain the raw cookie content)
	  if ($auth_cookie ~* "(; .*)") {
	    set $auth_cookie_name_0 $auth_cookie;
	    set $auth_cookie_name_1 "auth_cookie_name_1=$auth_cookie_name_upstream_1$1";
	  }

	  # Send both Set-Cookie headers now if there was a second part
	  if ($auth_cookie_name_upstream_1) {
	    add_header Set-Cookie $auth_cookie_name_0;
	    add_header Set-Cookie $auth_cookie_name_1;
	  }

	  proxy_pass http://server/;
	}
}                                                                                                                                                                                                                                                                                   
# front-end #1
server {
	listen <port> ssl;
	server_name <domain name>;
	ssl_certificate /etc/x509/https/tls.crt;
	ssl_certificate_key /etc/x509/https/tls.key;
  ssl_protocols TLSv1.2 TLSv1.3;
	underscores_in_headers on;
	location / {
		proxy_pass                       http://<domain name>:<port>;
		proxy_set_header Host 		       $host;
		proxy_set_header X-Real-IP 	     $remote_addr;
		proxy_set_header X-Scheme        $scheme;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}

# front-end #2
server {
	listen <port> ssl;
	server_name **<domain name>**;
	ssl_certificate /etc/x509/https/tls.crt;
	ssl_certificate_key /etc/x509/https/tls.key;
	ssl_protocols TLSv1.2 TLSv1.3;
	underscores_in_headers on;
	location / {
		proxy_pass                       https://<domain name>:<port>;
		proxy_set_header Host  		       $host;
		proxy_set_header X-Real-IP  	   $remote_addr;
		proxy_set_header X-Scheme        $scheme;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
} 

Docker-compose - docker-compose.yml

Note: fields between <> symbols represents parameters that users must replace with their own values to correctly configure and deploy the dockers.

version: '3.5'

services:

  proxy:
    image: quay.io/oauth2-proxy/oauth2-proxy:v7.3.0
    container_name: oauth2-proxy
    command: --config /oauth2-proxy.cfg --oidc-extra-audience="account"
    restart: unless-stopped
    ports:
      - 4180:4180
      - 443:443
    environment:
      - OAUTH2_PROXY_COOKIE_SECRET=MTExMTExMTExMTExMTExMQ==
    networks:
      - proxy-network
    volumes:
      - ./config/oauth2-proxy.cfg:/oauth2-proxy.cfg
    depends_on:
      - keycloak
      - server

  keycloak:
    image: jboss/keycloak:16.1.0
    restart: unless-stopped
    environment:
      - DB_VENDOR=MYSQL
      - DB_ADDR=mysql
      - DB_DATABASE=<keycloak>
      - DB_USER=<keycloak>
      - DB_PASSWORD=<password>
      - PROXY_ADDRESS_FORWARDING=false
    volumes:
      - ./config/tls.crt:/etc/x509/https/tls.crt
      - ./config/tls.key:/etc/x509/https/tls.key
    networks:
      proxy-network:
        aliases:
          - keycloak.localtest.me
    ports:
      - 8080:8080
      - 8443:8443
    depends_on:
      - mysql

  mysql:
    image: mysql:5.7
    container_name: keycloak-db
    restart: unless-stopped
    volumes:
      - ./data/mysql_data:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=<keycloak>
      - MYSQL_ROOT_PASSWORD=<password>
      - MYSQL_USER=<keycloak>
      - MYSQL_PASSWORD=<password>
    networks:
      - proxy-network

  server:
    image: kennethreitz/httpbin
    restart: unless-stopped
    ports:
      - 8000:80
    container_name: server
    networks:
      - proxy-network

  nginx:
    image: nginx:alpine
    ports:
      - 9000:80
      - <port_front-end_1>:<port_front-end_1>
      - <port_front-end_2>:<port_front-end_2>
    container_name: nginx
    restart: unless-stopped
    volumes:
      - ./nginx:/etc/nginx/conf.d
      - ./config/tls.crt:/etc/x509/https/tls.crt
      - ./config/tls.key:/etc/x509/https/tls.key
    networks:
      - proxy-network
    depends_on:
      - proxy
      - server

networks:
  proxy-network:
    name: local

Installation & Deployment

A detailed guide on how to install a working instance of the software:

Note: Do not copy/paste the commands bellow. Parameters between <> symbols, must be replaced with correspondent values.

  1. Create a directory under which locate all configuration files:
    mkdir <directory>
    mkdir <directory>/config
    mkdir <directory>/data
    mkdir <directory>/nginx
  1. Move configuration files to said directory:
    mv nginx.conf <directory>/nginx/
    mv docker-compose.yml <directory>/
  1. Create certificates for domain:
    sudo certbot certonly --standalone --http-01-port <iam_port>
    cp /etc/letsencrypt/live/<domain name>/fullchain.pem <directory>/config/tls.crt
    cp /etc/letsencrypt/live/<domain name>/privkey.pem <directory>/config/tls.key
  1. Deploy using:
    cd <directory>
    sudo docker-compose up
  1. Finally:
    To finish setting up the IAM, follow the instructions at https://www.keycloak.org/docs/latest/server_admin/#creating-first-admin_server_administration_guide.
    Further instructions are available in the How to use it section.