Giter Club home page Giter Club logo

ssh's Introduction

A lightweight package to execute commands over an SSH connection

Latest Version on Packagist GitHub Tests Action Status Total Downloads

You can execute an SSH command like this:

Ssh::create('user', 'host')->execute('your favorite command');

It will return an instance of Symfony's Process.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Installation

You can install the package via composer:

composer require spatie/ssh

Usage

You can execute an SSH command like this:

$process = Ssh::create('user', 'example.com')->execute('your favorite command');

It will return an instance of Symfony's Process.

If you don't want to wait until the execute commands complete, you can call executeAsync

$process = Ssh::create('user', 'example.com')->executeAsync('your favorite command');

Getting the result of a command

To check if your command ran ok

$process->isSuccessful();

This is how you can get the output

$process->getOutput();

Running multiple commands

To run multiple commands pass an array to the execute method.

$process = Ssh::create('user', 'example.com')->execute([
   'first command',
   'second command',
]);

Choosing a port

You can choose a port by passing it to the constructor.

$port = 123;

Ssh::create('user', 'host', $port);

Alternatively you can use the usePort function:

Ssh::create('user', 'host')->usePort($port);

Setting a timeout

You can set a timeout for the command.

Ssh::create('user', 'host')->setTimeout(100);

Specifying a jump host

If using a jump/proxy/bastion host, the useJumpHost function allows you to set the jump hosts details:

Ssh::create('user', 'host')->useJumpHost("$jumpuser@$jumphost:$jumpport");

Using SSH multiplexing

If making many connections to the same host, SSH multiplexing enables re-using one TCP connection. Call useMultiplexing function to set control master options:

Ssh::create('user', 'host')->useMultiplexing($controlPath, $controlPersist);

// Ssh::create('user', 'host')->useMultiplexing('/home/.ssh/control_masters/%C', '15m');

Specifying the private key to use

You can use usePrivateKey to specify a path to a private SSH key to use.

Ssh::create('user', 'host')->usePrivateKey('/home/user/.ssh/id_rsa');

Disable Strict host key checking

By default, strict host key checking is enabled. You can disable strict host key checking using disableStrictHostKeyChecking.

Ssh::create('user', 'host')->disableStrictHostKeyChecking();

Enable quiet mode

By default, the quiet mode is disabled. You can enable quiet mode using enableQuietMode.

Ssh::create('user', 'host')->enableQuietMode();

Disable Password Authentication

By default, the password authentication is enabled. You can disable password authentication using disablePasswordAuthentication.

Ssh::create('user', 'host')->disablePasswordAuthentication();

Uploading & downloading files and directories

You can upload files & directories to a host using:

Ssh::create('user', 'host')->upload('path/to/local/file', 'path/to/host/file');

Or download them:

Ssh::create('user', 'host')->download('path/to/host/file', 'path/to/local/file');

Under the hood the process will use scp.

Modifying the Symfony process

Behind the scenes all commands will be performed using Symfonys Process.

You can configure to the Process by using the configureProcess method. Here's an example where we disable the timeout.

Ssh::create('user', 'host')->configureProcess(fn (Process $process) => $process->setTimeout(null));

Immediately responding to output

You can get notified whenever your command produces output by passing a closure to onOutput.

Ssh::create('user', 'host')->onOutput(function($type, $line) {echo $line;})->execute('whoami');

Whenever there is output that closure will get called with two parameters:

  • type: this can be Symfony\Component\Process\Process::OUT for regular output and Symfony\Component\Process\Process::ERR for error output
  • line: the output itself

Windows Target

If your target is a Windows machine, you can use the removeBash method to remove the bash command from the command line.

Ssh::create('user', 'host')->removeBash();

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Alternatives

If you need some more features, take a look at DivineOmega/php-ssh-connection.

Credits

The Ssh class contains code taken from laravel/envoy

License

The MIT License (MIT). Please see License File for more information.

ssh's People

Contributors

adrianmrn avatar alexmanase avatar angeljqv avatar arnedesmedt avatar bambamboole avatar bomas13 avatar chapeupreto avatar dbakan avatar ebulku avatar freekmurze avatar imliam avatar ipwnpancakes avatar localheinz avatar m1guelpf avatar mallardduck avatar matusboa avatar mazedlx avatar michaelaguiar avatar mohammedalkutrani avatar nielsvanpach avatar patinthehat avatar pkboom avatar pyrech avatar rubenvanassche avatar samuelnitsche avatar sebastiandedeyne avatar tal7aouy avatar timrspratt avatar yob-yob avatar zaherg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ssh's Issues

TTY support

Is there any way to connect the TTY terminal to the ssh session?

Like executing vim editor over the ssh.

Missing environment variables

Hi,

I'm using this library (among others) to create a CLI application wrapping a local Laravel Homestead environment, so that developers can interact with artisan and other build tools without having to SSH into the machine themselves. Unfortunately, I've noticed that if I issue an export command with this library, none of the needed environment variables are not there.

If I on the other hand just issue ssh vagrant@localhost -p 2222 on my local system – it all works as expected.

Why could this be, and how can I get around it?

The setup is running two sites and the database environment is specified through Homestead.yaml but it's all there if I do a regular SSH. Only through this library are the variables missing.'

Thanks,
Jonathan

avoid confirmation on first time remote

Thanks for making this project,

I have some problem with confirmation on first time remote the server

How to avoid this ?

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'ip_address' (ED25519) to the list of known hosts

SSH Connection always ask for ssh key passphrase

Good night,
I'm giving this package a try, and here is how i am connecting to my ssh host:

\Spatie\Ssh\Ssh::create('MY USER', 'MY HOST')
            ->usePort(2222)
            ->usePrivateKey('path to my key file')
            ->execute('ls -la')
            ->getOutput()

Then, i run php artisan serve, and, in my linux terminal, this is the output:

started
[Fri Feb 14 00:08:36 2020] 127.0.0.1:44010 Accepted
[Fri Feb 14 00:08:36 2020] 127.0.0.1:44012 Accepted
Enter passphrase for key 'path_to_my_key_file': 

What i am doing wrong? Can't figure out what am i missing.

Thanks!

Is it possible to authenticate with a password?

We have a use case where some users authenticate with a password, instead of using an SSH key.

Does this package support using a password instead? And if not, is it something you'd accept a PR for?

Access to remote server

Hi @freekmurze

Thank you for your great package.
Can I ask one thing?
This package provides for only hosted project?

Ssh::create('user', 'host')->usePrivateKey('/home/user/.ssh/id_rsa');

It seems I need to use this command to access to remote server, right?

Then if someone knows my user and privateKey path then can anyone access to server?
I was a bit confused.

Is there any way to access SSH using username & password or something like that?

Thank you!

Requirements could not be resolved

I get this error when trying to install via composer:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for spatie/ssh ^0.0.1 -> satisfiable by spatie/ssh[0.0.1].
    - Conclusion: remove symfony/process v4.4.4
    - Conclusion: don't install symfony/process v4.4.4
    - spatie/ssh 0.0.1 requires symfony/process ^5.0 -> satisfiable by symfony/process[5.0.x-dev, 5.1.x-dev, v5.0.0, v5.0.0-BETA1, v5.0.0-BETA2, v5.0.0-RC1, v5.0.1, v5.0.2, v5.0.3, v5.0.4].
    - Can only install one of: symfony/process[5.0.x-dev, v4.4.4].
    - Can only install one of: symfony/process[5.1.x-dev, v4.4.4].
    - Can only install one of: symfony/process[v5.0.0, v4.4.4].
    - Can only install one of: symfony/process[v5.0.0-BETA1, v4.4.4].
    - Can only install one of: symfony/process[v5.0.0-BETA2, v4.4.4].
    - Can only install one of: symfony/process[v5.0.0-RC1, v4.4.4].
    - Can only install one of: symfony/process[v5.0.1, v4.4.4].
    - Can only install one of: symfony/process[v5.0.2, v4.4.4].
    - Can only install one of: symfony/process[v5.0.3, v4.4.4].
    - Can only install one of: symfony/process[v5.0.4, v4.4.4].
    - Installation request for symfony/process (locked at v4.4.4) -> satisfiable by symfony/process[v4.4.4].

ssh to remote server from another remote server

First of all, I want to thanks the people behind this nice project.

Now I'm working on project and I need to ssh to remote server 1 and then from the remote server 1 I want to ssh to the remote server 2, as being said I would like to know if this package manage this edge case?

Thanks

Bug: Using timeout causes "scp" related commands to fail

Hello again! πŸ˜…

So I noticed that while #86 fixed the issue for regular SSH commands, it did not fix the issues within the other commands. While contemplating on a fix, I came across a decision that I would like to get approval on:

$extraOptions seems to be meant to eventually be transformed into a command's flags/options. But since we're leveraging Symfony/Process' timeout, couldn't we just make a private $timeout property, rather than holding the timeout value in $extraOptions?

My rationale is that while I could just duplicate the filtering logic in:

ssh/src/Ssh.php

Lines 242 to 248 in 169a920

protected function getExtraOptions(): array
{
// Removed timeout from extra options; it's only used as a value for Symfony\Process, not as an SSH option
$extraOptions = array_filter($this->extraOptions, fn ($key) => $key !== 'timeout', ARRAY_FILTER_USE_KEY);
return array_values($extraOptions);
}

to:

ssh/src/Ssh.php

Lines 229 to 240 in 169a920

protected function getExtraScpOptions(): string
{
$extraOptions = $this->extraOptions;
if (isset($extraOptions['port'])) {
$extraOptions['port'] = str_replace('-p', '-P', $extraOptions['port']);
}
$extraOptions[] = '-r';
return implode(' ', array_values($extraOptions));
}

I think the better long term solution would be to just hold the value for the timeout in a different place than $extraOptions

General error - windows

Hi, is this package compatible with Windows ?

Every time I want to execute any kind of command, I get General Error in error text output and theres no real output, like should be.

$ssh = \Spatie\Ssh\Ssh::create($user, $host, $port);
echo $ssh->execute('ls -l')->getExitCodeText(); // result is "General error"

Maybe it does not like the command syntax ?

ssh -p 12345 [email protected] 'bash -se' << \EOF-SPATIE-SSH
ls -l
EOF-SPATIE-SSH

Question - Possibility to track the download time/speed

First and foremost, thanks to all the spatie team and contributors which make our work on products much easier.

What I would like to know is if it's possible to expose the donwload speed, ellapsed time, remaining time, size of download file of the download function ?

Maybe something like this to better illustrate my question.
Capture d’écran 2021-03-19 aΜ€ 11 24 25

usePort signature should be changed

Currently usePort method requires an int ?

public function usePort(int $port): self

What if I create a Ssh object with a specific port and I want to remove that port ? Currently this is not possible you should change the signature to usePort(?int $port): self IMHO.

Connection refused

Hey guys im facing an odd issue and unsure if its related to this pack im using

Currently i have two symfony commands setup, the first command SSH' onto a server and runs some commands (that works fine)
My second command do basically the same but just confirming the first one worked correctly, this also works

the issue im having is that from the point of the first command finishing and the second starting sometimes im getting a (ssh: connect to host xxx.xxx.xxx.xxx port 22: Connection refused) if i sleep the code 45 seconds to a minute the connection goes across fine, is this due to the connection not being terminated ?

any ideas greatly appreciated
Thanks!

Trying to SSH to a Windows Machine

I know it is not common to SSH to another Windows Machine, but it is not working.
I have tracked it and the reason is the part of hardcoding 'bash -se' in the command, and it is not recognized by Windows.
To fix it just remove 'bash -se' from getExecuteCommand() function:

from:

return "ssh {$extraOptions} {$target} 'bash -se' << \\$delimiter".PHP_EOL
                    .$commandString.PHP_EOL
                    .$delimiter;

to:

return "ssh {$extraOptions} {$target} << \\$delimiter".PHP_EOL
                    .$commandString.PHP_EOL
                    .$delimiter;

Can you log in with a password?

Can you log in with a password?
I am using machine A to log in to B... N through the intranet, and I hope to log in through the password. At present, it is not supported. Is there a plan to support it?

Make method getExtraOptions() protected

The getter method getExtraOptions() is private but the property retrieved by it ($extraOptions) is protected.

Also, all the other getter methods are protected, making this one the only exception.

SSH From Windows Not Working

Hey Guys,

I am trying to SSH to a linux box from my windows pc.
Using the pvt key works in a ssh terminal, but through the below example, I am getting a general error...

How can I get it to work from a windows pc for development?

$process = Ssh::create('root', 'xx.xx.xx.xx', 22)
->usePrivateKey(storage_path('id_rsa'))
->execute([
'mkdir hello',
'ls -alh',
]);

Package and host requirements?

Could you share host or server requirements for using this library? Is a php ssh extension required?

On our host env we have ssh:

$ whereis ssh
ssh: /usr/bin/ssh /etc/ssh /usr/share/man/man1/ssh.1.gz

But on a web page on the host we do not. For example:

<?php 
/***
 * https://..../test.php
 */
echo exec("which ssh");
// No output.

Similar results after installing the library. The Process result is statuscode 127, command not found:

<?php

namespace Drupal\my_test\Controller;

use GuzzleHttp\ClientInterface;
use Symfony\Component\Process\Process;
use Spatie\Ssh\Ssh;

/**
 * Fetch a token.
 */
class GetSSHToken {

  /**
   * Fetch the SSH result.
   */
  public static function test() {

    dump([
      exec("ssh"),
      exec("which ssh"),
    ]);

    $process = Ssh::create($sshUser, $sshHost)
      ->usePort($sshPort)
      ->usePrivateKey($sshKeyPath)
      ->disableStrictHostKeyChecking()
      ->execute('token');

    dump([
      $process,
      $process->isSuccessful(),
      $process->getOutput(),
    ]);
    $process = Ssh::create($sshUser, $sshHost)
      ->usePort($sshPort)
      ->usePrivateKey($sshKeyPath)
      ->disableStrictHostKeyChecking()
      ->execute('token');

    dump([
      $process,
      $process->isSuccessful(),
      $process->getOutput(),
    ]);

  }
}

Bug: Using public setTimeout creates invalid SSH commands

Hello!

I noticed when using this package in production that using the setTimeout function actually causes the resulting SSH command to be invalid. If you add this test:

it('setting timeout does not alter ssh command', function () {
    $command = $this->ssh->setTimeout(10)->getExecuteCommand('whoami');

    assertMatchesSnapshot($command);
});

You will see this result:

ssh 10 [email protected] 'bash -se' << \EOF-SPATIE-SSH
whoami
EOF-SPATIE-SSH

When checking the ssh man page, it seems that the correct usage is to pass it in as an option as -o ConnectTimeout=10. But instead it is serialized as an integer due to the way getExecuteCommand turns everything in the $this->extraOptions array to a string.

Though I do see that this option is intended to merely pass the integer to Symfony's Process class.

Call to undefined method Symfony\Component\Process\Process::usePrivateKey()

When I do:

$process = Ssh::create('root', 'host_ip_here')->execute('whoami')
    ->usePrivateKey('/home/user/.ssh/id_rsa');

$result = [
    'isSuccessful' => $process->isSuccessful(),
    'output' => $process->getOutput(),
];

dd($result);

I get the error:

Call to undefined method Symfony\Component\Process\Process::usePrivateKey()

usePrivateKey is in the Ssh class, so I'm unsure what I'm doing wrong...

Thank you

script is not throwing any error or executing

I am trying to run SSH command on ec2 linux instance, but it is not running or not even throwing any error
I wrote this command in laravel command and running script through terminal.
Please help

$process = Ssh::create('ec2-user', $publicIP)->usePrivateKey(public_path('Web-SDP.pem'))->execute(
                'streamlink twitch.tv/nickmercs best,1080p60,1080,720,480,worst --output ~/test.mp4 --retry-streams 10 --force --retry-max 360 --retry-open 20 --twitch-disable-hosting --twitch-disable-ads'
            );

            echo $process->isSuccessful();
            echo $process->getOutput();

Uncaught Error: Class "Ssh" not found

I trying use but every time get "class not found" but, why?

<?php
use Spatie\Ssh;
require "vendor/autoload.php";
$process = Ssh::create('user', 'my.server.net');
?>

Ubuntu 22
Nginx
PHP 8.1

syntax error, unexpected 'string' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST)

Hello,

I use this code in my controller:

            \Spatie\Ssh\Ssh::create("myname", "myip")
            ->usePort(22)
            ->usePrivateKey('/my/key/path')
            ->execute('whoami')
            ->getOutput();

But when i execute this, I get the following error:

syntax error, unexpected 'string' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST)

This refers to line 12 of the SSH controller.
protected string $user;

Is there a way to solve this?

0 is a valid port number

ssh/src/Ssh.php

Line 114 in daace80

if ($this->port) {

The following code will fail if I choose 0 as a port number because 0 is a valid port number You should improve port validation in this case and enable any positive number and 0 and update the check to be if (null !== $this->port) instead.

Uncaught Error: Class "Ssh" not found

Hi!

I just installed this package on the latest version 1.6.
When running the php file like this:

require 'vendor/autoload.php'; $process = Ssh::create('user', 'host')->execute('ls'); echo $process;

I do get the error: Uncaught Error: Class "Ssh" not found.
Any idea what this is? im using this in a plain PHP file/setup.

Thanks

secure copy file from one remote server to another using scp ubuntu command

I have two ubuntu server and want to write php artisan command to securely copy the file from one remote ubuntu server "A" to another "B". I configured the ssh keys in both server when I am manually ssh ing to server A from my terminal and running this command scp path/to/file/in-server-A user@IP:~/data/ it's working perfectly, but running the same command from php artisan copy:file it give me this error Error Output: ================ user@IP: Permission denied (publickey). lost connection didn't figure out what is the problem and how to solve it.

Ssh::create('user', 'host')->execute('scp path/to/file/in-server-A user@IP:~/data/');

Question - Using multiple commands

Does spatie/ssh wait for one command to complete before advancing to the next when using multiple commands?

I understand this might be a bad question - I could be doing something wrong in my commands. I'm currently using the Laravel Collective package, and one of the main issues I have is that stacking commands doesn't wait for one to complete before moving to the next.

SSH connection without specifying a user

We often define the SSH access configuration in the SSH config file (f.e. in ~/.ssh/config):

Host my-prod
    Hostname x.x.x.x
    User debian

In such cases, we can connect to the server with only ssh my-prod. But unless I'm wrong, this is not possible at the moment as the user argument is always mandatory in spatie/ssh.

Would it be possible to make it optional? I could give it a try if you would accept such a PR πŸ™‚

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.