I had been using the Python socket module to create a very basic client-server for testing purposes, but soon I wanted to have something slightly more standard, like an HTTP server. I decided to try the Python Flask framework.
First I set up a Flask server on a CentOS 7 Linux VM running on VirtualBox:
# yum install python-pip # pip install Flask # mkdir flask-server && cd flask-server
I created the
hello.py file as described on the Flask homepage:
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!"
Likewise, I started running Flask:
# FLASK_APP=hello.py flask run * Serving Flask app "hello" * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Then I set up port forwarding in VirtualBox on my desktop host so that I could communicate with the virtual machine, using the following settings:
Host IP: 127.0.0.1
Host Port: 9500
Guest IP: 10.0.2.16
Guest Port: 5000
I tested it in a browser (Firefox) on my desktop at
No connection. Firefox endlessly tries to load the file.
I tried from the local machine itself:
# curl http://localhost:5000/ Hello World!
I tried running
tcpdump to see what the network traffic to that port looked like:
# tcpdump -n -i enp0s3 port 5000 ... 14:54:11.938625 IP 10.0.2.2.63923 > 10.0.2.16.commplex-main: Flags [S], seq 3067208705, win 65535, options [mss 1460], length 0 ...
Over and over I saw the same SYN packet from the client host, but the server never replied with a SYN-ACK.
I also noted that the local port was labeled
commplex-main. This label is from
# grep commplex /etc/services commplex-main 5000/tcp # commplex-main 5000/udp # commplex-link 5001/tcp # commplex-link 5001/udp #
I don’t know what
commplex-main is, but since I’m not running anything else on port 5000 other than Flask, it shouldn’t matter.
It turned out there were 2 separate problems:
- Flask was listening only on localhost
- firewalld was blocking the requests from external hosts
To fix the first, run Flask with the host flag:
# FLASK_APP=hello.py flask run --host=0.0.0.0 * Serving Flask app "hello" * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
(This is mentioned in the Flask Quickstart guide, under Externally Visible Server.)
You can also specify an alternative port, e.g.:
# FLASK_APP=hello.py flask run --host=0.0.0.0 --port=56789 * Serving Flask app "hello" * Running on http://0.0.0.0:56789/ (Press CTRL+C to quit)
To fix the latter temporarily, I disabled
systemctl stop firewalld systemctl disable firewalld
Obviously, if you are dealing with a machine connected directly to the Internet, this would be a terrible solution. You’d want to add rules allowing only the hosts and ports from which you expect to receive connections. But for testing communications between my desktop and a virtual host running on it, this seemed like a quick solution.
After those 2 changes, I was able to load the sample “hello” Flask app in a browser: