Setup new asterisk server through SimpleTrunk

In this article, I will demonstrate the required steps to configure new asterisk server.

Prerequisites:

  • Ubuntu 18.04
  • Asterisk version 13 installed
  • SimpleTrunk
  • goagent running in the same server

If you do not have simpleTrunk and goagent, you can use nano, but you should have access to the server with sudo privileges.

First, you will have to add the asterisk server to simpleTrunk

In simpleTrunk home page, click insert new pbx, and you will be redirected to the below page:

Enter the above parameters where:

  • Title is the name will appear in the simpleTrunk list
  • Config file name is the name of the .stc file
  • Agent URL is the URL of the goagent web service

Then choose username and password for AMI (remember them, because we will need them later)

Then click on the add button.

In the main page, you will now see the new asterisk server, click on it.

From the main menu, choose Files, then from the sub menu choose All Files

First we will configure manager.conf file:

Add the following lines:

webenabled = yes

[user]

secret = secret

permit=127.0.0.1/255.255.255.0

permit=0.0.0.0/255.255.255.0

read = system, call,log, verbose, command, agent,user, config, command, dtmf, reporting,cdr,dialplan,originate

write = system,call,log, verbose, command, agent, user, config, command, dtmf, reporting, cdr, dialplan, originate

writetimeout = 5000

where user is the AMI user, and secret is the AMI password

In the above image, the name between the [] is the AMI username that you chose previously, and the secret ins the AMI password.

Save the file and go to All Files.

You can also change the above file through server using nano, the file is:

/etc/asterisk/manager.conf

Next, we will go to http.conf (/etc/asterisk/http.conf)

Add/uncomment the following lines: (make sure to add them under the [general] context)

enabled=yes
webenabled=yes

bindport=8088

sessionlimit=1000

enablestatic=yes

Save and exit.

Next, go to sip.conf (/etc/asterisk/sip.conf)

Change the option “tcpenable=no” to “tcpenable=yes” to allow tcp connection.

Save and exit.

Next, from the main menu, go to CLI commands, then choose core reload from the sub menu.

You can do this from the server (if you do not have simpleTrunk) through the following commands:

$ sudo asterisk -rvv

$ core reload

And now, asterisk has been setup successfully.

FreeRADIUS with REST

Introduction

Starting from FreeRADIUS v3.x, FreeRADIUS has added support to REST API.

This article will talk about how to configure FreeRADIUS to make authentication by connecting to a remote server using REST.

Prerequisite

Make sure you have Ubuntu 16.04 or higher with FreeRADIUS v3.x installed, but alternative is to upgrade FreeRADIUS independently of Ubuntu version.

Also make sure you have configured your clients.conf file and added your network access server.

Configurations

Open the terminal, and enable root mode using the following command:

$ sudo su

Then go to FreeRADIUS folder using “cd” command:

$ cd /etc/freeradius

If you are in Ubuntu 18.04, then use this command:

$ cd /etc/freeradius/3.0

Use ls command and you will get all the folders in FreeRADIUS.

mods-available folder contain all the modules provided by FreeRADIUS, and mods-enabled folder contains the enabled modules that the FreeRADIUS server will use.

We will use the rest module to configure FreeRADIUS to work with REST.

To use the rest module, we have to enable it first.

To enable it we have to make a soft link of it in mods-enabled folder.
This is done using the following commands:

$ cd mods-enabled
$ ln -s ../mods-available/rest

Now, we will configure the rest module.

$ nano rest

First, replace connect_uri with your HTTP domain.

connect_uri = "http://localhost:8084/RestForRadius"

Then, replace authorize{} section with the below configurations

authorize {
uri = "${..connect_uri}/authorize"
method = 'post'
tls = ${..tls}
body = 'json'
data = '{ "username": "%{User-Name}", "password": "%{User-Password}", "calling-station-id": "%{Calling-Station-Id}" }'
}

Where “authorize” is the name of the web service responsible for authorization.

Also replace the authenticate{} section with the below configurations

authenticate { 
uri = "${..connect_uri}/authenticate"
method = 'post'
body = 'json'
data = '{ "username": "%{User-Name}", "password": "%{User-Password}", "calling-station-id": "%{Calling-Station-Id}" }'
tls = ${..tls}
}

Where “authenticate” is the name of the web service responsible for authentication.

Save the changes and close the rest module.

The next step is to configure the virtual server.
There are two virtual servers enabled: default, and inner-tunnel.

We will configure them both with the same configurations.

Go to /etc/freeradius/sites-enabled and run the following command

$ nano default

This file represent the configurations for the default server.

Go to the authorize{} section and add rest as below:

authorize {
...

rest

...
}

Do the same with authenticate{} section.

authenticate {
...

rest

...
}

Save and exit.

Do the same to inner-tunnel server file.

Now we will start FreeRADIUS in debug mode. Make sure that your remote server (connect_uri) is up and accessible or you will get an error.

$ freeradius -X

If you get Ready to process requests then you have configured it successfully.

References

http://system-eng.blogspot.com/2016/09/sending-freeradius-accounting-data-to.html

https://stackoverflow.com/questions/43698251/freeradius-3-0-13-rlm-rest-restful-api-authentication


JSON Web Tokens (JWTs)

JSON Web Token is an open standard that defines a compact and self-contained way for securely transmitting digitally signed information between parties as a JSON object.

Compact: it can be sent through an URL, POST parameter, or inside an HTTP header.

Self-contained: the payload has all the necessary information about the user.

Structure of JWT

JWTs contain three parts separated by a dot(.) and they are:

  • Header
  • Payload
  • Signature

So the JWT look like this:

