How is data secure over https?

https

STEP1: Client HELLO

STEP2: Server HELLO

STEP3: Server authentication

STEP4: Secret key exchange

STEP5: Client HELLO finished

STEP6: Server HELLO finished

STEP7: Data exchange

Thanks for reading and hope you learned something new. Feel free to comment if you have any suggestions or corrections.

Advertisements
Posted in General | Leave a comment

Rails Sidekiq configuration for micro services on reverse proxy.

Content posted here with the permission of the author Rahul Ojha, who is currently employed at Josh Software. Original post available here.

This blog is intended to describe how to configure multiple sidekiq webs for API only apps using reverse proxy server.

Background

We have 4 API services running on ECS. We used a single domain for all the services and segregated them with the namespace in routing. For namespace routing and pointing to Docker containers, we have used Traefik. We can do the same thing using Nginx and some other reverse proxy too.

Example:

www.domain.com/rails-api-1/REST_ROUTES
www.domain.com/rails-api-2/REST_ROUTES
www.domain.com/rails-api-3/REST_ROUTES
www.domain.com/rails-api-4/REST_ROUTES

Problem Faced

Now the problem was when we try to access sidekiq webs with these namespace routes. It does not load rails assets because namespace path ‘rails-api-1 ’ is not considered in the root path, and sidekiq tries to find assets in the path `www.domain.com/sidekiq/` and it doesn’t exist actually.

Solution

Initially, we mounted sidekiq path in config/routes.rb like this.

mount Sidekiq::Web => '/sidekiq'

Later, we changed it to

mount Sidekiq::Web => '/rails-api-1-sidekiq'

Configuration for Traefik:

You need to add a new rule in docker labels

Key => traefik.sidekiq.frontend.rule 
Value => Host:www.domain.com;PathPrefix:/rails-ap1-1-sidekiq

Configuration for Nginx:

If you are using Nginx as a reverse proxy then you need to add these configuration for each service.

location /rails-ap1-1-sidekiq/ {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://your_domain/rails-ap1-1-sidekiq/;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
  }location /rails-ap1-2-sidekiq/ {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://your_domain/rails-ap1-2-sidekiq/;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
  }

Now you can access your sidekiq web at

https://www.domain.com/rails-api-1-sidekiq/retries

After that Sidekiq will look for assets in path /rails-api-1-sidekiq/. Here as per docker label rails-api-1-sidekiq indicates that it will point to the container rails-api-1 because it is configured forrails-api-1task and within that container, it will look for the assets in /rails-api-1-sidekiq/.path, You can see in below image

Similarly, you can setup multiple sidekiq on your reverse proxy.

Thank you!

Posted in General, Ruby on Rails | Leave a comment

Building Decentralised Link Shortner on Ethereum blockchain using Truffle

Original post available here.

Blockchain is emerging technology, it needs no introduction. By any chance if you are left behind and don’t know about blockchain then I recommend reading about blockchain first before reading this article. You can read about blockchain here or here or search on internet and you will find plenty of article to read from.

What is Ethereum ?

Launched in 2015, Ethereum is the world’s leading programmable blockchain. It is a global, open-source platform for decentralized applications. These decentralized applications (or “dapps”) gain the benefits of cryptocurrency and blockchain technology. Read more about ethereum here.

What is Truffle ?

Truffle is a framework for blockchain development, it streamlined smart contractcreationcompilationtesting, and deployment onto Ethereum. Read more about truffle here

What is Decentralised App ?

Decentralised application does not require centralised server to work (hence no maintenance cost). It interacts with smart contract deployed on blockchain network.

What is Smart Contract ?

Smart contracts are programs which govern the behaviour of accounts within the Ethereum state. We will write smart contract in Solidity language, Solidity is an object-oriented, high-level language for implementing smart contracts. Read more about solidity from here.

Getting Started:

A) Install npm, node & Truffle

Follow https://docs.npmjs.com/downloading-and-installing-node-js-and-npm for installing npn & node.

Then install truffle

npm install -g truffle

check if truffle installed successfully or not

$ truffle version
Truffle v5.0.21 (core: 5.0.21)
Solidity v0.5.0 (solc-js)
Node v11.0.0
Web3.js v1.0.0-beta.37

