Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Writing a Simple Server

Here are resources for more information about tools covered in this lesson:

00:00 In the previous lesson, I introduced you to HTTPS. In this lesson, I’m going to show you how to build a simple server inside of Flask that tries to hide its content from the spying public.

00:13 Here’s the scenario. You want to put a secret message up on the web, you want members of your club able to view the messages, and you want to make sure that no one else can.

00:24 I’m going to start out by showing you how to build a simple web application using Flask. To do this, you’re going to want to do pip install flask, preferably in a clean virtual environment.

00:36 This is a simple Flask application. The key to it is line 8 and 9. The decorator, called @app.route, registers the "/" path with this function.

00:48 When you hit the Flask server and use / as your path, this method gets called. Whatever’s returned from this method is sent back as the HTTP response. In this case, I’ll be taking the message defined in the global variable message and returning it. Flask has a built-in development server. Generally, you don’t want to use this in production. If you’re just testing something out, you can call app.run(), and you have a web server.

01:17 You’ll recall that the web by default is on port 80. Port 80 is a restricted port. In fact, in most operating systems, any number under 1024 is restricted and you have to have superuser privileges to run on that port. Flask, like most development engines, use a different port for its development server.

01:37 Because I’m trying to hide this message, I’ve changed the default to a different port number, port 5684. So unless the members of our club know to hit this URL on this port, they’re not going to be able to get the message. In the lower window, I’m going to run the application.

01:55 The Flask development server outputs some information to you, reminds you This is a development servernot to use it in production—and tells you that it’s listening to localhost, IP address 127.0.0.1 on port 5684.

02:11 Now, I’m going to use curl to hit that server.

02:17 What comes back is the message shhhh, this is a secret.

02:22 Although I thought I was being very clever by hiding the web server on a nonstandard port, this isn’t real security. In fact, it’s very easy to figure out what processes are listening to what ports on a machine. If you’ve got a Unix-based operating system, such as Linux or Mac OS, or you’re running the Windows Subsystem for Linux on a Windows application, you’ll have access to the lsof command.

02:47 The lsof command will tell you all sorts of information, including what services are connected to what ports, and what ports are being used. If you’re on a pure Windows installation, the netstat command will give you similar sorts of information. lsof and netstat only look at the processes local to the machine, but even if you trust the people who are on your machine, there are other ways to find out what’s running on your box.

03:12 In order for your web server to be available to your friends, it has to be public. This means a port scanner, such as nmap, could find your process across the internet.

03:23 nmap is included in some Linux packages, but is not included with Mac or Windows. In order to use this tool, you’ll need to visit nmap.org and install a binary from there.

03:34 Let me show you how easy it is to find your processes. I’m going to restart the server. Flask is running on localhost port 5684. And in the upper window, I’m going to run the lsof command. lsof stands for list open files. On Unix machines, everything is treated as a file, including sockets.

03:57 The -i parameter here tells the lsof command I’m only interested in those sockets on localhost and not other open files.

04:07 Here are the results. You can see the processes owned by my username, that it’s a Python command, and then it’s listening via TCP on localhost, port 5684.

04:19 Well, there you have it. My secret’s already out.

04:23 This can also be detected through a port scanner on another machine. nmap is such a port scanner. The -A tells nmap to give back some information about the operating system that it discovers on the other side. -p says that I’m only interested in scanning certain ports. In this case, I want to scan for TCP content between ports 5600 and 5700.

04:46 You can scan all ports without a problem—it just takes a while, so I’ve restricted the window here so it doesn’t take as long. And finally, you give it an IP address—in this case, localhost. nmap starts up.

05:00 The key here is it finds port 5684 running HTTP. It’s the Werkzeug httpd (Werkzeug HTTP daemon), which is what Flask runs. It even tells you what version of Python I’m operating. In the lower window, you can see the effects of the port scanner hitting the Flask server.

05:19 There are a whole bunch of requests logged.

05:23 nmap, in order to try and figure out what kind of server’s being run and what information is available, is asking for all sorts of content.

05:33 Most of these are returning 404 because the server doesn’t have them there.

05:47 By looking at this content, nmap can tell you all sorts of information about the server that’s running on the other end. So, running it on port 5684 isn’t really a secret, and isn’t secure.

06:01 If someone ran a port scanner on your box, they’d be able to see that you are listening to 5684. Once they saw that it was a web server, they could then use other tools to look at the content. Network tools such as packet analyzers, allow you to examine the entire exchange between the browser and the server.

06:18 A popular open-source packet analyzer is called Wireshark. It’s available here. Binary packages are available for a variety of operating systems. Linux, Windows, and Mac are all there. Let me show you what you can do with Wireshark.

06:33 This is the first screen on Wireshark. What you’re seeing here is a listing of all the network interfaces on my machine. The Flask server is running on localhost, which is the loopback instance. So, I can select Loopback, and then I can enter a capture filter.

06:50 The capture filter tells Wireshark to capture information only from certain areas—in this case, port 5684.

07:01 This filters content, so you’re only getting a small amount of data at a time—the data that you’re interested in inspecting. When I push Enter, it’ll start capturing what’s on the loopback interface, i.e. localhost on port 5684.

07:18 In a different window on my machine, I’m running Flask. And in another window, I’m about to hit that server with curl. All of this information that shows up in Wireshark is what happened when curl hit the Flask web server on port 5684.

07:34 A lot of information here is stuff that you’re not interested in, so you can filter it by saying you only want HTTP content protocol information in the display. I’ve hit Enter, and now you can see the two pieces of HTTP.

07:50 The first is the GET from curl and the second is the response from the web server.

07:58 Starting with the GET, in the middle window, you can see all the pieces that are put together. Networks can be thought of as a stack of operations.

08:08 This listing here, are the different levels of the stack. In the top layer of the stack is the HTTP protocol. Below that is TCP, below that is IP, and below that is the hardware information.

08:23 By opening up the HTTP content I can see what was sent to the server. GET / using HTTP version 1.1 the Host that was being hit, the User-Agent string, the Accept contents, and then some information.

08:41 In the bottom window, you can see all of the content that was sent up. This is a hex dump of the same information showing up in the middle window. It’s a little hard to read because it’s all jumbled together, but as you can see, you’ve got the GET, the Host, and the agent information, and finally, the Accept header. So, that’s the request.

09:02 How about the response? By clicking on the corresponding response on the top, it changes over. Once again in the middle, you see the different areas of the stack. This time, HTTP response 200 came back, the Content-Type, its length, and the information that came back.

09:20 It shows that there were 22 bytes worth of content that came back from the server. The next layer down can actually show you what was sent. Uh-oh. Our secret isn’t very secret, is it? Once again, inside of the hex space, you can see this broken down byte by byte.

09:39 As you can see, if somebody’s got something like Wireshark running, you are able to see all the contents of what’s happening on the network. An obscure port number is not enough to hide your content from anyone.

09:51 The secret message is actually publicly exposed. When you’re done capturing stuff from Wireshark, you hit the stop button. You now have the option of saving that information to the disc, so that if you wish to inspect it later, you can.

10:05 I think I firmly established that an obscure port number is not enough to keep something secret. In the next lesson, I’ll talk about cryptography and how you can use that to help actually keep your secrets secret.

Become a Member to join the conversation.