From d541062eda6699d4a4e1a97fb01002993a263b4b Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Thu, 16 Nov 2023 22:41:38 +0000 Subject: [PATCH] create openldap setup utilities, prototype ldap api interface --- .eslintrc.json | 42 +++++++++++++++++++++++++++++++++++++ .gitignore | 3 +++ openldap/auth.template.ldif | 20 ++++++++++++++++++ openldap/init.sh | 18 ++++++++++++++++ openldap/init.template.ldif | 23 ++++++++++++++++++++ openldap/pass.template.ldif | 23 ++++++++++++++++++++ package.json | 34 ++++++++++++++++++++++++++++++ src/ldap.js | 31 +++++++++++++++++++++++++++ src/main.js | 30 ++++++++++++++++++++++++++ 9 files changed, 224 insertions(+) create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 openldap/auth.template.ldif create mode 100755 openldap/init.sh create mode 100644 openldap/init.template.ldif create mode 100644 openldap/pass.template.ldif create mode 100644 package.json create mode 100644 src/ldap.js create mode 100644 src/main.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..86a2b41 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,42 @@ +{ + "env": { + "es2021": true, + "node": true + }, + "extends": "standard", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "rules": { + "no-tabs": [ + "error", + { + "allowIndentationTabs": true + } + ], + "indent": [ + "error", + "tab" + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "double" + ], + "semi": [ + "error", + "always" + ], + "brace-style": [ + "error", + "stroustrup", + { + "allowSingleLine": false + } + ] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7fd5b7c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +**/package-lock.json +**/node_modules +**/*.token \ No newline at end of file diff --git a/openldap/auth.template.ldif b/openldap/auth.template.ldif new file mode 100644 index 0000000..e219f70 --- /dev/null +++ b/openldap/auth.template.ldif @@ -0,0 +1,20 @@ +# Add permissions +dn: olcDatabase={1}mdb,cn=config +changetype: modify +delete: olcAccess +- +add: olcAccess +olcAccess: {0}to attrs=userPassword + by self write + by anonymous auth + by * none +olcAccess: {1}to attrs=shadowLastChange + by self write + by * read +olcAccess: {2}to dn.subtree="$BASE_DN" + by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage + by group/groupOfNames/member="cn=admins,ou=groups,$BASE_DN" write + by * read +olcAccess: {3}to * + by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage + by * read diff --git a/openldap/init.sh b/openldap/init.sh new file mode 100755 index 0000000..7d57605 --- /dev/null +++ b/openldap/init.sh @@ -0,0 +1,18 @@ +export BASE_DN='' +read -p "Base DN: " BASE_DN + +export PAAS_PASSWD=$(tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' paas.token +echo "Saved PAAS Authentication Token (password) to paas.token" + +envsubst '$BASE_DN' < auth.template.ldif > auth.ldif +envsubst '$BASE_DN' < pass.template.ldif > pass.ldif +envsubst '$BASE_DN:$PAAS_PASSWD' < init.template.ldif > init.ldif + +sudo ldapmodify -H ldapi:/// -Y EXTERNAL -f auth.ldif +sudo ldapmodify -H ldapi:/// -Y EXTERNAL -f pass.ldif +sudo ldapadd -H ldapi:/// -Y EXTERNAL -c -f init.ldif + +unset BASE_DN +unset PAAS_PASSWD +rm auth.ldif init.ldif pass.ldif diff --git a/openldap/init.template.ldif b/openldap/init.template.ldif new file mode 100644 index 0000000..0d41689 --- /dev/null +++ b/openldap/init.template.ldif @@ -0,0 +1,23 @@ +# people ou +dn: ou=people,$BASE_DN +objectClass: organizationalUnit +ou: people + +# group ou +dn: ou=groups,$BASE_DN +objectClass: organizationalUnit +ou: groups + +# admin group +dn: cn=admins,ou=groups,$BASE_DN +objectClass: groupOfNames +member: uid=paas,ou=people,$BASE_DN +cn: admins + +# paas user +dn: uid=paas,ou=people,$BASE_DN +objectClass: inetOrgPerson +cn: paas +sn: paas +uid: paas +userPassword: $PAAS_PASSWD diff --git a/openldap/pass.template.ldif b/openldap/pass.template.ldif new file mode 100644 index 0000000..857c5ab --- /dev/null +++ b/openldap/pass.template.ldif @@ -0,0 +1,23 @@ +# load pw-sha2 module +dn: cn=module{0},cn=config +changetype: modify +add: olcModuleLoad +olcModuleLoad: pw-sha2.la +olcModuleLoad: ppolicy.la + +# set default password hash to SSHA512 +dn: olcDatabase={-1}frontend,cn=config +changetype: modify +add: olcPasswordHash +olcPasswordHash: {SSHA512} + +# add password policy to use SSHA512 hash +dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config +changetype: add +objectClass: olcOverlayConfig +objectClass: olcPPolicyConfig +olcOverlay: ppolicy +olcPPolicyDefault: cn=password,ou=policies,$BASE_DN +olcPPolicyHashCleartext: TRUE +olcPPolicyUseLockout: FALSE +olcPPolicyForwardUpdates: FALSE \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..318affc --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "proxmoxaas-ldap", + "version": "0.0.1", + "description": "LDAP intermediate API for ProxmoxAAS", + "main": "src/main.js", + "type": "module", + "dependencies": { + "axios": "^1.5.1", + "body-parser": "^1.20.1", + "cookie": "^0.5.0", + "cookie-parser": "^1.4.6", + "cors": "^2.8.5", + "express": "^4.18.2", + "ldapjs": "^3.0.5", + "minimist": "^1.2.8", + "morgan": "^1.10.0" + }, + "devDependencies": { + "eslint": "^8.43.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^16.0.1", + "eslint-plugin-promise": "^6.1.1", + "body-parser": "^1.20.1", + "cookie": "^0.5.0", + "cookie-parser": "^1.4.6", + "express": "^4.18.2", + "minimist": "^1.2.8", + "morgan": "^1.10.0" + }, + "scripts": { + "lint": "DEBUG=eslint:cli-engine eslint --fix ." + } +} diff --git a/src/ldap.js b/src/ldap.js new file mode 100644 index 0000000..25de68a --- /dev/null +++ b/src/ldap.js @@ -0,0 +1,31 @@ +import ldap from "ldapjs"; +import { exit } from "process"; + +export class LDAP { + #client = null; + #paasBind = null; + #baseDN = null; + + constructor (url, paasBind, baseDN) { + const opts = { + url + }; + this.#client = ldap.createClient(opts); + this.#client.on("connectError", (err) => { + console.err(`Error: could not establish connection to ${url}`); + console.err(err); + exit(1); + }); + + this.#paasBind = paasBind; + this.#baseDN = baseDN; + } + + addUser (uid, entry) {} + + getUser (uid) {} + + modUser (uid, entry) {} + + delUser (uid) {} +} diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..c6fda35 --- /dev/null +++ b/src/main.js @@ -0,0 +1,30 @@ +import express from "express"; +import bodyParser from "body-parser"; +import cookieParser from "cookie-parser"; +import morgan from "morgan"; +import LDAP from "ldap.js"; + +const app = express(); +app.use(bodyParser.urlencoded({ extended: true })); +app.use(cookieParser()); +app.use(morgan("combined")); + +app.listen(global.db.listenPort, () => { + console.log(`proxmoxaas-api v${global.api.version} listening on port ${global.db.listenPort}`); +}); + +app.get("/:user", (req, res) => { + +}); + +app.post("/:user", (req, res) => { + +}); + +app.delete("/:user", (req, res) => { + +}); + +app.post("/:user/password", (req, res) => { + +});