Trouble accessing webservice from EC2 instance - python

I have a small bottle webservice running on EC2 virtual windows server i launched. I am able to access it on localhost or by using the IPV4 specified in the main method as below but I am not able to access it over internet from other computers.
Please suggest me how to deal with this. I saw one similar question like this but the suggestions didnt work so am posting again. Apologies for that.
Trying:http://172.31.30.244:8080/
#route('/')
def index():
""" Display welcome & instruction messages """
return "<p>Welcome to bottle powered server !</p> \
<p>There are many ways to invoke the web service :\
<ul><li>http://localhost:8080/in?s=type_your_string_here</li>\
</ul>"
some code here for calculations
IN my Main method
if __name__ == '__main__':
bottle.debug(True)
run(host='172.31.30.244', port=8080,debug=True)

Ran bottle server on EC2 instance, opened a port 8083 and accessed using the fully_qualified_machine_name:8083 thank you for your suggestion on using the public DNS name. I was not opening the port properly which i later did using custom TCP under 'Add rule' for inbounds of EC2 instance

Related

Streamlit server configuration on remote HTTPS using Azure Compute Instance

I am trying to host a Streamlit app on Azure Compute Instance resource.
It appears that accessing the instance is possible through https://{instanceName}-{internalPort}.northeurope.instances.azureml.ms (with an Azure-provided security layer in between).
To smoketest this I created a simple Flask app and verified I could access it: I was able to access my dummy app on https://[REDACTED]-5000.northeurope.instances.azureml.ms/.
Attempt 1: Basic Configuration
Now I want to serve my Streamlit app. Initially I wanted to eliminate error sources and simply check if wires are connected correctly, and my app is simply:
import streamlit as st
st.title("Hello, World!")
Running this streamlit app (streamlit run sl_app.py) gives:
2022-03-28 11:49:38.932 Trying to detect encoding from a tiny portion of (13) byte(s).
2022-03-28 11:49:38.933 ascii passed initial chaos probing. Mean measured chaos is 0.000000 %
2022-03-28 11:49:38.933 ascii is most likely the one. Stopping the process.
You can now view your Streamlit app in your browser.
Network URL: http://[REDACTED]:8501
External URL: http://[REDACTED]:8501
Trying to access this through https://[REDACTED]-8501.northeurope.instances.azureml.ms/ I can access the app, but the "Please wait..." indicator appears indefinitely:
Attempt 2: Updated Streamlit Config
Inspired by App is not loading when running remotely Symptom #2 I created a Streamlit config.toml with a reconfiguring of server/browser access points, and ended up with the following:
[browser]
serverAddress = "[REDACTED]-8501.northeurope.instances.azureml.ms"
serverPort = 80
gatherUsageStats = false
[server]
port = 8501
headless = true
enableCORS = false
enableXsrfProtection = false
enableWebsocketCompression = false
Running the app now gives:
You can now view your Streamlit app in your browser.
URL: http://[REDACTED]-8501.northeurope.instances.azureml.ms:80
However, I still get the infinite Please wait-indicator. Diving a little bit deeper reveals something related to a wss stream? Whatever that is?
I suspect that what I'm seeing is due to the fact that Azure automatically pipes my request from http:// to https://, and this for some reason rejects the stream component that Streamlit uses?
Note: Various IP addresses and hostnames are REDACTED for the sake of security :-)
The major issue happened here is to access the SSL certificate. Here is a perfect guide to follow to deploy streamlit on Azure.
https://towardsdatascience.com/beginner-guide-to-streamlit-deployment-on-azure-f6618eee1ba9
https://towardsdatascience.com/beginner-guide-to-streamlit-deployment-on-azure-part-2-cf14bb201b8e
First link is to deploy without any errors and second link is to activate with SSL certificate to make the URL as HTTPS from HTTP.

steps I need to take to make my flask webpage visible by others

