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=${MONGO_INITDB_ROOT_USERNAME:?} - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD:?} ports: - "27018:27017" volumes: - db:/data/db - ./config/mongo/mongod.conf:/etc/mongod.conf backendapp: image: infisign/infisign-nag:admin-latest command: sh -c "python manage.py migrate && python manage.py collectstatic --noinput && gunicorn app.wsgi:application --bind 0.0.0.0:8001" environment: - API_HOSTNAME=https://app.infisign.net/ - SSO_HOSTNAME=<mydomain>/sso/verify - INFISIGN_NAG_SUBSCRIPTION_KEY=test - INFISIGN_NAG_URL_IDENTIFIER=test - SENTRY_ENV=<nag_envname> - BACKEND_IMAGE=infisign/infisign-nag:admin-latest - SSO_IMAGE=infisign/infisign-nag:sso-v1 - FRONTEND_IMAGE=infisign/infisign-nag:mfe-v1 - OTHER_INSTANCES= - SCHEDULED_TIME=22:00 - MONGO_DB_CONNECTION=${MONGO_DB_CONNECTION:?} ports: - "8001:8001" depends_on: - db frontend: image: infisign/infisign-nag:mfe-latest environment: - BASE_URL=<mydomain> - SSO_URL=<mydomain>/sso/verify - SENTRY_ENV=<nag_envname> ports: - "8081:80" sso: image: infisign/infisign-nag:sso-latest environment: - BASE_URL=<mydomain> - SOCKET_URL=<mydomain> - SENTRY_ENV=<nag_envname> ports: - "8080:80" nginx: image: nginx:latest ports: - "80:80" volumes: - ./config/nginx/:/etc/nginx/conf.d depends_on: - backendapp - frontend - sso 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; } 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 / { proxy_pass http://frontend; } location /sso{ proxy_pass http://sso; } location /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 { proxy_pass http://backendapp; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; } location /service { 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
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