Monday 30 September 2019

The Last Argument

Now this is firmly in the realms of "I Did Not Know That" ....

Whilst tinkering with a private Docker Registry, I was reading this tutorial from Digital Ocean: -

How To Set Up a Private Docker Registry on Ubuntu 18.04


On the server you have created to host your private Docker Registry, you can create a docker-registry directory, move into it, and then create a data subfolder with the following commands:

    mkdir ~/docker-registry && cd $_

    mkdir data

The thing that perked my interest was the use of $_

I realised that this was somehow magically changing into the newly created ~/docker-registry subdirectory .....

How did this work ?

The internet had the answer ...

what does 'cd $_' mean?

$_ expands to the last argument to the previous simple command* or to previous command if it had no arguments.

mkdir my-new-project && cd $_

^ Here you have a command made of two simple commands. The last argument to the first one is my-new-project so $_ in the second simple command will expand to my-new-project. 


In other words, the magic argument $_ means "Take the argument from the previous command i.e. my-new-project and run the cd command against it.

So, to take the first example further, I could've done this: -

mkdir -p ~/docker-registry/data && cd $_

which would: -

(a) create the entire path - ~/docker-registry/data
(b) change into it

which can be validated: -

pwd

/Users/hayd/docker-registry/data

Amazing !

Nginx and IP v6 - not best friends ...

Having installed Nginx on an Ubuntu 18.04.3 LTS box, I saw this: -

systemctl status nginx.service

● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Mon 2019-09-30 02:04:20 PDT; 7s ago
     Docs: man:nginx(8)
  Process: 8643 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS)
  Process: 8477 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
  Process: 8644 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=1/FAILURE)
 Main PID: 8482 (code=exited, status=0/SUCCESS)

Sep 30 02:04:20 arnold.sideways.com systemd[1]: Starting A high performance web server and a reverse proxy server...
Sep 30 02:04:20 arnold.sideways.com nginx[8644]: nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)
Sep 30 02:04:20 arnold.sideways.com nginx[8644]: nginx: configuration file /etc/nginx/nginx.conf test failed
Sep 30 02:04:20 arnold.sideways.com systemd[1]: nginx.service: Control process exited, code=exited status=1
Sep 30 02:04:20 arnold.sideways.com systemd[1]: nginx.service: Failed with result 'exit-code'.
Sep 30 02:04:20 arnold.sideways.com systemd[1]: Failed to start A high performance web server and a reverse proxy server.

As ever, Google helped: -


In essence, the problem was that Nginx was trying to bind to an IP version 6 ( IP v6 ) address, which wasn't available on this particular host.

This is controlled within the Nginx configuration file: -

/etc/nginx/sites-available/default

...
server {
        listen 80 default_server;
        listen [::]:80 default_server;
...

Once I removed ( commented out ) this line, and restarted Nginx: -

systemctl restart nginx.service

Nginx was A-OK: -

systemctl status nginx.service

● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-09-30 02:10:02 PDT; 5s ago
     Docs: man:nginx(8)
  Process: 8643 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS)
  Process: 9064 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
  Process: 9054 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
 Main PID: 9068 (nginx)
    Tasks: 3 (limit: 2319)
   CGroup: /system.slice/nginx.service
           ├─9068 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           ├─9069 nginx: worker process
           └─9070 nginx: worker process

Sep 30 02:10:02 arnold.sideways.com systemd[1]: Starting A high performance web server and a reverse proxy server...
Sep 30 02:10:02 arnold.sideways.com systemd[1]: Started A high performance web server and a reverse proxy server.

Friday 20 September 2019

SSH and "Too many authentication failures" - a new one on me

Having created a new user on an Ubuntu 16.04 boxen, I started seeing this: -

Received disconnect from 192.168.3.123 port 22:2: Too many authentication failures
Disconnected from 192.168.3.123 port 22

whilst trying to SSH into the box, using the new account: -

ssh testfest@192.168.3.123

even though I was able to SSH using my own account ....