B) Create Project

Create new folder for project & initialise with truffle. We will use React Truflle box

$ mkdir link_shortner
$ cd link_shortner/
$ truffle unbox react
✔ Preparing to download
✔ Downloading
✔ Cleaning up temporary files
✔ Setting up box
Unbox successful. Sweet!
Commands:
Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test

If you are new to Truffle then read about created directory from https://www.trufflesuite.com/docs/truffle/getting-started/creating-a-project

C) Install Ganache for blockchain setup on local machine https://www.trufflesuite.com/docs/ganache/overview


Link Shortner Smart Contract

Create LinkShortner.sol file inside contracts/ folder and write following content in it.

pragma solidity ^0.5.0;

contract LinkShortner {
  event LinkAdded(uint linkId, string url);
  uint lastLinkId;
struct LinkTemplate {
  address userAddress;
  string url;
 }

mapping (uint => LinkTemplate) public linkMapping;
constructor() public {
  lastLinkId = 0;
 }

function createNewLink(string memory url) public returns (uint, string memory) {
   lastLinkId++;
  linkMapping[lastLinkId] = LinkTemplate(msg.sender, url);
    emit LinkAdded(lastLinkId, url);
  return(lastLinkId, url);
 }

function getLink(uint linkId) public view returns(address, string memory) {
  LinkTemplate memory link = linkMapping[linkId];
  return(link.userAddress, link.url);
 }

function getLastLink() public view returns(address, string memory, uint) {
  LinkTemplate memory link = linkMapping[lastLinkId];
  return(link.userAddress, link.url, lastLinkId);
 }
}


Now deploy this contract on local blockchain network:


$ truffle compile
$ truffle migrate
Ganache Screenshot after contract deployment

React Application for interaction with Smart Contract

Open client/src/App.js file & Replace

import SimpleStorageContract from"./contracts/SimpleStorage.json";

with

import SimpleStorageContract from "./contracts/LinkShortner.json";

Creating new link

contract.methods.createNewLink(this.state.url).send({ from: accounts[0] })

Install Metamask chrome extension

and run React app

cd client
npm run start

Deploying contract on Ropsten test network

- Register new account on infura.io
- Create new project
- Get project api and connection link:
ROPSTEN_URL=https://ropsten.infura.io/v3/<your-api-key>

Goto Truffle project, install truffle-hdwallet-provider

npm install truffle-hdwallet-provider — save

Create `.env` file, put MNEMONIC and <network>_URL to file

MNEMONIC=wallet mnemonic 12 words
ROPSTEN_URL=https://ropsten.infura.io/v3/<your-api-key>

Update truffle-config with following content

const path = require("path");
require('dotenv').config()
const HDWalletProvider = require('truffle-hdwallet-provider')
const MNEMONIC = process.env.MNEMONIC
const ROPSTEN_URL = process.env.ROPSTEN_URLmodule.exports = {
  // See <http://truffleframework.com/docs/advanced/configuration>
  // to customize your Truffle configuration!
  contracts_build_directory: path.join(__dirname, "client/src/contracts"),
  networks: {
    ropsten: {
      provider: function() {
        return new HDWalletProvider(MNEMONIC, ROPSTEN_URL);
      },
      network_id: '3',
    },
    development: {
      host: "127.0.0.1",
      port: 7545,
      network_id: "*",
   },
   test: {
     host: "127.0.0.1",
     port: 7545,
     network_id: "*",
  }
 }
};

Run following command to deploy

truffle migrate --network ropsten

Sinatra API for reading Short Link on ethereum network

Create folder backend
Add following content in backend/app.rb

# Require the bundler gem and then call Bundler.require to load in all gems
# listed in Gemfile.
require 'bundler'
Bundler.require

require 'sinatra'

require 'ethereum'before do
  content_type 'application/json'
end

class Contract
  def initialize
    @client = Ethereum::HttpClient.new("https://ropsten.infura.io/v3/<API-KEY>")
    contract_json = JSON.parse(File.read('LinkShortner.json'))
    @contract_abi = contract_json['abi']
    @address = contract_json["networks"]["3"]["address"]
    @client.default_account = "0x3b8B0b23C4850FA8289da815a6abEE4Fc2DF941A"
  end

  def result(id)
    return nil unless id
    contract_instance.call.get_link(id.to_i)[1]
  enddef contract_instance
    Ethereum::Contract.create(name: "LinkShortner", address: @address, abi: @contract_abi,
                              client: @client)
  end
