Compare commits

..

2 Commits

Author SHA1 Message Date
65fde7640b adminSys update - add config firewall web 2026-03-07 10:51:14 +01:00
897214921f correction de gitignore 2026-03-07 10:41:06 +01:00
14 changed files with 1623 additions and 11 deletions

27
.gitignore vendored
View File

@@ -1,6 +1,21 @@
.git # Ignorer les spécifiques
.obsidian /ecoleA
.theia
.config # IDE et éditeurs
ecoleA .theia/
/ecoleA/ .vscode/
.idea/
# Configuration Obsidian
.obsidian/workspace.json
.obsidian/graph.json
# Systèmes et dossiers de config inutiles en prod
.config/
.DS_Store
Thumbs.db
# Fichiers temporaires de scripts
*.log
__pycache__/
.env

4
.obsidian/app.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"alwaysUpdateLinks": true,
"showUnsupportedFiles": true
}

1
.obsidian/appearance.json vendored Normal file
View File

@@ -0,0 +1 @@
{}

3
.obsidian/community-plugins.json vendored Normal file
View File

@@ -0,0 +1,3 @@
[
"obsidian-git"
]

33
.obsidian/core-plugins.json vendored Normal file
View File

@@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"footnotes": false,
"properties": true,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": true,
"bases": true,
"webviewer": false
}

452
.obsidian/plugins/obsidian-git/main.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
{
"author": "Vinzent",
"authorUrl": "https://github.com/Vinzent03",
"id": "obsidian-git",
"name": "Git",
"description": "Integrate Git version control with automatic backup and other advanced features.",
"isDesktopOnly": false,
"fundingUrl": "https://ko-fi.com/vinzent",
"version": "2.37.1"
}

View File

