Sample webserver is not accessible on external ip of GCP VM - google-cloud-platform

I have created a sample webserver using python in GCP VM Using below code.
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
hostName = "localhost"
serverPort = 5500
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
print("Server started http://%s:%s" % (hostName, serverPort))
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
I can access this server on the VM using the command.
user#instance1:~$ curl http://localhost:5500
<html><head><title>https://pythonbasics.org</title></head><p>Request: /</p><body><p>This is an example web server.</p></body></html>
I have created a firewall rule to allow access from all source ips. But not able to access using external ip. I have also tried from external browser.
Firewall rule screen. Allow HTTP(S).Here the external ip is 34.122.198.62
user#instance1:~$ curl http://34.122.198.62:5500/
curl: (7) Failed to connect to 34.122.198.62 port 5500: Connection refused
Could you please help in resolve the issue? Thank you in advance

Running the server with python3 manage.py runserver 0.0.0.0:8000 resolved the issue.

Related

Troubleshooting access to Flask app in Vagrant guest

I have a toy Flask app:
from flask import Flask
app = Flask(__name__)
#app.route("/home")
def home():
return "<h1>Home...</h1>"
#app.route("/health")
def health():
return "<h1>Healthy</h1>"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
.. which is being provisioned using Ansible on a Vagrant guest machine with the following Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "geerlingguy/centos7"
config.vm.provision "ansible_local" do |ansible|
ansible.playbook = "playbooks/run.yml"
ansible.tags = "install"
end
config.vm.network "forwarded_port", guest: 5000, host: 5000
config.vm.provider "virtualbox" do |v|
v.memory = 2048
v.cpus = 1
end
end
If I vagrant ssh to the guest and launch the flaskapp in with the following:
export FLASK_APP='/flaskapp/app.py'
export FLASK_ENV='development'
cd /flaskapp
python3 -m flask run
I can curl 127.0.0.1:5000/home with a successful response.
However from the Vagrant host (i.e. not the guest where the flask app is running), I cannot access http://localhost:5000/home. Accessing localhost:5000/home (or 127.0.0.1:500/home) is:
The connection was reset
The connection to the server was reset while the page was loading.
The site could be temporarily unavailable or too busy. Try again in a few moments.
If you are unable to load any pages, check your computer’s network connection.
If your computer or network is protected by a firewall or proxy, make sure that Firefox is permitted to access the Web.
I'm using Windows 10, and the guest VMs network config looks like this:
I have tried assigning static ip or assigning an ip dynamically but I cannot access. I am not sure if it's something that I need to add to the /etc/hosts file...
Can anyone help to identify the issue here and how can I debug this kind of problem?

Connect to RabbitMQ instance remotely (created on AWS)

I'm having trouble connecting to a RabbitMQ instance (it's my first time doing so). I've spun one up on AWS, and been given access to an admin panel which I'm able to access.
I'm trying to connect to the RabbitMQ server in python/pika with the following code:
import pika
import logging
logging.basicConfig(level=logging.DEBUG)
credentials = pika.PlainCredentials('*******', '**********')
parameters = pika.ConnectionParameters(host='a-25c34e4d-a3eb-32de-abfg-l95d931afc72f.mq.us-west-1.amazonaws.com',
port=5671,
virtual_host='/',
credentials=credentials,
)
connection = pika.BlockingConnection(parameters)
I get pika.exceptions.IncompatibleProtocolError: StreamLostError: ("Stream connection lost: ConnectionResetError(54, 'Connection reset by peer')",) when I run the above.
you're trying to connect through AMQP protocol and AWS is using AMQPS, you should add ssl_options to your connection parameters like this
import ssl
logging.basicConfig(level=logging.DEBUG)
credentials = pika.PlainCredentials('*******', '**********')
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
parameters = pika.ConnectionParameters(host='a-25c34e4d-a3eb-32de-abfg-l95d931afc72f.mq.us-west-1.amazonaws.com',
port=5671,
virtual_host='/',
credentials=credentials,
ssl_options=pika.SSLOptions(context)
)
connection = pika.BlockingConnection(parameters)

SSL EOF Error when using Python Requests Session

