I'm developing a website using the Python Flask framework and I now do some devving, pushing my changes to a remote dev server. I set this remote dev server up to serve the website publically using app.run(host='0.0.0.0')
.
This works fine, but I just don't want other people to view my website yet. For this reason I somehow want to whitelist my ip so that the dev server only serves the website to my own ip address, giving no response, 404's or some other non-useful response to other ip addresses. I can of course set up the server to use apache or nginx to actually serve the website, but I like the automatic reloading of the website on code changes for devving my website
So does anybody know of a way to do this using the built in Flask dev server? All tips are welcome!
Using just the features of Flask, you could use a before_request()
hook testing the request.remote_addr
attribute :
from flask import abort, request
@app.before_request
def limit_remote_addr():
if request.remote_addr != '10.20.30.40':
abort(403) # Forbidden
but using a firewall rule on the server is probably the safer and more robust option.
Note that the Remote_Addr can be masked if there is a reverse proxy in between the browser and your server; be careful how you limit this and don't lock yourself out. If the proxy lives close to the server itself (like a load balancer or front-end cache), you can inspect the request.access_route
list to access the actual IP address. Do this only if remote_addr
itself is a trusted IP address too :
trusted_proxies = ('42.42.42.42', '82.42.82.42', '127.0.0.1')
def limit_remote_addr():
remote = request.remote_addr
route = list(request.access_route)
while remote in trusted_proxies:
remote = route.pop()
if remote != '10.20.30.40':
abort(403) # Forbidden
This IPTABLES/Netfilter rule will attend your need, dropping all incoming traffic, EXCEPT the traffic originated from your_ip_address
to port 80:
$ /sbin/iptables -A INPUT -s ! your_ip_address --dport 80 -j DROP
Here's something presented on many forums, which allows localhost traffic + external access to your Flask app from your_ip_address
, but reject all traffic from other IP address:
$ /sbin/iptables -A INPUT -i lo -j ACCEPT
$ /sbin/iptables -A INPUT -s your_ip_address --dport 80 -j DROP
$ /sbin/iptables -A INPUT --dport 80 -j REJECT
Although you can easily achieve the expected result via Flask (as pointed out on the elected answer), this kind of issue should be treated at the Network Layer of the Operating System. Considering that you're using a Nix-like OS, you can deny/allow incoming connections using Netfilter via IPTABLES , with rules like these.
Incoming traffic/packets, firstly, they pass through the analysis of the Kernel of your Operating System. To deny/allow traffic, from any source to specific ports, it's a job for the Firewall of the Operating System, on the Network Layer of its Kernel. If you don't have a Firewall running on your server, you should configure it.
Here's a takeaway:
I found this very helpful, but there is an easier way to do this if you have multiple ip address.
trusted_ips = ['42.42.42.42', '82.42.82.42', '127.0.0.1']
@app.before_request
def limit_remote_addr():
if request.remote_addr not in trusted_ips:
abort(404) # Not Found
This will check your trusted ip list and return "404 - Not Found" if the remote ip is not in the list.
You can also block specific ip by changing a few things
bad_ips = ['42.42.42.42', '82.42.82.42', '127.0.0.1']
@app.before_request
def limit_remote_addr():
if request.remote_addr in bad_ips:
abort(404) # Not Found
Same thing but blocks the ips in your bad_ips list
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.