Como usar tuneles SSH en Python

Hoy venimos con una entrada sobre como usar tuneles SSH en Python. Ademas venimos con novedad, porque es una entrada del blog con video, la primera que hacemos con ambos contenidos.

¡Empezamos!

Lo primero, ¿Qué es un tunel SSH? Un tunel SSH es una redirección de un puerto mediante SSH, esta redirección permite hacer conexión desde y hasta el servidor mediante SSH .

Todo lo que explicamos a mas adelante, está detallado en el video:

Para instalar sshtunel

pip install sshtunel

Hemos montado un docker con un servicio SSH corriendo:

[ger-pc ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                        PORTS               NAMES
d95b81fa73e3        centos:7            "bash"              2 hours ago         UP 40 minutes ago                       servertest

Como se puede ver tiene a la escucha el puerto 22 por todas las interfaces pero el proceso httpd solamente escucha el puerto 80 en 127.0.0.1. Esto lo hemos configurado nosotros en la configuración de Apache:

[ger-pc ~]# docker exec -it servertest su -
Last login: Tue Feb 18 23:26:51 UTC 2020 on pts/1
[root@servertest ~]# ss -putan
Netid State      Recv-Q Send-Q                                              Local Address:Port                                                             Peer Address:Port              
tcp   LISTEN     0      128                                                     127.0.0.1:80                                                                          *:*                   users:(("httpd",pid=57,fd=3))
tcp   LISTEN     0      128                                                             *:22                                                                          *:*                   users:(("sshd",pid=34,fd=3))
tcp   LISTEN     0      128                                                          [::]:22                                                                       [::]:*                   users:(("sshd",pid=34,fd=4))
[root@servertest ~]# 

Si hacemos conexión contra el puerto que nos facilitará el codigo python de mas adelante al ejecutarlo nos devolverá el resultadode de Apache del docker CentOS como los que se obtienen ejecutando curl desde dentro del docker:

[ger-pc ~]# docker exec -it servertest su -
Last login: Tue Feb 18 22:20:38 UTC 2020 on pts/1
[root@servertest ~]# curl localhost

.....
e is used to test the proper operation of the Apache HTTP server after it has been installed. If you can read this page it means that this site is working properly. This server is powered by CentOS.

 

Para ejecutar el script, tenemos que instalar primero primero la dependencia SSHTUNNEL:

[ger-pc ~]# pip3 install sshtunnel
Collecting sshtunnel
Downloading https://files.pythonhosted.org/packages/c5/5c/4b320d7ec4b0d5d4d6df1fdf66a5799625b3623d0ce4efe81719c6f8dfb3/sshtunnel-0.1.5.tar.gz (49kB)
|████████████████████████████████| 51kB 2.0MB/s
Requirement already satisfied: paramiko>=1.15.2 in /usr/lib/python3.8/site-packages (from sshtunnel) (2.7.1)
Requirement already satisfied: bcrypt>=3.1.3 in /usr/lib/python3.8/site-packages (from paramiko>=1.15.2->sshtunnel) (3.1.7)
Requirement already satisfied: cryptography>=2.5 in /usr/lib/python3.8/site-packages (from paramiko>=1.15.2->sshtunnel) (2.8)
Requirement already satisfied: pynacl>=1.0.1 in /usr/lib/python3.8/site-packages (from paramiko>=1.15.2->sshtunnel) (1.3.0)
Requirement already satisfied: cffi>=1.1 in /usr/lib/python3.8/site-packages (from bcrypt>=3.1.3->paramiko>=1.15.2->sshtunnel) (1.13.2)
Requirement already satisfied: six>=1.4.1 in /usr/lib/python3.8/site-packages (from bcrypt>=3.1.3->paramiko>=1.15.2->sshtunnel) (1.14.0)
Requirement already satisfied: pycparser in /usr/lib/python3.8/site-packages (from cffi>=1.1->bcrypt>=3.1.3->paramiko>=1.15.2->sshtunnel) (2.19)
Installing collected packages: sshtunnel
Running setup.py install for sshtunnel ... done
Successfully installed sshtunnel-0.1.5
[ger-pc ~]#

El siguiente código de python es para conectar mediante el tunel (si lo quieres está en github) :

from sshtunnel import SSHTunnelForwarder
import requests

server = None

def main():
    global server
    try:
        server = SSHTunnelForwarder(
            '172.17.0.2',
            ssh_username="root",
            ssh_password="M3gusta_eltuneL",
            remote_bind_address=('127.0.0.1',80)
        )
        server.start()
        tunnel_port = server.local_bind_port
        print(tunnel_port)
        url = "http://localhost:{port}".format(
            port=tunnel_port
        )
        r = requests.get(url)
        print(r.text)
    except Exception as e:
        print("something was wrong: {error}".format(
            error=e
            )
        )
        server.stop()
        exit()

if __name__=="__main__":
    main()
    while "c" not in input():
        pass
    server.close()

Y este es el resultado de la ejecución:

[ger@ger-pc codigo_tunel_ssh]$ python tuneles_ssh.py 
36101
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
                <title>Apache HTTP Server Test Page powered by CentOS</title>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                                

Como usar tuneles SSH en Python

Espero que os haya gustado el artículo, si es así no dudéis en comentar o compartir el enlace.

¡Hasta la próxima!

Si estás interesado en aprender Docker puedes puedes adquirir nuestro libro aquí.

Docker para novatosDocker para novatos

Deja una respuesta