Compare commits

..

8 Commits

Author SHA1 Message Date
7c03a89335 Try new editor for 3.5.1 2026-07-05 17:15:55 +02:00
1d2bd68cdf Sortie version 3.5.0 2026-07-05 14:21:30 +02:00
db103dab71 Candidate 3.5.0 2026-07-05 14:04:28 +02:00
c03d254f90 Mise a jour de dépendances. 2025-09-06 20:13:42 +02:00
199f5f7ebb Correction de la fonction de recherche de serveurs
Correction apportée dans la liste de recherche des noms de serveurs :
(utilisable en tapant f<chaine de caractères dans le nom du serveur>)

Cette correction inclut :
- Un inversement de la liste des configurations de serveurs en entrée
  du bloc for utilisé pour lister les serveurs et chercher la chaine
  de caractères dans les noms de serveurs.
- Ajout d'une commande "echo" dans la ligne de comparaison entre les
  valeurs du filtre entré et du nom du serveur.

En effet, sans la commande "echo" dans la partie droite de la
comparaison, Bash ajoute systématiquement les backslash, ce qui casse
le méchanisme de comparaison et donne de ce fait toujours un résultat
faux.

Concernant l'inversement de la liste, utiliser simplement
"${server_map[@]}" affiche une map inversée par rapport à ce qui avait
été entré dans le bloc de création de cette map.
Pour corriger ce problème, une ligne d'inversement à été nécessaire :
> printf '%s\n' "${server_map[@]}" | tac | cut -d " " -f 6
2025-09-06 20:03:29 +02:00
e6895038a8 Amelioration sécurité de la configuration SSHD
Amélioration de la configuration de la sécurité du daemon SSHD du bastion à l'aide de l'outil ssh-audit.
(Disponible ici : https://github.com/jtesta/ssh-audit)
2025-07-24 15:25:41 +02:00
cfff11c611 Correction problème de array démarrant à 0 et non 1. 2025-02-16 15:28:16 +01:00
54a9eeacd5 Ajout de filtre + amélioration de l'interface
Ajout de la possibilité de filtrer les hôtes par leur nom dans le menu
de sélection des serveurs de connexion.

Ajout de clear dans les menus de serveur et admin afin de rendre
l'interface plus lisible pour les utilisateurs.
2025-02-16 14:54:12 +01:00
8 changed files with 493 additions and 122 deletions

View File

@ -4,7 +4,7 @@ FROM alpine:3.20.0 AS monosphere-builder
#Setting default settings, please change them at run #Setting default settings, please change them at run
ARG MONOSPHERE_VERSION="3.3.9 Alpha" ARG MONOSPHERE_VERSION="3.5.0 Alpha"
#Defining build settings #Defining build settings
@ -13,7 +13,7 @@ USER root
#Updating and installing required dependencies #Updating and installing required dependencies
RUN apk add make=4.4.1-r2 git=2.45.3-r0 gcc=13.2.1_git20240309-r0 alpine-sdk=1.0-r1 && \ RUN apk add make=4.4.1-r2 git=2.45.4-r0 gcc=13.2.1_git20240309-r1 alpine-sdk=1.0-r1 && \
addgroup root abuild && \ addgroup root abuild && \
mkdir -p /var/cache/distfiles && \ mkdir -p /var/cache/distfiles && \
chmod a+w /var/cache/distfiles chmod a+w /var/cache/distfiles
@ -51,7 +51,7 @@ USER root
#Preparations #Preparations
#Updating and installing required dependencies #Updating and installing required dependencies
RUN apk add openssh-server=9.7_p1-r4 openssh-client=9.7_p1-r4 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-r5 openssh-client=9.7_p1-r5 openrc=0.54-r1 bash=5.2.26-r0 sshpass=1.10-r0 gawk=5.3.0-r1 && \
apk --no-cache add shadow=4.15.1-r0 apk --no-cache add shadow=4.15.1-r0
@ -67,6 +67,7 @@ ADD server_menu.sh /opt/public/scripts/
ADD admin_menu.sh /opt/public/scripts/ ADD admin_menu.sh /opt/public/scripts/
ADD authorized_servers.txt /opt/public/servers/ ADD authorized_servers.txt /opt/public/servers/
ADD admin_rights.txt /opt/public/rights/ ADD admin_rights.txt /opt/public/rights/
ADD transfer_rights.txt /opt/public/rights/
ADD bastion_users.txt /root/scripts/users/ ADD bastion_users.txt /root/scripts/users/
ADD sshd_config /etc/ssh/ ADD sshd_config /etc/ssh/
@ -77,6 +78,12 @@ COPY --from=monosphere-builder /usr/local/bin/ttyrec /usr/local/bin/ttyrec
COPY --from=monosphere-builder /usr/local/bin/ttytime /usr/local/bin/ttytime COPY --from=monosphere-builder /usr/local/bin/ttytime /usr/local/bin/ttytime
#Creating transfer logs directory
RUN mkdir -p /var/log/monosphere && \
touch /var/log/monosphere/transfers.log && \
chmod 777 /var/log/monosphere && \
chmod 666 /var/log/monosphere/transfers.log
#Activating scripts ; #Activating scripts ;
RUN chmod 644 /etc/ssh/sshd_config && \ RUN chmod 644 /etc/ssh/sshd_config && \
chown -R root:root /root/scripts && \ chown -R root:root /root/scripts && \

106
README.md
View File

@ -22,6 +22,7 @@ Il offre une interface de menu permettant aux utilisateurs autorisés de se conn
- [Configuration de la connexion par clés SSH pour les utilisateurs et administrateurs](#configuration-de-la-connexion-par-clés-ssh-pour-les-utilisateurs-et-administrateurs) - [Configuration de la connexion par clés SSH pour les utilisateurs et administrateurs](#configuration-de-la-connexion-par-clés-ssh-pour-les-utilisateurs-et-administrateurs)
- [Ajout de serveurs distants dans la configuration](#ajout-de-serveurs-distants-dans-la-configuration) - [Ajout de serveurs distants dans la configuration](#ajout-de-serveurs-distants-dans-la-configuration)
- [Configuration des accès aux hotes distants](#configuration-des-accès-aux-hotes-distants) - [Configuration des accès aux hotes distants](#configuration-des-accès-aux-hotes-distants)
- [Transfert de fichiers (non-interactif)](#transfert-de-fichiers-non-interactif)
- [Scripts personnalisés](#scripts-personnalisés) - [Scripts personnalisés](#scripts-personnalisés)
- [Configuration SSH](#configuration-ssh) - [Configuration SSH](#configuration-ssh)
- [Fichiers](#fichiers) - [Fichiers](#fichiers)
@ -29,6 +30,7 @@ Il offre une interface de menu permettant aux utilisateurs autorisés de se conn
- [Audit des sessions](#audit-des-sessions) - [Audit des sessions](#audit-des-sessions)
- [Modification des accès aux hotes distants](#modification-des-accès-aux-hotes-distants) - [Modification des accès aux hotes distants](#modification-des-accès-aux-hotes-distants)
- [Modification des privilèges d'administration](#modification-des-privilèges-dadministration) - [Modification des privilèges d'administration](#modification-des-privilèges-dadministration)
- [Gestion des droits de transfert](#gestion-des-droits-de-transfert)
- [Codes d'erreurs lors du lancement du bastion](#codes-derreurs-lors-du-lancement-du-bastion) - [Codes d'erreurs lors du lancement du bastion](#codes-derreurs-lors-du-lancement-du-bastion)
- [License](#license) - [License](#license)
- [Remerciements](#remerciements) - [Remerciements](#remerciements)
@ -39,9 +41,13 @@ Voici une liste des différentes fonctionnalités déjà en place sur le bastion
- Création et configuration automatisée du bastion au lancement (ce conteneur est entièrement stateless, signifiant qu'il peut être redéployé sans souci, les configurations de ce dernier étant sous forme de fichiers). - Création et configuration automatisée du bastion au lancement (ce conteneur est entièrement stateless, signifiant qu'il peut être redéployé sans souci, les configurations de ce dernier étant sous forme de fichiers).
- Support des utilisateurs de connexion multiples pour les hôtes distants. - Support des utilisateurs de connexion multiples pour les hôtes distants.
- Support pour la connexion par clés SSH (le support pour la connexion automatisée en mot de passe est prévu.) - Support pour la connexion par clés SSH et mots de passe sur les hôtes distants.
- Sessions enregistrées et visionnables par les administrateurs du bastion ayant les autorisation appropriées. - Sessions enregistrées et visionnables par les administrateurs du bastion ayant les autorisation appropriées.
- Support pour l'execution de scripts personalisés au lancement du conteneur. - Support pour l'execution de scripts personalisés au lancement du conteneur.
- Recherche possible par nom de serveur distant dans la liste des serveurs du menu de connexion (pratique pour les grandes flottes).
- Transfert de fichiers en une commande vers les serveurs distants via `push_file`/`retrieve_file` (non-interactif, sans stockage intermédiaire).
- Contrôle des droits de transfert par serveur, gérable par les administrateurs en temps réel.
- Journalisation complète de tous les transferts (utilisateur, serveur, fichier, taille, statut).
## Pourquoi choisir ce bastion ? ## Pourquoi choisir ce bastion ?
@ -57,20 +63,23 @@ Voici une liste des différentes fonctionnalités déjà en place sur le bastion
Ci-dessous une liste non exhaustive des objectifs des prochaines mises à jour du projet: Ci-dessous une liste non exhaustive des objectifs des prochaines mises à jour du projet:
- [ ] Ajouter une option pour le transfert de fichiers au travers du bastion vers les machines distantes. - [x] Ajouter le transfert de fichiers non-interactif au travers du bastion (`push_file`/`retrieve_file`).
- [ ] Ajouter une option de recherche d'hôtes distants dans la liste des serveurs. - [x] Ajouter une option de recherche d'hôtes distants dans la liste des serveurs.
- [ ] Ajouter une option sous forme de variable d'environnement pour fournir au bastion les clés d'hôtes des machines distantes. (avec un mode confiance, strict ou test par exemple) - [ ] Ajouter une option sous forme de variable d'environnement pour fournir au bastion les clés d'hôtes des machines distantes. (avec un mode confiance, strict ou test par exemple)
- [ ] Ajouter le support pour un serveur LDAP. (Objectif sur le long terme) - [ ] Ajouter le support pour un serveur LDAP. (Objectif sur le long terme)
- [ ] Ajouter un système de mise à jour automatique dans le conteneur, évitant ainsi les redéploiements. - [ ] Ajouter un système de mise à jour automatique dans le conteneur, évitant ainsi les redéploiements.
- [x] Ajouter la possibilité de revenir dans le menu des serveurs après une déconnexion d'une machine distante. - [x] Ajouter la possibilité de revenir dans le menu des serveurs après une déconnexion d'une machine distante.
- [ ] Ajouter un système de cluster avec master/slave et synchronisation entre les nodes. - [ ] Ajouter un système de cluster avec master/slave et synchronisation entre les nodes.
- [ ] Améliorer le système de journalisation du déploiement du bastion, avec les erreurs de déploiement affichées lors de la connexion des utilisateurs internes. - [ ] Ajouter une option de gestion des droits de transfert par groupes d'utilisateurs.
- [ ] Support du chiffrement de bout en bout pour les transferts de fichiers sensibles.
- [x] Améliorer le système de journalisation du déploiement du bastion, avec les erreurs de déploiement affichées lors de la connexion des utilisateurs internes.
- [x] Ajouter un menu d'administration et de gestion lors de la connexion des utilisateurs internes du bastion. - [x] Ajouter un menu d'administration et de gestion lors de la connexion des utilisateurs internes du bastion.
- [x] Créer des rôles administrateur/inspecteur avec des droits différents au sein du bastion. - [x] Créer des rôles administrateur/inspecteur avec des droits différents au sein du bastion.
Correction en cours pour les bugs ci dessous : Corrections de la version 3.5.0 :
Aucun bug n'a été détecté dans les configuration et scripts actuels du bastion, ou ces derniers ont bien été corrigés. - [x] Correction de la récursion infinie dans le visionnage des sessions (`sessions_viewer`).
- [x] Correction du filtre utilisateur dans le menu d'administration (typo `user_map` → `users_map`, `user_counter` → `users_counter`).
Veuillez signaler tout problème rencontré en envoyant un email à l'adresse "**<crossghostmansiphonight@gmail.com>**", détaillant le problème ainsi que le contexte entourant le constat de ce dernier. Veuillez signaler tout problème rencontré en envoyant un email à l'adresse "**<crossghostmansiphonight@gmail.com>**", détaillant le problème ainsi que le contexte entourant le constat de ce dernier.
@ -125,7 +134,8 @@ docker run -d -p 22:22 \
-v /datasets/monosphere-bastion/servers:/opt/public/servers \ -v /datasets/monosphere-bastion/servers:/opt/public/servers \
-v /datasets/monosphere-bastion/custom-scripts:/opt/custom/scripts \ -v /datasets/monosphere-bastion/custom-scripts:/opt/custom/scripts \
-v /datasets/monosphere-bastion/users:/root/scripts/users \ -v /datasets/monosphere-bastion/users:/root/scripts/users \
-v /datasets/monosphere-bastion/admin_rights:/opt/public/rights \ -v /datasets/monosphere-bastion/rights:/opt/public/rights \
-v /datasets/monosphere-bastion/logs:/var/log/monosphere \
-p "22:22" \ -p "22:22" \
--name monosphere-bastion siphonight/monosphere-bastion:latest --name monosphere-bastion siphonight/monosphere-bastion:latest
``` ```
@ -148,7 +158,8 @@ services:
- /datasets/monosphere-bastion/servers:/opt/public/servers - /datasets/monosphere-bastion/servers:/opt/public/servers
- /datasets/monosphere-bastion/custom-scripts:/opt/custom/scripts - /datasets/monosphere-bastion/custom-scripts:/opt/custom/scripts
- /datasets/monosphere-bastion/users:/root/scripts/users - /datasets/monosphere-bastion/users:/root/scripts/users
- /datasets/monosphere-bastion/admin_rights:/opt/public/rights - /datasets/monosphere-bastion/rights:/opt/public/rights
- /datasets/monosphere-bastion/logs:/var/log/monosphere
ports: ports:
- 22:22 - 22:22
restart: unless-stopped restart: unless-stopped
@ -171,7 +182,8 @@ A noter que mettre la valeur à "1" pour **PASSWORD_AUTH** ne générera pas de
| **/opt/public/servers** | Le répertoire doit contenir un fichier nommé "**authorized_servers.txt**", contenant les autorisations de connexion et la liste des informations de machines distantes. Si vous utilisez l'authentification par clés privés ou par mots de passe pré-renseignés pour la connexion aux hôtes distants vous devez également ajouter les fichiers de ces dernières dans ce même répertoire. | *Ce fichier est ce qui vas gérer les droits accordés aux comptes sur les différents serveurs distants en temps réel. Une modification du fichier entrainera donc directement une modification au niveau des droits de connexion des utilisateurs, et des serveurs auquels le bastion permettra la connexion.* | | **/opt/public/servers** | Le répertoire doit contenir un fichier nommé "**authorized_servers.txt**", contenant les autorisations de connexion et la liste des informations de machines distantes. Si vous utilisez l'authentification par clés privés ou par mots de passe pré-renseignés pour la connexion aux hôtes distants vous devez également ajouter les fichiers de ces dernières dans ce même répertoire. | *Ce fichier est ce qui vas gérer les droits accordés aux comptes sur les différents serveurs distants en temps réel. Une modification du fichier entrainera donc directement une modification au niveau des droits de connexion des utilisateurs, et des serveurs auquels le bastion permettra la connexion.* |
| **/opt/custom/scripts** | Ce répertoire doit contenir les scripts personnalisés de l'utilisateur, tous avec l'extension ".sh". Ces derniers seront exécutés avec le compte root au lancement du conteneur. | *Ces scripts peuvent servir à personnaliser plus amplement le conteneur du bastion, en modifiant par exemple la bannière en temps réel ou bien en changeant les paramètres du bastion qui ne sont pas disponibles avec une modification par variables d'environnement ou volumes.* | | **/opt/custom/scripts** | Ce répertoire doit contenir les scripts personnalisés de l'utilisateur, tous avec l'extension ".sh". Ces derniers seront exécutés avec le compte root au lancement du conteneur. | *Ces scripts peuvent servir à personnaliser plus amplement le conteneur du bastion, en modifiant par exemple la bannière en temps réel ou bien en changeant les paramètres du bastion qui ne sont pas disponibles avec une modification par variables d'environnement ou volumes.* |
| **/root/scripts/users** | Un fichier nommé "**bastion_users.txt**" contenant la liste des utilisateurs et de leurs paramètres de configuration. La syntaxe exacte de ce fichier est précisée plus bas dans la section "**Ajout d'utilisateurs**". Si vous activez l'option pour l'authentification par clé, vous devez également placer ici les dossiers aux noms des utilisateurs ajoutés ayant le contenu de leur répertoire "**.ssh**" avec les fichiers des clés publiques de connexion à l'utilisateur. | *Grace à ces paramètres, il est possible d'utiliser ce conteneur bastion de manière 100% stateless, car le redéployer en utilisant la même configuration et les mêmes fichiers permet de répliquer les mêmes comportements.* | | **/root/scripts/users** | Un fichier nommé "**bastion_users.txt**" contenant la liste des utilisateurs et de leurs paramètres de configuration. La syntaxe exacte de ce fichier est précisée plus bas dans la section "**Ajout d'utilisateurs**". Si vous activez l'option pour l'authentification par clé, vous devez également placer ici les dossiers aux noms des utilisateurs ajoutés ayant le contenu de leur répertoire "**.ssh**" avec les fichiers des clés publiques de connexion à l'utilisateur. | *Grace à ces paramètres, il est possible d'utiliser ce conteneur bastion de manière 100% stateless, car le redéployer en utilisant la même configuration et les mêmes fichiers permet de répliquer les mêmes comportements.* |
| **/opt/public/rights** | Ce répertoire doit contenir un fichier nommé "**admin_rights**", complété avec les droits administratifs sur le bastion et des utilisateurs auquels ces droits sont accordés. | *Les droits inscrits dans ce fichier sont mis à jour en temps réels. Veuillez vous assurer que ces derniers sont corrects et attribués aux administrateurs souhaités.* | | **/opt/public/rights** | Ce répertoire doit contenir les fichiers "**admin_rights.txt**" (droits d'administration) et "**transfer_rights.txt**" (droits de transfert). | *Les droits inscrits dans ces fichiers sont mis à jour en temps réel. Veuillez vous assurer que ces derniers sont corrects et attribués aux utilisateurs et administrateurs souhaités.* |
| **/var/log/monosphere** | Le fichier "**transfers.log**" est créé automatiquement. | *Répertoire contenant les logs de transfert de fichiers. Accessible en consultation depuis le menu admin.* |
A noter que les droits mis sur les fichiers et dossiers configurés dans ces volumes ne sont pas importants, car ces derniers sont adaptés lors du déploiement du conteneur bastion. A noter que les droits mis sur les fichiers et dossiers configurés dans ces volumes ne sont pas importants, car ces derniers sont adaptés lors du déploiement du conteneur bastion.
@ -243,6 +255,7 @@ Explication des différents droits d'administration disponibles :
- **sessionswatch_admins** : Ce droit permet aux administrateurs le possédant de lire et visionner les sessions de connexion de tout les utilisateurs et administrateurs du bastion. - **sessionswatch_admins** : Ce droit permet aux administrateurs le possédant de lire et visionner les sessions de connexion de tout les utilisateurs et administrateurs du bastion.
- **serverscontrol_admins** : Ce droit donne la possibilité de modifier les accès des utilisateurs et administrateurs du bastion aux hôtes distants, ainsi que les méthodes d'authentification et la configuration des serveurs distants. - **serverscontrol_admins** : Ce droit donne la possibilité de modifier les accès des utilisateurs et administrateurs du bastion aux hôtes distants, ainsi que les méthodes d'authentification et la configuration des serveurs distants.
- **adminscontrol_admins** : Ce droit permet de modifier l'attribution des autres droits. Un administrateur possédant ce dernier peut de ce fait gérer les privilèges des autres administrateurs du bastion, *y compris lui même*. - **adminscontrol_admins** : Ce droit permet de modifier l'attribution des autres droits. Un administrateur possédant ce dernier peut de ce fait gérer les privilèges des autres administrateurs du bastion, *y compris lui même*.
- **transfercontrol_admins** : Ce droit permet de gérer les droits de transfert de fichiers des utilisateurs du bastion. Un administrateur possédant ce droit peut éditer le fichier `transfer_rights.txt` pour autoriser ou restreindre les transferts vers les serveurs distants.
Dans l'exemple ci dessus, l'administrateur "bastion" à le droit de lire les sessions de connexion mais également de modifier les paramètres des connexions et accès aux serveurs distants ainsi que de donner ou de retirer des droits aux autres administrateurs du bastion. L'administrateur "vieweradmin" quant à lui n'a qu'un droit de lecture des sessions du bastion, et ne pourra pas effectuer de modifications. Dans l'exemple ci dessus, l'administrateur "bastion" à le droit de lire les sessions de connexion mais également de modifier les paramètres des connexions et accès aux serveurs distants ainsi que de donner ou de retirer des droits aux autres administrateurs du bastion. L'administrateur "vieweradmin" quant à lui n'a qu'un droit de lecture des sessions du bastion, et ne pourra pas effectuer de modifications.
@ -264,7 +277,7 @@ Ce fichier devra avoir la syntaxe suivante pour chacune de ses lignes :
Explication des valeurs possibles : Explication des valeurs possibles :
- **Nom de l'utilisateur** : Définit le nom de l'utilisateur. Ce dernier doit être entièrement en minuscules et peut contenir des carachtères alphanumériques. - **Nom de l'utilisateur** : Définit le nom de l'utilisateur. Ce dernier doit être entièrement en minuscules et peut contenir des carachtères alphanumériques.
- **1** : Permet de définir le compte comme étant celui d'un tuilisateur. - **1** : Permet de définir le compte comme étant celui d'un utilisateur.
- **hash du mot de passe** : Champ pour entrer le mot de passe de l'utilisateur au format hashé si il en a un. Il est possible de ne pas donner de mot de passe à l'utilisateur en mettant "0" à cet endroit. Dans ce cas le mot de passe ce cet utilisateur sera le nom de lui même (par exemple, l'utilisateur sans mot de passe "user1" aura de ce fait pour mot de passe "user1"). Pour obtenir le hash du mot de passe que vous souhaitez utiliser pour cet utilisateur, lancez la commande ci dessous dans un terminal sous Linux et utilisez son résultat EXACT comme valeur pour ce champ : - **hash du mot de passe** : Champ pour entrer le mot de passe de l'utilisateur au format hashé si il en a un. Il est possible de ne pas donner de mot de passe à l'utilisateur en mettant "0" à cet endroit. Dans ce cas le mot de passe ce cet utilisateur sera le nom de lui même (par exemple, l'utilisateur sans mot de passe "user1" aura de ce fait pour mot de passe "user1"). Pour obtenir le hash du mot de passe que vous souhaitez utiliser pour cet utilisateur, lancez la commande ci dessous dans un terminal sous Linux et utilisez son résultat EXACT comme valeur pour ce champ :
```bash ```bash
@ -375,6 +388,50 @@ Si vous souhaitez vous connecter sur la même machine distante mais avec un util
A savoir qu'il est également possible d'utiliser des noms de domaine DNS à la place d'une adresse IP, mais prenez en compte le fait que la résolution de nom se fera au niveau du bastion et non du client. A savoir qu'il est également possible d'utiliser des noms de domaine DNS à la place d'une adresse IP, mais prenez en compte le fait que la résolution de nom se fera au niveau du bastion et non du client.
### Transfert de fichiers (non-interactif)
Depuis la version 3.5.0, le bastion Monosphere supporte le transfert de fichiers vers les serveurs distants via des commandes SSH non-interactives. Aucun menu interactif n'est nécessaire, le transfert s'effectue directement depuis votre machine en une seule commande.
#### Prérequis
- Vous devez être autorisé à vous connecter au serveur distant (présent dans `authorized_servers.txt`).
- Vous devez avoir les droits de transfert pour ce serveur (configurés dans `transfer_rights.txt`, ou fichier absent = autorisé).
- Le bastion doit avoir accès au serveur distant (clé SSH ou mot de passe préconfiguré dans `authorized_servers.txt`).
#### Push — Envoyer un fichier vers un serveur distant
Depuis votre machine locale, envoyez un fichier directement vers un serveur distant à travers le bastion :
```bash
cat application.conf | ssh bastion_admin@bastion 'push_file serveur-prod /etc/app/application.conf'
```
Le fichier est transféré en une étape : il traverse le bastion et atterrit directement sur le serveur cible. Aucun stockage temporaire sur le bastion.
**Exemple concret :** Envoyer une archive de backup :
```bash
tar czf - /home/user/documents | ssh admin@bastion 'push_file serveur-backup /backups/documents-$(date +%F).tar.gz'
```
#### Pull — Récupérer un fichier depuis un serveur distant
```bash
ssh bastion_admin@bastion 'retrieve_file serveur-prod /var/log/app/error.log' > error.log
```
Le fichier est lu depuis le serveur distant et écrit sur stdout. Redirigez-le vers un fichier local.
**Exemple concret :** Récupérer plusieurs fichiers en une passe :
```bash
for f in access.log error.log audit.log; do
ssh admin@bastion "retrieve_file serveur-prod /var/log/nginx/\$f" > "./logs/\$f"
done
```
#### Journalisation
Tous les transferts (push, retrieve) sont horodatés et journalisés dans `/var/log/monosphere/transfers.log` avec l'utilisateur, le serveur cible, le fichier, la taille et le statut. Les administrateurs peuvent consulter ces logs depuis le menu admin (option `logs`).
### Scripts personnalisés ### Scripts personnalisés
Vous pouvez ajouter des scripts personnalisés qui seront exécutés au démarrage du conteneur. Placez vos scripts dans le répertoire **/opt/custom/scripts/**. Vous pouvez ajouter des scripts personnalisés qui seront exécutés au démarrage du conteneur. Placez vos scripts dans le répertoire **/opt/custom/scripts/**.
@ -410,6 +467,7 @@ Ne modifiez jamais ces paramètres cela pourrait provoquer des problèmes de sé
- **admin_menu.sh** : Script permettant aux administrateurs d'exercer leurs droits au travers d'un menu controllé en fonction de leurs autorisations sur le bastion. - **admin_menu.sh** : Script permettant aux administrateurs d'exercer leurs droits au travers d'un menu controllé en fonction de leurs autorisations sur le bastion.
- **admin_rights.txt** : Liste des droits administratifs sur le bastion et ses ressources, exclusive aux administraturs du bastion. - **admin_rights.txt** : Liste des droits administratifs sur le bastion et ses ressources, exclusive aux administraturs du bastion.
- **transfer_rights.txt** : Liste des droits de transfert de fichiers par serveur, permettant de controler quels utilisateurs peuvent transferer des fichiers vers quels serveurs distants.
- **authorized_servers.txt** : Liste des utilisateurs autorisés et des serveurs correspondants. - **authorized_servers.txt** : Liste des utilisateurs autorisés et des serveurs correspondants.
- **bastion_users.txt** : Liste servant à générer les utilisateurs et administrateurs du bastion et contenant leurs paramètres de création. - **bastion_users.txt** : Liste servant à générer les utilisateurs et administrateurs du bastion et contenant leurs paramètres de création.
- **Dockerfile** : Le fichier Dockerfile pour construire l'image Monosphere Bastion. - **Dockerfile** : Le fichier Dockerfile pour construire l'image Monosphere Bastion.
@ -573,6 +631,34 @@ Veuillez à ce que ce fichier ne comporte pas d'erreurs, ce dernier étant appli
Référez vous à la partie [Ajout d'administrateurs](#ajout-dadministrateurs) pour plus d'informations. Référez vous à la partie [Ajout d'administrateurs](#ajout-dadministrateurs) pour plus d'informations.
### Gestion des droits de transfert
Depuis la version 3.5.0, il est possible de controler quels utilisateurs peuvent transferer des fichiers vers quels serveurs distants.
Pour modifier ces droits, connectez-vous avec un administrateur disposant de la permission "transfercontrol_admins" et sélectionnez l'option "Gestion_des_droits_de_transfert" :
```text
@@@@@@@@@@[Welcome to the Monosphere bastion]@@@@@@@@@@
[...]
Veuillez sélectionner une option d'administration :
1) Gestion_des_droits_de_transfert
2) ...
Votre choix (1-X): 1
```
Le fichier `transfer_rights.txt` se trouve dans `/opt/public/rights/`. Son format est le suivant :
```text
# Format: nom_serveur user1,user2,...
# Les utilisateurs listés peuvent transferer des fichiers vers ces serveurs.
serveur1 alice,bob
serveur2 *
```
- Si le fichier est vide ou absent, **tous les utilisateurs** autorisés (via `authorized_servers.txt`) peuvent transferer des fichiers (comportement par défaut).
- Le caractère `*` permet d'autoriser **tous les utilisateurs** pour un serveur donné.
- Les modifications sont appliquées en temps réel, sans redémarrage du conteneur.
### Codes d'erreurs lors du lancement du bastion ### Codes d'erreurs lors du lancement du bastion
Si lors du déploiement du bastion vous obtenez des messages indiquant "[ NOOK ] Code XX", veuillez consulter cette section, elle détaille la signification de chacun d'entre eux. Si lors du déploiement du bastion vous obtenez des messages indiquant "[ NOOK ] Code XX", veuillez consulter cette section, elle détaille la signification de chacun d'entre eux.

View File

@ -1,95 +1,166 @@
#!/bin/bash #!/bin/bash
if [[ -n ${SSH_ORIGINAL_COMMAND} ]]; then
bash /opt/public/scripts/server_menu.sh
exit $?
fi
function secure_file_editor() { function secure_file_editor() {
File_Path="${*}" local file_path="${*}"
echo -e "\n=====SECURE=FILE=EDITOR=====" local -a lines=()
if [[ -e ${File_Path} ]]; then local cmd rest line_num new_content modified=0
echo "Le fichier selectionne existe et a pour contenu :"
cat "${File_Path}" if [[ -f ${file_path} ]]; then
read -r -p 'Souhaitez vous modifier le contenu du fichier ? (y/n) : ' choice while IFS= read -r line; do
else lines+=("${line}")
echo "Creation d un nouveau fichier \"${File_Path}\"." done < "${file_path}"
touch "${File_Path}"
choice="y"
fi fi
case ${choice} in
"y" | "Y") echo ""
printf '%s\n' " Consignes d'utilisation de cet editeur : - Lorsque l'edition du fichier est achevee, entrez ctrl-d sur une ligne vide pour sortir. - ATTENTION : Copiez les lignes que vous souhaitez garder intactes, le contenu du fichier complet sera ecrase par ce qui suit. - Tout fichier vide sera supprime. :" echo "===== SECURE FILE EDITOR ====="
New_Content+=$(xargs -0) echo "Fichier : ${file_path}"
echo "${New_Content}" >"${File_Path}" echo ""
;;
"n" | "N") set +H
echo "Edition du fichier abandonnee." while true; do
;; echo "--- Lignes ${#lines[@]} ---"
if [[ ${#lines[@]} -eq 0 ]]; then
echo "(fichier vide)"
else
for i in "${!lines[@]}"; do
printf '%3d: %s\n' $((i + 1)) "${lines[${i}]}"
done
fi
echo "---------------------------"
echo "e <n> <texte> - Remplacer la ligne n"
echo "i <n> <texte> - Inserer apres la ligne n (0 = debut)"
echo "d <n> - Supprimer la ligne n"
echo "wq - Enregistrer et quitter"
echo "q! - Quitter sans enregistrer"
echo ""
*) read -r -p "> " input
echo "Selection invalide." cmd="${input%% *}"
;; rest="${input#* }"
esac
unset New_Content case "${cmd}" in
unset File_Path e)
echo "Modifications appliquées." line_num="${rest%% *}"
echo -e "=====SECURE=FILE=EDITOR=====\n" new_content="${rest#* }"
if [[ ${line_num} =~ ^[0-9]+$ ]] && (( line_num >= 1 && line_num <= ${#lines[@]} )); then
lines[$((line_num - 1))]="${new_content}"
modified=1
else
echo "Ligne invalide (1-${#lines[@]})."
fi
;;
i)
line_num="${rest%% *}"
new_content="${rest#* }"
if [[ ${line_num} =~ ^[0-9]+$ ]] && (( line_num >= 0 && line_num <= ${#lines[@]} )); then
lines=("${lines[@]:0:line_num}" "${new_content}" "${lines[@]:line_num}")
modified=1
else
echo "Position invalide (0-${#lines[@]})."
fi
;;
d)
line_num="${rest}"
if [[ ${line_num} =~ ^[0-9]+$ ]] && (( line_num >= 1 && line_num <= ${#lines[@]} )); then
unset 'lines[$((line_num - 1))]'
lines=("${lines[@]}")
modified=1
else
echo "Ligne invalide (1-${#lines[@]})."
fi
;;
wq)
if [[ ${modified} -eq 1 ]] || [[ ! -f ${file_path} ]]; then
printf '%s\n' "${lines[@]}" > "${file_path}"
if [[ ${#lines[@]} -eq 0 ]]; then
rm -f "${file_path}"
echo "Fichier vide, supprime."
else
echo "Fichier enregistre (${#lines[@]} lignes)."
fi
else
echo "Aucune modification."
fi
break
;;
q|'q!')
echo "Abandon."
break
;;
*)
echo "Commandes : e <n> <txt>, i <n> <txt>, d <n>, wq, q!"
;;
esac
echo ""
done
echo ""
} }
function sessions_viewer() { 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
local selected_option
selected_option="${users_map[${choice}]}"
while true; do
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 ${sessions_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 while true; do
sessions_viewer echo -e "Ci dessous les utilisateurs disponibles sur le bastion.\nVeillez sélectionner celui dont vous souhaitez visionner les accès :"
done Available_Users=$(find /home/. -maxdepth 1 -type d | grep -v "\.$" | cut -d "/" -f 4)
users_counter=0
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 (0-${users_counter}): " choice
if [[ ${choice} == "quit" ]] || [[ ${choice} == "${users_counter}" ]]; then
return
elif [[ $(echo "${choice}" | cut -c1-1) == "f" ]]; then
filter=$(echo "${choice}" | cut -c2-)
echo "=====Résultats du filtre====="
for idx in "${!users_map[@]}"; do
if [[ ${users_map[${idx}]} == *"${filter}"* ]]; then
echo "${idx}) ${users_map[${idx}]}"
fi
done
read -r -p "Votre choix (0-${users_counter}) : " choice
elif [[ -z ${choice} ]] || [[ -z ${users_map[${choice}]} ]]; then
clear
echo "Sélection invalide."
else
local selected_option="${users_map[${choice}]}"
while true; do
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 revenir au choix d'utilisateur."
read -r -p "Votre choix (1-${sessions_counter}): " choice
if [[ ${choice} == "quit" ]] || [[ ${choice} == "${sessions_counter}" ]]; then
break
elif [[ -z ${choice} ]] || [[ -z ${sessions_map[${choice}]} ]]; then
clear
echo "Sélection invalide."
else
ttyplay /home/"${selected_option}"/"${sessions_map[${choice}]}"
fi
done
fi
done
} }
function servers_access_control() { function servers_access_control() {
@ -100,6 +171,7 @@ function servers_access_control() {
case "${choice}" in case "${choice}" in
"1") "1")
clear
Authorization_Files_List=$(find /opt/public/servers/. -type f ! -name 'authorized_servers.txt' | cut -d "/" -f 6) Authorization_Files_List=$(find /opt/public/servers/. -type f ! -name 'authorized_servers.txt' | cut -d "/" -f 6)
echo -e "Le ficher d'authentification qui sera crée ou modifié sera placé dans le répertoire \"/opt/public/servers/\" du bastion.\nle nom de ce dernier ne doit pas comporter de \"/\", être vide ou être égal à \"authorized_servers.txt\"." echo -e "Le ficher d'authentification qui sera crée ou modifié sera placé dans le répertoire \"/opt/public/servers/\" du bastion.\nle nom de ce dernier ne doit pas comporter de \"/\", être vide ou être égal à \"authorized_servers.txt\"."
echo -e "Ci dessous la liste des fichiers d'authentification existants :\n${Authorization_Files_List}" echo -e "Ci dessous la liste des fichiers d'authentification existants :\n${Authorization_Files_List}"
@ -118,6 +190,7 @@ function servers_access_control() {
;; ;;
"2") "2")
clear
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." 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."
secure_file_editor "/opt/public/servers/authorized_servers.txt" secure_file_editor "/opt/public/servers/authorized_servers.txt"
;; ;;
@ -127,6 +200,7 @@ function servers_access_control() {
;; ;;
*) *)
clear
echo "Sélection invalide." echo "Sélection invalide."
;; ;;
esac esac
@ -141,7 +215,13 @@ function admin_rights_control() {
secure_file_editor "/opt/public/rights/admin_rights.txt" secure_file_editor "/opt/public/rights/admin_rights.txt"
} }
function transfer_rights_control() {
echo -e "Editez les droits de transfert de fichiers ci dessous.\nFormat : nom_serveur user1,user2,...\nSi le fichier est vide, les transferts sont refuses pour tous."
secure_file_editor "/opt/public/rights/transfer_rights.txt"
}
function main_menu() { function main_menu() {
clear
ADMIN_RIGHTS_PATH="opt/public/rights" ADMIN_RIGHTS_PATH="opt/public/rights"
ADMIN_RIGHTS_FILE="/${ADMIN_RIGHTS_PATH}/admin_rights.txt" ADMIN_RIGHTS_FILE="/${ADMIN_RIGHTS_PATH}/admin_rights.txt"
CONNECTED_ADMIN="$(whoami)" CONNECTED_ADMIN="$(whoami)"
@ -156,45 +236,66 @@ function main_menu() {
} }
}' "${ADMIN_RIGHTS_FILE}") }' "${ADMIN_RIGHTS_FILE}")
if [[ -z ${ADMIN_RIGHTS} ]]; then counter=0
echo -e "Vous n'avez aucune autorisation d'administration.\nVous pouvez cependant vous connecter aux serveurs dont l'accès vous est autorisé." adminrights_list=()
fi
echo "Veuillez sélectionner une option d'administration :"
counter=1
declare -A adminrights_map
while read -r line; do while read -r line; do
admin_right=$(echo "${line}" | cut -d ' ' -f 1) admin_right=$(echo "${line}" | cut -d ' ' -f 1)
admin_right_pretty_name=$(echo "${line}" | cut -d ' ' -f 2) admin_right_pretty_name=$(echo "${line}" | cut -d ' ' -f 2)
adminrights_map[${counter}]="${admin_right} ${admin_right_pretty_name}" if [[ -n ${admin_right_pretty_name} ]]; then
echo "${counter}) ${admin_right_pretty_name}" adminrights_list[${counter}]="${admin_right} ${admin_right_pretty_name}"
counter=$((counter + 1)) counter=$((counter + 1))
fi
done <<<"${ADMIN_RIGHTS}" done <<<"${ADMIN_RIGHTS}"
if [[ ${counter} -gt 0 ]]; then
echo "Veuillez sélectionner une option d'administration :"
for ((idx=0; idx<counter; idx++)); do
echo "${idx}) $(echo "${adminrights_list[${idx}]}" | cut -d ' ' -f 2-)"
done
else
echo "Vous n'avez aucune autorisation d'administration."
fi
echo "Vous pouvez cependant vous connecter aux serveurs dont l'accès vous est autorisé."
local servers_access_idx=${counter}
echo "${counter}) Tapez 'servers_access' ou ${counter} pour vous connecter a un serveur." echo "${counter}) Tapez 'servers_access' ou ${counter} pour vous connecter a un serveur."
counter=$((counter + 1)) counter=$((counter + 1))
local logs_idx=${counter}
echo "${counter}) Tapez 'logs' ou ${counter} pour consulter les logs de transfert."
counter=$((counter + 1))
local quit_idx=${counter}
echo "${counter}) Tapez 'quit' ou ${counter} pour vous déconnecter." echo "${counter}) Tapez 'quit' ou ${counter} pour vous déconnecter."
read -r -p "Votre choix (1-${counter}): " choice read -r -p "Votre choix (0-${counter}): " choice
if [[ ${choice} == "servers_access" ]] || [[ ${choice} == "$((counter - 1))" ]]; then if [[ ${choice} == "servers_access" ]] || [[ ${choice} == "${servers_access_idx}" ]]; then
bash /opt/public/scripts/server_menu.sh bash /opt/public/scripts/server_menu.sh
elif [[ ${choice} == "quit" ]] || [[ ${choice} == "${counter}" ]]; then elif [[ ${choice} == "logs" ]] || [[ ${choice} == "${logs_idx}" ]]; then
clear
if [[ -f /var/log/monosphere/transfers.log ]]; then
cat /var/log/monosphere/transfers.log
else
echo "Aucun log de transfert disponible."
fi
read -r -p "Appuyez sur Entree pour continuer..."
elif [[ ${choice} == "quit" ]] || [[ ${choice} == "${quit_idx}" ]]; then
echo "Déconnexion du bastion." echo "Déconnexion du bastion."
exit 0 exit 0
elif [[ -z ${choice} ]] || [[ -z ${adminrights_map[${choice}]} ]]; then elif [[ -z ${choice} ]] || [[ -z ${adminrights_list[${choice}]+isset} ]]; then
clear
echo "Sélection invalide." echo "Sélection invalide."
else else
local selected_option local selected_option
selected_option="${adminrights_map[${choice}]}" selected_option="${adminrights_list[${choice}]}"
case "$(echo "${selected_option}" | cut -d ' ' -f 1)" in case "$(echo "${selected_option}" | cut -d ' ' -f 1)" in
"sessionswatch_admins") "sessionswatch_admins")
clear
sessions_viewer sessions_viewer
;; ;;
"serverscontrol_admins") "serverscontrol_admins")
clear
servers_access_control servers_access_control
;; ;;
# #
@ -203,15 +304,22 @@ function main_menu() {
# ;; # ;;
# #
"adminscontrol_admins") "adminscontrol_admins")
clear
admin_rights_control admin_rights_control
;; ;;
"transfercontrol_admins")
clear
transfer_rights_control
;;
# #
# "cluster_admins") # "cluster_admins")
# #
# ;; # ;;
*) *)
clear
echo -e "Un problème de configuration a été détecté sur \nles options du droit administrateur sélectionné.\nVeuillez contacter votre administrateur." echo -e "Un problème de configuration a été détecté sur \nles options du droit administrateur sélectionné.\nVeuillez contacter votre administrateur."
;; ;;
esac esac

View File

@ -1,3 +1,4 @@
sessionswatch_admins Visionnage_des_sessions_du_bastion bastion sessionswatch_admins Visionnage_des_sessions_du_bastion bastion
serverscontrol_admins Administration_des_acces_serveurs bastion serverscontrol_admins Administration_des_acces_serveurs bastion
adminscontrol_admins Administration_des_privileges bastion adminscontrol_admins Administration_des_privileges bastion
transfercontrol_admins Gestion_des_droits_de_transfert bastion

View File

@ -104,7 +104,14 @@ good_msg "Création des utilisateurs terminée."
info_msg "Monosphere configure le répertoire public." info_msg "Monosphere configure le répertoire public."
chown -R root:bastionadmin /opt/public chown -R root:bastionadmin /opt/public
chmod -R 775 /opt/public chmod -R 775 /opt/public
good_msg "Répertoire public configuré."
info_msg "Configuration des répertoires de logs et droits."
touch /opt/public/rights/transfer_rights.txt
mkdir -p /var/log/monosphere
chmod 777 /var/log/monosphere
touch /var/log/monosphere/transfers.log
chmod 666 /var/log/monosphere/transfers.log
good_msg "Répertoires configurés."
info_msg "Démarrage du service SSHD de Monosphere." info_msg "Démarrage du service SSHD de Monosphere."
rc-status rc-status

View File

@ -19,10 +19,148 @@ if [[ -z ${USER_SERVERS} ]]; then
exit 1 exit 1
fi fi
function main_menu() { TRANSFER_LOG="/var/log/monosphere/transfers.log"
echo "Veuillez sélectionner un serveur auquel vous connecter :" TRANSFER_RIGHTS_FILE="/opt/public/rights/transfer_rights.txt"
counter=1 mkdir -p "$(dirname "${TRANSFER_LOG}")" 2>/dev/null
touch "${TRANSFER_LOG}" 2>/dev/null
chmod 666 "${TRANSFER_LOG}" 2>/dev/null
check_transfer_rights() {
local server_name="$1"
if [[ ! -f ${TRANSFER_RIGHTS_FILE} ]] || [[ ! -s ${TRANSFER_RIGHTS_FILE} ]]; then
return 0
fi
local user_allowed
user_allowed=$(awk -v server="${server_name}" -v user="${CONNECTED_USER}" '
$1 == server {
split($2, ulist, ",");
for (i in ulist) {
if (ulist[i] == user || ulist[i] == "*") { print "yes"; exit; }
}
}
' "${TRANSFER_RIGHTS_FILE}")
if [[ -z ${user_allowed} ]]; then
return 1
fi
return 0
}
scp_to_target() {
local src="$1" ip="$2" port="$3" user="$4" dest="$5" authmethod="$6" authfile="$7"
if [[ -z ${authmethod} ]]; then
scp -o StrictHostKeyChecking=accept-new -P "${port}" "${src}" "${user}@${ip}:${dest}" 2>&1
elif [[ ${authmethod} == "key" ]] && [[ -f /${AUTHORIZED_SERVERS_PATH}/${authfile} ]]; then
scp -o StrictHostKeyChecking=accept-new -i "/${AUTHORIZED_SERVERS_PATH}/${authfile}" -P "${port}" "${src}" "${user}@${ip}:${dest}" 2>&1
elif [[ ${authmethod} == "password" ]] && [[ -f /${AUTHORIZED_SERVERS_PATH}/${authfile} ]]; then
sshpass -p "$(cat /${AUTHORIZED_SERVERS_PATH}/${authfile})" scp -o StrictHostKeyChecking=accept-new -P "${port}" "${src}" "${user}@${ip}:${dest}" 2>&1
else
return 1
fi
}
ssh_to_target_cat() {
local ip="$1" port="$2" user="$3" path="$4" authmethod="$5" authfile="$6"
if [[ -z ${authmethod} ]]; then
ssh -T -o StrictHostKeyChecking=accept-new -p "${port}" "${user}@${ip}" "cat '${path}'" < /dev/null
elif [[ ${authmethod} == "key" ]] && [[ -f /${AUTHORIZED_SERVERS_PATH}/${authfile} ]]; then
ssh -T -o StrictHostKeyChecking=accept-new -i "/${AUTHORIZED_SERVERS_PATH}/${authfile}" -p "${port}" "${user}@${ip}" "cat '${path}'" < /dev/null
elif [[ ${authmethod} == "password" ]] && [[ -f /${AUTHORIZED_SERVERS_PATH}/${authfile} ]]; then
sshpass -p "$(cat /${AUTHORIZED_SERVERS_PATH}/${authfile})" ssh -T -o StrictHostKeyChecking=accept-new -p "${port}" "${user}@${ip}" "cat '${path}'" < /dev/null
else
return 1
fi
}
log_transfer() {
local action="$1" server="$2" path="$3" size="$4" status="$5"
echo "$(date '+%Y-%m-%d %H:%M:%S') USER=${CONNECTED_USER} ACTION=${action} SERVER=${server} FILE=${path} SIZE=${size} STATUS=${status}" >> "${TRANSFER_LOG}"
}
if [[ -n ${SSH_ORIGINAL_COMMAND} ]]; then
case "${SSH_ORIGINAL_COMMAND}" in
"push_file "*)
args="${SSH_ORIGINAL_COMMAND#push_file }"
server_name=$(echo "${args}" | cut -d ' ' -f 1)
dest_path=$(echo "${args}" | cut -d ' ' -f 2-)
if [[ -z ${server_name} ]] || [[ -z ${dest_path} ]]; then
echo "Usage: push_file <server_name> <remote_dest_path>"
exit 1
fi
server_line=$(echo "${USER_SERVERS}" | awk -v name="${server_name}" '$3 == name {print; exit}')
if [[ -z ${server_line} ]]; then
echo "Serveur \"${server_name}\" non trouve ou non autorise."
exit 1
fi
if ! check_transfer_rights "${server_name}"; then
echo "Vous n'avez pas le droit de transferer des fichiers vers ${server_name}."
exit 1
fi
srv_ip=$(echo "${server_line}" | cut -d ' ' -f 1)
srv_port=$(echo "${server_line}" | cut -d ' ' -f 2)
srv_user=$(echo "${server_line}" | cut -d ' ' -f 4)
srv_authmethod=$(echo "${server_line}" | cut -d ' ' -f 6)
srv_authfile=$(echo "${server_line}" | cut -d ' ' -f 7)
tmpfile=$(mktemp /tmp/.push_XXXXXX)
cat > "${tmpfile}"
file_size=$(stat -c %s "${tmpfile}" 2>/dev/null || stat -f %z "${tmpfile}" 2>/dev/null)
scp_to_target "${tmpfile}" "${srv_ip}" "${srv_port}" "${srv_user}" "${dest_path}" "${srv_authmethod}" "${srv_authfile}"
exit_code=$?
rm -f "${tmpfile}"
if [[ ${exit_code} -eq 0 ]]; then
log_transfer "push" "${server_name}" "${dest_path}" "${file_size:-0}" "success"
else
log_transfer "push" "${server_name}" "${dest_path}" "${file_size:-0}" "failed"
fi
exit ${exit_code}
;;
"retrieve_file "*)
args="${SSH_ORIGINAL_COMMAND#retrieve_file }"
server_name=$(echo "${args}" | cut -d ' ' -f 1)
remote_path=$(echo "${args}" | cut -d ' ' -f 2-)
if [[ -z ${server_name} ]] || [[ -z ${remote_path} ]]; then
echo "Usage: retrieve_file <server_name> <remote_path>"
exit 1
fi
server_line=$(echo "${USER_SERVERS}" | awk -v name="${server_name}" '$3 == name {print; exit}')
if [[ -z ${server_line} ]]; then
echo "Serveur \"${server_name}\" non trouve ou non autorise."
exit 1
fi
if ! check_transfer_rights "${server_name}"; then
echo "Vous n'avez pas le droit de transferer des fichiers vers ${server_name}."
exit 1
fi
srv_ip=$(echo "${server_line}" | cut -d ' ' -f 1)
srv_port=$(echo "${server_line}" | cut -d ' ' -f 2)
srv_user=$(echo "${server_line}" | cut -d ' ' -f 4)
srv_authmethod=$(echo "${server_line}" | cut -d ' ' -f 6)
srv_authfile=$(echo "${server_line}" | cut -d ' ' -f 7)
ssh_to_target_cat "${srv_ip}" "${srv_port}" "${srv_user}" "${remote_path}" "${srv_authmethod}" "${srv_authfile}"
exit_code=$?
if [[ ${exit_code} -eq 0 ]]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') USER=${CONNECTED_USER} ACTION=retrieve SERVER=${server_name} FILE=${remote_path} STATUS=success" >> "${TRANSFER_LOG}"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') USER=${CONNECTED_USER} ACTION=retrieve SERVER=${server_name} FILE=${remote_path} STATUS=failed" >> "${TRANSFER_LOG}"
fi
exit ${exit_code}
;;
*)
echo "Commande non reconnue: ${SSH_ORIGINAL_COMMAND}"
echo "Commandes supportees:"
echo " push_file <server> <dest_path> - Pousser stdin vers un serveur distant"
echo " retrieve_file <server> <src_path> - Recuperer un fichier distant vers stdout"
exit 1
;;
esac
fi
function main_menu() {
if [[ -z $choice ]] || [[ ${choice} == "null" ]]; then
echo "Veuillez sélectionner un serveur auquel vous connecter :"
fi
counter=0
declare -A server_map declare -A server_map
while read -r line; do while read -r line; do
ip=$(echo "${line}" | cut -d ' ' -f 1) ip=$(echo "${line}" | cut -d ' ' -f 1)
@ -31,21 +169,39 @@ function main_menu() {
server_user=$(echo "${line}" | cut -d ' ' -f 4) server_user=$(echo "${line}" | cut -d ' ' -f 4)
server_authmethod=$(echo "${line}" | cut -d ' ' -f 6) server_authmethod=$(echo "${line}" | cut -d ' ' -f 6)
server_auth=$(echo "${line}" | cut -d ' ' -f 7) server_auth=$(echo "${line}" | cut -d ' ' -f 7)
server_map[${counter}]="${ip} ${port} ${server_user} ${server_authmethod} ${server_auth}" server_map[${counter}]="${ip} ${port} ${server_user} ${server_authmethod} ${server_auth} ${custom_name}"
echo "${counter}) ${custom_name} - ${server_user} ${ip}:${port}" if [[ -z $choice ]] || [[ ${choice} == "null" ]]; then
echo "${counter}) ${custom_name} - ${server_user} ${ip}:${port}"
fi
counter=$((counter + 1)) counter=$((counter + 1))
done <<<"${USER_SERVERS}" done <<<"${USER_SERVERS}"
echo "${counter}) Tapez 'quit' ou ${counter} pour vous déconnecter." if [[ -z $choice ]] || [[ ${choice} == "null" ]]; then
echo "${counter}) Tapez 'quit' ou ${counter} pour vous déconnecter."
echo "f) Tapez 'f'<nom de l'hote> pour filtrer les entrées."
read -r -p "Votre choix (1-${counter}): " choice read -r -p "Votre choix (0-${counter}) : " choice
fi
if [[ ${choice} == "quit" ]] || [[ ${choice} == "${counter}" ]]; then if [[ ${choice} == "quit" ]] || [[ ${choice} == "${counter}" ]]; then
echo "Déconnexion du bastion." echo "Déconnexion du bastion."
exit 0 exit 0
elif [[ $(echo "${choice}" | cut -c1-1) == "f" ]]; then
filter=$(echo "${choice}" | cut -c2-)
find_counter=0
echo "=====Résultats du filtre====="
for host in $(printf '%s\n' "${server_map[@]}" | tac | cut -d " " -f 6); do
if [[ $(echo "${host}" | awk '{print $(NF)}' | grep -m 1 -o "${filter}" | head -1) == $(echo "${filter}") ]]; then
echo "${find_counter}) $(echo ${server_map[${find_counter}]} | awk '{print $(NF)}') - $(echo ${server_map[${find_counter}]} | cut -d ' ' -f 3) $(echo ${server_map[${find_counter}]} | cut -d ' ' -f 1):$(echo ${server_map[${find_counter}]} | cut -d ' ' -f 2)"
fi
find_counter=$((find_counter + 1))
done
read -r -p "Votre choix (0-${counter}) : " choice
elif [[ -z ${choice} ]] || [[ -z ${server_map[${choice}]} ]]; then elif [[ -z ${choice} ]] || [[ -z ${server_map[${choice}]} ]]; then
echo "Sélection invalide." echo "Sélection invalide."
choice="null"
else else
clear
local selected_server local selected_server
selected_server="${server_map[${choice}]}" selected_server="${server_map[${choice}]}"
echo "Connexion à $(echo "${selected_server}" | cut -d " " -f -3)..." echo "Connexion à $(echo "${selected_server}" | cut -d " " -f -3)..."
@ -65,9 +221,11 @@ function main_menu() {
else else
echo -e "Un problème de configuration a été détecté sur \nles options de connexion à l'hôte selectionné.\nVeuillez contacter votre administrateur." echo -e "Un problème de configuration a été détecté sur \nles options de connexion à l'hôte selectionné.\nVeuillez contacter votre administrateur."
fi fi
choice="null"
fi fi
} }
while true; do while true; do
main_menu main_menu
clear
done done

View File

@ -126,15 +126,18 @@ AcceptEnv LANG LC_*
#Order by preference #Order by preference
HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_rsa_key
#Logging #Logging
SyslogFacility AUTH
LogLevel VERBOSE LogLevel VERBOSE
#Authentication settings #Authentication settings
PermitRootLogin no PermitRootLogin no
MaxAuthTries 6 MaxAuthTries 6
MaxSessions 6
MaxStartups 4:50:8
PerSourceMaxStartups 2
PermitEmptyPasswords no PermitEmptyPasswords no
#Forwaring settings #Forwaring settings
@ -150,16 +153,13 @@ Banner /root/scripts/monosphere_banner.txt
Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO
#Kex accepted protocols #Kex accepted protocols
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 kexalgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
#Accepted ciphers #Accepted ciphers
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
#Accepted MACs #Accepted MACs
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com MACs umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
#Accepted public key types
#PubkeyAcceptedKeyTypes sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com
#Per user basis settings #Per user basis settings
AllowStreamLocalForwarding no AllowStreamLocalForwarding no

4
transfer_rights.txt Normal file
View File

@ -0,0 +1,4 @@
# Format: server_custom_name user1,user2,...
# Les utilisateurs listés peuvent transferer des fichiers vers ces serveurs.
# Si le fichier n'existe pas, tous les utilisateurs autorises (via authorized_servers.txt) peuvent transferer.
# example-fake-server bastion