Quick Start Guide
Technical Overview
The Syntmon application is comprised of three parts:
- The Syntmon application
- An InfluxDB (version 1.11.8) for storing all file information
- A MySQL Database (version 5.7) for application configuration, logging, and authentication
The core application is provided by BrythonicBytes a Docker container, the database components are provided by third parties and can be setup according to your use case.
The default root password is “Brythonic@1”
Quick Install Walkthrough
This covers how to quickly set up Syntmon for evaluation using Docker on Linux. Here we walk through the install process, host addition, manual report uploading, alert creation, API key creation, and automated report uploading.
This setup is not fit for production and is for evaluation only.
Syntmon Service
The Syntmon service is responsible for accepting data from clients, processing information, and serving content for web frontend users.
docker pull brythonicbytes/syntmon:latest
The essential environment variables are:
Variable | Description | Examples |
---|---|---|
INFLUXDB_HOST | The InfluxDB endpoint | “http://10.1.2.3:8086” |
DOMAIN_NAME | The domain name that the backend API (and web frontend) are accessible on | “syntmon.example.com” |
MYSQLDB_HOST | The MYSQL endpoint | “mysql.syntmon.svc.cluster.local” “mysql.example.com” |
MYSQLDB_USER | A username for accessing the MYSQL database | “admin” “user01” |
MYSQLDB_PASSWORD | The corresponding password for MYSQLDB_USER | “P@5sw0rd” |
MYSQLDB_PORT | The corresponding port for MYSQLDB_HOST | “3306” |
PORT | The port to access the HTTP service | 80 |
Quick Start Configs
--- version: "3" services: mysql_svc: image: mysql:5.7 command: '--default-authentication-plugin=mysql_native_password' volumes: - mysql_data:/var/lib/mysql restart: always environment: - MYSQL_DATABASE=syntmon - MYSQL_PASSWORD=password - MYSQL_ROOT_PASSWORD=password - MYSQL_USER=user expose: - 3306 influx_svc: image: influxdb:1.11.8 volumes: - influx_data:/var/lib/influxdb restart: always environment: - INFLUXDB_ADMIN_USER=admin - INFLUXDB_ADMIN_PASSWORD=password - INFLUXDB_ADMIN_USER_PASSWORD=password expose: - 8086 syntmon: image: brythonicbytes/syntmon:latest environment: - INFLUXDB_HOST=http://influx_svc:8086 - DOMAIN_NAME=syntmon.localhost - PORT=80 - MYSQLDB_HOST=mysql_svc - MYSQLDB_USER=root - MYSQLDB_PASSWORD=password - MYSQLDB_PORT=3306 ports: - 80:80 restart: always volumes: mysql_data: influx_data:
--- apiVersion: v1 kind: Namespace metadata: name: syntmon --- kind: Deployment apiVersion: apps/v1 metadata: name: syntmon namespace: syntmon spec: replicas: 1 selector: matchLabels: app: syntmon template: metadata: labels: app: syntmon spec: containers: - name: syntmon image: brythonicbytes/syntmon:latest ports: - containerPort: 5000 env: - name: INFLUXDB_HOST value: "http://influxdb.syntmon.svc.cluster.local:8086" - name: DOMAIN_NAME value: "syntmon-frontend" - name: PORT value: "5000" - name: MYSQLDB_HOST value: mysql.syntmon.svc.cluster.local - name: MYSQLDB_USER value: "root" - name: LOGLEVEL value: "3" - name: MYSQLDB_PASSWORD value: "password" - name: MYSQLDB_PORT value: "3306" - name: SEARCH_TIMEOUT value: "30" --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: syntmon namespace: syntmon annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/proxy-body-size: 100m nginx.ingress.kubernetes.io/proxy-read-timeout: "120" spec: rules: - host: syntmon http: paths: - path: / pathType: Prefix backend: service: name: syntmon port: number: 5000 --- apiVersion: v1 kind: Service metadata: name: syntmon namespace: syntmon spec: ports: - name: http targetPort: 5000 port: 5000 selector: app: syntmon --- kind: Deployment apiVersion: apps/v1 metadata: name: syntmon-influxdb namespace: syntmon spec: replicas: 1 selector: matchLabels: app: syntmon-influxdb template: metadata: labels: app: syntmon-influxdb spec: containers: - name: syntmon-influxdb image: influxdb:1.8 ports: - containerPort: 8086 volumeMounts: - mountPath: /var/lib/influxdb name: data env: - name: INFLUXDB_ADMIN_USER value: "admin" - name: INFLUXDB_ADMIN_PASSWORD value: "password" - name: INFLUXDB_ADMIN_USER_PASSWORD value: "password" resources: requests: memory: "7Gi" limits: memory: "12Gi" volumes: - name: data hostPath: path: /var/lib/containers/storage/syntmon/influxdb --- apiVersion: v1 kind: Service metadata: name: influxdb namespace: syntmon spec: ports: - name: syntmon-influxdb port: 8086 targetPort: 8086 selector: app: syntmon-influxdb --- apiVersion: apps/v1 kind: Deployment metadata: labels: service: mysql name: mysql namespace: syntmon spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - env: - name: MYSQL_DATABASE value: syntmon - name: MYSQL_PASSWORD value: "password" - name: MYSQL_ROOT_PASSWORD value: "password" - name: MYSQL_USER value: "user" image: mysql:5.7 name: mysql ports: - containerPort: 3306 volumeMounts: - mountPath: /var/lib/mysql name: mysql-data volumes: - name: mysql-data hostPath: path: /var/lib/containers/storage/syntmon/mysql --- apiVersion: v1 kind: Service metadata: name: mysql namespace: syntmon spec: selector: app: mysql ports: - name: mysql targetPort: 3306 port: 3306
--- #This requires both ELB and ALB to be installed and configured #Documentation is available here: #https://docs.aws.amazon.com/eks/latest/userguide/lbc-manifest.html #https://repost.aws/knowledge-center/eks-persistent-storage #ELB also requires public subnets to have the "kubernetes.io/role/elb" with a value of "1" #This benefits from the AWS ELB domain being set in the DOMAIN_NAME environment var for the syntmon container #This can be found in the AWS dashboard in EC2>Load balancers, or from $ kubectl get ing -nsyntmon #The region used should be set in the storage class apiVersion: v1 kind: Namespace metadata: name: syntmon --- apiVersion: v1 kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: awsgp2vol provisioner: ebs.csi.eks.amazonaws.com volumeBindingMode: Immediate parameters: csi.storage.k8s.io/fstype: ext4 type: gp2 allowedTopologies: - matchLabelExpressions: - key: topology.ebs.csi.aws.com/zone values: - us-east-1a - us-east-1b --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-mysql namespace: syntmon spec: resources: requests: storage: 20Gi accessModes: - ReadWriteOnce storageClassName: awsgp2vol --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-influxdb namespace: syntmon spec: resources: requests: storage: 50Gi accessModes: - ReadWriteOnce storageClassName: awsgp2vol --- kind: Deployment apiVersion: apps/v1 metadata: name: syntmon namespace: syntmon spec: replicas: 1 selector: matchLabels: app: syntmon template: metadata: labels: app: syntmon spec: containers: - name: syntmon image: brythonicbytes/syntmon:latest ports: - containerPort: 5000 env: - name: INFLUXDB_HOST value: "http://influxdb.syntmon.svc.cluster.local:8086" - name: DOMAIN_NAME value: "tmp" - name: PORT value: "5000" - name: MYSQLDB_HOST value: "mysql.syntmon.svc.cluster.local" - name: SECURE_LOGIN #remove the secure flag on the login cookie to allow testing with elb generated domains value: "false" - name: MYSQLDB_USER value: "root" - name: LOGLEVEL value: "3" - name: MYSQLDB_PASSWORD value: "password" - name: MYSQLDB_PORT value: "3306" --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: syntmon namespace: syntmon annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=600 spec: ingressClassName: alb rules: - http: paths: - path: / pathType: Prefix backend: service: name: syntmon port: number: 80 --- apiVersion: v1 kind: Service metadata: name: syntmon namespace: syntmon spec: ports: - name: http targetPort: 5000 port: 80 selector: app: syntmon --- kind: Deployment apiVersion: apps/v1 metadata: name: syntmon-influxdb namespace: syntmon spec: replicas: 1 selector: matchLabels: app: syntmon-influxdb template: metadata: labels: app: syntmon-influxdb spec: containers: - name: syntmon-influxdb image: influxdb:1.8 ports: - containerPort: 8086 volumeMounts: - mountPath: /var/lib/influxdb name: data env: - name: INFLUXDB_ADMIN_USER value: "admin" - name: INFLUXDB_ADMIN_PASSWORD value: "password" - name: INFLUXDB_ADMIN_USER_PASSWORD value: "password" volumes: - name: data persistentVolumeClaim: claimName: pvc-influxdb --- apiVersion: v1 kind: Service metadata: name: influxdb namespace: syntmon spec: ports: - name: syntmon-influxdb port: 8086 targetPort: 8086 selector: app: syntmon-influxdb --- apiVersion: apps/v1 kind: Deployment metadata: labels: service: mysql name: mysql namespace: syntmon spec: replicas: 1 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - env: - name: MYSQL_DATABASE value: syntmon - name: MYSQL_PASSWORD value: "password" - name: MYSQL_ROOT_PASSWORD value: "password" - name: MYSQL_USER value: "user" image: mysql:5.7 name: mysql args: - "--ignore-db-dir=lost+found" ports: - containerPort: 3306 volumeMounts: - mountPath: /var/lib/mysql name: mysql-data volumes: - name: mysql-data persistentVolumeClaim: claimName: pvc-mysql --- apiVersion: v1 kind: Service metadata: name: mysql namespace: syntmon spec: selector: app: mysql ports: - name: mysql targetPort: 3306 port: 3306
Client Configuration
Configuring clients to produce and upload reports to Syntmon requires Aide and cURL to be installed along with the ability to POST data to the backend.
A suitable Aide configuration to scan all files on a system is:
/ p+u+g+sha512 database_out=file:/var/db/aide.db database_new=file:/var/db/aide.db
After generating an API key from the users page within the web frontend, this can then be automated from crontab with something like:
aide -ic /etc/aide.conf&&mv /var/db/aide.db.new /var/db/aide.db&&curl -k -XPOST https://<ENDPOINT>/api/v1/upload-report -H"content-Type: multipart/form-data" -H'Accept: application/json' -H "Authorization: Bearer <APIKEY>" -Ftype="aidelogfile" -Fdata=@/var/db/aide.db -Fhost=$(hostname -f)
Reports can be generated and submitted from Windows in a similar fashion, the array of paths to be searched in $P, the ENDPOINT, and APIKEY all need changing to suit your environment:
$P="C:\","D:\";$T = New-TemporaryFile;Get-Date -Format "yyyy/MM/dd HH:mm:ss K">$T;Get-ChildItem $P -File -Recurse -PipelineVariable File|ForEach-Object{$stream = try {[IO.FileStream]::new( $File.FullName, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::Read )}catch {[IO.FileStream]::new( $File.FullName, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::ReadWrite )}if( $stream ) {try {Get-FileHash -InputStream $stream -Algorithm SHA512 | Select-Object @{ Name = 'Path'; Expression = { $File.Fullname } }, Hash}finally {$stream.Close()}}}>>$T;C:\WINDOWS\system32\curl.exe -XPOST https://<ENDPOINT>/api/v1/upload-report -H"content-Type: multipart/form-data" -H'Accept: application/json' -H "Authorization: Bearer <APIKEY>" -Ftype="windowshashlist" -Fdata=@$T -Fhost=$(hostname) -Ftimezone=$(get-date -Format"K ")
For uploading PS(1) output, run the following command either manually or using a cronjob:
ps auxww>/tmp/psout;curl -XPOST https:/<ENDPOINT>/api/v1/upload-procs -H"content-Type: multipart/form-data" -H'Accept: application/json' -H "Authorization: Bearer <APIKEY>" -Ftype="ps" -Fdata=@/tmp/psout -Fhost=$(hostname -f) -Ftimezone=$(date +"%z")