feat: add declarative NFTables NAT config documents#13374
Open
pranav767 wants to merge 1 commit into
Open
Conversation
- Add NATRuleConfigV1Alpha1 document (masquerade/snat/dnat) - Add NATType enum and NfTablesDNATTarget proto message - Implement postrouting (masquerade/SNAT) and prerouting (DNAT) chains - Add unit tests for NAT config marshal/unmarshal/validation Signed-off-by: Pranav Patil <pranavppatil767@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR adds first-class, declarative NAT configuration to Talos by introducing a new machine config document (NetworkNATRuleConfig) and extending the nftables rule/chain plumbing to support masquerade, SNAT, and DNAT via the google/nftables library.
Changes:
- Introduce
NetworkNATRuleConfig(v1alpha1) document + schema/docs and config aggregation (Config.NetworkNATRules()). - Extend
NfTablesRuleAPI/resource model with NAT actions (masquerade,snat,dnat) and new target messages. - Add NAT chain generation in
NfTablesChainConfigController(postrouting for masquerade/SNAT, prerouting for DNAT) and compile NAT actions to nftables expressions.
Reviewed changes
Copilot reviewed 19 out of 25 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| website/content/v1.14/schemas/config.schema.json | Publish updated website JSON schema including NetworkNATRuleConfig. |
| website/content/v1.14/reference/configuration/network/networknatruleconfig.md | Add generated reference page for the new NAT config document with examples. |
| website/content/v1.14/reference/api.md | Update API reference docs to include new NAT-related proto messages/fields. |
| pkg/machinery/resources/network/nftables_chain.go | Extend NfTablesRule with NAT fields; add SNAT/DNAT target structs. |
| pkg/machinery/resources/network/deep_copy.generated.go | Deep-copy support for new SNAT/DNAT target pointers in rules. |
| pkg/machinery/nethelpers/nethelpers.go | Add NATType to enumer generation list. |
| pkg/machinery/nethelpers/nat_type.go | Define NATType enum (masquerade/snat/dnat). |
| pkg/machinery/nethelpers/arpalltargets_enumer.go | Regenerate enumer output to include NATType string/parse helpers. |
| pkg/machinery/config/types/network/yaml_gen_test.go | Add marshal/unmarshal/validate tests for NATRuleConfig documents. |
| pkg/machinery/config/types/network/testdata/natruleconfig.yaml | Golden YAML for masquerade config doc encoding. |
| pkg/machinery/config/types/network/testdata/natruleconfig_snat.yaml | Golden YAML for SNAT config doc encoding. |
| pkg/machinery/config/types/network/testdata/natruleconfig_dnat.yaml | Golden YAML for DNAT config doc encoding. |
| pkg/machinery/config/types/network/network.go | Wire docgen/deep-copy generation to include nat_config.go + NATRuleConfig deep-copy. |
| pkg/machinery/config/types/network/network_doc.go | Add generated doc entries/examples for NATRuleConfig and related structs. |
| pkg/machinery/config/types/network/nat_config.go | Implement NetworkNATRuleConfig document, validation, and accessors. |
| pkg/machinery/config/types/network/deep_copy.generated.go | Add deep-copy implementation for NATRuleConfigV1Alpha1. |
| pkg/machinery/config/schemas/config.schema.json | Update machinery JSON schema to include NetworkNATRuleConfig. |
| pkg/machinery/config/container/container.go | Add Container.NetworkNATRules() aggregator hook. |
| pkg/machinery/config/config/network.go | Add NAT config interfaces + wrapper aggregation helpers. |
| pkg/machinery/config/config/config.go | Extend config.Config interface with NetworkNATRules(). |
| pkg/machinery/api/resource/definitions/network/network.pb.go | Regenerate protobuf Go for new NAT target messages/fields. |
| pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go | Regenerate vtproto code for new NAT target messages/fields. |
| internal/app/machined/pkg/controllers/network/nftables_chain_config.go | Generate NAT base chains and translate NAT config docs into NfTablesChain rules. |
| internal/app/machined/pkg/adapters/network/nftables_rule.go | Compile Masquerade/SNAT/DNAT rule actions into nftables expressions; add address-family helper. |
| api/resource/definitions/network/network.proto | Extend proto definitions for NAT rule fields and SNAT/DNAT target messages. |
Files not reviewed (5)
- pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go: Language not supported
- pkg/machinery/config/types/network/deep_copy.generated.go: Language not supported
- pkg/machinery/config/types/network/network_doc.go: Language not supported
- pkg/machinery/nethelpers/arpalltargets_enumer.go: Language not supported
- pkg/machinery/resources/network/deep_copy.generated.go: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| warnings = append(warnings, "snatPort has no effect on dnat rules") | ||
| } | ||
| default: | ||
| return nil, fmt.Errorf("unknown NAT type %q", s.Type) |
| InputInterface NATInterfaceConfig `yaml:"inputInterface,omitempty"` | ||
| // description: | | ||
| // DestinationAddress restricts which destination addresses are matched. | ||
| // Applies to snat and dnat. |
Comment on lines
+515
to
+519
| if subnets := rule.DestinationSubnets(); len(subnets) > 0 { | ||
| nfRule.MatchDestinationAddress = &network.NfTablesAddressMatch{ | ||
| IncludeSubnets: subnets, | ||
| } | ||
| } |
Comment on lines
+751
to
+754
| if a.NfTablesRule.Masquerade { | ||
| // masquerade: replace source address with the outgoing interface address. | ||
| rulePost = append(rulePost, &expr.Masq{}) | ||
| } |
Comment on lines
+756
to
+760
| if a.NfTablesRule.SNAT != nil { | ||
| target := a.NfTablesRule.SNAT | ||
|
|
||
| addrBin, family, err := nfAddrInfo(target.Address) | ||
| if err != nil { |
Comment on lines
+116
to
+120
| if cfg != nil { | ||
| hasPostrouting, hasDNAT := natRuleTypes(cfg) | ||
|
|
||
| if hasPostrouting { | ||
| if err = safe.WriterModify(ctx, r, network.NewNfTablesChain(network.NamespaceName, PostroutingNATChainName), ctrl.buildPostroutingNATChain(cfg)); err != nil { |
|
This PR is stale because it has been open 45 days with no activity. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
Resolves #12383
What? (description)
This PR involves implementing declarative NAT for talos, Main changes were to update existing resource
NfTablesRulewith all NAT types and updating chain config controller to create bothPostroutingNATChainandPerroutingNATChainon any new resources, having a new NAT rule config document for users to add any NAT type, also implementing NAT on https://github.com/google/nftables/ lib for interacting with linux nftables instructionsWhy? (reasoning)
Provide a declarative(config) way for users to use NAT using nftables
Acceptance
Please use the following checklist:
make conformance)make fmt)make lint)make docs)make unit-tests)This PR might still need more tests, I'll add those if the code seems ok.
I've learned quite a lot from this task both talos internals and nftables.
Just dropping in some references which I used to learn both
https://wiki.nftables.org/wiki-nftables/index.php/Main_Page
https://www.netfilter.org/projects/nftables/manpage.html
https://github.com/google/nftables/
To understand talos i.e. resources & controllers and working of COSI.. I used AI to learn how this fits in (thankfully ingress firewall was already implemented so took a reference to see how chains, rules etc was implemented)
Will write a detailed blog on this 🙂