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
The security of generating the ssh key in this manner. Is it better to use in-built methods to generate the ssh key?
Is it safe to assume that the
.ssh
folder is located under the users directory (for linux platforms)?General structure of the program and overall thoughts
I plan to extend this to automatically add the location, username and box name to
.ssh/config
allowing me to then dossh 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);
}
}
}
}