Rupert  Beatty

Rupert Beatty

1670560320

3 Best Ways to Connect and SSH into an EC2 Instance – AWS

3 Ways to Connect and SSH into an EC2 Instance – AWS. In this guide you are going to learn how to connect to your EC2 instance from your local Linux or Mac or from your Windows machine.

3 Ways to Connect and SSH into an EC2 Instance

  1. Connect using a standalone SSH client.
  2. Connect using Session Manager.
  3. Connect using browser-based SSH connection.

Prerequisites

  1. A running EC2 Instance. Learn how to create an AWS EC2 instance.
  2. Assigned a Elastic IP to your EC2 Instance.
  3. Pem key file downloaded when you have created your EC2 Instance.
  4. If you are on Windows and try the standalone method, you need PUTTY SSH client to connect to your Instance.

Before you connect to your EC2 instance make sure your IP address is added in the Firewall to allow connections from your IP address or your instance allows connection from anywhere.

Connect using browser-based SSH connection

This is the easiest way to connect yo your Instance instantly. This method don’t require any additional clients installed in your local machine. To use this method,

Select your Instance and click the Connect button in your EC2 Dashboard.

In the Connection method choose EC2 Instance Connect.

The username of the AMI will get populated automatically.

Now click Connect.

Now a new window will get opened and a connection will get established to your Instance.

If you get any errors you need to wait for sometime once your instance is created.

Connect to EC2 Instance from Linux/Mac machines

From your Linux/Mac machine you can simply open your terminal window, use the ssh command to connect to the instance. You specify the private key (.pem) file, the user name for your AMI (in this case it is ubuntu), and the public DNS name for your instance or your Elastic IP address.

The connection string looks similar to the one below.

ssh -i "cloudbooklet.pem" ubuntu@ec2-35-171-69-92.compute-1.amazonaws.com

Connect to EC2 Instance from Windows using PUTTY

To SSH to your instance you need to convert your private key (.pem) file using PUTTYgen to ppk format.

Open PUTTYgen and Click Load.

Select the pem key you have downloaded while created your instance.

Once the file is imported, click Save private key to convert it to ppk format.

Save the file.

Launch PUTTY.

In Hostname/IP address enter DNS name or Elastic IP address.

In Port enter default 22.

In the left menu under Connection expand SSH and click Auth.

Browse and select the PPK file you just converted using PUTTYgen.

Now click Open.

This will create an SSH connection to your EC2 Instance.

Become a Certified AWS Professional with this easy to learn course now.

Conclusion

Now you have learned how to connect to your EC2 instance in AWS using standalone method or browser connection..

Thanks for your time. If you face any problem or any feedback, please leave a comment below.

Original article source at: https://www.cloudbooklet.com/

#aws #ssh #ec2 

 3 Best Ways to Connect and SSH into an EC2 Instance – AWS

How to SSH Logging and Session Management using AWS SSM

A comprehensive tutorial on how to log SSH activity—minus sensitive input, like passwords—occurring in Linux AWS EC2 instances to either CloudWatch Logs or S3 buckets.

Setting up custom tools or scripts to keep an SSH log on Linux can be tedious and error-prone.

Engineers can use rootsh, screen, or another utility to log user activity but if the user permissions are not set correctly, a skilled user can erase audit logs to cover their tracks. Another option would be to set up logging at the kernel level, but the expertise needed for that isn’t so common.

Thankfully, there’s a way to log user activity without writing even a single Linux command! We’ll need these services:

Let’s see how to set up each of them.

EC2 and IAM

Launching an EC2 instance is normally fairly easy, but there’s one key task that must be done during launch: We need to attach an IAM role to our instance, otherwise we won’t be able to achieve the expected results detailed at the end of this article.

The IAM role we associate with our EC2 instance must have the built-in AmazonSSMManagedInstanceCore policy, plus this policy (attached as inline or customer-managed):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogStream",
                "logs:DescribeLogStreams",
                "logs:DescribeLogGroups",
                "logs:PutLogEvents"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

Aside from the IAM role, we generally use this EC2 instance configuration:

  • The OS is Amazon Linux 2, because by default it comes with AWS Systems Manager Agent (SSM Agent) installed. (So do Ubuntu distributions, which are also an option.)
  • The Instance Type is t3.micro (but any type will do).
  • The default Security Group that AWS assigns to the VPC will work, as we don’t need an SSH port open for this exercise.

We can start to set up KMS without waiting for the EC2 instance to boot up.

KMS

We need a KMS key if we want all session logs delivered to CloudWatch to be stored encrypted. Let’s head over to the KMS service and create a key.

 

A screenshot of AWS with breadcrumbs "KMS," "Customer managed keys," and "Create key," currently at Step 1: "Configure key." The "Key type" can be set to "Symmetric" (selected) or "Asymmetric." Under "Advanced options," the setting "Key material origin" can be "KMS" (selected), "External," or "Custom key store (CloudHSM)."

Step 1: Choosing a symmetric key type.

 

 

A screenshot of AWS with the same breadcrumbs, now at Step 2: "Add labels." An Alias field is set to "cwlg," an optional Description field is left blank, and an optional Tags field has no tags added.

Step 2: Naming our key.

 

 

A screenshot of AWS with the same breadcrumbs, now at Step 3: "Define key administrative permissions." The first field, "Key administrators," has a blank search box with 10 rows of results (page 1 of 3) with columns Name, Path, and Type. Only the first row (with respective column values "admin," "/," and "User") has its corresponding checkbox checked. The other field, "Key deletion," has a single option, "Allow key administrators to delete this key," which has its checkbox checked as well.

Step 3 (optional): Assigning an administrator.

 

We recommend assigning an administrator so that the key can be managed by users other than the AWS account root user, but if others won’t need access, we can skip Step 3.

Here we chose the IAM user “admin” as a key administrator, but we’re free to choose any user or role. We can also opt to disable key deletion permission for the administrator.

 

A screenshot of AWS with the same breadcrumbs, now at Step 4: "Define key usage permissions." The first field, "This account," has the same search results as in Step 3, but none of them are checked. The other field, "Other AWS accounts," has nothing added to it.

Step 4: Skipping the user assignment page.

 

We won’t be assigning any users to this key because we want this key to be used only by the CloudWatch Logs service for SSH log encryption and decryption operations.

 

A screenshot of AWS with the same breadcrumbs, now at Step 5: "Review." The first field, "Key configuration," lists the "Key type" as "Symmetric," the "Key spec" as "SYMMETRIC_DEFAULT," the "Key usage" as "Encrypt and decrypt," and the "Origin" as "AWS_KMS." The next field, "Alias and description," lists one Alias, "cwlg," with no Description. The next field, "Tags," shows no data. The last field, "Key policy," includes a textbox prefilled with a policy in JSON format.

Step 5: Review our configuration and swap the default key policy.

 

On the Review page, we will need to change the KMS-generated key policy because it doesn’t include permissions for CloudWatch Logs to use the key. We’ll replace it with this policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::ACCOUNT_ID:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::ACCOUNT_ID:user/USERNAME"
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow access to CloudWatch Log",
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.REGION.amazonaws.com"
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*",
            "Condition": {
                "ArnLike": {
                    "kms:EncryptionContext:aws:logs:arn": "arn:aws:logs:REGION:ACCOUNT_ID:*"
                }
            }
        }
    ]
}

Make sure to replace all the placeholders:

  • ACCOUNT_ID becomes our AWS account ID.
  • USERNAME becomes the administrator username selected in Step 3. If we opted out of that step, here we remove the second statement block (the one with "Sid": "Allow access for Key Administrators").
  • REGION becomes the regional identifier code we are deploying services to (e.g., us-west-1).

With that, KMS is ready to go.

CloudWatch Log Group

Next we need a CloudWatch Log group (and/or an S3 bucket—see below) where SSM Agent can send SSH session logs. Let’s create it.

 

A screenshot of AWS with breadcrumbs "CloudWatch," "CloudWatch Logs," "Log groups," and "Create log group." There is no multistep sidebar. The first field, "Log group details," has three sub-fields: "Log group name" (set to "ssm-session-demo"), "Retention setting" (set to "Never expire" from a dropdown), and "KMS key ARN - optional" (set to a truncated value beginning with "arn:aws:kms"). The second field, "Tags," has no tags.

Creating a “CloudWatch Logs” log group.

 

Note the KMS key ARN field: AWS provides us with the value needed here after the key is created in Step 5 of the KMS section.

(If we didn’t associate the correct policy to our KMS key earlier, allowing the CloudWatch Logs service to use the key, we’ll receive an error related to the KMS key at this point.)

Storing SSH Logs in an S3 Bucket

For storing activity logs with S3 instead of—or in addition to—CloudWatch Logs, we need to add these permissions to our EC2 instance profile as a separate policy (or manually combine them with other permissions we may need associated):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::BUCKET_NAME/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetEncryptionConfiguration"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "kms:GenerateDataKey",
            "Resource": "*"
        }
    ]
}

In the above snippet, be sure to replace the BUCKET_NAME placeholder.

Now that we’ve set up somewhere to store the logs—CloudWatch Logs, an S3 bucket, or both—we’re ready to tap into SSH sessions.

AWS Systems Manager Session Manager

This is the final key step, where we configure secure access to our Linux machine for SSH session monitoring and logging. We’ll start at the Session Manager dashboard.

 

A screenshot of the AWS Session Manager dashboard with sections, "How it works," "Why use Session Manager?," "Getting started," "More resources," and in the upper-right corner, "Start a session." The latter section has an orange "Start Session" button and a white "Configure Preferences" button.

Step 1: Getting started with the dashboard.

 

On the dashboard, click on the white “Configure Preferences” button in the upper-right “Start a session” box to enable session logging.

On the Preferences page, we will find multiple sections that we could explore, but our focus will be on streaming SSH session logs to CloudWatch or S3 to allow us to quickly see what is happening within our Linux machine.

 

A screenshot of an AWS section entitled "CloudWatch logging." Its first setting, also called "CloudWatch logging," has a checkbox labeled Enable that is checked. The next setting, "Choose your preferred logging option," has "Stream session logs (Recommended)" selected instead of "Upload session logs." The next setting, "Enforce encryption," has a checkbox labeled "Allow only encrypted CloudWatch log groups" that is checked. The final setting, "CloudWatch log group," has "Choose a log group name from the list" selected instead of "Enter a log group in the text box." Beneath it is a list, "CloudWatch log groups," with "ssm-session-demo" selected. It has corresponding columns "Encryption" (set to "Encrypted"), "Expire events after" (set to "Never expire"), "Metric filters" (set to 0), "Stored bytes" (set to 0), and a "Creation time" timestamp.

Step 2a: Enabling CloudWatch logging.

 

Just after the “CloudWatch logging” section, there’s an “S3 logging” section where we can select the bucket.

 

A screenshot of an AWS section entitled "S3 logging." Its first setting, "Send session logs to S3," has a checkbox labeled "Enable" that is checked. Its next setting, "Enforce encryption," has a checkbox labeled "Allow only encrypted S3 buckets" that is checked. Its next setting, "Choose S3 bucket," has "Choose a bucket name from the list" selected instead of "Enter a bucket name in the textbox." Beneath that, "ssm-session-demo" is selected from a drop-down list. The last field, "S3 key prefix - optional," is blank.

Step 2b: Enabling S3 logging.

 

Once SSH logging is configured, we can SSH into our Linux machine and execute some commands to see if the activity is getting captured or not.

So, let’s start a session. On the same page, we will find a “Sessions” tab where we can start a session. Clicking the “Start session” button will give us a list of EC2 machines on which we can initiate a session:

 

A screenshot of AWS with breadcrumbs AWS Systems Manager, Session Manager, and Start a session. A "Target instances" search box has no query filled in and only one result, with "Instance name" set to "SSM Demo."

Step 3: Selecting our EC2 instance to start an SSH session with.

 

If we don’t see our EC2 Linux instance in the list, we should check whether it’s in a running state and has the IAM permissions associated with it that we described earlier.

Handling an SSM Agent “Doesn’t Support Streaming Logs” Error

In case we receive an error saying the SSM Agent version installed on our EC2 machine does not support streaming CloudWatch logs, not to worry. There’s a painless way to fix this.

 

A screenshot of an AWS error message with white text on a red background. A circled X is next to the message, "The SSM Agent version installed on this instance doesn't support streaming logs to CloudWatch. Either update the SSM Agent to the latest version, or disable the streaming logs option in your preferences."A potential “outdated SSM agent version” error.

 

To update the SSM Agent, we need to navigate to Run Command in the left panel of the AWS Systems Manager service.

 

A screenshot of the AWS Systems Manager Run Command dashboard with sections, "How it works," "Features and Benefits," "Use Cases and Blogposts," "Documentation," and in the upper-right corner, "Manage your instances." That section contains only an orange "Run a Command" button.Step 1: Starting with the “Run Command” dashboard.

 

Once we’re there, we can click on the orange “Run a Command” button, leading to a new page where we can fill in some parameters.

 

A screenshot of AWS with breadcrumbs AWS Systems Manager, Run Command, and Run a command. A search box labeled "Command document" lists 10 rows (page 4 of more than 5), with one named "AWS-UpdateSSMAgent" selected. It has "Amazon" in its "Owner" column and "Windows, Linux" in its "Platform types" column. A field at the bottom, "Document version," has "1 (Default)" selected from a drop-down list.Step 2: Selecting a command document.

 

We’ll start by selecting AWS-UpdateSSMAgent from the list.

 

A screenshot of an AWS section entitled "Targets." The first field, also called "Targets," has options "Specify instance tags," "Choose instances manually" (selected), and "Choose a resource group." At the bottom is an "Instances" search box with no query, with its only result, "SSM Demo," checked. The corresponding instance ID in the row is copied to a box just above "Instances" with an X.Step 3: Selecting the EC2 instance that has an SSM agent in need of an update.

 

Once that’s selected, we’ll scroll down until we see the “Targets” section. There we need to select the EC2 instance on which we want to update the SSM Agent, then hit the “Run” button at the end. This will send us to a page where we can monitor the progress of the update.

 

A screenshot of AWS with breadcrumbs "AWS Systems Manager," "Run Command," and "Command ID" (followed by a GUID). The first section, "Command status," shows success indicators, as does the only row of the next section, "Targets and outputs," which lists the single instance from earlier. There are also two unexpanded sections at the bottom, "Command description" and "Command parameters."Step 4: Monitoring our update progress.

 

The agent update shouldn’t take more than five minutes. Once that’s done, we should be able to create a session back in the Session Manager.

At this point, we should have an SSH session started.

 

A screenshot of AWS with a session ID and instance ID above a terminal. The prompt is "sh-4.2$" and the commands "whoami" and "pwd" have been entered, with the outputs "ssm-user" and "/usr/bin" respectively.

An SSH session using the SSM agent via AWS Systems Manager Session Manager.

 

After executing a few commands, let’s navigate to the CloudWatch Logs log group (or our S3 bucket, not shown) and confirm that the activity is being recorded.

 

A screenshot of AWS with breadcrumbs "CloudWatch," "CloudWatch Logs," "Log groups," "ssm-session-demo," and the session ID of the previous step. The only section is a search box, "Log events," with rows that each have a timestamp and a JSON-formatted message. One of them is expanded to reveal its JSON pretty-printed and with a white button to the right labeled "Copy."

SSH log events being recorded in CloudWatch Logs.

We now have a setup, with at-rest encryption enabled, recording every command fired in our Linux machine.

In fact, every command may be more than we want: Any secrets provided or generated during the session will be recorded in CloudWatch or S3 and can be seen by anyone who has the required permissions. To prevent that, we can use stty -echo; read passwd; stty echo; for each secret we need to provide during the session.

A Great SSM/SSH AWS Logging Solution With Minor Caveats

Session Manager is a useful tool to gain remote access to our virtual machines in AWS without having to open port 22. In fact, we can’t generate SSH logs this way if we use port forwarding or a direct SSH connection, as the Session Manager documentation notes.

Nonetheless, combining Session Manager with session logging is a robust solution for controlling and monitoring activity within VMs. Moreover, we’re not charged for using the Session Manager service. We only pay for our EC2 instance and CloudWatch Logs or an S3 bucket for storing logs.

For readers who prefer video tutorials, I’ve covered a very similar procedure a bit more thoroughly on YouTube.

Original article source at: https://www.toptal.com/

#aws #ssm #logging #ssh 

How to SSH Logging and Session Management using AWS SSM
Reid  Rohan

Reid Rohan

1667124660

Xterm.js: A Terminal for The Web

Xterm.js

Xterm.js is a front-end component written in TypeScript that lets applications bring fully-featured terminals to their users in the browser. It's used by popular projects such as VS Code, Hyper and Theia.

Features

  • Terminal apps just work: Xterm.js works with most terminal apps such as bash, vim, and tmux, including support for curses-based apps and mouse events.
  • Performant: Xterm.js is really fast, it even includes a GPU-accelerated renderer.
  • Rich Unicode support: Supports CJK, emojis, and IMEs.
  • Self-contained: Requires zero dependencies to work.
  • Accessible: Screen reader and minimum contrast ratio support can be turned on.
  • And much more: Links, theming, addons, well documented API, etc.

What xterm.js is not

  • Xterm.js is not a terminal application that you can download and use on your computer.
  • Xterm.js is not bash. Xterm.js can be connected to processes like bash and let you interact with them (provide input, receive output).

Getting Started

First, you need to install the module, we ship exclusively through npm, so you need that installed and then add xterm.js as a dependency by running:

npm install xterm

To start using xterm.js on your browser, add the xterm.js and xterm.css to the head of your HTML page. Then create a <div id="terminal"></div> onto which xterm can attach itself. Finally, instantiate the Terminal object and then call the open function with the DOM object of the div.

<!doctype html>
  <html>
    <head>
      <link rel="stylesheet" href="node_modules/xterm/css/xterm.css" />
      <script src="node_modules/xterm/lib/xterm.js"></script>
    </head>
    <body>
      <div id="terminal"></div>
      <script>
        var term = new Terminal();
        term.open(document.getElementById('terminal'));
        term.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ')
      </script>
    </body>
  </html>

Importing

The recommended way to load xterm.js is via the ES6 module syntax:

import { Terminal } from 'xterm';

Addons

⚠️ This section describes the new addon format introduced in v3.14.0, see here for the instructions on the old format

Addons are separate modules that extend the Terminal by building on the xterm.js API. To use an addon, you first need to install it in your project:

npm i -S xterm-addon-web-links

Then import the addon, instantiate it and call Terminal.loadAddon:

import { Terminal } from 'xterm';
import { WebLinksAddon } from 'xterm-addon-web-links';

const terminal = new Terminal();
// Load WebLinksAddon on terminal, this is all that's needed to get web links
// working in the terminal.
terminal.loadAddon(new WebLinksAddon());

The xterm.js team maintains the following addons, but anyone can build them:

Browser Support

Since xterm.js is typically implemented as a developer tool, only modern browsers are supported officially. Specifically the latest versions of Chrome, Edge, Firefox, and Safari.

Xterm.js works seamlessly in Electron apps and may even work on earlier versions of the browsers. These are the versions we strive to keep working.

Node.js Support

We also publish xterm-headless which is a stripped down version of xterm.js that runs in Node.js. An example use case for this is to keep track of a terminal's state where the process is running and using the serialize addon so it can get all state restored upon reconnection.

API

The full API for xterm.js is contained within the TypeScript declaration file, use the branch/tag picker in GitHub (w) to navigate to the correct version of the API.

Note that some APIs are marked experimental, these are added to enable experimentation with new ideas without committing to support it like a normal semver API. Note that these APIs can change radically between versions, so be sure to read release notes if you plan on using experimental APIs.

Releases

Xterm.js follows a monthly release cycle roughly.

All current and past releases are available on this repo's Releases page, you can view the high-level roadmap on the wiki and see what we're working on now by looking through Milestones.

Beta builds

Our CI releases beta builds to npm for every change that goes into master. Install the latest beta build with:

npm install -S xterm@beta

These should generally be stable, but some bugs may slip in. We recommend using the beta build primarily to test out new features and to verify bug fixes.

Contributing

You can read the guide on the wiki to learn how to contribute and set up xterm.js for development.

Real-world uses

Xterm.js is used in several world-class applications to provide great terminal experiences.

  • SourceLair: In-browser IDE that provides its users with fully-featured Linux terminals based on xterm.js.
  • Microsoft Visual Studio Code: Modern, versatile, and powerful open source code editor that provides an integrated terminal based on xterm.js.
  • ttyd: A command-line tool for sharing terminal over the web, with fully-featured terminal emulation based on xterm.js.
  • Katacoda: Katacoda is an Interactive Learning Platform for software developers, covering the latest Cloud Native technologies.
  • Eclipse Che: Developer workspace server, cloud IDE, and Eclipse next-generation IDE.
  • Codenvy: Cloud workspaces for development teams.
  • CoderPad: Online interviewing platform for programmers. Run code in many programming languages, with results displayed by xterm.js.
  • WebSSH2: A web based SSH2 client using xterm.js, socket.io, and ssh2.
  • Spyder Terminal: A full fledged system terminal embedded on Spyder IDE.
  • Cloud Commander: Orthodox web file manager with console and editor.
  • Next Tech: Online platform for interactive coding and web development courses. Live container-backed terminal uses xterm.js.
  • RStudio: RStudio is an integrated development environment (IDE) for R.
  • Terminal for Atom: A simple terminal for the Atom text editor.
  • Eclipse Orion: A modern, open source software development environment that runs in the cloud. Code, deploy, and run in the cloud.
  • Gravitational Teleport: Gravitational Teleport is a modern SSH server for remotely accessing clusters of Linux servers via SSH or HTTPS.
  • Hexlet: Practical programming courses (JavaScript, PHP, Unix, databases, functional programming). A steady path from the first line of code to the first job.
  • Selenoid UI: Simple UI for the scalable golang implementation of Selenium Hub named Selenoid. We use XTerm for streaming logs over websockets from docker containers.
  • Portainer: Simple management UI for Docker.
  • SSHy: HTML5 Based SSHv2 Web Client with E2E encryption utilising xterm.js, SJCL & websockets.
  • JupyterLab: An extensible computational environment for Jupyter, supporting interactive data science and scientific computing across all programming languages.
  • Theia: Theia is a cloud & desktop IDE framework implemented in TypeScript.
  • Opshell Ops Helper tool to make life easier working with AWS instances across multiple organizations.
  • Proxmox VE: Proxmox VE is a complete open-source platform for enterprise virtualization. It uses xterm.js for container terminals and the host shell.
  • Script Runner: Run scripts (or a shell) in Atom.
  • Whack Whack Terminal: Terminal emulator for Visual Studio 2017.
  • VTerm: Extensible terminal emulator based on Electron and React.
  • electerm: electerm is a terminal/ssh/sftp client(mac, win, linux) based on electron/node-pty/xterm.
  • Kubebox: Terminal console for Kubernetes clusters.
  • Azure Cloud Shell: Azure Cloud Shell is a Microsoft-managed admin machine built on Azure, for Azure.
  • atom-xterm: Atom plugin for providing terminals inside your Atom workspace.
  • rtty: Access your terminals from anywhere via the web.
  • Pisth: An SFTP and SSH client for iOS.
  • abstruse: Abstruse CI is a continuous integration platform based on Node.JS and Docker.
  • Azure Data Studio: A data management tool that enables working with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux.
  • FreeMAN: A free, cross-platform file manager for power users.
  • Fluent Terminal: A terminal emulator based on UWP and web technologies.
  • Hyper: A terminal built on web technologies.
  • Diag: A better way to troubleshoot problems faster. Capture, share and reapply troubleshooting knowledge so you can focus on solving problems that matter.
  • GoTTY: A simple command line tool that shares your terminal as a web application based on xterm.js.
  • genact: A nonsense activity generator.
  • cPanel & WHM: The hosting platform of choice.
  • Nutanix: Nutanix Enterprise Cloud uses xterm in the webssh functionality within Nutanix Calm, and is also looking to move our old noserial (termjs) functionality to xterm.js.
  • SSH Web Client: SSH Web Client with PHP.
  • Juno: A flexible Julia IDE, based on Atom.
  • webssh: Web based ssh client.
  • info-beamer hosted: Uses xterm.js to manage digital signage devices from the web dashboard.
  • Jumpserver: Jumpserver Luna project, Jumpserver is a bastion server project, Luna use xterm.js for web terminal emulation.
  • LxdMosaic: Uses xterm.js to give terminal access to containers through LXD
  • CodeInterview.io: A coding interview platform in 25+ languages and many web frameworks. Uses xterm.js to provide shell access.
  • Bastillion: Bastillion is an open-source web-based SSH console that centrally manages administrative access to systems.
  • PHP App Server: Create lightweight, installable almost-native applications for desktop OSes. ExecTerminal (nicely wraps the xterm.js Terminal), TerminalManager, and RunProcessSDK are self-contained, reusable ES5+ compliant Javascript components.
  • NgTerminal: NgTerminal is a web terminal that leverages xterm.js on Angular 7+. You can easily add it into your application by adding <ng-terminal></ng-terminal> into your component.
  • tty-share: Extremely simple terminal sharing over the Internet.
  • Ten Hands: One place to run your command-line tasks.
  • WebAssembly.sh: A WebAssembly WASI browser terminal
  • Gus: A shared coding pad where you can run Python with xterm.js
  • Linode: Linode uses xterm.js to provide users a web console for their Linode instances.
  • FluffOS: Active maintained LPMUD driver with websocket support.
  • x-terminal: Atom plugin for providing terminals inside your Atom workspace.
  • CoCalc: Lots of free software pre-installed, to chat, collaborate, develop, program, publish, research, share, teach, in C++, HTML, Julia, Jupyter, LaTeX, Markdown, Python, R, SageMath, Scala, ...
  • Dank Domain: Open source multiuser medieval game supporting old & new terminal emulation.
  • DockerStacks: Local LAMP/LEMP development studio
  • Codecademy: Uses xterm.js in its courses on Bash.
  • Laravel Ssh Web Client: Laravel server inventory with ssh web client to connect at server using xterm.js
  • Replit: Collaborative browser based IDE with support for 50+ different languages.
  • TeleType: cli tool that allows you to share your terminal online conveniently. Show off mad cli-fu, help a colleague, teach, or troubleshoot.
  • Intervue: Pair programming for interviews. Multiple programming languages are supported, with results displayed by xterm.js.
  • TRASA: Zero trust access to Web, SSH, RDP, and Database services.
  • Commas: Commas is a hackable terminal and command runner.
  • Devtron: Software Delivery Workflow For Kubernetes.
  • NxShell: An easy to use new terminal for SSH.
  • gifcast: Converts an asciinema cast to an animated GIF.
  • WizardWebssh: A terminal with Pyqt5 Widget for embedding, which can be used as an ssh client to connect to your ssh servers. It is written in Python, based on tornado, paramiko, and xterm.js.
  • Wizard Assistant: Wizard Assistant comes with advanced automation tools, preloaded common and special time-saving commands, and a built-in SSH terminal. Now you can remotely administer, troubleshoot, and analyze any system with ease.
  • ucli: Command Line for everyone :family_man_woman_girl_boy: at www.ucli.tech.
  • Tess: Simple Terminal Fully Customizable for Everyone. Discover more at tessapp.dev
  • HashiCorp Nomad: A container orchestrator with the ability to connect to remote tasks via a web interface using websockets and xterm.js.
  • TermPair: View and control terminals from your browser with end-to-end encryption
  • gdbgui: Browser-based frontend to gdb (gnu debugger)
  • goormIDE: Run almost every programming languages with real-time collaboration, live pair programming, and built-in messenger.
  • FleetDeck: Remote desktop & virtual terminal
  • OpenSumi: A framework helps you quickly build Cloud or Desktop IDE products.
  • KubeSail: The Self-Hosting Company - uses xterm to allow users to exec into kubernetes pods and build github apps
  • WiTTY: Web-based interactive terminal emulator that allows users to easily record, share, and replay console sessions.
  • libv86 Terminal Forwarding: Peer-to-peer SSH for the web, using WebRTC via Bugout for data transfer and v86 for web-based virtualization.
  • hack.courses: Interactive Linux and command-line classes using xterm.js to expose a real terminal available for everyone.
  • Render: Platform-as-a-service for your apps, websites, and databases using xterm.js to provide a command prompt for user containers and for streaming build and runtime logs.
  • CloudTTY: A Friendly Kubernetes CloudShell (Web Terminal).
  • Go SSH Web Client: A simple SSH web client using Go, WebSocket and Xterm.js.
  • web3os: A decentralized operating system for the next web
  • Cratecode: Learn to program for free through interactive online lessons. Cratecode uses xterm.js to give users access to their own Linux environment.
  • And much more...

Do you use xterm.js in your application as well? Please open a Pull Request to include it here. We would love to have it on our list. Note: Please add any new contributions to the end of the list only.

Download Details:

Author: xtermjs
Source Code: https://github.com/xtermjs/xterm.js 
License: MIT license

#typescript #javascript #console #ssh 

Xterm.js: A Terminal for The Web

PHPseclib: PHP Secure Communications Library

phpseclib - PHP Secure Communications Library

Supporting phpseclib

Introduction

MIT-licensed pure-PHP implementations of the following:

SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / Ed449 / Curve25519 / Curve449, ECDSA / ECDH (with support for 66 curves), RSA (PKCS#1 v2.2 compliant), DSA / DH, DES / 3DES / RC4 / Rijndael / AES / Blowfish / Twofish / Salsa20 / ChaCha20, GCM / Poly1305

Documentation

Branches

master

  • Development Branch
  • Unstable API
  • Do not use in production

3.0

  • Long term support (LTS) release
  • Major expansion of cryptographic primitives
  • Minimum PHP version: 5.6.1
  • PSR-4 autoloading with namespace rooted at \phpseclib3
  • Install via Composer: composer require phpseclib/phpseclib:~3.0

2.0

  • Long term support (LTS) release
  • Modernized version of 1.0
  • Minimum PHP version: 5.3.3
  • PSR-4 autoloading with namespace rooted at \phpseclib
  • Install via Composer: composer require phpseclib/phpseclib:~2.0

1.0

Security contact information

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.

Support

Need Support?

Special Thanks

Special Thanks to our $50+ sponsors!:

Contributing

Fork the Project

Ensure you have Composer installed (see Composer Download Instructions)

Install Development Dependencies

composer install

Create a Feature Branch

Run continuous integration checks:

composer global require php:^8.1 squizlabs/php_codesniffer friendsofphp/php-cs-fixer vimeo/psalm
phpcs --standard=build/php_codesniffer.xml
php-cs-fixer fix --config=build/php-cs-fixer.php --diff --dry-run --using-cache=no
psalm --config=build/psalm.xml --no-cache --long-progress --report-show-info=false --output-format=text
vendor/bin/phpunit --verbose --configuration tests/phpunit.xml

Send us a Pull Request

Download Details:

Author: phpseclib
Source Code: https://github.com/phpseclib/phpseclib 
License: MIT license

#php #ssh 

PHPseclib: PHP Secure Communications Library
Elian  Harber

Elian Harber

1665114240

Teleport: The Easiest, Most Secure Way to Access infrastructure

Introduction

Teleport is the easiest, most secure way to access all your infrastructure. Teleport is an identity-aware, multi-protocol access proxy which understands SSH, HTTPS, RDP, Kubernetes API, MySQL, MongoDB and PostgreSQL wire protocols.

On the server-side, Teleport is a single binary which enables convenient secure access to behind-NAT resources such as:

Teleport is trivial to set up as a Linux daemon or in a Kubernetes pod. It's rapidly replacing legacy sshd-based setups at organizations who need:

  • Developer convenience of having instant secure access to everything they need across many environments and cloud providers.
  • Audit log with session recording/replay for multiple protocols
  • Easily manage trust between teams, organizations and data centers.
  • Role-based access control (RBAC) and flexible access workflows (one-time access requests)

In addition to its hallmark features, Teleport is interesting for smaller teams because it facilitates easy adoption of the best infrastructure security practices like:

  • No need to manage shared secrets such as SSH keys: Teleport uses certificate-based access with automatic certificate expiration time for all protocols.
  • Two-factor authentication (2FA) for everything.
  • Collaboratively troubleshoot issues through session sharing.
  • Single sign-on (SSO) for everything via Github Auth, OpenID Connect, or SAML with endpoints like Okta or Active Directory.
  • Infrastructure introspection: Use Teleport via the CLI or Web UI to view the status of every SSH node, database instance, Kubernetes cluster, or internal web app.

Teleport is built upon the high-quality Golang SSH implementation. It is fully compatible with OpenSSH, sshd servers, and ssh clients.

Project LinksDescription
Teleport WebsiteThe official website of the project.
DocumentationAdmin guide, user manual and more.
Demo Video3-minute video overview of Teleport.
BlogOur blog where we publish Teleport news.
ForumAsk us a setup question, post your tutorial, feedback, or idea on our forum.
SlackNeed help with your setup? Ping us in our Slack channel.
Cloud-hostedWe offer Enterprise with a Cloud-hosted option. For teams that require easy and secure access to their computing environments.

Installing and Running

| Follow the Installation Guide

Download the latest binary release, unpack the .tar.gz and run sudo ./install. This will copy Teleport binaries into /usr/local/bin.

Then you can run Teleport as a single-node cluster:

sudo teleport start

In a production environment, Teleport must run as root. For testing or non-production environments, run it as the $USER:

chown $USER /var/lib/teleport

  • In this case, you will not be able to log in as another user.

Docker

| Follow the Docker-Compose Getting Started Guide

Deploy Teleport

If you wish to deploy Teleport inside a Docker container:

# This command will pull the Teleport container image for version 8
docker pull public.ecr.aws/gravitational/teleport:8

View latest tags on Amazon ECR Public | gravitational/teleport

For Local Testing and Development

Follow the instructions in the docker/README file.

To run a full test suite locally, see the test dependecies list

Building Teleport

The teleport repository contains the Teleport daemon binary (written in Go) and a web UI written in Javascript (a git submodule located in the webassets/ directory).

If your intention is to build and deploy for use in a production infrastructure a released tag should be used. The default branch, master, is the current development branch for an upcoming major version. Get the latest release tags listed at https://goteleport.com/download/ and then use that tag in the git clone. For example git clone https://github.com/gravitational/teleport.git -b v9.1.2 gets release v9.1.2.

Dockerized Build

It is often easiest to build with Docker, which ensures that all required tooling is available for the build. To execute a dockerized build, ensure that docker is installed and running, and execute:

make -C build.assets build-binaries

Local Build

Dependencies

Ensure you have installed correct versions of necessary dependencies:

  • Go version from go.mod
  • If you wish to build the Rust-powered features like Desktop Access, see the Rust and Cargo version in build.assets/Makefile (search for RUST_VERSION)
  • For tsh version > 10.x with FIDO support, you will need libfido and openssl 1.1 installed locally

For an example of Dev Environment setup on a Mac, see these instructions.

Perform a build

Important

  • The Go compiler is somewhat sensitive to the amount of memory: you will need at least 1GB of virtual memory to compile Teleport. A 512MB instance without swap will not work.
  • This will build the latest version of Teleport, regardless of whether it is stable. If you want to build the latest stable release, run git checkout and git submodule update --recursive to the corresponding tag (for example,
  • run git checkout v8.0.0) before performing a build.

Get the source

git clone https://github.com/gravitational/teleport.git
cd teleport

To perform a build

make full

To build tsh with Apple TouchID support enabled:

Important

tsh binaries with Touch ID support are only functional using binaries signed with Teleport's Apple Developer ID and notarized by Apple. If you are a Teleport maintainer, ask the team for access.

make build/tsh TOUCHID=yes

To build tsh with libfido:

make build/tsh FIDO2=dynamic

On a Mac, with libfido and openssl 1.1 installed via homebrew

export PKG_CONFIG_PATH="$(brew --prefix openssl@1.1)/lib/pkgconfig"
make build/tsh FIDO2=dynamic

Build output and running locally

If the build succeeds, the installer will place the binaries in the build directory.

Before starting, create default data directories:

sudo mkdir -p -m0700 /var/lib/teleport
sudo chown $USER /var/lib/teleport

Web UI

The Teleport Web UI resides in the Gravitational Webapps repo.

Rebuilding Web UI for development

To clone this repository and rebuild the Teleport UI package, run the following commands:

git clone git@github.com:gravitational/webapps.git
cd webapps
make build-teleport

Then you can replace Teleport Web UI files with the files from the newly-generated /dist folder.

To enable speedy iterations on the Web UI, you can run a local web-dev server.

You can also tell Teleport to load the Web UI assets from the source directory. To enable this behavior, set the environment variable DEBUG=1 and rebuild with the default target:

# Run Teleport as a single-node cluster in development mode:
DEBUG=1 ./build/teleport start -d

Keep the server running in this mode, and make your UI changes in /dist directory. For instructions about how to update the Web UI, read the webapps README file.

Updating Web UI assets

After you commit a change to the webapps repo, you need to update the Web UI assets in the webassets/ git submodule.

Run make update-webassets to update the webassets repo and create a PR for teleport to update its git submodule.

You will need to have the gh utility installed on your system for the script to work. For installation instructions, read the GitHub CLI installation documentation.

Managing dependencies

All dependencies are managed using Go modules. Here are the instructions for some common tasks:

Add a new dependency

Latest version:

go get github.com/new/dependency

and update the source to use this dependency.

To get a specific version, use go get github.com/new/dependency@version instead.

Set dependency to a specific version

go get github.com/new/dependency@version

Update dependency to the latest version

go get -u github.com/new/dependency

Update all dependencies

go get -u all

Debugging dependencies

Why is a specific package imported?

go mod why $pkgname

Why is a specific module imported?

go mod why -m $modname

Why is a specific version of a module imported?

go mod graph | grep $modname

Why did We Build Teleport?

The Teleport creators used to work together at Rackspace. We noticed that most cloud computing users struggle with setting up and configuring infrastructure security because popular tools, while flexible, are complex to understand and expensive to maintain. Additionally, most organizations use multiple infrastructure form factors such as several cloud providers, multiple cloud accounts, servers in colocation, and even smart devices. Some of those devices run on untrusted networks, behind third-party firewalls. This only magnifies complexity and increases operational overhead.

We had a choice, either start a security consulting business or build a solution that's dead-easy to use and understand. A real-time representation of all of your servers in the same room as you, as if they were magically teleported. Thus, Teleport was born!

More Information

Support and Contributing

We offer a few different options for support. First of all, we try to provide clear and comprehensive documentation. The docs are also in Github, so feel free to create a PR or file an issue if you have ideas for improvements. If you still have questions after reviewing our docs, you can also:

  • Join Teleport Discussions to ask questions. Our engineers are available there to help you.
  • If you want to contribute to Teleport or file a bug report/issue, you can create an issue here in Github.
  • If you are interested in Teleport Enterprise or more responsive support during a POC, we can also create a dedicated Slack channel for you during your POC. You can reach out to us through our website to arrange for a POC.

Is Teleport Secure and Production Ready?

Teleport is used by leading companies to enable engineers to quickly access any computing resource anywhere. Teleport has completed several security audits from the nationally recognized technology security companies. We make some our audits public, view our latest audit reports.. We are comfortable with the use of Teleport from a security perspective.

You can see the list of companies who use Teleport in production on the Teleport product page.

You can find the latest stable Teleport build on our Releases page.

Who Built Teleport?

Teleport was created by Gravitational Inc. We have built Teleport by borrowing from our previous experiences at Rackspace. Learn more about Teleport and our history.

Read our Blog: https://goteleport.com/blog/

Read our Documentation: https://goteleport.com/docs/getting-started/

Download Details:

Author: Gravitational
Source Code: https://github.com/gravitational/teleport 
License: Apache-2.0 license

#go #golang #kubernetes #ssh 

Teleport: The Easiest, Most Secure Way to Access infrastructure
Elian  Harber

Elian Harber

1665061140

Cloud Enhanced SSH Client Replacement with Host Auto-completion

cloud-ssh

Cloud enhanced SSH client replacement with host auto-completion.

In times of digital clouds, servers come and go, and you barely remember its names and addresses. This tiny tool provide fuzzy search (yeah like SublimeText) for your instances list, based on tags, security groups and names.

Installation

Automatic installation. Just run following code in your terminal

  bash <(curl -# https://buger.github.io/cloud-ssh/install.sh)

Manual installation - download and unpack latest release: http://github.com/buger/cloud-ssh/releases

Examples

sh-3.2$ # Lets say i want connect to server called stage-matching
sh-3.2$ ./cloud-ssh leon@stama
Found config: /Users/buger/.ssh/cloud-ssh.yaml
Found clound instance:
Cloud: granify_ec2      Matched by: aws:autoscaling:groupName=stage-matching    Addr: ec2-50-200-40-200.compute-1.amazonaws.com

Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-25-virtual x86_64)

If there are more then 1 server matching your query, it will ask you to choose one:

sh-3.2$ # I want to check one of my CouchBase servers
sh-3.2$ ./cloud-ssh ubuntu@couch
Found config: /Users/buger/.ssh/cloud-ssh.yaml
Found multiple instances:
1)  Cloud: granify_ec2  Matched by: Name=couchbase-02   Addr: ec2-50-200-40-201.compute-1.amazonaws.com
2)  Cloud: granify_ec2  Matched by: Name=couchbase-03   Addr: ec2-50-200-40-202.compute-1.amazonaws.com
3)  Cloud: granify_ec2  Matched by: Name=couchbase-04   Addr: ec2-50-200-40-203.compute-1.amazonaws.com
4)  Cloud: granify_ec2  Matched by: Name=couchbase-01   Addr: ec2-50-200-40-204.compute-1.amazonaws.com
5)  Cloud: granify_ec2  Matched by: Name=couchbase-05   Addr: ec2-50-200-40-205.compute-1.amazonaws.com
Choose instance: 1
Welcome to Ubuntu 12.04.4 LTS (GNU/Linux 3.2.0-58-virtual x86_64)

Nice, right? More over, cloud-ssh can act as full ssh replacement, since it just forward all calls to ssh command.

Configuration

By default it checks your environment for AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables. If you want advanced configuration you can create cloud-ssh.yaml in one of this directories: ./ (current), ~/.ssh/, /etc/

Note that you can define multiple clouds, per provider, if you have multi-datacenter setup or just different clients. Cloud name will be included into search term, so you can filter by it too!

Right now only 2 data cloud providers supported: Amazon EC2 and DigitalOcean.

Example configuration:

gran_ec2: # cloud name, used when searching
    provider: aws 
    region: us-east-1
    access_key: AAAAAAAAAAAAAAAAA
    secret_key: BBBBBBBBBBBBBBBBBBBBBBBBB
    default_user: ubuntu
gran_digital:
    provider: digital_ocean
    client_id: 111111111111111111
    api_key: 22222222222222222

Faq

Can it be drop-in replacement for SSH?

Totally yes! Actually it just SSH wrapper, so all SSH command options will work as before.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Official site: https://buger.github.io/cloud-ssh/

Download Details:

Author: Buger
Source Code: https://github.com/buger/cloud-ssh 

#go #golang #cloud #ssh 

Cloud Enhanced SSH Client Replacement with Host Auto-completion
Reid  Rohan

Reid Rohan

1665012000

SSH2 Client and Server Modules Written in Pure JavaScript for Node.js

Description

SSH2 client and server modules written in pure JavaScript for node.js.

Development/testing is done against OpenSSH (8.7 currently).

Changes (breaking or otherwise) in v1.0.0 can be found here.

Requirements

  • node.js -- v10.16.0 or newer
    • node v12.0.0 or newer for Ed25519 key support
  • (Optional) cpu-features is set as an optional package dependency (you do not need to install it explicitly/separately from ssh2) that will be automatically built and used if possible. See the project's documentation for its own requirements.
    • This addon is currently used to help generate an optimal default cipher list

Installation

npm install ssh2

Client Examples

Execute 'uptime' on a server

const { readFileSync } = require('fs');

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.exec('uptime', (err, stream) => {
    if (err) throw err;
    stream.on('close', (code, signal) => {
      console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
      conn.end();
    }).on('data', (data) => {
      console.log('STDOUT: ' + data);
    }).stderr.on('data', (data) => {
      console.log('STDERR: ' + data);
    });
  });
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  privateKey: readFileSync('/path/to/my/key')
});

// example output:
// Client :: ready
// STDOUT:  17:41:15 up 22 days, 18:09,  1 user,  load average: 0.00, 0.01, 0.05
//
// Stream :: exit :: code: 0, signal: undefined
// Stream :: close

Start an interactive shell session

const { readFileSync } = require('fs');

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.shell((err, stream) => {
    if (err) throw err;
    stream.on('close', () => {
      console.log('Stream :: close');
      conn.end();
    }).on('data', (data) => {
      console.log('OUTPUT: ' + data);
    });
    stream.end('ls -l\nexit\n');
  });
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  privateKey: readFileSync('/path/to/my/key')
});

// example output:
// Client :: ready
// STDOUT: Last login: Sun Jun 15 09:37:21 2014 from 192.168.100.100
//
// STDOUT: ls -l
// exit
//
// STDOUT: frylock@athf:~$ ls -l
//
// STDOUT: total 8
//
// STDOUT: drwxr-xr-x 2 frylock frylock 4096 Nov 18  2012 mydir
//
// STDOUT: -rw-r--r-- 1 frylock frylock   25 Apr 11  2013 test.txt
//
// STDOUT: frylock@athf:~$ exit
//
// STDOUT: logout
//
// Stream :: close

Send a raw HTTP request to port 80 on the server

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.forwardOut('192.168.100.102', 8000, '127.0.0.1', 80, (err, stream) => {
    if (err) throw err;
    stream.on('close', () => {
      console.log('TCP :: CLOSED');
      conn.end();
    }).on('data', (data) => {
      console.log('TCP :: DATA: ' + data);
    }).end([
      'HEAD / HTTP/1.1',
      'User-Agent: curl/7.27.0',
      'Host: 127.0.0.1',
      'Accept: */*',
      'Connection: close',
      '',
      ''
    ].join('\r\n'));
  });
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  password: 'nodejsrules'
});

// example output:
// Client :: ready
// TCP :: DATA: HTTP/1.1 200 OK
// Date: Thu, 15 Nov 2012 13:52:58 GMT
// Server: Apache/2.2.22 (Ubuntu)
// X-Powered-By: PHP/5.4.6-1ubuntu1
// Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT
// Content-Encoding: gzip
// Vary: Accept-Encoding
// Connection: close
// Content-Type: text/html; charset=UTF-8
//
//
// TCP :: CLOSED

Forward local connections to port 8000 on the server to us

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.forwardIn('127.0.0.1', 8000, (err) => {
    if (err) throw err;
    console.log('Listening for connections on server on port 8000!');
  });
}).on('tcp connection', (info, accept, reject) => {
  console.log('TCP :: INCOMING CONNECTION:');
  console.dir(info);
  accept().on('close', () => {
    console.log('TCP :: CLOSED');
  }).on('data', (data) => {
    console.log('TCP :: DATA: ' + data);
  }).end([
    'HTTP/1.1 404 Not Found',
    'Date: Thu, 15 Nov 2012 02:07:58 GMT',
    'Server: ForwardedConnection',
    'Content-Length: 0',
    'Connection: close',
    '',
    ''
  ].join('\r\n'));
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  password: 'nodejsrules'
});

// example output:
// Client :: ready
// Listening for connections on server on port 8000!
//  (.... then from another terminal on the server: `curl -I http://127.0.0.1:8000`)
// TCP :: INCOMING CONNECTION: { destIP: '127.0.0.1',
//  destPort: 8000,
//  srcIP: '127.0.0.1',
//  srcPort: 41969 }
// TCP DATA: HEAD / HTTP/1.1
// User-Agent: curl/7.27.0
// Host: 127.0.0.1:8000
// Accept: */*
//
//
// TCP :: CLOSED

Get a directory listing via SFTP

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.sftp((err, sftp) => {
    if (err) throw err;
    sftp.readdir('foo', (err, list) => {
      if (err) throw err;
      console.dir(list);
      conn.end();
    });
  });
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  password: 'nodejsrules'
});

// example output:
// Client :: ready
// [ { filename: 'test.txt',
//     longname: '-rw-r--r--    1 frylock   frylock         12 Nov 18 11:05 test.txt',
//     attrs:
//      { size: 12,
//        uid: 1000,
//        gid: 1000,
//        mode: 33188,
//        atime: 1353254750,
//        mtime: 1353254744 } },
//   { filename: 'mydir',
//     longname: 'drwxr-xr-x    2 frylock   frylock       4096 Nov 18 15:03 mydir',
//     attrs:
//      { size: 1048576,
//        uid: 1000,
//        gid: 1000,
//        mode: 16877,
//        atime: 1353269007,
//        mtime: 1353269007 } } ]

Connection hopping

const { Client } = require('ssh2');

const conn1 = new Client();
const conn2 = new Client();

// Checks uptime on 10.1.1.40 via 192.168.1.1

conn1.on('ready', () => {
  console.log('FIRST :: connection ready');
  // Alternatively, you could use something like netcat or socat with exec()
  // instead of forwardOut(), depending on what the server allows
  conn1.forwardOut('127.0.0.1', 12345, '10.1.1.40', 22, (err, stream) => {
    if (err) {
      console.log('FIRST :: forwardOut error: ' + err);
      return conn1.end();
    }
    conn2.connect({
      sock: stream,
      username: 'user2',
      password: 'password2',
    });
  });
}).connect({
  host: '192.168.1.1',
  username: 'user1',
  password: 'password1',
});

conn2.on('ready', () => {
  // This connection is the one to 10.1.1.40

  console.log('SECOND :: connection ready');
  conn2.exec('uptime', (err, stream) => {
    if (err) {
      console.log('SECOND :: exec error: ' + err);
      return conn1.end();
    }
    stream.on('close', () => {
      conn1.end(); // close parent (and this) connection
    }).on('data', (data) => {
      console.log(data.toString());
    });
  });
});

Forward remote X11 connections

const { Socket } = require('net');

const { Client } = require('ssh2');

const conn = new Client();

conn.on('x11', (info, accept, reject) => {
  const xserversock = new net.Socket();
  xserversock.on('connect', () => {
    const xclientsock = accept();
    xclientsock.pipe(xserversock).pipe(xclientsock);
  });
  // connects to localhost:0.0
  xserversock.connect(6000, 'localhost');
});

conn.on('ready', () => {
  conn.exec('xeyes', { x11: true }, (err, stream) => {
    if (err) throw err;
    let code = 0;
    stream.on('close', () => {
      if (code !== 0)
        console.log('Do you have X11 forwarding enabled on your SSH server?');
      conn.end();
    }).on('exit', (exitcode) => {
      code = exitcode;
    });
  });
}).connect({
  host: '192.168.1.1',
  username: 'foo',
  password: 'bar'
});

Dynamic (1:1) port forwarding using a SOCKSv5 proxy (using socksv5)

const socks = require('socksv5');
const { Client } = require('ssh2');

const sshConfig = {
  host: '192.168.100.1',
  port: 22,
  username: 'nodejs',
  password: 'rules'
};

socks.createServer((info, accept, deny) => {
  // NOTE: you could just use one ssh2 client connection for all forwards, but
  // you could run into server-imposed limits if you have too many forwards open
  // at any given time
  const conn = new Client();
  conn.on('ready', () => {
    conn.forwardOut(info.srcAddr,
                    info.srcPort,
                    info.dstAddr,
                    info.dstPort,
                    (err, stream) => {
      if (err) {
        conn.end();
        return deny();
      }

      const clientSocket = accept(true);
      if (clientSocket) {
        stream.pipe(clientSocket).pipe(stream).on('close', () => {
          conn.end();
        });
      } else {
        conn.end();
      }
    });
  }).on('error', (err) => {
    deny();
  }).connect(sshConfig);
}).listen(1080, 'localhost', () => {
  console.log('SOCKSv5 proxy server started on port 1080');
}).useAuth(socks.auth.None());

// test with cURL:
//   curl -i --socks5 localhost:1080 google.com

Make HTTP(S) connections easily using a custom http(s).Agent

const http = require('http');

const { Client, HTTPAgent, HTTPSAgent } = require('ssh2');

const sshConfig = {
  host: '192.168.100.1',
  port: 22,
  username: 'nodejs',
  password: 'rules'
};

// Use `HTTPSAgent` instead for an HTTPS request
const agent = new HTTPAgent(sshConfig);
http.get({
  host: '192.168.200.1',
  agent,
  headers: { Connection: 'close' }
}, (res) => {
  console.log(res.statusCode);
  console.dir(res.headers);
  res.resume();
});

Invoke an arbitrary subsystem

const { Client } = require('ssh2');

const xmlhello = `
  <?xml version="1.0" encoding="UTF-8"?>
  <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <capabilities>
      <capability>urn:ietf:params:netconf:base:1.0</capability>
    </capabilities>
  </hello>]]>]]>`;

const conn = new Client();

conn.on('ready', () => {
  console.log('Client :: ready');
  conn.subsys('netconf', (err, stream) => {
    if (err) throw err;
    stream.on('data', (data) => {
      console.log(data);
    }).write(xmlhello);
  });
}).connect({
  host: '1.2.3.4',
  port: 22,
  username: 'blargh',
  password: 'honk'
});

Server Examples

Password and public key authentication and non-interactive (exec) command execution

const { timingSafeEqual } = require('crypto');
const { readFileSync } = require('fs');
const { inspect } = require('util');

const { utils: { parseKey }, Server } = require('ssh2');

const allowedUser = Buffer.from('foo');
const allowedPassword = Buffer.from('bar');
const allowedPubKey = parseKey(readFileSync('foo.pub'));

function checkValue(input, allowed) {
  const autoReject = (input.length !== allowed.length);
  if (autoReject) {
    // Prevent leaking length information by always making a comparison with the
    // same input when lengths don't match what we expect ...
    allowed = input;
  }
  const isMatch = timingSafeEqual(input, allowed);
  return (!autoReject && isMatch);
}

new Server({
  hostKeys: [readFileSync('host.key')]
}, (client) => {
  console.log('Client connected!');

  client.on('authentication', (ctx) => {
    let allowed = true;
    if (!checkValue(Buffer.from(ctx.username), allowedUser))
      allowed = false;

    switch (ctx.method) {
      case 'password':
        if (!checkValue(Buffer.from(ctx.password), allowedPassword))
          return ctx.reject();
        break;
      case 'publickey':
        if (ctx.key.algo !== allowedPubKey.type
            || !checkValue(ctx.key.data, allowedPubKey.getPublicSSH())
            || (ctx.signature && allowedPubKey.verify(ctx.blob, ctx.signature) !== true)) {
          return ctx.reject();
        }
        break;
      default:
        return ctx.reject();
    }

    if (allowed)
      ctx.accept();
    else
      ctx.reject();
  }).on('ready', () => {
    console.log('Client authenticated!');

    client.on('session', (accept, reject) => {
      const session = accept();
      session.once('exec', (accept, reject, info) => {
        console.log('Client wants to execute: ' + inspect(info.command));
        const stream = accept();
        stream.stderr.write('Oh no, the dreaded errors!\n');
        stream.write('Just kidding about the errors!\n');
        stream.exit(0);
        stream.end();
      });
    });
  }).on('close', () => {
    console.log('Client disconnected');
  });
}).listen(0, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});

SFTP-only server

const { timingSafeEqual } = require('crypto');
const { readFileSync } = require('fs');
const { inspect } = require('util');

const {
  Server,
  sftp: {
    OPEN_MODE,
    STATUS_CODE,
  },
} = require('ssh2');

const allowedUser = Buffer.from('foo');
const allowedPassword = Buffer.from('bar');

function checkValue(input, allowed) {
  const autoReject = (input.length !== allowed.length);
  if (autoReject) {
    // Prevent leaking length information by always making a comparison with the
    // same input when lengths don't match what we expect ...
    allowed = input;
  }
  const isMatch = timingSafeEqual(input, allowed);
  return (!autoReject && isMatch);
}

// This simple SFTP server implements file uploading where the contents get
// ignored ...

new ssh2.Server({
  hostKeys: [readFileSync('host.key')]
}, (client) => {
  console.log('Client connected!');

  client.on('authentication', (ctx) => {
    let allowed = true;
    if (!checkValue(Buffer.from(ctx.username), allowedUser))
      allowed = false;

    switch (ctx.method) {
      case 'password':
        if (!checkValue(Buffer.from(ctx.password), allowedPassword))
          return ctx.reject();
        break;
      default:
        return ctx.reject();
    }

    if (allowed)
      ctx.accept();
    else
      ctx.reject();
  }).on('ready', () => {
    console.log('Client authenticated!');

    client.on('session', (accept, reject) => {
      const session = accept();
      session.on('sftp', (accept, reject) => {
        console.log('Client SFTP session');
        const openFiles = new Map();
        let handleCount = 0;
        const sftp = accept();
        sftp.on('OPEN', (reqid, filename, flags, attrs) => {
          // Only allow opening /tmp/foo.txt for writing
          if (filename !== '/tmp/foo.txt' || !(flags & OPEN_MODE.WRITE))
            return sftp.status(reqid, STATUS_CODE.FAILURE);

          // Create a fake handle to return to the client, this could easily
          // be a real file descriptor number for example if actually opening
          // a file on disk
          const handle = Buffer.alloc(4);
          openFiles.set(handleCount, true);
          handle.writeUInt32BE(handleCount++, 0);

          console.log('Opening file for write')
          sftp.handle(reqid, handle);
        }).on('WRITE', (reqid, handle, offset, data) => {
          if (handle.length !== 4
              || !openFiles.has(handle.readUInt32BE(0))) {
            return sftp.status(reqid, STATUS_CODE.FAILURE);
          }

          // Fake the write operation
          sftp.status(reqid, STATUS_CODE.OK);

          console.log('Write to file at offset ${offset}: ${inspect(data)}');
        }).on('CLOSE', (reqid, handle) => {
          let fnum;
          if (handle.length !== 4
              || !openFiles.has(fnum = handle.readUInt32BE(0))) {
            return sftp.status(reqid, STATUS_CODE.FAILURE);
          }

          console.log('Closing file');
          openFiles.delete(fnum);

          sftp.status(reqid, STATUS_CODE.OK);
        });
      });
    });
  }).on('close', () => {
    console.log('Client disconnected');
  });
}).listen(0, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});

You can find more examples in the examples directory of this repository.

API

require('ssh2').Client is the Client constructor.

require('ssh2').Server is the Server constructor.

require('ssh2').utils is an object containing some useful utilities.

require('ssh2').HTTPAgent is an http.Agent constructor.

require('ssh2').HTTPSAgent is an https.Agent constructor. Its API is the same as HTTPAgent except it's for HTTPS connections.

Agent-related

require('ssh2').AgentProtocol is a Duplex stream class that aids in communicating over the OpenSSH agent protocol.

require('ssh2').BaseAgent is a base class for creating custom authentication agents.

require('ssh2').createAgent is a helper function that creates a new agent instance using the same logic as the agent configuration option: if the platform is Windows and it's the value "pageant", it creates a PageantAgent, otherwise if it's not a path to a Windows pipe it creates a CygwinAgent. In all other cases, it creates an OpenSSHAgent.

require('ssh2').CygwinAgent is an agent class implementation that communicates with agents in a Cygwin environment.

require('ssh2').OpenSSHAgent is an agent class implementation that communicates with OpenSSH agents over a UNIX socket.

require('ssh2').PageantAgent is an agent class implementation that communicates with Pageant agent processes.

Client

Client events

banner(< string >message, < string >language) - A notice was sent by the server upon connection.

change password(< string >prompt, < function >done) - If using password-based user authentication, the server has requested that the user's password be changed. Call done with the new password.

close() - The socket was closed.

end() - The socket was disconnected.

error(< Error >err) - An error occurred. A 'level' property indicates 'client-socket' for socket-level errors and 'client-ssh' for SSH disconnection messages. In the case of 'client-ssh' messages, there may be a 'description' property that provides more detail.

handshake(< object >negotiated) - Emitted when a handshake has completed (either initial or rekey). negotiated contains the negotiated details of the handshake and is of the form:

    // In this particular case `mac` is empty because there is no separate MAC
    // because it's integrated into AES in GCM mode
    { kex: 'ecdh-sha2-nistp256',
      srvHostKey: 'rsa-sha2-512',
      cs: { // Client to server algorithms
        cipher: 'aes128-gcm',
        mac: '',
        compress: 'none',
        lang: ''
      },
      sc: { // Server to client algorithms
        cipher: 'aes128-gcm',
        mac: '',
        compress: 'none',
        lang: ''
      }
    }

hostkeys(< array >keys) - Emitted when the server announces its available host keys. keys is the list of parsed (using parseKey()) host public keys.

keyboard-interactive(< string >name, < string >instructions, < string >instructionsLang, < array >prompts, < function >finish) - The server is asking for replies to the given prompts for keyboard-interactive user authentication. name is generally what you'd use as a window title (for GUI apps). prompts is an array of { prompt: 'Password: ', echo: false } style objects (here echo indicates whether user input should be displayed on the screen). The answers for all prompts must be provided as an array of strings and passed to finish when you are ready to continue. Note: It's possible for the server to come back and ask more questions.

ready() - Authentication was successful.

rekey() - Emitted when a rekeying operation has completed (either client or server-initiated).

tcp connection(< object >details, < function >accept, < function >reject) - An incoming forwarded TCP connection is being requested. Calling accept accepts the connection and returns a Channel object. Calling reject rejects the connection and no further action is needed. details contains:

destIP - string - The remote IP the connection was received on (given in earlier call to forwardIn()).

destPort - integer - The remote port the connection was received on (given in earlier call to forwardIn()).

srcIP - string - The originating IP of the connection.

srcPort - integer - The originating port of the connection.

unix connection(< object >details, < function >accept, < function >reject) - An incoming forwarded UNIX socket connection is being requested. Calling accept accepts the connection and returns a Channel object. Calling reject rejects the connection and no further action is needed. details contains:

  • socketPath - string - The originating UNIX socket path of the connection.

x11(< object >details, < function >accept, < function >reject) - An incoming X11 connection is being requested. Calling accept accepts the connection and returns a Channel object. Calling reject rejects the connection and no further action is needed. details contains:

srcIP - string - The originating IP of the connection.

srcPort - integer - The originating port of the connection.

Client methods

(constructor)() - Creates and returns a new Client instance.

connect(< object >config) - (void) - Attempts a connection to a server using the information given in config:

agent - string - Path to ssh-agent's UNIX socket for ssh-agent-based user authentication. Windows users: set to 'pageant' for authenticating with Pageant or (actual) path to a cygwin "UNIX socket." Default: (none)

agentForward - boolean - Set to true to use OpenSSH agent forwarding (auth-agent@openssh.com) for the life of the connection. agent must also be set to use this feature. Default: false

algorithms - object - This option allows you to explicitly override the default transport layer algorithms used for the connection. The value for each category must either be an array of valid algorithm names to set an exact list (with the most preferable first) or an object containing append, prepend, and/or remove properties that each contain an array of algorithm names or RegExps to match to adjust default lists for each category. Valid keys:

cipher - mixed - Ciphers.

  • Default list (in order from most to least preferable):
    • chacha20-poly1305@openssh.com (priority of chacha20-poly1305 may vary depending upon CPU and/or optional binding availability)
    • aes128-gcm
    • aes128-gcm@openssh.com
    • aes256-gcm
    • aes256-gcm@openssh.com
    • aes128-ctr
    • aes192-ctr
    • aes256-ctr
  • Other supported names:
    • 3des-cbc
    • aes256-cbc
    • aes192-cbc
    • aes128-cbc
    • arcfour256
    • arcfour128
    • arcfour
    • blowfish-cbc
    • cast128-cbc

compress - mixed - Compression algorithms.

  • Default list (in order from most to least preferable):
    • none
    • zlib@openssh.com
    • zlib
  • Other supported names:

hmac - mixed - (H)MAC algorithms.

  • Default list (in order from most to least preferable):
    • hmac-sha2-256-etm@openssh.com
    • hmac-sha2-512-etm@openssh.com
    • hmac-sha1-etm@openssh.com
    • hmac-sha2-256
    • hmac-sha2-512
    • hmac-sha1
  • Other supported names:
    • hmac-md5
    • hmac-sha2-256-96
    • hmac-sha2-512-96
    • hmac-ripemd160
    • hmac-sha1-96
    • hmac-md5-96

kex - mixed - Key exchange algorithms.

  • Default list (in order from most to least preferable):
    • curve25519-sha256 (node v14.0.0+)
    • curve25519-sha256@libssh.org (node v14.0.0+)
    • ecdh-sha2-nistp256
    • ecdh-sha2-nistp384
    • ecdh-sha2-nistp521
    • diffie-hellman-group-exchange-sha256
    • diffie-hellman-group14-sha256
    • diffie-hellman-group15-sha512
    • diffie-hellman-group16-sha512
    • diffie-hellman-group17-sha512
    • diffie-hellman-group18-sha512
  • Other supported names:
    • diffie-hellman-group-exchange-sha1
    • diffie-hellman-group14-sha1
    • diffie-hellman-group1-sha1

serverHostKey - mixed - Server host key formats.

  • Default list (in order from most to least preferable):
    • ssh-ed25519 (node v12.0.0+)
    • ecdsa-sha2-nistp256
    • ecdsa-sha2-nistp384
    • ecdsa-sha2-nistp521
    • rsa-sha2-512
    • rsa-sha2-256
    • ssh-rsa
  • Other supported names:
    • ssh-dss

authHandler - mixed - Must be an array of objects as described below, an array of strings containing valid authentication method names (username and credentials are pulled from the object passed to connect()), or a function with parameters (methodsLeft, partialSuccess, callback) where methodsLeft and partialSuccess are null on the first authentication attempt, otherwise are an array and boolean respectively. Return or call callback() with either the name of the authentication method or an object containing the method name along with method-specific details to try next (return/pass false to signal no more methods to try). Valid method names are: 'none', 'password', 'publickey', 'agent', 'keyboard-interactive', 'hostbased'. Default: function that follows a set method order: None -> Password -> Private Key -> Agent (-> keyboard-interactive if tryKeyboard is true) -> Hostbased

When returning or calling callback() with an object, it can take one of the following forms:

{
  type: 'none',
  username: 'foo',
}
{
  type: 'password'
  username: 'foo',
  password: 'bar',
}
{
  type: 'publickey'
  username: 'foo',
  // Can be a string, Buffer, or parsed key containing a private key
  key: ...,
  // `passphrase` only required for encrypted keys
  passphrase: ...,
}
{
  type: 'hostbased'
  username: 'foo',
  localHostname: 'baz',
  localUsername: 'quux',
  // Can be a string, Buffer, or parsed key containing a private key
  key: ...,
  // `passphrase` only required for encrypted keys
  passphrase: ...,
}
{
  type: 'agent'
  username: 'foo',
  // Can be a string that is interpreted exactly like the `agent`
  // connection config option or can be a custom agent
  // object/instance that extends and implements `BaseAgent`
  agent: ...,
}
{
  type: 'keyboard-interactive'
  username: 'foo',
  // This works exactly the same way as a 'keyboard-interactive'
  // Client event handler
  prompt: (name, instructions, instructionsLang, prompts, finish) => {
    // ...
  },
}

debug - function - Set this to a function that receives a single string argument to get detailed (local) debug information. Default: (none)

forceIPv4 - boolean - Only connect via resolved IPv4 address for host. Default: false

forceIPv6 - boolean - Only connect via resolved IPv6 address for host. Default: false

host - string - Hostname or IP address of the server. Default: 'localhost'

hostHash - string - Any valid hash algorithm supported by node. The host's key is hashed using this algorithm and passed to the hostVerifier function as a hex string. Default: (none)

hostVerifier - function - Function with parameters (hashedKey[, callback]) where hashedKey is a string hex hash of the host's key for verification purposes. Return true to continue with the handshake or false to reject and disconnect, or call callback() with true or false if you need to perform asynchronous verification. Default: (auto-accept if hostVerifier is not set)

