¿Cómo ejecutar comandos de forma remota a través de SSH en Android?

El protocolo SSH usa encriptación para asegurar la conexión entre un cliente y un servidor. Toda la autenticación de usuario, los comandos, la salida y las transferencias de archivos están encriptados para proteger contra ataques en la red. La mayoría de las veces, necesitará SSH en sus máquinas virtuales en la nube o en un shell remoto. Por lo general, necesitamos un cliente SSH para establecer una conexión SSH. Para Windows, el cliente GUI gratuito (libre) PuTTY se utiliza para este propósito. Así es como parece acceder a un shell remoto de Linux en PuTTY:

El siguiente tutorial ilustra cómo se puede lograr lo mismo en Android. Biblioteca: Apache MINA SSHD

Implementación paso a paso

Paso 1: crear un nuevo proyecto

Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Tenga en cuenta que seleccione Java como lenguaje de programación.

Paso 2: Agregar dependencias

Ahora necesitamos agregar las dependencias requeridas para usar la biblioteca apache mina sshd. Abra el archivo app/src/build.gradle en el directorio de su proyecto y agregue lo siguiente en dependencias:

// Agregando implementaciones requeridas para la biblioteca de Apache Mina

implementación ‘org.apache.mina:mina-core:3.0.0-M2’

implementación ‘org.apache.sshd:sshd-core:2.1.0’

implementación ‘org.apache.sshd:sshd-putty:2.1.0’

implementación ‘org.apache.sshd:sshd-common:2.1.0’

implementación ‘org.slf4j:slf4j-api:1.7.5’

implementación ‘org.slf4j:slf4j-simple:1.6.4’

Paso 3: agregue permiso a Internet en su archivo AndroidManifest.xml

Agregue debajo de dos líneas dentro de su archivo src/res/AndroidManifest.xml dentro de las etiquetas <manifest></manifest>.

<usos-permiso android:name=”android.permission.INTERNET” />

Paso 4: Modifique el archivo strings.xml

Abra aplicación > src > principal > res > valores > strings.xml y agregue el siguiente código:

XML

<resources>
    <string name="app_name">gfg_ssh</string>
    <string name="host">Host</string>
    <string name="port">Port</string>
    <string name="defaultPort">22</string>
    <string name="username">Username</string>
    <string name="password">Password</string>
    <string name="button_send">SEND</string>
</resources>

Paso 5: Creación de la interfaz de usuario

Vamos a tener dos actividades en nuestra aplicación.

  • MainActivity : aquí, ingresaremos los detalles de inicio de sesión
  • sshActivity : Aquí, veremos la salida del shell.

Trabajando con el archivo activity_main.xml:

Ahora, navegue a la aplicación> src> principal> res> diseño> actividad_principal.xml y agregue el siguiente código al archivo.

XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    tools:context=".MainActivity">
  
    <LinearLayout
        android:id="@+id/linear"
        android:layout_width="270dp"
        android:layout_height="413dp"
        android:layout_margin="50dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent=".8">
  
        <EditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:autofillHints="host"
            android:background="@color/white"
            android:ems="10"
            android:hint="@string/host"
            android:inputType="textPersonName"
            android:padding="10dp"
            android:textColor="@color/black"
            android:textColorHint="@color/black"
            app:layout_constraintWidth_percent=".8" />
  
        <EditText
            android:id="@+id/portField"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="22dp"
            android:autofillHints="port"
            android:background="@color/white"
            android:ems="10"
            android:hint="@string/port"
            android:inputType="textPersonName"
            android:padding="10dp"
            android:textColor="@color/black"
            android:textColorHint="@color/black"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintWidth_percent=".8"
            tools:text="@string/defaultPort" />
  
        <EditText
            android:id="@+id/usernameField"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="22dp"
            android:autofillHints="username"
            android:background="@color/white"
            android:ems="10"
            android:hint="@string/username"
            android:inputType="textPersonName"
            android:padding="10dp"
            android:textColor="@color/black"
            android:textColorHint="@color/black"
            app:layout_constraintBottom_toTopOf="@+id/passwordField"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/portField"
            app:layout_constraintWidth_percent=".8" />
  
        <EditText
            android:id="@+id/passwordField"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="22dp"
            android:autofillHints="password"
            android:background="@color/white"
            android:ems="10"
            android:hint="@string/password"
            android:inputType="textPassword"
            android:padding="10dp"
            android:textColor="@color/black"
            android:textColorHint="@color/black"
            app:layout_constraintWidth_percent=".8" />
  
        <Button
            android:id="@+id/button"
            android:layout_width="194dp"
            android:layout_height="61dp"
            android:layout_gravity="center"
            android:layout_marginTop="69dp"
            android:layout_marginBottom="373dp"
            android:background="#594FAA"
            android:onClick="authenticate"
            android:text="@string/button_send"
            android:textColor="@android:color/background_light"
            tools:text="@string/button_send" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Primero, cree una nueva actividad sshActivity haciendo clic con el botón derecho en la carpeta de actividades (com.example.gfg_ssh) y luego seleccione New > Activity > Empty Activity y ahora agregue el siguiente código al archivo activity_ssh.xml para la interfaz de usuario de esta actividad.

XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".sshActivity">
  
    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="688dp"
        android:background="@android:color/black"
        android:textColor="@color/white"
        android:textSize="18sp" />
  
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Paso 6: trabajar con el archivo MainActivity.java

Vaya al archivo MainActivity.java y consulte el siguiente código. A continuación se muestra el código del archivo MainActivity.java . Se agregan comentarios dentro del código para comprender el código con más detalle.

Java

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
  
import androidx.appcompat.app.AppCompatActivity;
  
public class MainActivity extends AppCompatActivity {
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
  
    public void authenticate(View view) {
        
        // Create an intent for sshActivity
        Intent intent = new Intent(this, sshActivity.class);
  
        // Declare fields
        EditText editText = (EditText) findViewById(R.id.editText);
        EditText portField = (EditText) findViewById(R.id.portField);
        EditText usernameField = (EditText) findViewById(R.id.usernameField);
        EditText passwordField = (EditText) findViewById(R.id.passwordField);
          
        // Get input data from fields
        String host = editText.getText().toString();
        String port = portField.getText().toString();
        String username = usernameField.getText().toString();
        String password = passwordField.getText().toString();
  
        // Pass on data to sshActivity via intent
        intent.putExtra("host", host);
        intent.putExtra("port", port);
        intent.putExtra("username", username);
        intent.putExtra("password", password);
        startActivity(intent);
        finish();
    }
}

Paso 7: Trabajar con el archivo sshActivity.java

Esta es la actividad en la que importamos la biblioteca Apache MINA SSHD y nos conectamos a nuestra máquina remota a través de SSH. Obtenemos los datos de inicio de sesión de la intención. sshActivity.java

Java

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
  
import androidx.appcompat.app.AppCompatActivity;
  
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.channel.Channel;
import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
  
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;
  
public class sshActivity extends AppCompatActivity {
  
    ClientChannel channel;
    TextView shellOutput;
    String host, username, password;
    Integer port;
    String command;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ssh);
  
        // set output field
        shellOutput = findViewById(R.id.textView);
  
        // Get user credentials from indent
        Intent intent = getIntent();
        host = intent.getStringExtra("host");
        port = Integer.parseInt(intent.getStringExtra("port"));
        username = intent.getStringExtra("username");
        password = intent.getStringExtra("password");
  
        // Command which will be executed
        command = "pwd\n";
          
        // Setting user.com property manually 
        // since isn't set by default in android
        String key = "user.home";
        Context Syscontext;
        Syscontext = getApplicationContext();
        String val = Syscontext.getApplicationInfo().dataDir;
        System.setProperty(key, val);
  
        // Creating a client instance
        SshClient client = SshClient.setUpDefaultClient();
        client.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE);
        client.start();
  
        // Starting new thread because network processes 
        // can interfere with UI if started in main thread
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // Connection establishment and authentication
                    try (ClientSession session = client.connect(username, host, port).verify(10000).getSession()) {
                        session.addPasswordIdentity(password);
                        session.auth().verify(50000);
                        System.out.println("Connection establihed");
  
                        // Create a channel to communicate
                        channel = session.createChannel(Channel.CHANNEL_SHELL);
                        System.out.println("Starting shell");
  
                        ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
                        channel.setOut(responseStream);
  
                        // Open channel
                        channel.open().verify(5, TimeUnit.SECONDS);
                        try (OutputStream pipedIn = channel.getInvertedIn()) {
                            pipedIn.write(command.getBytes());
                            pipedIn.flush();
                        }
  
                        // Close channel
                        channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED),
                                TimeUnit.SECONDS.toMillis(5));
  
                        // Output after converting to string type
                        String responseString = new String(responseStream.toByteArray());
                        System.out.println(responseString);
                        shellOutput.setText(responseString);
                          
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        client.stop();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }
}

Producción:

Iniciando sesión:

Ejecución del comando SSH:

Publicación traducida automáticamente

Artículo escrito por abhijeetcatches33 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *