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

Add firewall documentation #20

merged 3 commits into from
Sep 16, 2021

Conversation

jkuester
Copy link
Contributor

Adds documentation to the README regarding the required firewall configuration.

Copy link
Contributor

@mrsarm mrsarm left a comment

Choose a reason for hiding this comment

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

Thanks for contributing on this, today I learned how to do some UFW stuff 😄

README.md Outdated
Comment on lines 68 to 73
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.

README.md Show resolved Hide resolved
@mrjones-plip
Copy link
Contributor

Yay! Great to see documentation improvements. I think we should be sure to call out that you need to figure out which subnet your on. In our existing docs, we explicitly state that we assume the user is on 192.168.0.3. I think for these firewall additions in this PR, we should add something like:

Assuming you're in the 192.168.0.0/24 subnet on your LAN, you would blah blah blah

Not at all a blocking request, just and FYI, I was hoping to use the docker0 virtual interface in a UFW rule to avoid needing to specifiy the subnet. I couldn't quite get it to work, but did discover a whole "docker, UFW and the docker0 NIC" world (see here and https://www.techrepublic.com/article/how-to-fix-the-docker-and-ufw-security-flaw/)?!1 What we have is good enough, especially if we limit the source and destinations!

Copy link
Contributor

@mrsarm mrsarm left a comment

Choose a reason for hiding this comment

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

Awesome ! Thanks to this pull request I started to use UFW again 😄

default:
ipam:
config:
- subnet: 172.16.0.0/16
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice ! Going to test in a few minutes ...

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah - nice trick! just docker stop didn't do the trick for mme, but after some harder hitting prune calls, I'm in the right zone \o/

Before:

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

Then with a (likely too heavy handed) prune and rm:

docker system prune&&docker volume prune
docker image rm medicmobile/nginx-local-ip

I'm good to go then! Here's after:

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

> Since local IP addresses can change over time, ranges are used in these rules so that the firewall configuration does not have to be updated each time a new address is assigned.

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

@mrjones-plip mrjones-plip Sep 15, 2021

Choose a reason for hiding this comment

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

I'll "lgtm" the PR as this is minor, but since a lot of people run a different RFC1918 subnet on their LAN (eg 10.10.0.0/24), they'd have to change this. Since they're more likely to have a /24 than a /16 on their local LAN, I'd say go with the /24 instead of the /16.

(Noted that /16 as is, goes up to my LAN's subnet 192.168.68.0/24 - which is quite handy ; )

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since they're more likely to have a /24 than a /16 on their local LAN

@mrjones-plip, am I wrong or wouldn't /16 include all the addresses covered by /24? Maybe I am totally off, but it based on what I was reading I thought that the range covered increases as the mask number decreases (seems very counter-intuitive...).

Copy link
Contributor

Choose a reason for hiding this comment

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

No no! You're totally correct: A /16 covers way more (65k) than a /24 (256), just like that link you cited says. However, a 192.168.0.0/16 won't cover a 10.10.0.0/24. And given few, if any, folks will run a /16 on their LAN, I was just saying that they'd be more familiar and comfortable with changing it to their specific /24 instead of wondering if the /16 covers their range or not. TMI on all three RFC1918 ranges here, but all in there's 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16

Still - this is good as is I think!

Copy link
Contributor

@mrjones-plip mrjones-plip left a comment

Choose a reason for hiding this comment

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

lgtm!

@jkuester jkuester merged commit f7d427f into main Sep 16, 2021
@jkuester jkuester deleted the firewall_doc branch September 16, 2021 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants