Python web service and DMZ - python

I have written a python library and a web service using flask to expose functions from that library. The library should run on computer A (to do its processing). In our IT setup, web servers will run on a DMZ (computer B). This being the case, if the flask web service directly imports the library and runs a function, it would be running on the DMZ, rather than the intended computer? How do I design the program such that the library executes on the intended hardware, but the web service is hosted by the webserver on the DMZ?

If you want the service itself to run on dedicated hardware within the network and have the webserver itself hosted on the DMZ you'll have to use a proxy. You can use Nginx (for instance) to forward the port in which you're exposing the webserver to the port opened by flask on the dedicated machine. You'll have to configure your firewall to forward that port so that it's accessible to the machine in the DMZ.
I'd provide the configuration for your firewall and Nginx but it really depends on the parameters of your network and the service you want to run.

Related

how can I post to api running on remote desktop?

I'm creating a python flask api on remote desktop and running it on localhost of remote desktop.
Is there anyway I can access this api from my local machine?
We are working in a team and I want to share this with my team members, but this is confidential and not to be deployed on open server.
We want to post and get the result with every member's local machine from api runnnig on remote desktop.
Both of our local machines and remote desktop are windows10.
Sorry for being abstract but I'm searching for any way out. Thanks.
Well, you should open your way to this API. You'll have to set up a VPN or IP address filter in the server so you can access the server from your network while still have it secured on the Internet. You can also setup a simpler proxy if you prefer it. I'll not cover the details on how to setup a VPN or proxy since it can get pretty extensive, but a Google search will help you out find the best alternative for you.
AFAIK, the Remote Desktop Protocol does not allow for any kind of VPN. However, if you can switch to TeamViewer, it does have an easy to setup VPN system that will allow you to get into the network with few configuration. Once a VPN is configured, it will work like if you were in the same network as the server, so from there you can access your API from your host machine by just going to the IP address of the server.
Do notice the security policies of whoever owns the server, since you can get into trouble if you don't have permission to enable some access from the outside. Security goes always in front of comfort.
Short term solution:
Firstly download ngrok for your operating system.
For debugging and testing purposes you can expose a secure tunnel connection to your API by running this command in your command prompt / terminal.
ngrok http <PORT_NUMBER>-host-header="localhost:<PORT_NUMBER>"
Where PORT_NUMBER is the port number in which your flask application is running.
Example if your flask application is running at port 5000 then simply execute this command:
ngrok http 5000 -host-header="localhost:5000"
Running this will give you two hostnames one with HTTP and other a secure HTTPS connected by a tunnel like this for a duration of 8 hours after which the command needs to again re-run.
Which you can call remotely
Long term solution:
Deploy flask application using FastCGI
or
To a cloud infrastructure provider like Microsoft Azure which gives readymade templates for flask applications.

Error accessing my webpage from network

I've just started learning network developing using Flask. According to its official tutorial:
Externally Visible Server
If you run the server you will notice that the server is only
accessible from your own computer, not from any other in the network.
This is the default because in debugging mode a user of the
application can execute arbitrary Python code on your computer.
If you have the debugger disabled or trust the users on your network,
you can make the server publicly available simply by adding
--host=0.0.0.0 to the command line:
flask run --host=0.0.0.0
This tells your operating system to listen on all public IPs.
However, when I try to access 0.0.0.0:5000 on another device, I got an error: ERR_CONNECTION_REFUSE. In fact, I think this behavior is reasonable, since people all around world can use 0.0.0.0:5000 for different testing purposes, but isn't the tutorial implying that adding --host=0.0.0.0 can make my webpage "accessible not only from your own computer, but also from any other in the network"?
So, my question is:
What does adding --host=0.0.0.0 do?
How can I access my webpage on device B while the server is running on device A?
You don't access the Flask server on another computer by going to 0.0.0.0:5000. Instead, you need to put in the IP address of the computer that it is running on.
For example, if you are developing on a computer that has IP address 10.10.0.1, you can run the server like so:
flask run --host=0.0.0.0 --port=5000
This will start the server (on 10.10.0.1:5000) and listen for any connections from anywhere. Now your other device (say, on 10.10.0.2) can access that server by going to http://10.10.0.1:5000 in the browser.
If you don't have the host=0.0.0.0, the server on 10.10.0.1 will only listen for connections from itself (localhost). By adding that parameter, you are telling it to listen from connections external to itself.