end

class App < Sinatra::Base
  get '/url' do
    response.headers["Access-Control-Allow-Origin"] = "*"
    return {url: Contract.new.result(params[:id])}.to_json
  end
end

Deploy sinatra API on heroku

heroku create
heroku buildpacks:set https://github.com/timanovsky/subdir-heroku-buildpack
heroku buildpacks:add heroku/ruby
heroku config:set PROJECT_PATH=backend
git push heroku master

Now use deployed API for reading short link

fetch("https://<heroku-app-url>/url?id="+id).then((response) => {
  return response.json();
}).then((response) => {
  const url = response.url
  console.log(url)
})

That’s it, now you have your link shortner decentralised app deployed on ethereum network. Generated short link can be shared with anyone, irrespective of browser. For creating short link Metamask plugin is required.

Code is hosted on github

Application is hosted at http://anilmaurya.github.io/link-shortner

Demo of Link Shortner

References:


https://medium.com/@nhancv/deploy-smart-contract-with-truffle-79d2bf218332

https://hackernoon.com/making-a-decentralized-url-shortener-using-ethereum-4fdfccf712a6

Posted in Blockchain, Tutorials | Tagged , , , | Leave a comment

An Efficient way to manage API calls with RxRetrofit

Prologue

Android is becoming popular day by day and thousands of apps are being published on Play Store. To survive in this competition, the User experience matters a lot. The app crash is the worst User experience, in other words we can say 1 billion dollar mistake. So I am going to explain how to use RxRetrofit efficiently to make API calls.

Problem

The most common mistake made by the Android developer is while making an API call and not handling the fact that the user can exit the app or press the back button, before the API call returns. The result is app crash!

In more detail, when an API is hit, that network call is being performed on the background thread and based on response the UI needs to be updated in UI thread. Now, when the background thread is running and the back button is pressed, the current screen (Activity or Fragment) will be popped out from the stack. After this when data is received from the API and an attempt to update the UI will result in a crash as the current screen (Activity or Fragment) will not be in the stack.

Solution

Make API calls using RxRetrofit !!

Example

RetrofitApiClient.createService(ApiInterface::class.java)
   .callLoginApi(“email”,”password”)
   .observeOn(AndroidSchedulers.mainThread()) // On UI thread
   .subscribeOn(Schedulers.io()) // On background thread 
   .subscribe({ response -> // On Success 

         // App will crash on the below line
         editTextOtp.setText(response?.body()?.otp)
         buttonLogin.setText("Verify OTP")

   }, {
       // On Error (Could not reach to the server)
   })

According to the above example, when you hit the Login API and immediately press the back button (Activity or Fragment removed from the stack) then you get the response from the API in the subscribe() method, you try to update the UI and the app will crash!

Use the Disposable interface of the RxJava which is used with RxRetrofit.

See the below example :

public interface Disposable {
   void dispose();  // Dispose the resource or an operation.
   boolean isDisposed(); // Returns true if this resource has been disposed.
}


Let’s implement it in the above example,

1) private var disposableLoginAPI: Disposable? = null // Globally
2) 
disposableLoginAPI = 
RetrofitApiClient.createService(ApiInterface::class.java)
   .callLoginApi(“email”,”password”)
   .observeOn(AndroidSchedulers.mainThread()) // On UI thread
   .subscribeOn(Schedulers.io()) // On background thread 
   .subscribe({ response -> // On Success 

         editTextOtp.setText(response?.body()?.otp)
         buttonLogin.setText("Verify OTP")

   }, {
       // On Error (Could not reach to the server)
   })

The subscribe() returns disposable so initialize the disposable with it.

3) override fun onStop() {
   super.onStop()

     // If it's not disposed then dispose  
    if (disposableLoginAPI?.isDisposed == false) {
         disposableLoginAPI?.dispose() // Magic!
    }  
} 

