1
\$\begingroup\$

I have started to create a console app, which I am testing locally on my mac.

The idea is to generate an ssh key and structure the storage of these keys within the .ssh folder. My thought behind this is for my digital ocean ssh keys, and so I am using a folder structure dictated by the droplet name and user.

i.e

/users/user.name/.ssh/<droplet1>/root
/users/user.name/.ssh/<droplet1>/git
/users/user.name/.ssh/<droplet2>/root
/users/user.name/.ssh/<droplet2>/git

I have used asp.net core. I am assuming the .ssh folder is directly below the location of the $HOME directory. I have also assumed the ssh-keygen program is located at /usr/bin/ssh-keygen

My questions relate to

  1. The security of generating the ssh key in this manner. Is it better to use in-built methods to generate the ssh key?

  2. Is it safe to assume that the .ssh folder is located under the users directory (for linux platforms)?

  3. General structure of the program and overall thoughts

  4. I plan to extend this to automatically add the location, username and box name to .ssh/config allowing me to then do ssh droplet1-root to login to droplet1 as root user.

My simple program is as follows:

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace gssh
{
    class Program
    {
        static void Main(string[] args)
        {
            ValidateCompatibility();

            string homePath = GetHomePathOrExit();

            Console.WriteLine($"The users home directory is: {homePath}\n");

            // Check the state of .ssh directory
            string sshDirectory, configLocation;
            bool configFileExists;
            CheckStateOfSshDirectory(homePath, out sshDirectory, out configLocation, out configFileExists);

            string locationOfSshKey = GetLocationOfKeyOrExit(sshDirectory);

            // Check that the directory does not exsist otherwise exit
            // Create Directory
            // generate key

            if (Directory.Exists(locationOfSshKey))
            {
                Console.WriteLine("Key location already exists, exiting...");
                Environment.Exit(1);
            }

            Directory.CreateDirectory(locationOfSshKey);
            Console.WriteLine("Directory Created");

            CreateSshKey(locationOfSshKey);

            Console.WriteLine(configLocation);
            Console.WriteLine(configFileExists);
        }

        private static void CreateSshKey(string locationOfSshKey)
        {
            //Create process
            System.Diagnostics.Process pProcess = new System.Diagnostics.Process();

            //strCommand is path and file name of command to run
            pProcess.StartInfo.FileName = "/usr/bin/ssh-keygen";

            //strCommandParameters are parameters to pass to program
            pProcess.StartInfo.Arguments = $"-t rsa -b 4096 -N '' -f {locationOfSshKey}/key";

            pProcess.StartInfo.UseShellExecute = true;

            //Start the process
            pProcess.Start();

            //Wait for process to finish
            pProcess.WaitForExit();
        }

        private static string GetLocationOfKeyOrExit(string sshDirectory)
        {
            Console.Write("What is the name of the machine/service the ssh key will be used for? ");
            var machine = Console.ReadLine();
            Console.Write("What user/role ssh key will be used for? ");
            var user = Console.ReadLine();

            if (String.IsNullOrEmpty(machine) || String.IsNullOrEmpty(user))
            {
                Console.WriteLine("One or more of your options was empty");
                Environment.Exit(0);
            }

            string locationOfSshKey = $"{sshDirectory}/{machine}/{user}";

            Console.WriteLine("The location of your ssh key will be: ");
            Console.WriteLine(locationOfSshKey);
            Console.Write("is this ok (y/N): ");
            var ok = Console.ReadLine();

            if (!ok.ToLowerInvariant().Equals("y"))
            {
                Console.WriteLine("Key was not created");
                Environment.Exit(0);
            }

            return locationOfSshKey;
        }

        private static void CheckStateOfSshDirectory(string homePath, out string sshDirectory, out string configLocation, out bool configFileExists)
        {
            sshDirectory = $"{homePath}/.ssh";
            configLocation = $"{sshDirectory}/config";
            configFileExists = false;
            if (!Directory.Exists(sshDirectory))
            {
                Console.WriteLine($"Could not find .ssh directory ({sshDirectory})");
                Environment.Exit(1);
            }

            configFileExists = File.Exists($"{sshDirectory}/config");
            Console.WriteLine($"Checking whether ssh config file exists {configLocation}: {configFileExists}");
        }

        private static string GetHomePathOrExit()
        {
            string homePath = Environment.GetEnvironmentVariable("HOME");
            if (homePath == null || !Directory.Exists(homePath))
            {
                Console.WriteLine("Could not find HOME environment variable or HOME path does not exist");
                Environment.Exit(1);
            }

            return homePath;
        }

        private static void ValidateCompatibility()
        {
            bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
            if (isWindows)
            {
                Console.WriteLine("Windows is not yet supported");
                Environment.Exit(0);
            }
        }
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.