Malgranda malantaŭa pordo sur Flask aŭ kiel kontroli komputilon en loka reto

Hej Habr!

Mi lastatempe spektis elŝutitan version de la programa fluo "Kiel krei vian propran TTT-aplikaĵon en Flask." Kaj mi decidis plifirmigi miajn sciojn en iu projekto. Dum longa tempo mi ne sciis kion skribi kaj venis al mi la ideo: "Kial ne fari mini-malantaŭan pordon en Flask?"

La unuaj opcioj por efektivigoj kaj kapabloj de la malantaŭa pordo tuj aperis en mia kapo. Sed mi decidis tuj fari liston de malantaŭpordaj kapabloj:

  1. Sciu kiel malfermi retejojn
  2. Havu komandlinian aliron
  3. Povi malfermi programojn, fotojn, filmetojn

Do, la unua punkto estas ege facile efektivigebla per la retumila modulo. Mi decidis efektivigi la duan punkton per la os-modulo. Kaj la tria estas ankaŭ per la os-modulo, sed mi uzos "ligilojn" (pli pri tio poste).

Skribante servilon

Do, *drumroll* la tuta servila kodo:

from flask import Flask, request
import webbrowser
import os
import re

app = Flask(__name__)
@app.route('/mycomp', methods=['POST'])
def hell():
    json_string = request.json
    if json_string['command'] == 'test':
        return 'The server is running and waiting for commands...'
    if json_string['command'] == 'openweb':
        webbrowser.open(url='https://www.'+json_string['data'], new=0)
        return 'Site opening ' + json_string['data'] + '...'
    if json_string['command'] == 'shell':
        os.system(json_string['data'])
        return 'Command execution ' + json_string['data'] + '...'
    if json_string['command'] == 'link':
        links = open('links.txt', 'r')
        for i in range(int(json_string['data'])):
            link = links.readline()
        os.system(link.split('>')[0])
        return 'Launch ' + link.split('>')[1]
if __name__ == '__main__':
    app.run(host='0.0.0.0')

Mi jam forĵetis la tutan kodon, estas tempo klarigi la esencon.

Ĉiu kodo funkcias en la loka komputilo sur la haveno 5000. Por interagi kun la servilo, ni devas sendi peton JSON POST.

JSON-peta strukturo:

{‘command’:  ‘comecommand’, ‘data’: ‘somedata’}

Nu, havas sencon, ke 'komando' estas la komando, kiun ni volas plenumi. Kaj 'datenoj' estas la komandaj argumentoj.

Vi povas skribi kaj sendi JSON-petojn por interagi kun la servilo permane (petoj helpos vin). Aŭ vi povas skribi konzolan klienton.

Skribante klienton

Kodo:

import requests

logo = ['nn',
        '******      ********',
        '*******     *********',
        '**    **    **     **',
        '**    **    **     **      Written on Python',
        '*******     **     **',
        '********    **     **',
        '**     **   **     **      Author: ROBOTD4',
        '**     **   **     **',
        '**     **   **     **',
        '********    *********',
        '*******     ********',
        'nn']

p = ''
iport = '192.168.1.2:5000'
host = 'http://' + iport + '/mycomp'

def test():
    dict = {'command': 'test', 'data': 0}
    r = requests.post(host, json=dict)
    if r.status_code == 200:
        print (r.content.decode('utf-8'))

def start():
    for i in logo:
        print(i)

start()
test()

while True:
    command = input('>')
    if command == '':
        continue
    a = command.split()
    if command == 'test':
        dict = {'command': 'test', 'data': 0}
        r = requests.post(host, json=dict)
        if r.status_code == 200:
            print (r.content.decode('utf-8'))
    if a[0] == 'shell':
        for i in range(1, len(a)):
            p = p + a[i] + ' '
        dict = {'command': 'shell', 'data': p}
        r = requests.post(host, json=dict)
        if r.status_code == 200:
            print (r.content.decode('utf-8'))
        p = ''
    if a[0] == 'link':
        if len(a) > 1:
            dict = {'command': 'link', 'data': int(a[1])}
            r = requests.post(host, json=dict)
            if r.status_code == 200:
                print (r.content.decode('utf-8'))
        else:
            print('Комманда не содержит аргументов!')
    if a[0] == 'openweb':
            if len(a) > 1:
                dict = {'command': 'openweb', 'data': a[1]}
                r = requests.post(host, json=dict)
                if r.status_code == 200:
                    print (r.content.decode('utf-8'))
            else:
                print('Комманда не содержит аргументов!')
    if a[0] == 'set':
        if a[1] == 'host':
            ip = a[2] + ':5000'
    if command == 'quit':
        break

Klarigoj:

Antaŭ ĉio, la petoj-modulo estas importita (por interagado kun la servilo). Malsupre estas priskriboj de la komencaj kaj testaj funkcioj. Kaj tiam la ciklo en kiu la magio okazas. Ĉu vi legis la kodon? Do vi komprenas la signifon de la magio, kiu okazas en la ciklo. Enigu la komandon - ĝi estas ekzekutita. Ŝelo - komandoj por la komandlinio (la logiko estas eksterskala).

Testo - kontrolu ĉu la servilo funkcias (malantaŭa pordo)
Ligo - uzo de "mallongigo"
Openweb - malfermante retejon
Quit - forlasu la klienton
Agordu - agordi la ip-on de via komputilo en la loka reto

Kaj nun pli pri ligilo.

Estas link.txt dosiero apud la servilo. Ĝi enhavas ligilojn (plena vojo) al dosieroj (filmetoj, fotoj, programoj).

La strukturo estas tia:

полный_путь>описание
полный_путь>описание

La rezulto

Ni havas malantaŭpordan servilon por kontroli komputilon en loka reto (ene de reto wi-fi). Teknike, ni povas ruli la klienton de iu ajn aparato, kiu havas python-interpretilon.

PS Mi aldonis la agordan komandon por ke se komputilo en la loka reto estas asignita malsama IP, ĝi povas esti ŝanĝita rekte en la kliento.

fonto: www.habr.com

Aldoni komenton