Summary
I have a flask application deployed to Kubernetes with python 2.7.12, Flask 0.12.2 and using requests library. I'm getting a SSLError while using requests.session to send a POST Request inside the container. When using requests sessions to connect to a https url , requests throws a SSLError
Some background
I have not added any certificates
The project works when I run a docker image locally but after deployment to kubernetes, from inside the container - the post request is not being sent to the url
verify=false does not work either
System Info - What I am using:
Python 2.7.12, Flask==0.12.2, Kubernetes, python-requests-2.18.4
Expected Result
Get HTTP Response code 200 after sending a POST request
Error Logs
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 511, in send
raise SSLError(e, request=request)
SSLError: HTTPSConnectionPool(host='dev.domain.nl', port=443): Max retries exceeded with url: /ingestion?LrnDevEui=0059AC0000152A03&LrnFPort=1&LrnInfos=TWA_100006356.873.AS-1-135680630&AS_ID=testserver&Time=2018-06-22T11%3A41%3A08.163%2B02%3A00&Token=1765b08354dfdec (Caused by SSLError(SSLEOFError(8, u'EOF occurred in violation of protocol (_ssl.c:661)'),))
/usr/local/lib/python2.7/site-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
Reproduction Steps
import requests
from flask import Flask, request, jsonify
from requests import Request, Session
sess = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries = 200)
sess.mount('http://', adapter)
sess.mount('https://', adapter)
sess.cert ='/usr/local/lib/python2.7/site-packages/certifi/cacert.pem'
def test_post():
url = 'https://dev.domain.nl/ingestion/?'
header = {'Content-Type': 'application/json', 'Accept': 'application/json'}
response = sess.post(url, headers= header, params= somepara, data= json.dumps(data),verify=True)
print response.status_code
return response.status_code
def main():
threading.Timer(10.0, main).start()
test_post()
if __name__ == '__main__':
main()
app.run(host="0.0.0.0", debug=True, port=5001, threaded=True)
Docker File
FROM python:2.7-alpine
COPY ./web /web
WORKDIR /web
RUN pip install -r requirements.txt
ENV FLASK_APP app.py
EXPOSE 5001
EXPOSE 443
CMD ["python", "app.py"]
The problem may be in the Alpine Docker image that lacks CA certificates. On your laptop code works as it uses CA certs from you local workstation. I would think that running Docker image locally will fail too - so the problem is not k8s.
Try to add the following line to the Dockerfile:
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
It will install CA certs inside the container.

Connect to secure web servive with pfx certificate using python

Hi i need help to get info from web service on secure site with pfx certificate with password.
i tried more then one example..
code example:
import requests
wsdl_url = 'blabla'
requests.get(wsdl_url, cert='cert.pfx', verify=True)
other example:
import urllib3
import certifi
wsdl_url = 'blabla'
http = urllib3.PoolManager(
cert_reqs='CERT_REQUIRED', # Force certificate check.
ca_certs=certifi.where() # Path to the Certifi bundle.
)
certifi.where()
# You're ready to make verified HTTPS requests.
try:
r = http.request('GET', wsdl_url)
print r
except urllib3.exceptions.SSLError as e:
print "wrong"
# Handle incorrect certificate error.
Error type:
connection aborted
an existing connection was forcibly closed by the remote host
help please

How can i get the running server URL

When i run the server it shows me a message http://127.0.0.1:8000/. I want to get the url in code. I dont have request object there.
request.build_absolute_uri('/')
or you could try
import socket
socket.gethostbyname(socket.gethostname())
With Django docs here, You can use:
domain = request.get_host()
# domain = 'localhost:8000'
If you want to know exactly the IP address that the development server is started with, you can use sys.argv for this. The Django development server uses the same trick internally to restart the development server with the same arguments
Start development server:
manage.py runserver 127.0.0.1:8000
Get address in code:
if settings.DEBUG:
import sys
print sys.argv[-1]
This prints 127.0.0.1:8000
import socket
host = socket.gethostname()
import re
import subprocess
def get_ip_machine():
process = subprocess.Popen(['ifconfig'], stdout=subprocess.PIPE)
ip_regex = re.compile('(((1?[0-9]{1,2})|(2[0-4]\d)|(25[0-5]))\.){3}((1?[0-9]{1,2})|(2[0-4]\d)|(25[0-5]))')
return ip_regex.search(process.stdout.read(), re.MULTILINE).group()