<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ ssh - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ ssh - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 20 May 2026 22:47:05 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/ssh/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Use Your Raspberry Pi Headlessly with VS Code and SSH (No Monitor Needed) ]]>
                </title>
                <description>
                    <![CDATA[ The Raspberry Pi is a portable computer with an onboard processor that fits comfortably in the palm of your hand. Compared with general purpose computers, it’s an affordable option developed by the Raspberry Pi Foundation. The Raspberry Pi Model B wa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-your-raspberry-pi-headlessly-with-vs-code-and-ssh/</link>
                <guid isPermaLink="false">6835cf3101fd0876c3c66de0</guid>
                
                    <category>
                        <![CDATA[ Raspberry Pi ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vscode extensions ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Josiah Adesola ]]>
                </dc:creator>
                <pubDate>Tue, 27 May 2025 14:41:53 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748452192906/594a76a0-be8f-478b-a9ae-e3ba55850c65.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Raspberry Pi is a portable computer with an onboard processor that fits comfortably in the palm of your hand. Compared with general purpose computers, it’s an affordable option developed by the <a target="_blank" href="https://www.raspberrypi.org/">Raspberry Pi Foundation</a>.</p>
<p>The Raspberry Pi Model B was introduced in 2012 as the first sellable unit, and the company has since released many more models. There are even low-cost models like the Raspberry Pi Zero Series, which is quite small and tailored to embedded systems applications. All the models operate on an operating system called the Raspberry Pi OS, a Linux flavor niched for Raspberry PI Computers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747912686077/498ff16a-c6a0-4774-b6e4-a0d573afd4f8.jpeg" alt="A Raspberry Pi Model 4B single-board computer with visible ports, components." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>In this tutorial, we’ll be using the Raspberry Pi 4 Model for a headless setup through a SSH connection using Visual Studio Code (VS Code). The Raspberry Pi 4 Model has a Quad-core ARM Cortex-A72 (64-bit) SoC at 1.5GHz, up to 8GB RAM options, video inputs, Ethernet shield, USB ports, MicroSD card slot for storage, USB-C power input and 40 General Purpose Inputs and Outputs Pins (GPIO). Impressive, right?</p>
<p>You’ll be able to use the Raspberry Pi as a personal computer, for home automation and IoT projects, robotics projects, network applications, educational tools, and Artificial Intelligence projects.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-understanding-the-headless-setup">Understanding the Headless Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-preparing-the-microsd-card">Preparing the MicroSD Card</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-boot-the-raspberry-pi">How to Boot the Raspberry Pi</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-the-led-of-the-raspberry-pi-during-setup">Understanding the LED of the Raspberry Pi During Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-establish-an-ssh-connection">How to Establish an SSH Connection</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-visual-studio-code-for-remote-development">How to Set Up Visual Studio Code for Remote Development</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-write-and-run-the-code-remotely">How to Write and Run the Code Remotely</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-understanding-the-headless-setup">Understanding the Headless Setup</h2>
<p>Many Raspberry Pi computers are sold with additional peripherals, including a keyboard, mouse, and monitor, that are essential for the Raspberry Pi's setup. A headless setup is the process of configuring the Raspberry Pi or preparing it for use without needing these peripherals. This entails operating the Raspberry Pi through a network protocol like SSH (Secure Shell) or VNC (Virtual Network Computing).</p>
<p>This is really helpful when you don’t need peripherals, as it lets you use your personal computer to connect to the Raspberry Pi without needing to purchase specialized peripherals. It’s also excellent for remote access. This headless setup is also essential for remote monitoring systems, such as surveillance systems with remote camera access, and IoT systems.</p>
<p><a target="_blank" href="https://www.raspberrypi.com/products/raspberry-pi-400/"><img src="https://assets.raspberrypi.com/static/neat-lg@2x-38697d13d9952791ca96da4891de9a12.jpg" alt="A Raspberry Pi 400 in use on a desk, with a mouse and monitor connected" width="600" height="400" loading="lazy"></a></p>
<p>Remote development lets you write code and modify your Raspberry Pi and other devices connected to the GPIO pins through a headless configuration via SSH.</p>
<p>SSH guarantees a secure connection for transferring and modifying files, as well as transferring and debugging commands from one computer (your personal computer) to another computer (the Raspberry Pi). It restricts unauthorized access from any other system that aims to intercept the communication channel.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Here’s what you’ll need to follow along with this tutorial:</p>
<h3 id="heading-hardware-requirements">Hardware Requirements</h3>
<ol>
<li><p>Raspberry Pi 4 or 5</p>
</li>
<li><p>MicroSD Card (8GB or higher recommended)</p>
</li>
<li><p>Flash Drive with SD Card Slot or a MicroSD Card Adapter</p>
</li>
<li><p>Power Supply (5V 2A/3A)</p>
</li>
<li><p>Network Connection (Wi-Fi, Pi, and laptop must be on the same network)</p>
</li>
<li><p>Personal Computer (Windows, macOS, Linux)</p>
</li>
</ol>
<h3 id="heading-software-requirements">Software Requirements</h3>
<ol>
<li><p>Raspberry Pi Operating System (Raspberry Pi OS)</p>
</li>
<li><p>Visual Studio Code</p>
</li>
<li><p>Remote SSH Extension in VS Code</p>
</li>
</ol>
<h2 id="heading-preparing-the-microsd-card">Preparing the MicroSD Card</h2>
<p>The Raspberry Pi requires a MicroSD Card that serves as the storage of your the Raspberry Pi OS using Raspberry Pi Imager. The operating system of the Raspberry Pi provides a graphical interface to interact with the Raspberry Pi, store files and datasets, and write commands to get your Raspberry Pi working.</p>
<p>But the Raspberry Pi needs an empty MicroSD Card to install the Raspberry Pi OS in the MicroSD Card. Here are some step by step instructions that’ll show you how to get your MicroSD Card setup before inserting it back into the Raspberry Pi for SSH Connection.</p>
<h3 id="heading-downloading-and-flashing-raspberry-pi-os">Downloading and flashing Raspberry Pi OS</h3>
<h4 id="heading-insert-your-microsd-card-into-a-flash-drive-with-a-sd-card-slot">Insert your MicroSD Card into a flash drive with a SD Card slot</h4>
<p>Aside from using a flash drive with an SD Card slot (so as to get the memory card connected to the computer), you can also use a SD Card adapter. Make sure it’s inserted into your computer where you have the Raspberry PI Imager downloaded to flash – that is, transfer the OS into the SD Card.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747921369222/7deebdff-d0bc-4f08-9aab-07c562a712bd.jpeg" alt="My flash drive with an SD card slot" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h4 id="heading-download-the-raspberry-pi-imagerhttpswwwraspberrypicomsoftware-based-on-your-pcs-operating-system">Download the <a target="_blank" href="https://www.raspberrypi.com/software/">Raspberry Pi Imager</a> based on your PC’s operating system</h4>
<p>This involves clicking the link and selecting your operating system (either MacOS, Windows or Linux operating system). The Raspberry Pi OS comes in these variants for different OSes</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747922079380/d1aa21cb-3166-4924-8f98-e2f16816fec6.png" alt="Screenshot of a webpage from raspberrypi.com showing instructions for installing Raspberry Pi OS using Raspberry Pi Imager. It includes download links for Windows, macOS, and Ubuntu. There is a command for installing on Raspberry Pi OS and an image of the Raspberry Pi Imager interface." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h4 id="heading-next-install-and-open-the-raspberry-pi-imager">Next, install and open the Raspberry Pi imager</h4>
<p>Click the Raspberry Pi Imager download, follow all the instructions during the installation process. Once this screen pops up, you’re good to go!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747922173921/02e58463-0634-41d6-bc85-0a1a3a199996.png" alt="The image shows the Raspberry Pi Imager v1.8.5 interface. It has options to &quot;Choose Device,&quot; &quot;Choose OS,&quot; and &quot;Choose Storage.&quot; There is also a faded &quot;Next&quot; button at the bottom. The background is a shade of raspberry red." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h4 id="heading-choose-your-raspberry-pi-device-and-operating-system-and-select-storage">Choose your Raspberry Pi Device and operating system and select Storage</h4>
<p>For each of the three configurations, you must select one sequentially. Select a device according to the type of Raspberry Pi you have, and various options will appear. I selected the Raspberry Pi 4, as it is my preferred device. You may choose between the Raspberry Pi 5 and the Raspberry Pi Zero 2 W, depending on your device requirements.</p>
<p>Next, proceed to the operating system – I would recommend choosing the 64-bit version. While many people opt for the legacy version (32-bit), I think the 64-bit version is best. Once you're finished, you can choose a storage option, and your MicroSD should appear. My storage is around 128GB, which is why you can see 125.1GB displayed there in the screenshot below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747922610658/d5f4c750-ab40-47ed-8c0c-fe5951f68660.png" alt="Screenshot of the Raspberry Pi Imager v1.8.5 interface. It shows options for selecting a Raspberry Pi device, operating system, and storage. Available devices include Raspberry Pi 5, 4, and Zero 2 W. Operating systems listed are Raspberry Pi OS in 64-bit and 32-bit versions, and there is a USB device listed for storage." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h4 id="heading-click-on-next-and-edit-the-settings">Click on “Next” and edit the settings</h4>
<p>It is a customary practice to keep your username as "pi", but it’s not required. The goal is to have something simple and easy to remember when setting up your SSH connection. It’s also helpful to make your password simple. I used 'roboticsai'.</p>
<p>Try to avoid using numbers simply to make things easier, because you may not be able to see what you are entering in the terminal. Then, make sure that your wireless LAN and SSID (WIFI or Hotspot name if you're using a phone, as well as the password for your WIFI or Hotspot) is the same network as the one linked to your computer.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747922797428/c1a1ae55-e109-4a35-878c-820d1ef3f406.png" alt="Setting up the username and password of the Raspberry Pi" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h4 id="heading-click-on-services-and-enable-ssh-then-use-password-authentication-for-security-and-click-on-save">Click on “SERVICES” and enable SSH. Then use password authentication for security and Click on “SAVE”.</h4>
<p>After you've completed the changes in the General Section, go to the Services section and click the checkbox button “<em>Enable SSH</em>”. Once highlighted, make sure you pick “<em>Use password authentication</em>”, avoid the “<em>RUN SSH-KEYGEN</em>” button at the moment, and then click Save.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747923037374/b6c63a5a-e3b6-4c9f-9612-53df7e566e41.png" alt="Screenshot of an OS customization window under the &quot;Services&quot; tab. &quot;Enable SSH&quot; is checked, with &quot;Use password authentication&quot; selected. An option for &quot;Allow public-key authentication only&quot; is available. A disabled &quot;RUN SSH-KEYGEN&quot; button and a &quot;SAVE&quot; button are visible." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h4 id="heading-click-yes-to-apply-the-customizations-and-the-raspberry-pi-os-should-get-flashed-into-your-sd-card">Click “YES” to apply the customizations, and the Raspberry Pi OS should get flashed into your SD Card.</h4>
<p>Following the previous stage, you will be shown various buttons to apply the adjustments you have made. Pick yes, and the Raspberry Pi OS will be flashed or transferred to your Memory Card. This could take between 10 and 20 minutes to go from transferring to writing or customizing. Hold on and enjoy the process.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747923100214/d86fca18-e540-4844-9f26-5253ef5b04b8.png" alt="Raspberry Pi Imager dialog box offering to apply OS customisation settings with options to edit, clear, accept, or decline." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h4 id="heading-after-a-successful-installation-into-the-disk-remove-your-sd-card">After a successful installation into the disk, remove your SD Card.</h4>
<p>You will receive a successful popup like the one shown below. This demonstrates that all processes were completed successfully, and the Raspberry Pi OS is now installed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747926095493/ed017dc6-e3a5-4cda-8b3c-6f6a2d74c1ac.png" alt="A notification on Raspberry Pi Imager v1.8.5 shows that Raspberry Pi OS (64-bit) has been successfully written to a mass storage device USB. It instructs to remove the SD card and has a &quot;Continue&quot; button." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-boot-the-raspberry-pi">How to Boot the Raspberry Pi</h2>
<h3 id="heading-eject-the-microsd-safely-from-your-computer"><strong>Eject the MicroSD safely from your computer</strong></h3>
<p>Once the installation is successful, eject the MicroSD safely from the computer.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747926401040/a37dafbb-68ae-4884-9ffe-3c374e6b62b9.jpeg" alt="The Raspberry Pi Board with a micro SD card slot is placed on a wooden surface. A SanDisk 128 GB micro SD card lies next to it." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-insert-it-upside-down-into-the-microsd-card-slot-of-your-raspberry-pi">Insert it “upside down” into the MicroSD card slot of your Raspberry Pi</h3>
<p>To properly insert the MicroSD card, place it gently into the slot with the back or gold side facing upward. It will protrude slightly once it is inserted. You are good to go!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747926384277/f7a0c5e9-6a13-4cd2-b94a-65b329a08a5c.jpeg" alt="A Raspberry Pi single-board computer placed on a gray surface, displaying various ports and components including USB ports and an HDMI connector." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-connect-the-usb-c-port-of-your-raspberry-pi-to-your-computer-give-the-raspberry-pi-some-time-to-load">Connect the USB-C port of your Raspberry Pi to your computer. Give the Raspberry Pi some time to load</h3>
<p>Get a USB-C cable and connect one end to your Raspberry Pi's USB-C port and the other to a laptop port. It should light up red, indicating that there is an adequate power source. You may also power your Raspberry Pi directly by plugging into a wall socket.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747926452530/b023abe6-5555-4d61-ab99-0d8e36a828a4.jpeg" alt="A Raspberry Pi connected to a laptop via a USB cable on a wooden surface." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>After a while, the memory card should begin to boot into the Raspberry Pi, and the green LED will blink for a while. In the next section, we’ll talk about the different states of the two LEDs during and after a successful boot.</p>
<h2 id="heading-understanding-the-led-status-of-the-raspberry-pi-during-setup">Understanding the LED Status of the Raspberry Pi During Setup</h2>
<p>The below table describes the LED statuses you might see when you power on your Raspberry Pi and the SD Card is in the slot.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>LED Color</strong></td><td><strong>State/Pattern</strong></td><td><strong>Meaning/Recommendation</strong></td></tr>
</thead>
<tbody>
<tr>
<td>🔴Red</td><td>Solid (ON)</td><td>Stable and sufficient power supply</td></tr>
<tr>
<td>🔴Red</td><td>Off or Blinking</td><td>Undervoltage detected (Use a direct phone Charger connected to a Socket)</td></tr>
<tr>
<td>🟢Green</td><td>Blinking (Irregular Pattern)</td><td>SD Card is being read/written (normal booting activity)</td></tr>
<tr>
<td>🟢Green</td><td>Solid (ON)</td><td>Raspberry Pi is stuck or trying to boot.</td></tr>
<tr>
<td>🟢Green</td><td>Off</td><td>No SD Card detected or boot completed</td></tr>
<tr>
<td>🟢Green</td><td>Repeated blink patterns (for example 4 long, 4 short)</td><td>Error code indicating firmware issues.</td></tr>
<tr>
<td>🟢Green</td><td>Constant Blinking</td><td>Normal activity (Raspbian OS is loading and running smoothly)</td></tr>
</tbody>
</table>
</div><h2 id="heading-how-to-establish-an-ssh-connection">How to Establish an SSH Connection</h2>
<p>The SSH (Secure Shell) connection is a network protocol that allows two computers to safely communicate without leaking any information. It’s also used for remote command line execution and for file transfers between two computers.</p>
<p>To establish an SSH connection, you’ll have to complete a few steps. Then I’ll explain how to enable SSH using a Visual Studio Code extension</p>
<h3 id="heading-create-a-wpasupplicantconftxt-in-the-same-folder-of-your-raspberry-pi-sd-card"><strong>Create a</strong> <code>wpa_supplicant.conf.txt</code> <strong>in the same folder of your Raspberry Pi SD Card</strong></h3>
<p>Insert your MicroSD card back into the computer. Then the files that comprise the Raspberry Pi OS will appear on your computer. Create a new text (.txt) document on your computer, similar to the image below, under the SD Card storage section.</p>
<p>Add the code below, making sure that "ssid" is the name of your Wi-Fi network and "psk" is your network's password.</p>
<pre><code class="lang-plaintext">country=NG # Your 2-digit country code
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
network={
    ssid="Josiah"
    psk="roboticsai"
    key_mgmt=WPA-PSK
}
</code></pre>
<h3 id="heading-save-the-file-on-the-same-sd-card"><strong>Save the file on the same SD Card</strong></h3>
<p>Once you've finished producing the text file, save it to the SD Card storage, as shown in the image below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747928812199/fb766a84-7750-468d-ae78-1ff3c688a52b.jpeg" alt="Screenshot of a file explorer window showing contents of the &quot;bootfs (D:)&quot; directory. Various system and configuration files are listed, including kernel images and .elf files. The selected file is &quot;wpa_supplicant.conf.txt&quot;." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-create-a-ssh-folder"><strong>Create a .ssh folder</strong></h3>
<p>In your personal computer, create a <code>.ssh</code> folder if it doesn’t exist on your personal computer.</p>
<p>If it exists, the <code>.ssh</code> folder should contain files like <code>id_rsa</code>, <code>known_hosts</code>, and <code>config</code> files. It shouldn’t be empty.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747928560247/d07f8cb9-ec22-47ff-a2a5-d18b614e9985.png" alt="A computer file explorer window showing a list of folders in the &quot;JOSIAH&quot; directory. The folder names include &quot;.matplotlib,&quot; &quot;.mchp_cm,&quot; &quot;.ssh,&quot; and others, with details like date modified and type. The &quot;.ssh&quot; folder is highlighted." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>After a successful boot, open your terminal or command line application on your personal computer.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747928958812/2c198297-08a5-4781-9a6a-45fd6c7e85d3.png" alt="Command Prompt window showing &quot;Microsoft Windows [Version 10.0.26100.3915]&quot; and the prompt at &quot;C:sersOSIAH>&quot;." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Make sure that the Raspberry Pi is connected to the same network before moving ahead. Once your wifi or mobile hotspot is switched on, make sure it’s the same password as the <code>wpa_supplicant.conf.txt</code> and the settings page while installing the Raspberry Pi.</p>
<p>As long as the SD card is in the Raspberry Pi and there is adequate power supply for at least 2-5 minutes, the Raspberry Pi will get connected to the wifi or your mobile hotspot.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747931364223/13947f34-c1a9-4b1c-b020-c236b4d377af.jpeg" alt="Screenshot of connected devices interface showing a limit of 3 devices. Two devices are listed: &quot;raspberrypi&quot; with MAC address d8:3a:dd:43:27:71, and &quot;Josiah&quot; with MAC address dc:71:96:d0:d5:4a. A blocklist option is available for viewing devices not allowed to connect." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-resolve-connection-problems">How to Resolve Connection Problems</h3>
<p>If there is no connection, reinstall the Raspberry Pi OS Imager on the SD Card again. Then you can also change the network AP Band from 5GHz to 2.5GHz or vice-versa. This can be very tricky.</p>
<p>It should get connected after trying this. Just make sure that the passwords are consistent and that you don’t accidentally have the caps lock key switched on while typing, for example.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748028008935/192fb282-93c7-4b65-86a2-c26cdfac9d53.jpeg" alt="Screenshot of a portable hotspot setup screen showing fields for network name, password, security setting (WPA2-Personal), AP band selection (5 GHz), and an option to hide the SSID, which is off." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>To confirm if the Raspberry Pi is connected using the command line interface, use the <code>ping</code> command – it shows the devices connected to the device.</p>
<pre><code class="lang-bash">ping raspberrypi.local
</code></pre>
<p>After running the above command, you should see an image showing the connection once it’s successful like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747931544791/77217325-4f3e-4abb-a136-d4634b773f2d.png" alt="A command prompt window showing a ping test to &quot;raspberrypi.local&quot; with an IPv6 address. Four packets are sent and received with no loss. Round trip times range from 6ms to 125ms, with an average of 36ms." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>For establishing an SSH connection using the terminal, run the code below:</p>
<pre><code class="lang-bash">ssh pi@raspberrypi.local
</code></pre>
<p>This will result in a request for a password. If it shows an error like the image below, it means you have to delete the <code>known_hosts.old</code> and <code>known_hosts</code> if either or both exist in the <code>.ssh</code> folder in your PC. This is because the keys are conflicting with each other. Then re-run the above code <code>ssh pi@raspberrypi.local</code> in your terminal.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747931933273/d8f111cc-3455-4de3-af0c-cf0a9814a877.png" alt="SSH warning message indicating a change in the remote host identification for a Raspberry Pi, suggesting possible eavesdropping or a host key update. Offers instructions for resolving the issue by updating the known_hosts file." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>After successful entry, type “<code>yes</code>” in the terminal.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747932392301/a09ad065-8e1e-464f-baef-5529eee26ce4.png" alt="Command-line interface showing an SSH connection attempt to a Raspberry Pi. It prompts the user to confirm the authenticity of the host with a given key fingerprint, asking if they want to continue connecting." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p><code>Connection Closed</code> should show when the connection is successful.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747932449402/bcd16bc6-18a1-4a84-82cf-d5c7431345e3.png" alt="Screenshot of a terminal window showing an SSH connection attempt from a user to a Raspberry Pi. The authenticity of the host is questioned, asking for confirmation to continue. The fingerprint is displayed, indicating it's not previously known. The connection is then added to known hosts, before closing." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-set-up-visual-studio-code-for-remote-development">How to Set Up Visual Studio Code for Remote Development</h2>
<p>Download and install <a target="_blank" href="https://code.visualstudio.com/">Visual Studio Code</a> if you don’t have it already.</p>
<p>Then, click on the VS Code extension and search for <code>Remote - SSH</code> by Microsoft and install it to your machine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747933199343/2c181e3a-80bd-44d1-8b40-5e3cf6191f2b.png" alt="Screenshot of the Visual Studio Code extension marketplace displaying the &quot;Remote - SSH&quot; extension by Microsoft. It shows installation details, ratings, and features like using a remote machine with SSH for development. The left sidebar lists related extensions." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Next, click on the “Remote Explorer” icon that looks like a monitor. Select the SSH config in your <code>C:\Users\{name}\.ssh\config</code> folder.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747933364169/7eaa4a7b-294c-41ef-8ecb-fe80151e6399.png" alt="Screenshot of Visual Studio Code showing the Remote - SSH extension interface. The SSH configuration file selection is open, displaying file paths. On the right, there is a description and installation details for the extension, including version and update information. The left sidebar displays a connection to a remote SSH machine named &quot;raspberrypi&quot;." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Make sure the config has this command:</p>
<pre><code class="lang-bash">Host raspberrypi.local
    HostName raspberrypi.local
    User pi
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747933533204/611b6a3d-cd4c-4756-982b-76efb0aa25c9.png" alt="611b6a3d-cd4c-4756-982b-76efb0aa25c9" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Enter your username as <code>raspberrypi.local</code> and input your password – the same as the password during loading Raspbian OS.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747933839359/7f43b231-5177-4b11-9d10-7234961db3f7.png" alt="Visual Studio Code interface showing a prompt to enter a password for &quot;pi@raspberrypi.local&quot; to set up an SSH host. The background features a shortcut guide and a loading bar." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>After inputting the correct password, it should start downloading the server.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747933859344/0c87fd5c-071b-4016-b113-4fc88c166032.png" alt="Visual Studio Code interface showing keyboard shortcuts for various commands. A download progress bar at the bottom indicates &quot;Downloading VS Code Server…&quot;" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Congratulations! The image below has a blue rectangle button showing <code>SSH:raspberrypi.local</code> which shows a successful SSH Connection through Visual Studio Code. This also means you can start remote development as we discussed earlier in this tutorial.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747933925369/a2aaf412-e465-47e9-8e97-129734f87534.png" alt="A screenshot of Visual Studio Code's welcome screen. The interface lists options to open a folder or clone a repository. The &quot;Start&quot; section has options like &quot;New File&quot; and &quot;Open Folder.&quot; The &quot;Recent&quot; section displays a list of recently accessed projects. The &quot;Walkthroughs&quot; area suggests getting started guides. The sidebar on the left shows file explorer and other icons. The bottom status bar indicates an SSH connection." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-write-and-run-the-code-remotely">How to Write and Run the Code Remotely</h2>
<p>Create a new file on your VS Code. This way, you’re creating files and writing to them directly. Go to the terminal and type the commands to create a folder and a file:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747934210225/a6e7f454-6f65-4a87-8692-cadaa642b007.png" alt="Screenshot of Visual Studio Code showing a terminal session and a text editor. The terminal is open at the bottom, with commands for creating a directory, navigating to it, and opening it in the editor. The main editor area prompts to select a language or open a different editor. The Explorer sidebar is visible on the left." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-create-a-new-file-and-write-in-your-code"><strong>Create a new file and write in your code</strong></h3>
<p>Create a new file and name it <code>led.py</code> on your Visual Studio Code. It should be in the same folder as <code>test-raspberry</code> on the Raspberry Pi remote network through the SSH connection on VSCode.</p>
<p>Once you have your file created, you can write in your code such as blinking LED to a Raspberry Pi, as you can see in the code below:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> gpiozero <span class="hljs-keyword">import</span> LED
<span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep

<span class="hljs-comment"># Set the GPIO pin where the LED is connected</span>
led = LED(<span class="hljs-number">17</span>)  <span class="hljs-comment"># Replace 17 with your GPIO pin number</span>

<span class="hljs-comment"># Blink the LED in a loop</span>
<span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
    led.on()        <span class="hljs-comment"># Turn LED on</span>
    sleep(<span class="hljs-number">1</span>)        <span class="hljs-comment"># Wait for 1 second</span>
    led.off()       <span class="hljs-comment"># Turn LED off</span>
    sleep(<span class="hljs-number">1</span>)        <span class="hljs-comment"># Wait for 1 second</span>
</code></pre>
<p>After writing this code in the new file you’ve created, run the code by typing the command below in your terminal:</p>
<pre><code class="lang-bash">python led.py
</code></pre>
<p>As soon as this command is sent, the LED positive terminal is connected to the GPIO 17 according to the code and the negative terminal is connected to the GND GPIO pin of the Raspberry Pi. The image from <a target="_blank" href="https://randomnerdtutorials.com/raspberry-pi-pinout-gpios/">Random Nerd Tutorials</a> below shows the GPIO pins and their number to understand the connection. Just note that the connection of the LED is beyond the scope of this tutorial.</p>
<p><img src="https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2023/03/Raspberry-Pi-Pinout-Random-Nerd-Tutorials.png?quality=100&amp;strip=all&amp;ssl=1" alt="Raspberry Pi Pinout Guide: How to use the Raspberry Pi GPIOs? | Random Nerd  Tutorials" width="600" height="400" loading="lazy"></p>
<p>The LED should start blinking each second according to the code. With this, you can now control your Raspberry Pi (a tiny computer) with another computer (your personal computer) through an SSH connection on Visual Studio Code.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you went through the whole process of setting up a headless Raspberry Pi for remote development using VS Code.</p>
<p>This offers a wide range of benefits: there’s no need for external peripherals, it provides remote access from anywhere within your network, and it leverages efficient coding and debugging with VS Code integration.</p>
<p>You can use this to deploy web servers and IoT dashboards, and you can explore with automating processes using Python scripts and GPIO control.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Connect Your AWS EC2 Instance to VS Code ]]>
                </title>
                <description>
                    <![CDATA[ As a DevOps engineer, it is crucial to master at least one cloud provider. Cloud services simplify storage, data migration, and CI/CD workflows and help make these tasks easier and more efficient. If you need a basic introduction to cloud computing, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-connect-your-aws-ec2-instance-to-vs-code/</link>
                <guid isPermaLink="false">67e2ec52cd467794ee79d63e</guid>
                
                    <category>
                        <![CDATA[ ec2 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Cloud ]]>
                    </category>
                
                    <category>
                        <![CDATA[ server ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ijeoma Igboagu ]]>
                </dc:creator>
                <pubDate>Tue, 25 Mar 2025 17:48:02 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742397603245/c1ca0496-dbab-4570-8b6b-cb4bac5f72c1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a DevOps engineer, it is crucial to master at least one cloud provider. Cloud services simplify storage, data migration, and CI/CD workflows and help make these tasks easier and more efficient.</p>
<p>If you need a basic introduction to cloud computing, here’s a beginner-friendly tutorial for you: <a target="_blank" href="https://www.freecodecamp.org/news/cloud-computing-guide-for-beginners/"><strong>What is Cloud Computing? A Guide for Beginners.</strong></a></p>
<p>In this guide, I’ll show you how to create an AWS EC2 instance. This is one of AWS’s top services for building applications. By the end of this guide, you'll know how to launch an AWS EC2 instance and connect it to VS Code.</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-an-aws-ec2-instance">What is an AWS EC2 Instance?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-connect-your-aws-ec2-instance-to-vs-code">Why Connect Your AWS EC2 Instance to VS Code?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-launch-and-connect-your-aws-ec2-instance-to-vs-code">How to Launch and Connect Your AWS EC2 Instance to VS Code</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-create-an-aws-ec2-instance">Step 1: Create an AWS EC2 Instance</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-connect-the-aws-ec2-instance-to-your-code-editor">Step 2: Connect the AWS EC2 Instance to Your Code Editor</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-install-the-programming-language">Step 3: Install the Programming Language</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-open-a-remote-window">Step 4: Open a Remote Window</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-access-your-project-folder">Step 5: Access Your Project Folder</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start, make sure you have:</p>
<ul>
<li><p>An AWS account. If you do not have one, <a target="_blank" href="https://aws.amazon.com/free/?gclid=Cj0KCQiAvvO7BhC-ARIsAGFyToVguvjmSCa99VkB7XsHepginSELSYCCYnVzZXeZSKFpRRTC8DKyh98aAkZkEALw_wcB&amp;trk=2d3e6bee-b4a1-42e0-8600-6f2bb4fcb10c&amp;sc_channel=ps&amp;ef_id=Cj0KCQiAvvO7BhC-ARIsAGFyToVguvjmSCa99VkB7XsHepginSELSYCCYnVzZXeZSKFpRRTC8DKyh98aAkZkEALw_wcB:G:s&amp;s_kwcid=AL!4422!3!645125273261!e!!g!!aws!19574556887!145779846712&amp;all-free-tier.sort-by=item.additionalFields.SortRank&amp;all-free-tier.sort-order=asc&amp;awsf.Free%20Tier%20Types=*all&amp;awsf.Free%20Tier%20Categories=*all">sign up here</a>.</p>
</li>
<li><p>A GitHub repository with your source code. If you don’t have a GitHub account, <a target="_blank" href="https://github.com/">sign up here</a>.</p>
</li>
<li><p>Basic knowledge of web development and version control.</p>
</li>
<li><p>A code editor. For this tutorial, I’m using VS Code.</p>
</li>
</ul>
<p>Let’s jump right in!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735997217784/fdb3b399-7a07-4cf2-8577-10859bf5542d.gif" alt="fdb3b399-7a07-4cf2-8577-10859bf5542d" class="image--center mx-auto" width="220" height="220" loading="lazy"></p>
<h2 id="heading-what-is-an-aws-ec2-instance">What is an AWS EC2 Instance?</h2>
<p>AWS EC2 (Elastic Compute Cloud) allows you to run virtual machines in the cloud. These computers allow you to run your applications without needing physical hardware.</p>
<p>There are a number of things you can you do with AWS EC2, such as hosting websites or apps, running big data or machine-learning tasks, creating testing environments, and handling tasks that need flexible, scalable computing power.</p>
<h2 id="heading-why-connect-your-aws-ec2-instance-to-vs-code">Why Connect Your AWS EC2 Instance to VS Code?</h2>
<p>Connecting your AWS EC2 instance to VS Code is helpful for several reasons. Before we start the setup process, it’s important to learn why it’s beneficial.</p>
<ol>
<li><p>Using VS Code provides a familiar and efficient development space. It feels like coding on your own machine.</p>
</li>
<li><p>You don’t have to log into your AWS EC2 instance each time. You can edit files, run commands, and debug code from a distance.</p>
</li>
<li><p>You can streamline your workflow with built-in terminal access and extensions. This way, you won't have to switch between SSH clients all the time.</p>
</li>
<li><p>You can push changes to GitHub. This makes working together and deploying much smoother.</p>
</li>
<li><p>VS Code works well with Java, Node.js, and Python. It supports many languages and frameworks, so it's great for cloud development.</p>
</li>
</ol>
<p>Now that you understand the benefits, let’s move on to setting up the connection.</p>
<h2 id="heading-how-to-launch-and-connect-your-aws-ec2-instance-to-vs-code"><strong>How to Launch and Connect Your AWS EC2 Instance to VS Code</strong></h2>
<p>To launch an EC2 instance on AWS, just follow these steps:</p>
<h3 id="heading-step-1-create-an-aws-ec2-instance"><strong>Step 1: Create an AWS EC2 Instance</strong></h3>
<p>First, log into your AWS account. Then, use the search bar to find EC2 and select it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736016609765/f784db8e-46cc-4e03-abc0-7bdea9b1c668.png" alt="Searching for EC2 on AWS Console" class="image--center mx-auto" width="1920" height="970" loading="lazy"></p>
<p>Click EC2 and follow the on-screen instructions to create a new instance.</p>
<ol>
<li><p><strong>Choose an AMI (Amazon Machine Image):</strong> This is a pre-configured template that includes an operating system and may come with additional software.</p>
</li>
<li><p><strong>Select an instance type:</strong> Pick the right size for your needs. For example, <code>t2.micro</code> is a good option for beginners and small workloads.</p>
</li>
<li><p><strong>Configure Your EC2 Instance:</strong> Set up networking, storage, security groups, and other options based on your requirements.</p>
</li>
<li><p><strong>Launch Your Instance:</strong> Start your virtual server and access it remotely to begin using it.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736174305817/e8d9d8dd-f09d-4bca-a838-42ee55607fa5.gif" alt="creating an EC2 instance" class="image--center mx-auto" width="1920" height="971" loading="lazy"></p>
<p>Launched instance running:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736174700999/b729de98-bd8f-496f-9486-3079d87fb4de.png" alt="Launched Instance" class="image--center mx-auto" width="1553" height="209" loading="lazy"></p>
<p>So what’s happening in Step 1?</p>
<p>By launching an AWS EC2 instance, you are setting up a remote server in the cloud. AWS offers different AMIs that serve as pre-configured environments.</p>
<h3 id="heading-step-2-connect-the-aws-ec2-instance-to-your-code-editor">Step 2: <strong>Connect the AWS EC2 Instance to Your Code Editor</strong></h3>
<p>To connect your EC2 instance created in AWS to your VS Code, you need SSH.</p>
<h4 id="heading-what-is-ssh">What is SSH?</h4>
<p>SSH (Secure Shell) is a secure way to connect and communicate with other devices. It keeps your connection safe. This is important when you access servers or repositories. In Git, you can use SSH instead of HTTPS to clone repositories with a secure connection.</p>
<h4 id="heading-why-is-ssh-important-here">Why is SSH important here?</h4>
<p>With SSH, you can link your local code editor (like VS Code) to your AWS EC2 instance. This allows you to work on files stored on the EC2 instance directly from your editor as if on your local computer.</p>
<p><strong>To connect your AWS EC2 instance to your local editor using SSH, follow these steps:</strong></p>
<ul>
<li><p>Open your terminal.</p>
</li>
<li><p>Go to the folder where your <code>.pem</code> key file is. The key file (.pem) downloads automatically when you create your EC2 instance (usually in the Downloads folder).</p>
</li>
<li><p>Update the file permissions to keep your key secure and ensure proper authentication.</p>
</li>
</ul>
<p>For Linux users, use this command to update the file permissions:</p>
<pre><code class="lang-bash">chmod 400 codebuild-keypair.pem
</code></pre>
<p>For Windows users, first you’ll need to find the username of your laptop, as you’ll need it to update the file permissions.</p>
<p>To do this, open your terminal and type:</p>
<pre><code class="lang-powershell">whoami
</code></pre>
<p>This will display your current username.</p>
<p>Once you have your username, use the following command to update the file permissions:</p>
<pre><code class="lang-powershell">icacls <span class="hljs-string">"codebuild-keypair.pem"</span> /reset
icacls <span class="hljs-string">"codbuild-keypair.pem"</span> /grant:<span class="hljs-built_in">r</span> <span class="hljs-string">"%USERNAME%:R"</span>
icacls <span class="hljs-string">"codebuld-keypair.pem"</span> /inheritance:<span class="hljs-built_in">r</span>
</code></pre>
<p>Here's what I mean: My username is <strong>ijeon</strong>, so you should replace it with <strong>your laptop's username</strong> and <strong>own</strong> key, which ends with <code>.pem</code> extension.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736021541861/048a9411-2348-48dc-8a6e-04d51dbd347d.png" alt="pasting the command on the terminal" class="image--center mx-auto" width="1096" height="102" loading="lazy"></p>
<p>Running this command above updates the file permissions. So with this, you can work with your remote server.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736021649692/118c75cf-30b4-474c-b726-142c2b4326e9.png" alt="the output of the command pasted" width="722" height="153" loading="lazy"></p>
<p>Now that you have set the correct file permissions, you can use the SSH command along with the IPv4 address to connect to our EC2 instance. Type the following command:</p>
<pre><code class="lang-powershell">ssh <span class="hljs-literal">-i</span> [<span class="hljs-type">PATH</span> <span class="hljs-type">TO</span> <span class="hljs-type">YOUR</span> <span class="hljs-type">.PEM</span> <span class="hljs-type">FILE</span>] ec2<span class="hljs-literal">-user</span><span class="hljs-selector-tag">@</span>[<span class="hljs-type">YOUR</span> <span class="hljs-type">PUBLIC</span> <span class="hljs-type">IPV4</span> <span class="hljs-type">DNS</span>]
</code></pre>
<p>Example:</p>
<pre><code class="lang-powershell">ssh <span class="hljs-literal">-i</span> <span class="hljs-string">"C:\Users\ijeon\OneDrive\Desktop\devops-series-nextwork\codebuild-keypair.pem"</span> ec2<span class="hljs-literal">-user</span>@ec2<span class="hljs-literal">-35</span><span class="hljs-literal">-178</span><span class="hljs-literal">-142</span><span class="hljs-literal">-201</span>.eu<span class="hljs-literal">-west</span><span class="hljs-literal">-2</span>.compute.amazonaws.
</code></pre>
<p>Breaking it down:</p>
<ol>
<li><p><code>ssh</code>: This starts a secure remote connection.</p>
</li>
<li><p><code>-i "C:\Users\ijeon\...\codebuild-keypair.pem"</code>: This tells SSH to use the <code>.pem</code> key file for secure access.</p>
</li>
<li><p><a target="_blank" href="mailto:ec2-user@ec2-35-178-142-201.eu-west-2.compute.amazonaws.com"><code>ec2-user@ec2-35-178-142-201.eu-west-2.compute.amazonaws.com</code></a>:</p>
<ul>
<li><p><code>ec2-user</code> is the default username for EC2 instances.</p>
</li>
<li><p><code>@ec2-35-178-142-201...</code> is the public address of your EC2 instance.</p>
</li>
</ul>
</li>
</ol>
<p>This command logs you into your EC2 instance remotely from your computer. It then uses the key (<code>.pem</code> file) instead of a password for security. It also lets you control the EC2 instance from your terminal as if you were using it directly.</p>
<p>If everything is set up correctly, a “success message” will appear. This confirms that you've logged in and can access the remote server.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742153348953/a68f32fc-7578-4904-9b2e-e63a353e84a0.gif" alt="connecting via ssh" class="image--center mx-auto" width="1920" height="1079" loading="lazy"></p>
<h3 id="heading-step-3-install-the-programming-language"><strong>Step 3: Install the Programming Language</strong></h3>
<p>Now that you’ve linked your instance to the editor, you can install the packages needed to build your web app. You can use any programming language you're comfortable with, but we’ll use Java for this tutorial. This will be a simple web application – we don’t need to go into advanced details.</p>
<h4 id="heading-1-install-java"><strong>1. Install Java</strong></h4>
<p>In your terminal, run the following commands to install <strong>Java</strong>:</p>
<pre><code class="lang-powershell">sudo dnf install <span class="hljs-literal">-y</span> java<span class="hljs-literal">-1</span>.<span class="hljs-number">8.0</span><span class="hljs-literal">-amazon</span><span class="hljs-literal">-corretto</span><span class="hljs-literal">-devel</span>

export JAVA_HOME=/usr/lib/jvm/java<span class="hljs-literal">-1</span>.<span class="hljs-number">8.0</span><span class="hljs-literal">-amazon</span><span class="hljs-literal">-corretto</span>.x86_64

export PATH=/usr/lib/jvm/java<span class="hljs-literal">-1</span>.<span class="hljs-number">8.0</span><span class="hljs-literal">-amazon</span><span class="hljs-literal">-corretto</span>.x86_64/jre/bin/:<span class="hljs-variable">$PATH</span>
</code></pre>
<p>This installs Java on your system. You also need Maven. It helps manage Java projects and create templates for web applications.</p>
<h4 id="heading-2-install-maven"><strong>2. Install Maven</strong></h4>
<p>Maven helps you organize Java projects. It also lets you create templates for web applications. Run these commands to install Maven:</p>
<pre><code class="lang-powershell"><span class="hljs-built_in">wget</span> https://archive.apache.org/dist/maven/maven<span class="hljs-literal">-3</span>/<span class="hljs-number">3.5</span>.<span class="hljs-number">2</span>/binaries/apache<span class="hljs-literal">-maven</span><span class="hljs-literal">-3</span>.<span class="hljs-number">5.2</span><span class="hljs-literal">-bin</span>.tar.gz

sudo tar <span class="hljs-literal">-xzf</span> apache<span class="hljs-literal">-maven</span><span class="hljs-literal">-3</span>.<span class="hljs-number">5.2</span><span class="hljs-literal">-bin</span>.tar.gz <span class="hljs-literal">-C</span> /opt

<span class="hljs-built_in">echo</span> <span class="hljs-string">"export PATH=/opt/apache-maven-3.5.2/bin:<span class="hljs-variable">$PATH</span>"</span> &gt;&gt; ~/.bashrc

source ~/.bashrc
</code></pre>
<p>To confirm Maven's correct installation, run this command:</p>
<pre><code class="lang-powershell">mvn <span class="hljs-literal">-v</span>
</code></pre>
<p>Also, run the following command to check whether you have Java installed:</p>
<pre><code class="lang-powershell">java <span class="hljs-literal">-version</span>
</code></pre>
<p>Now that you have installed Maven, you can use it to create a Java web app with the following command:</p>
<pre><code class="lang-powershell">mvn archetype:generate \
  <span class="hljs-literal">-DgroupId</span>=com.nextwork.app \
  <span class="hljs-literal">-DartifactId</span>=nextwork<span class="hljs-literal">-web</span><span class="hljs-literal">-project</span> \
  <span class="hljs-literal">-Dpackage</span>=com.nextwork.app \
  <span class="hljs-literal">-DarchetypeArtifactId</span>=maven<span class="hljs-literal">-archetype</span><span class="hljs-literal">-webapp</span> \
  <span class="hljs-literal">-DarchetypeVersion</span>=<span class="hljs-number">1.4</span> \
  <span class="hljs-literal">-DinteractiveMode</span>=false
</code></pre>
<p>Running the command above generates a template for your application. In the terminal, it should show a "Build Success" message. This means the setup worked.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742122446716/7c51b3a2-6a8c-463d-817c-9630488a803d.png" alt="Installing the template" class="image--center mx-auto" width="1410" height="854" loading="lazy"></p>
<h3 id="heading-step-4-open-a-remote-window"><strong>Step 4:</strong> Open a Remote Window</h3>
<p>Now that you’ve installed the necessary packages and set up your app template, you need to open your IDE or code editor. This will let you access the folders on your remote server.</p>
<p>In your terminal, click the double arrow icon at the bottom left.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736073016500/cb3a4d44-3ae5-4ccb-9006-c592c0be30f7.png" alt="double arrow at the left" class="image--center mx-auto" width="155" height="119" loading="lazy"></p>
<p>When you click on it, it opens a modal window for you.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736073334686/a24d115c-9da3-4b46-80be-a75d73a189ab.gif" alt="connect to the host" class="image--center mx-auto" width="1920" height="1079" loading="lazy"></p>
<p>A window will appear. Click "Connect to Host," which will open another window.</p>
<p>Then choose "Add New SSH Host" to open the SSH connection terminal.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736073802080/45dbc209-0b4c-41a2-83eb-3fa05a8eff20.gif" alt="adding ssh host" class="image--center mx-auto" width="1920" height="1079" loading="lazy"></p>
<p>Input your SSH command to configure the host.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736078262849/b09d017e-cbd3-476e-9641-63dc41e34d83.png" alt="image of SSH connection command" class="image--center mx-auto" width="928" height="146" loading="lazy"></p>
<p>After pressing "Enter," a configuration file will open. In this file, ensure that the <code>.pem</code> file and the <code>IP4v DNS</code> addresses from your EC2 instance are correct.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736083806867/e158ee79-67d3-41c8-bb63-870caab0033b.png" alt="place to press for the configuration file" class="image--center mx-auto" width="890" height="207" loading="lazy"></p>
<p>Here’s a GIF view of the image above:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736083586490/7520a325-376d-42a8-905d-2e22770498de.gif" alt="a gif view of how to open your configuration file" class="image--center mx-auto" width="1920" height="1079" loading="lazy"></p>
<p>Here’s the configuration file:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736084278100/6e71324f-6b47-4a2a-b7a1-89c1be10c39b.png" alt="config file" class="image--center mx-auto" width="1348" height="349" loading="lazy"></p>
<p>Go back to your editor and click on that double arrow again. This will automatically open a new window.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736086002267/53e4edd8-afe2-4652-90ab-56bc90f80405.gif" alt="Re-opening a new window" class="image--center mx-auto" width="1920" height="1079" loading="lazy"></p>
<p>If your editor displays the IPv4 DNS address, your VS Code is successfully connected to the EC2 instance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736086479299/e399f86c-e236-4efc-8d4d-a7055139d01e.png" alt="connection to the remote server" width="683" height="209" loading="lazy"></p>
<p>Now that you’re connected and a new window has opened, let’s access the folder stored in the cloud.</p>
<h3 id="heading-step-5-access-your-project-folder">Step 5: Access Your Project Folder</h3>
<p>In step 3, remember when you installed Maven? It created a template for your web app. Now, you’ll access the folder where you created this.</p>
<ol>
<li><p>Go to the Explorer panel in the window.</p>
</li>
<li><p>Click the <strong>“</strong>Open Folder<strong>”</strong> button.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736087503207/7fb21fcb-939e-4f17-83d2-93a6e0e3ee68.png" alt="access remote folder" class="image--center mx-auto" width="219" height="171" loading="lazy"></p>
<p>Clicking on this button opens a modal box for you to select your folder, which was created by the Maven template:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742134089654/77104e69-4c7a-4b59-812d-423167079f24.gif" alt="accessing the folder" class="image--center mx-auto" width="1920" height="1079" loading="lazy"></p>
<p>To access the template file, click the “src” folder. This takes you to the <code>index.jsp</code> file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742135158716/4cfedc15-1c2e-4d60-b9f6-fe04c300dfa0.png" alt="template automatically created for you" width="1920" height="1080" loading="lazy"></p>
<p>With this template created, you can decide to tweak it and send it to your Git repository for storage.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Great job! You’ve set up an AWS EC2 instance, linked it to your code editor, and installed the tools needed for your web app. In this tutorial, we used Java, but you can also choose other languages like Node.js or Python.</p>
<p>If you found this article helpful, please share it with others who may find it interesting.</p>
<p>Stay updated with my projects by following me on <a target="_blank" href="https://twitter.com/ijaydimples">Twitter</a>, <a target="_blank" href="https://twitter.com/ijaydimples">LinkedIn</a> and <a target="_blank" href="https://github.com/ijayhub">GitHub</a>.</p>
<p>Thank you for reading.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How SSH Authentication with GitHub Works Under the Hood ]]>
                </title>
                <description>
                    <![CDATA[ SSH (Secure Shell) is a client-server protocol for connecting and authenticating to a remote server. Authentication means that the remote server can verify that it’s actually you and not somebody else talking on your behalf. You may already be using ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/ssh-authentication-with-github-under-the-hood/</link>
                <guid isPermaLink="false">67ace33e18a2c0de81d7ffc3</guid>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ public-key cryptgraphy ]]>
                    </category>
                
                    <category>
                        <![CDATA[ encryption ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Vivek Agrawal ]]>
                </dc:creator>
                <pubDate>Wed, 12 Feb 2025 18:06:54 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1739082652213/aba38efa-117c-4ef7-a844-91599c0a4d62.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>SSH (Secure Shell) is a client-server protocol for connecting and authenticating to a remote server.</p>
<p>Authentication means that the remote server can verify that it’s actually you and not somebody else talking on your behalf.</p>
<p>You may already be using GitHub’s SSH authentication, but do you know how it actually works? In this article, you’ll learn what happens under the hood and how SSH authentication actually works.</p>
<p>Along the way, you’ll understand the fundamental concepts of cryptography that every developer should know about: symmetric key encryption, asymmetric key encryption, cryptographic hash functions, and digital signatures.</p>
<p>Some developers usually don’t get the chance to learn and understand these cryptography fundamentals, but these concepts will help you in the long run. Also, they’ll help you be in a much better position to take informed security decisions for your production web applications.</p>
<p>So come on, fasten your seat belts, and let’s start!</p>
<h3 id="heading-heres-what-well-cover">Here’s what we’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-first-why-is-authentication-so-important">First, Why is Authentication So Important?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-symmetric-key-encryption">Symmetric Key Encryption</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-asymmetric-key-encryption">Asymmetric Key Encryption</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cryptographic-hash-functions">Cryptographic Hash Functions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-digital-signatures">Digital Signatures</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-ssh-authentication-works">How SSH Authentication Works</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-wrapping-it-all-up">Wrapping it All Up</a></p>
</li>
</ol>
<h2 id="heading-first-why-is-authentication-so-important">First, Why is Authentication So Important?</h2>
<p>When we run <code>git push</code>, GitHub needs to verify that the right person is interacting with GitHub. Imagine if an attacker could manage to do <code>git push</code> on your behalf.</p>
<p>Then all your repositories would be under that attacker's control. They could delete all your code along with all the commit history.</p>
<p>This sounds quite dangerous, doesn’t it? So to verify that it’s actually you who’s talking to GitHub, and not an attacker, GitHub has several ways to authenticate you.</p>
<p>The most widely used method to authenticate with GitHub is SSH authentication.</p>
<p>Before we understand how SSH authentication works under the hood, we will need to understand the fundamental cryptography concepts, namely — symmetric key encryption, asymmetric key encryption, cryptographic hash functions, and digital signatures.</p>
<p>Let’s begin!</p>
<h2 id="heading-symmetric-key-encryption">Symmetric Key Encryption</h2>
<p>In the ancient days, rulers devised various methods of communicating secret military messages to their army commanders.</p>
<p>One of the earliest methods, likely used by ancient Greek rulers and possibly later the Romans, involved using a cylindrical wooden rod called a <a target="_blank" href="https://en.wikipedia.org/wiki/Scytale"><strong>Scytale</strong></a>.</p>
<p>Before a military invasion, the ruler would have two exact same cylindrical wooden rods made called scytales. Then he would give one scytale to the army commander and keep one for himself.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734514827027/b4945c3a-64d4-458b-a410-f23b1a08d9ef.png" alt="A scytale with leather strip wounded and a message written on it." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The device worked by winding a strip of leather around the scytale. After doing this, the ruler would write the message on top of the wound-up leather strip so that it could only be read when properly wound again.</p>
<p>Suppose the scytale allowed him to write three letters around in a circle and five letters straight across/along its length. The wound leather strip with the message <code>attackfromright</code> written on it would look like this:</p>
<pre><code class="lang-plaintext">       |   |   |   |   |   |
       | a | t | t | a | c |  |
     __| k | f | r | o | m |__|
    |  | r | i | g | h | t |
    |  |   |   |   |   |   |
</code></pre>
<p>After writing the message on the scytale, the ruler would unwind the leather strip and send it to the army commander. When it was unwound, the leather strip would have the following jumbled message:</p>
<pre><code class="lang-plaintext">----------------
akrtfitrgaohcmt
----------------
</code></pre>
<p>So now you see, even if the leather strip got intercepted by an enemy spy, the message would not make sense. Isn't this fascinating? The smart use of a wooden rod and a leather strip might have helped some ancient rulers win battles!</p>
<p>When the leather strip reached the army commander, he would wind it around his own scytale (which would be exactly the same as ruler’s), and then the commander would be able to understand the message properly.</p>
<p>This scytale technique is actually an example of symmetric key encryption in practice.</p>
<p>Encryption is a process in which the original message is modified (or encoded) in such a way that only the intended recipient can decode and see the actual message.</p>
<p>The original message is called plaintext, while the encoded message is called ciphertext. Encryption converts <code>plaintext to ciphertext</code> with the help of a key.</p>
<p>To decrypt the message, that is to convert <code>ciphertext to plaintext</code>, a person must have access to that same key.</p>
<p>If we compare it to the scytale technique, the scytale is the key. The ruler only shares the key (scytale) with the army commander who needs to know what the message says.</p>
<p>Here's what the encryption process looks like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734519516607/75c926a3-faec-402a-8bcd-122039f47a01.png" alt="Encryption with scytale as key." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The decryption process will look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734519525487/de096889-332c-4482-b2df-b28ce609a8a6.png" alt="Decryption with scytale as key." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>We call this symmetric key encryption because the same key is used to both encrypt and decrypt the message.</p>
<p>This key (the scytale) must be kept protected from enemy access. If the enemy get’s access to this key, then they’ll be able to decrypt the messages.</p>
<p>But there’s another type of encryption called asymmetric key encryption. Now that you understand symmetric key encryption, let’s move on to asymmetric key encryption.</p>
<h2 id="heading-asymmetric-key-encryption">Asymmetric Key Encryption</h2>
<p>In symmetric key encryption, like we saw above, the same key was used by both the ruler and the army commander to encrypt and decrypt the message.</p>
<p>But in an asymmetric key encryption, there are two keys (called a key pair). Out of the two keys, one is a private key and the other is a public key.</p>
<p>The public key can be shared with everyone (which is why it’s called public). But the private key is meant to be kept secret! It must never ever be revealed to anybody.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735200860039/7aca8ffa-c33a-44e5-ab1a-181492ebefd8.png" alt="Public key can be shared with everyone. But the private key must be kept secret." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The interesting thing about asymmetric key encryption is that, if a message is encrypted with the public key, then it can only be decrypted with the corresponding private key. No other key can decrypt it.</p>
<p>And it works the other way too. If a message is encrypted with the private key then it can only be decrypted using the corresponding public key.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735120077350/b90901c8-b55c-428a-8eb4-1b8ffa65fa06.png" alt="Illustration of public and private key mathematically linked with each other." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The two keys – public and private – are mathematically linked with each other. While one encrypts, the other decrypts.</p>
<p>Just a small note that asymmetric key encryption is also called public key encryption. These two terms are used interchangeably but they mean the same thing.</p>
<h2 id="heading-cryptographic-hash-functions">Cryptographic Hash Functions</h2>
<p>A cryptographic hash function is designed to take in an input of any length and produce a fixed-length output. The fixed-length output is called as hash value.</p>
<p>A popular example of a cryptographic hash function is SHA-256.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735030835833/201640c6-13b4-4b2b-9be3-88e245269bd1.png" alt="SHA-256 calculation of &quot;freeCodeCamp.org&quot;" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The above image shows the SHA-256 hash value of the input “freeCodeCamp.org“. Cryptographic hash function has three properties that make it very useful (we’ll see how in the coming sections).</p>
<p>First<strong>,</strong> it’s practically impossible to take the hash value and figure out the input from the hash value.</p>
<p>For example, if we are given the hash value <code>c9c31315ef2257e4b7698</code>, there’s no way for us to figure out that the input to the hash function was “freeCodeCamp.org“.</p>
<p>Second<strong>,</strong> if we pass the same input to the hash function, we get the same hash value as output.</p>
<p>If we pass “freeCodeCamp.org“ again to the SHA-256 hash function, we will get the same hash output as our previous call.</p>
<p>Third<strong>,</strong> two different inputs never share the same hash value. Even the slightest change in input produces an entirely different output.</p>
<p>Suppose if we provide “freeCodeCamp“ as input instead of “freeCodeCamp.org“ – we would get a totally different output.</p>
<h2 id="heading-digital-signatures">Digital Signatures</h2>
<p>In your daily lives, you might have to sign various documents. These might be legal documents, or your kids’ school report card, or maybe something else.</p>
<p>When your signature is present on the document, it conveys to the other party that it is you who agrees with whatever is written on that document.</p>
<p>Later on, you cannot walk back from doing what’s written on the document. Correct?</p>
<p>Similarly, in the digital world, we have digital signatures – or we can simply call them signatures.</p>
<p>Let’s understand how signatures works using an example. We have two users named “Alice“ and “Bob“.</p>
<p>Bob wants to transfer some money to Alice’s bank account. So Bob asks Alice about her bank account information.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735042150046/034d26c5-b33d-4b82-aeb8-173e47cd8e8e.png" alt="An illustration showing alice and bob's computers far away from each other and alice's bank account number." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Alice knows about digital signatures and decided to use one. At the end, you will understand why Alice opted for a digital signature.</p>
<p>Before Alice can create a digital signature. Alice provides Bob with her public key (and keeps the private key to herself).</p>
<p>Then Alice creates a digital signature and places it at the end of the document.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735041977880/35313148-8820-42d7-b122-3ddf0cbaa723.png" alt="Process of digital signature generation." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>A digital signature is created by first passing the document contents to a cryptographic hash function like SHA-256. In Alice’s case, the document’s content is her bank account number.</p>
<p>Once we get the hash value, it gets encrypted with Alice’s <strong>private key</strong>. The output of this encryption is the signature which gets placed at the end of the document.</p>
<p>This is then sent to Bob over the Internet.</p>
<p>When Bob receives this document, he verifies whether the <strong>signature is valid or not</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735043216695/256f7707-3f40-433f-9b00-c11b27ef01e8.png" alt="Process of signature verification." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>To verify the signature, Bob first decrypts the signature with Alice’s public key. If you remember, Alice generated the signature by encrypting the hash value.</p>
<pre><code class="lang-plaintext"> plaintext                         ciphertext  
     |                                 |
     |                                 |
     |                                 |
hash value --------encrypt--------&gt; signature
</code></pre>
<p>So, when Bob decrypts the signature, he will get the hash value that Alice calculated. Let’s call this Alice’s hash value.</p>
<pre><code class="lang-plaintext"> ciphertext                         plaintext  
     |                                 |
     |                                 |
     |                                 |
signature --------decrypt--------&gt; hash value
</code></pre>
<p>Then Bob takes the bank account number that’s present on the document and passes it to the hash function.</p>
<p>Finally, Bob matches the Alice’s hash value (the decrypted signature) and the hash value that he just calculated. If both the hash values match then that means the signature is valid.</p>
<p>OK — but why did we need to do all this? What does it mean if the signature is valid?</p>
<p>When the signature verification is successful, it proves two things.</p>
<p>First<strong>,</strong> it proves that the document has been sent by Alice only. Nobody else could have sent this document.</p>
<p>The assurance that only Alice has sent this document comes from the fact that we were able to decrypt the signature using Alice’s public key.</p>
<p>We have learned that if something is encrypted using a private key then it can only be decrypted using its linked public key.</p>
<p>So, if Bob was successfully able to decrypt the signature using Alice’s public key, it means that it was encrypted using Alice’s private key, correct?</p>
<p>And only Alice has access to her private key. This means that Alice is the only person who could have sent this document!</p>
<p>Second<strong>,</strong> it proves that the content of the message has not been modified by an attacker during network transmission.</p>
<p>We did two things to verify the signature. We decrypted the signature, and it gave us the hash value that Alice calculated. And we also hashed the received bank account number.</p>
<p>If the hash value that Alice calculated and the hash value that Bob calculated are the same, this means that Alice and Bob gave exactly the same input to the hash function.</p>
<p>And this means that the bank account number that Alice sent and that Bob received are exactly same.</p>
<p>If an attacker would have changed the bank account number before the document reached Bob, then Bob would’ve received a modified bank account number.</p>
<p>When Bob went to calculate the hash value of this modified bank account number, the hash value would’ve come out to be different than what Alice had calculated.</p>
<p>So while matching Alice’s hash value (decrypted signature) and the hash value that Bob calculated, the matching would fail. And it would prevent Bob from transferring money to the wrong bank account number.</p>
<p>To conclude, when the signature is successfully verified, it means that:</p>
<ol>
<li><p>The document is only from Alice.</p>
</li>
<li><p>The document’s contents were not modified by any third party.</p>
</li>
</ol>
<p>Now you’ve learned about symmetric key encryption, asymmetric key encryption, cryptographic hash functions, and digital signatures. That’s awesome!</p>
<p>We have built a really solid foundation. Now understanding SSH authentication is going to be much easier for you.</p>
<h2 id="heading-how-ssh-authentication-works">How SSH Authentication Works</h2>
<p>If you have not setup SSH authentication with GitHub, then after completing this article you can follow <a target="_blank" href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account">GitHub’s detailed documentation on how to do it</a>. For now, please stay here till the end.</p>
<p>The crux of the setup process is that you create a public and private key pair on your local computer. Then you upload your public key to your GitHub profile – and that’s it!</p>
<p>After we have created our public-private key pair, in Ubuntu, public-private key pair are stored inside the <code>~/.ssh</code> directory.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735035539565/1f837d9b-9717-44fa-a5e0-5801276113df.png" alt="Showing my public key from my terminal." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The above image shows my public key. I have this public key uploaded to my GitHub profile:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735035898284/1ef9133a-895b-4847-a7ac-6157fdcc3143.png" alt="Showing my GitHub profile settings where my public key is uploaded for SSH authentication with GitHub." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Now, when I run <code>git push</code> or any other command that wants to communicate with GitHub, I will be authenticated using SSH authentication.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735053545173/6fb293f1-f90a-4b64-b026-082d8676afae.png" alt="The illustration of SSH authentication process between client and GitHub server." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>SSH is a client-server protocol. Our computer that runs <code>git push</code> is the SSH client. GitHub is the SSH server.</p>
<p>The client starts off the authentication process by first fetching our public key that we have inside <code>~/.ssh</code>.</p>
<p>The client then prepares a message which has our public key. And then the client generates the signature using the corresponding private key.</p>
<p>The public key and signature are sent to GitHub. Upon receiving this message, GitHub does two things:</p>
<p>First, it verifies whether the public key mentioned in the message is connected to a GitHub profile or not. Since we upload our public key to GitHub, this step checks out successfully.</p>
<p>Second, GitHub verifies the signature using the public key that we have uploaded.</p>
<p>We have learned that if the signature verification turns out to be successful this means that only the person who is in the possession of the corresponding private key could have sent the message.</p>
<p>Since only we have the private key linked to the uploaded public key, this proves to GitHub that it is indeed us attempting to communicate with GitHub and not an attacker.</p>
<p>Now, GitHub is 100% sure that we are the correct person, we are successfully authenticated, and our <code>git push</code> is allowed to proceed further.</p>
<p>See, it became so easy to understand SSH authentication as you already learned the fundamentals.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735120630613/e9a8bbba-3cc4-43e7-8369-865ab377fb87.png" alt="A xkcd comic depicting Cueball thinking to share his private key. A dangerous move!" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The above image is from the popular <a target="_blank" href="https://xkcd.com/1553/">xkcd comic</a>. The character there (named Cueball) is thinking about revealing his private key. I hope now you know why it’s bad to reveal your private key.</p>
<p>If you reveal your private key then someone else can authenticate to GitHub on your behalf. You don’t want that to happen, right? ;)</p>
<p>So, always make sure to keep your private key just to yourself.</p>
<h2 id="heading-wrapping-it-all-up">Wrapping it All Up</h2>
<p>If you have read this far, then Congratulations 🥳.</p>
<p>You’ve learned how SSH authentication actually works — when the signature was successfully verified by GitHub, it confirms to GitHub that it is we who are talking to it not an attacker.</p>
<p>Along the way you built a foundational understanding of symmetric key encryption, asymmetric key encryption, cryptographic hash functions and digital signatures.</p>
<p>Thanks for being with me on this one, I hope you are going away with some new and valuable learnings.</p>
<p>I put useful ideas and resources on my Twitter. <a target="_blank" href="https://twitter.com/vkwebdev"><strong>You should follow me there.</strong></a> I will respect your time.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use SSH to Safely Connect to GitHub: A Simple Guide for Windows OS ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we will explore the Secure Shell (SSH) protocol, a vital tool for securing network communications. SSH is widely used for accessing remote servers and managing code repositories securely, particularly in environments like GitHub. You... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-ssh-to-connect-to-github-guide-for-windows/</link>
                <guid isPermaLink="false">66f6c252eda714770c805738</guid>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                    <category>
                        <![CDATA[ networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Beginner Developers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Programming Blogs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oghenekparobo Stephen ]]>
                </dc:creator>
                <pubDate>Fri, 27 Sep 2024 14:33:54 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727226065318/c1522ad1-df49-4bc9-aa31-567d4012585a.avif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we will explore the Secure Shell (SSH) protocol, a vital tool for securing network communications.</p>
