Add PA Host OK

This commit is contained in:
Douglas Barone 2021-01-14 15:12:37 -04:00
parent 681b83188b
commit 80f81b4013
7 changed files with 73 additions and 39 deletions

View File

@ -20,6 +20,7 @@
"date-fns": "^2.16.1",
"dotenv": "^8.2.0",
"graphql": "^14.6.0",
"ip": "^1.1.5",
"jsonwebtoken": "^8.5.1",
"ldapjs": "^2.2.1",
"node-cron": "^2.0.3",
@ -5857,6 +5858,11 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"node_modules/ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@ -13822,6 +13828,11 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",

View File

@ -46,6 +46,7 @@
"date-fns": "^2.16.1",
"dotenv": "^8.2.0",
"graphql": "^14.6.0",
"ip": "^1.1.5",
"jsonwebtoken": "^8.5.1",
"ldapjs": "^2.2.1",
"node-cron": "^2.0.3",

View File

@ -1,8 +1,8 @@
-- CreateTable
CREATE TABLE "PanOS" (
CREATE TABLE "PAHost" (
"id" SERIAL,
"cidr" TEXT NOT NULL,
"description" TEXT NOT NULL,
"ip" TEXT NOT NULL,
"encryptedKey" TEXT NOT NULL,
"note" TEXT,
"user" TEXT NOT NULL,

View File

@ -123,11 +123,11 @@ model Statistic {
onlineWifiDevices Int
}
model PanOS {
model PAHost {
id Int @id @default(autoincrement())
user String
description String
ip String @unique
cidr String @unique
encryptedKey String
note String?
createdAt DateTime @default(now())

View File

@ -1,14 +1,18 @@
// Ref.: https://docs.paloaltonetworks.com/pan-os/9-1/pan-os-panorama-api/pan-os-xml-api-request-types/apply-user-id-mapping-and-populate-dynamic-address-groups-api.html
import axios from 'axios'
import prisma from '../prisma'
import https from 'https'
import { subMinutes } from 'date-fns'
import { isIPv4 } from 'net'
import qs from 'qs'
import { add, subMinutes } from 'date-fns'
import { logError, logSuccess } from './logger'
import { AES, enc } from 'crypto-js'
import ip from 'ip'
import prisma from '../prisma'
const TIMEOUT_IN_MINUTES = '3'
const CIDR_RE = /^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$/
const httpsAgent = new https.Agent({
rejectUnauthorized: false
@ -92,49 +96,67 @@ async function updateUserIdMappings() {
}
}
async function getUserKey({ ip, user, password }) {
async function getUserKey({ ipAddr, user, password }) {
try {
const result = await axios({
url: `https://${ip}/api/`,
url: `https://${ipAddr}/api/`,
method: 'POST',
params: { type: 'keygen', user, password },
httpsAgent
})
return result.data.split('<key>')[1].split('</key>')[0]
} catch (e) {
throw new Error(e.message)
}
}
async function addHost({ ip, user, password, description, note }) {
function encryptKey(key) {
return AES.encrypt(key, process.env.CRYPT_SECRET).toString()
}
function decryptKey(encryptedKey) {
return AES.decrypt(encryptedKey, process.env.CRYPT_SECRET).toString(enc.Utf8)
}
async function addHost({ cidr, user, password, description, note }) {
try {
const key = await getUserKey({ ip, user, password })
if (!CIDR_RE.test(cidr)) throw new Error('Este não é um CIDR válido')
const encryptedKey = AES.encrypt(key, process.env.CRYPT_SECRET).toString()
const ipAddr = cidr.split('/')[0]
// const decryptedKey = AES.decrypt(
// encryptedKey,
// process.env.CRYPT_SECRET
// ).toString(enc.Utf8)
if (!isIPv4(ipAddr)) throw new Error('Este não é um IPv4 válido')
const host = await prisma.panOS.create({
data: {
ip,
const net = ip.cidrSubnet(cidr)
if (net.subnetMaskLength > 32 || net.networkAddress == '0.0.0.0')
throw new Error('Esta não é uma combinação de IP/máscara IPv4 válida')
const key = await getUserKey({ ipAddr, user, password })
const encryptedKey = encryptKey(key)
const pAHost = {
cidr,
encryptedKey,
user,
description,
note
}
const host = await prisma.pAHost.upsert({
where: { cidr: cidr },
create: pAHost,
update: pAHost
})
return {
...host,
key: `${key.slice(
0,
8
)}************************************************************************************************`
key: `${key.slice(0, 5)}`
}
} catch (e) {
logError({
message: `Não foi possível adicionar o host ${ip}.`,
data: e.message,
message: `Não foi possível adicionar o host ${cidr}. ${e?.message}`,
tags: ['paloalto']
})
throw new Error(e.message)

View File

@ -46,8 +46,8 @@ const Mutation = {
return updateUserIdMappings()
},
async addPAHost(_, { data: { ip, user, password, description, note } }) {
return addHost({ ip, user, password, description, note })
async addPAHost(_, { data: { cidr, user, password, description, note } }) {
return addHost({ cidr, user, password, description, note })
}
}

View File

@ -260,7 +260,7 @@ const typeDefs = gql`
type PAHost {
id: ID!
description: String
ip: String
cidr: String
key: String
note: String
createdAt: String
@ -303,7 +303,7 @@ const typeDefs = gql`
}
input AddPAHostInput {
ip: String!
cidr: String!
user: String!
password: String!
description: String!