From 4ebff9e687b452c52f0cb85420c2c8fe219db6ad Mon Sep 17 00:00:00 2001 From: Siphonight Date: Mon, 20 Jan 2025 21:04:52 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20fonctionnalit=C3=A9s=20majeures=20?= =?UTF-8?q?et=20bugfix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajout du menu des administrateurs et préparation pour les futures features d'administration du bastion. Les administrateurs n'ont plus accès à un terminal bash désormais afin de controler leurs droits et ne permettre que les actions prévues dans la configuration. FEATURES : Ajout de la fonctionnalité de lecture des sessions utilisateurs depuis le menu du bastion des administrateurs. Ajout de la première partie de la fonctionnalité de modification des droits d'accès sur les serveurs distants. Le groupe "bastionadmins" est désormais utilisé au sein du bastion afin de déterminer les utilisateurs ayant les droits d'administration. Les droits d'administrations sont désormais gérés au sein d'un fichier qui sera par la suite modifiable aussi bien lors du déploiement du conteneur (et lors de la génération de la configuration des utilisateurs) que par les administrateurs habilités au travers du menu d'administration (COMING VERY SOON). BUGFIX : Les utilisateurs ne faisant partie d'aucun groupe (bastionadmin ou bastionuser) n'ont désormais plus d'accès au serveur. AFTERNOTES : Les configurations actuelles n'ont pas besoin de modifications à proprement parler, cependant les utilisateurs ayant des droits d'administration doivent désormais utiliser le fichier "admin_rights" afin de pouvoir exercer leurs privilèges au sein du bastion. La prochaine release sera publiée après le prochain commit, qui permettra de finir les derniers ajustements et fixer les rpoblèmes constatés. --- Dockerfile | 9 ++- admin_menu.sh | 170 +++++++++++++++++++++++++++++++++++++++++ admin_rights.txt | 2 + authorized_servers.txt | 1 + entrypoint.sh | 21 ++++- server_menu.sh | 6 +- sshd_config | 5 ++ 7 files changed, 203 insertions(+), 11 deletions(-) create mode 100644 admin_menu.sh create mode 100644 admin_rights.txt diff --git a/Dockerfile b/Dockerfile index 7457427..3530d49 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ FROM alpine:3.20.0 AS monosphere-builder #Setting default settings, please change them at run -ARG MONOSPHERE_VERSION="1.0.4 Alpha" +ARG MONOSPHERE_VERSION="2.0.5 Alpha" #Defining build settings @@ -13,7 +13,7 @@ USER root #Updating and installing required dependencies -RUN apk add make=4.4.1-r2 git=2.45.2-r0 gcc=13.2.1_git20240309-r0 alpine-sdk=1.0-r1 && \ +RUN apk add make=4.4.1-r2 git=2.45.3-r0 gcc=13.2.1_git20240309-r0 alpine-sdk=1.0-r1 && \ addgroup root abuild && \ mkdir -p /var/cache/distfiles && \ chmod a+w /var/cache/distfiles @@ -51,7 +51,7 @@ USER root #Preparations #Updating and installing required dependencies -RUN apk add openssh-server=9.7_p1-r4 openssh-client=9.7_p1-r4 sudo=1.9.15_p5-r0 openrc=0.54-r1 bash=5.2.26-r0 sshpass=1.10-r0 gawk=5.3.0-r1 && \ +RUN apk add openssh-server=9.7_p1-r4 openssh-client=9.7_p1-r4 sudo=1.9.15_p5-r0 openrc=0.54-r1 bash=5.2.26-r0 sshpass=1.10-r0 gawk=5.3.0-r1 nano=8.0-r0 && \ apk --no-cache add shadow=4.15.1-r0 @@ -60,12 +60,13 @@ RUN rc-update add sshd && \ mkdir -p /run/openrc && \ touch /run/openrc/softlevel - #Copying from build and adding default configuration files COPY --from=monosphere-builder /root/scripts/monosphere_banner.txt /root/scripts/monosphere_banner.txt ADD entrypoint.sh /root/scripts/ ADD server_menu.sh /opt/public/scripts/ +ADD admin_menu.sh /opt/public/scripts/ ADD authorized_servers.txt /opt/public/servers/ +ADD admin_rights.txt /opt/public/rights/ ADD bastion_users.txt /root/scripts/users/ ADD sshd_config /etc/ssh/ diff --git a/admin_menu.sh b/admin_menu.sh new file mode 100644 index 0000000..79aa2ea --- /dev/null +++ b/admin_menu.sh @@ -0,0 +1,170 @@ +#!/bin/bash + +function sessions_viewer() { + echo -e "Ci dessous les utilisateurs disponibles sur le bastion.\nVeillez sélectionner celui dont vous souhaitez visionner les accès :" + Available_Users=$(find /home/. -maxdepth 1 -type d | grep -v "\.$" | cut -d "/" -f 4) + users_counter=1 + declare -A users_map + while read -r line; do + user="${line}" + users_map[${users_counter}]="${user}" + echo "${users_counter}) ${user}" + users_counter=$((users_counter + 1)) + done <<<"${Available_Users}" + + echo "${users_counter}) Tapez 'quit' ou ${users_counter} pour revenir au menu précédent." + + read -r -p "Votre choix (1-${users_counter}): " choice + + if [[ ${choice} == "quit" ]] || [[ ${choice} == "${users_counter}" ]]; then + main_menu + elif [[ -z ${choice} ]] || [[ -z ${users_map[${choice}]} ]]; then + echo "Sélection invalide." + else + while true; do + local selected_option + selected_option="${users_map[${choice}]}" + Available_Sessions=$(find /home/"${selected_option}"/. -maxdepth 1 -type f -name "*.ttyrec" | grep -v "\.$" | cut -d "/" -f 5) + echo "Sélectionnez une session de cet utilisateur que vous souhaitez visionner :" + + sessions_counter=1 + declare -A sessions_map + while read -r line; do + session_name="${line}" + sessions_map[${sessions_counter}]="${session_name}" + echo "${sessions_counter}) ${session_name}" + sessions_counter=$((sessions_counter + 1)) + done <<<"${Available_Sessions}" + + echo "${sessions_counter}) Tapez 'quit' ou ${sessions_counter} pour vous revenir au choix d'utilisateur." + + read -r -p "Votre choix (1-${sessions_counter}): " choice + if [[ ${choice} == "quit" ]] || [[ ${choice} == "${sessions_counter}" ]]; then + sessions_viewer + elif [[ -z ${choice} ]] || [[ -z ${users_map[${choice}]} ]]; then + echo "Sélection invalide." + else + local selected_session + selected_session="${sessions_map[${choice}]}" + ttyplay /home/"${selected_option}"/"${selected_session}" + fi + done + fi + + while true; do + sessions_viewer + done + +} + +function servers_access_control() { + echo -e "Choisissez une option d'administration des serveurs ci dessous :" + echo -e "1) Ajout de fichiers clés privées/mots de passes pour l'authentification aux serveurs distants.\n2) Modification des droits d'accès aux serveurs.\n3) Tapez 'quit' ou 3 pour revenir au menu précédent." + + read -r -p "Votre choix (1-3): " choice + + case "${choice}" in + "1") + echo -e "Option non implémentée pour le moment.\nElle sera ajoutée lors d'une prochaine mise à jour." + ;; + + "2") + echo -e "Veuillez bien vérifier la syntaxe de votre configuration avant de valider cette dernière.\nPour plus d'informations, consultez la documentation de Monosphere." + nano /opt/public/servers/authorized_servers.txt + ;; + + "3" | "quit") + main_menu + ;; + + *) + echo "Sélection invalide." + ;; + esac + + while true; do + servers_access_control + done +} + +function main_menu() { + ADMIN_RIGHTS_PATH="opt/public/rights" + ADMIN_RIGHTS_FILE="/${ADMIN_RIGHTS_PATH}/admin_rights.txt" + CONNECTED_ADMIN="$(whoami)" + + ADMIN_RIGHTS=$(awk -v user="${CONNECTED_ADMIN}" ' +{ + split($3, users, ","); + for (i in users) { + if (users[i] == user) { + print $0; + } + } +}' "${ADMIN_RIGHTS_FILE}") + + if [[ -z ${ADMIN_RIGHTS} ]]; then + echo -e "Vous n'avez aucune autorisation d'administration.\nVous pouvez cependant vous connecter aux serveurs dont l'accès vous est autorisé." + fi + + echo "Veuillez sélectionner une option d'administration :" + + counter=1 + declare -A adminrights_map + while read -r line; do + admin_right=$(echo "${line}" | cut -d ' ' -f 1) + admin_right_pretty_name=$(echo "${line}" | cut -d ' ' -f 2) + adminrights_map[${counter}]="${admin_right} ${admin_right_pretty_name}" + echo "${counter}) ${admin_right_pretty_name}" + counter=$((counter + 1)) + done <<<"${ADMIN_RIGHTS}" + + echo "${counter}) Tapez 'servers_access' ou ${counter} pour vous connecter a un serveur." + counter=$((counter + 1)) + echo "${counter}) Tapez 'quit' ou ${counter} pour vous déconnecter." + + read -r -p "Votre choix (1-${counter}): " choice + + if [[ ${choice} == "servers_access" ]] || [[ ${choice} == "$((counter - 1))" ]]; then + bash /opt/public/scripts/server_menu.sh + elif [[ ${choice} == "quit" ]] || [[ ${choice} == "${counter}" ]]; then + echo "Déconnexion du bastion." + exit 0 + elif [[ -z ${choice} ]] || [[ -z ${adminrights_map[${choice}]} ]]; then + echo "Sélection invalide." + else + local selected_option + selected_option="${adminrights_map[${choice}]}" + case "$(echo "${selected_option}" | cut -d ' ' -f 1)" in + + "sessionswatch_admins") + sessions_viewer + ;; + + "serverscontrol_admins") + servers_access_control + ;; + # + # "usercontrol_admins") + # + # ;; + # + # "adminscontrol_admins") + # + # ;; + # + # "cluster_admins") + # + # ;; + + *) + echo -e "Un problème de configuration a été détecté sur \nles options du droit administrateur sélectionné.\nVeuillez contacter votre administrateur." + ;; + esac + fi + + while true; do + main_menu + done +} + +main_menu diff --git a/admin_rights.txt b/admin_rights.txt new file mode 100644 index 0000000..693afd1 --- /dev/null +++ b/admin_rights.txt @@ -0,0 +1,2 @@ +sessionswatch_admins Visionnage_des_sessions_du_bastion bastion +serverscontrol_admins Administration_des_acces_serveurs bastion diff --git a/authorized_servers.txt b/authorized_servers.txt index e69de29..952fc90 100644 --- a/authorized_servers.txt +++ b/authorized_servers.txt @@ -0,0 +1 @@ +255.255.255.256 22 example-fake-server example-fake-user bastion diff --git a/entrypoint.sh b/entrypoint.sh index c753e36..d989de5 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -2,21 +2,24 @@ if ! grep -qo "^Port ${PORT}$" /etc/ssh/sshd_config; then echo "Génération de la configuration de SSH pour le bastion Monosphere..." + echo "Port selectionne pour la connexion SSH : ${PORT}" echo "Port ${PORT}" >>/etc/ssh/sshd_config echo "#Last authentication configurations" >>/etc/ssh/sshd_config if [[ ${PASSWORD_AUTH} -eq "1" ]]; then + echo "Authentification par mot de passe autorisee." echo "PasswordAuthentication yes" >>/etc/ssh/sshd_config else + echo "Authentification par mot de passe interdite." echo "PasswordAuthentication no" >>/etc/ssh/sshd_config fi if [[ ${KEY_AUTH} -eq "1" ]]; then + echo "Authentification par clés privées autorisee." echo "PubkeyAuthentication yes" >>/etc/ssh/sshd_config else + echo "Authentification par clés privées interdite." echo "PubkeyAuthentication no" >>/etc/ssh/sshd_config fi fi -sshd -t -echo "Configuration du service SSHD de Monosphere vérifiée." echo "Monosphere active et execute les scripts personalisés" chown -R root:root /opt/custom @@ -43,6 +46,10 @@ echo "Fin de la création des groupes d'utilisateurs." echo "Création des utilisateurs en cours..." userfile=$(cat /root/scripts/users/bastion_users.txt) +if [[ -z ${userfile} ]]; then + echo "Configuration utilisateur introuvable, veuillez vérifier votre configuration." + exit 1 +fi for userinfo in ${userfile}; do user=$(echo "${userinfo}" | cut -d ';' -f 1) is_bastion=$(echo "${userinfo}" | cut -d ';' -f 2) @@ -58,6 +65,7 @@ for userinfo in ${userfile}; do if ! grep -qo "^${user} ALL=(ALL) NOPASSWD:" /etc/sudoers; then echo "${user} ALL=(ALL) NOPASSWD: /usr/local/bin/ttyplay*" | sudo EDITOR='tee -a' visudo echo "${user} ALL=(ALL) NOPASSWD: /bin/ls*" | sudo EDITOR='tee -a' visudo + echo "${user} ALL=(ALL) NOPASSWD: nano /opt/public/servers/authorized_servers.txt" fi mkdir /home/"${user}" ln -s /opt/public/scripts/server_menu.sh /home/"${user}"/server_menu.sh @@ -78,13 +86,18 @@ for userinfo in ${userfile}; do fi done echo "Création des utilisateurs terminée." -echo "Monosphere a bien été configuré et démarré avec succès." echo "Démarrage du service SSHD de Monosphere." rc-status rc-service sshd restart -echo "Le bastion Monosphere est désormais en marche." +if sshd -t; then + echo "Configuration du service SSHD de Monosphere vérifiée et valide." + echo "Monosphere a bien été configuré et démarré avec succès." +else + echo -e "Configuration du service SSHD de Monosphere invalide\n Veuillez vérifier la configuration et relancer le deploiement." + exit 1 +fi # Keep the container running tail -f /dev/null diff --git a/server_menu.sh b/server_menu.sh index 95fab8d..76d9627 100644 --- a/server_menu.sh +++ b/server_menu.sh @@ -14,7 +14,7 @@ USER_SERVERS=$(awk -v user="${CONNECTED_USER}" ' } }' "${AUTHORIZED_SERVERS_FILE}") -if [[ -z "${USER_SERVERS}" ]]; then +if [[ -z ${USER_SERVERS} ]]; then echo "Vous n'avez pas l'autorisation de vous connecter à un serveur." exit 1 fi @@ -40,10 +40,10 @@ function main_menu() { read -r -p "Votre choix (1-${counter}): " choice - if [[ "${choice}" == "quit" ]] || [[ "${choice}" == "${counter}" ]]; then + if [[ ${choice} == "quit" ]] || [[ ${choice} == "${counter}" ]]; then echo "Déconnexion du bastion." exit 0 - elif [[ -z "${choice}" ]] || [[ -z "${server_map[${choice}]}" ]]; then + elif [[ -z ${choice} ]] || [[ -z ${server_map[${choice}]} ]]; then echo "Sélection invalide." else local selected_server diff --git a/sshd_config b/sshd_config index fd8f3e8..0ce3926 100644 --- a/sshd_config +++ b/sshd_config @@ -166,7 +166,12 @@ AllowStreamLocalForwarding no Match Group bastionuser ForceCommand /opt/public/scripts/server_menu.sh X11Forwarding no +Match Group bastionadmin + ForceCommand /opt/public/scripts/admin_menu.sh + X11Forwarding no # End the 'Match' block Match all + ForceCommand echo -e "===========================================================\nSorry, you re not part of the bastion s users or administrators and have therefore no access.\nPlease contact your administrator for further informations.\n==========================================================="; exit + X11Forwarding no #Used port number