PhillipBlanton.com

"Save me, oh God, from people who have no sense of humor."
— Ludlow Porch

Setting up GitHub SSH on Linux (Or Windows using GitBash)

Have you ever run across an issue you remember having solved before, but can't remember how to solve it now; then you Google it, find a great article on it, and realize that you wrote it some years back?

That's what this article is. EVERYTIME I have to set up SSH on a new Linux development machine I end up Googling pieces parts here and there and end up cobbling together the solution myself. Then I move on and some time later, have to set up Github SSH on a new Linux machine again. Well that just happened, so I decided to write it all down so that it doesn't trip me up again.

Before I get started with the dry, terminal commands, let me emphasize that the main thing that trips people up is that Github gives you the HTTPS url by default, and you are going to want to use the SSH URL if you want to use Git at the bash prompt.

To begin, fire up the new Linux machine (in this case I'm using Ubuntu Gnome 17.10) and start up a terminal.

Generate your new RSA keypair...

In your Linux Bash prompt, or GitBas on Windows, run ...

   $ ssh-keygen -t rsa -b 4096 -C "yourem@iladdr.ess"

  • It will default to saving the keypair to the .ssh directory in your home directory as "id_rsa". If that's fine, then just accept the default.

    If you already have an id_rsa keypair, then name this one something else. Since this is a ssh key for Gitlab, I called mine "id_rsa_Gitlab". You can also give them project-specific, or account-specific names like, "is_rsa_gfnproject". The convention is that they all start with "id_rsa".

  • Enter your passphrase (or leave it blank)
  • Enter it again, then the key will be saved.

You will have two files in ~/.ssh/. One of them will be named according to what you specified. This is your private key. The other one has a ".pub" file extension. Open that one in a text editor and copy its contents to your paste buffer.

  • Log in to GitHub (or the Git system of your choice)
  • Click on your picture in the top-right corner and select "Settings"
  • On the left, click on "SSH and GPG keys".
  • In the top right corner, click the green [New SSH Key] button.
  • Give it a meaningful title, like "Linux Dev Box" and paste the contents of the public key into the "key" field.
  • Click the green [Add SSH Key] button.

You should be good to go. Clone a GitHub repo to the local machine like this...

Go to a directory where you want to store your repositories

Execute the following command (modified for your own account and repo)...

   $ git clone git@github.com:acctname/reponame.git

You should see the clone procedure run. If it complains about your credentials not being trusted, then have a look at the keys SSH has installed...

Execute the following command 

   $ ssh-add -l

You should see something like...

4096 SHA256:i2fLkp3x3Dy+V3GpnU5IBWFb0wVZoPBvRsYp4aRWwsL /home/pblanton/.ssh/id_rsa (RSA)
4096 SHA256:i2fLkp3x3Dy+V3GpnU5IBWFb0wVZoPBvRsYp4aRWwsL yourem@iladdr.ess (RSA)

I have of course, shown fake keys for demo purposes.

If you don't see the expected keys, then run this command...

   $ ssh-add

Type in your passphrase (if any), and the SSH client will ingest your keys. Try cloning again, and it should all work. You should be able to Git at the command-line to your heart's content without being prompted for your credentials again.

Time to start writing some shell scripts to automate everything now. Automation is cool!

Update 2/14/2018:

Normally I am working on a virtual machine that has been especially configured for a client, so creating an ssh public/private keypair, saved as id_rsa works fine. Today however, I needed to access a Git repository at a client's site, running under a system called "Gerrit" which is a code review system with a Git back-end. This client also has an internal GitHub Enterprise system set up at Github.<clientname>.com, and we also use plain ol' Github.com; That means three different Git systems that I have to access from the same system. I want my Git bash to work in any repository, as it targets any of these systems, transparently. The way to do that is with an ssh config file. After you have created the requisite number of properly named ssh certificates using the instructions above, then you are ready to create your config file as follows...

Navigate to your .ssh directory, open a text editor of your choice and create a file called "config" with no file extension. I'm doing it in Git Bash, so vi...

   $ vi config

Edit the file as necessary. Here is an example...

The keys are the Host, and IdentityFile settings as follows...

Host: url that will trigger this identification.
 IdentityFile: The SSH Cert to use for this authentication.

The indentation of the IdentityFile line under "Host" is important. Make it one space.

More examples...

Let's say that I am only using Github, but I have a work account and a personal account on Github. My personal account name is "pblanton" and let's assume I also have a Github account for Gort work. My configuration would look like this...

   # SSH Authentication for my personal projects
   Host pblanton.github.com
    IdentityFile /f/.ssh/id_rsa_pblanton

 

   # SSH Authentication for Gort projects
   Host gortbot.github.com
    IdentityFile /f/.ssh/id_rsa_gortbot
 

Now, when you clone a project for your personal work, add "pblanton" to the url. For instance, let's clone WebGoat (git@github.com:WebGoat/WebGoat.git). In this case though if we tweak the url to be

   git@pblanton.github.com:WebGoat/WebGoat.git

then when we clone it...

Github doesn't care about the extra subdomain, but the Git client will associate it with the credentials specified by the "Host" line that matches "pblanton.Github.com" in the config file, and anytime we push or pull it the correct creds will be used.

Gitlab, BitBucket, et. al.

Since the Git client associates your credentials to the url string found in "Host" you aren't limited to Github. ANY repository that implements Git will work as long as you have a valid "Host" entry that matches the url.

For instance, my GitLab repos can use the credentials in .ssh/id_rsa_lab through the following entry in config...

   # SSH Authentication for my personal projects
   Host gitlab.com
    IdentityFile /f/.ssh/id_rsa_gitlab

 

Since "Gitlab" is unique among the "Host" values in my ssh config file, there is no need to prepend it with "pblanton", but if I had multiple accounts on Gitlab that I used for different purposes, then that would work here too.

Make a bootable USB drive for ANY bootable ISO from Linux.

So, you have abandoned Microsoft Windows wholesale, choosing to perform most of your work in Linux or OSX. But now you need to make a bootable Windows 10 USB drive in order to set up a laptop for someone. You Google how to create a bootable disk "FROM LINUX" but all you get is different flavors of the same Ubuntu bootable live USB drive from Windows. Occasionally you'll find a tutorial for Linux that references some crappy UI app to do it for you.

That's not necessary.  It's pretty easy to make a bootable flash drive from Linux using ANY bootable ISO you have access to. Here's the command...

sudo dd bs=4M if=blahblahblah.iso of=/dev/sda && sync

Break it down...

  • sudo -> because you have to be a super-user in order to do it.
  • dd -> data dump (dd) is the program we will use.
  • bs=4M -> Be sure to use four-meter long bullshit sticks *
  • if -> input file
  • of -> output file. In this case the flash drive is /dev/sda.
  • && -> chain another command IF the first command succeeds.
  • sync -> flushes the write buffers to ensure that the write operation is complete before you yank the drive.

* just kidding. bs is the BlockSize switch. We're telling dd to copy the data in 4Megabyte blocks. If you're on a Mac, be sure to use a lower-case "m".

If your flash drive partition is  "/dev/sda1" then be sure to use just "/dev/sda". You want to write the iso file contents to the raw drive and not as a separate partition. 

Now you'll NEVER need Windows and Rufus ever again.

Accessing Windows NTFS partitions from Linux on a dual-boot system

I dual boot Windows 10 and Kubuntu 16.04 Linux. Recently, after upgrading to Windows 10, I noticed that I was unable to mount my exFat and NTFS partitions from the Linux side.

The exFat problem is easy to resolve. Start up the terminal of your choice and type...

sudo apt-get install exfat-fuse

That will install the exFat drivers for your Linux system. From now on you're good to go regarding exFat. If you don't know about exFat, it is the best format for flash drives. It is supported on Windows, Mac OSX and Linux (after you install it) unlike FAT32, and doesn't have the 4GB limitation that FAT does; which makes it perfect for using one drive across all of your operating systems.  

But this isn't the exFat issue. It is the problem of not being able to mount an NTFS partition from Linux, which has always been a no-brainer.If you get an error like this when you try to mount an NTFS partition, then you know what I'm talking about...

An error occurred while accessing 'Home', the system responded: The requested operation has failed: Error mounting /dev/sda1 at /media/9C9445DC9445BA12: Command-line `mount -t "ntfs" -o "uhelper=udisks2,nodev,nosuid,uid=500,gid=500,dmask=0077,fmask=0177" "/dev/sda1" "/media/9C9445DC9445BA12"' exited with non-zero exit status 14: Windows is hibernated, refused to mount. Failed to mount '/dev/sda1': Operation not permitted The NTFS partition is in an unsafe state. Please resume and shutdown Windows fully (no hibernation or fast restarting), or mount the volume read-only with the 'ro' mount option.

The problem is caused by new functionality in Windows 10 (and Windows 8, which I never used) that causes the default shutdown behavior to be to hibernate your PC rather than actually shutting it down. It is called "Fast Startup" and is supposed to make Windows 10 "feel" faster than it really is. In order to access these NTFS partitions on Linux, you need to disable Fast Startup and hibernation as follows...

  • Boot to Windows 10.
  • Click your start menu and type "Power Options" in the search box and select Power Options from the search results.
  • On the left side, click "Change what the power buttons do".
  • Scroll to the bottom (you may have to unlock the page - Look for a link to unlock options at the top), and de-select the "Turn on fast startup (recommended)" and "Hibernate" options.

This will probably fix the issue, but in case it doesn't, you can force the issue by executing the following command in a windows terminal window (command prompt) running as Administrator...

powercfg.exe -h off

Shut-down Windows normally now, and re-boot into Linux. You should then be able to access your Windows 10 NTFS partition normally.

Good luck!

Just replaced the Windows 7 Bootcamp Partition with OpenSUSE 11.2

openSUSE.org

And it is the finest Linux distribution I have ever used. I used to use SUSE back in the 2001-2004 time, before Novell bought it. I liked buying the boxed version at Best Buy or CompUSA. After Novell bought it, they jacked up the price and it went away from the retailers. I'd heard good things about this upstart Ubuntu distro and that is what I started using. When OpenSUSE came out, I stuck with Ubuntu, because I liked it. Recently though I was wanting to try out a new distribution on a Windows machine I was upgrading to Linux, and the OpenSUSE with the latest KDE blew me away.

After getting my new Core i7, 27" iMac, I was thinking about setting up the Boot Camp partition with Windows 7, but thought I'd try OpenSUSE on Boot Camp. I downloaded the freshly released 11.2 in 64-bit and was hooked. I can run Windows 7 in a Fusion Virtual Machine without any trouble, so my newly carved out Boot Camp partition goes OpenSUSE. My machine is *nix to the metal. It's a good feeling.

If you are a Windows developer and are looking for a nice, clean operating system for a change (Yeah, I know Windows 7 is the bomb. I don't care), I heartily recommend upgrading to a Mac, and Boot Camping, 64-bit style with OpenSUSE Linux.