I have a webpage with some simple algorithm, which returns the output based on user input & local data file. I checked it's working with my local machine, but found that it doesn't work from my cell phone / other laptops.
I tried several things from web - such as 'python app.py --host=0.0.0.0' on my terminal, or app.run(host='0.0.0.0', port=5000) but didn't work.
I'm trying again from the beginning. below is my code (I named the file app.py), where I put it back to default before any edit.
from flask import Flask,render_template,url_for,request
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
#app.route('/predict',methods=['POST'])`
def predict():
#some algorithm stuffs
return render_template('result.html', tables=[result.to_html(classes='data',escape=False)], titles=result.columns.values)
if __name__ == '__main__':
app.run(debug=True)
what should I add on this py file?
Also, is there anything beside coding I should do? (firewall, port, etc) I'm currently starting with local machine and planning to work it with virtual machine later (EC2)
If you want to deploy your application in your own local network and make it accessible to your phone or to other computers in the network for testing reasons, then the following steps is enough:
Make sure your computer is connected to your access point and receives an ip address, then launch your application with the command: flask run --host=0.0.0.0 which tells your operating system to listen on all public IPs.
Check the ip address of your machine and the port number on which flask is running (eg: 192.168.43.114:5000). Type it in the browser on your phone or another computer on the network and you will have access to your application.
If you want a larger deployment, for example having computers in other networks access your application, then you need to consider other strategies. Here are a few examples, all of which relate to a specific use case:
Flask-ngrok
Pythonanywhere
Excellent tutorial about deployement on heroku
If you want to make it visible by anyone you have to open at least one port of your box (depending on your box model you can find some explanations on how to do it), this can be unsafe. You'll then have to map your box port with your PC's port.
You should go straight with a cloud virtual machine as it's much easier (just allow connexion to the VM port 80)
A good alternative would be to use Docker and deploy your app on Heroku or Azure (it's free!)
If you want to make it visible on your own network (just the people on the same WIFI) then it's easier but I don't think that's your point

Very Lost: Flack and NYU Osiris Challenges

I am going through some CTF challenges at https://recruit.osiris.cyber.nyu.edu/challenges.
I got to one for Template Programming where the task is to "Read /flag.txt from the server. http://recruit.osiris.cyber.nyu.edu:2000"
I am not asking for a solution, but I would like some better understanding of what is going on below:
What is this code doing?
Should I be worried about running out of Debugging mode and/or using host="0.0.0.0"?
What are some resources that could help me understand this? I tried reading through the Flask documentation and the tutorialspoint page, but I am unclear as to how this doesn't just set up a local server for testing as opposed to accessing a remote server...
If I ctrl+C do I need to worry about leaving a server still running on an open port when I am not in Debugging mode?
#!/usr/bin/env python3
from flask import Flask, request, abort, render_template_string
import os.path
app = Flask(__name__)
#app.route('/', methods=['GET'])
def index():
name = request.args.get('name')
if name is not None:
return render_template_string(open('templates/hello.html').read().format(name=name))
return render_template_string(open('templates/index.html').read())
if __name__ == "__main__":
app.run(host="0.0.0.0")
I think I can answer most of these.
As you probably already figured out, Flask is a fairly basic web framework. By the look of things, what you have there is a copy of the code running at the CTF site. It displays just two pages; one that contains the initial web form (templates/index.html) and another that uses a query string variable to greet the user (templates/hello.html) when a name has been provided.
You don't really have to run this code yourself. The 0.0.0.0 host address is catch-all that matches all IPv4 addresses on the local machine, which would include local addresses like 192.168.0.1 and 127.0.0.1 as well as the IP address used for incoming connections to the server.
Like I said, this is the code running on the remote server.
I think what you need to do is find some way of crafting a request to this web service in such a way that it reveals the contents of /flag.txt instead of (or perhaps in addition to) just saying hello. A quick search for something like "flask include file vulnerability" should give you some idea of how to attack this problem.

How to use CherrPy as Web server and Bottle as Application to support multiple virtual hosts?

I have a website (which running in Amazon EC2 Instance) running Python Bottle application with CherryPy as its front end web server.
Now I need to add another website with a different domain name already registered. To reduce the cost, I want to utilize the existing website host to do that.
Obviously, virtual host is the solution.
I know Apache mod_wsgi could play the trick. But I don't want to replace CherryPy.
I've googled a a lot, there are some articles showing how to make virtual hosts on CherryPy, but they all assume Cherrypy as Web Sever + Web application, Not CherrPy as Web server and Bottle as Application.
How to use CherrPy as Web server and Bottle as Application to support multiple virtual hosts?
As you mentioned, use VirtualHost. In the example cherrypy.Application instances are used, but any WSGI callable (e. g. Bottle app) will do.
perhaps you can simply put nginx as reverse proxy and configure it to send the traffic to the two domains to the right upstream (the cherryPy webserver).
Another idea would be to use Nginx (http://wiki.nginx.org/Main) with uWsgi(http://projects.unbit.it/uwsgi/) & (uWsgi-python) plug-in
uWsgi has a module named emperor that you can link vhosts(vassals) in, sort of.
i'm a newbie at this myself, so not necessarily an answer but rather a suggestion to check it out.
just a heads up, uWsgi and Nginx can be a hassle to get it to work, depending on your linux distro. Does work nicely with bottle, tested it myself.
hope it helps
jwalker's answer is pretty clear. In case any CherryPy newbie need whole script for reference, I post one below.
import cherrypy
from bottle import Bottle
import os
app1 = Bottle()
app2 = Bottle()
#app1.route('/')
def homePage():
return "========= home1 ==============="
#app2.route('/')
def homePage_2():
return "========= home2 ==============="
vhost = cherrypy._cpwsgi.VirtualHost(None,
domains={
'www.domain1.com': app1,
'www.domain2.com': app2,
}
)
cherrypy.tree.graft(vhost)
cherrypy.config.update({
'server.socket_host': '192.168.1.4',
'server.socket_port': 80,
})
cherrypy.engine.start()
cherrypy.engine.block()
you could make www.domain1.com and www.domain1.com point to one IP adress of you server, so it servers for 2 domain in one Web Server.

Python, Twisted, Django, reactor.run() causing problem

I have a Django web application. I also have a spell server written using twisted running on the same machine having django (running on localhost:8090). The idea being when user does some action, request comes to Django which in turn connects to this twisted server & server sends data back to Django. Finally Django puts this data in some html template & serves it back to the user.
Here's where I am having a problem. In my Django app, when the request comes in I create a simple twisted client to connect to the locally run twisted server.
...
factory = Spell_Factory(query)
reactor.connectTCP(AS_SERVER_HOST, AS_SERVER_PORT, factory)
reactor.run(installSignalHandlers=0)
print factory.results
...
The reactor.run() is causing a problem. Since it's an event loop. The next time this same code is executed by Django, I am unable to connect to the server. How does one handle this?
The above two answers are correct. However, considering that you've already implemented a spelling server then run it as one. You can start by running it on the same machine as a separate process - at localhost:PORT. Right now it seems you have a very simple binary protocol interface already - you can implement an equally simple Python client using the standard lib's socket interface in blocking mode.
However, I suggest playing around with twisted.web and expose a simple web interface. You can use JSON to serialize and deserialize data - which is well supported by Django. Here's a very quick example:
import json
from twisted.web import server, resource
from twisted.python import log
class Root(resource.Resource):
def getChild(self, path, request):
# represents / on your web interface
return self
class WebInterface(resource.Resource):
isLeaf = True
def render_GET(self, request):
log.msg('GOT a GET request.')
# read request.args if you need to process query args
# ... call some internal service and get output ...
return json.dumps(output)
class SpellingSite(server.Site):
def __init__(self, *args, **kwargs):
self.root = Root()
server.Site.__init__(self, self.root, **kwargs)
self.root.putChild('spell', WebInterface())
And to run it you can use the following skeleton .tac file:
from twisted.application import service, internet
site = SpellingSite()
application = service.Application('WebSpell')
# attach the service to its parent application
service_collection = service.IServiceCollection(application)
internet.TCPServer(PORT, site).setServiceParent(service_collection)
Running your service as another first class service allows you to run it on another machine one day if you find the need - exposing a web interface makes it easy to horizontally scale it behind a reverse proxying load balancer too.
reactor.run() should be called only once in your whole program. Don't think of it as "start this one request I have", think of it as "start all of Twisted".
Running the reactor in a background thread is one way to get around this; then your django application can use blockingCallFromThread in your Django application and use a Twisted API as you would any blocking API. You will need a little bit of cooperation from your WSGI container, though, because you will need to make sure that this background Twisted thread is started and stopped at appropriate times (when your interpreter is initialized and torn down, respectively).
You could also use Twisted as your WSGI container, and then you don't need to start or stop anything special; blockingCallFromThread will just work immediately. See the command-line help for twistd web --wsgi.
You should stop reactor after you got results from Twisted server or some error/timeout happening. So on each Django request that requires query your Twisted server you should run reactor and then stop it. But, it's not supported by Twisted library — reactor is not restartable. Possible solutions:
Use separate thread for Twisted reactor, but you will need to deploy your django app with server, which has support for long running threads (I don't now any of these, but you can write your own easily :-)).
Don't use Twisted for implementing client protocol, just use plain stdlib's socket module.

Categories