<p>SSH is widely used for accessing remote servers and managing code repositories securely, particularly in environments like GitHub. You’ll learn about the fundamental concepts of SSH, how it works, and practical steps to set it up on Windows. We will cover everything from generating SSH keys to testing your connection and cloning repositories.</p>
<p>By the end of this guide, you will have a solid understanding of SSH and be equipped to enhance your workflow with secure connections.</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-is-ssh">What is SSH?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-does-the-secure-shell-protocol-work">How Does the Secure Shell Protocol Work?</a></p>
</li>
</ol>
<ul>
<li><p><a class="post-section-overview" href="#heading-tcpip">TCP/IP</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-ssh-connection-process">The SSH Connection Process</a></p>
</li>
</ul>
<ol start="3">
<li><a class="post-section-overview" href="#heading-how-to-use-ssh-in-windows">How to Use SSH in Windows</a></li>
</ol>
<ul>
<li><p><a class="post-section-overview" href="#heading-windows-powershell-or-command-prompt">Windows PowerShell or Command Prompt</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-windows-subsystem-for-linux-wsl">Windows Subsystem for Linux (WSL)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-third-party-ssh-clients-for-example-putty">Third-Party SSH Clients (for example, PuTTY)</a></p>
</li>
</ul>
<ol start="4">
<li><a class="post-section-overview" href="#heading-how-to-use-ssh-in-windows-to-connect-to-github">How to Use SSH In Windows To Connect To GitHub</a></li>
</ol>
<ul>
<li><p><a class="post-section-overview" href="#heading-install-through-windows-optional-features">Install Through Windows Optional Features</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-download-and-install-from-github">Download And Install From Github</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-generate-ssh-keys">How To Generate SSH Keys</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-add-the-public-key-to-github">How To Add The Public Key To GitHub</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-the-ssh-connection">Testing The SSH Connection</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cloning-a-repository-using-ssh">Cloning A Repository Using SSH</a></p>
</li>
</ul>
<ol start="5">
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>Before you begin this tutorial, ensure you have the following:</p>
<ul>
<li><p><strong>Basic Understanding of Command Line</strong>: You should be familiar with using the command line interface (CLI) on Windows, including how to open PowerShell or Command Prompt.</p>
</li>
<li><p><strong>Windows Operating System</strong>: This tutorial is specifically tailored for users running Windows 10 or later versions.</p>
</li>
<li><p><strong>OpenSSH Client Installed</strong>: Ensure that you have the OpenSSH client installed on your system. You can check this by typing <code>ssh</code> in your command line interface.</p>
</li>
<li><p><strong>GitHub Account</strong>: You’ll need a GitHub for testing SSH connections and managing repositories.</p>
</li>
<li><p><strong>Text Editor</strong>: You’ll also need a code editor (like Visual Studio Code, Notepad++, or similar) to edit configuration files if needed.</p>
</li>
</ul>
<h1 id="heading-what-is-ssh">What is SSH?</h1>
<p><strong>SSH</strong> stands for secure shell (protocol). The secure shell protocol is a cryptographic network protocol for operating network services securely over an unsecured network.</p>
<p>In simpler terms, <strong>SSH</strong> is a way to safely use services on a network, like accessing a remote computer, even when the network itself isn’t fully secure. It protects your data and communications by scrambling (encrypting) everything, so no one can eavesdrop or tamper with it, even if they intercept it.</p>
<p>This is especially useful when connecting to services like GitHub, where you want to securely manage code on a remote server.</p>
<h3 id="heading-how-does-the-secure-shell-protocol-work">How Does The Secure Shell Protocol Work?</h3>
<p>SSH runs on the <a target="_blank" href="https://www.freecodecamp.org/news/what-is-tcp-ip-layers-and-protocols-explained/">TCP/IP set of rules</a> that computers use to communicate over the internet.</p>
<h3 id="heading-tcpip">TCP/IP</h3>
<p><strong>TCP</strong> stands for <strong>Transmission Control Protocol</strong>. It’s one of the core protocols in the <strong>TCP/IP suite</strong>, which is used to send data over the internet. The <strong>IP</strong> stands for <strong>Internet Protocol</strong>. It's part of the TCP/IP set of rules also, and its job is to guide packets of data to the right destination on the internet.</p>
<p>You can read more about the TCP/IP protocol <a target="_blank" href="https://www.cloudflare.com/learning/ddos/glossary/tcp-ip/">here</a> if you’d like to go deeper.</p>
<h3 id="heading-the-ssh-connection-process">The SSH Connection Process</h3>
<p>The <strong>Secure Shell protocol</strong> operates by establishing a secure connection between a client (your local machine) and a remote server.</p>
<p>First, the client initiates the connection by specifying the server's address (IP or domain) and login credentials. During the authentication phase, the server verifies the identity of the client, typically using a password or, more securely, SSH keys. These are a pair consisting of a private key stored on the client and a public key on the server.</p>
<p>Once authenticated, SSH encrypts all data transferred between the client and the server, ensuring confidentiality and integrity. This secure channel allows the client to execute commands, transfer files, and manage the server remotely as if physically present while safeguarding the data from potential interception or tampering.</p>
<p><strong>IP</strong> is responsible for addressing and routing the initial connection request from the client to the server. It ensures that the request, which includes the server's address, is sent to the correct destination.</p>
<p>Once the SSH connection request reaches the server, <strong>TCP</strong> establishes a reliable communication channel. It manages data transmission between the client and the server, ensuring that all packets are delivered accurately and in the correct order.</p>
<p>During the SSH session, <strong>TCP</strong> ensures that data <a target="_blank" href="https://www.cloudflare.com/learning/network-layer/what-is-a-packet/">packets</a> are correctly transmitted and reassembled, while <strong>IP</strong> handles the addressing. SSH then uses this secure and reliable channel to authenticate the client, encrypt all transferred data, and maintain a secure connection. This allows remote management and file transfer with confidentiality and integrity.</p>
<h2 id="heading-how-to-use-ssh-in-windows">How to Use SSH in Windows</h2>
<p>Windows provides a few different ways to use SSH:</p>
<h3 id="heading-windows-powershell-or-command-prompt"><strong>Windows PowerShell or Command Prompt</strong></h3>
<p>Windows comes with a built-in OpenSSH client. You can access this by opening PowerShell or Command Prompt and typing <code>ssh</code> This method is simple and requires no additional software.</p>
<h3 id="heading-windows-subsystem-for-linux-wsl"><strong>Windows Subsystem for Linux (WSL)</strong></h3>
<p>You can enable Windows Subsystem for Linux to run a Linux distribution directly on your Windows PC. Many Linux distros come with OpenSSH pre-installed, allowing you to use <code>ssh</code> commands from the Linux terminal. This method is great if you prefer a Linux-like environment.</p>
<h3 id="heading-third-party-ssh-clients-for-example-putty"><strong>Third-Party SSH Clients (for example, PuTTY)</strong></h3>
<p>If you prefer a standalone application, tools like PuTTY offer a graphical interface to manage SSH connections. PuTTY is widely used for connecting to servers and supports advanced options like saving connection profiles.</p>
<p>Windows 10 and later versions come with a native OpenSSH client, which allows you to securely connect to remote systems over an SSH (Secure Shell) connection.</p>
<h2 id="heading-how-to-use-ssh-in-windows-to-connect-to-github">How to Use SSH in Windows to Connect to GitHub</h2>
<p>If you're using Windows 10 or a later version, you can take advantage of the built-in SSH capabilities.</p>
<p>To get started, open your Windows Terminal or PowerShell, preferably as an administrator. In the command line interface, you can check if SSH is installed by typing the command <code>ssh</code>. This will confirm if the SSH client is available on your system.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727215416889/9985624e-ffe6-4aff-9e58-2fe3e6b36f26.png" alt="ssh cli command result, in this case a positive one that ssh is installed on the system" class="image--center mx-auto" width="620" height="157" loading="lazy"></p>
<p>If you got the above image, it means SSH is available on your local system.</p>
<p>The first thing you'll need to set up an SSH connection is a pair of SSH keys – a public key and a private key. These are typically located in the <code>.ssh</code> directory in your home directory if generated already.</p>
<p>On Windows, your home directory is usually <code>C:\Users\owner\.ssh</code>. This is where you will find your SSH key files if they've already been generated.</p>
<p>You can easily install OpenSSH on your Windows system. There are a couple of ways to do this:</p>
<h3 id="heading-install-through-windows-optional-features">Install Through Windows Optional Features</h3>
<ol>
<li><p>Open the Windows Start menu and type "optional features" in the search bar.</p>
</li>
<li><p>Click on "Add or remove Windows optional features" to open the Optional Features window.</p>
</li>
<li><p>In the Optional Features window, scroll down and find the "OpenSSH Client" option.</p>
</li>
<li><p>Check the box next to it and click the "Install" button at the bottom to install the OpenSSH client.</p>
</li>
</ol>
<h3 id="heading-download-and-install-from-github">Download and Install from GitHub</h3>
<ol>
<li><p>Visit the GitHub repository for the Win32-OpenSSH (32-bit) or Win64-OpenSSH (64-bit) release, depending on your Windows version:</p>
<ul>
<li><p>32-bit: <a target="_blank" href="https://github.com/PowerShell/Win32-OpenShell/releases">https://github.com/PowerShell/Win32-OpenShell/releases</a></p>
</li>
<li><p>64-bit: <a target="_blank" href="https://github.com/PowerShell/Win64-OpenShell/releases">https://github.com/PowerShell/Win64-OpenShell/releases</a></p>
</li>
</ul>
</li>
<li><p>Download the latest .msi installer file that matches your Windows architecture.</p>
</li>
<li><p>Run the .msi installer to install the OpenSSH client on your system.</p>
</li>
</ol>
<p>After installing OpenSSH, you can now generate SSH keys by opening the Windows Terminal or PowerShell and running the <code>ssh-keygen</code> command. This will walk you through the process of creating a new public-private key pair that you can use to authenticate your SSH connections, such as to your GitHub account.</p>
<p>The public key can then be added to your GitHub account settings, allowing you to connect to your repositories using the SSH protocol instead of HTTPS. Remember to keep your private key safe and secure, as it provides access to your GitHub account.</p>
<p>By installing OpenSSH, you've set up the necessary foundation to work with SSH keys and establish secure connections to remote systems and services like GitHub.</p>
<p>Now you can check if the OpenSSH server is running by accessing the Windows Services utility. To do this, press the Windows key + R to open the Run dialog, then input "services.msc" and press Enter. This will open the services manager.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727217366905/348ece20-432c-443e-951c-5c61ae4c7b94.png" alt="a windows prompt, generated by clicking &quot;windows + r&quot;" class="image--center mx-auto" width="395" height="197" loading="lazy"></p>
<p>The services manager:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727217489636/dffca024-3cb2-4b2b-8a03-fb4a2b5cc629.png" alt="The services manager generated after clicking &quot;windows + r&quot;" class="image--center mx-auto" width="796" height="563" loading="lazy"></p>
<p>Scroll and look for the openSSH SSH server:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727217823859/accbf838-e6cb-491a-ad1a-affa0dd59230.png" alt="this is image indicates that openSSH server is runing in the system, automatically as far as the system is powered on " class="image--center mx-auto" width="451" height="19" loading="lazy"></p>
<p>If the OpenSSH Server service is running in the Services window, it means that the OpenSSH server component is properly set up on your Windows system. This is an important first step in enabling secure SSH connections.</p>
<p>To ensure the OpenSSH server starts automatically whenever your PC is turned on, you can further configure the service's startup type. In the Services window, right-click on the "OpenSSH Server" service and select "Properties."</p>
<p>In the service properties, look for the "Startup type" dropdown and select "Automatic." This will ensure the OpenSSH Server service starts up automatically whenever your computer is powered on, rather than requiring you to manually start it each time.</p>
<p>By setting the OpenSSH Server service to start automatically, you can be confident that the server will be ready to accept incoming SSH connections at all times, without needing to remember to start it manually. This streamlines the process of using SSH-based authentication and remote access on your Windows machine.</p>
<p>Remember, having the OpenSSH Server service running and set to start automatically is just the first step. You'll still need to generate SSH keys and configure your GitHub account (or other services) to use the public key for authentication. But this initial setup of the OpenSSH server lays the foundation for seamless SSH usage going forward.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727218121688/a902b304-8103-49a5-8852-7094b4f70d5a.png" alt="opened the openSSH on the services manager" class="image--center mx-auto" width="901" height="584" loading="lazy"></p>
<p>Now that you've confirmed the OpenSSH Server is running on your Windows system, the next step is to ensure it can communicate through the Windows Firewall. The easiest way to do this is by using a PowerShell command.</p>
<p>Open PowerShell as an administrator and run the following command:</p>
<pre><code class="lang-plaintext">New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH SSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 -Program "C:\Program Files\OpenSSH\sshd.exe"
</code></pre>
<p>This PowerShell command will create a new firewall rule that allows inbound TCP traffic on port 22 (the default SSH port) for the OpenSSH Server executable located at "C:\Program Files\OpenSSH\sshd.exe".</p>
<p>Here's a breakdown of the different parameters used in the command:</p>
<ul>
<li><p><code>-Name sshd</code>: Assigns the name "sshd" to the new firewall rule.</p>
</li>
<li><p><code>-DisplayName 'OpenSSH SSH Server'</code>: Provides a descriptive display name for the rule.</p>
</li>
<li><p><code>-Enabled True</code>: Ensures the rule is active and enabled.</p>
</li>
<li><p><code>-Direction Inbound</code>: Specifies that the rule applies to inbound network traffic.</p>
</li>
<li><p><code>-Protocol TCP</code>: Configures the rule to allow TCP protocol connections.</p>
</li>
<li><p><code>-Action Allow</code>: Instructs the firewall to allow the specified traffic.</p>
</li>
<li><p><code>-LocalPort 22</code>: Sets the local port to 22, which is the default SSH port.</p>
</li>
<li><p><code>-Program "C:\Program Files\OpenSSH\sshd.exe"</code>: Identifies the specific program (the OpenSSH Server executable) that the rule should apply to.</p>
</li>
</ul>
<p>By running this PowerShell command, you're creating a dedicated firewall rule that permits the OpenSSH Server to communicate through the Windows Firewall, enabling you to establish secure SSH connections to your system.</p>
<p>Remember, it's always a good practice to review your firewall settings periodically, especially if you make changes to your network configuration or want to refine access to the OpenSSH Server further.</p>
<p>If successful, you should get this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727219301264/fb58d5ce-f8cf-49d2-9b56-6f1571c08652.png" alt=" dedicated firewall rule that permits the OpenSSH Server to communicate through the Windows Firewall" class="image--center mx-auto" width="1364" height="435" loading="lazy"></p>
<h4 id="heading-summary-of-the-above-cli-response">Summary of the above CLI response:</h4>
<ul>
<li><p><strong>Rule Name</strong>: sshd</p>
</li>
<li><p><strong>Display Name</strong>: OpenSSH SSH Server</p>
</li>
<li><p><strong>Direction</strong>: Inbound</p>
</li>
<li><p><strong>Action</strong>: Allow</p>
</li>
<li><p><strong>Enabled</strong>: True</p>
</li>
<li><p><strong>Profile</strong>: Any</p>
</li>
</ul>
<p>The rule is designed to allow inbound traffic, enabling external clients to connect to the server. The "Enabled" status confirms that the rule is currently active, while the "Profile" set to "Any" indicates that it applies to all network types, including public, private, and domain.</p>
<h4 id="heading-security-policies">Security Policies:</h4>
<ul>
<li><p><strong>Edge Traversal Policy</strong>: Block</p>
</li>
<li><p><strong>Loose Source Mapping</strong>: False</p>
</li>
<li><p><strong>Local Only Mapping</strong>: False</p>
</li>
</ul>
<p>The "EdgeTraversalPolicy" is configured to "Block," preventing traffic from traversing the network boundary, specifically disallowing connections from public networks to private ones. This helps enhance security by mitigating potential vulnerabilities.</p>
<p>The settings for "LooseSourceMapping" and "LocalOnlyMapping" are both set to false, ensuring that only direct connections are allowed without additional mapping.</p>
<h4 id="heading-status-and-enforcement">Status and Enforcement:</h4>
<ul>
<li><p><strong>Primary Status</strong>: OK</p>
</li>
<li><p><strong>Status</strong>: The rule was parsed successfully from the store.</p>
</li>
<li><p><strong>Enforcement Status</strong>: NotApplicable</p>
</li>
<li><p><strong>Policy Store Source</strong>: PersistentStore</p>
</li>
<li><p><strong>Policy Store Source Type</strong>: Local</p>
</li>
</ul>
<p>The "Status" field confirms that the rule has been successfully parsed from the policy store, indicating no configuration issues. The "EnforcementStatus" marked as "NotApplicable" suggests there are no restrictions that would prevent the rule from being enforced.</p>
<p>Remember, to set up an SSH connection we need a pair of SSH keys – a public key and a private key. Let’s see how to do that now.</p>
<h3 id="heading-how-to-generate-ssh-keys">How to Generate SSH Keys</h3>
<ul>
<li><p>Open your Windows Terminal or PowerShell.</p>
</li>
<li><p>Run the command <code>ssh-keygen</code> to generate a new SSH key pair.</p>
</li>
<li><p>Follow the prompts to specify the save location and passphrase (optional) for your keys.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727220068539/7ee02096-da9e-4a26-8da8-106ec2dcefee.png" alt="cli command for generating ssh keys and its response" class="image--center mx-auto" width="698" height="362" loading="lazy"></p>
<p>You will get what you see in the above image if you’re successful.</p>
<p>The public key will be saved as <code>id_</code><a target="_blank" href="http://rsa.pub"><code>rsa.pub</code></a> in the <code>.ssh</code> directory of your user's home folder (for example, <code>C:\Users\you\.ssh\id_</code><a target="_blank" href="http://rsa.pub"><code>rsa.pub</code></a>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727220167279/b04fed4a-17d1-49e6-ad34-d5cb41692d13.png" alt="viewing the private and public ky oon our local system in our home-directory/.ssh" class="image--center mx-auto" width="766" height="171" loading="lazy"></p>
<h3 id="heading-how-to-add-the-public-key-to-github">How to Add the Public Key to GitHub</h3>
<ul>
<li><p>Log in to your GitHub account and go to your account settings.</p>
</li>
<li><p>Navigate to the "SSH and GPG keys" section.</p>
</li>
<li><p>Click on the "New SSH key" button. Give your key a descriptive title, and then copy the contents of the <code>id_</code><a target="_blank" href="http://rsa.pub"><code>rsa.pub</code></a> file (your public key) into the "Key" field.</p>
</li>
<li><p>Click "Add SSH key" to save the new key.</p>
</li>
</ul>
<h3 id="heading-testing-the-ssh-connection">Testing the SSH Connection</h3>
<p>In your Windows Terminal or PowerShell, execute the following command to test your SSH connection to GitHub:</p>
<pre><code class="lang-plaintext">bashCopy codessh -T git@github.com
</code></pre>
<p>If prompted, enter your passphrase if you set one during the key generation process. If you did not set a passphrase, simply type "yes" when asked for a response to the handshake.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727220975104/6ed54e15-00a9-4cad-b95e-3424be855596.png" alt="6ed54e15-00a9-4cad-b95e-3424be855596" class="image--center mx-auto" width="680" height="93" loading="lazy"></p>
<p>If the connection is successful, you should see a message like "Hi username! You've successfully authenticated, but GitHub does not provide shell access."</p>
<p>You can solve this by following the process <a target="_blank" href="https://gist.github.com/bsara/5c4d90db3016814a3d2fe38d314f9c23">here</a>.</p>
<h3 id="heading-cloning-a-repository-using-ssh">Cloning a Repository Using SSH</h3>
<p>Navigate to one of your GitHub repositories and copy the SSH clone URL, which typically starts with <a target="_blank" href="mailto:git@github.com"><code>git@github.com</code></a>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727222441040/926444a1-bdf8-4f33-980c-0c2c87691a6b.png" alt="ssh link to clone a github repo" class="image--center mx-auto" width="208" height="135" loading="lazy"></p>
<p>In your local terminal, run the command <code>git clone</code> <a target="_blank" href="mailto:git@github.com"><code>git@github.com</code></a><code>:username/repository.git</code> to clone the repository using the SSH protocol.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You now have SSH working between your Windows computer and your GitHub account. This means you can work with your GitHub projects more easily and securely.</p>
<h3 id="heading-why-ssh-is-cool">Why SSH is Cool:</h3>
<ol>
<li><p>It's super secure. SSH scrambles your data so others can't snoop on it.</p>
</li>
<li><p>It's convenient. No more typing passwords all the time!</p>
</li>
<li><p>It's flexible. You can use it for more than just GitHub.</p>
</li>
<li><p>You can have different "keys" for different projects.</p>
</li>
<li><p>It works well with automatic coding tools.</p>
</li>
</ol>
<p>But it’s not perfect:</p>
<ol>
<li><p>Keeping track of many SSH keys can be a headache.</p>
</li>
<li><p>If someone gets your private key, they could access your stuff.</p>
</li>
<li><p>Setting it up the first time can be tricky.</p>
</li>
<li><p>You need to remember to change your keys yourself for extra safety.</p>
</li>
<li><p>Some networks might block SSH, which can be annoying.</p>
</li>
</ol>
<p>Remember to keep your private SSH key safe. It's like a special password for your GitHub account, so guard it well.</p>
<p>Even with these small downsides, SSH is still awesome for most coders. You are now all set to work on your GitHub projects more easily and safely. Have fun with your improved coding setup, and keep learning about ways to keep your work secure.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is SSH? SSH Meaning in Linux ]]>
                </title>
                <description>
                    <![CDATA[ By Shittu Olumide Secure Shell (SSH) is a widely used network protocol that provides a secure way to access remote servers and computers.  In Linux, SSH is an essential tool for remote administration and file transfer. In this article, we will go ove... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/ssh-meaning-in-linux/</link>
                <guid isPermaLink="false">66d461413bc3ab877dae2243</guid>
                
                    <category>
                        <![CDATA[ computer network ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 02 May 2023 13:29:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/Shittu-Olumide-What-is-SSH-SSH-Meaning-in-Linux.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Shittu Olumide</p>
<p>Secure Shell (SSH) is a widely used network protocol that provides a secure way to access remote servers and computers. </p>
<p>In Linux, SSH is an essential tool for remote administration and file transfer. In this article, we will go over the meaning of SSH in Linux, its history, features, configuration, and use cases.</p>
<h2 id="heading-what-is-ssh">What is SSH?</h2>
<p>SSH is a cryptographic network protocol that allows secure communication between networked devices. It was developed as a replacement for <a target="_blank" href="https://en.wikipedia.org/wiki/Telnet">Telnet</a>, which sends all data, including passwords, in clear text, making it susceptible to eavesdropping and interception. </p>
<p>SSH provides encryption and authentication mechanisms to protect the confidentiality and integrity of network communications.</p>
<h2 id="heading-brief-history-of-ssh">Brief History of SSH</h2>
<p>The first version of SSH, SSH-1, was developed by <a target="_blank" href="https://www.usenix.org/conference/lisa13/speaker-or-organizer/tatu-yl%C3%B6nen-ssh-communications-security">Tatu Ylönen in 1995</a> as a response to the insecurity of Telnet and FTP. </p>
<p>In 1996, SSH Communications Security released a commercial version of SSH-1, which became widely used in the industry. </p>
<p>But SSH-1 had some security vulnerabilities, and in 1998, Ylönen developed SSH-2, which addressed these issues and became the most widely used version of SSH.</p>
<h2 id="heading-how-ssh-works">How SSH Works</h2>
<p>SSH uses a client-server architecture, where the client initiates a connection to the server and requests a secure communication channel. The server responds by generating a pair of cryptographic keys, one public and one private.</p>
<p>The public key is sent to the client, while the private key is kept securely on the server. The client then encrypts a random session key using the server's public key and sends it back to the server. The server decrypts the session key using its private key and sends an acknowledgement to the client. From this point on, all data transmitted between the client and server is encrypted using the session key.</p>
<h2 id="heading-ssh-features">SSH Features</h2>
<ul>
<li><strong>Encryption</strong>: SSH uses strong encryption algorithms, such as AES, to protect the confidentiality and integrity of data transmitted over the network.</li>
<li><strong>Secure file transfer</strong>: It provides secure file transfer (SFTP) capabilities, which allow users to transfer files between remote servers securely.</li>
<li><strong>Remote login</strong>: SSH provides a secure way to login to remote servers and computers, without exposing login credentials to attackers.</li>
<li><strong>Port forwarding</strong>: It provides port forwarding capabilities, which allow users to access restricted services on remote servers through a secure communication channel.</li>
<li><strong>X11 forwarding</strong>: SSH provides X11 forwarding capabilities, which allow users to run graphical applications remotely, without having to install them locally.</li>
<li><strong>Agent forwarding</strong>: It also provides agent forwarding capabilities, which allow users to use SSH keys for authentication on remote servers, without having to enter their password every time.</li>
</ul>
<h2 id="heading-ssh-configuration">SSH Configuration</h2>
<p>SSH configuration involves various settings and options that can be customized to optimize the SSH connection and improve security. Here are some common SSH configuration tasks:</p>
<ul>
<li><strong>Generating SSH keys</strong>: Before using SSH, users must generate a pair of cryptographic keys, one public and one private. The public key is shared with the server, while the private key is kept securely on the user's computer.</li>
<li><strong>Editing configuration files</strong>: Users can create and edit SSH configuration files to customize their SSH settings, such as specifying the preferred encryption algorithm or setting up port forwarding. The SSH configuration files are usually located in the <code>/etc/ssh/</code> directory.</li>
<li><strong>Authentication methods</strong>: SSH supports various authentication methods, such as password authentication, public key authentication, and multi-factor authentication. Users can choose the most suitable authentication method based on their security needs.</li>
<li><strong>Secure SSH configuration</strong>: To ensure maximum security, users should follow best practices for secure SSH configuration, such as disabling root login, enforcing strong passwords, and limiting the number of failed login attempts. Users can also use tools like Fail2Ban to prevent brute-force attacks on SSH.</li>
<li><strong>Enabling X11 forwarding</strong>: SSH provides X11 forwarding capabilities, which allow users to run graphical applications remotely, without having to install them locally. To enable X11 forwarding, users can add the -X or -Y flag when connecting to the remote server.</li>
<li><strong>Port forwarding</strong>: SSH allows users to set up port forwarding, which can be useful for accessing restricted services on remote servers through a secure communication channel. Users can set up local or remote port forwarding, depending on their needs.</li>
<li><strong>Compression</strong>: SSH supports data compression, which can improve the performance of the SSH connection, especially when transferring large files or running resource-intensive applications. Users can enable compression by adding the <code>-C</code> flag when connecting to the remote server.</li>
</ul>
<h2 id="heading-ssh-examples-and-use-cases">SSH Examples and Use Cases</h2>
<ul>
<li><strong>Remote server administration</strong>: SSH is commonly used for remote server administration, allowing users to execute commands and manage servers from a remote location.</li>
<li><strong>Secure file transfer</strong>: provides a secure way to transfer files between remote servers, without exposing the files or login credentials to attackers.</li>
<li><strong>Running graphical applications remotely</strong>: allows users to run graphical applications remotely, without having to install them locally, which can be useful for resource-intensive applications or when using a low-power device.</li>
<li><strong>Port forwarding for accessing restricted services</strong>: allows users to access restricted services on remote servers through a secure communication channel, by setting up port forwarding.</li>
<li><strong>Tunneling for secure communication</strong>: SSH allows users to set up encrypted tunnels for secure communication between two networked devices, which can be useful for accessing resources on a private network.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>To end this article, here's a recap of what we covered and what you should know about SSH:</p>
<ul>
<li>SSH is a secure protocol for remote communication in Linux.</li>
<li>SSH uses encryption to protect data and authentication mechanisms to verify users.</li>
<li>SSH is a reliable and efficient way to communicate securely over the internet, and is a vital tool for Linux system administration and development.</li>
<li>SSH provides remote login, secure file transfer, port forwarding, X11 forwarding, and agent forwarding capabilities.</li>
<li>To use SSH, users must generate a pair of cryptographic keys, one public and one private.</li>
<li>SSH configuration files can be customized to optimize the SSH connection and improve security.</li>
<li>SSH supports various authentication methods, such as password authentication, public key authentication, and multi-factor authentication.</li>
<li>To ensure maximum security, users should follow best practices for secure SSH configuration, such as disabling root login, enforcing strong passwords, and limiting the number of failed login attempts.</li>
<li>SSH can be used for remote server administration, secure file transfer, running graphical applications remotely, port forwarding, and tunneling for secure communication.</li>
<li>SSH is a widely used and supported protocol, with many SSH clients and servers available for different platforms.</li>
</ul>
<p>Let's connect on <a target="_blank" href="https://www.twitter.com/Shittu_Olumide_">Twitter</a> and on <a target="_blank" href="https://www.linkedin.com/in/olumide-shittu">LinkedIn</a>. You can also subscribe to my <a target="_blank" href="https://www.youtube.com/channel/UCNhFxpk6hGt5uMCKXq0Jl8A">YouTube</a> channel.</p>
<p>Happy Coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ SSH Keygen Tutorial – How to Generate an SSH Public Key for RSA Login ]]>
                </title>
                <description>
                    <![CDATA[ Cryptography uses encryption and decryption to conceal messages. This introduces secrecy in information security. The purpose of cryptography is to ensure secure communication between two people or devices who are connecting through insecure channels... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/ssh-keygen-how-to-generate-an-ssh-public-key-for-rsa-login/</link>
                <guid isPermaLink="false">66d84e28ec0a9800d5b8e6b5</guid>
                
                    <category>
                        <![CDATA[ Cryptography ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ information security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Bolaji Ayodeji ]]>
                </dc:creator>
                <pubDate>Tue, 30 Aug 2022 15:51:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/08/article-banner.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Cryptography uses encryption and decryption to conceal messages. This introduces secrecy in information security.</p>
<p>The purpose of cryptography is to ensure secure communication between two people or devices who are connecting through insecure channels.</p>
<p>The sender often employs an encryption key to lock the message, while the recipient uses a decryption key to unlock the message.</p>
<p>In general, cryptography employs two strategies:</p>
<ol>
<li><p><strong>Symmetric-key Cryptography (Private key):</strong> With this technique, the encryption and decryption keys are both known to the sender and receiver. Some examples of algorithms that use this technique include One Time Pad cipher, Vernam cipher, Playfair, Row column cipher, and Data Encryption Standard (DES).</p>
</li>
<li><p><strong>Asymmetric Key Cryptography (Public key):</strong> With this technique, each person has two keys: the Private (secret and accessible to the creator) and Public keys (freely available to anyone). The sender and receiver use different keys for encryption and decryption. Some examples of algorithms that use this technique include the Rivest–Shamir–Adleman algorithm (RSA), Diffie - Hellman Key Exchange (DHE), and the Digital Signature Algorithm (DSA).</p>
</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/Cryptography--2-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The Encryption Model for Secured Data Transmission</em></p>
<p>Software engineers generally have to authenticate with servers or other services like GitHub for version control.</p>
<p>As opposed to using password authentication, they can use public key authentication to generate and store a pair of cryptographic keys on their computer. Then they can configure the server running on another computer to recognize and accept those keys.</p>
<p>This is the asymmetric key cryptography technique flow we discussed earlier and it is a more secure authentication process.</p>
<p>In this tutorial, you will learn how it all works, what SSH means, and how to generate SSH keys with an RSA algorithm using SSH keygen.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p>A working computer running on any operating system.</p>
</li>
<li><p>Basic knowledge of navigating around the command-line.</p>
</li>
<li><p>A smile on your face :)</p>
</li>
</ul>
<h2 id="heading-brief-introduction-to-ssh-secure-shell-protocol">Brief Introduction to SSH (<strong>S</strong>ecure <strong>Sh</strong>ell Protocol)</h2>
<p>Public key authentication using SSH is a more secure approach for logging into services than passwords. Understanding SSH is easier once you understand how cryptography works from the above intro.</p>
<p>Here's a helpful basic definition:</p>
<blockquote>
<p>"The <strong>S</strong>ecure <strong>Sh</strong>ell Protocol is a <strong>cryptographic network protocol</strong> for operating network services securely <strong>over an unsecured network</strong>." (<a target="_blank" href="https://en.wikipedia.org/wiki/Secure_Shell">Source</a>)</p>
</blockquote>
<p>SSH is used between a client and a server both running on the SSH protocol to remotely login into the server and access certain resources through the command line.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/image-197.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Source: SSH Academy</em></p>
<p>There is an open-source version of the SSH protocol (version 2) with a suite of tools called <a target="_blank" href="https://www.openssh.com">OpenSSH</a> (also known as OpenBSD Secure Shell). This project includes the following tools:</p>
<ul>
<li><p>Remote operations: <a target="_blank" href="https://man.openbsd.org/ssh.1">ssh</a>, <a target="_blank" href="https://man.openbsd.org/scp.1">scp</a>, and <a target="_blank" href="https://man.openbsd.org/sftp.1">sftp</a>.</p>
</li>
<li><p>Key generation: <a target="_blank" href="https://man.openbsd.org/ssh-add.1">ssh-add</a>, <a target="_blank" href="https://man.openbsd.org/ssh-keysign.8">ssh-keysign</a>, <a target="_blank" href="https://man.openbsd.org/ssh-keyscan.1">ssh-keyscan</a>, and <a target="_blank" href="https://man.openbsd.org/ssh-keygen.1"><strong>ssh-keygen</strong></a>.</p>
</li>
<li><p>Service side: <a target="_blank" href="https://man.openbsd.org/sshd.8">sshd</a>, <a target="_blank" href="https://man.openbsd.org/sftp-server.8">sftp-server</a>, and <a target="_blank" href="https://man.openbsd.org/ssh-agent.1">ssh-agent</a>.</p>
</li>
</ul>
<h2 id="heading-how-to-generate-an-ssh-public-key-for-rsa-login">How to Generate an SSH Public Key for RSA Login</h2>
<p>Our goal is to use ssh-keygen to generate an SSH public key using the RSA algorithm. This will create a key pair containing a private key (saved to your local computer) and a public key (uploaded to your chosen service).</p>
<p>Now to proceed, follow the steps below to achieve this:</p>
<ol>
<li>Install OpenSSH if you don't have it installed already using the command below:</li>
</ol>
<pre><code class="lang-python">// <span class="hljs-keyword">for</span> mac

brew install openssh

// <span class="hljs-keyword">for</span> linux

sudo apt install openssh-client &amp;&amp; sudo apt install openssh-server
</code></pre>
<ol start="2">
<li>Create a private/public key pair with an RSA algorithm (2046-bit encryption by default), using the command:</li>
</ol>
<pre><code class="lang-python">ssh-keygen -t rsa
</code></pre>
<ol start="3">
<li>Or, if you want to create with an RSA algorithm with 4096-bit encryption, use the command:</li>
</ol>
<pre><code class="lang-python">ssh-keygen -t rsa -b <span class="hljs-number">4096</span>
</code></pre>
<ol start="4">
<li><p>Enter a file location to save the key to (by default it will save to your users directory (for example, <code>(/Users/bolajiayodeji/.ssh/id_rsa)</code> ).</p>
</li>
<li><p>Enter a passphrase for extra security to your private key. Generally, a good passphrase should have at least 15 characters (including at least one upper case letter, lower case letters, numerical digits, and special characters) and must be difficult to guess. You can use one of those password generators online or use hexdump to generate a paraphrase easily like so:</p>
</li>
</ol>
<pre><code class="lang-python">hexdump -vn16 -e<span class="hljs-string">'4/4 "%08X" 1 "\n"'</span> /dev/urandom
</code></pre>
<ol start="6">
<li>Once you've successfully created your password, your private key will be saved in <code>/&lt;your_chosen_directory&gt;/.ssh/id_rsa</code> and your public key will be saved in <code>/&lt;your_chosen_directory&gt;/.ssh/id_rsa.pub</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/Screenshot-2022-08-30-at-1.18.15-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now you can copy the created key into the authorized_keys file of the server you want to connect to using ssh-copy-id (this tool is a part of openSSH) like so:</p>
<pre><code class="lang-python">ssh-copy-id username@remote_host
</code></pre>
<p>Alternatively, you'd want to add your SSH private key to the ssh-agent and store your passphrase in the keychain. You can then add the SHH key to your server's account via a dashboard UI or so (for example, using tools like Git or GitHub).</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Although a strong password helps prevent brute-force attacks, public key authentication provides a much more secure authentication process using cryptography.</p>
<p>I hope you found this article helpful. In addition, you can check out the <a target="_blank" href="https://man.openbsd.org/ssh-keygen.1">ssh-keygen manual page</a> and the following resources for further learning:</p>
<ul>
<li><p><a target="_blank" href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh">Connecting to GitHub with SSH</a></p>
</li>
<li><p><a target="_blank" href="https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse">Get started with OpenSSH for Windows</a></p>
</li>
</ul>
<p>Cheers! 💙</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to SSH into a Docker Container – Secure Shell vs Docker Attach ]]>
                </title>
                <description>
                    <![CDATA[ By Sebastian Sigl Containers are the bread and butter for running applications today. And the most popular container technology is called Docker.  Knowing how to SSH into a container is essential to using, debugging, and operating containers on your ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-ssh-into-a-docker-container-secure-shell-vs-docker-attach/</link>
                <guid isPermaLink="false">66d460fc3dce891ac3a9681e</guid>
                
                    <category>
                        <![CDATA[ Docker ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 24 Mar 2022 19:47:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/ssh-into-docker-container-image-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sebastian Sigl</p>
<p>Containers are the bread and butter for running applications today. And the most popular container technology is called <a target="_blank" href="https://www.docker.com/">Docker</a>. </p>
<p>Knowing how to SSH into a container is essential to using, debugging, and operating containers on your local operating system or remote setup. </p>
<p>This article will describe different methods for doing so along with their constraints.</p>
<h2 id="heading-method-1-attach-to-a-running-container-using-docker-exec">Method 1 – Attach to a Running Container using <code>docker exec</code></h2>
<p>The most common and helpful command for getting a shell in a container is <code>docker exec -it</code>. It runs a new command in the container, which allows you to start a new interactive shell:</p>
<pre><code class="lang-sh"><span class="hljs-comment"># start a container</span>
$ docker run --name nginx --rm -p 8080:80  -d nginx

<span class="hljs-comment"># create and connect to a bash shell in the container</span>
$ docker <span class="hljs-built_in">exec</span> -it nginx bash

root@a84ad71521b1:/<span class="hljs-comment">#</span>
</code></pre>
<p>You can exit the current shell by pressing <code>control + d</code> or typing <code>exit</code>.</p>
<p>It works because:</p>
<ul>
<li><code>docker exec</code> runs a new command,</li>
<li><code>-i</code> adds a stdin stream,</li>
<li><code>-t</code> adds a terminal driver,</li>
<li><code>-it</code> combines <code>-i</code> and <code>-t</code>, which allows you to interact with the process.</li>
</ul>
<p>‌‌It can happen that your container does not have bash installed. In case you can not start bash, you can try starting a <code>sh</code>-shell:</p>
<pre><code class="lang-sh">docker <span class="hljs-built_in">exec</span> -it nginx sh
</code></pre>
<p>‌‌Also, there might not be a shell installed in the container. Therefore, there is no way to get a shell in that container in a plain docker Universum and you can not start any shell.‌‌</p>
<p>Depending on your container orchestration tool, you might still be able to access the container. For example, <a target="_blank" href="https://github.com/GoogleContainerTools/distroless">distroless containers</a> are getting more popular to reduce the footprint of the container. If you use Kubernetes, an <a target="_blank" href="https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers/">ephemeral container</a> feature allows you to debug containers without a shell as well as crashed containers.</p>
<h2 id="heading-method-2-attach-to-a-running-container-using-docker-attach">Method 2 – Attach to a Running Container using <code>docker attach</code></h2>
<blockquote>
<p>The <code>docker attach</code> command attaches your terminal’s standard input, output, and error to a running container using the container’s id or name. (Source <a target="_blank" href="https://docs.docker.com/engine/reference/commandline/attach/">docker.com</a>)</p>
</blockquote>
<p>In practice, this means everything you enter gets forwarded to the container, and everything that is printed will be shown in your console.</p>
<p>Now, you attach to the running container:</p>
<pre><code class="lang-sh">$ docker attach nginx                              

172.17.0.1 - - [18/Mar/2022:08:37:14 +0000] <span class="hljs-string">"GET / HTTP/1.1"</span> 304 0 <span class="hljs-string">"-"</span> <span class="hljs-string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"</span> <span class="hljs-string">"-"</span>
</code></pre>
<p>While running this, you can open <a target="_blank" href="http://localhost:8080">http://localhost:8080</a>. Because the container prints access logs on each page opened, you will see the output in your terminal.</p>
<p>Additionally, input is forwarded as well to the container. So if you press <code>control + c</code>, which triggers a kill signal, your container will shut down.</p>
<pre><code class="lang-sh">$ docker attach nginx                              
172.17.0.1 - - [18/Mar/2022:08:37:14 +0000] <span class="hljs-string">"GET / HTTP/1.1"</span> 304 0 <span class="hljs-string">"-"</span> <span class="hljs-string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"</span> <span class="hljs-string">"-"</span>
^[[A^C2022/03/18 08:39:50 [notice] 1<span class="hljs-comment">#1: signal 2 (SIGINT) received, exiting</span>
2022/03/18 08:39:50 [notice] 32<span class="hljs-comment">#32: exiting</span>
</code></pre>
<p>Detaching can be tricky because <code>control + c</code> is also used for detaching. To be able to detach without stopping the container, you can attach to the container by disabling forwarding signals:</p>
<pre><code class="lang-sh"><span class="hljs-comment"># start the container again</span>
docker run --name nginx --rm -p 8080:80  -d nginx

<span class="hljs-comment"># attach with proxying signals</span>
docker attach --sig-proxy=<span class="hljs-literal">false</span> nginx
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>To connect to a container using plain docker commands, you can use <code>docker exec</code> and <code>docker attach</code>.</p>
<p><code>docker exec</code> is a lot more popular because you can run a new command that allows you to spawn a new shell. You can check processes, files and operate like in your local environment.</p>
<p><code>docker attach</code> is more restricted because it attaches your terminal’s standard input, output, and error to the main process of a running container.</p>
<p>I hope you enjoyed the article.</p>
<p>If you liked it and felt the need to give me a round of applause or just want to get in touch, <a target="_blank" href="https://twitter.com/sesigl">follow me on Twitter</a>.</p>
<p>I work at eBay Kleinanzeigen, one of the world’s biggest classified companies. By the way, <a target="_blank" href="https://jobs.ebayclassifiedsgroup.com/ebay-kleinanzeigen">we are hiring</a>!</p>
<h3 id="heading-references">References</h3>
<ul>
<li><a target="_blank" href="https://phoenixnap.com/kb/how-to-ssh-into-docker-container">How to SSH into a Running Docker Container and Run Commands</a></li>
<li><a target="_blank" href="https://www.cloudsavvyit.com/14226/how-to-detach-from-a-docker-container-without-stopping-it/#:~:text=Docker%20supports%20a%20keyboard%20combination,alive%2C%20keeping%20your%20container%20running.">How to Detach From a Docker Container Without Stopping It</a></li>
<li><a target="_blank" href="https://docs.docker.com/engine/reference/commandline/attach/">Docker attach documentation</a></li>
<li><a target="_blank" href="https://docs.docker.com/engine/reference/commandline/exec/">Docker exec documentation</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ RSync Examples – Rsync Options and How to Copy Files Over SSH ]]>
                </title>
                <description>
                    <![CDATA[ Rsync stands for “remote synchronization”. It is a remote and local file synchronization tool that helps you efficiently transfer files. What RSync Is Rsync is faster than tools like Secure Copy Protocol (SCP). It uses the delta-transfer algorithm th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/rsync-examples-rsync-options-and-how-to-copy-files-over-ssh/</link>
                <guid isPermaLink="false">66d0361812c679876b0602eb</guid>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Tue, 08 Sep 2020 20:54:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/09/rsync.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Rsync stands for “remote synchronization”. It is a remote and local file synchronization tool that helps you efficiently transfer files.</p>
<h2 id="heading-what-rsync-is">What RSync Is</h2>
<p>Rsync is faster than tools like <a target="_blank" href="https://www.geeksforgeeks.org/scp-command-in-linux-with-examples/">Secure Copy Protocol (SCP)</a>. It uses the <a target="_blank" href="https://www.dynamsoft.com/help/SAW%20Standalone/Getting%20Started/Delta%20Transfer.htm">delta-transfer</a> algorithm that minimizes the data transfer by copying only the sections of a file that have been updated.</p>
<p>Some of the additional features of Rsync include:</p>
<ul>
<li>Supports copying links, devices, owners, groups, and permissions</li>
<li>Does not require super-user privileges</li>
<li>Pipelines file transfers to <a target="_blank" href="https://whatis.techtarget.com/definition/latency">minimize latency costs</a></li>
</ul>
<p>You can only transfer files from local  to  remote or remote  to  local. Rsync does not support remote  to  remote file transfers.</p>
<h2 id="heading-how-rsync-works">How RSync Works</h2>
<p>Now that you know what Rsync is, let's look at how to work with it.</p>
<p>Rsync works similarly to other remote server management tools like SSH and SCP.</p>
<p>Here is the basic syntax of Rsync:</p>
<pre><code>rsync [options] source [destination]
</code></pre><p>Here is the syntax to transfer a file from your local system to a remote server. It is also called a “push” operation.</p>
<pre><code>rsync local_file_path user@remote-host:remote_file_path
</code></pre><p>Here's how to transfer a file from a remote server to your local system, also called a “pull” operation.</p>
<pre><code>rsync user@remote-host:remote_file_path local_file_path
</code></pre><blockquote>
<p>Note: When working with remote systems, make sure you have <a target="_blank" href="https://www.hostinger.in/tutorials/ssh-tutorial-how-does-ssh-work?__cf_chl_jschl_tk__=f550a12fdfece557e30dc21901117b432d5a8e1d-1599060891-0-AQrE-UcUtiSpJOvL7PClSP8WK3uhRkd2Va_WJS_Hr7mHzy4lylrjibVz-sFxPrqTOYzEL8kjWnc_WKPSFQq4_CGDfTHPmPF3uv3IBQyDJnHm3v_FHx9-6uH7IG663DhoKDAdMayU1_iN33sQ5fsuniN5ga8w33sjEXqwdW-0-dKQeXXGPN37aTbwu7NlmtFf8MGAvsqbs2NEFChJ2Mpi9qasX6dy0guXG446JenTxsOz_P3g9wzw1qv8hXZtfC7UOdR4s_guli8xDi_EOuzgNoYVRe2r2nRBQ3jNb0fzLwK5frAhmmbv6LClLgrF5r8NRYqxsBPD4FCXp8wvFo7agjs">SSH access to the remote system</a>. Rsync establishes the connection using SSH in order to enable file transfer.</p>
</blockquote>
<h2 id="heading-how-to-use-flags-in-rsync">How to Use Flags in RSync</h2>
<p>Rsync lets you add additional options via command-line flags. Let's look at a few useful flags.</p>
<h3 id="heading-recursive">Recursive</h3>
<p>If you add the <strong>-r</strong> option, RSync will execute a recursive file transfer. This is useful when working with directories. Here is an example:</p>
<pre><code>rsync -r user@remote-host:remote_directory/ local_directory
</code></pre><h3 id="heading-archive">Archive</h3>
<p>The <strong>-a</strong> flag is used to preserve <a target="_blank" href="https://www.geeksforgeeks.org/soft-hard-links-unixlinux/">symbolic links</a> while transferring files. The archive flag also preserves special and device files, modification times, and permissions from the source directory.</p>
<p>The archive flag also syncs files recursively, so it is used more than the recursive flag. Here is how you use it:</p>
<pre><code>rsync -a user@remote-host:remote_directory/ local_directory
</code></pre><h3 id="heading-compression">Compression</h3>
<p>You can also compress files using the <strong>-z</strong> flag. Compressing files can reduce network load and speed up file transfer. </p>
<pre><code>rsync -az user@remote-host:remote_directory/ local_directory
</code></pre><h3 id="heading-progress">Progress</h3>
<p>For large file transfers, it is useful to know the progress of the operation. You can use the <strong>-P</strong> flag to know the progress of the file transfer. With Rsync, you can also resume file transfers if they are interrupted. </p>
<pre><code>rsync -aP user@remote-host:remote_directory/ local_directory
</code></pre><h3 id="heading-verbose">Verbose</h3>
<p>Finally, the verbose command can help you understand every step of the file transfer. You can use the <strong>-v</strong> flag for this. </p>
<pre><code>rsync -av user@remote-host:remote_directory/ local_directory
</code></pre><p>You can also use the help command with RSnsc to get a list of all the options and flags. </p>
<pre><code>rsync --help
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2020/09/Screenshot-2020-09-02-at-9.07.47-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>rsync help</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Rsync simplifies the whole file transfer process by offering a robust, versatile, and flexible tool compared to alternatives like SCP. </p>
<p>RSync is great for maintenance operations, backups, and general file operations between local and remote machines.</p>
<h2 id="heading-references">References</h2>
<ul>
<li><a target="_blank" href="https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories-on-a-vps">https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories-on-a-vps</a></li>
<li><a target="_blank" href="https://linux.die.net/man/1/rsync">https://linux.die.net/man/1/rsync</a></li>
<li><a target="_blank" href="https://www.geeksforgeeks.org/rsync-command-in-linux-with-examples/">https://www.geeksforgeeks.org/rsync-command-in-linux-with-examples/</a></li>
</ul>
<p>I am <a target="_blank" href="https://www.manishmshiva.com/">Manish</a> and I write about Cybersecurity, Artificial Intelligence, and DevOps. If you liked this article, <a target="_blank" href="https://medium.com/manishmshiva">you can find my blog here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Manage Multiple SSH Keys ]]>
                </title>
                <description>
                    <![CDATA[ It is safe to say that most developers in the web sphere have at some point encountered SSH. SSH is one of the most used protocols for safe data exchange. You use SSH for connecting to remote servers, which also includes managing your code using Git ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-manage-multiple-ssh-keys/</link>
                <guid isPermaLink="false">66c35399b3da455a9c10dc15</guid>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 30 Jan 2020 21:46:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9d43740569d1a4ca36c9.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>It is safe to say that most developers in the web sphere have at some point encountered SSH. SSH is one of the most used protocols for safe data exchange. You use SSH for connecting to remote servers, which also includes managing your code using Git and syncing with remote repositories.</p>
<p>Even though it is considered a good practice to have one private-public key pair per device, sometimes you need to use multiple keys and/or you have unorthodox key names. </p>
<p>You might be using one SSH key-pair for working on your company’s internal projects but you might be using a different key for accessing some corporate client’s servers. You might even be using a different key for accessing your own private server.</p>
<p>Managing SSH keys can become cumbersome as soon as you need to use a second key. I hope this article will be of help to anyone who is having issues with SSH key management.</p>
<p>I assume the reader has basic knowledge of Git and SSH. Most examples throughout the article will be using Git. Of course, all of this will apply to any other SSH communication. That being said, there are some Git-specific tricks included.</p>
<p>Strap in, here we go!</p>
<h2 id="heading-dealing-with-one-ssh-key">Dealing with one SSH key</h2>
<p>First, let us see what your workflow might look like before having multiple keys to worry about.</p>
<p>You have one private key stored in <code>~/.ssh/id_rsa</code> with a corresponding public key <code>~/.ssh/id_rsa.pub</code>.</p>
<p>Let us imagine that you want to push/pull code changes to/from a remote Git server – say GitHub, why not. To do so, you first have to add your public key to GitHub. </p>
<p>I will not go over that step, it should be easy enough to find out how to do that. I have also assumed that your name is Steve and you are working on a top-secret project which uses Raspberry Pies to sniff network traffic.</p>
<p>To start your work, you have to clone a git repository using SSH:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> git@github.com:steve/raspberry-spy.git
</code></pre>
<p>At this moment GitHub will be like: “Yo, this a private repository! We need to encrypt traffic using this public key I have here and your private key.”</p>
<p>You have added the public key to your profile on GitHub, but SSH has to somehow figure out where your corresponding private key is located. </p>
<p>Since we have no clue which private key should be used when SSH-ing into <code>git@github.com</code>, SSH client tries to find a key in default location, which is <code>~/.ssh/id_rsa</code> - it’s his best guess. If there is no file in that location, you will get an error:</p>
<pre><code class="lang-bash">Cloning into <span class="hljs-string">'raspberry-spy'</span>...
Permission denied (publickey).
fatal: Could not <span class="hljs-built_in">read</span> from remote repository.

Please make sure you have the correct access rights
and the repository exists.
</code></pre>
<p>If you have <em>some</em> private key stored in file <code>~/.ssh/id_rsa</code>, SSH client will use that private key for communication encryption. If that key is passworded (as it should be), you will be prompted for a password, like so:</p>
<pre><code class="lang-bash">Enter passphrase <span class="hljs-keyword">for</span> key <span class="hljs-string">'/Users/steve/.ssh/id_rsa'</span>:
</code></pre>
<p>If you enter the correct passphrase and if that private key indeed is the one which corresponds to the public key which you attached to your profile, all will go fine and the repository will be cloned successfully.</p>
<p>But what if you named your key differently (ex. <code>~/.ssh/_id_rsa</code>)? SSH client will not be able to determine where the private key is stored. You will get the same <code>Permission denied ...</code> error as before.</p>
<p>If you want to use a private key that you named differently, you have to add it manually:</p>
<pre><code class="lang-bash">ssh-add ~/.ssh/_id_rsa
</code></pre>
<p>After entering the passphrase you can check if the key was added to <code>ssh-agent</code> (SSH client) by executing <code>ssh-add -l</code>. This command will list all keys which are currently available to the SSH client.</p>
<p>If you try cloning the repository now, it will be successful.</p>
<h2 id="heading-so-far-so-good"><strong>So far, so good?</strong></h2>
<p>If you are keen-eyed, you might start noticing some potential issues.</p>
<p>Firstly, if you restart your computer, <code>ssh-agent</code> will restart and you will have to add your not-default-named keys using <code>ssh-add</code> all over again, typing passwords and all that tedious stuff.</p>
<p>Can we automate adding keys or somehow specify which key to use when accessing certain servers?</p>
<p>Can we somehow save passwords so we don’t have to type them in every time? If only there was something like a <em>keychain</em> for saving password-protected SSH keys ?.</p>
<p>Rest assured, there are answers to all those questions.</p>
<h2 id="heading-enter-ssh-config"><strong>Enter, SSH <code>config</code></strong></h2>
<p>As it turns out, <a target="_blank" href="https://linux.die.net/man/5/ssh_config">SSH configuration file</a> is a thing, a thing which can help us out. It is a per-user configuration file for SSH communication. Create a new file: <code>~/.ssh/config</code> and open it for editing.</p>
<h3 id="heading-managing-custom-named-ssh-keys"><strong>Managing custom-named SSH keys</strong></h3>
<p>First thing we are going to solve using this <code>config</code> file is avoid having to add custom-named SSH keys using <code>ssh-add</code>. Assuming your SSH key is named <code>~/.ssh/_id_rsa</code>, add following to the <code>config</code> file:</p>
<pre><code class="lang-bash">Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/_id_rsa
  IdentitiesOnly yes
</code></pre>
<p>Now make sure that <code>~/.ssh/_id_rsa</code> is not in <code>ssh-agent</code> by executing <code>ssh-add -D</code>. This command will remove all keys from currently active <code>ssh-agent</code> session. The session gets reset every time you log out or reboot (or if you kill <code>ssh-agent</code> process manually). We can “simulate” rebooting by executing the mentioned command.</p>
<p>If you try cloning your GitHub repository now, it will be the same as if we added the key manually (like we did before). You will be asked for password:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> git@github.com:steve/raspberry-spy.git
Cloning into <span class="hljs-string">'raspberry-spy'</span>...
Enter passphrase <span class="hljs-keyword">for</span> key <span class="hljs-string">'/Users/steve/.ssh/_id_rsa'</span>:
</code></pre>
<p>You will have noticed that the key for whose password we are prompted for is the same key which we specified in our <code>config</code> file. After entering the correct SSH key password, repository will be successfully cloned.</p>
<p>Note: if, after successful cloning, you try <code>git pull</code>, you will be prompted for password again. We will solve that later.</p>
<p>It is important that <code>Host github.com</code> from <code>config</code> and <code>github.com</code> from URI <code>git@github.com:steve/raspberry-spy.git</code> match. You can also change <code>config</code> to be <code>Host mygithub</code> and clone using URI <code>git@mygithub:steve/raspberry-spy.git</code>.</p>
<p>This opens the floodgates. As you are reding this, your mind is racing and thinking about how all your troubles with SSH keys are over. Here are some useful configuration examples:</p>
<pre><code class="lang-bash">Host bitbucket-corporate
        HostName bitbucket.org
        User git
        IdentityFile ~/.ssh/id_rsa_corp
        IdentitiesOnly yes
</code></pre>
<p>Now you can use <code>git clone git@bitbucket-corporate:company/project.git</code></p>
<pre><code class="lang-bash">Host bitbucket-personal
        HostName bitbucket.org
        User git
        IdentityFile ~/.ssh/id_rsa_personal
        IdentitiesOnly yes
</code></pre>
<p>Now you can use <code>git clone git@bitbucket-personal:steve/other-pi-project.git</code></p>
<pre><code class="lang-text">Host myserver
        HostName ssh.steve.com
        Port 1111
        IdentityFile ~/.ssh/id_rsa_personal
        IdentitiesOnly yes
        User steve
        IdentitiesOnly yes
</code></pre>
<p>Now you can SSH into your server using <code>ssh myserver</code>. How cool is that? You do not need to enter port and username manually every time you execute <code>ssh</code> command.</p>
<h3 id="heading-bonus-per-repository-settings">Bonus: Per-repository settings</h3>
<p>You can also define which specific key should be used for certain repository, overriding anything in SSH <code>config</code>. Specific SSH command can be defined by setting <code>sshCommand</code> under <code>core</code> in <code>&lt;project&gt;/.git/config</code>. Example:</p>
<pre><code class="lang-bash">[core]
        sshCommand = ssh -i ~/.ssh/id_rsa_corp
</code></pre>
<p>This is possible with git 2.10 or later. You can also use this command to avoid editing the file manually:</p>
<pre><code class="lang-bash">git config core.sshCommand <span class="hljs-string">'ssh -i ~/.ssh/id_rsa_corp'</span>
</code></pre>
<h2 id="heading-password-managemet">Password managemet</h2>
<p>Last piece of the puzzle is managing passwords. We want to avoid having to enter password every time when SSH connection is initiating. To do so, we can utilize keychain management software that comes with MacOS and various Linux distributions.</p>
<p>Start by adding your key to the keychain by passing <code>-K</code> option to the <code>ssh-add</code> command:</p>
<pre><code class="lang-bash">ssh-add -K ~/.ssh/id_rsa_whatever
</code></pre>
<p>Now you can see your SSH key in the keychain. On MacOS it looks something like this:</p>
<p><img src="https://raw.githubusercontent.com/fvoska/guides/master/static/images/pages/ssh/managing-multiple-ssh-keys/keychain-access.png" alt="Keychain Access" width="989" height="711" loading="lazy"></p>
<p>If you remove the keys from <code>ssh-agent</code> via <code>ssh-add -D</code> (this will happen when you restart your computer, as mentioned before) and try SSH-ing, you will be prompted for password again. Why? We just added the the key to the keychain. If you check Keychain Access again, you will notice that the key you added using <code>ssh-add -K</code> is still in the keychain. Weird, huh?</p>
<p>It turns out there is one more hoop to jump through. Open your SSH <code>config</code> file and add the following:</p>
<pre><code class="lang-bash">Host *
  AddKeysToAgent yes
  UseKeychain yes
</code></pre>
<p>Now, SSH will look for key in keychain and if it finds it you will not be prompted for password. Key will also be added to <code>ssh-agent</code>. On MacOS this will work on MacOS Sierra 10.12.2 or later. On Linux you can use something like <code>gnome-keyring</code> and it might work even without this last modification to SSH <code>config</code>. As for Windows - who knows, right?</p>
<p>I hope someone found this useful. Now go and configure your SSH <code>config</code> file!</p>
<h2 id="heading-learn-more-about-ssh">Learn more about SSH:</h2>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/the-ultimate-guide-to-ssh-setting-up-ssh-keys/">The ultimate guide to SSH keys</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/a-top-down-introduction-to-ssh-965f4fadd32e/">A top-down introduction to SSH</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Run Commands on Multiple Linux Hosts Using PSSH ]]>
                </title>
                <description>
                    <![CDATA[ I'm sure you've heard that all the cool kids are playing with orchestration automation these days. But do you know why? Well first, the resources consumed by modern microservices workloads are becoming much more complex and deploy to far more instanc... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/running-commands-linux-hosts-using-pssh/</link>
                <guid isPermaLink="false">66b9962a7bb37b73c3f3c4ea</guid>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Orchestration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                    <category>
                        <![CDATA[ virtualization ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Thu, 09 Jan 2020 14:00:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9e08740569d1a4ca3af6.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I'm sure you've heard that all the cool kids are playing with orchestration automation these days. But do you know why? Well first, the resources consumed by modern microservices workloads are becoming much more complex and deploy to far more instances than ever before. And second, more and more of those resources are virtual rather than physical - so many of them will only exist for minutes or even seconds.</p>
<p>All of which means that even if you wanted to go around logging into each of your many servers, it just wouldn't make sense. In most cases in fact, it wouldn't even be possible. Instead, you're going to be running a lot of clever scripts. And the tools you use to run those kinds of scripts are generally called orchestrators.</p>
<p>I'm sure you've encountered at least one or two members of the orchestration club. Besides Ansible, there's Terraform, Chef, Puppet and others. But there are also lower-level tools that work as add-ons to core Linux tools like SSH. Although, seeing how it'll run natively on Windows and, of course, macOS, I'm not sure it's quite correct to call SSH a "Linux" tool any more. </p>
<p>One of those SSH add-ons is a tool set called pssh - which stands for Parallel SSH. That's what we're going to be learning about in this article - which is excerpted from my new <a target="_blank" href="https://pluralsight.pxf.io/RqrJb">Pluralsight course, Linux System Optimization</a>.</p>
<p>For now, though, I'm going to tell you a bit about the lab I'm using so that you can more easily reproduce it and follow along at home. I've got three Ubuntu <a target="_blank" href="https://www.freecodecamp.org/news/linux-containers-lxc-lxd/">LXD containers</a> running. The base for all of our operations will be the one with an IP address of 10.0.3.140, while the two host nodes we'll be remotely provisioning will use 10.0.3.93 and 10.0.3.43.</p>
<p>Everything we'll do assumes that we've got passwordless SSH access from my base container to each of the two nodes. If you're not sure how to do that, you can view the SSH module of my <a target="_blank" href="https://pluralsight.pxf.io/9DYVe">Protocol Deep Dive: SSH and Telnet course</a> on Pluralsight. If you're in a hurry, <a target="_blank" href="https://www.redhat.com/sysadmin/passwordless-ssh">this Red Hat tutorial</a> will get you to the same place.</p>
<p>Installing pssh on Ubuntu is simple and quick: <code>sudo apt install pssh</code>. It doesn't get any harder on CentOS.</p>
<p>I created a simple host inventory file called sshhosts.txt that contains nothing more than the IP addresses of my two nodes:</p>
<pre><code>$ less sshhosts.txt
<span class="hljs-number">10.0</span><span class="hljs-number">.3</span><span class="hljs-number">.93</span>
<span class="hljs-number">10.0</span><span class="hljs-number">.3</span><span class="hljs-number">.43</span>
</code></pre><p>Now I'm going to run the pssh parallel-ssh command to execute a single command on my hosts.</p>
<pre><code>$ parallel-ssh -i -h sshhosts.txt df -ht ext4
</code></pre><p>-i tells the program to run as interactive - otherwise we wouldn't be shown any command output. -h points to the hosts file that I called sshhosts.txt. And the command itself will be the old Unix utility df. That'll return a list of drives attached to the system along with their mount points and usage information. The -h here will display disk space in human readable units and the t will restrict access to only drives formatted as ext4. </p>
<p>Why do I care about that ext4 business? Because Ubuntu uses the snap package manager and each snap creates its own virtual device. So what? Well, I don't want to have to comb through a dozen or so virtual devices reporting 0 free space just to get to the real drives reporting actual usage.</p>
<pre><code>$ parallel-ssh -i -h sshhosts.txt df -ht ext4
[<span class="hljs-number">1</span>] <span class="hljs-number">22</span>:<span class="hljs-number">02</span>:<span class="hljs-number">00</span> [SUCCESS] <span class="hljs-number">10.0</span><span class="hljs-number">.3</span><span class="hljs-number">.43</span>
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       <span class="hljs-number">457</span>G  <span class="hljs-number">131</span>G  <span class="hljs-number">304</span>G  <span class="hljs-number">30</span>% /
[<span class="hljs-number">2</span>] <span class="hljs-number">22</span>:<span class="hljs-number">02</span>:<span class="hljs-number">00</span> [SUCCESS] <span class="hljs-number">10.0</span><span class="hljs-number">.3</span><span class="hljs-number">.93</span>
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       <span class="hljs-number">457</span>G  <span class="hljs-number">131</span>G  <span class="hljs-number">304</span>G  <span class="hljs-number">30</span>% /
</code></pre><p>And there you go! Full disk space information about both of my nodes. I'm sure you noticed that the information is identical. That's because these are both containers running on my workstation, so as far as they know, they both have full access to my own drive.</p>
<p>For my next trick, I'll collect the /etc/group files from each of my nodes. This is the kind of operation that could be useful to quickly monitor the security status of your nodes. You could add a script that parses the incoming data and alerts you if there are any anomalies. </p>
<p>Before I begin, I'll create a directory locally called host-files. Then I'll use the <code>parallel-slurp</code> command - whose name wonderfully describes its function. Again, -h points to the hosts file. The <code>-L</code> sets the host-files directory as the target location for writing the data we're going to generate, <code>/etc/group</code> is the remote file we want to slurp up, and <code>group</code> is the name we'd like to assign the data locally.</p>
<pre><code>mkdir host-files
parallel-slurp -h sshhosts.txt -L host-files/ <span class="hljs-regexp">/etc/g</span>roup group
</code></pre><p>When it's done, your host-files directory will contain sub-directories named after the IP address of each of your nodes. As you can see, there's a file called "group" that contains the /etc/group data from each node.</p>
<pre><code>$ tree host-files/
host-files/
├── <span class="hljs-number">10.0</span><span class="hljs-number">.3</span><span class="hljs-number">.43</span>
│   └── group
└── <span class="hljs-number">10.0</span><span class="hljs-number">.3</span><span class="hljs-number">.93</span>
    └── group
</code></pre><p>Does pssh come with any other treats? Yup. And running <code>apropos</code> gives you the whole list.</p>
<pre><code>$ apropos parallel
parallel-nuke (<span class="hljs-number">1</span>)    - parallel process kill program
parallel-rsync (<span class="hljs-number">1</span>)   - parallel process kill program
parallel-scp (<span class="hljs-number">1</span>)     - parallel process kill program
parallel-slurp (<span class="hljs-number">1</span>)   - parallel process kill program
parallel-ssh (<span class="hljs-number">1</span>)     - parallel ssh program
</code></pre><p><em>This article is based on content in my <a target="_blank" href="https://pluralsight.pxf.io/RqrJb">Pluralsight course, "Linux System Optimization."</a> There's much more administration goodness in the form of books, courses, and articles available at <a target="_blank" href="https://bootstrap-it.com">bootstrap-it.com</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Get and Configure Your Git and GitHub SSH Keys ]]>
                </title>
                <description>
                    <![CDATA[ If you use GitHub without setting up an SSH key, you're really missing out. Just think–all of that time you spent entering your email address and password into the console every time you push a commit could have been spent coding. Well no more. Here'... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/git-ssh-how-to/</link>
                <guid isPermaLink="false">66c34b8ca7aea9fc97bdfb31</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                    <category>
                        <![CDATA[ toothbrush ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 03 Jan 2020 17:46:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9e49740569d1a4ca3c4e.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you use GitHub without setting up an SSH key, you're really missing out. Just think–all of that time you spent entering your email address and password into the console every time you push a commit could have been spent coding.</p>
<p>Well no more. Here's a quick guide to generate and configure an SSH key with GitHub so you never have to authenticate the old fashioned way again.</p>
<h3 id="heading-check-for-an-existing-ssh-key">Check for an existing SSH key</h3>
<p>First, check if you've already generated SSH keys for your machine. Open a terminal and enter the following command:</p>
<pre><code class="lang-shell">ls -al ~/.ssh
</code></pre>
<p>If you've already generated SSH keys, you should see output similar to this:</p>
<pre><code class="lang-sh">-rw-------  1 user_name user_name  1766 Jul  7  2018 id_rsa
-rw-r--r--  1 user_name user_name   414 Jul  7  2018 id_rsa.pub
-rw-------  1 user_name user_name 12892 Feb  5 18:39 known_hosts
</code></pre>
<p>If your keys already exist, skip ahead to the <strong>Copy your public SSH key</strong> section below.</p>
<p>If you don't see any output or that directory doesn't exist (you get a <code>No such file or directory</code> message), then run:</p>
<pre><code class="lang-shell">mkdir $HOME/.ssh
</code></pre>
<p>Then generate a new set of keys with:</p>
<pre><code class="lang-shell">ssh-keygen -t rsa -b 4096 -C your@email.com
</code></pre>
<p>Now check that your keys exist with the <code>ls -al ~/.ssh</code> command and ensure that the output is similar to the one listed above.</p>
<p><strong>Note:</strong> SSH keys are always generated as a pair of public (<code>id_rsa.pub</code>) and private (<code>id_rsa</code>) keys. It's extremely important that you <strong>never reveal your private</strong> key, and <strong>only use your public</strong> key for things like GitHub authentication. You can read more about how SSH / RSA key pairs work <a target="_blank" href="https://www.freecodecamp.org/news/a-top-down-introduction-to-ssh-965f4fadd32e/">here</a>.</p>
<h3 id="heading-add-your-ssh-key-to-ssh-agent">Add your SSH key to ssh-agent</h3>
<p><code>ssh-agent</code> is a program that starts when you log in and stores your private keys. For it to work properly, it needs to be running and have a copy of your private key.</p>
<p>First, make sure that <code>ssh-agent</code> is running with:</p>
<pre><code class="lang-shell">eval "$(ssh-agent -s)" # for Mac and Linux
</code></pre>
<p>or:</p>
<pre><code class="lang-shell">eval `ssh-agent -s`
ssh-agent -s # for Windows
</code></pre>
<p>Then, add your private key to <code>ssh-agent</code> with:</p>
<pre><code class="lang-shell">ssh-add ~/.ssh/id_rsa
</code></pre>
<h3 id="heading-copy-your-public-ssh-key">Copy your public SSH key</h3>
<p>Next, you need to copy your public SSH key to the clipboard.</p>
<p>For Linux or Mac, print the contents of your public key to the console with:</p>
<pre><code class="lang-shell">cat ~/.ssh/id_rsa.pub # Linux
</code></pre>
<p>Then highlight and copy the output.</p>
<p>Or for Windows, simply run:</p>
<pre><code class="lang-shell">clip &lt; ~/.ssh/id_rsa.pub # Windows
</code></pre>
<h3 id="heading-add-your-public-ssh-key-to-github">Add your public SSH key to GitHub</h3>
<p>Go to your GitHub <a target="_blank" href="https://github.com/settings/keys">settings</a> page and click the "New SSH key" button:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/02/image-14.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Then give your key a recognizable title and paste in your public (<code>id_rsa.pub</code>) key:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/02/image-15.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Finally, test your authentication with:</p>
<pre><code class="lang-shell">ssh -T git@github.com
</code></pre>
<p>If you've followed all of these steps correctly, you should see this message:</p>
<pre><code class="lang-sh">Hi your_user_name! You<span class="hljs-string">'ve successfully authenticated, but GitHub does not provide shell access.</span>
</code></pre>
<h3 id="heading-more-info-on-ssh">More info on SSH:</h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/the-ultimate-guide-to-ssh-setting-up-ssh-keys/">Ultimate guide to SSH</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/a-top-down-introduction-to-ssh-965f4fadd32e/">A top-down intro to SSH</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Ultimate Guide to SSH - Setting Up SSH Keys ]]>
                </title>
                <description>
                    <![CDATA[ Welcome to our ultimate guide to setting up SSH (Secure Shell) keys. This tutorial will walk you through the basics of creating SSH keys, and also how to manage multiple keys and key pairs. Create a New SSH Key Pair Open a terminal and run the follow... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-ultimate-guide-to-ssh-setting-up-ssh-keys/</link>
                <guid isPermaLink="false">66c362c6020f8e9c31066e5a</guid>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 03 Dec 2019 18:03:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9ee3740569d1a4ca3fb6.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Welcome to our ultimate guide to setting up SSH (Secure Shell) keys. This tutorial will walk you through the basics of creating SSH keys, and also how to manage multiple keys and key pairs.</p>
<h2 id="heading-create-a-new-ssh-key-pair">Create a New SSH Key Pair</h2>
<p>Open a terminal and run the following command:</p>
<pre><code class="lang-text">ssh-keygen
</code></pre>
<p>You will see the following text:</p>
<pre><code class="lang-text">Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):
</code></pre>
<p>Press enter to save your keys to the default <code>/home/username/.ssh</code> directory.</p>
<p>Then you'll be prompted to enter a password:</p>
<pre><code class="lang-text">Enter passphrase (empty for no passphrase):
</code></pre>
<p>It's recommended to enter a password here for an extra layer of security. By setting a password, you could prevent unauthorized access to your servers and accounts if someone ever gets a hold of your private SSH key or your machine.</p>
<p>After entering and confirming your password, you'll see the following:</p>
<pre><code class="lang-text">Your identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:/qRoWhRcIBTw0D4KpTUyK6YepyL6RQ2CQrtWsaicCb4 username@871e129f767b
The key's randomart image is:
+---[RSA 2048]----+
| .o=+....        |
|+.*o+o .         |
|+X.=o o          |
|@.=.oo .         |
|=O ...o S        |
|o.oo . .         |
|.E+ . . . .      |
|oo . ... +       |
|=.. .o. . .      |
+----[SHA256]-----+
</code></pre>
<p>You now have a public and private SSH key pair you can use to access remote servers and to handle authentication for command line programs like Git.</p>
<h2 id="heading-manage-multiple-ssh-keys">Manage Multiple SSH Keys</h2>
<p>Though it's considered good practice to have only one public-private key pair per device, sometimes you need to use multiple keys or you have unorthodox key names. For example, you might be using one SSH key pair for working on your company's internal projects, but you might be using a different key for accessing a client's servers. On top of that, you might be using a different key pair for accessing your own private server.</p>
<p>Managing SSH keys can become cumbersome as soon as you need to use a second key. Traditionally, you would use <code>ssh-add</code> to store your keys to <code>ssh-agent</code>, typing in the password for each key. The problem is that you would need to do this every time you restart your computer, which can quickly become tedious.</p>
<p>A better solution is to automate adding keys, store passwords, and to specify which key to use when accessing certain servers.</p>
<h3 id="heading-ssh-config">SSH <code>config</code></h3>
<p>Enter SSH <code>config</code>, which is a per-user configuration file for SSH communication. Create a new file: <code>~/.ssh/config</code> and open it for editing:</p>
<pre><code class="lang-text">nano ~/.ssh/config
</code></pre>
<h3 id="heading-managing-custom-named-ssh-key">Managing Custom Named SSH key</h3>
<p>The first thing we are going to solve using this <code>config</code> file is to avoid having to add custom-named SSH keys using <code>ssh-add</code>. Assuming your private SSH key is named <code>~/.ssh/id_rsa</code>, add following to the <code>config</code> file:</p>
<pre><code class="lang-bash">Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa
  IdentitiesOnly yes
</code></pre>
<p>Next, make sure that <code>~/.ssh/id_rsa</code> is not in <code>ssh-agent</code> by opening another terminal and running the following command:</p>
<pre><code class="lang-text">ssh-add -D
</code></pre>
<p>This command will remove all keys from currently active <code>ssh-agent</code> session.</p>
<p>Now if you try closing a GitHub repository, your <code>config</code> file will use the key at <code>~/.ssh/ida_rsa</code>.</p>
<p>Here are some other useful configuration examples:</p>
<pre><code class="lang-bash">Host bitbucket-corporate
        HostName bitbucket.org
        User git
        IdentityFile ~/.ssh/id_rsa_corp
        IdentitiesOnly yes
</code></pre>
<p>Now you can use <code>git clone git@bitbucket-corporate:company/project.git</code></p>
<pre><code class="lang-bash">Host bitbucket-personal
        HostName bitbucket.org
        User git
        IdentityFile ~/.ssh/id_rsa_personal
        IdentitiesOnly yes
</code></pre>
<p>Now you can use <code>git clone git@bitbucket-personal:username/other-pi-project.git</code></p>
<pre><code class="lang-text">Host myserver
        HostName ssh.username.com
        Port 1111
        IdentityFile ~/.ssh/id_rsa_personal
        IdentitiesOnly yes
        User username
        IdentitiesOnly yes
</code></pre>
<p>Now you can SSH into your server using <code>ssh myserver</code>. You no longer need to enter a port and username every time you SSH into your private server.</p>
<h3 id="heading-password-management">Password management</h3>
<p>The last piece of the puzzle is managing passwords. It can get very tedious entering a password every time you initialize an SSH connection. To get around this, we can use the password management software that comes with macOS and various Linux distributions.</p>
<p>For this tutorial we will use macOS's Keychain Access program. Start by adding your key to the Keychain Access by passing <code>-K</code> option to the <code>ssh-add</code> command:</p>
<pre><code class="lang-bash">ssh-add -K ~/.ssh/id_rsa_whatever
</code></pre>
<p>Now you can see your SSH key in Keychain Access:</p>
<p><img src="https://raw.githubusercontent.com/fvoska/guides/master/static/images/pages/ssh/managing-multiple-ssh-keys/keychain-access.png" alt="Keychain Access" width="989" height="711" loading="lazy"></p>
<p>But if you remove the keys from <code>ssh-agent</code> with <code>ssh-add -D</code> or restart your computer, you will be prompted for password again when you try to use SSH. Turns out there's one more hoop to jump through. Open your SSH <code>config</code> file by running <code>nano ~/.ssh/config</code> and add the following:</p>
<pre><code class="lang-bash">Host *
  AddKeysToAgent yes
  UseKeychain yes
</code></pre>
<p>With that, whenever you run <code>ssh</code> it will look for keys in Keychain Access. If it finds one, you will no longer be prompted for a password. Keys will also automatically be added to <code>ssh-agent</code> every time you restart your machine.</p>
<p>Now that you know the basics of creating new SSH keys and managing multiple keys, go out and <code>ssh</code> to your heart's content!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A top-down introduction to SSH and how it enables secure data-sharing ]]>
                </title>
                <description>
                    <![CDATA[ By Sam Ollason This article will take a high-level and top-down approach to explain how SSH works and how it is used for securely communicating with remote computers. We will look at how an SSH session is actually ‘secure’ and how computers establish... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-top-down-introduction-to-ssh-965f4fadd32e/</link>
                <guid isPermaLink="false">66c343600bafa8455505c66b</guid>
                
                    <category>
                        <![CDATA[ encryption ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 06 Mar 2019 12:18:02 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*TiltvM4ydji8sXcvbsEL_Q.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sam Ollason</p>
<p><strong>This article will take a high-level and top-down approach to explain how SSH works and how it is used for securely communicating with remote computers.</strong></p>
<p>We will look at how an SSH session is actually ‘secure’ and how computers establish and set-up an SSH session in the first place. We will also look at the benefits of using SSH.</p>
<p><em>Note:</em> This is intended as future notes to myself, but I hope you learn something from it too!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/F0xSx0bm1cKylEjl0uyrNv0IUDmaXv2DE3mb" alt="Image" width="800" height="559" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/photos/pY_AZJfdbHQ?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" rel="noopener" target="_blank" title=""&gt;Matt Artz on &lt;a href="https://unsplash.com/search/photos/key?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" rel="noopener" target="<em>blank" title=")</em></p>
<h3 id="heading-what-is-ssh">What is SSH?</h3>
<p>SSH is short for ‘secure shell’. It is a protocol for sharing data between two computers over the internet.</p>
<p>A protocol is essentially a set of rules that define the language that computers can use to communicate.</p>
<p>Typically, the two computers involved are your computer (the ‘client’) and a remote server (the ‘host’).</p>
<h3 id="heading-why-do-we-care">Why do we care?</h3>
<h4 id="heading-secure-communications-between-computers">Secure communications between computers</h4>
<p>Whenever two computers communicate over the internet we want to be sure that our messages can’t be intercepted and understood by anyone listening to the messages.</p>
<p>Imagine sending your bank details over the internet to buy something online. If your messages weren’t encrypted, then any computer that was listening or any computer that received the messages to pass onwards may be able to see your account number and your password. That isn’t good!</p>
<p>I believe this is an important concept to understand for anyone who aspires to work with web technologies.</p>
<h4 id="heading-secure-access-to-remote-computers">Secure access to remote computers</h4>
<p>Using SSH to check authentication is a more secure way of authentication than using a password. We will explore how this works below.</p>
<h3 id="heading-how-is-ssh-secure">How is SSH secure?</h3>
<p>SSH is a secure way of sending communications between two computers.</p>
<p>By ‘secure’, I mean a way of encoding the messages on a client computer such that the only other computer that can decode the messages and understand them is the host. This encoding/decoding is called <strong>encryption,</strong> so what we really mean here is SSH is secure because it uses an <strong>encrypted communication channel.</strong></p>
<h3 id="heading-how-is-a-ssh-session-established">How is a SSH session established?</h3>
<p>There are several processes that need to happen between two computers in order for an SSH session to begin.</p>
<ol>
<li>First we need a way of setting up a secure method of exchanging messages between the computers. We need to set up an <strong>encrypted channel.</strong></li>
<li>We need a way of checking that the data received by the host hasn’t been tampered with. This called <strong>verification</strong> and here we are verifying the integrity of the data that is sent by the client.</li>
<li>Verification (again). We need a way of checking that the computer we are communicating with isn’t an imposter. This is another form of verification but here we are verifying the identity of the computer.</li>
</ol>
<p>After these three steps, we can now communicate securely with a remote computer.</p>
<p>After these steps, we can share ‘secret’ data securely and we can also check if a client has permission to access a host in a more secure way than using a password. This process is called <strong>authentication using asymmetric encryption.</strong></p>
<p>Each of these sections below will go into more detail on these steps.</p>
<h3 id="heading-setting-up-an-encrypted-channel"><strong>Setting up an encrypted channel</strong></h3>
<p>A core part of the SSH protocol is that is it secure (it is in even in the name!), meaning all information that is sent using SSH is encrypted.</p>
<h4 id="heading-how-does-this-information-get-encrypted">How does this information get encrypted?</h4>
<p>Encrypting essentially just means ‘jumbling up the letters’ using some clever maths. Both computers need to have a way of encrypting the information so that only the other computer can decrypt the information and understand it.</p>
<h4 id="heading-how-does-this-work">How does this work?</h4>
<p>Both computers have an identical version of a <strong>symmetric key.</strong> The symmetric key is just a string of letters stored somewhere on the computers. The computers can use the symmetric keys to encrypt and also decrypt messages sent to them.</p>
<p>Using this symmetric key approach is called <strong>symmetric encryption.</strong> The ‘symmetric’ part comes from the fact the symmetric key on each computer is identical. This approach works really well … but it only works as long as no other computers have access to the symmetric key.</p>
<h4 id="heading-a-problem">A problem</h4>
<p>How do both computers know what the symmetric key is?</p>
<p>One computer could create it and send it in a message over the internet. But the messages wouldn’t be encrypted yet, so anyone intercepting the messages would instantly have the symmetric key … and can decrypt all future communications. That’s bad!</p>
<p>This is sometimes called the ‘key-exchange’ problem. It is clear that we need to add another step in the process before we can use symmetric keys.</p>
<h4 id="heading-a-solution">A solution</h4>
<p>A solution to the ‘key-exchange’ problem above is that both computers share some public information with each other (it is ‘public’ meaning they don’t mind if anyone intercepts it) and combine this with some information on their own computer to <strong>independently</strong> create <strong>identical</strong> symmetric keys.</p>
<p>These symmetric keys can then be used in symmetric encryption in the way outlined above.</p>
<h4 id="heading-how-this-works">How this works</h4>
<p>Both computers each have their own private key and public key. Together they form a <strong>key-pair</strong>. The computers <strong>share their public keys</strong> with each other over the internet. So, at this point in the process each computer knows</p>
<ul>
<li>its own private key,</li>
<li>its own public key,</li>
<li>and the other computer’s public key.</li>
</ul>
<h4 id="heading-generating-symmetric-keys">Generating Symmetric Keys</h4>
<p>Both computers then use these 3 pieces of information to independently generate an <strong>identical</strong> symmetric key.</p>
<p>Each computer uses a mathematical algorithm which uses the 3 inputs mentioned above. This algorithm is part of the Diffie-Hellman key exchange algorithm. The algorithm that will be executed on each computer is something like this:</p>
<pre><code>Host
pub_2 = other computer<span class="hljs-string">'s public key
pub_1 = my public key
pri_1 = my private key

f(pub_2, pub_1, pri_1) = abcdefg // Symmetric Key

Client:
f(pub_1, pub_2, pri_2) = abcdefg // Symmetric Key</span>
</code></pre><p>The important thing to take away here is that computers have <strong>shared only public information</strong> over the internet <strong>but have still been able to create symmetric keys!</strong></p>
<p>The approach of using key-pairs and sharing public information to generate identical symmetric keys is called <strong>asymmetric encryption</strong>. It is called ‘asymmetric’ because both computers start off with their own, different, key pairs.</p>
<p><strong>So far:</strong> we have seen how to use asymmetric encryption to independently generate identical symmetric keys on both computers <em>in a secure way</em> (solving the key-exchange problem) and then securely exchange information between computers using symmetric keys for encryption and decryption.</p>
<h3 id="heading-verification">Verification</h3>
<p>So we can communicate securely. But the next part of the process of establishing an SSH session is to verify that the data hasn’t been tampered with as it has been transmitted <strong>and</strong> that the other computer is actually who it is says it is.</p>
<h4 id="heading-why-do-we-need-this">Why do we need this?</h4>
<p>Another computer could impersonate one of the computers and initiate the key exchange above. So how do we <strong>securely</strong> figure out that the message is actually from the other computer and not from an imposter?</p>
<h4 id="heading-hashing">Hashing</h4>
<p>We have to use a <strong>hash</strong> function. This is just a mathematical function that takes inputs and produces a string of a fixed size.</p>
<p>The important feature of this function is that it is virtually impossible to work out what the inputs were just using the outputs.</p>
<p>After a client and a host have generated their symmetric keys, the client will use a hashing function to generate a HMAC. This just stands for “hash-based message authentication code”. This is just another string of characters/numbers. The client will send this HMAC to the server for verification.</p>
<p>The ingredients to the hashing function are</p>
<ul>
<li>The symmetric key on the client</li>
<li>The package sequence number (each message that is sent is contained in a ‘package’ of information)</li>
<li>The (encrypted!!!) message contents</li>
</ul>
<p>An example with fake data:</p>
<pre><code>symm_key       = abcdefg
pkge_no        = <span class="hljs-number">13</span>
encr_message   = encrypted_password

Hash(symm_key, pkge_no, encr_message) = *HMAC* <span class="hljs-comment">// Hashed value</span>
</code></pre><h4 id="heading-how-does-the-host-use-this-information">How does the host use this information?</h4>
<p>When the host receives the HMAC, it can use <strong>the same</strong> hash function with these three ingredients:</p>
<ul>
<li>its own copy of the (identical!) symmetric key,</li>
<li>the package sequence number,</li>
<li>and the encrypted message.</li>
</ul>
<p>If the hashed value it computes is the same as the HMAC it received from the client, then we have verified that the connecting computer is the same as the computer who has the symmetric key.</p>
<p>Remember that only the host and client know what the symmetric key is and no other computers do!</p>
<p>So here it doesn’t matter that the host doesn’t know the decoded contents of the encrypted message —the host has still verified the identity of the connecting computer!</p>
<p>The beauty of this approach is that we have not just verified the identity of the client and made sure that the data hasn’t been tampered, but we have done so securely (without <strong>without sharing any private information)</strong>.</p>
<p><strong>Summary:</strong> we used a hash function on the client and then on the host to verify data integrity and verify the identity of the client.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ej0rVm5QFV0xIuBr4f2Dm8CIAqxZTjkfl5jP" alt="Image" width="800" height="533" loading="lazy"></p>
<h3 id="heading-authentication">Authentication</h3>
<p>The final part of the securely communicating with remote computers is:</p>
<p><em>even if</em> we have generated symmetric keys with the connecting computer and</p>
<p><em>even if</em> we are using the symmetric keys to communicate securely and</p>
<p><em>even if</em> the connecting computer is genuinely the client we expect and not an imposter,</p>
<p>then we have set up an SSH session … but does the connecting computer have <strong>permission</strong> to access the contents of the host?</p>
<p>This is called ‘authentication’: the act of checking permissions and access rights.</p>
<h4 id="heading-there-are-two-ways-of-checking-authentication">There are two ways of checking authentication:</h4>
<p><strong>1—Using a password</strong></p>
<p>The client can send the host an (encrypted) message containing a password. The host can decrypt the message and check the password in a database to check if the client has permission to access the specified ‘user’ (area of the computer). Job done.</p>
<p><strong>2 — Using key-pairs and asymmetric encryption</strong></p>
<p>Earlier, we saw how asymmetric encryption can use two key-pairs to securely generate identical symmetric keys on both the client and the host. Using similar ideas, the client can <strong>log in without a password</strong>.</p>
<p>This is a very high-level approach to the how the process works:</p>
<p><em>Setting up:</em></p>
<p>On the client, head to the terminal and use a command to generate a public key and a private key (under the surface it uses ‘RSA’, a mathematical algorithm) on the client. Copy the <strong>public</strong> key (NOT the private key!) to the clipboard.</p>
<p><em>I repeat:</em> Copy the <strong>PUBLIC</strong> key (<strong>NOT THE PRIVATE</strong> KEY!) to the clipboard.</p>
<p>Then, in the terminal on the client, use a password to remotely log in to the host. Paste the public key of the client into the appropriate folder on the host alongside any other public keys.</p>
<p>Now, the host has</p>
<ul>
<li>It’s own public/private key-pair</li>
<li>The public key of the client</li>
</ul>
<p>Looking at the section above on the key-exchange algorithm, you can see how the host has all the ingredients it needs to generate a symmetric key!</p>
<p><em>Challenging:</em></p>
<p>When the client wants to connect, the host can use issue a ‘challenge’ by sending a message that has been encrypted (with the host’s symmetric key) and say: <em>‘I will only authorise you access if you can decrypt this message!’.</em></p>
<p>The client then has</p>
<ul>
<li>its own public and private key</li>
<li>the public key of the host</li>
<li>the encrypted message</li>
</ul>
<p>So now the client has everything needed to generate an (identical) symmetric key … and decrypt the message! It can decrypt the message and send confirmation that is has ‘succeeded’ in the challenge back to the host.</p>
<p>The host is satisfied that the connecting client is authorised and grants permission for access.</p>
<p><strong>Why bother using the second approach?</strong></p>
<p>This is seen as more secure than simply using a password because a bot can use a ‘brute force’ approach to keep using lots of combinations to guess your password, but they will not have they right key-pairs for the second approach to work.</p>
<p>Further reading:</p>
<p><a target="_blank" href="https://www.hostinger.com/tutorials/ssh-tutorial-how-does-ssh-work"><strong>SSH Tutorial for Beginners - How Does SSH Work</strong></a><br><a target="_blank" href="https://www.hostinger.com/tutorials/ssh-tutorial-how-does-ssh-work">_SSH, or Secure Shell, is a remote administration protocol that allows users to control and modify their remote servers…_www.hostinger.com</a></p>
<p><a target="_blank" href="https://www.udemy.com/the-complete-junior-to-senior-web-developer-roadmap/">https://www.udemy.com/the-complete-junior-to-senior-web-developer-roadmap/</a></p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>SSH is an important tool used to remotely control other computers.</p>
<p>SSH is secure because both computers can encrypt and decrypt message using identical symmetric keys (known as ‘symmetric encryption’).</p>
<p>The main steps to initiate an SSH session are:</p>
<ol>
<li><strong>Setting up an encrypted channel.</strong> Using asymmetric encryption to solve the key-exchange problem which independently generates identical symmetric keys on both computers without sharing any private information.</li>
<li><strong>Verification:</strong> Using hashing on both computers to verify the identity of the connecting computer</li>
<li>Verification (again). Using hashing on both computers to verify data integrity hasn’t been compromised in transmission.</li>
</ol>
<p>We can then use SSH to securely send data between the computers. One important use case of this is for <strong>authentication.</strong> Although you can use a password, using asymmetric encryption to check the connecting ‘client’ has permission to access the ‘host’ is is seen as more secure.</p>
<p>If you are interested in leveling up your SSH, I seriously recommend <a target="_blank" href="https://www.udemy.com/the-complete-junior-to-senior-web-developer-roadmap/">this</a> course. I found it really useful to sharpen up some of my skills! (<em>disclaimer:</em> I have no links or ties to the author or the platform. I took the course a while ago and found it really good!)</p>
<p>Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to create and connect to Google Cloud Virtual Machine with SSH ]]>
                </title>
                <description>
                    <![CDATA[ By Nezar Assawiel Google Cloud offers many tools and services. One of these services is creating highly customizable virtual machines. If you are not familiar with what a virtual machine is, here is a definition from Microsoft: A virtual machine is ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-and-connect-to-google-cloud-virtual-machine-with-ssh-81a68b8f74dd/</link>
                <guid isPermaLink="false">66c35130a1d481faeda49bb4</guid>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ virtual machine ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 02 Nov 2018 16:45:23 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*uGmqUMo3h7NHNCkP.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nezar Assawiel</p>
<p>Google Cloud offers many tools and services. One of these services is creating highly customizable virtual machines. If you are not familiar with what a virtual machine is, here is a definition from Microsoft:</p>
<blockquote>
<p>A virtual machine is a computer file, typically called an image, that behaves like an actual computer. In other words, creating a computer within a computer. It runs in a window, much like any other program, giving the end user the same experience on a virtual machine as they would have on the host operating system itself. The virtual machine is sandboxed from the rest of the system, meaning that the software inside a virtual machine can’t escape or tamper with the computer itself.</p>
</blockquote>
<p>Virtual machines are needed in many situations to test applications against other operating systems, to access virus-infected data, or to experiment with other operating systems. You can install virtual machines on your computer. You can also create them in the cloud and simply connect to them.</p>
<p>In this tutorial, I will walk you through how to create a virtual machine in Google Cloud. We can connect to it with SSH from your computer.</p>
<ol>
<li>If you don’t have one already, create a Google Cloud account from <a target="_blank" href="https://cloud.google.com/">here</a>.</li>
</ol>
<p>You will get $300 credit to play around with for a year! It is more than enough to learn and play with everything Google Cloud offers.</p>
<ol start="2">
<li>Create a new project or use an existing one. You can create a new project called <strong>project1</strong>, for example, as in the following gif:</li>
</ol>
<p><img src="https://cdn-media-1.freecodecamp.org/images/d8N926cdgrmskacPUiCBS-8j3E26n3wZKJMz" alt="Image" width="1429" height="728" loading="lazy"></p>
<ol start="3">
<li>Now you are set to create a virtual machine. Go to the top left corner of your Google Cloud home page, click on the triple bar icon ≡ and select <strong>Compute Engine -&gt;VM insta<em>n</em></strong>ce and cli<strong>ck Cre</strong>ate.</li>
</ol>
<p>Enter whatever name you want in the <strong>Name</strong> field as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/qBdgjOVIiVQwafsecV7Gx0LmggEy2LkxHEec" alt="Image" width="790" height="268" loading="lazy"></p>
<p>Keep the default region and zone. Any region/zone will do for this tutorial. If you are curious about what they mean, you can read Google Cloud’s documentation about them <a target="_blank" href="https://cloud.google.com/compute/docs/regions-zones/">here</a>.</p>
<p>You can keep default machine type or click <strong>Customize</strong> to select the number of CPU cores, memory, and GPUs you would like your virtual machine to have. You will see the cost on the right side changes!</p>
<p>For your first experiments with Google Cloud, you can be conservative with the $300 credit for some actual work. In such a case, you can choose the following configuration:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1dxebYaNuExfqZ8pfqh0xVbo2AM5mJVXWn9H" alt="Image" width="474" height="509" loading="lazy"></p>
<p>Next choose a boot disk. For example, you can choose <strong>20 GB, SSD, Ubuntu 16.04 LTS</strong> as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/yYCIobWt-a0d4u2CobgwkpqHuxKnrAfSb3Ur" alt="Image" width="470" height="186" loading="lazy"></p>
<p>Then set the <strong>Service Account</strong> under <strong>Identity and API access</strong> to <strong>No service account</strong> as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/GFhEp7kU2Q4w8vIAmGG8mVWsYf5EehrZ-qM4" alt="Image" width="470" height="158" loading="lazy"></p>
<p>Finally, go to the <strong>Security</strong> tab under <strong>Firewall</strong>. You will see an <strong>SSH Key</strong> field as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/xgqwfK55ZoSZYLrKQ863EgDD42iW37KVo9mu" alt="Image" width="455" height="500" loading="lazy"></p>
<p>This where you are going to connect your computer to the virtual machine using your SSH Key!</p>
<p>If you are not familiar with SSH (Secure Shell) and why you may want to use it, it is a network protocol that provides encrypted data communication between two computers (your computer and Google’s servers, in this case) which are connected over an insecure network (the Internet here).</p>
<p>To establish an SSH connection, you <em>may</em> need an application that can do that, depending on your operating system. <strong>Follow the rest of this post depending on your operating system (Windows or Mac/Linux).</strong></p>
<h4 id="heading-windows"><strong>Windows</strong></h4>
<p>I recommend <strong>PuTTY</strong>. It is an open-source and easy to use SSH client. You can download PuTTY and install it from <a target="_blank" href="https://www.putty.org/">here</a>.</p>
<p>After installing PuTTY, open <strong>PuTTY Key Generator</strong> and click <strong>create</strong>. It will generate a random key by <strong>you</strong> moving the mouse over the blank area. After it is done, you will get something like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/j6FJhRY3ijIeF2UOCU6rXR6hlxgXxDoJ-yJE" alt="Image" width="479" height="470" loading="lazy"></p>
<p>Change the <strong>key comment</strong> field to something recognizable and easy to type, as this will become a user name later!</p>
<p>Then save both the public and private keys by clicking the corresponding icons shown in the picture above.</p>
<p>Highlight the whole <strong>Key</strong> field from the PuTTY Key Generator, and copy and paste it in the <strong>key data</strong> field in Google Cloud:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Wl6IzBYOc7UgC7MtV-A6wbPe1x5aHKeuN38l" alt="Image" width="465" height="335" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/S9zZ0zEE-wcbiUTyA-NQh5onxHushq3ENrFF" alt="Image" width="470" height="336" loading="lazy"></p>
<p>Click <strong>create</strong> and wait for the virtual machine instance to be created.</p>
<p>In the meantime, you can go to PuTTY. Go to <strong>SSH -&gt;A</strong>uth and browse for the private key file that you saved.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/7MbOpAr9WTaSj-hqcIjvv1xihat-FRPryrUv" alt="Image" width="453" height="438" loading="lazy"></p>
<p>Next, go to Google Cloud and copy the external IP from the virtual machine instance that you just created as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/OSZMJ8Lqd1SyxuVYZFZcNTef3-ChxBFUSF6y" alt="Image" width="559" height="66" loading="lazy"></p>
<p>And paste it on the Host field under <strong>Sessions</strong> in PuTTY and hit <strong>Enter</strong>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/7rKBTabUWQ4bwJPEXMPhhjNxSEAJuEZ0iq4F" alt="Image" width="455" height="439" loading="lazy"></p>
<p>Note: you might get an error message. Ignore it and click <strong>yes</strong>. (It just says the key is not already in the registry. Are you sure you want to connect?)</p>
<p>Then enter the username you created when generating the key (<strong>key comment</strong> above). Boom! you are in the virtual machine that you just created.</p>
<p>You can install python and Google APIs on it, for example, to start making some magic! Don’t forget to shut it down in Google Cloud after you are done to be economic with your credit :)</p>
<h4 id="heading-maclinux"><strong>Mac/Linux</strong></h4>
<p>Mac and Linux support SSH connection natively. You just need to generate an SSH key pair (public key/private key) to connect securely to the virtual machine.</p>
<p>The private key is equivalent to a password. Thus, it is kept private, residing on your computer, and should not be shared with any entity. The public key is shared with the computer or server to which you want to establish the connection. To generate the SSH key pair to connect securely to the virtual machine, follow these steps:</p>
<p>Enter the following command in Terminal: <code>ssh-keygen -t rsa</code> . It will start the key generation process. You will be prompted to choose the location to store the SSH key pair. Press ENTER to accept the default location as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/R3w3esMPp0ClobIdopPztKXJKS9VBB3tmEmo" alt="Image" width="703" height="128" loading="lazy"></p>
<p>Next, choose a password for your login to the virtual machine or hit ENTER if you wish not to use a password. The private key (i.e. identification) and the public key will be generated as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/b8KjgTG8JFeY38Lvdp3jdytUxcCQ71UnVo7K" alt="Image" width="701" height="349" loading="lazy"></p>
<p>Now run the following command: <code>cat ~/.ssh/id_rsa.pub</code> . It will display the public key in the terminal as shown below. Highlight and copy this key:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/fsKg95sN2WmbA7zWAkOc23K3xWxmKuqnOyL2" alt="Image" width="747" height="350" loading="lazy"></p>
<p>and paste it in the SSH key field in Google Cloud and hit <strong>Create</strong>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/REYZEUmTlmkyKvRdSNb6TYjGXp2LEdbhSPoN" alt="Image" width="477" height="557" loading="lazy"></p>
<p>Now you can use the <strong>External IP</strong> of the virtual machine you just created:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/FwkOZXHdOi8xv9XMeE9V4J4vo2BjVHgmzO2k" alt="Image" width="661" height="86" loading="lazy"></p>
<p>to <em>ssh</em> to it as follows:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/fN1tFu7LE0uQOrNrSPJCILOjiysC4xyc7U4i" alt="Image" width="699" height="38" loading="lazy"></p>
<p>You will get “The authenticity of host…etc.” warning as shown in the picture below. This is normal. Whenever SSH connects to a system it hasn’t seen before, it will generate a warning like this. Reply <strong>yes</strong> to connect, and bingo! You are in the virtual machine, as you can see from host name <strong>instance-3.</strong> To exit the virtual machine, just type <strong>exit.</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/60u5MB5wOQP9RAsG-KhrQgoJ5NB36YZKBYbG" alt="Image" width="748" height="301" loading="lazy"></p>
<p>Don’t forget to shut the virtual machine in Google Cloud after you are done to save that $300 credit!</p>
<p><em>Originally published at <a target="_blank" href="http://www.assawiel.com/blog">assawiel.com/blog</a> on December 23, 2017. Updated: Oct 10, 2018</em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
