REX de mon access SSH en accès directe depuis l'exterieur

Bonjour à tous,

Je vous partage mon petit retour d’expérience suite à la mise en place d’une règle NAT au niveau de ma box internet sur le port 22 pour pouvoir me connecter en SSH depuis l’exterieur … 155000 tentatives de connexion en SSH sur mon Jeedom à partir d’adresses IP diverses (majoritairement chine et russie) entre le 01/11/2024 et le 12/11/2024, soit près de 10 tentatives / min !!!
Les compte utilisés : root, admin, webadm, users, abc, supervisor, steam, …
Aucune n’a réussi à se connecter, bien sur

Voilà, cet accès ssh m’étant indispensable pour établir un tunnel SSH entre un réseau avec une antenne stralink (en cgnat) et ce réseau, seule solution (que j’ai trouvé) : mettre un autre port par défaut que le 22 (port > à 10000)
depuis 2 jours, plus aucune tentative de connexion pirate

Pour ceux qui veulent verifier … (lastb permet de voir toutes les tentatives de connexion echouées)

sudo lastb | wc -l

Norbert

5 « J'aime »

Bonjour Norbert,

J’ai une question, il y a moyen de réinitialisé le chiffre obtenu ?

lastb dépend du fichier de log /var/log/btmp.
Il faut le créer si il n’existe pas.

touch /var/log/btmp

Pour repartir de zéro, il doit suffire d’effacer le fichier puis de le recréer.

1 « J'aime »

Tu peux juste purger le fichier btmp

sudo truncate -s 0 /var/log/btmp

Attention btmp ne recense qu eles connexions echouées …
Si tu veux les connexions réussies, c’ets la commande last et le fichier wtmp

Norbert

2 « J'aime »

Bonjour

Pour garder les infos du fichier, il peut être préférable d’utiliser les options ( voir man lastb):

       -s, --since time
           Display the state of logins since the specified time. This is useful, e.g., to easily determine who was
           logged in at a particular time. The option is often combined with --until.

       -t, --until time
           Display the state of logins until the specified time.

avec le format :

TIME FORMATS
       The options that take the time argument understand the following formats:
       ┌─────────────────────┬────────────────────────────────────────┐
       │                     │                                        │
       │ YYYYMMDDhhmmss      │                                        │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ YYYY-MM-DD hh:mm:ss │                                        │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ YYYY-MM-DD hh:mm    │ (seconds will be set to 00)            │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ YYYY-MM-DD          │ (time will be set to 00:00:00)         │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ hh:mm:ss            │ (date will be set to today)            │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ hh:mm               │ (date will be set to today, seconds to │
       │                     │ 00)                                    │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ now                 │                                        │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ yesterday           │ (time is set to 00:00:00)              │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ today               │ (time is set to 00:00:00)              │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ tomorrow            │ (time is set to 00:00:00)              │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ +5min               │                                        │
       ├─────────────────────┼────────────────────────────────────────┤
       │                     │                                        │
       │ -5days              │                                        │
       └─────────────────────┴────────────────────────────────────────┘


exemple :

root@fedora ~ $ lastb --since 2025-04-09 | wc -l
5

Attention, supprimer et recréer un fichier pose souvent pb ! puisque le lien entre le fichier et le process est perdu. Ceci necessite de relancer le process ou relancer le serveur la plupart du temps.
Il faut plutot remettre à 0 (via truncate ou simplement >) le fichier que de supprimer/recreer

Norbert

Effacer et recréer doit suffire.

Les fichiers wtmp et btmp sont parfois absents. Le système ne journalise les informations
que si les fichiers sont déjà présents, mais ne les crée pas de lui-même. Il s’agit
d’un choix local de configuration. Si vous désirez utiliser ces journalisations, vous pouvez
créer les fichiers avec une simple commande touch (par exemple, touch /var/log/wtmp).