On the target box, I was seeing: -

 Sep 19 16:21:24 ubuntu sshd[192635]: error: maximum authentication attempts exceeded for testfest from 192.168.6.124 port 54324 ssh2 [preauth]
 Sep 19 16:21:24 ubuntu sshd[192635]: Disconnecting: Too many authentication failures [preauth]
 Sep 19 16:21:48 ubuntu su[192609]: pam_unix(su:session): session closed for user testfest

One key (!) difference ....

For my own user, I'm using my SSH private key ...

For this new user, I'm using a password ...

There was a correlation ...

In my Mac's local SSH directory ( ~/.ssh ) I had a file: -

~/.ssh/config

which was set to: -

Host *
 AddKeysToAgent yes
 UseKeychain yes
 IdentityFile ~/.ssh/id_rsa

In broad terms, my Mac was trying to be helpful and send MY private key to assert the identity of this new user ... which wasn't ever going to work ...

I tried moving ~/.ssh/config to ~/.ssh/cheese but to no avail.

As ever, Google had the answer ( and, yes, Google is my friend ) : -


This is usually caused by inadvertently offering multiple ssh keys to the server. The server will reject any key after too many keys have been offered.

You can see this for yourself by adding the -v flag to your ssh command to get verbose output. You will see that a bunch of keys are offered, until the server rejects the connection saying: "Too many authentication failures for [user]". Without verbose mode, you will only see the ambiguous message "Connection reset by peer".

To prevent irrelevant keys from being offered, you have to explicitly specify this in every host entry in the ~/.ssh/config (on the client machine) file by adding IdentitiesOnly like so:

Host www.somehost.com
  IdentityFile ~/.ssh/key_for_somehost_rsa
  IdentitiesOnly yes
  Port 22

If you use the ssh-agent, it helps to run ssh-add -D to clear the identities.

Of course, I didn't think to enable verbose mode on the SSH client via ssh -v but ...

I did try the tip of clearing the identities: -

ssh-add -D

and ... IT WORKED!!

Every day, it's a school day !

Friday 13 September 2019

Yay, we have a new mainframe with which to play .... IBM z15

Sharing an article from Patrick Moorhead, hosted at Forbes: -

IBM Galvanizes Its Place In Secure And Private Workloads With New z15 Platform

In the world of computers, one of the oldest and best-known in the industry is the IBM mainframe, which has existed since the 1960s. This week IBM unveiled the latest addition to its Z mainframe portfolio, a new platform called the “z15”, which was designed with data privacy, security and hybrid multicloud in mind. Let’s take a closer look at the offering, and what it means for IBM’s play for a seat at the secured hybrid cloud table.  

IBM Galvanizes Its Place In Secure And Private Workloads With New z15 Platform

and we have one sitting in the machine-room less than 50 feet away from where I'm sitting right now ....

To say I'm excited is an under-statement .....

More to follow .....

Friday 6 September 2019

MainframerZ Skills meetup at Mediaocean in London - 2 October 2019

I'll be there, will you ?

MainframerZ Skills meetup at Mediaocean

Join us for our 4th MainframerZ meetup on Wednesday 2nd October. With the success of our last event, we'll be hosted again by Mediaocean near the Tate Modern.

This will be our first themed event, with focus on Z Skills. Come along for a range of lightning talks, discussions, and not forgetting of course, free pizza!

Meet other Z professionals, grow your network, and help continue to shape the future of MainframerZ!

