OpenSSL SFTP + Program C# + Clé privé

Fermé
svChris Messages postés 1 Date d'inscription mercredi 24 août 2022 Statut Membre Dernière intervention 24 août 2022 - Modifié le 6 sept. 2022 à 15:59
 SvChris - 25 août 2022 à 23:00

Bonjour,

J'ai besoin de créer un programme en C# afin d'envoyer des fichiers sur un serveur SFTP, avec connexion avec des clefs de chiffrement et une passphrase.

Pour ce faire j'utilise Renci.SshNert dans Visual Studio.
Et j'ai créé un serveur SFTP sur un vieux PC sous Linux Ubuntu. A l'aide de OpenSSL.
 

Cela fonctionne, mais j'ai mis du temps à le mettre en route et j'ai des interrogations.

Dans un 1er temps j'ai créé mon serveur avec une connexion par mot de passe.

J'ai testé la liaison avec powershell. c'est OK

Puis créer les clefs avec openSSL sur mon PC Windows10.

J'ai placé la clef public (renommé en authorized_key) sur le serveur 'linux" dans /home/<user>/.ssh. , mais j'ai constaté qu'à la fin de ma clef public, j'ai mon nom et domaine de connexion. Déjà est-ce normale?

Ensuite j'ai modifié le fichier sshd_config pour qu'il utilise une clef de chiffrement et qu'il ne demande plus le mot de passe.

Dans le PC Windows 10, j'ai placé la clé privé dans c:/Users/<user>/.ssh. (j'ai créé le répertoire).

Lorsque je me connecte avec PowerShell, cela fonctionne, mais avec mon program en C# lorsque je charge la clef privé il plante tout de suite avec une indication d'incompatibilité, avant même donc la tentative de connexion.

Du coup j'ai essayé de créer des clefs depuis puttykeygen, mais si je place la clef public de puty sur le serveur, plus rien ne fonctionne.

Je suis arrivé à le faire fonctionner, en utilisant la clef public de OpenSSH, puis en chargeant la clef privé dans Putykeygen et la convertissant en openSSL, et la si je charge dans mon application cette clef privé cela fonctionne.

Mes questions:

1)Est-ce normale que dans ma clef public, j'ai mon nom et domaine de connexion Windows ? Cela ne bloque t'il pas la connexion pour d'autre utilisateur ?

2)J'ai vraiment beaucoup tâtonné pour arriver à me connecter avec mon application à l'aide d'une clef privé créer par OpenSSL, mais en la convertissant en openSSL par puttykeygen (effectivement putty modifie la clef) est-ce normale.
 

Une clef public créer par puttykegen, n'a pas fonctionné non plus.

Avez-vous des sites ou information à me donner pour mieux comprendre tout cela.

Merci

le code C#:
 

//ecriture du fichier sur le serveur SFTP avec une clé privée
                    string keyFimePathName = VariablesGlobales.StorgeSFTPPath + "\\" + VariablesGlobales.SFTPKeyFile;
                    if (File.Exists(keyFimePathName))
                    {
                         var keyFile = new PrivateKeyFile(keyFimePathName, VariablesGlobales.SFTPKeyPassphrase);
                        var keyFiles = new[] { keyFile };
                        var methods = new List<AuthenticationMethod>();
                        methods.Add(new PrivateKeyAuthenticationMethod(VariablesGlobales.SFTPUserName, keyFiles));
                        var con = new ConnectionInfo(VariablesGlobales.SFTPHost, VariablesGlobales.SFTPPort, VariablesGlobales.SFTPUserName, methods.ToArray());
                        using (var client = new SftpClient(con))
                        {
                            // connexion
                            client.Connect();
                            // vérification de l'existence du répertoire
                            if (!client.Exists(VariablesGlobales.DistantCSVFilePath))
                            {
                                // et création du répertoire s'il n'existe pas
                                client.CreateDirectory(VariablesGlobales.DistantCSVFilePath);
                            }
                            // écriture du fichier
                            client.ChangeDirectory(VariablesGlobales.DistantCSVFilePath);
                            using (var fileStream = new FileStream(CSVFilePathName, FileMode.Open))
                            {
                                //client.UploadFile(fileStream, System.IO.Path.GetFileName(CSVFilePathName));
                                client.UploadFile(fileStream, System.IO.Path.GetFileName(CSVFilePathName));
                            }
                            client.Disconnect();
                        }
                    }
