Infisign Network Access Gateway (NAG): Pre-requisites and Installation Documentation
Server Requirements: Staging Server Requirements for NAG
Server -1
CPU - 4
Memory -16 GB
Storage - 25 GB
OS -Ubuntu/RHEL
Server Requirements: Production Server Requirements for NAG
Server-1
CPU - 4
Memory -32 GB
Storage - 100 GB
OS -Ubuntu/RHEL
Server-2
CPU - 4
Memory -32 GB
Storage - 100 GB
OS -Ubuntu/RHEL
Load Balancer Server-3
CPU - 2
Memory -4 GB
Storage - 25 GB
OS -Ubuntu/RHEL
Load Balancer Server-4
CPU - 2
Memory -4 GB
Storage - 25 GB
OS -Ubuntu/RHEL
Appendix - Manual Installation Steps
Env file
.env
MONGO_INITDB_ROOT_USERNAME=infisignroot MONGO_INITDB_ROOT_PASSWORD=FVYG4hkj321cf89cyvu5678HJGFC67iOfdbffeae0a65d MONGO_DB_CONNECTION=mongodb://infisignroot:FVYG4hkj321cf89cyvu5678HJGFC67iOfdbffeae0a65d@nag_db:27017/
docker-compose_template.yaml
Save this file as a docker-compose_template.yaml
Command to save the file - vi docker-compose_template.yaml
version: "3.4"
services:
db:
image: mongo:4.4-bionic
environment:
- MONGO_INITDB_ROOT_USERNAME=infisignroot
- MONGO_INITDB_ROOT_PASSWORD=FVYG4hkj321cf89cyvu5678HJGFC67iOfdbffeae0a65d
ports:
- "27018:27017"
volumes:
- db:/data/db
- ./config/mongo/mongod.conf:/etc/mongod.conf
backendapp:
image: infisign/infisign-nag:admin-latest
command: bash /app/docker-entrypoint.sh
environment:
- API_HOSTNAME=https://app.infisign.net/
- SSO_HOSTNAME=<mydomain>/sso/verify
- INFISIGN_NAG_SUBSCRIPTION_KEY=test
- INFISIGN_NAG_URL_IDENTIFIER=test
- INFISIGN_NAG_TENANT_ID=test
- SENTRY_ENV=<nag_envname>
- BACKEND_IMAGE=infisign/infisign-nag:admin-latest
- SSO_IMAGE=infisign/infisign-nag:sso-latest
- FRONTEND_IMAGE=infisign/infisign-nag:mfe-latest
- DIRECTORY_IMAGE=infisign/infisign-nag:dir-latest
- SCHEDULED_TIME=22:00
- MONGO_DB_CONNECTION=mongodb://infisignroot:FVYG4hkj321cf89cyvu5678HJGFC67iOfdbffeae0a65d@nag_db:27017/
- IS_MULTI_INSTANCE=false
- SENTRY_ENABLED=true
ports:
- "8001:8001"
depends_on:
- db
directory:
image: infisign/infisign-nag:dir-latest
environment:
- BASE_URL=<mydomain>
- SENTRY_ENV=<nag_envname>
- SENTRY_ENABLED=true
ports:
- "8082:80"
frontend:
image: infisign/infisign-nag:mfe-latest
environment:
- DOMAIN_URL=<mydomain>
- API_ENDPOINT=<mydomain>
- SSO_URL=<mydomain>/sso/verify
- SENTRY_ENV=<nag_envname>
- SENTRY_ENABLED=true
ports:
- "8081:80"
sso:
image: infisign/infisign-nag:sso-latest
environment:
- DOMAIN_URL=<mydomain>
- DEV_ENDPOINT=<mydomain>
- SOCKET_URL=<mydomain>
- SENTRY_ENV=<nag_envname>
- SENTRY_ENABLED=true
ports:
- "8080:80"
os:
image: infisign/infisign-nag:os-staging
ports:
- "8010:8010"
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./config/nginx/:/etc/nginx/conf.d
depends_on:
- backendapp
- frontend
- sso
- directory
- os
volumes:
db:
name: db-infisign
external: false
Note; Update the value of INFISIGN_NAG_SUBSCRIPTION_KEY and INFISIGN_NAG_URL_IDENTIFIER
Update OTHER_INSTANCES=http://otherinstanceip
Add secondary instance ip in primary instance conf and primary in secondary ip instance conf
docker-compose.yaml file creation
File needs to be created on the server.
Create a new folder in the name of config using the following command.
mkdir config
open the config folder and create two new folders mongo and nginx.
Open the folder mongo.
Create a file in the name of mongod and paste the below script.
# mongod.conf # for documentation of all options, see: # http://docs.mongodb.org/manual/reference/configuration-options/ # Where and how to store data. # storage: # dbPath: /var/lib/mongodb # journal: # enabled: true # engine: # mmapv1: # wiredTiger: # where to write logging data. # systemLog: # destination: file # logAppend: true # path: /var/log/mongodb/mongod.log # network interfaces net: port: 27017 bindIp: 0.0.0.0 # how the process runs # processManagement: # timeZoneInfo: /usr/share/zoneinfo #security: #operationProfiling: #replication: #sharding: ## Enterprise-Only Options: #auditLog: #snmp:
Open the folder nginx.
Create a file in the name of nginx_template and paste the below script.
upstream backendapp {
server backendapp:8001;
}
upstream frontend {
server frontend:80;
}
upstream sso {
server sso:80;
}
upstream os {
server os:8010;
}
upstream directory {
server directory:80;
}
server {
listen 80;
server_name <myip>;
location /nag {
proxy_pass http://backendapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /directory{
proxy_pass http://directory;
}
location / {
proxy_pass http://frontend;
}
location /sso{
proxy_pass http://sso;
}
location /os-service/ {
rewrite ^/os-service/(.*)$ /$1 break;
proxy_pass http://os;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /saml-service/saml {
proxy_pass http://backendapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /openid-service/openid {
proxy_pass http://backendapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /auth-service/service {
proxy_pass http://backendapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /verification-service/service {
proxy_pass http://backendapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /directory-service/service {
proxy_pass http://backendapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /identity-service/service {
proxy_pass http://backendapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /cloudrunner-service/cloudrunner {
proxy_pass http://backendapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
The below Shell script will be used for docker-compose.yaml file creation
Create a file name using write_environment.sh and paste the below script.
echo "Starting Environment File config"
env_var_template="./docker-compose_template.yaml"
machine_ip=$(curl -s https://ifconfig.me)
my_domain="test"
system=$(uname -s)
release=$(uname -r)
nag_envname="${system}-${release}-${machine_ip}"
if [ ! -f "$env_var_template" ]; then
echo "Error: Template for Environment file '$env_var_template' not found."
exit 1
fi
template_content=$(cat "$env_var_template")
updated_content=$(echo "$template_content" | sed "s/<myip>/$machine_ip/g")
updated_content=$(echo "$updated_content" | sed "s/<mydomain>/$my_domain/g")
updated_content=$(echo "$updated_content" | sed "s/<nag_envname>/$nag_envname/g")
if [ $? -ne 0 ]; then
echo "Error: Failed to replace the placeholder in the Environment template."
exit 1
fi
env_file="./docker-compose.yaml"
echo "$updated_content" > "$env_file"
echo "Environment variable config is Done"
echo "Started nginx config file creation"
env_var_template="config/nginx/nginx_template"
template_content=$(cat "$env_var_template")
updated_content=$(echo "$template_content" | sed "s/<myip>/$machine_ip/g")
if [ $? -ne 0 ]; then
echo "Error: Failed to replace the placeholder in the Environment template."
exit 1
fi
env_file="config/nginx/nginx.conf"
echo "$updated_content" > "$env_file"
echo "Nginx config is Done"
Note: Update the value of my_domain in the above code
Before running the below command give write permission to the file.
sudo chmod 400 write_environment.sh
Command to run the script - sudo sh write_environment.sh
get-host-ip.py
#!/usr/bin/env python3
import sys
from socket import AF_INET, SOCK_DGRAM, socket
def main():
the_socket = socket(AF_INET, SOCK_DGRAM)
try:
the_socket.connect(("8.8.8.8", 80))
inet_addr = the_socket.getsockname()
if "-v" in sys.argv:
print(f"IP address={inet_addr[0]}", file=sys.stderr)
print(inet_addr[0])
except:
print("Failed to connect", file=sys.stderr)
print("127.0.0.1")
if __name__ == "__main__":
main()
Give the write permission to this script chmod 777 -R get-host-ip.py
Docker setup on the Server
Docker and Docker compose should be installed on the server.
Step 1 - Docker installation
The below Shell script will be used for installation.
docker_install.sh
#!/bin/bash # Check if Docker is installed if ! command -v docker &> /dev/null then # Docker not found, installing Docker echo "Docker not found. Installing Docker..." # Update the apt package index sudo apt update # Install packages to allow apt to use a repository over HTTPS sudo apt install -y \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release # Add Docker’s official GPG key curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # Set up the stable Docker repository echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # Install Docker Engine sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io # Add user to docker group sudo usermod -aG docker $USER HOST_DEFAULT_ROUTE_IP=$(./get-host-ip.py) docker swarm init --advertise-addr $HOST_DEFAULT_ROUTE_IP echo "Docker installed successfully." else echo "Docker is already installed." fi
Step 2 - Docker Compose Installation
docker_compose.sh
The below Shell script will be used for installation.
#!/bin/bash # Check if Docker Compose is installed if ! command -v docker-compose &> /dev/null then # Docker Compose not found, installing Docker Compose echo "Docker Compose not found. Installing Docker Compose..." # Download the current stable release of Docker Compose sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # Apply executable permissions to the binary sudo chmod +x /usr/local/bin/docker-compose echo "Docker Compose installed successfully." else echo "Docker Compose is already installed." fi
Step 3 - Running the service using restart_all.sh script
restart_all.sh
#! /usr/bin/env bash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
set -a
source $SCRIPT_DIR/.env
set +a
docker stack deploy --compose-file=$SCRIPT_DIR/docker-compose.yaml $extra_args nag --with-registry-auth --prune
docker service update --force nag_nginx
docker service update --force nag_backendapp
docker service update --force nag_frontend
docker service update --force nag_sso
docker service update --force nag_os
Command to run the script - ./restart_all.sh
Updated handling
Create the nag_update.sh
#!/bin/bash
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if ! command -v jq &> /dev/null; then
echo "jq is not installed. Installing jq..."
sudo apt-get update
sudo apt-get install -y jq
# Check again if jq is installed
if ! command -v jq &> /dev/null; then
echo "Failed to install jq. Exiting."
exit 1
fi
fi
BACKEND_CONTAINER_ID=$(docker ps -qf "name=nag_backendapp")
if [ -z "$BACKEND_CONTAINER_ID" ]; then
echo "Container not found or not running."
exit 1
fi
docker exec "$BACKEND_CONTAINER_ID" cat /app/nag_update.json > $CURRENT_PATH/nag_update.json
json_file="$CURRENT_PATH/nag_update.json"
can_update=$(jq -r .can_update "$json_file")
if [ "$can_update" = "true" ]; then
if $CURRENT_PATH/restart_all.sh; then
jq '.can_update = false' "$json_file" > "$json_file.tmp" && mv "$json_file.tmp" "$json_file"
docker cp $json_file $BACKEND_CONTAINER_ID:/app/nag_update.json
echo "Updated successfully"
else
echo "Error:failed. Update aborted"
fi
else
echo "No Updates. Exiting..."
fi
Create the write_crontab.sh
#!/bin/bash CURRENT_PATH=$(pwd) echo "The current path is: $CURRENT_PATH" # Define the command and schedule CRON_COMMAND="$CURRENT_PATH/nag_update.sh 2>&1 | /usr/bin/logger -t CRONOUTPUT" CRON_SCHEDULE="0 */12 * * *" echo "$CRON_COMMAND" # Write the command to a temporary crontab file echo "$CRON_SCHEDULE $CRON_COMMAND" > /tmp/my_cronjob # Install the temporary crontab file crontab /tmp/my_cronjob # Remove the temporary crontab file rm /tmp/my_cronjob echo "Cron job set up successfully!"
Note: Update the CRON_SCHEDULE="0 */12 * * *" based on your needed time to update the scripts
Run the write_crontab.sh to make sure to update the instance for latest code in the scheduled time
Setup Completed
Your service is now running in this URI
{{URI}} - Public ip of the instance with 80 port
Use the Public IP to view the NAG Dashboard.
List of domains to whitelist in NAG
https://infisign-01.s3.amazonaws.com/
https://826fb84d23eb4540adf97442ef1c807@o4505516034162688.ingest.sentry.io/4505520095625216
https://634bdb5939c23e42b95e7e0325229763@o4505516034162688.ingest.sentry.io/4506273758904320
https://09128e44fd5f4f48909239eb0ba349ac@o4505516034162688.ingest.sentry.io/4505516766003200
https://play.google.com/store/apps/details?id=com.wallet.infisign