So once you are about to leave the screen (Activity or Fragment), in the onStop() method, dispose() method will dispose the API call and there will be no response in the subscribe() method, so UI will not be updated and the app will not crash.

For Multiple API calls

You can use CompositeDisposable to add multiple disposable objects:

val listOfDisposables=CompositeDisposable() // Init object

//Adding multiple disposables
listOfDisposables.add(disposableLogin!!)
listOfDisposables.add(disposableForgotPassword!!)

And finally dispose in the onStop() method.

override fun onStop() {
   super.onStop()

   listOfDisposables.dispose()  // Dispose all the disposables 
} 

Happy Coding!

Posted in General | Tagged , , | Leave a comment

AWS EC2: Increase volume size on the fly (Using AWS Management Console)

As time passes the production requirements grow. This happens all the time and recently again it happened and I got an alert from Nagios telling me that disk space is getting full. I immediately checked the server to find out what is consuming space!!

Initially, I thought, perhaps unnecessary files are consuming the space. I can just delete those files and get rid of the problem. But on checking it turned out that everything was important to keep in the EBS (Elastic Block Store) volume and nothing can be deleted.

The only solution was to increase the volume size. Thankfully it is AWS. They have enhanced the console to a great extent and increasing the volume size is a piece of cake now. Here are the simple steps:

1) Check the exact volume size which is initially their with ‘lsblk’.

 nvme0n1     259:0    0   50G  0 disk  
 └─nvme0n1p1 259:1    0   50G  0 part / 

This is the exact size of my volume it means 50 GB is available and it is using the exact 50 GB

To increase the volume size follow the below steps:

2) Login to your aws console and than go to the volumes in your EC2 dashboard and find the volume which you want to increase.

3) Select the volume and then click on the ‘Actions’ -> ’Modify Volume’ .

4) Increase the volume size edit the field and enter the new volume size (In my case i want to increase it to 60 GB).

5) Click on the ‘Modify’ button then you can see it will be reflacted to your aws console within a minute but it will be not in use until ‘reboot’.

6) Login to your server and check with ‘lsblk’ you will get to see output as below.

nvme0n1     259:0    0   60G  0 disk  
└─nvme0n1p1 259:1    0   50G  0 part /

Note: This denotes that disk size is 60 GB and 50 GB is allocated to nvme0n1p1.

7) Now to allocate 60 GB to nvme0n1p1 reboot your instance.

CAUTION: While rebooting the instance it will down your service.

8) After rebooting its done now you can check with ‘df -h’. You will see partition is using 60 GB.

/dev/nvme0n1p1   59G  24G   35G  42% /
Posted in General | Leave a comment

Deploy Digital Certificates to the iOS System keychain Store

Content posted here with the permission of the author Amit Dhadse, who is currently employed at Josh Software. Original post available here.

iOS devices became widely used in an enterprise level daily-work now a days, due to this we need to have guaranteed secure communications between device and associated enterprise services.

So question raise about enterprise environment security which can be covered with the help of VPN or any other third party tool. Actually what VPN does is creating secure tunnel between identity device and service which is hosted on cloud or on partner networks.

Thats one part of accessing enterprise service but what if we don’t want to use any VPN client and still wants to access enterprise service from any device in our case we are taking iOS device.One way of doing that is using digital certificates to encrypt/decrypt, sign and authenticate communications and data.So how we can use certificate on iOS device at system level so that iOS can use that certificate while consuming services. Advantage of this over VPN is, User has login every time on VPN Client to consume services where as deploying certificate on iOS device is one time activity and it will work all along till User removed certificate.

ssl-certificate

I have been asked to create an iOS app to request and deploy digital certificates in device system keychain so that, it will be recognised by all system apps of iOS while accessing enterprise services. After doing my research I concluded that in iOS devices there are two types of certificate keychain stores:

  • App certificates keychain store:
    • This keychain store embedded  in app space and can be used by that app only.(Not exposed at system level)
    • Apple offer APIs to Insert/Delete/Update certificate
  • System certificate keychain store:
    • This keychain is exposed at system level. This store located in Setting -> General -> Profiles used for VPN and wifi networks
    • Apple does not offer any API to deploy/retrieve certificates from the system certificate keychain store (Profiles).