How to make flask server running in a VM externally available?

If I run my flask app on my local machine I get proper results by connecting to http://127.0.0.1:5000/report?id=1
But now I want to make it externally visible by deploying my flask in a VM in azure. I have opened the port 80 on my VM. And I'm running the flask app using this:
if __name__ == '__main__':
app.run(host='0.0.0.0')
I'm still not able to connect to my flask server using this (assume the public IP address of my VM is x.x.x.x):
http://x.x.x.x:5000/report?id=1
Any suggestions how should I go ahead with it?
Edit: I'm able to psping my VM's public IP address on port 80.
The problem isn't related to Flask, since you opened up your application to listen on any public IP (0.0.0.0).
Moreover you should do a proper port mapping in your azure configuration. Google said, you might have a look here: https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-set-up-endpoints/
EDIT
Another idea, where some colleages often run into, is that you may have skype open which somewhat uses port 80/443 and therefore is blocking it. Shutdown skype if you do so or use a different port for your webapp.
So here's the deal with Azure:
If you open a port from the Azure portal, the firewall in your VM STILL blocks that port. You have to manually go in and create a firewall setting in your VM to keep the port 5000 open for your flask server. Once that is done, you should be able to connect to it.

Flask development server blocked by proxy at work

I am trying to use the flask development server at an office with a strict proxy that blocks the default 127.0.0.1:5000 host and port. I have tried using different hosts and ports with no success. I have also tried setting up Flask with XAMPP on Windows via mod_wsgi with no success. I am looking for an option to continue testing flask on my local machine with as little setup as possible as my production environment is a PaaS and does not use the same setup as my local machine.

How can a python web app open a program on the client machine?

I'm going to be using python to build a web-based asset management system to manage the production of short cg film. The app will be intranet-based running on a centos machine on the local network. I'm hoping you'll be able to browse through all the assets and shots and then open any of them in the appropriate program on the client machine (also running centos). I'm guessing that there will have to be some sort of set up on the client-side to allow the app to run commands, which is fine because I have access to all of the clients that will be using it (although I don't have root access). Is this sort of thing possible?
As you already guessed, you will need to have a service running on the client PC listening on a predetermined port.
When the client requests to open an asset, your webapp will send the request to the running service to download the asset and run it. As long as your port no. is above 1024 and you are not running any application which requires root access, you can run this service without root.
But this is a very bad idea as it exposes the clients to malicious attacks. You will have to ensure all requests to the client service is properly signed and that the client verifies each request as valid before executing it. There may be many other security factors you will have to consider depending on your implementation of the client service. But in general, having a service that can run arbitrary requests from a remote machine is a very dangerous thing to have.
You may also not be allowed to run such a service on client PC depending on your comany's IT policies.
You are better of having the client download the resource normally and then having the user execute the resource manually.
PS: You can have the client service run on a port below 1024, but it will have to start as root and after binding to the port drop all root privileges and change the running user to a different user using setuid (or the equivalent in your language of choice)
Note this is not a standard way. Imagine the websites out there had the ability to open Notepad or Minesweeper at their will when you visit or click something.
The way it is done is, you need to have a service which is running on the client machine which can expose certain apis and trust the request from the web apps call. this needs to be running on the client machines all the time and in your web app, you can send a request to this service to launch the application that you desire.
If you have a specific subset of applications that will be run on the client systems (aka you are distributing jobs), then you might want to consider python salt. It is a distributed RPC which uses a secure protocol and authentication to distribute jobs and deliver results:
http://docs.saltstack.org/en/latest/topics/index.html
If you are looking at automating content generation based on specific updates then you might want to consider Jenkins, which has plugins for various revision control systems and build systems:
https://wiki.jenkins-ci.org/display/JENKINS/Meet+Jenkins
It may not have integration with the particular tools you are using, but if it does then it could be a quicker setup and administration than generic salt automation.
--David

Categories