Pass open connection between two different python programs
Here is my use case..
I want to connect to ssh server ( network / linux/ windows) and open the connection.
And have another python program continue to use open session from step 1 and provide user inputs (commands )
The reason programs have to be separate is the caller is going to orchestrate these programs into a graphical process flow inside a designer workflow e.g mistral.
CAN I PASS THE HANDLE OF WHATEVER? NO (I'm pretty sure at least)
... why not just pass the credentials and let it open connection?
or basically your first program would have to run some sort of server, that listens for commands and forwards them up the tree ... something like this i guess
one way of passing information between two applications might be to have a flask server running on one and the other calls the flask endpoints (you dont have to use flask ... theres many ways to do this)
import argparse
import requests
from flask import Flask,request
def prog_1():
''' manage some open connection '''
my_open_thing = OpenConnection(stuff)
app = flask.Flask("__main__")
#app.route("/execute"):
def execute_command():
if request.form.get("CMD",None):
my_open_thing.send(request.form['CMD'])
return my_open_thing.recv().to_string()
app.run(port=23123)
def prog_2():
'''interact with other thing'''
while 1:
cmd = input("CMD:")
if cmd in ["quit","q"]:
break
print(requests.post("http://localhost:23123/execute",{"CMD":cmd}).content)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('TYPE',choices=['manager','client'],help="Serve the connection, or use the manager")
parser.parse_args()
if parser.TYPE == "manager":
prog_1()
else:
prog_2()
Related
I am currently underway with my Senior Capstone project, in which I am to write a somewhat basic program which allows a custom interface on my iPhone6 device to remotely control or issue critical commands to a NIDS (Suricata) established at my home RaspberryPi(3B+) VPN. My question, however, is whether it's feasible to write said program which can allow remote access control of basic functions/response options on the Pi's IDS, given that I am utilizing it as a device within the VPN network. The main issue would be establish remote signaling to the iOS device whenever there is an anomaly and allowing it to respond back and execute root-level commands on the NIDS.
If it is of any good use, I am currently using Pythonista as a runtime environment on my mobile device and have set my VPN's connection methods to UDP, but I'm not sure if enabling SSH would assist me. I have a rather basic understanding of how to operate programming in regards to network connectivity. I very much appreciate any and all the help given!
from tkinter import *
window=Tk()
window.geometry("450x450")
window.title("IDS Response Manager")
label1=Label(window,text="Intrusion Response Options",fg= 'black',bg ='white',relief="solid",font=("times new roman",12,"bold"))
label1.pack()
button1=Button(window,text="Terminate Session",fg='white', bg='brown',relief=RIDGE,font=("arial",12,"bold"))
button1.place(x=50,y=110) #GROOVE ,RIDGE ,SUNKEN ,RAISED
button2=Button(window,text="Packet Dump",fg='white', bg='brown',relief=RIDGE,font=("arial",12,"bold"))
button2.place(x=220,y=110) #GROOVE ,RIDGE ,SUNKEN ,RAISED
button3=Button(window,text="Block Port",fg='white', bg='brown',relief=RIDGE,font=("arial",12,"bold"))
button3.place(x=110,y=170) #GROOVE ,RIDGE ,SUNKEN ,RAISED
Very basic options as are shown here.
You can use a flask server with an API, which you can send post requests to. You can then send get requests to receive the commands. To host your API, look at Heroku (free tier available, and very much functional, with already configured app_name.herokuapp.com).
Search up to send a post request with the technologies you are using to build your app. Send keyword command with the command to the /send_commands along with the password, "password_here" (changeable to anything you want).
Python:
Modules: Flask (server), request (client)
Server Code:
from flask import Flask
app = Flask(__name__)
commands = []
#app.route('/get_commands', methods=['GET'])
def get_commands():
tmp_commands = commands[::]
commands = []
return {'commands': tmp_commands}
#app.route('/send_commands', methods=['POST'])
def send_commands():
if request.json['password'] == "password_here":
commands.append(request.json['command'])
return {'worked': True}
else:
return {'worked': False}
if __name__ == '__main__':
app.run(debug=True)
Client Code:
import requests
URL = "url_here/get_commands"
commands = requests.get(url = URL)
for command in commands:
os.system(command)
I need your advice on how to go about the following:
I am running a Counter Strike Game server on an Azure VM
The server is nothing but a Desktop utility that runs a service on certain port
to which my friends connect and play the game
At times, I have to change the "map" on the game which means I have to go/login on the
Azure VM and manually perform some actions (very basic like increase
round-time for a match) or kick a user
Every time, I have to login on server and do this manually. If I want someone else to do it, then I
will have to give them the VM access which is not what I want
I know moderate Python, so I can write a script that would actually perform
this action (using Python OS library)
But I want to be able to run this script remotely from a web app or any other trigger
So the use case would look like this:
A user goes to a URL (myGameserver.com:8989)
He sees a list of available users in the game. He selects one and presses KICK button
The kick button kicks that user from server by running a program that I mentioned in point 5 above
The thing I need your help with is; What type of app /tech should I use to make this web application and How do I pass this "user selection" as an input to my program so that it knows what user to kick ?
Here is a simple flask api to kick players by steamid using rcon.
You can use curl to post data to it like this:
curl -H "Content-Type: application/json" \
--d '{"steamid":"STEAM_1:0:1234567"}' \
https://myGameserver.com:8989/kickplayer
The api:
from flask import Flask, request
import valve.rcon
app = Flask(__name__)
HOST = "0.0.0.0"
PORT = 8989
DEBUG = True
# replace with your VM's local ip if you are running this web app on the same VM as the csgo server
# or with the azure public ip if not. (You will need to open up port 27015 TCP for rcon)
CSGO_SERVER_IP = "10.0.100.100"
RCON_PORT = 27015
RCON_PASS = "supersekret123456"
#app.route('/kickplayer', methods=['POST'])
def kick_player():
data = request.get_json()
steamid = data["steamid"] # STEAM_1:0:XXXXXXXXX
rcon_command = "sm_kick " + steamid
with valve.rcon.RCON((CSGO_SERVER_IP, RCON_PORT), RCON_PASS) as rcon:
response = rcon.execute(rcon_command)
return f"Kicked player {steamid}"
if __name__ == '__main__':
app.run(debug=DEBUG, host=HOST, port=PORT)
Feel free to message me on discord for more advice, I run csgo servers and have written csgo web panels before: BurningTimes#1938
How to logged in to multiple server using pywinauto application? I am using below program for access putty and run the command, This is work for single server when i have defined like
app = Application ().Start (cmd_line = 'C:\Program Files\PuTTY\putty.exe -ssh user#10.55.167.4')
But while i am passing with for loop to do the same task for another server it does not work.
from pywinauto.application import Application
import time
server = [ "10.55.167.4", "10.56.127.23" ]
for inser in server:
print(inser)
app = Application ().Start (cmd_line = 'C:\Program Files\PuTTY\putty.exe -ssh user#inser')
putty = app.PuTTY
putty.Wait ('ready')
time.sleep (1)
putty.TypeKeys ("aq#wer")
putty.TypeKeys ("{ENTER}")
putty.TypeKeys ("ls")
putty.TypeKeys ("{ENTER}")
pywinauto is a Python module to automatize graphical user interface (GUI) operations for example to simulate mouse clicking and everything else humans used to do on GUIs to interact with the computer. SSH is a remote access protocol designed primarily for command line and having excellent programmatic support in Python. Putty is a little GUI tool to manage SSH and Telnet connections. Although, based on quick check, I think it is possible to read the console output (you mean in cmd.com?) by pywinauto, I think your approach is unnecessarily complicated: you don't need to use a GUI tool designed for human interaction to access a protocol with excellent command line and programmatic library support. I suggest you to use paramiko which gives a very simple and convenient interface to SSH:
import paramiko
def ssh_connect(server, **kwargs):
client = paramiko.client.SSHClient()
client.load_system_host_keys()
# note: here you can give other paremeters
# like user, port, password, key file, etc.
# also you can wrap the call below into
# try/except, you can expect many kinds of
# errors here, if the address is unreachable,
# times out, authentication fails, etc.
client.connect(server, **kwargs)
return client
servers = ['10.55.167.4', '10.56.127.23']
# connect to all servers
clients = dict((server, ssh_connect(server)) for server in servers)
# execute commands on the servers by the clients, 2 examples:
stdin, stdout, stderr = clients['10.55.167.4'].exec_command('pwd')
print(stdout.read())
# b'/home/denes\n'
stdin, stdout, stderr = clients['10.56.127.23'].exec_command('rm foobar')
print(stderr.read())
# b"rm: cannot remove 'foobar': No such file or directory\n"
# once you finished close the connections
_ = [cl.close() for cl in clients.values()]
I have the following script which just boots up a web server serving a dynamically created website. In order to get dynamic data the script opens a file to read the data.
My concern is how can I catch CTRL-C command for killing the python script so I can close the file before script thread is killed.
I tried the following couple things but neither work:
from flask import Flask, render_template
import time
# Initialize the Flask application
app = Flask(__name__)
fileNames = {}
fileDesc = {}
for idx in range(1,4):
fileNames["name{}".format(idx)] = "./name" + str(idx) + ".txt"
fileDesc["name{}".format(idx)] = open(fileNames["name{}".format(idx)],'r')
try:
#app.route('/')
def index():
# code for reading data from files
return render_template('index.html', var1 = var1)
#app.errorhandler(Exception)
def all_exception_handler(error):
print("Closing")
for key, value in fileDesc:
val.close()
print("Files closed")
if __name__ == '__main__':
app.run(
host="192.168.0.166",
port=int("8080"),
debug=True
)
except KeyboardInterrupt:
print("Closing")
for key, value in fileDesc:
val.close()
print("Files closed")
Thanks in advance.
I am struggling with the same thing in my project. Something that did work for me was using signal to capture CTRL-C.
import sys
import signal
def handler(signal, frame):
print('CTRL-C pressed!')
sys.exit(0)
signal.signal(signal.SIGINT, handler)
signal.pause()
When this piece of code is put in the script that is running the Flask app, the CTRL-C can be captured. As of now, you have to use CTRL-C twice and then the handler is executed though. I'll investigate further and edit the answer if I find something new.
Edit 1
Okay I've done some more research and came up with some other methods, as the above is quite hack 'n slash.
In production, clean-up code such as closing databases or files is done via the #app.teardown_appcontext decorator. See this part of the tutorial.
When using the simple server, you can shut it down via exposing the werkzeug shutdown function. See this post.
Edit 2
I've tested the Werkzeug shutdown function, and it also works together with the teardown_appcontext functions. So I suggest to write your teardown functions using the decorator and writing a simple function that just does the shutdown of the werkzeug server. That way production and development code are the same.
Use atexit to handle this, from: https://stackoverflow.com/a/30739397/5782985
import atexit
#defining function to run on shutdown
def close_running_threads():
for thread in the_threads:
thread.join()
print "Threads complete, ready to finish"
#Register the function to be called on exit
atexit.register(close_running_threads)
#start your process
app.run()
I have written a single user application that currently works with Flask internal web server. It does not seem to be very robust and it crashes with all sorts of socket errors as soon as a page takes a long time to load and the user navigates elsewhere while waiting. So I thought to replace it with Apache.
The problem is, my current code is a single program that first launches about ten threads to do stuff, for example set up ssh tunnels to remote servers and zmq connections to communicate with a database located there. Finally it enters run() loop to start the internal server.
I followed all sorts of instructions and managed to get Apache service the initial page. However, everything goes wrong as I now don't have any worker threads available, nor any globally initialised classes, and none of my global variables holding interfaces to communicate with these threads do not exist.
Obviously I am not a web developer.
How badly "wrong" my current code is? Is there any way to make that work with Apache with a reasonable amount of work? Can I have Apache just replace the run() part and have a running application, with which Apache communicates? My current app in a very simplified form (without data processing threads) is something like this:
comm=None
app = Flask(__name__)
class CommsHandler(object):
__init__(self):
*Init communication links to external servers and databases*
def request_data(self, request):
*Use initialised links to request something*
return result
#app.route("/", methods=["GET"]):
def mainpage():
return render_template("main.html")
#app.route("/foo", methods=["GET"]):
def foo():
a=comm.request_data("xyzzy")
return render_template("foo.html", data=a)
comm = CommsHandler()
app.run()
Or have I done this completely wrong? Now when I remove app.run and just import app class to wsgi script, I do get a response from the main page as it does not need reference to global variable comm.
/foo does not work, as "comm" is an uninitialised variable. And I can see why, of course. I just never thought this would need to be exported to Apache or any other web server.
So the question is, can I launch this application somehow in a rc script at boot, set up its communication links and everyhing, and have Apache/wsgi just call function of the running application instead of launching a new one?
Hannu
This is the simple app with flask run on internal server:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
To run it on apache server Check out fastCGI doc :
from flup.server.fcgi import WSGIServer
from yourapplication import app
if __name__ == '__main__':
WSGIServer(app).run()