https://manpages.ubuntu.com/manpages/focal/fr/man1/last.1.html

Je te confirme ce que j’ai dit, ca ne marche pas (je viens de tester). Si tu supprimes et que tu recrées le fichier, les connexions échouées ne sont plus loguées
Je pense que ce qui est ecrit foncitonne SI le fichier n’existe pas. Si le fichier existe, le lien avec le fichier suppirmé n’est pas réinitialisé.
A noter que c’est ce pb (de suppression/recreation de fichiers) qui peut générer des ecarts enormes entre une commande « du » qui liste l’espace disque logiquement occupé et « df » qui liste l’espace disque physiquement occupé.

Sur Linux, on ne supprime pas les fichiers de log, on les copie et on les vide. Ca evite aussi des pbs de droits sur le sfichiers

Norbert

1 « J'aime »

Et aussi :

2 « J'aime »

Attention, si le fichier est vide, la commande retourne 2

-rw-rw---- 1 root utmp 0  1 avril 00:00 /var/log/btmp
root@jeedom:~# lastb | wc -l
2

Bonjour,
Donc si je comprend bien si on a 2 c’est bon signe ?

Le mieux est d’abord de faire lastb pour voir si il y a des lignes.
Après pour les compter, la commande de ngrataloup.

La quesiton n’ets pas vraiment de savoir si vous en avez 2 ou 10 … mai splutot 10000
pour exclure tout ca et avoir par exemple les connexions echouées sur 7 jours

lastw --since "-7days" --until "now" | sed '/^$/d' | sed '$d' | wc -l

Bonjour

J’obtiens 3 :
Une ligne avec 1 connexion
Une ligne vide
Une ligne avec le commentaire « btmp commence Tue Apr 1 17:58:35 2025 »
Il faut donc retirer 2. Normal.

root@jeedom:~# lastb
jeedo    ssh:notty    192.168.1.132    Tue Apr  1 17:58 - 17:58  (00:00)

btmp commence Tue Apr  1 17:58:35 2025
root@jeedom:~# lastb | wc -l
3
root@jeedom:~# 
1 « J'aime »

J’ai fait la même chose comme toi mais tu as été plus rapide.

root@jeedom:~# lastb
toto     ssh:notty    192.168.1.110   Tue Apr 15 14:55 - 14:55  (00:00)
toto     ssh:notty    192.168.1.110   Tue Apr 15 14:55 - 14:55  (00:00)
toto     ssh:notty    192.168.1.110   Tue Apr 15 14:54 - 14:54  (00:00)
toto     ssh:notty    192.168.1.110   Tue Apr 15 14:54 - 14:54  (00:00)

btmp commence Tue Apr 15 14:54:50 2025
root@jeedom:~# lastb | wc -l
6

Ce qui est intéressant dans le rex de ngrataloup c’est la démarche, +2 ou moins 2 cela ne change rien.

J’ai un vps hébergé avec le port 22 exposé :

root@vpsXXXXX:~# lastb

un extrait:
env_exam ssh:notty    14.224.141.217   Tue Apr  1 02:25 - 02:25  (00:00)
sol      ssh:notty    195.178.110.26   Tue Apr  1 02:24 - 02:24  (00:00)
rstudio  ssh:notty    103.186.1.131    Tue Apr  1 02:20 - 02:20  (00:00)
steam    ssh:notty    83.229.74.210    Tue Apr  1 02:19 - 02:19  (00:00)
jarservi ssh:notty    103.186.1.131    Tue Apr  1 02:18 - 02:18  (00:00)
steam    ssh:notty    207.180.219.72   Tue Apr  1 02:17 - 02:17  (00:00)
solana   ssh:notty    195.178.110.26   Tue Apr  1 02:17 - 02:17  (00:00)
bot_serv ssh:notty    83.229.74.210    Tue Apr  1 02:16 - 02:16  (00:00)
bot      ssh:notty    207.180.219.72   Tue Apr  1 02:13 - 02:13  (00:00)
john     ssh:notty    196.251.113.5    Tue Apr  1 02:12 - 02:12  (00:00)
john     ssh:notty    196.251.113.5    Tue Apr  1 02:11 - 02:11  (00:00)
12345    ssh:notty    194.0.234.36     Tue Apr  1 02:10 - 02:10  (00:00)
test     ssh:notty    111.68.107.91    Tue Apr  1 02:07 - 02:07  (00:00)
admin    ssh:notty    103.186.1.131    Tue Apr  1 02:07 - 02:07  (00:00)
testadmi ssh:notty    111.68.107.91    Tue Apr  1 02:04 - 02:04  (00:00)

