[IMPROVED] Gestión de Usuarios PRITUNL VPN

- Crea usuario
- Elimina usuario
- Habilita y deshabilita usuario (modulo ansible falla)
This commit is contained in:
Mauro Rosero P. 2025-01-05 22:12:29 -05:00
parent 3d46c8e394
commit e46a671a7e
Signed by: mrosero
GPG key ID: 83BD2A5F674B7E26
13 changed files with 610 additions and 0 deletions

7
.gitignore vendored
View file

@ -10,6 +10,9 @@
!bin/lib/
!bin/msg/
!bin/config/
!bin/ansible/
!inventory
!templates
# Permitir el seguimiento de archivos específicos
# !archivo1.txt
@ -22,3 +25,7 @@
!bin/lib/*
!bin/msg/*
!bin/config/*
!bin/ansible/**
!inventory/**
!templates/**
!sops/*.yaml

View file

@ -0,0 +1,15 @@
---
# Include: includes/load_messages.yaml
# Description: load messages languages
# Author: Mauro Rosero P.
# Email: mauro@rosero.one (mauro.rosero@gmail.com)
# Organization: ROSERO ONE
# Created: Ene 04, 2025 12:00:00
# Updated: 2025-01-05 00:00:00
- name: Include language vars messages file
ansible.builtin.include_vars:
file: '{{ messages_file }}'
name: messages
connection: local
become: no

View file

@ -0,0 +1,26 @@
---
# Include: includes/sops_credentials.yaml
# Description: Get sops secure encrypted credentials
# Author: Mauro Rosero P.
# Email: mauro@rosero.one (mauro.rosero@gmail.com)
# Organization: ROSERO ONE
# Created: Ene 04, 2025 12:00:00
# Updated: 2025-01-05 00:00:00
- name: Get if credential access exists
ansible.builtin.stat:
path: "{{ sops_file }}"
register: credentials_access
connection: local
become: no
- name: Check if credentials access exists
ansible.builtin.assert:
that:
- credentials_access.stat.exists
fail_msg: "{{ messages.console.error.no_credentials }}"
quiet: true
- name: Get sops credentials access vars
set_fact:
sops_vars: "{{ lookup('community.sops.sops', sops_file, input_type='yaml', output_type='yaml') | from_yaml }}"

View file

@ -0,0 +1,20 @@
---
# ROSERO.ONE PERSONAL PLATFORM
# ANSIBLE MESSAGES (ES)
# File bin/ansible/messages/MESG-ES.yaml
# Global Definitions & Parameters
# Created 2024-03-14-00:12:00
# Updated 2024-06-01-00:41:00
console:
info:
hello: "{{ info }}Bienvenido, esto es una prueba"
warn:
hello: "{{ warn }}Bienvenido, esto es una prueba"
error:
hello: "{{ fail }}Bienvenido, esto es una prueba"
no_credentials: "{{ fail }}Archivo de credenciales sops no definido!"
credentials_fail: "{{ fail }}Archivo de credenciales es incorrecto!"
no_pritunl_user: "{{ fail }}USUARIO PRITUNL VPN no fue definido!"
no_pritunl_email: "{{ fail }}Correo electrónico de USUARIO PRITUNL VPN no fue definido!"
no_pritunl_action: "{{ fail }}Acción para gestión de USUARIO PRITUNL VPN es invalida!"

View file

@ -0,0 +1,133 @@
---
# Devops Ansible Script
# Playbook: pritunl_users.yaml
# Description: Add, enable, disable or remove pritunl vpn users
# Author: Mauro Rosero P.
# Email: mauro@rosero.one (mauro.rosero@gmail.com)
# Organization: ROSERO ONE
# Created: Ene 04, 2025 12:00:00
# Updated: 2025-01-05 00:00:00
- name: PLAYBOOK - {{ playbook_program | upper }} ({{ playbook_description | upper }})
hosts: [localhost]
become: no
gather_facts: no
vars:
playbook_program: 'pritunl_users'
playbook_description: 'Add, enable, disable or remove pritunl vpn users'
managed_sufix: 'pritunl-vpn'
main_action: 'MANAGE PRITUNL VPN USERS'
language: "{{ lang_modified | default(default_lang, true) }}"
messages_file: "{{ messages_path }}/{{ messages_prefix | upper}}-{{ language | upper }}.yaml"
pre_tasks:
- name: PRE -- LOAD FULL LANGUAGE MESSAGES FOR THIS PLAYBOOK
include_tasks:
file: includes/load_messages.yaml
run_once: true
- name: PRE -- SET PRITUNL VPN CREDENTIALS SOPS FILE
set_fact:
sops_file: '{{ sops_vpnadm_file }}'
- name: PRE -- GET REQUIRED SOPS CREDENTIALS
include_tasks:
file: includes/sops_credentials.yaml
run_once: true
- name: Check for succesfull credential vars loaded
ansible.builtin.assert:
that:
- sops_vars is defined
- sops_vars.PRITUNL_SECRET is defined
- sops_vars.PRITUNL_TOKEN is defined
fail_msg: "{{ messages.console.error.credentials_fail }}"
quiet: true
run_once: true
- name: Check if pritunl action is defined
ansible.builtin.assert:
that:
- input_pritunl_action is not defined or ( input_pritunl_action is defined and input_pritunl_action in ["add", "remove", "enable", "disable"] )
fail_msg: "{{ messages.console.error.no_pritunl_action }}"
quiet: true
run_once: true
- name: Check if pritunl user is defined
ansible.builtin.assert:
that:
- input_pritunl_user is defined
fail_msg: "{{ messages.console.error.no_pritunl_user }}"
quiet: true
run_once: true
- name: Check if pritunl email for user is defined
ansible.builtin.assert:
that:
- input_pritunl_email is defined
fail_msg: "{{ messages.console.error.no_pritunl_email }}"
quiet: true
when: input_pritunl_action is not defined or ( input_pritunl_action is defined and input_pritunl_action != "remove" )
run_once: true
tasks:
- block:
- name: --|| WAIT FOR SERVER(S) CONNECTION
wait_for_connection:
timeout: '{{ sysop_timeout_connection | int }}'
when: ansible_connection is defined and ansible_connection != 'local'
- block:
- name: --|| ADD PRITUNL VPN USER ({{ input_pritunl_user | upper }})
community.general.pritunl_user:
pritunl_url: "{{ platform_web_protocol }}{{ platform_vpn_server_devs }}:{{ platform_vpn_api_port }}"
pritunl_api_secret: "{{ sops_vars.PRITUNL_SECRET | b64decode | replace('\r', '') }}"
pritunl_api_token: "{{ sops_vars.PRITUNL_TOKEN | b64decode | replace('\r', '') }}"
organization: "{{ input_pritunl_org | default(platform_pritunl_org_default, true) | upper }}"
user_name: '{{ input_pritunl_user | lower }}'
user_email: '{{ input_pritunl_email | lower }}'
user_disabled: '{{ platform_pritunl_usr_default }}'
user_gravatar: '{{ platform_pritunl_img_default }}'
when: input_pritunl_action is not defined or ( input_pritunl_action is defined and input_pritunl_action == 'add' )
- name: --|| REMOVE PRITUNL VPN USER ({{ input_pritunl_user | upper }})
community.general.pritunl_user:
pritunl_url: "{{ platform_web_protocol }}{{ platform_vpn_server_devs }}:{{ platform_vpn_api_port }}"
pritunl_api_secret: "{{ sops_vars.PRITUNL_SECRET | b64decode | replace('\r', '') }}"
pritunl_api_token: "{{ sops_vars.PRITUNL_TOKEN | b64decode | replace('\r', '') }}"
state: absent
organization: "{{ input_pritunl_org | default(platform_pritunl_org_default, true) | upper }}"
user_name: '{{ input_pritunl_user | lower }}'
when: input_pritunl_action is defined and input_pritunl_action == 'remove'
- name: --|| ENABLE PRITUNL VPN USER ({{ input_pritunl_user | upper }})
community.general.pritunl_user:
pritunl_url: "{{ platform_web_protocol }}{{ platform_vpn_server_devs }}:{{ platform_vpn_api_port }}"
pritunl_api_secret: "{{ sops_vars.PRITUNL_SECRET | b64decode | replace('\r', '') }}"
pritunl_api_token: "{{ sops_vars.PRITUNL_TOKEN | b64decode | replace('\r', '') }}"
organization: "{{ input_pritunl_org | default(platform_pritunl_org_default, true) | upper }}"
user_name: '{{ input_pritunl_user | lower }}'
user_email: '{{ input_pritunl_email | lower }}'
user_disabled: false
when: input_pritunl_action is defined and input_pritunl_action == 'enable'
- name: --|| DISABLE PRITUNL VPN USER ({{ input_pritunl_user | upper }})
community.general.pritunl_user:
pritunl_url: "{{ platform_web_protocol }}{{ platform_vpn_server_devs }}:{{ platform_vpn_api_port }}"
pritunl_api_secret: "{{ sops_vars.PRITUNL_SECRET | b64decode | replace('\r', '') }}"
pritunl_api_token: "{{ sops_vars.PRITUNL_TOKEN | b64decode | replace('\r', '') }}"
organization: "{{ input_pritunl_org | default(platform_pritunl_org_default, true) | upper }}"
user_name: '{{ input_pritunl_user | lower }}'
user_email: '{{ input_pritunl_email | lower }}'
user_disabled: true
when: input_pritunl_action is defined and input_pritunl_action == 'disable'
when: true
when: true

View file

@ -123,6 +123,38 @@ function dialog_input_menu() {
}
# Dialog Main Menu
function menu_actions() {
local head_menu="$1"
local keys=$(echo -e "$2")
local rows=$3
options=()
while IFS= read -r line
do
name=$(echo "$line" | cut -d':' -f2)
index=$(echo "$line" | cut -d':' -f1)
options+=("${index}" "${name}")
((rows++))
done <<< "$keys"
choice=$(dialog --clear \
--erase-on-exit \
--cancel-label "${head_exit}" \
--backtitle "${title}" \
--title "${apps_title}" \
--menu "\n${head_menu}" \
${rows} 56 2 \
"${options[@]}" \
2>&1 >/dev/tty)
if [ $? -ne 0 ]
then
choice="${head_key_end}"
fi
echo "${choice}"
}
# Dialog Select File Box Input
function dialog_input_filepath() {

View file

@ -37,6 +37,7 @@ head_nodockerfile="No existe el archivo de configuración Dockerfile"
head_nobuilded="No se pudo completar la construcción del contenedor"
head_builded="Construcción del contenedor completada!"
head_zip="Utilitario zip no ha sido instalado!"
head_key_end="999999END"
head_container="Generando contenedor"
label_email="Correo Electrónico:"

48
bin/msg/pritunl.es Normal file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env bash
#bash script : pritunl.es
#apps : Pritunl VPN Utilities
#description : Pritunl VPN Translate Messages (es)
#author : MRP/mrp - Mauro Rosero P.
#company email : mauro@rosero.one
#personal email : mauro.rosero@gmail.com
#date : 20250101
#version : 1.0.2
#notes :
#==============================================================================
#==============================================================================
plmsg_000="(PRITUNL VPN TOOLS)"
plmsg_001="- PRITUNL VPN"
plmsg_002="Ansible no ha sido instalado!"
plmsg_003_1="Uso:"
plmsg_003_2="[--help] [--version] "
plmsg_004="Descripción: Este script permite gestionar usuarios de PRITUNL VPN."
plmsg_005="Opciones:"
plmsg_006=" --help Muestra este mensaje de ayuda."
plmsg_007=" --version Muestra la versión del script."
plmsg_100="MENÚ PRINCIPAL"
plmsg_101="GESTIÓN DE USUARIOS VPN"
# plmnu_000 - User Main Manu Keys
plmnu_k01="C"
plmnu_k02="A"
plmnu_k03="I"
plmnu_k04="E"
# plmnu_000 - User Main Manu Display Actions
plmnu_000="${plmnu_k01}:Crear Usuario"
plmnu_000="${plmnu_000}\n${plmnu_k02}:Activar Usuario"
plmnu_000="${plmnu_000}\n${plmnu_k03}:Inhabilitar Usuario"
plmnu_000="${plmnu_000}\n${plmnu_k04}:Eliminar Usuario"
# Input: Organización PRITUNL VPN
pllbl_000="Organización VPN"
plhlp_000="Código de Organización VPN para el usuario"
# Input: Usuario PRITUNL VPN
pllbl_001="Usuario VPN"
plhlp_001="Identifique el usuario VPN (minúsculas, sin caracteres especiales y espacios)"
# Input: Email VPN
pllbl_002="Email VPN"
plhlp_002="Correo Electrónico del Usuario VPN"

197
bin/vpn_users.sh Executable file
View file

@ -0,0 +1,197 @@
#!/bin/bash
#
# vpn_users.sh
# Modified: 2024/12/01 15:27:00
# Derechos de Autor (C) [2025] [Mauro Rosero P. <mauro@rosero.one> (mauro.rosero@gmail.com)]
#
# Este programa es software libre: usted puede redistribuirlo y/o modificarlo
# bajo los términos de la Licencia Pública Affero General de GNU tal como
# lo publica la Free Software Foundation, ya sea la versión 3 de la licencia,
# o (a su elección) cualquier versión posterior.
#
# Este programa se distribuye con la esperanza de que sea útil,
# pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de
# COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la
# Licencia Pública Affero General de GNU para obtener más detalles.
#
# Debería haber recibido una copia de la Licencia Pública Affero General
# junto con este programa. Si no la recibió, consulte <https://www.gnu.org/licenses/>.
DEVSPATH=devs
BIN_HOME=$HOME/$DEVSPATH
BIN_MESG=bin/msg
BIN_LIBS=bin/lib
VERSION=1.0.1
# CHECK SHELL LANGUAGE
BIN_LANG=${LANG:0:2}
# LOAD BASE BASH LIBRARY
source $BIN_HOME/$BIN_LIBS/base.lib
#baselib_test
# LOAD CONSOLE BASH LIBRARY
source $BIN_HOME/$BIN_LIBS/console.lib
#consolelib_test
# Load head messages
load_messages $BIN_HOME $BIN_MESG $BIN_LANG "head"
# Load head messages
load_messages $BIN_HOME $BIN_MESG $BIN_LANG "pritunl"
# Function to display help message
function help() {
echo "$plmsg_003_1 $0 $plmsg_003_2"
echo "$plmsg_004"
echo "$plmsg_005"
echo "$plmsg_006"
echo "$plmsg_007"
}
# Function to capture data to add, enable, disable, remove pritunl vpn users
function vpn_pritunl_users_form() {
local action=$1
declare -a response c_lbl, c_hlp, c_mod, c_opt, c_val, c_dat, c_def
# Input: Organization Pritunl VPN
c_lbl[0]="${pllbl_000}"
c_hlp[0]="${plhlp_000}"
c_mod[0]=1
c_opt[0]=0
c_def[0]="CUSTOMERS"
c_val[0]=0
c_dat[0]=""
# Input: User Pritunl VPN
c_lbl[1]="${pllbl_001}"
c_hlp[1]="${plhlp_001}"
c_mod[1]=1
c_opt[1]=0
c_def[1]=""
c_val[1]=0
c_dat[1]=""
# Input count
c_end=2
if [ "${action}" != "remove" ]; then
# Input count
c_end=3
# Input: User Email Pritunl VPN
i=2
c_lbl[$i]="${pllbl_002}"
c_hlp[$i]="${plhlp_002}"
c_mod[$i]=1
c_opt[$i]=0
c_def[$i]=""
c_val[$i]=010
c_dat[$i]=""
fi
dialog_form
if [ $? -eq 0 ]
then
display_text_header ${BIN_HOME} "${plmsg_000} ${plmsg_101}"
if [ "${action}" != "remove" ]
then
ansible-playbook -i ${BIN_HOME}/inventory/base.ini ${BIN_HOME}/bin/ansible/pritunl_users.yaml \
-e "input_pritunl_action=${action} input_pritunl_org=${response[0]} input_pritunl_user=${response[1]} input_pritunl_email=${response[2]}"
else
ansible-playbook -i $BIN_HOME/inventory/base.ini ${BIN_HOME}/bin/ansible/pritunl_users.yaml \
-e "input_pritunl_action=${action} input_pritunl_org=${response[0]} input_pritunl_user=${response[1]}"
fi
read -p "${head_pause}"
return 0
fi
}
########### MAIN PROGRAM ###########
# Check if dialog is not installed, exited!
if ! command -v dialog >/dev/null 2>&1
then
display_text_header ${BIN_HOME} "${plmsg_000} ${plmsg_101}"
echo "${head_001}"
exit 200
fi
# Check if ansible-playbook is not installed, exited!
if ! command -v ansible-playbook >/dev/null 2>&1
then
display_text_header ${BIN_HOME} "${plmsg_000} ${plmsg_101}"
echo "${plmsg_002}"
exit 210
fi
# Check for arguments option
help=false
version=false
while [[ $# -gt 0 ]]; do
case $1 in
--help)
help=true
shift
;;
--version)
version=true
shift
;;
esac
done
# Check to show help
if $help; then
help
exit 0
fi
# Check to show command version
if $version; then
echo "${head_version} ${VERSION}"
exit 0
fi
# Set program title
APPS_NAME="${head_000} ${head_002}"
title="${APPS_NAME} ${plmsg_001}"
apps_title="${plmsg_101}"
# Check if os is valid!
get_osname
if [ "${os_name}" == "${head_unknow}" ]
then
dialog_error_box "${head_error}" "${head_os_error}"
exit 3
fi
# Main Menu (users actions)
menu_option=""
menu_action=""
while [ "${menu_option}" != "${head_key_end}" ]
do
menu_option=$(menu_actions "${plmsg_100}" "${plmnu_000}" 8)
case "${menu_option}" in
"${plmnu_k01}")
menu_action="add"
vpn_pritunl_users_form "${menu_action}"
;;
"${plmnu_k02}")
menu_action="enable"
vpn_pritunl_users_form "${menu_action}"
;;
"${plmnu_k03}")
menu_action="disable"
vpn_pritunl_users_form "${menu_action}"
;;
"${plmnu_k04}")
menu_action="remove"
vpn_pritunl_users_form "${menu_action}"
;;
esac
done
# Clear console and exit
clear
exit 0

12
inventory/base.ini Normal file
View file

@ -0,0 +1,12 @@
# DEVOPS PLATFORM BASE INVENTORY
# File inventory/base.ini
# Created 2024-06-14-00:12:00
# Updated 2024-06-14-00:12:00
[all]
localhost ansible_connection=local
stations ansible_connection=local
[install]
stations

View file

@ -0,0 +1,66 @@
---
# DEVS ANSIBLE DEFINITIONS
# File inventory/group_vars/all/connections.yml
# Global Definitions & Parameters
# Created 2024-03-14-00:12:00
# Updated 2024-06-01-00:41:00
# Devops Default Path Configuration
# Base & Default configuration
timeout_connection: 15
bootstrap_wait_for_host: false
default_tz: "America/Panama"
default_lang: "{{ lookup('env','DEVS_LANG') | default('es', true) }}"
timezone: "{{ lookup('env','TZ') | default(default_tz, true) }}"
ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
ansible_python_interpreter: /usr/bin/python3
ansible_today: "{{ lookup('pipe','date +%Y-%m-%d-%H:%M:%S') }}"
# Base paths
devs_default: "{{ lookup('env','DEVS_DEFAULT') | default('devs', true) }}"
home_path: "{{ lookup('env','HOME') }}"
initial_path: "{{ lookup('env','AWXPATH') | default(home_path + '/' + devs_default, true) }}"
bin_path: "{{ initial_path }}/bin"
playbook_path: "{{ bin_path }}/ansible"
include_path: "{{ playbook_path }}/includes"
role_path: "{{ playbook_path }}/roles"
collection_path: "{{ playbook_path }}/collections"
assert_path: "{{ playbook_path }}/asserts"
# Inventory paths
inventory_default: "{{ initial_path }}/inventory }}/"
inventory_path: "{{ lookup('env','INV_PATH') | default(inventory_default, true) }}"
inventory_group_path: "{{ lookup('env','INV_GROUP') | default(inventory_path + 'group_vars', true) }}"
inventory_host_path: "{{ lookup('env','INV_HOST') | default(inventory_path + 'host_vars', true) }}"
inventory_all_path: "{{ lookup('env','INV_ALL') | default(default(inventory_group_path + '/all', true) }}"
# Messages definitions
messages_path: "{{ lookup('env','MESSAGES_PATH')| default(playbook_path + '/messages', true) }}"
messages_prefix: "MESG"
# ssh configuration
ssh_default_path: "{{ home_path }}/.ssh"
ssh_prefix_devops: id_github_rsa
ssh_prefix_server: id_rsa
ssh_pri_devops_default: "{{ ssh_prefix_devops }}"
ssh_pub_devops_default: "{{ ssh_prefix_devops }}.pub"
ssh_pri_server_default: "{{ ssh_prefix_server }}"
ssh_pub_server_default: "{{ ssh_prefix_server }}.pub"
ssh_forced: no
ssh_key_type: RSA
ssh_key_size: 4096
# Messages types
info: "INFO: "
warn: "ALERTA: "
fail: "ERROR: "
# Templates paths
template_path: "{{ lookup('env','TEMPLATE_PATH') | default(bin_path + '/templates', true) }}"
# Managed paths
managed_path: "/etc/managed"
# Temporal update flag files
ansible_remote_tmp: /tmp

View file

@ -0,0 +1,34 @@
---
# DEVOPS PLATFORM
# GLOBAL OWNER DATA
# File inventory/group_vars/all/owner.yml
# Global Definitions & Parameters
# Created 2024-03-14-00:12:00
# Updated 2024-06-01-00:41:00
# Devops Default Path Configuration
platform_name: "DEVOPS ROSERO ONE"
platform_domain: "rosero.one"
platform_devops_group: 'Devops'
platform_owner_user: "mrosero"
platform_owner_fname: 'Mauro'
platform_owner_mname: ' '
platform_owner_lname: 'Rosero'
platform_owner_sname: 'Pérez'
platform_owner_codename: 'gandalf'
platform_owner_fullname: "{{ platform_owner_fname }}{ platform_owner_mname }}{{ platform_owner_lname }} {{ platform_owner_sname }}"
platform_owner_email: "{{ platform_owner_fname | lower }}@{{ platform_domain }}"
platform_devops_email: "{{ platform_devops_group | lower }}@{{ platform_domain }}"
platform_owner_web: "{{ platform_owner_fname | lower }}.{{ platform_domain }}"
platform_git_server: "git.{{ platform_domain }}"
platform_vpn_server_devs: "vpnc.{{ platform_domain }}"
platform_web_protocol: "https://"
platform_vpn_api_port: 9443
platform_pritunl_org_default: CUSTOMERS
platform_pritunl_usr_default: false
platform_pritunl_img_default: false
platform_ssh_owner: true
platform_owner_sshkey: "{{ lookup('env','OWNER_SSHPATH') | default(ssh_default_path, true) }}"
linux_user_owner_uid: 10005

View file

@ -0,0 +1,19 @@
---
# DEVOPS PLATFORM
# GLOBAL SOPS CREDENTIALS DEFINITIONS
# File inventory/group_vars/all/sops.yaml
# Global Definitions & Parameters
# Created 2024-03-14-00:12:00
# Updated 2024-06-01-00:41:00
# Devops Secret OperationS Encrypted Data
sops_secure: "secure/sops"
sops_devops_default: "{{ initial_path }}/sops"
sops_personal_default: "{{ home_path }}/{{ sops_secure }}"
sops_peronal_path: "{{ lookup('env','SOPS_PERSONAL')|default(sops_personal_default, true) }}"
sops_devops_path: "{{ lookup('env','SOPS_DEVOPS')|default(sops_devops_default, true) }}"
# SopS Secure Encrypted Files
sops_vpnadm_file: "{{ sops_peronal_path }}/vpnadm-rosero-one.yaml"