@@ -0,0 +1,705 @@
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.git-signs-gutter {
.cm-gutterElement {
/* Needed to align the sign properly for different line heigts. Such as
* when having a heading or list item.
*/
padding-top: 0 !important;
}
}
.workspace-leaf-content[data-type="git-view"] .button-border {
border: 2px solid var(--interactive-accent);
border-radius: var(--radius-s);
}
.workspace-leaf-content[data-type="git-view"] .view-content {
padding-left: 0;
padding-top: 0;
padding-right: 0;
}
.workspace-leaf-content[data-type="git-history-view"] .view-content {
padding-left: 0;
padding-top: 0;
padding-right: 0;
}
.loading {
overflow: hidden;
}
.loading > svg {
animation: 2s linear infinite loading;
transform-origin: 50% 50%;
display: inline-block;
}
.obsidian-git-center {
margin: auto;
text-align: center;
width: 50%;
}
.obsidian-git-textarea {
display: block;
margin-left: auto;
margin-right: auto;
}
.obsidian-git-disabled {
opacity: 0.5;
}
.obsidian-git-center-button {
display: block;
margin: 20px auto;
}
.tooltip.mod-left {
overflow-wrap: break-word;
}
.tooltip.mod-right {
overflow-wrap: break-word;
}
/* Limits the scrollbar to the view body */
.git-view {
display: flex;
flex-direction: column;
position: relative;
height: 100%;
}
.git-tools {
display: flex;
margin-left: auto;
}
.git-tools .type {
padding-left: var(--size-2-1);
display: flex;
align-items: center;
justify-content: center;
width: 11px;
}
.git-tools .type[data-type="M"] {
color: orange;
}
.git-tools .type[data-type="D"] {
color: red;
}
.git-tools .buttons {
display: flex;
}
.git-tools .buttons > * {
padding: 0 0;
height: auto;
}
.workspace-leaf-content[data-type="git-view"] .tree-item-self,
.workspace-leaf-content[data-type="git-history-view"] .tree-item-self {
align-items: center;
}
.workspace-leaf-content[data-type="git-view"]
.tree-item-self:hover
.clickable-icon,
.workspace-leaf-content[data-type="git-history-view"]
.tree-item-self:hover
.clickable-icon {
color: var(--icon-color-hover);
}
/* Highlight an item as active if it's diff is currently opened */
.is-active .git-tools .buttons > * {
color: var(--nav-item-color-active);
}
.git-author {
color: var(--text-accent);
}
.git-date {
color: var(--text-accent);
}
.git-ref {
color: var(--text-accent);
}
/* ====== diff2html ======
The following styles are adapted from the obsidian-version-history plugin by
@kometenstaub https://github.com/kometenstaub/obsidian-version-history-diff/blob/main/src/styles.scss
which itself is adapted from the diff2html library with the following original license:
https://github.com/rtfpessoa/diff2html/blob/master/LICENSE.md
Copyright 2014-2016 Rodrigo Fernandes https://rtfpessoa.github.io/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
.theme-dark,
.theme-light {
--git-delete-bg: #ff475040;
--git-delete-hl: #96050a75;
--git-insert-bg: #68d36840;
--git-insert-hl: #23c02350;
--git-change-bg: #ffd55840;
--git-selected: #3572b0;
--git-delete: #c33;
--git-insert: #399839;
--git-change: #d0b44c;
--git-move: #3572b0;
}
.git-diff {
.d2h-d-none {
display: none;
}
.d2h-wrapper {
text-align: left;
border-radius: 0.25em;
overflow: auto;
}
.d2h-file-header.d2h-file-header {
background-color: var(--background-secondary);
border-bottom: 1px solid var(--background-modifier-border);
font-family:
Source Sans Pro,
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
height: 35px;
padding: 5px 10px;
}
.d2h-file-header,
.d2h-file-stats {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.d2h-file-header {
display: none;
}
.d2h-file-stats {
font-size: 14px;
margin-left: auto;
}
.d2h-lines-added {
border: 1px solid var(--color-green);
border-radius: 5px 0 0 5px;
color: var(--color-green);
padding: 2px;
text-align: right;
vertical-align: middle;
}
.d2h-lines-deleted {
border: 1px solid var(--color-red);
border-radius: 0 5px 5px 0;
color: var(--color-red);
margin-left: 1px;
padding: 2px;
text-align: left;
vertical-align: middle;
}
.d2h-file-name-wrapper {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 15px;
width: 100%;
}
.d2h-file-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--text-normal);
font-size: var(--h5-size);
}
.d2h-file-wrapper {
border: 1px solid var(--background-secondary-alt);
border-radius: 3px;
margin-bottom: 1em;
max-height: 100%;
}
.d2h-file-collapse {
-webkit-box-pack: end;
-ms-flex-pack: end;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border: 1px solid var(--background-secondary-alt);
border-radius: 3px;
cursor: pointer;
display: none;
font-size: 12px;
justify-content: flex-end;
padding: 4px 8px;
}
.d2h-file-collapse.d2h-selected {
background-color: var(--git-selected);
}
.d2h-file-collapse-input {
margin: 0 4px 0 0;
}
.d2h-diff-table {
border-collapse: collapse;
font-family: var(--font-monospace);
font-size: var(--code-size);
width: 100%;
}
.d2h-files-diff {
width: 100%;
}
.d2h-file-diff {
/*
overflow-y: scroll;
*/
border-radius: 5px;
font-size: var(--font-text-size);
line-height: var(--line-height-normal);
}
.d2h-file-side-diff {
display: inline-block;
margin-bottom: -8px;
margin-right: -4px;
overflow-x: scroll;
overflow-y: hidden;
width: 50%;
}
.d2h-code-line {
padding-left: 6em;
padding-right: 1.5em;
}
.d2h-code-line,
.d2h-code-side-line {
display: inline-block;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
width: 100%;
}
.d2h-code-side-line {
/* needed to be changed */
padding-left: 0.5em;
padding-right: 0.5em;
}
.d2h-code-line-ctn {
word-wrap: normal;
background: none;
display: inline-block;
padding: 0;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
vertical-align: middle;
width: 100%;
/* only works for line-by-line */
white-space: pre-wrap;
}
.d2h-code-line del,
.d2h-code-side-line del {
background-color: var(--git-delete-hl);
color: var(--text-normal);
}
.d2h-code-line del,
.d2h-code-line ins,
.d2h-code-side-line del,
.d2h-code-side-line ins {
border-radius: 0.2em;
display: inline-block;
margin-top: -1px;
text-decoration: none;
vertical-align: middle;
}
.d2h-code-line ins,
.d2h-code-side-line ins {
background-color: var(--git-insert-hl);
text-align: left;
}
.d2h-code-line-prefix {
word-wrap: normal;
background: none;
display: inline;
padding: 0;
white-space: pre;
}
.line-num1 {
float: left;
}
.line-num1,
.line-num2 {
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
/*
padding: 0 0.5em;
*/
text-overflow: ellipsis;
width: 2.5em;
padding-left: 0;
}
.line-num2 {
float: right;
}
.d2h-code-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-faint);
cursor: pointer;
display: inline-block;
position: absolute;
text-align: right;
width: 5.5em;
}
.d2h-code-linenumber:after {
content: "\200b";
}
.d2h-code-side-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-faint);
cursor: pointer;
overflow: hidden;
padding: 0 0.5em;
text-align: right;
text-overflow: ellipsis;
width: 4em;
/* needed to be changed */
display: table-cell;
position: relative;
}
.d2h-code-side-linenumber:after {
content: "\200b";
}
.d2h-code-side-emptyplaceholder,
.d2h-emptyplaceholder {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
}
.d2h-code-line-prefix,
.d2h-code-linenumber,
.d2h-code-side-linenumber,
.d2h-emptyplaceholder {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.d2h-code-linenumber,
.d2h-code-side-linenumber {
direction: rtl;
}
.d2h-del {
background-color: var(--git-delete-bg);
border-color: var(--git-delete-hl);
}
.d2h-ins {
background-color: var(--git-insert-bg);
border-color: var(--git-insert-hl);
}
.d2h-info {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
color: var(--text-faint);
}
.d2h-del,
.d2h-ins,
.d2h-file-diff .d2h-change {
color: var(--text-normal);
}
.d2h-file-diff .d2h-del.d2h-change {
background-color: var(--git-change-bg);
}
.d2h-file-diff .d2h-ins.d2h-change {
background-color: var(--git-insert-bg);
}
.d2h-file-list-wrapper {
a {
text-decoration: none;
cursor: default;
-webkit-user-drag: none;
}
svg {
display: none;
}
}
.d2h-file-list-header {
text-align: left;
}
.d2h-file-list-title {
display: none;
}
.d2h-file-list-line {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
text-align: left;
}
.d2h-file-list {
}
.d2h-file-list > li {
border-bottom: 1px solid var(--background-modifier-border);
margin: 0;
padding: 5px 10px;
}
.d2h-file-list > li:last-child {
border-bottom: none;
}
.d2h-file-switch {
cursor: pointer;
display: none;
font-size: 10px;
}
.d2h-icon {
fill: currentColor;
margin-right: 10px;
vertical-align: middle;
}
.d2h-deleted {
color: var(--git-delete);
}
.d2h-added {
color: var(--git-insert);
}
.d2h-changed {
color: var(--git-change);
}
.d2h-moved {
color: var(--git-move);
}
.d2h-tag {
background-color: var(--background-secondary);
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 10px;
margin-left: 5px;
padding: 0 2px;
}
.d2h-deleted-tag {
border: 1px solid var(--git-delete);
}
.d2h-added-tag {
border: 1px solid var(--git-insert);
}
.d2h-changed-tag {
border: 1px solid var(--git-change);
}
.d2h-moved-tag {
border: 1px solid var(--git-move);
}
/* needed for line-by-line*/
.d2h-diff-tbody {
position: relative;
}
}
/* ====================== Line Authoring Information ====================== */
.cm-gutterElement.obs-git-blame-gutter {
/* Add background color to spacing inbetween and around the gutter for better aesthetics */
border-width: 0px 2px 0.2px 2px;
border-style: solid;
border-color: var(--background-secondary);
background-color: var(--background-secondary);
}
.cm-gutterElement.obs-git-blame-gutter > div,
.line-author-settings-preview {
/* delegate text color to settings */
color: var(--obs-git-gutter-text);
font-family: monospace;
height: 100%; /* ensure, that age-based background color occupies entire parent */
text-align: right;
padding: 0px 6px 0px 6px;
white-space: pre; /* Keep spaces and do not collapse them. */
}
@media (max-width: 800px) {
/* hide git blame gutter not to superpose text */
.cm-gutterElement.obs-git-blame-gutter {
display: none;
}
}
.git-unified-diff-view,
.git-split-diff-view .cm-deletedLine .cm-changedText {
background-color: #ee443330;
}
.git-unified-diff-view,
.git-split-diff-view .cm-insertedLine .cm-changedText {
background-color: #22bb2230;
}
.git-obscure-prompt[git-is-obscured="true"] #git-show-password:after {
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"></path><circle cx="12" cy="12" r="3"></circle></svg>');
}
.git-obscure-prompt[git-is-obscured="false"] #git-show-password:after {
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye-off"><path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"></path><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"></path><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"></path><path d="m2 2 20 20"></path></svg>');
}
/* Override styling of Codemirror merge view "collapsed lines" indicator */
.git-split-diff-view .ͼ2 .cm-collapsedLines {
background: var(--interactive-normal);
border-radius: var(--radius-m);
color: var(--text-accent);
font-size: var(--font-small);
padding: var(--size-4-1) var(--size-4-1);
}
.git-split-diff-view .ͼ2 .cm-collapsedLines:hover {
background: var(--interactive-hover);
color: var(--text-accent-hover);
}
.git-signs-gutter {
.cm-gutterElement {
display: grid;
}
}
.git-gutter-marker:hover {
border-radius: 2px;
}
.git-gutter-marker.git-add {
background-color: var(--color-green);
justify-self: center;
height: inherit;
width: 0.2rem;
}
.git-gutter-marker.git-change {
background-color: var(--color-yellow);
justify-self: center;
height: inherit;
width: 0.2rem;
}
.git-gutter-marker.git-changedelete {
color: var(--color-yellow);
font-weight: var(--font-bold);
font-size: 1rem;
justify-self: center;
height: inherit;
}
.git-gutter-marker.git-delete {
background-color: var(--color-red);
height: 0.2rem;
width: 0.8rem;
align-self: end;
}
.git-gutter-marker.git-topdelete {
background-color: var(--color-red);
height: 0.2rem;
width: 0.8rem;
align-self: start;
}
div:hover > .git-gutter-marker.git-change {
width: 0.6rem;
}
div:hover > .git-gutter-marker.git-add {
width: 0.6rem;
}
div:hover > .git-gutter-marker.git-delete {
height: 0.6rem;
}
div:hover > .git-gutter-marker.git-topdelete {
height: 0.6rem;
}
div:hover > .git-gutter-marker.git-changedelete {
font-weight: var(--font-bold);
}
.git-gutter-marker.staged {
opacity: 0.5;
}
.git-diff {
.cm-merge-revert {
width: 4em;
}
/* Ensure that merge revert markers are positioned correctly */
.cm-merge-revert > * {
position: absolute;
background-color: var(--background-secondary);
display: flex;
}
}
/* Prevent shifting of the editor when git signs gutter is the only gutter present */
.cm-gutters.cm-gutters-before:has(> .git-signs-gutter:only-child) {
margin-inline-end: 0;
.git-signs-gutter {
margin-inline-start: -1rem;
}
}
.git-changes-status-bar-colored {
.git-add {
color: var(--color-green);
}
.git-change {
color: var(--color-yellow);
}
.git-delete {
color: var(--color-red);
}
}
.git-changes-status-bar .git-add {
margin-right: 0.3em;
}
.git-changes-status-bar .git-change {
margin-right: 0.3em;
}