So there are four ways to deploy certificates to system certificate keychain store (not programmatically):

  1. Configuration Profiles: Pre-configured profiles that used to distribute settings.(These can be created on MAC and deploy in iOS device)
  2. Using Simple Certificate Enrolment Protocol (SCEP): this protocol enables Over-the-Air Enrolment of digital certificates, mainly used for routers and switches.
  3. Email Attachment: send the certificate from a desktop or mac to iOS device as an email attachment. Open this attachment(certificate) in iOS mail client ( having system privileges ). It will automatically ask you for installation. 
  4. Using Safari: browse the certificate using Safari. Safari has system privileges over normal UIWebView.

After I did my research I found a workaround that worked for me to deploy a certificate to the System Certificate Store from Xcode directly.

Here’s what you will need to do, first, to create a web-server inside your App, then save the certificate in this web-server and open it’s URL.

When the page launches, Safari will recognize that it’s a certificate, then the System Profiles will pop up and ask the user to install the certificate. After the user install the certificate it will be saved to the Profiles and the certificate can be used in the System level.

To create web server inside iOS app, there are 2-3 libraries are available on Git. I recommend “GCDWebserver” library to create web server due to its easy implementation, background support and most important it is stable.

How to use GCDWebserver :-

    let localServer = GCDWebDAVServer(uploadDirectory: path)
    localServer?.start(withPort: 8080, bonjourName: nil)
    let url = localServer?.serverURL
    UIApplication.shared.open(url)
    • Here “path” is your certificate path(in my case it was document directory path as my certificate was store in document directory(NSDocumentDirectory) folder).
    • “serverURL”  will return URL of certificate which is hosted on local server.
    • Open this URL on safari, Safari recognise that it is certificate and pops an installation alert automatically.

Note :-  Now in this scenario here is one problem, as soon as user open URL in safari, user were no longer in app all control is shift to safari and to comeback in app, user has to do manually.

 Solution :- import “SafariServices” framework which already have a safari view in it which opens safari inside your app.

I spent a lot of time and research efforts to reach upto this solution, I hope someone surly will get benefit from my results. Please contact me for any question.

Posted in General | Tagged , , , , , , | Leave a comment

Adding SSL certificate to Traefik on ECS

Content posted here with the permission of the author Anil Kumar Maurya, who is currently employed at Josh Software. Original post available here.

Traefik is awesome reverse proxy & load balancer. If you are not using Traefik already then I recommend using it in your next project. I can guarantee that you will not regret.

Setting up SSL certificate on Traefik is a cakewalk. While adding SSL on traefik, I realised how it outshine other reverse proxy (Nginx , HAProxy).

Traefik use LetsEncrypt to automatically generate and renew SSL certificates.

Dockerfile

FROM      traefik:v1.7-alpine

COPY      traefik_ecs.toml /etc/traefik/traefik.toml
RUN touch /etc/traefik/acme.json
RUN chmod +x /etc/traefik/acme.json

traefik_ecs.toml

defaultEntryPoints = ["https", "http"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]
  [entryPoints.bar]
  address = ":8080"

[api]
entryPoint = "bar"
dashboard = true

[ecs]
clusters = ["YOUR_ECS_CLUSTER_NAME"]
watch = true
domain = "YOUR_DOMAIN_NAME"
autoDiscoverClusters = false
refreshSeconds = 15
exposedByDefault = true
region = "YOUR_AWS_REGION"
accessKeyID = "YOUR_AWS_ACCESS_KEY_ID"
secretAccessKey = "YOUR_AWS_SECRET_ACCESS_KEY"
[acme]
email = "YOUR_EMAIL"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
[acme.httpChallenge]
entryPoint = "http"

Replace YOUR_* values with actual, build image using Dockerfile and deploy it on ECS. That’s it, Traefik will take care of rest and SSL certificate will be added to your domain. Isn’t Traefik awesome ? Let me know what you think through comments below.

References:

  1. https://www.smarthomebeginner.com/traefik-reverse-proxy-tutorial-for-docker/
  2. https://blog.networkprofile.org/my-traefik-reverse-proxy-setup/
  3. https://github.com/netbears/traefik-cluster-ecs

 

Posted in General | Tagged , , | Leave a comment