Initial PanOS db support

This commit is contained in:
Douglas Barone 2021-01-14 13:04:41 -04:00
parent a8a4bf7f6a
commit 681b83188b
8 changed files with 165 additions and 6 deletions

View File

@ -42,3 +42,9 @@ PA_HOST=10.1.0.2
PA_USER=pti PA_USER=pti
PA_PASSWORD=senhadopaloaltocompermissaoparaapi PA_PASSWORD=senhadopaloaltocompermissaoparaapi
PA_NET=10.7. PA_NET=10.7.
# Criptografia
CRYPT_SECRET=umasenhaquenaopodeseralteradadepois
# Opicionais
TASK_SLEEP=30000

View File

@ -1,12 +1,12 @@
{ {
"name": "ifms-pti-svr", "name": "ifms-pti-svr",
"version": "2.5.0", "version": "2.6.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ifms-pti-svr", "name": "ifms-pti-svr",
"version": "2.5.0", "version": "2.6.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@babel/polyfill": "^7.12.1", "@babel/polyfill": "^7.12.1",
@ -16,6 +16,7 @@
"apollo-server-plugin-response-cache": "^0.5.6", "apollo-server-plugin-response-cache": "^0.5.6",
"axios": "^0.21.0", "axios": "^0.21.0",
"bcrypt": "^5.0.0", "bcrypt": "^5.0.0",
"crypto-js": "^4.0.0",
"date-fns": "^2.16.1", "date-fns": "^2.16.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"graphql": "^14.6.0", "graphql": "^14.6.0",
@ -3883,6 +3884,11 @@
"underscore": ">1.4.4" "underscore": ">1.4.4"
} }
}, },
"node_modules/crypto-js": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
},
"node_modules/crypto-random-string": { "node_modules/crypto-random-string": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
@ -4456,7 +4462,71 @@
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz",
"integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==",
"bundleDependencies": [ "bundleDependencies": [
"node-pre-gyp" "node-pre-gyp",
"abbrev",
"ansi-regex",
"aproba",
"are-we-there-yet",
"balanced-match",
"brace-expansion",
"chownr",
"code-point-at",
"concat-map",
"console-control-strings",
"core-util-is",
"debug",
"deep-extend",
"delegates",
"detect-libc",
"fs-minipass",
"fs.realpath",
"gauge",
"glob",
"has-unicode",
"iconv-lite",
"ignore-walk",
"inflight",
"inherits",
"ini",
"is-fullwidth-code-point",
"isarray",
"minimatch",
"minimist",
"minipass",
"minizlib",
"mkdirp",
"ms",
"needle",
"nopt",
"npm-bundled",
"npm-packlist",
"npmlog",
"number-is-nan",
"object-assign",
"once",
"os-homedir",
"os-tmpdir",
"osenv",
"path-is-absolute",
"process-nextick-args",
"rc",
"readable-stream",
"rimraf",
"safe-buffer",
"safer-buffer",
"sax",
"semver",
"set-blocking",
"signal-exit",
"string_decoder",
"string-width",
"strip-ansi",
"strip-json-comments",
"tar",
"util-deprecate",
"wide-align",
"wrappy",
"yallist"
], ],
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
@ -12114,6 +12184,11 @@
"underscore": ">1.4.4" "underscore": ">1.4.4"
} }
}, },
"crypto-js": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
},
"crypto-random-string": { "crypto-random-string": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",

View File

@ -42,6 +42,7 @@
"apollo-server-plugin-response-cache": "^0.5.6", "apollo-server-plugin-response-cache": "^0.5.6",
"axios": "^0.21.0", "axios": "^0.21.0",
"bcrypt": "^5.0.0", "bcrypt": "^5.0.0",
"crypto-js": "^4.0.0",
"date-fns": "^2.16.1", "date-fns": "^2.16.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"graphql": "^14.6.0", "graphql": "^14.6.0",

View File

@ -5,6 +5,7 @@ CREATE TABLE "PanOS" (
"ip" TEXT NOT NULL, "ip" TEXT NOT NULL,
"encryptedKey" TEXT NOT NULL, "encryptedKey" TEXT NOT NULL,
"note" TEXT, "note" TEXT,
"user" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL, "updatedAt" TIMESTAMP(3) NOT NULL,

View File

@ -125,6 +125,7 @@ model Statistic {
model PanOS { model PanOS {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
user String
description String description String
ip String @unique ip String @unique
encryptedKey String encryptedKey String

View File

@ -6,6 +6,7 @@ import https from 'https'
import { subMinutes } from 'date-fns' import { subMinutes } from 'date-fns'
import qs from 'qs' import qs from 'qs'
import { logError, logSuccess } from './logger' import { logError, logSuccess } from './logger'
import { AES, enc } from 'crypto-js'
const TIMEOUT_IN_MINUTES = '3' const TIMEOUT_IN_MINUTES = '3'
@ -91,4 +92,53 @@ async function updateUserIdMappings() {
} }
} }
export { updateUserIdMappings } async function getUserKey({ ip, user, password }) {
const result = await axios({
url: `https://${ip}/api/`,
method: 'POST',
params: { type: 'keygen', user, password },
httpsAgent
})
return result.data.split('<key>')[1].split('</key>')[0]
}
async function addHost({ ip, user, password, description, note }) {
try {
const key = await getUserKey({ ip, user, password })
const encryptedKey = AES.encrypt(key, process.env.CRYPT_SECRET).toString()
// const decryptedKey = AES.decrypt(
// encryptedKey,
// process.env.CRYPT_SECRET
// ).toString(enc.Utf8)
const host = await prisma.panOS.create({
data: {
ip,
encryptedKey,
user,
description,
note
}
})
return {
...host,
key: `${key.slice(
0,
8
)}************************************************************************************************`
}
} catch (e) {
logError({
message: `Não foi possível adicionar o host ${ip}.`,
data: e.message,
tags: ['paloalto']
})
throw new Error(e.message)
}
}
export { updateUserIdMappings, addHost }

View File

@ -3,7 +3,7 @@ import { User } from '../../classes/User'
import { ResetToken } from '../../classes/ResetToken' import { ResetToken } from '../../classes/ResetToken'
import { updateDevicesInfo } from '../../lib/wifiDevices' import { updateDevicesInfo } from '../../lib/wifiDevices'
import { updateUserIdMappings } from '../../lib/paloalto' import { updateUserIdMappings, addHost } from '../../lib/paloalto'
import { logInfo } from '../../lib/logger' import { logInfo } from '../../lib/logger'
const Mutation = { const Mutation = {
@ -44,6 +44,10 @@ const Mutation = {
async updateUserIdMappings() { async updateUserIdMappings() {
return updateUserIdMappings() return updateUserIdMappings()
},
async addPAHost(_, { data: { ip, user, password, description, note } }) {
return addHost({ ip, user, password, description, note })
} }
} }

View File

@ -84,6 +84,9 @@ const typeDefs = gql`
"Force update user-id mapping on firewall" "Force update user-id mapping on firewall"
updateUserIdMappings: String! @auth(roles: ["superAdmin"]) updateUserIdMappings: String! @auth(roles: ["superAdmin"])
"Add a PA host"
addPAHost(data: AddPAHostInput!): PAHost! @auth(roles: ["superAdmin"])
} }
type Subscription { type Subscription {
@ -254,6 +257,16 @@ const typeDefs = gql`
ERROR ERROR
} }
type PAHost {
id: ID!
description: String
ip: String
key: String
note: String
createdAt: String
updatedAt: String
}
input LoginInput { input LoginInput {
username: String! username: String!
password: String! password: String!
@ -288,6 +301,14 @@ const typeDefs = gql`
token: String! token: String!
newPassword: String! newPassword: String!
} }
input AddPAHostInput {
ip: String!
user: String!
password: String!
description: String!
note: String
}
` `
export { typeDefs } export { typeDefs }