keepaliveCountMax - integer - How many consecutive, unanswered SSH-level keepalive packets that can be sent to the server before disconnection (similar to OpenSSH's ServerAliveCountMax config option). Default: 3

keepaliveInterval - integer - How often (in milliseconds) to send SSH-level keepalive packets to the server (in a similar way as OpenSSH's ServerAliveInterval config option). Set to 0 to disable. Default: 0

localAddress - string - IP address of the network interface to use to connect to the server. Default: (none -- determined by OS)

localHostname - string - Along with localUsername and privateKey, set this to a non-empty string for hostbased user authentication. Default: (none)

localPort - string - The local port number to connect from. Default: (none -- determined by OS)

localUsername - string - Along with localHostname and privateKey, set this to a non-empty string for hostbased user authentication. Default: (none)

passphrase - string - For an encrypted privateKey, this is the passphrase used to decrypt it. Default: (none)

password - string - Password for password-based user authentication. Default: (none)

port - integer - Port number of the server. Default: 22

privateKey - mixed - Buffer or string that contains a private key for either key-based or hostbased user authentication (OpenSSH format). Default: (none)

readyTimeout - integer - How long (in milliseconds) to wait for the SSH handshake to complete. Default: 20000

sock - ReadableStream - A ReadableStream to use for communicating with the server instead of creating and using a new TCP connection (useful for connection hopping).

strictVendor - boolean - Performs a strict server vendor check before sending vendor-specific requests, etc. (e.g. check for OpenSSH server when using openssh_noMoreSessions()) Default: true

tryKeyboard - boolean - Try keyboard-interactive user authentication if primary user authentication method fails. If you set this to true, you need to handle the keyboard-interactive event. Default: false

username - string - Username for authentication. Default: (none)

end() - (void) - Disconnects the socket.

exec(< string >command[, < object >options], < function >callback) - (void) - Executes command on the server. callback has 2 parameters: < Error >err, < Channel >stream. Valid options properties are:

env - object - An environment to use for the execution of the command.

pty - mixed - Set to true to allocate a pseudo-tty with defaults, or an object containing specific pseudo-tty settings (see 'Pseudo-TTY settings'). Setting up a pseudo-tty can be useful when working with remote processes that expect input from an actual terminal (e.g. sudo's password prompt).

x11 - mixed - Set to true to use defaults below, set to a number to specify a specific screen number, or an object with the following valid properties:

cookie - mixed - The authentication cookie. Can be a hex string or a Buffer containing the raw cookie value (which will be converted to a hex string). Default: (random 16 byte value)

protocol - string - The authentication protocol name. Default: 'MIT-MAGIC-COOKIE-1'

screen - number - Screen number to use Default: 0

single - boolean - Allow just a single connection? Default: false

forwardIn(< string >remoteAddr, < integer >remotePort, < function >callback) - (void) - Bind to remoteAddr on remotePort on the server and forward incoming TCP connections. callback has 2 parameters: < Error >err, < integer >port (port is the assigned port number if remotePort was 0). Here are some special values for remoteAddr and their associated binding behaviors:

'' - Connections are to be accepted on all protocol families supported by the server.

'0.0.0.0' - Listen on all IPv4 addresses.

'::' - Listen on all IPv6 addresses.

'localhost' - Listen on all protocol families supported by the server on loopback addresses only.

'127.0.0.1' and '::1' - Listen on the loopback interfaces for IPv4 and IPv6, respectively.

forwardOut(< string >srcIP, < integer >srcPort, < string >dstIP, < integer >dstPort, < function >callback) - (void) - Open a connection with srcIP and srcPort as the originating address and port and dstIP and dstPort as the remote destination address and port. callback has 2 parameters: < Error >err, < Channel >stream.

openssh_forwardInStreamLocal(< string >socketPath, < function >callback) - (void) - OpenSSH extension that binds to a UNIX domain socket at socketPath on the server and forwards incoming connections. callback has 1 parameter: < Error >err.

openssh_forwardOutStreamLocal(< string >socketPath, < function >callback) - (void) - OpenSSH extension that opens a connection to a UNIX domain socket at socketPath on the server. callback has 2 parameters: < Error >err, < Channel >stream.

openssh_noMoreSessions(< function >callback) - (void) - OpenSSH extension that sends a request to reject any new sessions (e.g. exec, shell, sftp, subsys) for this connection. callback has 1 parameter: < Error >err.

openssh_unforwardInStreamLocal(< string >socketPath, < function >callback) - (void) - OpenSSH extension that unbinds from a UNIX domain socket at socketPath on the server and stops forwarding incoming connections. callback has 1 parameter: < Error >err.

rekey([< function >callback]) - (void) - Initiates a rekey with the server. If callback is supplied, it is added as a one-time handler for the rekey event.

sftp(< function >callback) - (void) - Starts an SFTP session. callback has 2 parameters: < Error >err, < SFTP >sftp. For methods available on sftp, see the SFTP client documentation.

shell([[< mixed >window,] < object >options]< function >callback) - (void) - Starts an interactive shell session on the server, with an optional window object containing pseudo-tty settings (see 'Pseudo-TTY settings'). If window === false, then no pseudo-tty is allocated. options supports the x11 and env options as described in exec(). callback has 2 parameters: < Error >err, < Channel >stream.

subsys(< string >subsystem, < function >callback) - (void) - Invokes subsystem on the server. callback has 2 parameters: < Error >err, < Channel >stream.

unforwardIn(< string >remoteAddr, < integer >remotePort, < function >callback) - (void) - Unbind from remoteAddr on remotePort on the server and stop forwarding incoming TCP connections. Until callback is called, more connections may still come in. callback has 1 parameter: < Error >err.

Server

Server events

connection(< Connection >client, < object >info) - A new client has connected. info contains the following properties:

family - string - The remoteFamily of the connection.

header - object - Information about the client's header:

identRaw - string - The raw client identification string.

versions - object - Various version information:

protocol - string - The SSH protocol version (always 1.99 or 2.0).

software - string - The software name and version of the client.

comments - string - Any text that comes after the software name/version.

        { identRaw: 'SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2',
          version: {
            protocol: '2.0',
            software: 'OpenSSH_6.6.1p1'
          },
          comments: 'Ubuntu-2ubuntu2' }
* **ip** - _string_ - The `remoteAddress` of the connection.

* **port** - _integer_ - The `remotePort` of the connection.

Server methods

(constructor)(< object >config[, < function >connectionListener]) - Creates and returns a new Server instance. Server instances also have the same methods/properties/events as net.Server. connectionListener if supplied, is added as a connection listener. Valid config properties:

algorithms - object - This option allows you to explicitly override the default transport layer algorithms used for incoming client connections. Each value must be an array of valid algorithms for that category. The order of the algorithms in the arrays are important, with the most favorable being first. For a list of valid and default algorithm names, please review the documentation for the version of ssh2 used by this module. Valid keys:

cipher - array - Ciphers.

compress - array - Compression algorithms.

hmac - array - (H)MAC algorithms.

kex - array - Key exchange algorithms.

serverHostKey - array - Server host key formats.

banner - string - A message that is sent to clients once, right before authentication begins. Default: (none)

debug - function - Set this to a function that receives a single string argument to get detailed (local) debug information. Default: (none)

greeting - string - A message that is sent to clients immediately upon connection, before handshaking begins. Note: Most clients usually ignore this. Default: (none)

highWaterMark - integer - This is the highWaterMark to use for the parser stream. Default: 32 * 1024

hostKeys - array - An array of either Buffers/strings that contain host private keys or objects in the format of { key: <Buffer/string>, passphrase: <string> } for encrypted private keys. (Required) Default: (none)

ident - string - A custom server software name/version identifier. Default: 'ssh2js' + moduleVersion + 'srv'

injectSocket(< DuplexStream >socket) - Injects a bidirectional stream as though it were a TCP socket connection. Additionally, socket should include net.Socket-like properties to ensure the best compatibility (e.g. socket.remoteAddress, socket.remotePort, socket.remoteFamily).

Connection events

authentication(< AuthContext >ctx) - The client has requested authentication. ctx.username contains the client username, ctx.method contains the requested authentication method, and ctx.accept() and ctx.reject([< Array >authMethodsLeft[, < Boolean >isPartialSuccess]]) are used to accept or reject the authentication request respectively. abort is emitted if the client aborts the authentication request. Other properties/methods available on ctx depends on the ctx.method of authentication the client has requested:

hostbased:

blob - Buffer - This contains the data to be verified that is passed to (along with the signature) key.verify() where key is a public key parsed with parseKey().

key - object - Contains information about the public key sent by the client:

algo - string - The name of the key algorithm (e.g. ssh-rsa).

data - Buffer - The actual key data.

localHostname - string - The local hostname provided by the client.

localUsername - string - The local username provided by the client.

signature - Buffer - This contains a signature to be verified that is passed to (along with the blob) key.verify() where key is a public key parsed with parseKey().

keyboard-interactive:

prompt(< array >prompts[, < string >title[, < string >instructions]], < function >callback) - (void) - Send prompts to the client. prompts is an array of { prompt: 'Prompt text', echo: true } objects (prompt being the prompt text and echo indicating whether the client's response to the prompt should be echoed to their display). callback is called with (responses), where responses is an array of string responses matching up to the prompts.

submethods - array - A list of preferred authentication "sub-methods" sent by the client. This may be used to determine what (if any) prompts to send to the client.

password:

password - string - This is the password sent by the client.

requestChange(< string >prompt, < function >callback) - (void) - Sends a password change request to the client. callback is called with (newPassword), where newPassword is the new password supplied by the client. You may accept, reject, or prompt for another password change after callback is called.

publickey:

blob - mixed - If the value is undefined, the client is only checking the validity of the key. If the value is a Buffer, then this contains the data to be verified that is passed to (along with the signature) key.verify() where key is a public key parsed with parseKey().

key - object - Contains information about the public key sent by the client:

algo - string - The name of the key algorithm (e.g. ssh-rsa).

data - Buffer - The actual key data.

signature - mixed - If the value is undefined, the client is only checking the validity of the key. If the value is a Buffer, then this contains a signature to be verified that is passed to (along with the blob) key.verify() where key is a public key parsed with parseKey().

close() - The client socket was closed.

end() - The client socket disconnected.

error(< Error >err) - An error occurred.

handshake(< object >negotiated) - Emitted when a handshake has completed (either initial or rekey). negotiated contains the negotiated details of the handshake and is of the form:

    // In this particular case `mac` is empty because there is no separate MAC
    // because it's integrated into AES in GCM mode
    { kex: 'ecdh-sha2-nistp256',
      srvHostKey: 'rsa-sha2-512',
      cs: { // Client to server algorithms
        cipher: 'aes128-gcm',
        mac: '',
        compress: 'none',
        lang: ''
      },
      sc: { // Server to client algorithms
        cipher: 'aes128-gcm',
        mac: '',
        compress: 'none',
        lang: ''
      }
    }

openssh.streamlocal(< function >accept, < function >reject, < object >info) - Emitted when the client has requested a connection to a UNIX domain socket. accept() returns a new Channel instance representing the connection. info contains:

  • socketPath - string - Destination socket path of outgoing connection.

ready() - Emitted when the client has been successfully authenticated.

rekey() - Emitted when a rekeying operation has completed (either client or server-initiated).

request(< mixed >accept, < mixed >reject, < string >name, < object >info) - Emitted when the client has sent a global request for name (e.g. tcpip-forward or cancel-tcpip-forward). accept and reject are functions if the client requested a response. If bindPort === 0, you should pass the chosen port to accept() so that the client will know what port was bound. info contains additional details about the request:

cancel-tcpip-forward and tcpip-forward:

bindAddr - string - The IP address to start/stop binding to.

bindPort - integer - The port to start/stop binding to.

cancel-streamlocal-forward@openssh.com and streamlocal-forward@openssh.com:

  • socketPath - string - The socket path to start/stop binding to.

session(< function >accept, < function >reject) - Emitted when the client has requested a new session. Sessions are used to start interactive shells, execute commands, request X11 forwarding, etc. accept() returns a new Session instance.

tcpip(< function >accept, < function >reject, < object >info) - Emitted when the client has requested an outbound (TCP) connection. accept() returns a new Channel instance representing the connection. info contains:

destIP - string - Destination IP address of outgoing connection.

destPort - string - Destination port of outgoing connection.

srcIP - string - Source IP address of outgoing connection.

srcPort - string - Source port of outgoing connection.

Connection methods

end() - (void) - Closes the client connection.

forwardOut(< string >boundAddr, < integer >boundPort, < string >remoteAddr, < integer >remotePort, < function >callback) - (void) - Alert the client of an incoming TCP connection on boundAddr on port boundPort from remoteAddr on port remotePort. callback has 2 parameters: < Error >err, < Channel >stream.

openssh_forwardOutStreamLocal(< string >socketPath, < function >callback) - (void) - Alert the client of an incoming UNIX domain socket connection on socketPath. callback has 2 parameters: < Error >err, < Channel >stream.

rekey([< function >callback]) - (void) - Initiates a rekey with the client. If callback is supplied, it is added as a one-time handler for the rekey event.

x11(< string >originAddr, < integer >originPort, < function >callback) - (void) - Alert the client of an incoming X11 client connection from originAddr on port originPort. callback has 2 parameters: < Error >err, < Channel >stream.

Session events

auth-agent(< mixed >accept, < mixed >reject) - The client has requested incoming ssh-agent requests be forwarded to them. accept and reject are functions if the client requested a response.

close() - The session was closed.

env(< mixed >accept, < mixed >reject, < object >info) - The client requested an environment variable to be set for this session. accept and reject are functions if the client requested a response. info has these properties:

key - string - The environment variable's name.

value - string - The environment variable's value.

exec(< mixed >accept, < mixed >reject, < object >info) - The client has requested execution of a command string. accept and reject are functions if the client requested a response. accept() returns a Channel for the command execution. info has these properties:

  • command - string - The command line to be executed.

pty(< mixed >accept, < mixed >reject, < object >info) - The client requested allocation of a pseudo-TTY for this session. accept and reject are functions if the client requested a response. info has these properties:

cols - integer - The number of columns for the pseudo-TTY.

height - integer - The height of the pseudo-TTY in pixels.

modes - object - Contains the requested terminal modes of the pseudo-TTY keyed on the mode name with the value being the mode argument. (See the table at the end for valid names).

rows - integer - The number of rows for the pseudo-TTY.

width - integer - The width of the pseudo-TTY in pixels.

sftp(< mixed >accept, < mixed >reject) - The client has requested the SFTP subsystem. accept and reject are functions if the client requested a response. accept() returns an SFTP instance in server mode (see the SFTP documentation for details). info has these properties:

shell(< mixed >accept, < mixed >reject) - The client has requested an interactive shell. accept and reject are functions if the client requested a response. accept() returns a Channel for the interactive shell.

signal(< mixed >accept, < mixed >reject, < object >info) - The client has sent a signal. accept and reject are functions if the client requested a response. info has these properties:

  • name - string - The signal name (e.g. SIGUSR1).

subsystem(< mixed >accept, < mixed >reject, < object >info) - The client has requested an arbitrary subsystem. accept and reject are functions if the client requested a response. accept() returns a Channel for the subsystem. info has these properties:

  • name - string - The name of the subsystem.

window-change(< mixed >accept, < mixed >reject, < object >info) - The client reported a change in window dimensions during this session. accept and reject are functions if the client requested a response. info has these properties:

cols - integer - The new number of columns for the client window.

height - integer - The new height of the client window in pixels.

rows - integer - The new number of rows for the client window.

width - integer - The new width of the client window in pixels.

x11(< mixed >accept, < mixed >reject, < object >info) - The client requested X11 forwarding. accept and reject are functions if the client requested a response. info has these properties:

cookie - string - The X11 authentication cookie encoded in hexadecimal.

protocol - string - The name of the X11 authentication method used (e.g. MIT-MAGIC-COOKIE-1).

screen - integer - The screen number to forward X11 connections for.

single - boolean - true if only a single connection should be forwarded.

Channel

This is a normal streams2 Duplex Stream (used both by clients and servers), with the following changes:

A boolean property allowHalfOpen exists and behaves similarly to the property of the same name for net.Socket. When the stream's end() is called, if allowHalfOpen is true, only EOF will be sent (the server can still send data if they have not already sent EOF). The default value for this property is true.

A close event is emitted once the channel is completely closed on both the client and server.

Client-specific:

For exec():

An exit event may (the SSH2 spec says it is optional) be emitted when the process finishes. If the process finished normally, the process's return value is passed to the exit callback. If the process was interrupted by a signal, the following are passed to the exit callback: null, < string >signalName, < boolean >didCoreDump, < string >description.

If there was an exit event, the close event will be passed the same arguments for convenience.

A stderr property contains a Readable stream that represents output from stderr.

For exec() and shell():

The readable side represents stdout and the writable side represents stdin.

setWindow(< integer >rows, < integer >cols, < integer >height, < integer >width) - (void) - Lets the server know that the local terminal window has been resized. The meaning of these arguments are described in the 'Pseudo-TTY settings' section.

signal(< string >signalName) - (void) - Sends a POSIX signal to the current process on the server. Valid signal names are: 'ABRT', 'ALRM', 'FPE', 'HUP', 'ILL', 'INT', 'KILL', 'PIPE', 'QUIT', 'SEGV', 'TERM', 'USR1', and 'USR2'. Some server implementations may ignore this request if they do not support signals. Note: If you are trying to send SIGINT and you find signal() doesn't work, try writing '\x03' to the Channel stream instead.

Server-specific:

For exec-enabled channel instances there is an additional method available that may be called right before you close the channel. It has two different signatures:

exit(< integer >exitCode) - (void) - Sends an exit status code to the client.

exit(< string >signalName[, < boolean >coreDumped[, < string >errorMsg]]) - (void) - Sends an exit status code to the client.

For exec and shell-enabled channel instances, channel.stderr is a writable stream.

Pseudo-TTY settings

cols - < integer > - Number of columns. Default: 80

height - < integer > - Height in pixels. Default: 480

modes - < object > - An object containing Terminal Modes as keys, with each value set to each mode argument. Default: null

rows - < integer > - Number of rows. Default: 24

term - < string > - The value to use for $TERM. Default: 'vt100'

width - < integer > - Width in pixels. Default: 640

rows and cols override width and height when rows and cols are non-zero.

Pixel dimensions refer to the drawable area of the window.

Zero dimension parameters are ignored.

Terminal modes

NameDescription
CS77 bit mode.
CS88 bit mode.
ECHOCTLEcho control characters as ^(Char).
ECHOEnable echoing.
ECHOEVisually erase chars.
ECHOKEVisual erase for line kill.
ECHOKKill character discards current line.
ECHONLEcho NL even if ECHO is off.
ICANONCanonicalize input lines.
ICRNLMap CR to NL on input.
IEXTENEnable extensions.
IGNCRIgnore CR on input.
IGNPARThe ignore parity flag. The parameter SHOULD be 0 if this flag is FALSE, and 1 if it is TRUE.
IMAXBELRing bell on input queue full.
INLCRMap NL into CR on input.
INPCKEnable checking of parity errors.
ISIGEnable signals INTR, QUIT, [D]SUSP.
ISTRIPStrip 8th bit off characters.
IUCLCTranslate uppercase characters to lowercase.
IXANYAny char will restart after stop.
IXOFFEnable input flow control.
IXONEnable output flow control.
NOFLSHDon't flush after interrupt.
OCRNLTranslate carriage return to newline (output).
OLCUCConvert lowercase to uppercase.
ONLCRMap NL to CR-NL.
ONLRETNewline performs a carriage return (output).
ONOCRTranslate newline to carriage return-newline (output).
OPOSTEnable output processing.
PARENBParity enable.
PARMRKMark parity and framing errors.
PARODDOdd parity, else even.
PENDINRetype pending input.
TOSTOPStop background jobs from output.
TTY_OP_ISPEEDSpecifies the input baud rate in bits per second.
TTY_OP_OSPEEDSpecifies the output baud rate in bits per second.
VDISCARDToggles the flushing of terminal output.
VDSUSPAnother suspend character.
VEOFEnd-of-file character (sends EOF from the terminal).
VEOL2Additional end-of-line character.
VEOLEnd-of-line character in addition to carriage return and/or linefeed.
VERASEErase the character to left of the cursor.
VFLUSHCharacter to flush output.
VINTRInterrupt character; 255 if none. Similarly for the other characters. Not all of these characters are supported on all systems.
VKILLKill the current input line.
VLNEXTEnter the next character typed literally, even if it is a special character
VQUITThe quit character (sends SIGQUIT signal on POSIX systems).
VREPRINTReprints the current input line.
VSTARTContinues paused output (normally control-Q).
VSTATUSPrints system status line (load, command, pid, etc).
VSTOPPauses output (normally control-S).
VSUSPSuspends the current program.
VSWTCHSwitch to a different shell layer.
VWERASEErases a word left of cursor.
XCASEEnable input and output of uppercase characters by preceding their lowercase equivalents with "".

HTTPAgent

HTTPAgent methods

  • (constructor)(< object >sshConfig[, < object >agentConfig]) - Creates and returns a new http.Agent instance used to tunnel an HTTP connection over SSH. sshConfig is what is passed to client.connect() and agentOptions is passed to the http.Agent constructor.

HTTPSAgent

HTTPSAgent methods

  • (constructor)(< object >sshConfig[, < object >agentConfig]) - Creates and returns a new https.Agent instance used to tunnel an HTTP connection over SSH. sshConfig is what is passed to client.connect() and agentOptions is passed to the https.Agent constructor.

Utilities

parseKey(< mixed >keyData[, < string >passphrase]) - mixed - Parses a private/public key in OpenSSH, RFC4716, or PPK format. For encrypted private keys, the key will be decrypted with the given passphrase. keyData can be a Buffer or string value containing the key contents. The returned value will be an array of objects (currently in the case of modern OpenSSH keys) or an object with these properties and methods:

comment - string - The comment for the key

equals(< mixed >otherKey) - boolean - This returns true if otherKey (a parsed or parseable key) is the same as this key. This method does not compare the keys' comments

getPrivatePEM() - string - This returns the PEM version of a private key

getPublicPEM() - string - This returns the PEM version of a public key (for either public key or derived from a private key)

getPublicSSH() - string - This returns the SSH version of a public key (for either public key or derived from a private key)

isPrivateKey() - boolean - This returns true if the key is a private key or not

sign(< mixed >data) - mixed - This signs the given data using this key and returns a Buffer containing the signature on success. On failure, an Error will be returned. data can be anything accepted by node's sign.update().

type - string - The full key type (e.g. 'ssh-rsa')

verify(< mixed >data, < Buffer >signature) - mixed - This verifies a signature of the given data using this key and returns true if the signature could be verified. On failure, either false will be returned or an Error will be returned upon a more critical failure. data can be anything accepted by node's verify.update().

sftp.OPEN_MODE - OPEN_MODE

sftp.STATUS_CODE - STATUS_CODE

sftp.flagsToString - flagsToString()

sftp.stringToFlags - stringToFlags()

AgentProtocol

AgentProtocol events

identities(< opaque >request) - (Server mode only) The client has requested a list of public keys stored in the agent. Use failureReply() or getIdentitiesReply() to reply appropriately.

sign(< opaque >request, < mixed >pubKey, < Buffer >data, < object >options) - (Server mode only) The client has requested data to be signed using the key identified by pubKey. Use failureReply() or signReply() to reply appropriately. options may contain any of:

  • hash - string - The explicitly desired hash to use when computing the signature. Currently if set, this may be either 'sha256' or 'sha512' for RSA keys.

AgentProtocol methods

(constructor)(< boolean >isClient) - Creates and returns a new AgentProtocol instance. isClient determines whether the instance operates in client or server mode.

failureReply(< opaque >request) - (void) - (Server mode only) Replies to the given request with a failure response.

getIdentities(< function >callback) - (void) - (Client mode only) Requests a list of public keys from the agent. callback is passed (err, keys) where keys is a possible array of public keys for authentication.

getIdentitiesReply(< opaque >request, < array >keys) - (void) - (Server mode only) Responds to a identities list request with the given array of keys in keys.

sign(< mixed >pubKey, < Buffer >data, < object >options, < function >callback) - (void) - (Client mode only) Requests that the agent sign data using the key identified by pubKey. pubKey can be any parsed (using utils.parseKey()) or parseable key value. callback is passed (err, signature) where signature is a possible Buffer containing the signature for the data. options may contain any of:

  • hash - string - The explicitly desired hash to use when computing the signature. Currently if set, this may be either 'sha256' or 'sha512' for RSA keys.

signReply(< opaque >request, < Buffer >signature) - (void) - (Server mode only) Responds to a sign request with the given signature in signature.

BaseAgent

In order to create a custom agent, your class must:

Extend BaseAgent

Call super() in its constructor

Implement at least the following methods:

getIdentities(< function >callback) - (void) - Passes (err, keys) to callback where keys is a possible array of public keys for authentication.

sign(< mixed >pubKey, < Buffer >data, < object >options, < function >callback) - (void) - Signs data using the key identified by pubKey. pubKey can be any parsed (using utils.parseKey()) or parseable key value. callback should be passed (err, signature) where signature is a possible Buffer containing the signature for the data. options may contain any of:

  • hash - string - The explicitly desired hash to use when computing the signature. Currently if set, this may be either 'sha256' or 'sha512' for RSA keys.

Additionally your class may implement the following method in order to support agent forwarding on the client:

  • getStream(< function >callback) - (void) - Passes (err, stream) to callback where stream is a possible Duplex stream to be used to communicate with your agent. You will probably want to utilize AgentProtocol as agent forwarding is an OpenSSH feature, so the stream needs to be able to transmit/receive OpenSSH agent protocol packets.

createAgent

  • createAgent(< string >agentValue) - (Agent) - Creates and returns a new agent instance using the same logic as the Client's agent configuration option: if the platform is Windows and it's the value "pageant", it creates a PageantAgent, otherwise if it's not a path to a Windows pipe it creates a CygwinAgent. In all other cases, it creates an OpenSSHAgent.

CygwinAgent

CygwinAgent methods

  • (constructor)(< string >socketPath) - Communicates with an agent listening at socketPath in a Cygwin environment.

OpenSSHAgent

OpenSSHAgent methods

  • (constructor)(< string >socketPath) - Communicates with an OpenSSH agent listening on the UNIX socket at socketPath.

PageantAgent

PageantAgent methods

  • (constructor)() - Creates a new agent instance for communicating with a running Pageant agent process.

Download Details:

Author: mscdex
Source Code: https://github.com/mscdex/ssh2 
License: MIT license

#javascript #node #ssh #client 

SSH2 Client and Server Modules Written in Pure JavaScript for Node.js
Elian  Harber

Elian Harber

1661346988

Connect to Your Flipper's UI Over Serial Or Make It Accessible Via SSH

🐬🧋 Fztea (flipperzero-tea)  

A bubbletea-bubble and TUI to interact with your flipper zero.
The flipper will be automatically detected, if multiple flippers are connected, the first one will be used.

🚀 Installation

# using go directly
$ go install github.com/jon4hz/fztea@latest

# from aur (btw)
$ yay -S fztea-bin

# local pkg manager
## debian / ubuntu
$ dpkg -i fztea-v0.2.0-linux-amd64.deb

## rhel / fedora / suse
$ rpm -i fztea-v0.2.0-linux-amd64.rpm

## alpine
$ apk add --allow-untrusted fztea-v0.2.0-linux-amd64.apk

# windows & macOS
# -> I'm sure you'll figure something out. (No binaries for macOS due to crosscompilation errors)

✨ Usage

# trying to autodetect that dolphin
$ fztea

# no flipper found automatically :(
$ fztea -p /dev/ttyACM0

⚡️ SSH

fztea also allows you to start an ssh server, serving the flipper zero ui over a remote connection.
Why? - Why not!

# start the ssh server listening on localhost:2222 (default)
$ fztea server -l 127.0.0.1:2222

# connect to the server (from the same machine)
$ ssh localhost -p 2222

By default, fztea doesn't require any authentication but you can specify an authorized_keys file if you want to.

# use authorized_keys for authentication
$ fztea server -l 127.0.0.1:2222 -k ~/.ssh/authorized_keys

⌨️ Button Mapping

KeyFlipper EventKeypress Type
w, ↑upshort
d, →rightshort
s, ↓downshort
a, ←leftshort
o, enter, spaceokshort
b, back, escbackshort
W, shift + ↑uplong
D, shift + →rightlong
S, shift + ↓downlong
A, shift + ←leftlong
Ooklong
Bbacklong

🎬 Demo

https://user-images.githubusercontent.com/26183582/181772189-13d7aeaa-ac26-4701-8104-a71ed218539c.mp4

Download Details:

Author: jon4hz
Source Code: https://github.com/jon4hz/fztea 
License: MIT license

#go #golang #ssh 

Connect to Your Flipper's UI Over Serial Or Make It Accessible Via SSH
Elian  Harber

Elian Harber

1661318820

Clidle: Play Wordle Over SSH

clidle

Wordle, now over SSH.

Try it:

ssh clidle.duckdns.org -p 3000

Or, run it locally:

go install github.com/ajeetdsouza/clidle@latest
Preview

How to play

You have 6 attempts to guess the correct word. Each guess must be a valid 5 letter word.

After submitting a guess, the letters will turn green, yellow, or gray.

  • Green: The letter is correct, and is in the correct position.
  • Yellow: The letter is present in the solution, but is in the wrong position.
  • Gray: The letter is not present in the solution.

Scoring

Your final score is based on how many guesses it took to arrive at the solution:

GuessesScore
1100
290
380
470
560
650

Download Details:

Author: Ajeetdsouza
Source Code: https://github.com/ajeetdsouza/clidle 
License: MIT license

#go #golang #cli #ssh 

Clidle: Play Wordle Over SSH
Elian  Harber

Elian Harber

1659831060

Certificates: A Private Certificate Authority (X.509 & SSH)

Step Certificates

step-ca is an online certificate authority for secure, automated certificate management. It's the server counterpart to the step CLI tool.

You can use it to:

  • Issue X.509 certificates for your internal infrastructure:
    • HTTPS certificates that work in browsers (RFC5280 and CA/Browser Forum compliance)
    • TLS certificates for VMs, containers, APIs, mobile clients, database connections, printers, wifi networks, toaster ovens...
    • Client certificates to enable mutual TLS (mTLS) in your infra. mTLS is an optional feature in TLS where both client and server authenticate each other. Why add the complexity of a VPN when you can safely use mTLS over the public internet?
  • Issue SSH certificates:
    • For people, in exchange for single sign-on ID tokens
    • For hosts, in exchange for cloud instance identity documents
  • Easily automate certificate management:

Whatever your use case, step-ca is easy to use and hard to misuse, thanks to safe, sane defaults.


Don't want to run your own CA? To get up and running quickly, or as an alternative to running your own step-ca server, consider creating a free hosted smallstep Certificate Manager authority.


star us

Features

🦾 A fast, stable, flexible private CA

Setting up a public key infrastructure (PKI) is out of reach for many small teams. step-ca makes it easier.

⚙️ Many ways to automate

There are several ways to authorize a request with the CA and establish a chain of trust that suits your flow.

You can issue certificates in exchange for:

🏔 Your own private ACME server

ACME is the protocol used by Let's Encrypt to automate the issuance of HTTPS certificates. It's super easy to issue certificates to any ACMEv2 (RFC8555) client.

Use ACME in development & pre-production

Supports the most popular ACME challenge types:

  • For http-01, place a token at a well-known URL to prove that you control the web server
  • For dns-01, add a TXT record to prove that you control the DNS record set
  • For tls-alpn-01, respond to the challenge at the TLS layer (as Caddy does) to prove that you control the web server

Works with any ACME client. We've written examples for:

Get certificates programmatically using ACME, using these libraries:

Our own step CLI tool is also an ACME client!

See our ACME tutorial for more

👩🏽‍💻 An online SSH Certificate Authority

🤓 A general purpose PKI tool, via step CLI integration

Installation

See our installation docs here.

Documentation

Documentation can be found in a handful of different places:

On the web at https://smallstep.com/docs/step-ca.

On the command line with step help ca xxx where xxx is the subcommand you are interested in. Ex: step help ca provisioner list.

In your browser, by running step help --http=:8080 ca from the command line and visiting http://localhost:8080.

The docs folder is being deprecated, but it still has some documentation and tutorials.

Feedback?


Questions? Find us in Discussions or Join our Discord.

Website | Documentation | Installation | Getting Started | Contributor's Guide 


Author: Smallstep
Source Code: https://github.com/smallstep/certificates 
License: Apache-2.0 license

#go #golang #tls #ssh #security 

Certificates: A Private Certificate Authority (X.509 & SSH)
Lawrence  Lesch

Lawrence Lesch

1657952100

Cipherhub: Encrypt Messages Based on Ssh Public Keys

cipherhub

encrypt messages based on ssh public keys

It can be frustrating and annoying to communicate with somebody using public key cryptography since setting up PGP/GPG is a hassle, particularly managing keyrings and webs of trust.

Luckily, you can fetch the public ssh keys of anybody on github by going to:

https://github.com/$USERNAME.keys

If you just want to send somebody an encrypted message out of the blue and they already have a github account with RSA keys uploaded to it, you can just do:

cipherhub $USERNAME < secret_message.txt

and it will fetch their public keys from github, storing the key locally for next time.

There is an openssl rsautl command to do this but the usage is not particularly friendly and doesn't keep a keyring around.

install

With npm do:

npm install -g cipherhub

to get the cipherhub command.

usage

cipherhub USERNAME {OPTIONS} < message.txt

  Create an encrypted message for USERNAME on stdin.
 
  If there isn't yet a local key stored for USERNAME, request a key from
  https://github.com/$USERNAME.keys
 
  If there are multiple RSA keys, the operation fails and you will need to
  add the key you want manually with `cipherhub --add`.
  If there are no RSA keys, the command fails with a nonzero exit code.
 
  OPTIONS are:
 
    --no-github     don't request key data from github, just fail
    --no-save       don't automatically save keys fetched from github
    --quiet, -q     suppress extra output
    --encoding, -e  output encoding to use. default: base64

cipherhub --add USERNAME < id_rsa.pub
cipherhub -a USERNAME < id_rsa.pub

  Set the public key for USERNAME from stdin.

cipherhub --remove USERNAME
cipherhub -r USERNAME

  Remove a USERNAME from the local key list.

cipherhub --list
cipherhub -l

  List all the keys in the local key list.

cipherhub --decrypt PRIVKEY {OPTIONS}
cipherhub -d PRIVKEY {OPTIONS}

  Decrypt a message on stdin with an rsa key file PRIVKEY.
  If PRIVKEY isn't specified, only `-d` by itself, cipherhub uses ~/.ssh/id_rsa

  OPTIONS are:

    --encoding, -e  input encoding. default: base64

crazy ideas

You can create private github issues by just encrypting your message with the maintainer's public key and posting the issue with the ciphertext.

caveat npmtor

github's servers can be compromised by a court order, intruder, or employee. You should use a secondary means of verification to check all the keys fetched from github where secrecy from courts, intruders, and github employees is of paramount importance.

Author: Substack
Source Code: https://github.com/substack/cipherhub 
License: View license

#javascript #key #ssh 

Cipherhub: Encrypt Messages Based on Ssh Public Keys

SSH2 Client & Server Modules Written in Pure JavaScript for Node.js

Description

SSH2 client and server modules written in pure JavaScript for node.js.

Development/testing is done against OpenSSH (8.7 currently).

Changes (breaking or otherwise) in v1.0.0 can be found here.

Requirements

  • node.js -- v10.16.0 or newer
    • node v12.0.0 or newer for Ed25519 key support
  • (Optional) cpu-features is set as an optional package dependency (you do not need to install it explicitly/separately from ssh2) that will be automatically built and used if possible. See the project's documentation for its own requirements.
    • This addon is currently used to help generate an optimal default cipher list

Installation

npm install ssh2

Client Examples

Execute 'uptime' on a server

const { readFileSync } = require('fs');

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.exec('uptime', (err, stream) => {
    if (err) throw err;
    stream.on('close', (code, signal) => {
      console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
      conn.end();
    }).on('data', (data) => {
      console.log('STDOUT: ' + data);
    }).stderr.on('data', (data) => {
      console.log('STDERR: ' + data);
    });
  });
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  privateKey: readFileSync('/path/to/my/key')
});

// example output:
// Client :: ready
// STDOUT:  17:41:15 up 22 days, 18:09,  1 user,  load average: 0.00, 0.01, 0.05
//
// Stream :: exit :: code: 0, signal: undefined
// Stream :: close

Start an interactive shell session

const { readFileSync } = require('fs');

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.shell((err, stream) => {
    if (err) throw err;
    stream.on('close', () => {
      console.log('Stream :: close');
      conn.end();
    }).on('data', (data) => {
      console.log('OUTPUT: ' + data);
    });
    stream.end('ls -l\nexit\n');
  });
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  privateKey: readFileSync('/path/to/my/key')
});

