Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add firewall documentation #20

Merged
merged 3 commits into from
Sep 16, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,17 @@ The server also opens the port 80 so if you forget to write the URL
with https:// , Nginx redirects the request to the HTTPS version
for you 😉.

**Docker note**: A local image is created the first time executed, and
there is no need to rebuild it if you change the Nginx configuration or the `entrypoint.sh` file. Only changes to the Dockerfile script require a rebuild. If you just edit the Nginx configuration, or want to change the ports mapped, only restart the container is needed.
#### Firewall

The HTTP/HTTPS ports (`80`/`443`) and your local webapp port (e.g. `5988`) need to be accessible from the LAN and not blocked by your firewall. If you are using the UFW firewall (in a Linux environment) you can allow traffic on these ports _just from your local LAN_ with the following commands:

```.sh
$ sudo ufw allow proto tcp from 192.168.0.0/24 to any port 80,443,5988
$ sudo ufw allow proto tcp from any to 192.168.0.0/24 port 80,443,5988
```
Copy link
Contributor

@mrsarm mrsarm Sep 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually only the first command is needed, the second one is an alternative if you are OK to let anybody that has access to the LAN enter to the app as well, or the LAN is already protected from outside traffic.

Also worth to mention that the LAN address in the command need to be changed according to the user's network.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkuester my bad, sorry, the 2 instructions are OK, you need both as you have described in the PR, I have confused the last instruction with sudo ufw allow proto tcp from any to any port 80,443,5988 that allows traffic from any host (within the LAN or not) as long as the destination ports are the mentioned in the instructions.

So I would only add a reminder that the network in the example needs to be replaced by the user's network (although most users will figure it out on their own).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so it turns out that I originally misunderstood the syntax of these commands (which is why I thought I needed both).

However, now that I think I have the syntax straight, the mystery deepens. The first rule here does not actually work for me (at least not how I thought it should). If I just have that rule, I still cannot connect even just from a browser running on my local machine. This does not make sense to me since, as I understand it, that rule should allow connections from anyone within my private ip range...

Having just the second rule does work for me, but, as I understand it, that rule is allowing connections from anyone that can reference my machine by its local ip address (so presumably it would just be anyone in my LAN?).

@mrsarm @mrjones-plip do you guys have any thoughts here on what I am missing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right @jkuester , the second instruction is wrong in the sense that may allow hosts from outside the LAN to access the app.

So I went dipper into the rules and I found that for the first rule we don't need to allow traffic to 5988, just 443 (and 80 in case the user don't enter the https:// prefix in the browser so is redirected). For the second rule, we only need to open the traffic from the Docker's network to the app (port 5988), and as far I could learn, all Docker networks by default are under the range 172.16.0.0/16 - 172.20.0.0/16, so the final 2 instruction would be as follow:

sudo ufw allow proto tcp from 192.168.0.0/24 to any port 80,443
sudo ufw allow proto tcp from  172.16.0.0/12 to any port 5988

Does work in my local, but please @jkuester and @mrjones-plip test in your local Linux to be sure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Exactly where I was going to suggest we look at how to do this @mrsarm! I'll test this later today and report back.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And @mrsarm great call on that Docker network. I was stuck thinking all the traffic was happening locally and forgot that traffic coming from inside a Docker container is not going to look like local traffic...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay! really fun to follow along on this one - thanks you two!

I did find that my nginx-local-ip container got an ip of 172.20.0.2 which fell outside of the /16. Not quite sure why though as per the article @jkuester cited, ip addr show docker0|grep 'inet ' agrees that it should have:

ip addr show docker0|grep 'inet '
  inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0

But then again, i have a silly bridge set up on my desktop...so 🤷 . Oh - no, I have no idea now how this is working 🤯

Laptop Ubuntu 20.04:

docker network inspect $(docker network ls | awk '$3 == "bridge" { print $1}') | jq -r '.[] | .Name + " " + .IPAM.Config[0].Subnet' -
bridge 172.17.0.0/16
nginx-local-ip_default 192.168.80.0/20

Desktop Ubuntu 18.04:

docker network inspect $(docker network ls | awk '$3 == "bridge" { print $1}') | jq -r '.[] | .Name + " " + .IPAM.Config[0].Subnet' -
bridge 172.17.0.0/16
nginx-local-ip_default 172.20.0.0/16

I guess just throw another word of caution about "use the right IPs!" kinda thing? Aha! Pardon my rambling comment, but I see now that docker-compose will grab what ever IPs it needs that aren't used. This explains what I'm seeing above.

Separately - am loving the docker status script to keep tabs on containers and IPs and such 😎

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 maybe if you try the previous network address suggested it works: sudo ufw allow proto tcp from 172.16.0.0/12 to any port 5988 , because the 12 bits mask should cover networks from 172.16.0.0 to 172.20.0.0.

If it works for you (did work in my laptop) maybe we can suggest that instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, after reading your responses and thinking on this some more,I am wondering if we can simplify this whole thing with two changes:

  1. Just add config to the docker-compose to force it to use a specific subnet so that we always know which one to allow in the firewall rule...
  2. Switch the rule for 80,443 to use the 192.168.0.0/16 range which (I believe) should cover everything from 192.168.0.0 - 192.168.255.255.

It seems like with these changes, the firewall config should work out-of-the-box for most people. (@mrsarm 's idea of using the 12 bit mask for the docker network range should also work if we would rather not hard-code the subnet in the docker-compose (the only thing that worries me about that is I have not been able to find any official doc yet that guarentees the docker IP addresses will be within 172.16.x.x - 172.20.x.x))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good twist ! I have tested locally and does work. And yes I think the suggestion of changing the mask for the local network is OK too, I actually have a 192.168.0.0/24 LAN in my home while in the coworking space I use to go is 192.168.1.0/24, so the 16 bits mask is suitable for both.


#### Docker note
jkuester marked this conversation as resolved.
Show resolved Hide resolved
A local image is created the first time executed, and there is no need to rebuild it if you change the Nginx configuration or the `entrypoint.sh` file. Only changes to the Dockerfile script require a rebuild. If you just edit the Nginx configuration, or want to change the ports mapped, only restart the container is needed.

If you do need to rebuild the container, append `--build` on to your compose call: ` docker-compose up --build`.

Expand Down