A voir également:

3 réponses

yg_be Messages postés 23406 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 décembre 2024 Ambassadeur 1 557
24 août 2022 à 14:01

bonjour, peux-tu expliquer cela en nommant les différents éléments impliqués?

"à la fin de ma clef public, j'ai mon nom", c'est particulièrement confus.
As-tu observé cela en décodant la clé?

Quand tu écris "/home/<user>/.ssh.", qu'est-ce <user>?

0
barnabe0057 Messages postés 14454 Date d'inscription lundi 2 mars 2009 Statut Contributeur Dernière intervention 30 novembre 2024 4 918
25 août 2022 à 18:35

Bonjour,

N'y aurait-il pas une confusion entre SFTP et FTPS ?

Car je ne comprend pas ce que vient faire OpenSSL dans l'histoire.



0

Vois avez parfaitement raison,  je me suis carement planté. Comme quoi il me faut vraiment potasser sur le sujet.  C'est OpenSSH pas SSL.

Je reviens vers vous demain je suis claqué là. 

Bonne nuit. 

0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
Modifié le 6 sept. 2022 à 15:58

Bonjour,

J'ai placé la clef public (renommé en authorized_key) sur le serveur 'linux" dans /home/<user>/.ssh. , mais j'ai constaté qu'à la fin de ma clef public, j'ai mon nom et domaine de connexion. Déjà est-ce normale?

Normalement c'est username@hostname (quel que soit l'OS) et c'est normal. Cela permet s'il y a plusieurs clés publiques installées de savoir laquelle correspond à quoi. Note que si l'on peut s'authentifier sur le serveur ssh distant (par exemple par login / mot de passe), on peut installer sa clé public avec la commande ssh-copy-id.

Exemple :

ssh-copy-id login_ubuntu@hostname_ou_ip_ubuntu

Ensuite j'ai modifié le fichier sshd_config pour qu'il utilise une clef de chiffrement et qu'il ne demande plus le mot de passe.

Oui c'est bien, pour sécuriser ton serveur ssh, il faut idéalement n'autoriser que les authentification par clé ssh. Voici les modifications que personnellement j'apporte à /etc/ssh/sshd_config (pour rappel les lignes précédées d'un # sont des commentaires ; certaines commentaires donnent des exemples de directives de configuration et peuvent être décommentées et modifiées) :

PermitRootLogin no
PasswordAuthentication no
UsePam no
ChallengeResponseAuthentication no
UseDNS no

Dans le PC Windows 10, j'ai placé la clé privé dans c:/Users/<user>/.ssh. (j'ai créé le répertoire).

Généralement tu crées une paire clé public/clé privée par machine cliente. Libre à toi d'utiliser cette paire de clé pour atteindre différents serveurs ssh. Il est important de protégée la paire de clé avec une passphrase au moment de sa création. Pour créer une clé tu peux utiliser la commande ssh-keygen.

Exemple :

ssh-keygen -t rsa -b 2048

Et donc tu as au niveau du serveur autant de clé public qu'il y a de machines clientes. Cela permet si une machine est compromise de n'avoir à révoquer qu'une seule clé (en la supprimant de ~/.ssh/authorized_keys) et c'est d'ailleurs dans ce cas de figure qu'on est content d'avoir le login/hostname associé à chaque clé.

Donc dans l'absolu, rien de générer une seule paire de clé privée/clé publique et de copier ta clé privée sur tes différentes machines. Mais si une machine est compromise, ta clé privée est potentiellement compromise (elle le sera quand la passphrase de la clé privée aura été cassée), et donc il faut repartir sur un jeu de clé neuve et révoquer l'ancienne.

Lorsque je me connecte avec PowerShell, cela fonctionne, mais avec mon program en C# lorsque je charge la clef privé il plante tout de suite avec une indication d'incompatibilité, avant même donc la tentative de connexion.

Je ne connais pas assez C# pour te dire, mais ce qui est sur c'est que si ta machine cliente est sous Linux, il faut que ssh-agent active la clé privée en lançant la commande :