// example output:
// Client :: ready
// STDOUT: Last login: Sun Jun 15 09:37:21 2014 from 192.168.100.100
//
// STDOUT: ls -l
// exit
//
// STDOUT: frylock@athf:~$ ls -l
//
// STDOUT: total 8
//
// STDOUT: drwxr-xr-x 2 frylock frylock 4096 Nov 18  2012 mydir
//
// STDOUT: -rw-r--r-- 1 frylock frylock   25 Apr 11  2013 test.txt
//
// STDOUT: frylock@athf:~$ exit
//
// STDOUT: logout
//
// Stream :: close

Send a raw HTTP request to port 80 on the server

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.forwardOut('192.168.100.102', 8000, '127.0.0.1', 80, (err, stream) => {
    if (err) throw err;
    stream.on('close', () => {
      console.log('TCP :: CLOSED');
      conn.end();
    }).on('data', (data) => {
      console.log('TCP :: DATA: ' + data);
    }).end([
      'HEAD / HTTP/1.1',
      'User-Agent: curl/7.27.0',
      'Host: 127.0.0.1',
      'Accept: */*',
      'Connection: close',
      '',
      ''
    ].join('\r\n'));
  });
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  password: 'nodejsrules'
});

// example output:
// Client :: ready
// TCP :: DATA: HTTP/1.1 200 OK
// Date: Thu, 15 Nov 2012 13:52:58 GMT
// Server: Apache/2.2.22 (Ubuntu)
// X-Powered-By: PHP/5.4.6-1ubuntu1
// Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT
// Content-Encoding: gzip
// Vary: Accept-Encoding
// Connection: close
// Content-Type: text/html; charset=UTF-8
//
//
// TCP :: CLOSED

Forward local connections to port 8000 on the server to us

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.forwardIn('127.0.0.1', 8000, (err) => {
    if (err) throw err;
    console.log('Listening for connections on server on port 8000!');
  });
}).on('tcp connection', (info, accept, reject) => {
  console.log('TCP :: INCOMING CONNECTION:');
  console.dir(info);
  accept().on('close', () => {
    console.log('TCP :: CLOSED');
  }).on('data', (data) => {
    console.log('TCP :: DATA: ' + data);
  }).end([
    'HTTP/1.1 404 Not Found',
    'Date: Thu, 15 Nov 2012 02:07:58 GMT',
    'Server: ForwardedConnection',
    'Content-Length: 0',
    'Connection: close',
    '',
    ''
  ].join('\r\n'));
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  password: 'nodejsrules'
});

// example output:
// Client :: ready
// Listening for connections on server on port 8000!
//  (.... then from another terminal on the server: `curl -I http://127.0.0.1:8000`)
// TCP :: INCOMING CONNECTION: { destIP: '127.0.0.1',
//  destPort: 8000,
//  srcIP: '127.0.0.1',
//  srcPort: 41969 }
// TCP DATA: HEAD / HTTP/1.1
// User-Agent: curl/7.27.0
// Host: 127.0.0.1:8000
// Accept: */*
//
//
// TCP :: CLOSED

Get a directory listing via SFTP

const { Client } = require('ssh2');

const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  conn.sftp((err, sftp) => {
    if (err) throw err;
    sftp.readdir('foo', (err, list) => {
      if (err) throw err;
      console.dir(list);
      conn.end();
    });
  });
}).connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  password: 'nodejsrules'
});

// example output:
// Client :: ready
// [ { filename: 'test.txt',
//     longname: '-rw-r--r--    1 frylock   frylock         12 Nov 18 11:05 test.txt',
//     attrs:
//      { size: 12,
//        uid: 1000,
//        gid: 1000,
//        mode: 33188,
//        atime: 1353254750,
//        mtime: 1353254744 } },
//   { filename: 'mydir',
//     longname: 'drwxr-xr-x    2 frylock   frylock       4096 Nov 18 15:03 mydir',
//     attrs:
//      { size: 1048576,
//        uid: 1000,
//        gid: 1000,
//        mode: 16877,
//        atime: 1353269007,
//        mtime: 1353269007 } } ]

Connection hopping

const { Client } = require('ssh2');

const conn1 = new Client();
const conn2 = new Client();

// Checks uptime on 10.1.1.40 via 192.168.1.1

conn1.on('ready', () => {
  console.log('FIRST :: connection ready');
  // Alternatively, you could use something like netcat or socat with exec()
  // instead of forwardOut(), depending on what the server allows
  conn1.forwardOut('127.0.0.1', 12345, '10.1.1.40', 22, (err, stream) => {
    if (err) {
      console.log('FIRST :: forwardOut error: ' + err);
      return conn1.end();
    }
    conn2.connect({
      sock: stream,
      username: 'user2',
      password: 'password2',
    });
  });
}).connect({
  host: '192.168.1.1',
  username: 'user1',
  password: 'password1',
});

conn2.on('ready', () => {
  // This connection is the one to 10.1.1.40

  console.log('SECOND :: connection ready');
  conn2.exec('uptime', (err, stream) => {
    if (err) {
      console.log('SECOND :: exec error: ' + err);
      return conn1.end();
    }
    stream.on('close', () => {
      conn1.end(); // close parent (and this) connection
    }).on('data', (data) => {
      console.log(data.toString());
    });
  });
});

Forward remote X11 connections

const { Socket } = require('net');

const { Client } = require('ssh2');

const conn = new Client();

conn.on('x11', (info, accept, reject) => {
  const xserversock = new net.Socket();
  xserversock.on('connect', () => {
    const xclientsock = accept();
    xclientsock.pipe(xserversock).pipe(xclientsock);
  });
  // connects to localhost:0.0
  xserversock.connect(6000, 'localhost');
});

conn.on('ready', () => {
  conn.exec('xeyes', { x11: true }, (err, stream) => {
    if (err) throw err;
    let code = 0;
    stream.on('close', () => {
      if (code !== 0)
        console.log('Do you have X11 forwarding enabled on your SSH server?');
      conn.end();
    }).on('exit', (exitcode) => {
      code = exitcode;
    });
  });
}).connect({
  host: '192.168.1.1',
  username: 'foo',
  password: 'bar'
});

Dynamic (1:1) port forwarding using a SOCKSv5 proxy (using socksv5)

const socks = require('socksv5');
const { Client } = require('ssh2');

const sshConfig = {
  host: '192.168.100.1',
  port: 22,
  username: 'nodejs',
  password: 'rules'
};

socks.createServer((info, accept, deny) => {
  // NOTE: you could just use one ssh2 client connection for all forwards, but
  // you could run into server-imposed limits if you have too many forwards open
  // at any given time
  const conn = new Client();
  conn.on('ready', () => {
    conn.forwardOut(info.srcAddr,
                    info.srcPort,
                    info.dstAddr,
                    info.dstPort,
                    (err, stream) => {
      if (err) {
        conn.end();
        return deny();
      }

      const clientSocket = accept(true);
      if (clientSocket) {
        stream.pipe(clientSocket).pipe(stream).on('close', () => {
          conn.end();
        });
      } else {
        conn.end();
      }
    });
  }).on('error', (err) => {
    deny();
  }).connect(sshConfig);
}).listen(1080, 'localhost', () => {
  console.log('SOCKSv5 proxy server started on port 1080');
}).useAuth(socks.auth.None());

// test with cURL:
//   curl -i --socks5 localhost:1080 google.com

Make HTTP(S) connections easily using a custom http(s).Agent

const http = require('http');

const { Client, HTTPAgent, HTTPSAgent } = require('ssh2');

const sshConfig = {
  host: '192.168.100.1',
  port: 22,
  username: 'nodejs',
  password: 'rules'
};

// Use `HTTPSAgent` instead for an HTTPS request
const agent = new HTTPAgent(sshConfig);
http.get({
  host: '192.168.200.1',
  agent,
  headers: { Connection: 'close' }
}, (res) => {
  console.log(res.statusCode);
  console.dir(res.headers);
  res.resume();
});

Invoke an arbitrary subsystem

const { Client } = require('ssh2');

const xmlhello = `
  <?xml version="1.0" encoding="UTF-8"?>
  <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <capabilities>
      <capability>urn:ietf:params:netconf:base:1.0</capability>
    </capabilities>
  </hello>]]>]]>`;

const conn = new Client();

conn.on('ready', () => {
  console.log('Client :: ready');
  conn.subsys('netconf', (err, stream) => {
    if (err) throw err;
    stream.on('data', (data) => {
      console.log(data);
    }).write(xmlhello);
  });
}).connect({
  host: '1.2.3.4',
  port: 22,
  username: 'blargh',
  password: 'honk'
});

Server Examples

Password and public key authentication and non-interactive (exec) command execution

const { timingSafeEqual } = require('crypto');
const { readFileSync } = require('fs');
const { inspect } = require('util');

const { utils: { parseKey }, Server } = require('ssh2');

const allowedUser = Buffer.from('foo');
const allowedPassword = Buffer.from('bar');
const allowedPubKey = parseKey(readFileSync('foo.pub'));

function checkValue(input, allowed) {
  const autoReject = (input.length !== allowed.length);
  if (autoReject) {
    // Prevent leaking length information by always making a comparison with the
    // same input when lengths don't match what we expect ...
    allowed = input;
  }
  const isMatch = timingSafeEqual(input, allowed);
  return (!autoReject && isMatch);
}

new Server({
  hostKeys: [readFileSync('host.key')]
}, (client) => {
  console.log('Client connected!');

  client.on('authentication', (ctx) => {
    let allowed = true;
    if (!checkValue(Buffer.from(ctx.username), allowedUser))
      allowed = false;

    switch (ctx.method) {
      case 'password':
        if (!checkValue(Buffer.from(ctx.password), allowedPassword))
          return ctx.reject();
        break;
      case 'publickey':
        if (ctx.key.algo !== allowedPubKey.type
            || !checkValue(ctx.key.data, allowedPubKey.getPublicSSH())
            || (ctx.signature && allowedPubKey.verify(ctx.blob, ctx.signature) !== true)) {
          return ctx.reject();
        }
        break;
      default:
        return ctx.reject();
    }

    if (allowed)
      ctx.accept();
    else
      ctx.reject();
  }).on('ready', () => {
    console.log('Client authenticated!');

    client.on('session', (accept, reject) => {
      const session = accept();
      session.once('exec', (accept, reject, info) => {
        console.log('Client wants to execute: ' + inspect(info.command));
        const stream = accept();
        stream.stderr.write('Oh no, the dreaded errors!\n');
        stream.write('Just kidding about the errors!\n');
        stream.exit(0);
        stream.end();
      });
    });
  }).on('close', () => {
    console.log('Client disconnected');
  });
}).listen(0, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});

SFTP-only server

const { timingSafeEqual } = require('crypto');
const { readFileSync } = require('fs');
const { inspect } = require('util');

const {
  Server,
  sftp: {
    OPEN_MODE,
    STATUS_CODE,
  },
} = require('ssh2');

const allowedUser = Buffer.from('foo');
const allowedPassword = Buffer.from('bar');

function checkValue(input, allowed) {
  const autoReject = (input.length !== allowed.length);
  if (autoReject) {
    // Prevent leaking length information by always making a comparison with the
    // same input when lengths don't match what we expect ...
    allowed = input;
  }
  const isMatch = timingSafeEqual(input, allowed);
  return (!autoReject && isMatch);
}

// This simple SFTP server implements file uploading where the contents get
// ignored ...

new ssh2.Server({
  hostKeys: [readFileSync('host.key')]
}, (client) => {
  console.log('Client connected!');

  client.on('authentication', (ctx) => {
    let allowed = true;
    if (!checkValue(Buffer.from(ctx.username), allowedUser))
      allowed = false;

    switch (ctx.method) {
      case 'password':
        if (!checkValue(Buffer.from(ctx.password), allowedPassword))
          return ctx.reject();
        break;
      default:
        return ctx.reject();
    }

    if (allowed)
      ctx.accept();
    else
      ctx.reject();
  }).on('ready', () => {
    console.log('Client authenticated!');

    client.on('session', (accept, reject) => {
      const session = accept();
      session.on('sftp', (accept, reject) => {
        console.log('Client SFTP session');
        const openFiles = new Map();
        let handleCount = 0;
        const sftp = accept();
        sftp.on('OPEN', (reqid, filename, flags, attrs) => {
          // Only allow opening /tmp/foo.txt for writing
          if (filename !== '/tmp/foo.txt' || !(flags & OPEN_MODE.WRITE))
            return sftp.status(reqid, STATUS_CODE.FAILURE);

          // Create a fake handle to return to the client, this could easily
          // be a real file descriptor number for example if actually opening
          // a file on disk
          const handle = Buffer.alloc(4);
          openFiles.set(handleCount, true);
          handle.writeUInt32BE(handleCount++, 0);

          console.log('Opening file for write')
          sftp.handle(reqid, handle);
        }).on('WRITE', (reqid, handle, offset, data) => {
          if (handle.length !== 4
              || !openFiles.has(handle.readUInt32BE(0))) {
            return sftp.status(reqid, STATUS_CODE.FAILURE);
          }

          // Fake the write operation
          sftp.status(reqid, STATUS_CODE.OK);

          console.log('Write to file at offset ${offset}: ${inspect(data)}');
        }).on('CLOSE', (reqid, handle) => {
          let fnum;
          if (handle.length !== 4
              || !openFiles.has(fnum = handle.readUInt32BE(0))) {
            return sftp.status(reqid, STATUS_CODE.FAILURE);
          }

          console.log('Closing file');
          openFiles.delete(fnum);

          sftp.status(reqid, STATUS_CODE.OK);
        });
      });
    });
  }).on('close', () => {
    console.log('Client disconnected');
  });
}).listen(0, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});

You can find more examples in the examples directory of this repository.

API

require('ssh2').Client is the Client constructor.

require('ssh2').Server is the Server constructor.

require('ssh2').utils is an object containing some useful utilities.

require('ssh2').HTTPAgent is an http.Agent constructor.

require('ssh2').HTTPSAgent is an https.Agent constructor. Its API is the same as HTTPAgent except it's for HTTPS connections.

Agent-related

require('ssh2').AgentProtocol is a Duplex stream class that aids in communicating over the OpenSSH agent protocol.

require('ssh2').BaseAgent is a base class for creating custom authentication agents.

require('ssh2').createAgent is a helper function that creates a new agent instance using the same logic as the agent configuration option: if the platform is Windows and it's the value "pageant", it creates a PageantAgent, otherwise if it's not a path to a Windows pipe it creates a CygwinAgent. In all other cases, it creates an OpenSSHAgent.

require('ssh2').CygwinAgent is an agent class implementation that communicates with agents in a Cygwin environment.

require('ssh2').OpenSSHAgent is an agent class implementation that communicates with OpenSSH agents over a UNIX socket.

require('ssh2').PageantAgent is an agent class implementation that communicates with Pageant agent processes.

Client

Client events

banner(< string >message, < string >language) - A notice was sent by the server upon connection.

change password(< string >prompt, < function >done) - If using password-based user authentication, the server has requested that the user's password be changed. Call done with the new password.

close() - The socket was closed.

end() - The socket was disconnected.

error(< Error >err) - An error occurred. A 'level' property indicates 'client-socket' for socket-level errors and 'client-ssh' for SSH disconnection messages. In the case of 'client-ssh' messages, there may be a 'description' property that provides more detail.

handshake(< object >negotiated) - Emitted when a handshake has completed (either initial or rekey). negotiated contains the negotiated details of the handshake and is of the form:

    // In this particular case `mac` is empty because there is no separate MAC
    // because it's integrated into AES in GCM mode
    { kex: 'ecdh-sha2-nistp256',
      srvHostKey: 'rsa-sha2-512',
      cs: { // Client to server algorithms
        cipher: 'aes128-gcm',
        mac: '',
        compress: 'none',
        lang: ''
      },
      sc: { // Server to client algorithms
        cipher: 'aes128-gcm',
        mac: '',
        compress: 'none',
        lang: ''
      }
    }

hostkeys(< array >keys) - Emitted when the server announces its available host keys. keys is the list of parsed (using parseKey()) host public keys.

keyboard-interactive(< string >name, < string >instructions, < string >instructionsLang, < array >prompts, < function >finish) - The server is asking for replies to the given prompts for keyboard-interactive user authentication. name is generally what you'd use as a window title (for GUI apps). prompts is an array of { prompt: 'Password: ', echo: false } style objects (here echo indicates whether user input should be displayed on the screen). The answers for all prompts must be provided as an array of strings and passed to finish when you are ready to continue. Note: It's possible for the server to come back and ask more questions.

ready() - Authentication was successful.

rekey() - Emitted when a rekeying operation has completed (either client or server-initiated).

tcp connection(< object >details, < function >accept, < function >reject) - An incoming forwarded TCP connection is being requested. Calling accept accepts the connection and returns a Channel object. Calling reject rejects the connection and no further action is needed. details contains:

destIP - string - The remote IP the connection was received on (given in earlier call to forwardIn()).

destPort - integer - The remote port the connection was received on (given in earlier call to forwardIn()).

srcIP - string - The originating IP of the connection.

srcPort - integer - The originating port of the connection.

unix connection(< object >details, < function >accept, < function >reject) - An incoming forwarded UNIX socket connection is being requested. Calling accept accepts the connection and returns a Channel object. Calling reject rejects the connection and no further action is needed. details contains:

  • socketPath - string - The originating UNIX socket path of the connection.

x11(< object >details, < function >accept, < function >reject) - An incoming X11 connection is being requested. Calling accept accepts the connection and returns a Channel object. Calling reject rejects the connection and no further action is needed. details contains:

srcIP - string - The originating IP of the connection.

srcPort - integer - The originating port of the connection.

Client methods

(constructor)() - Creates and returns a new Client instance.

connect(< object >config) - (void) - Attempts a connection to a server using the information given in config:

agent - string - Path to ssh-agent's UNIX socket for ssh-agent-based user authentication. Windows users: set to 'pageant' for authenticating with Pageant or (actual) path to a cygwin "UNIX socket." Default: (none)

agentForward - boolean - Set to true to use OpenSSH agent forwarding (auth-agent@openssh.com) for the life of the connection. agent must also be set to use this feature. Default: false

algorithms - object - This option allows you to explicitly override the default transport layer algorithms used for the connection. The value for each category must either be an array of valid algorithm names to set an exact list (with the most preferable first) or an object containing append, prepend, and/or remove properties that each contain an array of algorithm names or RegExps to match to adjust default lists for each category. Valid keys:

cipher - mixed - Ciphers.

  • Default list (in order from most to least preferable):
    • chacha20-poly1305@openssh.com (priority of chacha20-poly1305 may vary depending upon CPU and/or optional binding availability)
    • aes128-gcm
    • aes128-gcm@openssh.com
    • aes256-gcm
    • aes256-gcm@openssh.com
    • aes128-ctr
    • aes192-ctr
    • aes256-ctr
  • Other supported names:
    • 3des-cbc
    • aes256-cbc
    • aes192-cbc
    • aes128-cbc
    • arcfour256
    • arcfour128
    • arcfour
    • blowfish-cbc
    • cast128-cbc

compress - mixed - Compression algorithms.

  • Default list (in order from most to least preferable):
    • none
    • zlib@openssh.com
    • zlib
  • Other supported names:

hmac - mixed - (H)MAC algorithms.

  • Default list (in order from most to least preferable):
    • hmac-sha2-256-etm@openssh.com
    • hmac-sha2-512-etm@openssh.com
    • hmac-sha1-etm@openssh.com
    • hmac-sha2-256
    • hmac-sha2-512
    • hmac-sha1
  • Other supported names:
    • hmac-md5
    • hmac-sha2-256-96
    • hmac-sha2-512-96
    • hmac-ripemd160
    • hmac-sha1-96
    • hmac-md5-96

kex - mixed - Key exchange algorithms.

  • Default list (in order from most to least preferable):
    • curve25519-sha256 (node v14.0.0+)
    • curve25519-sha256@libssh.org (node v14.0.0+)
    • ecdh-sha2-nistp256
    • ecdh-sha2-nistp384
    • ecdh-sha2-nistp521
    • diffie-hellman-group-exchange-sha256
    • diffie-hellman-group14-sha256
    • diffie-hellman-group15-sha512
    • diffie-hellman-group16-sha512
    • diffie-hellman-group17-sha512
    • diffie-hellman-group18-sha512
  • Other supported names:
    • diffie-hellman-group-exchange-sha1
    • diffie-hellman-group14-sha1
    • diffie-hellman-group1-sha1

