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

Firewall: Add support for arbitrary rules for input, output and forward #12940

Conversation

kampfschlaefer
Copy link
Contributor

@kampfschlaefer kampfschlaefer commented Feb 11, 2016

This extends the firewall to support arbitrary rules for the INPUT, OUTPUT and
FORWARD chains. All the rules are placed in nixos-fw-[input|output|forward]
chains. It also adds support to define the default policies of the chains.

Logging works as special target. When hits for a rule should be logged, this
rule has to be defined twice, once with the LOG target and once with the actual
action. Or you just rely on logRejectedPackets.

The old nixos-fw chain is deleted first. This is only really needed when
switching to this new feature-branch and activiting the config the first time.
But for this one case its needed as otherwise the accept and refuse chains
can't be deleted. Also delete the invalid chain to allow reload to work.

For debugging its now possible to run only the ipv6 tests or only the ipv4
tests. Maybe this should even be extracted into a parameter before including
this in nixos.

@mention-bot
Copy link

By analyzing the blame information on this pull request, we identified @wkennington, @edolstra and @bluescreen303 to be potential reviewers

@fpletz
Copy link
Member

fpletz commented Feb 12, 2016

Thanks a lot for this! I'm willing to review & test this soon if nobody beats me to it.

default = null;
type = types.nullOr (
types.addCheck types.str (
v: v == "ACCEPT" || v == "DROP" || v == "REJECT"
Copy link
Member

Choose a reason for hiding this comment

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

why not an enum here? Also, isn't LOG an option sometimes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, enum sounds like the word I didn't remember when writing this ;-)

LOG would be the action to just log, nothing else, right?

Also I think having DROP and REJECT both could be seen as superfluous as the actual action depends on the global rejectPackets option. (Current difference between DROP and REJECT is that the first sends to nixos-fw-refuse while the later sends to nixos-fw-log-refuse.
Maybe these choices here shouldn't be these abstract names but the real chain names (without the nixos-fw-prefix)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@copumpkin

Also, isn't LOG an option sometimes?

What would you think is better:

rule = [
  { fromInterface = "eth0"; target = "LOG"; log-prefix="bla: "; log-level = "info"; }
  { fromInterface = "eth0"; target = "ACCEPT"; }
];

with two rule-entries to explicitly LOG and ACCEPT the connection/packet? Or

rule = [
  { fromInterface = "eth0"; target = "ACCEPT"; log-prefix="bla: "; log-level = "info"; }
];

to have one rule-entry and create two iptables rules with log and accept implicit. Is there a need for logging without any special ACCEPT/DROP/REJECT handling?

@abbradar
Copy link
Member

I vote for transparent conversion of allowed ports into rules -- I like them for simplicity (and no need for one to understand iptables).

@kampfschlaefer kampfschlaefer changed the base branch from release-15.09 to master September 28, 2016 11:58
@kampfschlaefer kampfschlaefer force-pushed the feature/improve_firewalling branch 2 times, most recently from 29a3f5d to 4316c21 Compare September 29, 2016 15:15
@kampfschlaefer kampfschlaefer changed the title [WIP, RFC] Firewall: Add support for rules for input, output and forward Firewall: Add support for arbitrary rules for input, output and forward Sep 29, 2016
@Mic92
Copy link
Member

Mic92 commented Oct 20, 2016

(triage)

@spacekitteh
Copy link
Contributor

@grahamc security

This extends the firewall to support arbitrary rules for the INPUT, OUTPUT and
FORWARD chains. All the rules are placed in nixos-fw-[input|output|forward]
chains. It also adds support to define the default policies of the chains.

Logging works as special target. When hits for a rule should be logged, this
rule has to be defined twice, once with the LOG target and once with the actual
action. Or you just rely on logRejectedPackets.

The old nixos-fw chain is deleted first. This is only really needed when
switching to this new feature-branch and activiting the config the first time.
But for this one case its needed as otherwise the accept and refuse chains
can't be deleted. Also delete the invalid chain to allow reload to work.

For debugging its now possible to run only the ipv6 tests or only the ipv4
tests. Maybe this should even be extracted into a parameter before including
this in nixos.
Copy link
Member

@primeos primeos left a comment

Choose a reason for hiding this comment

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

Hey, thank you very much for the PR, it contains some awesome stuff (imho) 😄

However, imho it's a bit too late to get this right for 17.3 and would suggest to aim for 17.9 instead (unfortunately at least I don't have the time for a proper review atm and it's a pretty complex change anyway).

There is also an issue (and PR as I just noticed) for switching to nftables and I'd personally aim for creating an abstraction layer (should require nixifying the rules, but even that's probably not enough...) so that we can use iptables, nftables, etc. as "back-ends" (I'll probably create an issue for that, but that has to wait for at least one weak as I don't have the time atm).

(Please note that the review is incomplete, just wanted to note some stuff until I or someone else has the time to do a proper review.)

FORWARD = "nixos-fw-forward";
PREROUTING = "PREROUTING";
POSTROUTING = "POSTROUTING";
};
Copy link
Member

Choose a reason for hiding this comment

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

It would be great if you could document these new rules at the beginning of the file.

getTargetForPolicy = policy:
if policy == "ACCEPT"
then "nixos-fw-accept"
else "nixos-fw-refuse";
Copy link
Member

Choose a reason for hiding this comment

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

This seems a bit odd (without looking at the rest). If I hear policy I'd expect the following:

Only built-in (non-user-defined) chains can have policies, and neither built-in nor user-defined chains can be policy targets.

ip46tables -D INPUT -j nixos-fw-input 2> /dev/null || true
ip46tables -D OUTPUT -j nixos-fw-output 2> /dev/null || true
ip46tables -D FORWARD -j nixos-fw-forward 2> /dev/null || true
for chain in nixos-fw nixos-fw-accept nixos-fw-input nixos-fw-output nixos-fw-forward nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse __invalid_chain__ FW_REFUSE; do
Copy link
Member

Choose a reason for hiding this comment

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

  • nixos-fw-accept appears twice
  • You can drop FW_REFUSE (see 460b43d (was after your PR))
  • I don't really like the following name: __invalid_chain__ (that's just my personal opinion tho)

# Accept packets from established or related connections.
ip46tables -A nixos-fw-input -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept
ip46tables -A nixos-fw-forward -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept
ip46tables -A nixos-fw-output -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept
Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't touch forward by default (probably set the policy to DROP - but that could break some setups).

I assume new connections are handled below, if not we need the connection state NEW as well.

input = mkOption {
default = "DROP";
type = types.enum targetTypes;
description = "";
Copy link
Member

Choose a reason for hiding this comment

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

An empty description seems a bit odd, even if we probably don't need it.

'';
};

networking.firewall.rules = mkOption {
Copy link
Member

Choose a reason for hiding this comment

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

Nixifying the FW rules seems like a great idea (imho).
However #22586 does that as well (IIRC), i.e. we have to compare/merge them.

@ocharles
Copy link
Contributor

As this has been open for a year (and @kampfschlaefer would certainly like at least a resolution on this PR), ccould we put it in the 17.09 milestone?

@primeos
Copy link
Member

primeos commented Feb 26, 2017

Please don't merge this - it conflict's with #22586 and there hasn't been any discussion yet!

Just wanted to make sure anyone is aware of this as I can't see how we (currently) can merge them both. I encourage anyone to compare them and decide which one we use (or we could probably use parts from both). I don't really have much time ATM but I created the following issue to share some of my thought/ideas: #23181

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.