ssh-add

La passphrase sera alors demandée et si elle est correctement donnée, l'identité correspondante sera activée.

Exemple :

(mando@silk) (~) $ ssh-add -L
The agent has no identities.

(mando@silk) (~) $ ssh-add
Enter passphrase for /home/mando/.ssh/id_rsa:  
Identity added: /home/mando/.ssh/id_rsa (/home/mando/.ssh/id_rsa)

(mando@silk) (~) $ ssh-add -L
ssh-rsa AAAAB3NzaC1[...]B9k8TzTNsLgPiThzMxUtPb
Gr /home/mando/.ssh/id_rsa

Une fois l'identité activée, tu peux te connecter aux serveurs ssh avec le login adéquat pour lesquels la clé ssh publique a été installée. Par exemple si ta clé est installée sur toto@11.22.33.44 :

ssh toto@11.22.33.44

Du coup j'ai essayé de créer des clefs depuis puttykeygen, mais si je place la clef public de puty sur le serveur, plus rien ne fonctionne.

Je suis arrivé à le faire fonctionner, en utilisant la clef public de OpenSSH, puis en chargeant la clef privé dans Putykeygen et la convertissant en openSSL, et la si je charge dans mon application cette clef privé cela fonctionne.

Personnellement je te conseille de ne pas générer des clé autrement qu'avec ssh-keygen. Putty a tendance à générer des clés dans un format qui n'est pas compris par ssh.

Mes questions:

1) Est-ce normal que dans ma clef public, j'ai mon nom et domaine de connexion Windows ? Cela ne bloque t'il pas la connexion pour d'autre utilisateur ?

Oui pour la première question. Non pour la seconde. C'est vraisemblablement le format de la clé publique qui est bancale ou l'identité qui n'est pas active côté client.

Une clé publique bien formée ressemble typiquement à ça:

ssh-rsa une_longue_chaine_hashée login@hostname

2) J'ai vraiment beaucoup tâtonné pour arriver à me connecter avec mon application à l'aide d'une clef privé créer par OpenSSL, mais en la convertissant en openSSL par puttykeygen (effectivement putty modifie la clef) est-ce normale.

Aucune idée, je t'ai donné la démarche qu'on aurait sous Linux (et les seules questions qu'on se poserait). Maintenant, je suis conscient que tu es sous Windows et que certains éléments s'utilisent peut être différement avec Putty.

@barnabe0057 N'y aurait-il pas une confusion entre SFTP et FTPS ?

C'est une bonne question, et j'invite svChris à jeter un œil à ce lien pour voir la différence entre les deux pour nous dire ce qu'il veut faire.

Concernant SFTP :

  • Côté serveur : il suffit d'installer un serveur SSH. Les utilisateurs SFTP sont les utilisateurs Linux définis sur la machine. Il est recommandé de n'autoriser que les authentification par clé afin de sécuriser le serveur SSH.
  • Côté client :
    • Sous Linux, la plupart des explorateurs de fichiers sous Linux (nautilus, dolphin, konqueror...) supportent nativement SFTP (il suffit dans nautilus d'aller à l'URL ssh://login@machine ; pour konqueror et dolphin : fish://login@hostname). Tu peux alors manipuler les fichiers distants comme pour un partage réseau classique. On peut aussi directement utiliser des commandes comme scp.
    • Sous Windows, l'idéal est d'utiliser un outil comme WinSCP.

Concernant FTPS :

  • Côté serveur :
    • Il faut au préalable installer et configurer un serveur ftp. Sous Linux le plus simple à mettre en place est proftpd. Certains installent vsftpd mais c'est assez compliqué à configurer.
    • Éventuellement, on peut modifier la politique utilisée pour définir les utilisateurs FTP. Par défaut, proftpd utilise les couples login/mot de passe des utilisateurs Linux définis sur la machine.
    • Enfin, il faut configurer le certificat SSL (car à ce stade, ce n'est que du FTP). Voir ce tutoriel.
  • Côté client :
    • Sous Linux, je ne sais pas si les URL sftp:// sont supportées dans les explorateurs classiques. A tester. Au pire installe FileZilla.
    • Sous Windows, l'idéal est d'utiliser un outil comme FileZilla.

Bonne chance

0