Skip to content

Instantly share code, notes, and snippets.

@dcode
Last active October 17, 2025 12:30
Show Gist options
  • Save dcode/0cfbf2699a1fe9b46ff04c41721dda74 to your computer and use it in GitHub Desktop.
Save dcode/0cfbf2699a1fe9b46ff04c41721dda74 to your computer and use it in GitHub Desktop.

Revisions

  1. dcode revised this gist Jul 24, 2023. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions GitHub Flavored Asciidoc (GFA).adoc
    Original file line number Diff line number Diff line change
    @@ -24,7 +24,7 @@ toc::[]
    I think most people use Markdown when creating documentation on GitHub. Markdown is great and easy, but I often create technical documentation or training material where some of the additional semantics of Asciidoc are really helpful.

    == GitHub-Specific customizations
    Often you might need to adjust some settings whether your document is being rendered on GitHub or offline using link::http://asciidoctor.org/[Asciidoctor] or similar. In your header simply use the `ifdef` preprocessor macro:
    Often you might need to adjust some settings whether your document is being rendered on GitHub or offline using link:http://asciidoctor.org/[Asciidoctor] or similar. In your header simply use the `ifdef` preprocessor macro:

    [source,asciidoc]
    ----
    @@ -157,4 +157,4 @@ Callouts are a great way to explain code segment and are, in fact, the one of th
    <2> The block underneath allows you to explain the code sample without getting in the way

    == What Next?
    I'll add more comments here as I write and find interesting nuances. In the meantime, the link::http://asciidoctor.org[Asciidoctor project] has _GREAT_ link::http://asciidoctor.org/docs/user-manual/[user manual] and link::http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[Quick Reference]!
    I'll add more comments here as I write and find interesting nuances. In the meantime, the link:http://asciidoctor.org[Asciidoctor project] has _GREAT_ link:http://asciidoctor.org/docs/user-manual/[user manual] and link:http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[Quick Reference]!
  2. dcode revised this gist Jul 24, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion GitHub Flavored Asciidoc (GFA).adoc
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@ endif::[]
    image::https://avatars3.githubusercontent.com/u/3137042?v=3&s=200[float="right"]

    This gist is to capture some of the semantics of GitHub-Flavored Asciidoc. GitHub uses Asciidoctor in safe mode to render files with the extension `.adoc`,
    `.ad`, and `.asciidoc`. This works in standard repositories as well as gists.
    `.asc`, and `.asciidoc`. This works in standard repositories as well as gists.

    toc::[]

  3. dcode revised this gist Sep 29, 2016. 1 changed file with 81 additions and 147 deletions.
    228 changes: 81 additions & 147 deletions GitHub Flavored Asciidoc (GFA).adoc
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@
    = GitHub Flavored Asciidoc (GFA)
    ifdef::env-github[]
    :imagesdir: https://gist.github.com/path/to/gist/revision/dir/with/all/images
    :imagesdir:
    https://gist.github.com/path/to/gist/revision/dir/with/all/images
    :tip-caption: :bulb:
    :note-caption: :information_source:
    :important-caption: :heavy_exclamation_mark:
    @@ -13,31 +14,64 @@ endif::[]
    :toc:
    :toc-placement!:

    This gist is to capture some of the semantics of GitHub-Flavored Asciidoc.
    image::https://avatars3.githubusercontent.com/u/3137042?v=3&s=200[float="right"]

    This gist is to capture some of the semantics of GitHub-Flavored Asciidoc. GitHub uses Asciidoctor in safe mode to render files with the extension `.adoc`,
    `.ad`, and `.asciidoc`. This works in standard repositories as well as gists.

    toc::[]

    I think most people use Markdown when creating documentation on GitHub. Markdown is great and easy, but I often create technical documentation or training material where some of the additional semantics of Asciidoc are really helpful.

    == GitHub-Specific customizations
    Often you might need to adjust some settings whether your document is being rendered on GitHub or offline using link::http://asciidoctor.org/[Asciidoctor] or similar. In your
    Often you might need to adjust some settings whether your document is being rendered on GitHub or offline using link::http://asciidoctor.org/[Asciidoctor] or similar. In your header simply use the `ifdef` preprocessor macro:

    [source,asciidoc]
    ----
    \ifdef::env-github[]
    :imagesdir: foo/
    \endif::[]
    ----

    Everything within the `ifdef` and `endif` will only be processed if you are on GitHub.

    == Table of Contents

    Often, I will write long documents that could use some extra organization (like this one). Asciidoc can automatically render a _Table of Contents (TOC)_ for you, based upon the heading structure you have used. This is especially handy for web content or PDFs (when rendered offline).

    To use TOC on GitHub, I use the following:

    [source,asciidoc]
    ----
    :toc:
    :toc-placement!:
    Here is my preamble paragraph, but I could really place the TOC anywhere! Lorem ipsum foo bar baz.
    toc::[]
    ----

    The `:toc:` directive states that I want to enable the `:toc:` processor. The `:toc-placement!:` directive undefines the current placement strategy, which doesn't work on GitHub. This indicates that we will specify where the TOC should be placed.

    Lastly, the `toc::[]` tells Asciidoctor to render a Table of Contents for the whole document here.

    == Admonitions

    Admonitions are handy blocks that are rendered seperate from the rest of the content. This is really helpful for explaining something that doesn't quite fit the flow, but you need to get the readers' attention. The `ifdef` portion and the rest of the lines that start with `:` go in your header.

    [source]
    The pre-processor directive `ifdef` checks to see if the GitHub environment is being used. To account for the opposite, create a block using `ifndef`. You can look at the header of this document to see how I managed it for this document.

    .Example conditional enabling of icons for admonitions
    [source,asciidoc]
    ----
    ifdef::env-github[]
    \ifdef::env-github[]
    :tip-caption: :bulb:
    :note-caption: :information_source:
    :important-caption: :heavy_exclamation_mark:
    :caution-caption: :fire:
    :warning-caption: :warning:
    endif::[]
    = Asciidoc on GitHub
    \endif::[]
    [NOTE]
    ====
    A sample note admonition.
    @@ -55,9 +89,7 @@ CAUTION: Don't forget to add the `...-caption` document attributes in the header
    WARNING: You have no reason not to use Asciidoctor.
    ----

    Will be rendered as

    = Asciidoc on GitHub
    Will be rendered as:

    [NOTE]
    ====
    @@ -74,153 +106,55 @@ IMPORTANT: Asciidoctor is awesome, don't forget!
    CAUTION: Don't forget to add the `...-caption` document attributes in the header of the document on GitHub.

    WARNING: You have no reason not to use Asciidoctor.
    == Generate & Load Keys

    First things first, you're going to need some crypto keys.

    === OpenSSH (Linux or Mac)

    If you do not already have RSA (or EC) keys, you can generate the default key path using the following command in a terminal.

    ```
    ssh-keygen -t rsa
    ```

    This will store the key in `${HOME}/.ssh/id_rsa` by default and prompt you for a passphrase. On both a Mac and Linux graphical desktops, this passphrase can be managed by the desktop keyring, so go ahead and make it a strong one. Either way, you only have to enter it once per user session.

    Your public key is stored in `${HOME}/.ssh/id_rsa.pub`. This is the file that you will need to copy to remote systems, and as the name implies, is safe to freely share to authenticate yourself.

    Finally, you want to load it into your SSH key agent. First, test that you have an SSH agent loaded by trying to list your current keys.

    ```
    ssh-add -l
    ```
    If this states that you cannot connect to an agent, we'll need to start one.

    ```
    eval $(ssh-agent)
    ```

    Now add your key (it will prompt you for your key passphrase)

    ```
    ssh-add ${HOME}/.ssh/id_rsa
    ```

    You should now be able to view your identity

    ```
    ssh-add -l
    2048 14:7b:4f:f9:0d:19:26:bb:b5:6f:bf:10:0f:df:90:5b /home/luser/.ssh/id_rsa (RSA)
    ```
    == Images

    === Putty Key Generation
    Images work as you would expect using the normal image syntax:

    _Sourced from link::https://www.digitalocean.com/community/tutorials/how-to-create-ssh-keys-with-putty-to-connect-to-a-vps[Digital Ocean]_

    While PuTTY is a client program for SSH (in addition to Telnet and Rlogin), it is not a port of or otherwise based on OpenSSH. Consequently, PuTTY does not have native support for reading OpenSSH's SSH-2 private key files. However, PuTTY does have a companion named PuTTYgen (an RSA and DSA key generation utility), that can convert OpenSSH private key files into PuTTY's format; allowing you to connect to your cloud server from a Windows machine, with the added security that SSH keys provide.

    PuTTYgen is a (free) open-source utility and can be downloaded from the maintainer's website. PuTTYgen is what you will use to generate your SSH keys for use in PuTTY. To start, all you need to do is download the exectuable files (.exe) and save them on the computer that you'll use to connect to your VPS, e.g. on the desktop. You will not need to "install" PuTTYgen, because it is a standalone application.

    ==== Generating OpenSSH-compatible Keys for Use with PuTTY
    To generate a set of RSA keys with PuTTYgen:

    . Start the PuTTYgen utility, by double-clicking on its .exe file;
    . For *Type of key to generate*, select *SSH-2 RSA*;
    . In the Number of bits in a generated key field, specify either *2048* or *4096* (increasing the bits makes it harder to crack the key by brute-force methods);
    . Click the *Generate* button;
    . Move your mouse pointer around in the blank area of the Key section, below the progress bar (to generate some randomness) until the progress bar is full;
    . A private/public key pair has now been generated;
    . In the Key comment field, enter any comment you'd like, to help you identify this key pair, later (e.g. your e-mail address; home; office; etc.) -- the key comment is particularly useful in the event you end up creating more than one key pair;
    . You should type a passphrase in the *Key passphrase* field & re-type the same passphrase in the *Confirm passphrase* field. Since we'll be using an agent to load the keys, you'll only have to type this once per session. Make it a strong passphrase.
    . Click the Save public key button & choose whatever filename you'd like (some users create a folder in their computer named my_keys);
    . Click the Save private key button & choose whatever filename you'd like (you can save it in the same location as the public key, but it should be a location that only you can access and that you will NOT lose! If you lose your keys and have disabled username/password logins, you will no longer be able log in!);
    . Right-click in the text field labeled Public key for pasting into OpenSSH authorized_keys file and choose Select All;
    . Right-click again in the same text field and choose Copy. Use this to setup the Public Key on the Remote Server(s) after we setup your ssh agent using Pageant.

    ==== Add Your Key to Pageant

    _Sourced from link::https://www.digitalocean.com/community/tutorials/how-to-use-pageant-to-streamline-ssh-key-authentication-with-putty[Digital Ocean]_

    If you installed the full distribution of PuTTY, you will have a number of utilities in the same directory as `putty.exe`. Namely, `pageant.exe`, `plink.exe`, and others. Launch `Pageant`. It will start minimized to the system tray by default. Right-click on the icon and select *View Keys*.

    image::pageant-1.jpg[]

    Click the *Add Key* button. This will open the file explorer, wher eyou can choose one or more keys at a time to load. You should select files with `.ppk` extension, which is the PuTTY key format.

    image::pageant-2.jpg[]

    If the key is passphrase-protected, Pageant will ask for your passphrase for that key. Once your key is loaded, you will no longer be prompted for the passphrase.

    image::pageant-3.jpg[]

    Once successfully loaded, you will see it listed in the *Pageant Key List* window.

    image::pageant-4.jpg[]


    == Setup Your Public Key on the Remote Server(s)

    Now it's time to setup the remote server. You will want to do this on the jump box and the final endpoint.

    . SSH to the system and ensure your `.ssh` is set up. SSH requires read and write privileges to only your user account. Without this, it will fail.

    ```
    mkdir -p ${HOME}/.ssh
    chmod 0700 ${HOME}/.ssh
    ```

    Now add your public key to the file `${HOME}/.ssh/authorized_keys`. This is from `id_rsa.pub` on your local system (or the key we copied from PuTTY).

    ```
    cat <<eof | tee -a ${HOME}/.ssh/authorized_keys
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDR3vzk//b72jiwReXjK/AKycn2UQMNm3H3GR2OS0nsudHA5hfyl9PsoyZWpQFdrt0Q5Caz7LszBjBm1qS1EEnE4fQa2qXLnNj3LI0r+hRhvonKJnDuTgaTkmVYfD2fcLWA718u5y2/TTStAC1xdcb+4T3vmVHvysWL08wEHa8TQT5woLgHufnFmRQs6Z+L0En2uaTeEFFVQMpo4z0eF2fXuy3XJXk71cghHsUJk7H/3jbo19NtORR23dNQMwwJLBodEoX95M2ruVyCWFnP356T02T9WkKpoTUdZY5UKQq+I3Ad0GTFoG2hKRuDbqrYVTw8dQUPUfh4Lfc/O+iHp8lR luser
    eof
    ```

    After you've done this on the jump box, try logging in again. If everything is setup correctly, you shouldn't be prompted for a password.

    From the jumpbox, ssh to your next hop and repeat the process. To test your keys on the next hop, connect to the jumpbox with the option to *Forward SSH Agent*. This is `ssh -A user@jumpbox` using OpenSSH. It is in the SSH options in PuTTY.

    == Setup the Proxy (Show me the magic!)

    === OpenSSH
    On your local workstation, edit the file (or create if needed) `${HOME}/.ssh/config`. This file lets us set per-host preferences for SSH.

    .Excerpt from ${HOME}/.ssh/config
    [source]
    [source,asciidoc]
    ----
    Host jumpbox
    Hostname 10.5.3.4
    Host endpoint <1>
    User my-username <2>
    Hostname 192.168.3.2 <3>
    ForwardAgent yes <4>
    ProxyCommand ssh -q -x jumpbox -W %h:%p <5>
    image::my_filename.png[]
    ----
    <1> This is the hostname, IP address, or alias that SSH will match on
    <2> The `User` option is only needed if it differs from your local username
    <3> This is the hostname that SSH will actually try to connect to. It can be a DNS resolvable name or an IP address
    <4> This tells SSH to forward your agent socket to the remote systems so you can authenticate to other systems
    <5> This is what tells SSH how to connect to this system through another system. In this case, we use the alias `jumpbox` which is also defined in this file.

    You should now be able to SSH directly to your endpoint! Try it out!
    You can also give an absolute URL:

    === PuTTY
    [source,asciidoc]
    ----
    image::https://avatars3.githubusercontent.com/u/3137042?v=3&s=200[]
    ----

    _Sourced from link::https://monkeyswithbuttons.wordpress.com/2010/10/01/ssh-proxycommand-and-putty/[Monkeys With Buttons] blog_
    There is a caveat, however. In order for them to be rendered inline, you must provide an absolute path to the `:imagesdir:` directive. On GitHub this consists of a full _HTTPS_ path to the image's parent directory. Once you have all of your images uploaded into your repository, look at the raw link for one of the images. Select just the directory portion of the URL and put that into:

    The concepts of the PuTTY configuration are similar. Create a connection entry as normal (specifying username in *Data* if needed), and select *Connection -> Proxy*.
    [source,asciidoc]
    ----
    \ifdef::env-github[]
    :imagesdir: https://gist.github.com/path/to/gist/revision/dir/with/all/images
    \endif::[]
    ----

    Specify the proxy type as `local` and put the jumpbox hostname as the *Proxy Hostname*. The equivalent to the *ProxyCommand* in OpenSSH is the lower box labelled *Telnet command, or local proxy command*. Enter the following:
    NOTE: When writing a Gist, all files must be in a single, flat directory. To upload images, you must first create a file in the Gist and then you can clone it. Once you've cloned it locally, you can add anything you like as long as you do not create any subdirectories.

    ```
    plink %user@%proxyhost -nc %host:%port
    ```
    == Callouts

    Your configuration should look something like this:
    Callouts are a great way to explain code segment and are, in fact, the one of the two main reasons I even looked into asciidoc (the other being the admonition blocks). Asciidoctor will place numbers in the code listing, which you can uses as references following the code listing.

    image::putty-proxy.jpg[]
    [source,asciidoc]
    ----
    [source]
    ----
    \ifdef::env-github[] \<1> <1>
    :imagesdir: https://gist.github.com/path/to/gist/revision/dir/with/all/images
    \endif::[]
    \ifndef::env-github[] \<2>
    :imagesdir: ./
    \endif::[]
    ----
    <1> Use the `ifdef` to customize for online rendering <2>
    <2> Use the `ifndef` to customize for offline
    ----
    <1> Callouts in the body of the listing appear as either an icon or within parentheses.
    <2> The block underneath allows you to explain the code sample without getting in the way

    NOTE: Thats it! Get back to work!
    == What Next?
    I'll add more comments here as I write and find interesting nuances. In the meantime, the link::http://asciidoctor.org[Asciidoctor project] has _GREAT_ link::http://asciidoctor.org/docs/user-manual/[user manual] and link::http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[Quick Reference]!
  4. dcode revised this gist Sep 29, 2016. 1 changed file with 8 additions and 2 deletions.
    10 changes: 8 additions & 2 deletions GitHub Flavored Asciidoc (GFA).adoc
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    = SSH Proxy Setup
    = GitHub Flavored Asciidoc (GFA)
    ifdef::env-github[]
    :imagesdir: https://gist.github.com/path/to/gist/revision/dir/with/all/images
    :tip-caption: :bulb:
    @@ -17,9 +17,15 @@ This gist is to capture some of the semantics of GitHub-Flavored Asciidoc.

    toc::[]

    == Overview
    I think most people use Markdown when creating documentation on GitHub. Markdown is great and easy, but I often create technical documentation or training material where some of the additional semantics of Asciidoc are really helpful.

    == GitHub-Specific customizations
    Often you might need to adjust some settings whether your document is being rendered on GitHub or offline using link::http://asciidoctor.org/[Asciidoctor] or similar. In your

    == Admonitions

    Admonitions are handy blocks that are rendered seperate from the rest of the content. This is really helpful for explaining something that doesn't quite fit the flow, but you need to get the readers' attention. The `ifdef` portion and the rest of the lines that start with `:` go in your header.

    [source]
    ----
    ifdef::env-github[]
  5. dcode revised this gist Sep 29, 2016. 1 changed file with 19 additions and 0 deletions.
    19 changes: 19 additions & 0 deletions GitHub Flavored Asciidoc (GFA).adoc
    Original file line number Diff line number Diff line change
    @@ -49,6 +49,25 @@ CAUTION: Don't forget to add the `...-caption` document attributes in the header
    WARNING: You have no reason not to use Asciidoctor.
    ----

    Will be rendered as

    = Asciidoc on GitHub

    [NOTE]
    ====
    A sample note admonition.
    We can use gemoji icons in the Asciidoctor markup.
    We assign an icon name to the document
    attributes `tip-caption`, `note-caption` and `important-caption`.
    ====

    TIP: It works!

    IMPORTANT: Asciidoctor is awesome, don't forget!

    CAUTION: Don't forget to add the `...-caption` document attributes in the header of the document on GitHub.

    WARNING: You have no reason not to use Asciidoctor.
    == Generate & Load Keys

    First things first, you're going to need some crypto keys.
  6. dcode created this gist Sep 29, 2016.
    201 changes: 201 additions & 0 deletions GitHub Flavored Asciidoc (GFA).adoc
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,201 @@
    = SSH Proxy Setup
    ifdef::env-github[]
    :imagesdir: https://gist.github.com/path/to/gist/revision/dir/with/all/images
    :tip-caption: :bulb:
    :note-caption: :information_source:
    :important-caption: :heavy_exclamation_mark:
    :caution-caption: :fire:
    :warning-caption: :warning:
    endif::[]
    ifndef::env-github[]
    :imagesdir: ./
    endif::[]
    :toc:
    :toc-placement!:

    This gist is to capture some of the semantics of GitHub-Flavored Asciidoc.

    toc::[]

    == Overview
    I think most people use Markdown when creating documentation on GitHub. Markdown is great and easy, but I often create technical documentation or training material where some of the additional semantics of Asciidoc are really helpful.

    [source]
    ----
    ifdef::env-github[]
    :tip-caption: :bulb:
    :note-caption: :information_source:
    :important-caption: :heavy_exclamation_mark:
    :caution-caption: :fire:
    :warning-caption: :warning:
    endif::[]
    = Asciidoc on GitHub
    [NOTE]
    ====
    A sample note admonition.
    We can use gemoji icons in the Asciidoctor markup.
    We assign an icon name to the document
    attributes `tip-caption`, `note-caption` and `important-caption`.
    ====
    TIP: It works!
    IMPORTANT: Asciidoctor is awesome, don't forget!
    CAUTION: Don't forget to add the `...-caption` document attributes in the header of the document on GitHub.
    WARNING: You have no reason not to use Asciidoctor.
    ----

    == Generate & Load Keys

    First things first, you're going to need some crypto keys.

    === OpenSSH (Linux or Mac)

    If you do not already have RSA (or EC) keys, you can generate the default key path using the following command in a terminal.

    ```
    ssh-keygen -t rsa
    ```

    This will store the key in `${HOME}/.ssh/id_rsa` by default and prompt you for a passphrase. On both a Mac and Linux graphical desktops, this passphrase can be managed by the desktop keyring, so go ahead and make it a strong one. Either way, you only have to enter it once per user session.

    Your public key is stored in `${HOME}/.ssh/id_rsa.pub`. This is the file that you will need to copy to remote systems, and as the name implies, is safe to freely share to authenticate yourself.

    Finally, you want to load it into your SSH key agent. First, test that you have an SSH agent loaded by trying to list your current keys.

    ```
    ssh-add -l
    ```
    If this states that you cannot connect to an agent, we'll need to start one.

    ```
    eval $(ssh-agent)
    ```

    Now add your key (it will prompt you for your key passphrase)

    ```
    ssh-add ${HOME}/.ssh/id_rsa
    ```

    You should now be able to view your identity

    ```
    ssh-add -l
    2048 14:7b:4f:f9:0d:19:26:bb:b5:6f:bf:10:0f:df:90:5b /home/luser/.ssh/id_rsa (RSA)
    ```

    === Putty Key Generation

    _Sourced from link::https://www.digitalocean.com/community/tutorials/how-to-create-ssh-keys-with-putty-to-connect-to-a-vps[Digital Ocean]_

    While PuTTY is a client program for SSH (in addition to Telnet and Rlogin), it is not a port of or otherwise based on OpenSSH. Consequently, PuTTY does not have native support for reading OpenSSH's SSH-2 private key files. However, PuTTY does have a companion named PuTTYgen (an RSA and DSA key generation utility), that can convert OpenSSH private key files into PuTTY's format; allowing you to connect to your cloud server from a Windows machine, with the added security that SSH keys provide.

    PuTTYgen is a (free) open-source utility and can be downloaded from the maintainer's website. PuTTYgen is what you will use to generate your SSH keys for use in PuTTY. To start, all you need to do is download the exectuable files (.exe) and save them on the computer that you'll use to connect to your VPS, e.g. on the desktop. You will not need to "install" PuTTYgen, because it is a standalone application.

    ==== Generating OpenSSH-compatible Keys for Use with PuTTY
    To generate a set of RSA keys with PuTTYgen:

    . Start the PuTTYgen utility, by double-clicking on its .exe file;
    . For *Type of key to generate*, select *SSH-2 RSA*;
    . In the Number of bits in a generated key field, specify either *2048* or *4096* (increasing the bits makes it harder to crack the key by brute-force methods);
    . Click the *Generate* button;
    . Move your mouse pointer around in the blank area of the Key section, below the progress bar (to generate some randomness) until the progress bar is full;
    . A private/public key pair has now been generated;
    . In the Key comment field, enter any comment you'd like, to help you identify this key pair, later (e.g. your e-mail address; home; office; etc.) -- the key comment is particularly useful in the event you end up creating more than one key pair;
    . You should type a passphrase in the *Key passphrase* field & re-type the same passphrase in the *Confirm passphrase* field. Since we'll be using an agent to load the keys, you'll only have to type this once per session. Make it a strong passphrase.
    . Click the Save public key button & choose whatever filename you'd like (some users create a folder in their computer named my_keys);
    . Click the Save private key button & choose whatever filename you'd like (you can save it in the same location as the public key, but it should be a location that only you can access and that you will NOT lose! If you lose your keys and have disabled username/password logins, you will no longer be able log in!);
    . Right-click in the text field labeled Public key for pasting into OpenSSH authorized_keys file and choose Select All;
    . Right-click again in the same text field and choose Copy. Use this to setup the Public Key on the Remote Server(s) after we setup your ssh agent using Pageant.

    ==== Add Your Key to Pageant

    _Sourced from link::https://www.digitalocean.com/community/tutorials/how-to-use-pageant-to-streamline-ssh-key-authentication-with-putty[Digital Ocean]_

    If you installed the full distribution of PuTTY, you will have a number of utilities in the same directory as `putty.exe`. Namely, `pageant.exe`, `plink.exe`, and others. Launch `Pageant`. It will start minimized to the system tray by default. Right-click on the icon and select *View Keys*.

    image::pageant-1.jpg[]

    Click the *Add Key* button. This will open the file explorer, wher eyou can choose one or more keys at a time to load. You should select files with `.ppk` extension, which is the PuTTY key format.

    image::pageant-2.jpg[]

    If the key is passphrase-protected, Pageant will ask for your passphrase for that key. Once your key is loaded, you will no longer be prompted for the passphrase.

    image::pageant-3.jpg[]

    Once successfully loaded, you will see it listed in the *Pageant Key List* window.

    image::pageant-4.jpg[]


    == Setup Your Public Key on the Remote Server(s)

    Now it's time to setup the remote server. You will want to do this on the jump box and the final endpoint.

    . SSH to the system and ensure your `.ssh` is set up. SSH requires read and write privileges to only your user account. Without this, it will fail.

    ```
    mkdir -p ${HOME}/.ssh
    chmod 0700 ${HOME}/.ssh
    ```

    Now add your public key to the file `${HOME}/.ssh/authorized_keys`. This is from `id_rsa.pub` on your local system (or the key we copied from PuTTY).

    ```
    cat <<eof | tee -a ${HOME}/.ssh/authorized_keys
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDR3vzk//b72jiwReXjK/AKycn2UQMNm3H3GR2OS0nsudHA5hfyl9PsoyZWpQFdrt0Q5Caz7LszBjBm1qS1EEnE4fQa2qXLnNj3LI0r+hRhvonKJnDuTgaTkmVYfD2fcLWA718u5y2/TTStAC1xdcb+4T3vmVHvysWL08wEHa8TQT5woLgHufnFmRQs6Z+L0En2uaTeEFFVQMpo4z0eF2fXuy3XJXk71cghHsUJk7H/3jbo19NtORR23dNQMwwJLBodEoX95M2ruVyCWFnP356T02T9WkKpoTUdZY5UKQq+I3Ad0GTFoG2hKRuDbqrYVTw8dQUPUfh4Lfc/O+iHp8lR luser
    eof
    ```

    After you've done this on the jump box, try logging in again. If everything is setup correctly, you shouldn't be prompted for a password.

    From the jumpbox, ssh to your next hop and repeat the process. To test your keys on the next hop, connect to the jumpbox with the option to *Forward SSH Agent*. This is `ssh -A user@jumpbox` using OpenSSH. It is in the SSH options in PuTTY.

    == Setup the Proxy (Show me the magic!)

    === OpenSSH
    On your local workstation, edit the file (or create if needed) `${HOME}/.ssh/config`. This file lets us set per-host preferences for SSH.

    .Excerpt from ${HOME}/.ssh/config
    [source]
    ----
    Host jumpbox
    Hostname 10.5.3.4
    Host endpoint <1>
    User my-username <2>
    Hostname 192.168.3.2 <3>
    ForwardAgent yes <4>
    ProxyCommand ssh -q -x jumpbox -W %h:%p <5>
    ----
    <1> This is the hostname, IP address, or alias that SSH will match on
    <2> The `User` option is only needed if it differs from your local username
    <3> This is the hostname that SSH will actually try to connect to. It can be a DNS resolvable name or an IP address
    <4> This tells SSH to forward your agent socket to the remote systems so you can authenticate to other systems
    <5> This is what tells SSH how to connect to this system through another system. In this case, we use the alias `jumpbox` which is also defined in this file.

    You should now be able to SSH directly to your endpoint! Try it out!

    === PuTTY

    _Sourced from link::https://monkeyswithbuttons.wordpress.com/2010/10/01/ssh-proxycommand-and-putty/[Monkeys With Buttons] blog_

    The concepts of the PuTTY configuration are similar. Create a connection entry as normal (specifying username in *Data* if needed), and select *Connection -> Proxy*.

    Specify the proxy type as `local` and put the jumpbox hostname as the *Proxy Hostname*. The equivalent to the *ProxyCommand* in OpenSSH is the lower box labelled *Telnet command, or local proxy command*. Enter the following:

    ```
    plink %user@%proxyhost -nc %host:%port
    ```

    Your configuration should look something like this:

    image::putty-proxy.jpg[]

    NOTE: Thats it! Get back to work!