hhhhhhhh.pppppppp.sssssssssss

Each part is Base64url encoded.

Header

The header usually has two parts:

  • The type of the token
  • The hashing algorithm used in signing the token

The image below shows an example of a header

alg: is the algorithm used for signing the token, and here it is the HMAC SHA256
typ: is the type of the token which is always JWT

Payload

The second part of the JWT. It contain claims, which are information about an entity and other data.

Claims are three types: registered (predefined claims), public (User defined), and private(custom claims used to share information between parties).

The image below present an example of a payload

The information contained in the payload are protected against tampering and modification, but they can be read by anyone because they are encoded not encrypted. So you should not put any secret information in the payload unless you encrypt them.

Signature

The signature is the third part of the JWT. it can be created by taking the base64 encoded header, the base64 encoded payload, a secret, the algorithm specified in the header and sign that.

Example:

{
HMACSHA256 (base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret)
}

The algorithm used in the previous example is the HMAC SHA256.

An Asymmetric hashing algorithm with a public/private key pair can also be used like RSA.

How JWT work

The image below describes how the JWT is used in authentication.

Implementation

There are libraries for implementing JWT in many different programming language. Every programming language has multiple libraries, and they differ in the syntax.

Java JWT example

The code below show how JWT can be created and verified. The library used in this example is jjwt. The signing was done using RS256 algorithm.

// import the necessary packages
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys

// specifying the algorithm and the public/private key pairs
KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256)

// creating the signed JWT
String jws = Jwts.builder()
.setHeaderParam("typ", "JWT")
.claim("Name", "Najy")
.claim("admin", true)
.signWith(keyPair.getPrivate())
.compact();




// Verifying the JWT
try{
Jws jws1;
jws1 = Jwts.parser()
.setSigningKey(keyPair.getPublic())
.parseClaimsJws(jws);
out.println("Signature verified, The JWT can be trusted");
out.println("Header: " + jws1.getHeader());
out.println("Payload: " + jws1.getBody());

} catch (Exception ex){ // in case JWT was altered
  out.println("Error: " + ex.getMessage());
}

References

https://jwt.io/introduction/

https://auth0.com/learn/json-web-tokens/

https://en.wikipedia.org/wiki/JSON_Web_Token

https://github.com/jwtk/jjwt

Couchbase

Couchbase Server  is an open source NoSQL document based database that is optimized for interactive web applications. It provides programmatic access to Couchbase server through the SDKs of the different programming languages.

It has a query language known as N1QL, which has a structure composed of statements, expressions, and comments.

Installation

To install latest version of Couchbase in Ubuntu 16.04 (xenial):

First, download Couchbase server from here. Make sure you choose ubuntu 16.04 as the operating system.

Then reload the local package database.

Install Couchbase Server using the following command:

where ./ is the path to the Couchbase server package and * is the version of the package that you have downloaded.

If dpkg reports any errors about missing dependencies, run the following command to download and install them:

Once installation is complete, Couchbase Server will start automatically.

Getting started with Couchbase

Open this link to access the Couchbase Server Web Console.

Enter the username and password that you have provided during installation and click sign in.

Cluster Dashboard

After signing in successfully, you will be forwarded to Cluster Dashboard.

The Cluster Dashboard provides a graphical summary of the current state of your Couchbase cluster.

Click on Buckets in the left-hand navigation bar to go to the bucket screen. On the bucket screen, click on “Add Bucket” to add a new bucket.

Give it a name and determine memory quota then click “Add Bucket”

After adding a bucket, go to “Query” screen to create primary index for your bucket. Use the following query:

CREATE PRIMARY INDEX ON `bucket_name` USING GSI;

Replace `bucket_name` with the name that you have given to your bucket. Then Execute.

You have successfully created your first bucket.


Using Java SDK with a java application

First, download Java SDK from here.

Then extract the zip file and add the following jars to your project:

  • couchbase-java-client:2.6.2
  • couchbase-core-io:1.6.2
  • rxjava:1.3.7
  • opentracing-api:0.31.0

The code segment below describes how the Java SDK can be used for some common operations (described in comments):

import com.couchbase.client.java.*; import com.couchbase.client.java.document.*; import com.couchbase.client.java.document.json.*; import com.couchbase.client.java.query.*;

public class Example {
  public static void main(String[] args) throws Exception {

// Initialize the Connection
  Cluster cluster = CouchbaseCluster.create("localhost");
cluster.authenticate("username", "password"); Bucket bucket = cluster.openBucket("bucketname");


// Create a JSON Document JsonObject arthur = JsonObject.create() .put("name", "Arthur") .put("email", "kingarthur@couchbase.com") .put("interests", JsonArray.from("Reading", "Sport"));

// Store the Document bucket.upsert(JsonDocument.create("u:king_arthur", arthur));


// Load the Document and print it
// Prints Content and Metadata of the stored Document
System.out.println(bucket.get("u:king_arthur"));


// Create a N1QL Primary Index (but ignore if it exists) bucket.bucketManager().createN1qlPrimaryIndex(true, false);


// Perform a N1QL Query
N1qlQueryResult result = bucket.query(N1qlQuery.parameterized("SELECT name FROM `bucketname` WHERE $1 IN interests", JsonArray.from("Sport")));

// Print each found Row
for (N1qlQueryRow row : result) {

// Prints {"name":"Arthur"}
System.out.println(row);

   }
  }
}

References

https://docs.couchbase.com/server/current/install/ubuntu-debian-install.html

https://docs.couchbase.com/server/current/manage/manage-buckets/create-bucket.html

https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/createprimaryindex.html

https://docs.couchbase.com/java-sdk/2.7/start-using-sdk.html