btmp begins Tue Apr  1 02:04:31 2025
root@vpsXXXXX:~# lastb | wc -l
2860

J’ai rebooté le vps le 12 avril suite à mise à jour du kernel:

root@vpsXXXXX:~# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	2
|  |- Total failed:	539
|  `- File list:	/var/log/auth.log
`- Actions
   |- Currently banned:	9
   |- Total banned:	165
   `- Banned IP list:	151.19.246.42 14.103.115.117 138.204.127.54 107.174.146.26 14.103.115.215 51.195.103.245 189.251.51.200 191.187.82.6 104.248.154.34
root@vpsXXXXX:~# 

Donc 539 connexions refusées avec bannissement depuis le 12 avril
et 2860 -2 connexions refusées depuis le 1 avril.

Les pirates vont attaqués en priorité le port 22, c’est logique c’est le port par défaut du ssh. Changer le numéro de port est une bonne solution mais pas seulement.
Sur le serveur Jeedom il faut vérifier que le programme fail2ban soit bien paramétré et tester le bannissement avec iptables -L. les tests peuvent être réalisés sur le port 22 et changé après. Il faut aussi regarder le journal fail2ban.log.

Chain f2b-sshd (1 references)
target     prot opt source               destination         
REJECT     all  --  104.248.154.34       anywhere             reject-with icmp-port-unreachable
REJECT     all  --  bfbb5206.virtua.com.br  anywhere             reject-with icmp-port-unreachable
REJECT     all  --  dsl-189-251-51-200-dyn.prod-infinitum.com.mx  anywhere             reject-with icmp-port-unreachable
REJECT     all  --  vps-d05b247a.vps.ovh.net  anywhere             reject-with icmp-port-unreachable
REJECT     all  --  14.103.115.215       anywhere             reject-with icmp-port-unreachable
REJECT     all  --  107-174-146-26-host.colocrossing.com  anywhere             reject-with icmp-port-unreachable
RETURN     all  --  anywhere             anywhere        

Un plugin « fail2ban » a été conçu pour surveiller le bon fonctionnement de fail2ban. Crowdsec est plus actuel mais difficilement interfaçable avec Jeedom.

Sauf pour ceux qui tapent la commande proposée et se posent des questions.

Je vous conseille d’utiliser le merveilleux tool « crowdsec » (made in france !). Il possède entre autre une large liste d’ip reconnues comme malveillantes, et ensuite un système d’analyse de log local permettant de reconnaître des patterns d’attaques (et pas que ssh).
Toutes mes VMs hébergées et qui expose un service sur l’extérieur sont protégées par crowdsec. Et effectivement, c’est assez flippant le nombre d’attaque auquel on est exposés chaque jour…

Attaques typiques journalières :

Nombre de paquets dropé sur mon reverse proxy sur les 7 derniers jours grâces à crowdsec :

J’utilise aussi nginx proxy manager, mais j’ai abandonné Crowdsec, moins simple que fail2ban a paramétrer pour moi. Je ne suis pas contre un petit tuto.

Merci @ngrataloup pour l’info ainsi que ton REX et merci à tous les autres pour leurs compléments d’info

1 « J'aime »