1.0.4 • Published 4 years ago

security-server v1.0.4

Weekly downloads
4
License
-
Repository
-
Last release
4 years ago

Docker image for the security server

This repo contains the source for the security server. It is based on a simple NodeJS express server.

About the security server

The security server has two functions:

  1. It should make it difficult to start the content without having the right access
  2. It should make it difficult to copy the content and move it to another server

To help with this the security server requires the origin to be from *.contentservice.net, *.contentservice.cn or localhost for the security check to succeed.

Security check end point

The url for the endpoint is:

"server.hostname/security_check?session={session}&hash={{hash}}&nr={{nr}}&version={{version}}"

The {session} and {hash} are the values forwarded from the Hyper player. Instead of the two argumens it is also possible to pass both in one called security_token. The security_token is the {session} and {hash1} seperated with a pipe: '|' The {nr} should be a random string. The {nr} is also used to validate the response. The {version} must be "1.0", and it is optional.

The endpoint will return:

    {
        "result": {{result}}
        "hash": {{hash2}}
        "comment": {{comment}}
    }

All 3 fields might be missing. The {{comment}} text is something that can be used for debugging.

The {{result}} is "OK" if the check was correct. It is something else if the check fails.

The {{session}}, {{result}}, and {{nr}} should be used to calculate an MD5 check, the MD5 hash can be verifyed with the {{hash2}} value. See below for example code (prior to this Hyper.Bridge.instance().open() should have completed):

function securityCheck()
{
    const readonly = Hyper.Bridge.instance().getvalue("_readonly");
    if (readonly)
    {
        if (readonly.security_token)
        {
            const nr = Math.random();
            const url = "server.hostname/security_check?security_token=" + readonly.security_token + "&nr=" + nr;
            return fetch(url)
            .then( response => {
                if (!response.ok)
                {
                    return Promise.reject(new Error("Security server error, got: " + response.status + " " + response.statusText));
                }

                return response.json();
            })
            .then( json => {
                if (json.result === 'OK')
                {
                    const check = md5("Debriefing Protocol///Verify Session response///" +
                    args["security_token"].split("|")[0] + "///" + json.result + "///" + args["nonce"]);

                    if (check.substring(0, 8).toUpperCase() !== json.hash.toUpperCase())
                    {
                        return Promise.reject(new Error("Security error"));
                    }
                }
                else
                {
                    return Promise.reject(new Error("Security error"));
                }
            });
        }
        else
        {
            return Promise.reject(new Error("Missing security_token"));
        }
    }
    else
    {
        return Promise.reject(new Error("Missing _readonly property"));
    }
}

There is also an xml version for legacy applications at

"server.hostname/SecurityCheck.aspx?session={session}&hash={{hash}}&nr={{nr}}&version={{version}}"

This end point returns an xml structure of the same data.

Configuration

The expiry time of a session can be configured by setting the EXPIRE_MINUTES environment variable.

Metrics and health

There is a Prometheus formatted metrics endpoint at

"server.hostname/metrics"

It currently returns these metrics:

  • up (gauge): 1 = up, 0 = not up (ie. should always be 1)
  • JSONRequests (counter): Number of requests to the JSON endpoint
  • XMLRequests (counter): Number of requests to the XML endpoint
  • TotalRequests (counter): Total number of security check requests
  • TimedOutRequests (counter): Number of failed security check requests due to timeout
  • TotalFailedRequests (counter): Total number of failed security check requests
  • RequestTimings (histogram): Histogram of (internal) time-to-reply for security check requests

There is also a health check endpoint at

"server.hostname/health"

This is for use with the Kubernetes liveness check (see https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/).

Building the image

docker build . -t registryname/image_name

Testing

docker run --rm -p 8080:80 -d registryname/image_name

The server will now be reachable at port 8080 (it will map the containers port 80 to port 8080 on the host). To stop it again, get the container ID from docker ps and run docker kill container_id.

Pushing to azure

Login (only has to be done once): docker login registryname You can find the login credentials via the Azure portal.

Pushing: docker push registryname/image_name

Example Kubernetes configuration file

There is an example of a Kubernetes deployment configuration file in k8s-example-deployment-config.yml. Simply correct the image link and imagePullSecrets fields to the correct values and it should work.