We look forward to meeting new members and welcoming back some of our experienced members (and don't forget your MainframerZ badges!)

Want to share something at the event? Or start a discussion? Get in touch with our organisers, we'd love to hear from you.

Provisional Agenda
6:15 - 6:45 Arrival and registration
7:00 - 9:15 Introductions, talks, pizza and discussion

GitHub and SSH keys - so now I know

I've been using GitHub in seriousness for the past 7 months or so, since switching into a development role.

One of the oh-so-lovely things is that I can access my repositories using SSH, making git clone and git remote and git fetch and git rebase so much easier ...

I no longer need to muck about with HTTPS URLs and user IDs and passwords, like a cave person ...

Instead, I merely need to teach the git client about my SSH credentials, and I'm good to go.

This means, in part, generating an SSH public/private key pair using a command such as ssh-keygen as per the following example: -

ssh-keygen -b 4096 -t rsa -f /tmp/foobar -N ""

Generating public/private rsa key pair.
Your identification has been saved in /tmp/foobar.
Your public key has been saved in /tmp/foobar.pub.
The key fingerprint is:
SHA256:jdVHYm0U7hceMDZ594LaOhBTz+BC0YPTWtfl6eNfv3I hayd@Daves-MBP
The key's randomart image is:
+---[RSA 4096]----+
|        .=  oO=o.|
|        + Boo=Boo|
|       . *.*.o+++|
|        =+. +o+ +|
|        S+.o  .=.|
|        . . . ...|
|         . .   ..|
|          o  . E+|
|           .  o.+|
+----[SHA256]-----+

and then grab the public key: -

cat /tmp/foobar.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+RhkGDj7zr86FLEkmhcQ5+bA9IwFGtdAVwq7bqkVvbbsWv4YtupknAEaao8epLAipZjHGgitlUskBGDlQc4TGTTyOHt6goYIjfetUv9XtWy4gsyF8k69x6NfvPZ/BFvLWSSc0LPH6+jYSs7ZNdzsqoafo7qr/nnjkCvD/raTUkuPgnoWFMAyKGcUbMHjaHHvOYf2DJriFoIlK+hSYO7tBj+Cf5OS1/DgNYHqSM8l3fVspM2fzyz2VAGEMZRsRWBh0CF7nKxc1aWp2gMzZEX5RJ9Lth+gIVIaWCixbuAerh82y4d/7eTHSh9OAOX/QNTwCC+eOTTaS7G/W+PoBSAx8wJi3xZapotOe43UgJ+KE+sRFjGXr/oe8w9IenfWiPiEAhdD9YHsOBCpvQ65zZLH75tGdKQ3Neu2wgP8os6qPTMU9S02wsit3vWsiAgLURRMX9Fat1XTI737B9rwdA/JnFMDf15szN9wg3nypRuvgtAtihhxJH87CT8R23XzlgNhCroYBkprlC+hGXmdyifxCFdSAgBo4xzm2XYRL63WBnfd8MOOLOoxxQDV8EYTW5PCS3grx3Rh07W6Lcs1Jnw6oYBUOpseZQHdzerX0mLuMoJL4uM3ZB+moTyi7UgsbMsBlPWO6xKTbhD3X4ZOhiMpBF/J9dJ3HfeFFnVU6Is6z2w== hayd@Daves-MBP

to the clipboard

PS On macOS, this is a simple matter of running pbcopy < /tmp/foobar.pub 

We can then navigate to the Settings -> SSH and GPG keys page on GitHub: -


From there we can simply click the New SSH key button, give the to-be-added key a useful name e.g. Dave's MacBook, September 2019 etc. and paste in the public key from the clipboard.

This results in a new key: -


However, there is one small downside - GitHub merely shows the fingerprint of the newly added key: -

19:fd:a6:ff:44:a2:5a:11:06:75:0b:86:4d:c1:88:4c

which makes it somewhat hard to track back to an actual key pair, especially if one uses a less-than-explanatory name.

However, there is good news ....

This command: -

ssh-keygen -l -E md5 -f /tmp/foobar

can be run against the public OR private key ( they're a pair! ), and returns the fingerprint in the same MD5 format as GitHub uses: -

4096 MD5:19:fd:a6:ff:44:a2:5a:11:06:75:0b:86:4d:c1:88:4c hayd@Daves-MBP (RSA)

Notice that the fingerprint is the same !!

Now on an audit of my GitHub and GitHub Enterprise accounts ........

*UPDATE* And I can do this to get the fingerprint of ALL the keys: -

for i in ~/.ssh/*.pub; do ssh-keygen -l -E md5 -f $i; done

Thanks to this: -


for inspiration.

Visual Studio Code - Wow 🙀

Why did I not know that I can merely hit [cmd] [p]  to bring up a search box allowing me to search my project e.g. a repo cloned from GitHub...