View File

@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# 1. Liste des hosts # 1. Liste des hosts
mapfile -t ALL_HOSTS < <(grep -riI "^Host " ~/.ssh/config ~/.ssh/config.d/ 2>/dev/null | awk '{print $2}' | grep -v '*' | sort -u) mapfile -t ALL_HOSTS < <(grep -riI "^Host " ~/.ssh/config ~/.ssh/config.d/ ~/.ssh/include/ 2>/dev/null | awk '{print $2}' | grep -v '*' | sort -u)
check_host() { check_host() {
local host=$1 local host=$1

View File

@@ -16,10 +16,6 @@
.\} .\}
.TH "" "" "" "" "" .TH "" "" "" "" ""
.hy .hy
.PP
.PD 0
.P
.PD
.SH NOM .SH NOM
.PP .PP
castopod_update - Mise à jour de CASTOPOD castopod_update - Mise à jour de CASTOPOD

31
servers/linux/README.md Normal file
View File

@@ -0,0 +1,31 @@
# 🛠️ Server Admin Setup (Debian/Ubuntu)
Ce dépôt contient un script d'automatisation pour la configuration initiale et la surveillance de serveurs Linux (Debian/Ubuntu).
## 🚀 Fonctionnalités
Le script `config_adminSys.sh` déploie les briques suivantes :
* **Sécurité Réseau** : Configuration de `UFW` (bloque tout sauf SSH/22) et installation de `Fail2Ban`. /!\ A personnaliser si c'est un serveur Web, postgres....
* **Maintenance** : Activation des `unattended-upgrades` pour les patchs de sécurité automatiques.
* **Alertes Mail** : Configuration de `msmtp` pour l'envoi de rapports système via SMTP.
* **Monitoring de Santé** : Script de surveillance (`sys_check.sh`) installé dans `/usr/local/bin/`. a paramétrer
* Alerte si **Disque > 90%**
* Alerte si **Inodes > 90%**
* Alerte si **RAM > 90%**
* **Automatisation** : Tâche Cron horaire pour le check de santé.
## 📋 Prérequis
1. Un serveur sous **Debian** ou compatible.
2. Un compte mail dédié (ex: `srv.hostname@domain.tld`).
3. Un **App Password** (Mot de passe d'application).
## 💻 Utilisation Rapide (One-Liner)
Connectez-vous à votre nouveau serveur et lancez la commande suivante :
```bash
wget -qO- [https://raw.githubusercontent.com/VOTRE_USER/VOTRE_REPO/main/config_adminSys.sh](https://raw.githubusercontent.com/VOTRE_USER/VOTRE_REPO/main/config_adminSys.sh) | sudo bash

109
servers/linux/config_adminSys.sh Executable file
View File

@@ -0,0 +1,109 @@
#!/bin/bash
# --- 0. VÉRIFICATION DES DROITS ---
if [ "$EUID" -ne 0 ]; then
echo "❌ Erreur : Ce script doit être lancé avec sudo."
exit 1
fi
# --- 1. CONFIGURATION DYNAMIQUE ---
HOSTNAME=$(hostname)
SMTP_HOST="mail.acemail.fr"
SMTP_PORT="587"
SMTP_USER="srv.${HOSTNAME}@a5l.fr"
DEST_EMAIL="cedric+${HOSTNAME}@abonnel.fr"
echo "=========================================================="
echo " VÉRIFICATION SMTP & DÉPLOIEMENT - ${HOSTNAME}"
echo "=========================================================="
# --- 2. TEST DU MOT DE PASSE SMTP ---
AUTH_OK=false
while [ "$AUTH_OK" = false ]; do
echo -n "🔑 Entrez le mot de passe SMTP pour ${SMTP_USER} : "
read -s SMTP_PASS
echo -e "\n⏳ Test de connexion en cours..."
# Config temporaire pour le test
cat > /tmp/.msmtp_test <<EOF
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
account test
host $SMTP_HOST
port $SMTP_PORT
from $SMTP_USER
user $SMTP_USER
password $SMTP_PASS
account default : test
EOF
chmod 600 /tmp/.msmtp_test
# Tentative d'envoi
echo "Test de configuration" | msmtp --file=/tmp/.msmtp_test -t "$DEST_EMAIL" 2>/dev/null
if [ $? -eq 0 ]; then
echo "✅ Authentification SMTP réussie !"
AUTH_OK=true
rm /tmp/.msmtp_test
else
echo "❌ Échec. Vérifiez le mot de passe ou la connexion réseau."
rm /tmp/.msmtp_test
fi
done
# --- 3. INSTALLATION ---
echo "--- Installation des paquets ---"
DEBIAN_FRONTEND=noninteractive apt update
DEBIAN_FRONTEND=noninteractive apt install -y msmtp msmtp-mta bsd-mailx ufw fail2ban unattended-upgrades curl
# --- 4. CONFIGURATION MSMTP ---
echo "--- Configuration MSMTP ---"
cat > /etc/msmtprc <<EOF
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /var/log/msmtp.log
account default
host $SMTP_HOST
port $SMTP_PORT
from $SMTP_USER
user $SMTP_USER
password $SMTP_PASS
EOF
chmod 600 /etc/msmtprc
ln -sf /usr/bin/msmtp /usr/sbin/sendmail
# --- 5. SCRIPT DE SURVEILLANCE ---
echo "--- Création du check santé ---"
# On utilise cat directement ici car on est déjà en root
cat > /usr/local/bin/sys_check.sh <<EOF
#!/bin/bash
THRESHOLD=90
EMAIL="$DEST_EMAIL"
HOST="\$(hostname)"
DISK_USAGE=\$(df / | awk 'NR==2 {print \$5}' | sed 's/%//')
RAM_USAGE=\$(free | grep Mem | awk '{print int(\$3/\$2 * 100)}')
if [ "\$DISK_USAGE" -gt "\$THRESHOLD" ] || [ "\$RAM_USAGE" -gt "\$THRESHOLD" ]; then
MESSAGE="ALERTE sur \$HOST\nDisque: \$DISK_USAGE% | RAM: \$RAM_USAGE%\nDate: \$(date)"
echo -e "\$MESSAGE" | mail -s "⚠️ ALERTE : \$HOST" "\$EMAIL"
fi
EOF
chmod +x /usr/local/bin/sys_check.sh
# --- 6. SÉCURITÉ & AUTOMATISATION ---
echo "--- Activation Sécurité & Cron ---"
ufw allow 22/tcp
ufw --force enable
systemctl restart fail2ban
(crontab -l 2>/dev/null | grep -v "sys_check.sh" ; echo "0 * * * * /usr/local/bin/sys_check.sh") | crontab -
# --- 7. RAPPORT FINAL ---
echo "Le déploiement est terminé avec succès sur $HOSTNAME." | mail -s "[OK] Setup Admin : $HOSTNAME" "$DEST_EMAIL"
echo "✅ Terminé avec succès !"

140
servers/linux/firewall.php Normal file
View File

@@ -0,0 +1,140 @@
<?php
// Configuration : ports à ne JAMAIS supprimer via l'interface
$protected_ports = ['22', '2222', '80', '443'];
$message = "";
$status = "Inactive";
// --- LOGIQUE D'ACTION ---
// Ajouter un port
if (isset($_POST['add_port']) && !empty($_POST['port'])) {
$port = escapeshellarg(trim($_POST['port']));
$proto = escapeshellarg($_POST['proto']);
exec("sudo /usr/sbin/ufw allow $port/$proto", $output, $return);
$message = ($return == 0) ? "✅ Port $port/$proto ouvert." : "❌ Erreur UFW.";
}
// Supprimer une règle
if (isset($_GET['delete'])) {
$id = (int)$_GET['delete'];
// Récupérer les détails de la règle avant suppression pour la sécurité
exec("sudo /usr/sbin/ufw status numbered", $check_output);
foreach ($check_output as $line) {
if (strpos($line, "[$id]") !== false) {
foreach ($protected_ports as $p) {
if (strpos($line, $p) !== false) {
die("🛑 ERREUR : La règle #$id semble protéger un port critique ($p). Suppression annulée par sécurité.");
}
}
}
}
exec("echo 'y' | sudo /usr/sbin/ufw delete $id", $output, $return);
header("Location: " . strtok($_SERVER["REQUEST_URI"], '?') . "?msg=deleted");
exit;
}
if (isset($_GET['msg']) && $_GET['msg'] == 'deleted') $message = "🗑️ Règle supprimée.";
// --- RÉCUPÉRATION DES DONNÉES ---
exec("sudo /usr/sbin/ufw status numbered", $ufw_output);
if (isset($ufw_output[0]) && strpos($ufw_output[0], 'active') !== false) {
$status = "Active";
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UFW Manager Local</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<style>
.status-badge { font-weight: bold; padding: 5px 10px; border-radius: 4px; }
.status-Active { background: #48c78e; color: white; }
.status-Inactive { background: #f14668; color: white; }
</style>
</head>
<body class="has-background-light" style="min-height: 100vh;">
<section class="section">
<div class="container is-max-desktop">
<div class="level">
<div class="level-left">
<h1 class="title">🔥 UFW Manager</h1>
</div>
<div class="level-right">
<span class="status-badge status-<?php echo $status; ?>">Status: <?php echo $status; ?></span>
</div>
</div>
<?php if ($message): ?>
<div class="notification is-primary is-light"><?php echo $message; ?></div>
<?php endif; ?>
<div class="box">
<form method="POST" class="field is-grouped">
<div class="control is-expanded">
<input class="input" type="text" name="port" placeholder="Port ou Service (ex: 8080)">
</div>
<div class="control">
<div class="select">
<select name="proto">
<option value="tcp">TCP</option>
<option value="udp">UDP</option>
</select>
</div>
</div>
<div class="control">
<button type="submit" name="add_port" class="button is-dark">Autoriser</button>
</div>
</form>
</div>
<div class="box p-0">
<table class="table is-fullwidth is-hoverable m-0">
<thead>
<tr class="has-background-white-ter">
<th class="pl-5">#</th>
<th>Vers</th>
<th>Action</th>
<th>Depuis</th>
<th class="has-text-right pr-5">Action</th>
</tr>
</thead>
<tbody>
<?php
$rules_found = false;
foreach ($ufw_output as $line) {
if (preg_match('/\[\s*(\d+)\]\s+(.*?)\s+(ALLOW|DENY|ALLOW IN|DENY IN)\s+(.*)/', $line, $matches)) {
$rules_found = true;
$is_critical = false;
foreach ($protected_ports as $p) { if (strpos($matches[2], $p) !== false) $is_critical = true; }
echo "<tr>
<td class='pl-5'><b>{$matches[1]}</b></td>
<td><code>{$matches[2]}</code></td>
<td><span class='tag is-light is-success'>{$matches[3]}</span></td>
<td><small>{$matches[4]}</small></td>
<td class='has-text-right pr-5'>";
if (!$is_critical) {
echo "<a href='?delete={$matches[1]}' class='button is-small is-danger is-outlined' onclick='return confirm(\"Supprimer la règle #{$matches[1]} ?\")'>Supprimer</a>";
} else {
echo "<span class='tag is-warning is-light'>Protégé</span>";
}
echo "</td></tr>";
}
}
if (!$rules_found) echo "<tr><td colspan='5' class='has-text-centered p-5'>Aucune règle active.</td></tr>";
?>
</tbody>
</table>
</div>
<p class="help has-text-centered mt-4">Lancé en mode local. Ctrl+C dans le terminal pour quitter.</p>
</div>
</section>
</body>
</html>

View File

@@ -0,0 +1,113 @@
#!/bin/bash
# --- 0. VERIFICATION DES DROITS ---
if [ "$EUID" -ne 0 ]; then
echo "❌ Erreur : Ce script doit être lancé avec sudo."
exit 1
fi
# Récupérer le vrai nom de l'utilisateur qui a lancé le sudo
REAL_USER=${SUDO_USER:-$USER}
echo "--- 1. Installation de PHP ---"
apt update && apt install -y php-cli
# --- 2. CONFIGURATION SUDOERS ---
echo "--- 2. Autorisation UFW pour l'utilisateur $REAL_USER ---"
SUDOERS_FILE="/etc/sudoers.d/ufw-php-manager"
if [ ! -f "$SUDOERS_FILE" ]; then
echo "$REAL_USER ALL=(ALL) NOPASSWD: /usr/sbin/ufw" > "$SUDOERS_FILE"
chmod 440 "$SUDOERS_FILE"
echo "✅ Sudoers configuré."
fi
# --- 3. OUVERTURE DU PORT 8080 ---
echo "--- 3. Configuration du Firewall pour l'interface ---"
ufw allow 8080/tcp
echo "✅ Port 8080 ouvert dans UFW."
# --- 4. CREATION DU FICHIER PHP ---
echo "--- 4. Création de firewall.php ---"
cat > firewall.php <<'EOF'
<?php
$protected_ports = ['22', '80', '443', '8080'];
$message = "";
// Action : Ajouter
if (isset($_POST['add_port']) && !empty($_POST['port'])) {
$port = escapeshellarg(trim($_POST['port']));
$proto = escapeshellarg($_POST['proto']);
exec("sudo /usr/sbin/ufw allow $port/$proto", $output, $return);
$message = ($return == 0) ? "✅ Port $port/$proto ouvert." : "❌ Erreur UFW.";
}
// Action : Supprimer
if (isset($_GET['delete'])) {
$id = (int)$_GET['delete'];
exec("sudo /usr/sbin/ufw status numbered", $check_output);
$is_protected = false;
foreach ($check_output as $line) {
if (strpos($line, "[$id]") !== false) {
foreach ($protected_ports as $p) {
if (strpos($line, $p) !== false) $is_protected = true;
}
}
}
if ($is_protected) {
$message = "🛑 Impossible de supprimer un port critique ($id).";
} else {
exec("echo 'y' | sudo /usr/sbin/ufw delete $id", $output, $return);
header("Location: firewall.php?msg=deleted");
exit;
}
}
if (isset($_GET['msg']) && $_GET['msg'] == 'deleted') $message = "🗑️ Règle supprimée.";
exec("sudo /usr/sbin/ufw status numbered", $ufw_output);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>UFW Remote Manager</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
</head>
<body class="p-5">
<div class="container is-max-desktop">
<h1 class="title">🔥 UFW Remote Manager</h1>
<?php if ($message) echo "<div class='notification is-info'>$message</div>"; ?>
<div class="box">
<form method="POST" class="field is-grouped">
<input class="input mr-2" type="text" name="port" placeholder="Port">
<div class="select mr-2"><select name="proto"><option value="tcp">TCP</option><option value="udp">UDP</option></select></div>
<button type="submit" name="add_port" class="button is-dark">Ajouter</button>
</form>
</div>
<table class="table is-fullwidth box">
<thead><tr><th>#</th><th>Vers</th><th>Action</th><th>Depuis</th><th>Action</th></tr></thead>
<tbody>
<?php foreach ($ufw_output as $line): ?>
<?php if (preg_match('/\[\s*(\d+)\]\s+(.*?)\s+(ALLOW|DENY|ALLOW IN)\s+(.*)/', $line, $m)): ?>
<tr>
<td><?= $m[1] ?></td><td><code><?= $m[2] ?></code></td><td><?= $m[3] ?></td><td><?= $m[4] ?></td>
<td><a href="?delete=<?= $m[1] ?>" class="button is-small is-danger">Supprimer</a></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
</body>
</html>
EOF
chown $REAL_USER:$REAL_USER firewall.php
# --- 5. LANCEMENT ---
echo "--- 5. Lancement du serveur ---"
echo "🚀 L'interface est disponible sur : http://$(hostname -I | awk '{print $1}'):8080/firewall.php"
echo "Pressez Ctrl+C pour arrêter le serveur."
# Lancer en tant qu'utilisateur normal (pas root) pour plus de sécurité
sudo -u $REAL_USER php -S 0.0.0.0:8080