serverHostKey - mixed - Server host key formats.

  • Default list (in order from most to least preferable):
    • ssh-ed25519 (node v12.0.0+)
    • ecdsa-sha2-nistp256
    • ecdsa-sha2-nistp384
    • ecdsa-sha2-nistp521
    • rsa-sha2-512
    • rsa-sha2-256
    • ssh-rsa
  • Other supported names:
    • ssh-dss

authHandler - mixed - Must be an array of objects as described below, an array of strings containing valid authentication method names (username and credentials are pulled from the object passed to connect()), or a function with parameters (methodsLeft, partialSuccess, callback) where methodsLeft and partialSuccess are null on the first authentication attempt, otherwise are an array and boolean respectively. Return or call callback() with either the name of the authentication method or an object containing the method name along with method-specific details to try next (return/pass false to signal no more methods to try). Valid method names are: 'none', 'password', 'publickey', 'agent', 'keyboard-interactive', 'hostbased'. Default: function that follows a set method order: None -> Password -> Private Key -> Agent (-> keyboard-interactive if tryKeyboard is true) -> Hostbased

When returning or calling callback() with an object, it can take one of the following forms:

{
  type: 'none',
  username: 'foo',
}
{
  type: 'password'
  username: 'foo',
  password: 'bar',
}
{
  type: 'publickey'
  username: 'foo',
  // Can be a string, Buffer, or parsed key containing a private key
  key: ...,
  // `passphrase` only required for encrypted keys
  passphrase: ...,
}
{
  type: 'hostbased'
  username: 'foo',
  localHostname: 'baz',
  localUsername: 'quux',
  // Can be a string, Buffer, or parsed key containing a private key
  key: ...,
  // `passphrase` only required for encrypted keys
  passphrase: ...,
}
{
  type: 'agent'
  username: 'foo',
  // Can be a string that is interpreted exactly like the `agent`
  // connection config option or can be a custom agent
  // object/instance that extends and implements `BaseAgent`
  agent: ...,
}
{
  type: 'keyboard-interactive'
  username: 'foo',
  // This works exactly the same way as a 'keyboard-interactive'
  // Client event handler
  prompt: (name, instructions, instructionsLang, prompts, finish) => {
    // ...
  },
}

debug - function - Set this to a function that receives a single string argument to get detailed (local) debug information. Default: (none)

forceIPv4 - boolean - Only connect via resolved IPv4 address for host. Default: false

forceIPv6 - boolean - Only connect via resolved IPv6 address for host. Default: false

host - string - Hostname or IP address of the server. Default: 'localhost'

hostHash - string - Any valid hash algorithm supported by node. The host's key is hashed using this algorithm and passed to the hostVerifier function as a hex string. Default: (none)

hostVerifier - function - Function with parameters (hashedKey[, callback]) where hashedKey is a string hex hash of the host's key for verification purposes. Return true to continue with the handshake or false to reject and disconnect, or call callback() with true or false if you need to perform asynchronous verification. Default: (auto-accept if hostVerifier is not set)

keepaliveCountMax - integer - How many consecutive, unanswered SSH-level keepalive packets that can be sent to the server before disconnection (similar to OpenSSH's ServerAliveCountMax config option). Default: 3

keepaliveInterval - integer - How often (in milliseconds) to send SSH-level keepalive packets to the server (in a similar way as OpenSSH's ServerAliveInterval config option). Set to 0 to disable. Default: 0

localAddress - string - IP address of the network interface to use to connect to the server. Default: (none -- determined by OS)

localHostname - string - Along with localUsername and privateKey, set this to a non-empty string for hostbased user authentication. Default: (none)

localPort - string - The local port number to connect from. Default: (none -- determined by OS)

localUsername - string - Along with localHostname and privateKey, set this to a non-empty string for hostbased user authentication. Default: (none)

passphrase - string - For an encrypted privateKey, this is the passphrase used to decrypt it. Default: (none)

password - string - Password for password-based user authentication. Default: (none)

port - integer - Port number of the server. Default: 22

privateKey - mixed - Buffer or string that contains a private key for either key-based or hostbased user authentication (OpenSSH format). Default: (none)

readyTimeout - integer - How long (in milliseconds) to wait for the SSH handshake to complete. Default: 20000

sock - ReadableStream - A ReadableStream to use for communicating with the server instead of creating and using a new TCP connection (useful for connection hopping).

strictVendor - boolean - Performs a strict server vendor check before sending vendor-specific requests, etc. (e.g. check for OpenSSH server when using openssh_noMoreSessions()) Default: true

tryKeyboard - boolean - Try keyboard-interactive user authentication if primary user authentication method fails. If you set this to true, you need to handle the keyboard-interactive event. Default: false

username - string - Username for authentication. Default: (none)

end() - (void) - Disconnects the socket.

exec(< string >command[, < object >options], < function >callback) - (void) - Executes command on the server. callback has 2 parameters: < Error >err, < Channel >stream. Valid options properties are:

env - object - An environment to use for the execution of the command.

pty - mixed - Set to true to allocate a pseudo-tty with defaults, or an object containing specific pseudo-tty settings (see 'Pseudo-TTY settings'). Setting up a pseudo-tty can be useful when working with remote processes that expect input from an actual terminal (e.g. sudo's password prompt).

x11 - mixed - Set to true to use defaults below, set to a number to specify a specific screen number, or an object with the following valid properties:

cookie - mixed - The authentication cookie. Can be a hex string or a Buffer containing the raw cookie value (which will be converted to a hex string). Default: (random 16 byte value)

protocol - string - The authentication protocol name. Default: 'MIT-MAGIC-COOKIE-1'

screen - number - Screen number to use Default: 0

single - boolean - Allow just a single connection? Default: false

forwardIn(< string >remoteAddr, < integer >remotePort, < function >callback) - (void) - Bind to remoteAddr on remotePort on the server and forward incoming TCP connections. callback has 2 parameters: < Error >err, < integer >port (port is the assigned port number if remotePort was 0). Here are some special values for remoteAddr and their associated binding behaviors:

'' - Connections are to be accepted on all protocol families supported by the server.

'0.0.0.0' - Listen on all IPv4 addresses.

'::' - Listen on all IPv6 addresses.

'localhost' - Listen on all protocol families supported by the server on loopback addresses only.

'127.0.0.1' and '::1' - Listen on the loopback interfaces for IPv4 and IPv6, respectively.

forwardOut(< string >srcIP, < integer >srcPort, < string >dstIP, < integer >dstPort, < function >callback) - (void) - Open a connection with srcIP and srcPort as the originating address and port and dstIP and dstPort as the remote destination address and port. callback has 2 parameters: < Error >err, < Channel >stream.

openssh_forwardInStreamLocal(< string >socketPath, < function >callback) - (void) - OpenSSH extension that binds to a UNIX domain socket at socketPath on the server and forwards incoming connections. callback has 1 parameter: < Error >err.

openssh_forwardOutStreamLocal(< string >socketPath, < function >callback) - (void) - OpenSSH extension that opens a connection to a UNIX domain socket at socketPath on the server. callback has 2 parameters: < Error >err, < Channel >stream.

openssh_noMoreSessions(< function >callback) - (void) - OpenSSH extension that sends a request to reject any new sessions (e.g. exec, shell, sftp, subsys) for this connection. callback has 1 parameter: < Error >err.

openssh_unforwardInStreamLocal(< string >socketPath, < function >callback) - (void) - OpenSSH extension that unbinds from a UNIX domain socket at socketPath on the server and stops forwarding incoming connections. callback has 1 parameter: < Error >err.

rekey([< function >callback]) - (void) - Initiates a rekey with the server. If callback is supplied, it is added as a one-time handler for the rekey event.

sftp(< function >callback) - (void) - Starts an SFTP session. callback has 2 parameters: < Error >err, < SFTP >sftp. For methods available on sftp, see the SFTP client documentation.

shell([[< mixed >window,] < object >options]< function >callback) - (void) - Starts an interactive shell session on the server, with an optional window object containing pseudo-tty settings (see 'Pseudo-TTY settings'). If window === false, then no pseudo-tty is allocated. options supports the x11 and env options as described in exec(). callback has 2 parameters: < Error >err, < Channel >stream.

subsys(< string >subsystem, < function >callback) - (void) - Invokes subsystem on the server. callback has 2 parameters: < Error >err, < Channel >stream.

unforwardIn(< string >remoteAddr, < integer >remotePort, < function >callback) - (void) - Unbind from remoteAddr on remotePort on the server and stop forwarding incoming TCP connections. Until callback is called, more connections may still come in. callback has 1 parameter: < Error >err.

Server

Server events

connection(< Connection >client, < object >info) - A new client has connected. info contains the following properties:

family - string - The remoteFamily of the connection.

header - object - Information about the client's header:

identRaw - string - The raw client identification string.

versions - object - Various version information:

protocol - string - The SSH protocol version (always 1.99 or 2.0).

software - string - The software name and version of the client.

comments - string - Any text that comes after the software name/version.

        { identRaw: 'SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2',
          version: {
            protocol: '2.0',
            software: 'OpenSSH_6.6.1p1'
          },
          comments: 'Ubuntu-2ubuntu2' }
* **ip** - _string_ - The `remoteAddress` of the connection.

* **port** - _integer_ - The `remotePort` of the connection.

Server methods

(constructor)(< object >config[, < function >connectionListener]) - Creates and returns a new Server instance. Server instances also have the same methods/properties/events as net.Server. connectionListener if supplied, is added as a connection listener. Valid config properties:

algorithms - object - This option allows you to explicitly override the default transport layer algorithms used for incoming client connections. Each value must be an array of valid algorithms for that category. The order of the algorithms in the arrays are important, with the most favorable being first. For a list of valid and default algorithm names, please review the documentation for the version of ssh2 used by this module. Valid keys:

cipher - array - Ciphers.

compress - array - Compression algorithms.

hmac - array - (H)MAC algorithms.

kex - array - Key exchange algorithms.

serverHostKey - array - Server host key formats.

banner - string - A message that is sent to clients once, right before authentication begins. Default: (none)

debug - function - Set this to a function that receives a single string argument to get detailed (local) debug information. Default: (none)

greeting - string - A message that is sent to clients immediately upon connection, before handshaking begins. Note: Most clients usually ignore this. Default: (none)

highWaterMark - integer - This is the highWaterMark to use for the parser stream. Default: 32 * 1024

hostKeys - array - An array of either Buffers/strings that contain host private keys or objects in the format of { key: <Buffer/string>, passphrase: <string> } for encrypted private keys. (Required) Default: (none)

ident - string - A custom server software name/version identifier. Default: 'ssh2js' + moduleVersion + 'srv'

injectSocket(< DuplexStream >socket) - Injects a bidirectional stream as though it were a TCP socket connection. Additionally, socket should include net.Socket-like properties to ensure the best compatibility (e.g. socket.remoteAddress, socket.remotePort, socket.remoteFamily).

Connection events

authentication(< AuthContext >ctx) - The client has requested authentication. ctx.username contains the client username, ctx.method contains the requested authentication method, and ctx.accept() and ctx.reject([< Array >authMethodsLeft[, < Boolean >isPartialSuccess]]) are used to accept or reject the authentication request respectively. abort is emitted if the client aborts the authentication request. Other properties/methods available on ctx depends on the ctx.method of authentication the client has requested:

hostbased:

blob - Buffer - This contains the data to be verified that is passed to (along with the signature) key.verify() where key is a public key parsed with parseKey().

key - object - Contains information about the public key sent by the client:

algo - string - The name of the key algorithm (e.g. ssh-rsa).

data - Buffer - The actual key data.

localHostname - string - The local hostname provided by the client.

localUsername - string - The local username provided by the client.

signature - Buffer - This contains a signature to be verified that is passed to (along with the blob) key.verify() where key is a public key parsed with parseKey().

keyboard-interactive:

prompt(< array >prompts[, < string >title[, < string >instructions]], < function >callback) - (void) - Send prompts to the client. prompts is an array of { prompt: 'Prompt text', echo: true } objects (prompt being the prompt text and echo indicating whether the client's response to the prompt should be echoed to their display). callback is called with (responses), where responses is an array of string responses matching up to the prompts.

submethods - array - A list of preferred authentication "sub-methods" sent by the client. This may be used to determine what (if any) prompts to send to the client.

password:

password - string - This is the password sent by the client.

requestChange(< string >prompt, < function >callback) - (void) - Sends a password change request to the client. callback is called with (newPassword), where newPassword is the new password supplied by the client. You may accept, reject, or prompt for another password change after callback is called.

publickey:

blob - mixed - If the value is undefined, the client is only checking the validity of the key. If the value is a Buffer, then this contains the data to be verified that is passed to (along with the signature) key.verify() where key is a public key parsed with parseKey().

key - object - Contains information about the public key sent by the client:

algo - string - The name of the key algorithm (e.g. ssh-rsa).

data - Buffer - The actual key data.

signature - mixed - If the value is undefined, the client is only checking the validity of the key. If the value is a Buffer, then this contains a signature to be verified that is passed to (along with the blob) key.verify() where key is a public key parsed with parseKey().

close() - The client socket was closed.

end() - The client socket disconnected.

error(< Error >err) - An error occurred.

handshake(< object >negotiated) - Emitted when a handshake has completed (either initial or rekey). negotiated contains the negotiated details of the handshake and is of the form:

    // In this particular case `mac` is empty because there is no separate MAC    // because it's integrated into AES in GCM mode    { kex: 'ecdh-sha2-nistp256',      srvHostKey: 'rsa-sha2-512',      cs: { // Client to server algorithms        cipher: 'aes128-gcm',        mac: '',        compress: 'none',        lang: ''      },      sc: { // Server to client algorithms        cipher: 'aes128-gcm',        mac: '',        compress: 'none',        lang: ''      }    }

openssh.streamlocal(< function >accept, < function >reject, < object >info) - Emitted when the client has requested a connection to a UNIX domain socket. accept() returns a new Channel instance representing the connection. info contains:

  • socketPath - string - Destination socket path of outgoing connection.

ready() - Emitted when the client has been successfully authenticated.

rekey() - Emitted when a rekeying operation has completed (either client or server-initiated).

request(< mixed >accept, < mixed >reject, < string >name, < object >info) - Emitted when the client has sent a global request for name (e.g. tcpip-forward or cancel-tcpip-forward). accept and reject are functions if the client requested a response. If bindPort === 0, you should pass the chosen port to accept() so that the client will know what port was bound. info contains additional details about the request:

cancel-tcpip-forward and tcpip-forward:

bindAddr - string - The IP address to start/stop binding to.

bindPort - integer - The port to start/stop binding to.

cancel-streamlocal-forward@openssh.com and streamlocal-forward@openssh.com:

  • socketPath - string - The socket path to start/stop binding to.

session(< function >accept, < function >reject) - Emitted when the client has requested a new session. Sessions are used to start interactive shells, execute commands, request X11 forwarding, etc. accept() returns a new Session instance.

tcpip(< function >accept, < function >reject, < object >info) - Emitted when the client has requested an outbound (TCP) connection. accept() returns a new Channel instance representing the connection. info contains:

destIP - string - Destination IP address of outgoing connection.

destPort - string - Destination port of outgoing connection.

srcIP - string - Source IP address of outgoing connection.

srcPort - string - Source port of outgoing connection.

Connection methods

end() - (void) - Closes the client connection.

forwardOut(< string >boundAddr, < integer >boundPort, < string >remoteAddr, < integer >remotePort, < function >callback) - (void) - Alert the client of an incoming TCP connection on boundAddr on port boundPort from remoteAddr on port remotePort. callback has 2 parameters: < Error >err, < Channel >stream.

openssh_forwardOutStreamLocal(< string >socketPath, < function >callback) - (void) - Alert the client of an incoming UNIX domain socket connection on socketPath. callback has 2 parameters: < Error >err, < Channel >stream.

rekey([< function >callback]) - (void) - Initiates a rekey with the client. If callback is supplied, it is added as a one-time handler for the rekey event.

x11(< string >originAddr, < integer >originPort, < function >callback) - (void) - Alert the client of an incoming X11 client connection from originAddr on port originPort. callback has 2 parameters: < Error >err, < Channel >stream.

Session events

auth-agent(< mixed >accept, < mixed >reject) - The client has requested incoming ssh-agent requests be forwarded to them. accept and reject are functions if the client requested a response.

close() - The session was closed.

env(< mixed >accept, < mixed >reject, < object >info) - The client requested an environment variable to be set for this session. accept and reject are functions if the client requested a response. info has these properties:

key - string - The environment variable's name.

value - string - The environment variable's value.

exec(< mixed >accept, < mixed >reject, < object >info) - The client has requested execution of a command string. accept and reject are functions if the client requested a response. accept() returns a Channel for the command execution. info has these properties:

  • command - string - The command line to be executed.

pty(< mixed >accept, < mixed >reject, < object >info) - The client requested allocation of a pseudo-TTY for this session. accept and reject are functions if the client requested a response. info has these properties:

cols - integer - The number of columns for the pseudo-TTY.

height - integer - The height of the pseudo-TTY in pixels.

modes - object - Contains the requested terminal modes of the pseudo-TTY keyed on the mode name with the value being the mode argument. (See the table at the end for valid names).

rows - integer - The number of rows for the pseudo-TTY.

width - integer - The width of the pseudo-TTY in pixels.

sftp(< mixed >accept, < mixed >reject) - The client has requested the SFTP subsystem. accept and reject are functions if the client requested a response. accept() returns an SFTP instance in server mode (see the SFTP documentation for details). info has these properties:

shell(< mixed >accept, < mixed >reject) - The client has requested an interactive shell. accept and reject are functions if the client requested a response. accept() returns a Channel for the interactive shell.

signal(< mixed >accept, < mixed >reject, < object >info) - The client has sent a signal. accept and reject are functions if the client requested a response. info has these properties:

  • name - string - The signal name (e.g. SIGUSR1).

subsystem(< mixed >accept, < mixed >reject, < object >info) - The client has requested an arbitrary subsystem. accept and reject are functions if the client requested a response. accept() returns a Channel for the subsystem. info has these properties:

  • name - string - The name of the subsystem.

window-change(< mixed >accept, < mixed >reject, < object >info) - The client reported a change in window dimensions during this session. accept and reject are functions if the client requested a response. info has these properties:

cols - integer - The new number of columns for the client window.

height - integer - The new height of the client window in pixels.

rows - integer - The new number of rows for the client window.

width - integer - The new width of the client window in pixels.

x11(< mixed >accept, < mixed >reject, < object >info) - The client requested X11 forwarding. accept and reject are functions if the client requested a response. info has these properties:

cookie - string - The X11 authentication cookie encoded in hexadecimal.

protocol - string - The name of the X11 authentication method used (e.g. MIT-MAGIC-COOKIE-1).

screen - integer - The screen number to forward X11 connections for.

single - boolean - true if only a single connection should be forwarded.

Channel

This is a normal streams2 Duplex Stream (used both by clients and servers), with the following changes:

A boolean property allowHalfOpen exists and behaves similarly to the property of the same name for net.Socket. When the stream's end() is called, if allowHalfOpen is true, only EOF will be sent (the server can still send data if they have not already sent EOF). The default value for this property is true.

A close event is emitted once the channel is completely closed on both the client and server.

Client-specific:

For exec():

An exit event may (the SSH2 spec says it is optional) be emitted when the process finishes. If the process finished normally, the process's return value is passed to the exit callback. If the process was interrupted by a signal, the following are passed to the exit callback: null, < string >signalName, < boolean >didCoreDump, < string >description.

If there was an exit event, the close event will be passed the same arguments for convenience.

A stderr property contains a Readable stream that represents output from stderr.

For exec() and shell():

The readable side represents stdout and the writable side represents stdin.

setWindow(< integer >rows, < integer >cols, < integer >height, < integer >width) - (void) - Lets the server know that the local terminal window has been resized. The meaning of these arguments are described in the 'Pseudo-TTY settings' section.

signal(< string >signalName) - (void) - Sends a POSIX signal to the current process on the server. Valid signal names are: 'ABRT', 'ALRM', 'FPE', 'HUP', 'ILL', 'INT', 'KILL', 'PIPE', 'QUIT', 'SEGV', 'TERM', 'USR1', and 'USR2'. Some server implementations may ignore this request if they do not support signals. Note: If you are trying to send SIGINT and you find signal() doesn't work, try writing '\x03' to the Channel stream instead.

Server-specific:

For exec-enabled channel instances there is an additional method available that may be called right before you close the channel. It has two different signatures:

exit(< integer >exitCode) - (void) - Sends an exit status code to the client.

exit(< string >signalName[, < boolean >coreDumped[, < string >errorMsg]]) - (void) - Sends an exit status code to the client.

For exec and shell-enabled channel instances, channel.stderr is a writable stream.

Pseudo-TTY settings

cols - < integer > - Number of columns. Default: 80

height - < integer > - Height in pixels. Default: 480

modes - < object > - An object containing Terminal Modes as keys, with each value set to each mode argument. Default: null

rows - < integer > - Number of rows. Default: 24

term - < string > - The value to use for $TERM. Default: 'vt100'

width - < integer > - Width in pixels. Default: 640

rows and cols override width and height when rows and cols are non-zero.

Pixel dimensions refer to the drawable area of the window.

Zero dimension parameters are ignored.

Terminal modes

NameDescription
CS77 bit mode.
CS88 bit mode.
ECHOCTLEcho control characters as ^(Char).
ECHOEnable echoing.
ECHOEVisually erase chars.
ECHOKEVisual erase for line kill.
ECHOKKill character discards current line.
ECHONLEcho NL even if ECHO is off.
ICANONCanonicalize input lines.
ICRNLMap CR to NL on input.
IEXTENEnable extensions.
IGNCRIgnore CR on input.
IGNPARThe ignore parity flag. The parameter SHOULD be 0 if this flag is FALSE, and 1 if it is TRUE.
IMAXBELRing bell on input queue full.
INLCRMap NL into CR on input.
INPCKEnable checking of parity errors.
ISIGEnable signals INTR, QUIT, [D]SUSP.
ISTRIPStrip 8th bit off characters.
IUCLCTranslate uppercase characters to lowercase.
IXANYAny char will restart after stop.
IXOFFEnable input flow control.
IXONEnable output flow control.
NOFLSHDon't flush after interrupt.
OCRNLTranslate carriage return to newline (output).
OLCUCConvert lowercase to uppercase.
ONLCRMap NL to CR-NL.
ONLRETNewline performs a carriage return (output).
ONOCRTranslate newline to carriage return-newline (output).
OPOSTEnable output processing.
PARENBParity enable.
PARMRKMark parity and framing errors.
PARODDOdd parity, else even.
PENDINRetype pending input.
TOSTOPStop background jobs from output.
TTY_OP_ISPEEDSpecifies the input baud rate in bits per second.
TTY_OP_OSPEEDSpecifies the output baud rate in bits per second.
VDISCARDToggles the flushing of terminal output.
VDSUSPAnother suspend character.
VEOFEnd-of-file character (sends EOF from the terminal).
VEOL2Additional end-of-line character.
VEOLEnd-of-line character in addition to carriage return and/or linefeed.
VERASEErase the character to left of the cursor.
VFLUSHCharacter to flush output.
VINTRInterrupt character; 255 if none. Similarly for the other characters. Not all of these characters are supported on all systems.
VKILLKill the current input line.
VLNEXTEnter the next character typed literally, even if it is a special character
VQUITThe quit character (sends SIGQUIT signal on POSIX systems).
VREPRINTReprints the current input line.
VSTARTContinues paused output (normally control-Q).
VSTATUSPrints system status line (load, command, pid, etc).
VSTOPPauses output (normally control-S).
VSUSPSuspends the current program.
VSWTCHSwitch to a different shell layer.
VWERASEErases a word left of cursor.
XCASEEnable input and output of uppercase characters by preceding their lowercase equivalents with "".

HTTPAgent

HTTPAgent methods

  • (constructor)(< object >sshConfig[, < object >agentConfig]) - Creates and returns a new http.Agent instance used to tunnel an HTTP connection over SSH. sshConfig is what is passed to client.connect() and agentOptions is passed to the http.Agent constructor.

HTTPSAgent

HTTPSAgent methods

  • (constructor)(< object >sshConfig[, < object >agentConfig]) - Creates and returns a new https.Agent instance used to tunnel an HTTP connection over SSH. sshConfig is what is passed to client.connect() and agentOptions is passed to the https.Agent constructor.

Utilities

parseKey(< mixed >keyData[, < string >passphrase]) - mixed - Parses a private/public key in OpenSSH, RFC4716, or PPK format. For encrypted private keys, the key will be decrypted with the given passphrase. keyData can be a Buffer or string value containing the key contents. The returned value will be an array of objects (currently in the case of modern OpenSSH keys) or an object with these properties and methods:

comment - string - The comment for the key

equals(< mixed >otherKey) - boolean - This returns true if otherKey (a parsed or parseable key) is the same as this key. This method does not compare the keys' comments

getPrivatePEM() - string - This returns the PEM version of a private key

getPublicPEM() - string - This returns the PEM version of a public key (for either public key or derived from a private key)

getPublicSSH() - string - This returns the SSH version of a public key (for either public key or derived from a private key)

isPrivateKey() - boolean - This returns true if the key is a private key or not

sign(< mixed >data) - mixed - This signs the given data using this key and returns a Buffer containing the signature on success. On failure, an Error will be returned. data can be anything accepted by node's sign.update().

type - string - The full key type (e.g. 'ssh-rsa')

verify(< mixed >data, < Buffer >signature) - mixed - This verifies a signature of the given data using this key and returns true if the signature could be verified. On failure, either false will be returned or an Error will be returned upon a more critical failure. data can be anything accepted by node's verify.update().

sftp.OPEN_MODE - OPEN_MODE

sftp.STATUS_CODE - STATUS_CODE

sftp.flagsToString - flagsToString()

sftp.stringToFlags - stringToFlags()

AgentProtocol

AgentProtocol events

identities(< opaque >request) - (Server mode only) The client has requested a list of public keys stored in the agent. Use failureReply() or getIdentitiesReply() to reply appropriately.

sign(< opaque >request, < mixed >pubKey, < Buffer >data, < object >options) - (Server mode only) The client has requested data to be signed using the key identified by pubKey. Use failureReply() or signReply() to reply appropriately. options may contain any of:

  • hash - string - The explicitly desired hash to use when computing the signature. Currently if set, this may be either 'sha256' or 'sha512' for RSA keys.

AgentProtocol methods

(constructor)(< boolean >isClient) - Creates and returns a new AgentProtocol instance. isClient determines whether the instance operates in client or server mode.

failureReply(< opaque >request) - (void) - (Server mode only) Replies to the given request with a failure response.

getIdentities(< function >callback) - (void) - (Client mode only) Requests a list of public keys from the agent. callback is passed (err, keys) where keys is a possible array of public keys for authentication.

getIdentitiesReply(< opaque >request, < array >keys) - (void) - (Server mode only) Responds to a identities list request with the given array of keys in keys.

sign(< mixed >pubKey, < Buffer >data, < object >options, < function >callback) - (void) - (Client mode only) Requests that the agent sign data using the key identified by pubKey. pubKey can be any parsed (using utils.parseKey()) or parseable key value. callback is passed (err, signature) where signature is a possible Buffer containing the signature for the data. options may contain any of:

  • hash - string - The explicitly desired hash to use when computing the signature. Currently if set, this may be either 'sha256' or 'sha512' for RSA keys.

signReply(< opaque >request, < Buffer >signature) - (void) - (Server mode only) Responds to a sign request with the given signature in signature.

BaseAgent

In order to create a custom agent, your class must:

Extend BaseAgent

Call super() in its constructor

Implement at least the following methods:

getIdentities(< function >callback) - (void) - Passes (err, keys) to callback where keys is a possible array of public keys for authentication.

sign(< mixed >pubKey, < Buffer >data, < object >options, < function >callback) - (void) - Signs data using the key identified by pubKey. pubKey can be any parsed (using utils.parseKey()) or parseable key value. callback should be passed (err, signature) where signature is a possible Buffer containing the signature for the data. options may contain any of:

  • hash - string - The explicitly desired hash to use when computing the signature. Currently if set, this may be either 'sha256' or 'sha512' for RSA keys.

Additionally your class may implement the following method in order to support agent forwarding on the client:

  • getStream(< function >callback) - (void) - Passes (err, stream) to callback where stream is a possible Duplex stream to be used to communicate with your agent. You will probably want to utilize AgentProtocol as agent forwarding is an OpenSSH feature, so the stream needs to be able to transmit/receive OpenSSH agent protocol packets.

createAgent

  • createAgent(< string >agentValue) - (Agent) - Creates and returns a new agent instance using the same logic as the Client's agent configuration option: if the platform is Windows and it's the value "pageant", it creates a PageantAgent, otherwise if it's not a path to a Windows pipe it creates a CygwinAgent. In all other cases, it creates an OpenSSHAgent.

CygwinAgent

CygwinAgent methods

  • (constructor)(< string >socketPath) - Communicates with an agent listening at socketPath in a Cygwin environment.

OpenSSHAgent

OpenSSHAgent methods

  • (constructor)(< string >socketPath) - Communicates with an OpenSSH agent listening on the UNIX socket at socketPath.

PageantAgent

PageantAgent methods

  • (constructor)() - Creates a new agent instance for communicating with a running Pageant agent process.

Author: mscdex
Source Code: https://github.com/mscdex/ssh2 
License: MIT license

#node #nodejs #javascript #ssh 

SSH2 Client & Server Modules Written in Pure JavaScript for Node.js
Waylon  Bruen

Waylon Bruen

1654864800

Manssh: Manage Your Ssh Alias Configs Easily

manssh

manssh is a command line tool for managing your ssh alias config easily, inspired by storm project, powered by Go.

Note:
This project is actually a simple glue project, the most complex and core parsing ssh config file logic implements by ssh_config, I didn't do much.
At first it was just a imitation of storm, now it has become a little different.

Feature

Install

Go

Before 1.17

go get -u github.com/xwjdsh/manssh/cmd/manssh

1.17 or higher

go install github.com/xwjdsh/manssh/cmd/manssh

Homebrew

brew tap xwjdsh/tap
brew install xwjdsh/tap/manssh

Docker

alias manssh='docker run -t --rm -v ~/.ssh/config:/root/.ssh/config wendellsun/manssh'

Manual

Download it from releases, and extract it to your PATH directory.

Usage

% manssh
NAME:
   manssh - Manage your ssh alias configs easily

USAGE:
   manssh [global options] command [command options] [arguments...]

VERSION:
   master

COMMANDS:
     add, a     Add a new SSH alias record
     list, l    List or query SSH alias records
     update, u  Update SSH record by specifying alias name
     delete, d  Delete SSH records by specifying alias names
     backup, b  Backup SSH config files
     help, h    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --file value, -f value  (default: "/Users/wendell/.ssh/config")
   --help, -h              show help
   --version, -v           print the version

Add a new alias

# manssh add test2 2.2.2.2
# manssh add test1 root@1.1.1.1:77 -c IdentityFile=~/.ssh/wendell
% manssh add test1 root@1.1.1.1:77 -i ~/.ssh/wendell
✔ alias[test1] added successfully.

        test1 -> root@1.1.1.1:77
                identityfile = /Users/wendell/.ssh/wendell

Username and port config is optional, the username is current login username and port is 22 by default.
Using -c to set more config options. For convenience, -i xxx can instead of -c identityfile=xxx.

List or query alias

# manssh list
# manssh list "*"
# manssh list Test -ic
% manssh list test1 77
✔ Listing 1 records.

        test1 -> root@1.1.1.1:77
                identityfile = /Users/wendell/.ssh/wendell

It will display all alias records If no params offered, or it will using params as keywords query alias records.
If there is a -it option, it will ignore case when searching.

Update an alias

# manssh update test1 -r test2
# manssh update test1 root@1.1.1.1:22022
% manssh update test1 -i "" -r test3 -c hostname=3.3.3.3 -c port=22022
✔ alias[test3] updated successfully.

        test3 -> root@3.3.3.3:22022

Update an existing alias record, it will replace origin user, hostname, port config's if connected string param offered.
You can use -c to update single and extra config option, -c identityfile= -c proxycommand= will remove identityfile and proxycommand options. 
For convenience, -i xxx can instead of -c identityfile=xxx
Rename the alias specified by -r flag.

Delete one or more alias

# manssh delete test1
% manssh delete test1 test2
✔ alias[test1,test2] deleted successfully.

Backup ssh config

% manssh backup ./config_backup
✔ backup ssh config to [./config_backup] successfully.

For Include directive

If you use the Include directive, there are some extra notes.

Add -p(--path) flag for list,add,update,delete command to show the file path where the alias is located, it can also be set by the MANSSH_SHOW_PATH environment variable.

MANSSH_SHOW_PATH

Set to true to show the file path where the alias is located. Default is false.


 

Add -ap(--addpath) flag for add command to specify the file path to which the alias is added, it can also be set by the MANSSH_ADD_PATH environment variable.

MANSSH_ADD_PATH

This file path indicates to which file to add the alias. Default is the entry config file.


 

For convenience, you can export these environments in your .zshrc or .bashrc, example:

export MANSSH_SHOW_PATH=true
export MANSSH_ADD_PATH=~/.ssh/config.d/temp

Thanks

Author: xwjdsh
Source Code: https://github.com/xwjdsh/manssh 
License: MIT license

#go #golang #ssh 

Manssh: Manage Your Ssh Alias Configs Easily
坂本  篤司

坂本 篤司

1654859640

VSCodeとSSHを使用してリモートでコーディングする

GUIを備えていないRaspberryPiまたはその他のLinuxシステムでコードを作成する必要があったことはありますか?コピーアンドペーストのコマンドを覚えておくのは、vi定期的に使用しない人にとってはほとんど不可能です。また、構文の強調表示、リンティング、さらには2つのファイルを並べて表示するなどの基本的なことも見逃します。

ありがたいことに、リモート/ヘッドレスシステムに接続するVS Codeの拡張機能があり、デスクトップでVS Codeを使用して、リモートファイルシステム上のファイルを編集できます。

Raspberry Piで実行することを目的としたコードを作成している場合は、PCではなくそのPiで開発作業を行うのが理にかなっています。土壇場で発見したくない言語とプラットフォームの依存関係があります。

多くのLinuxシステムにはグラフィカルコンソールがないため、そのリモートシステムで開発作業を行おうとすると、言語固有の拡張機能や素晴らしいグラフィカル統合などに慣れてきたVSCodeの機能が失われてしまいます。 gitとGitHub。

しかし、この難問を解決するVSCode拡張機能があります。

それはどのように見えますか?

SSH経由でリモートのVSCodeは、慣れているVS Codeであるため、慣れているVSCodeと同じように見えます。下のスクリーンショットでは、左側にあるおなじみのファイルツリーに注目してください。これらはリモートシステム上のファイルです!これらのファイルは、使い慣れたVS Codeコントロールを使用して、リモートシステムで開いたり、編集したり、保存したり、削除したりできます。

SSH拡張機能を備えたVSコード—作成者によるスクリーンショット

また、このスクリーンショットで開いているターミナルセッションがあることに注意してください。これは、リモートシステム上のターミナルセッションです。他のSSHウィンドウと同じように、このターミナルからコードをコンパイルして実行できます。

何が違うの?

SSH拡張機能をVSCodeにインストールすると、VSCodeウィンドウの左下隅に緑色のバーが表示されます。これをクリックすると、リモートホストに接続またはリモートホストから切断するためのメニューが表示されます。VS Codeは、必要に応じてお気に入りを追跡します。このスクリーンショットは、でLinuxホストに接続されているVSCodeウィンドウを示しています192.168.9.86

リモートホストに接続します—作成者によるスクリーンショット

リモートシステムに接続したら、[フォルダを開く]をクリックしてリモートシステム上の任意のディレクトリを開くことができます。また、最近の接続とリモートディレクトリのリストを提供する新しいアイコンがサイドバーにあることに注意してください。

リモートディレクトリを開く—作成者によるスクリーンショット

インストールして開始する

この拡張機能をインストールして開始するのは簡単です。VS Codeの「Extensions」に移動し、「SSH」を検索して、という名前のMicrosoft拡張機能で「Install」をクリックするだけRemote-SSHです。それでおしまい!VSCodeを再起動する必要はありません。

拡張機能のインストール—作成者によるスクリーンショット

拡張機能がインストールされたら、VSCodeウィンドウの左下隅にある緑色のバーをクリックして接続を開始します。

接続するには緑色のバーをクリックします—作成者によるスクリーンショット

次に、下のスクリーンショットに示すように、手動で入力するuser@hostか、[新しいSSHホストの追加...]をクリックして、頻繁にアクセスするホストへのブックマークを作成できます。

ユーザー名とホスト名を指定します—作成者によるスクリーンショット

結論

私は学校で毎週RaspberryPiで小さなCプロジェクトに取り組んでいますが、このVS Code拡張機能をインストールしてから、使用したことはなく、一度もvi使用していません。nano

私は言語拡張機能へのアクセス、gitとGitHubへの統合、そしてマウスを使用する贅沢さえも本当に大切にしています!

VS CodeのRemote-SSH拡張機能は私にとって価値のあるツールであり、同様に価値があると感じていただければ幸いです。

 このストーリーは、もともとhttps://betterprogramming.pub/learn-to-code-remotely-with-vs-code-and-ssh-68c630759279で公開されました

#vscode #ssh 

VSCodeとSSHを使用してリモートでコーディングする

Codifique De Forma Remota Con VS Code Y SSH

¿Alguna vez ha tenido que escribir código en una Raspberry Pi u otro sistema Linux que no tenía una GUI? Tratar de recordar los comandos para copiar y pegar vies casi imposible para aquellos que no lo usan regularmente. También echas de menos cosas como el resaltado de sintaxis, la pelusa e incluso lo básico como mirar dos archivos uno al lado del otro.

Afortunadamente, ahora hay una extensión para VS Code que se conecta a sistemas remotos/sin periféricos, lo que le permite usar VS Code en su escritorio para editar archivos en el sistema de archivos remoto.

Si estoy escribiendo un código destinado a ejecutarse en una Raspberry Pi, entonces tiene sentido hacer el trabajo de desarrollo en esa Pi y no en mi PC. Hay dependencias de idioma y plataforma que no quiero descubrir en el último minuto.

Muchos sistemas Linux no tienen una consola gráfica, por lo que si trato de hacer ese trabajo de desarrollo en ese sistema remoto, termino perdiendo funciones en VS Code a las que me he acostumbrado, como extensiones específicas del idioma y una excelente integración gráfica con git y github.

Pero hay una extensión de VS Code que resuelve este enigma.

¿Cómo se ve?

El control remoto de VS Code a través de SSH se parece al VS Code al que está acostumbrado porque es el VS Code al que está acostumbrado. En la captura de pantalla a continuación, observe el árbol de archivos familiar a la izquierda. ¡Estos son los archivos en el sistema remoto! Puede abrir, editar, guardar o eliminar estos archivos en el sistema remoto con los mismos controles de VS Code con los que está familiarizado.

Código VS con extensión SSH: captura de pantalla del autor

Observe también que hay una sesión de terminal abierta en esta captura de pantalla. Esta es una sesión de terminal en el sistema remoto. ¡Puede compilar y ejecutar código desde este terminal como lo haría desde cualquier ventana SSH!

¿Que es diferente?

Después de instalar la extensión SSH en VS Code, verá una barra verde en la esquina inferior izquierda de la ventana de VS Code. Al hacer clic aquí, aparecerá un menú para conectarse o desconectarse de un host remoto. VS Code incluso hará un seguimiento de sus favoritos si lo desea. Esta captura de pantalla muestra mi ventana de VS Code conectada a un host Linux en 192.168.9.86.

Conectarse al host remoto: captura de pantalla del autor

Una vez que se haya conectado a un sistema remoto, tendrá la oportunidad de hacer clic en "Abrir carpeta" para abrir cualquier directorio en el sistema remoto. Además, observe que hay un nuevo icono en la barra lateral que proporciona una lista de conexiones recientes y directorios remotos.

Abrir directorios remotos: captura de pantalla del autor

Instalar y comenzar

Es simple instalar esta extensión y comenzar. Simplemente vaya a "Extensiones" en VS Code, busque "SSH" y haga clic en "Instalar" en la extensión de Microsoft llamada Remote-SSH. ¡Eso es todo! Ni siquiera tiene que reiniciar VS Code.

Instalación de la extensión: captura de pantalla del autor

Una vez que la extensión esté instalada, simplemente haga clic en la barra verde en la esquina inferior izquierda de su ventana de VS Code para iniciar una conexión.

Haga clic en la barra verde para conectarse: captura de pantalla del autor

Luego, puede ingresar manualmente user@hosto hacer clic en "Agregar nuevo host SSH ..." para crear un marcador para un host visitado con frecuencia como se muestra en la captura de pantalla a continuación.

Especifique el nombre de usuario y el nombre de host: captura de pantalla del autor

Conclusión

He estado trabajando en pequeños proyectos C en una Raspberry Pi todas las semanas para la escuela, pero no he usado vini nanouna sola vez desde que instalé esta extensión de VS Code.

Realmente valoro el acceso a las extensiones de idioma, la integración con git y GitHub, ¡e incluso el lujo de usar un mouse!

La Remote-SSHextensión para VS Code es una herramienta valiosa para mí y espero que la encuentre igualmente valiosa.

 Esta historia se publicó originalmente en https://betterprogramming.pub/learn-to-code-remotely-with-vs-code-and-ssh-68c630759279

#vscode #ssh 

Codifique De Forma Remota Con VS Code Y SSH