Доступ к localhost API с удаленного хоста с помощью ssh

У меня есть приложение, работающее на безголовой удаленной машине (ubuntu). Это приложение содержит API, взаимодействующий с локальным хостом, порт 4068. Я могу подключиться к этой машине по ssh через порт 22.

Работая напрямую с python на удаленной машине, я могу использовать пакет sockets-client и получить в паре строк то, что хочу:

#From within remote machine!
import socket
s = socket.socket()
s.connect(("127.0.0.1",4068))
s.send("help")
print(s.recv(1024))
#prints the API help

Я хочу провести некоторую аналитику на моей локальной машине, связавшись с удаленным API (который действительно удален, а не в локальной сети).

До сих пор я использовал pxssh и вызывал telnet. Я предполагаю, что это не оптимально, точно не для меня. Я бы предпочел альтернативу с использованием пакета sockets-client или аналогичного.

Вот пример кода моего решения

#From my local machine.
from pexpect import pxssh
import pexpect
#hostname, username and password are information to connect to ssh
p = pxssh.pxssh()
p.login(hostname,username,password)
query = r"telnet 127.0.0.1 4068"
p.sendline(query)
p.sendline("help")
p.expect("help")
p.expect([p.PROMPT,pexpect.EOF,pexpect.TIMEOUT])
print(p.before)
#prints the API help together with waste.

Примечание. Я знаю, что должен использовать регулярное выражение в функции ожидания, а затем напечатать соответствующую строку. В любом случае, это не элегантно и очень сложно по сравнению с простым использованием пакета sockets-client.

Другие решения, которые я рассматривал, но менее оптимальны:

  • Я мог бы, конечно, перенаправить порт API на определенный порт моего коммутатора/модема, но я боюсь, что это приведет к проблемам с безопасностью (я не эксперт по безопасности, на самом деле даже не айтишник). Я мог бы также написать

  • Я мог бы иметь свою программу Python на удаленной машине, но это кажется более сложным, чем использование telnet через pxssh. Также это означает, что мне нужно управлять пакетами и еще много чего, поэтому мое решение не переносимо.


person Wli    schedule 11.10.2017    source источник


Ответы (1)


Поскольку я не знаю, что вы используете на стороне сервера, я использую pythons http.server здесь началось как

python3 -m http.server

На стороне клиента я использую sshtunnel со следующим кодом:

from sshtunnel import SSHTunnelForwarder
import socket

# open ssh tunnel
server = SSHTunnelForwarder(
    '',
    ssh_username="",
    ssh_password="",
    remote_bind_address=('127.0.0.1', 8000)
)

server.start()

print('local port:', server.local_bind_port)  # show assigned local port
# work with `SECRET SERVICE` through `server.local_bind_port`.

#create an INET, STREAMing socket
s = socket.socket(
    socket.AF_INET, socket.SOCK_STREAM)
#now connect to the web server on port 8080
s.connect(('127.0.0.1', server.local_bind_port))
s.send(b'GET / HTTP/1.0 \r\n\r\n')
print(s.recv(1000))
s.close()

server.stop()

Для взаимодействия с оболочкой, подобной telnet, вы можете использовать встроенную в python telnetlib< /а>.

person uphill    schedule 11.10.2017
comment
Это красиво, спасибо! У меня нет контроля на стороне сервера, но он работает так же (за исключением того, что я отправляю помощь, а не GET...). - person Wli; 11.10.2017
comment
Нет, SSHTunnelForwarder — это именно то, что мне было нужно и о чем я не знал. Мне не нравится использовать telnet, слишком много хлопот. - person Wli; 11.10.2017