mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-18 00:06:38 +00:00
Add forwarding commandline command
This commit is contained in:
90
client/cmd/forwarding_rules.go
Normal file
90
client/cmd/forwarding_rules.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
)
|
||||
|
||||
var forwardingRulesCmd = &cobra.Command{
|
||||
Use: "forwarding",
|
||||
Short: "List forwarding rules",
|
||||
Long: `Commands to list forwarding rules.`,
|
||||
RunE: listForwardingRules,
|
||||
}
|
||||
|
||||
func listForwardingRules(cmd *cobra.Command, _ []string) error {
|
||||
conn, err := getClient(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
client := proto.NewDaemonServiceClient(conn)
|
||||
resp, err := client.ForwardingRules(cmd.Context(), &proto.EmptyRequest{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list network: %v", status.Convert(err).Message())
|
||||
}
|
||||
|
||||
if len(resp.GetRules()) == 0 {
|
||||
cmd.Println("No forwarding rules available.")
|
||||
return nil
|
||||
}
|
||||
|
||||
printForwardingRules(cmd, resp.GetRules())
|
||||
return nil
|
||||
}
|
||||
|
||||
func printForwardingRules(cmd *cobra.Command, rules []*proto.ForwardingRule) {
|
||||
cmd.Println("Available forwarding rules:")
|
||||
|
||||
// Sort rules by translated address
|
||||
sort.Slice(rules, func(i, j int) bool {
|
||||
if rules[i].GetTranslatedAddress() != rules[j].GetTranslatedAddress() {
|
||||
return rules[i].GetTranslatedAddress() < rules[j].GetTranslatedAddress()
|
||||
}
|
||||
if rules[i].GetProtocol() != rules[j].GetProtocol() {
|
||||
return rules[i].GetProtocol() < rules[j].GetProtocol()
|
||||
}
|
||||
|
||||
return getFirstPort(rules[i].GetDestinationPort()) < getFirstPort(rules[j].GetDestinationPort())
|
||||
})
|
||||
|
||||
var lastIP string
|
||||
for _, rule := range rules {
|
||||
dPort := portToString(rule.GetDestinationPort())
|
||||
tPort := portToString(rule.GetTranslatedPort())
|
||||
if lastIP != rule.GetTranslatedAddress() {
|
||||
lastIP = rule.GetTranslatedAddress()
|
||||
cmd.Printf("\nTranslated peer: %s\n", rule.GetTranslatedAddress())
|
||||
}
|
||||
cmd.Printf(" ports (%s): %s to %s\n", strings.ToUpper(rule.GetProtocol()), dPort, tPort)
|
||||
}
|
||||
}
|
||||
|
||||
func getFirstPort(portInfo *proto.PortInfo) int {
|
||||
switch v := portInfo.PortSelection.(type) {
|
||||
case *proto.PortInfo_Port:
|
||||
return int(v.Port)
|
||||
case *proto.PortInfo_Range_:
|
||||
return int(v.Range.GetStart())
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func portToString(translatedPort *proto.PortInfo) string {
|
||||
switch v := translatedPort.PortSelection.(type) {
|
||||
case *proto.PortInfo_Port:
|
||||
return fmt.Sprintf("%d", v.Port)
|
||||
case *proto.PortInfo_Range_:
|
||||
return fmt.Sprintf("%d:%d", v.Range.GetStart(), v.Range.GetEnd())
|
||||
default:
|
||||
return "No port specified"
|
||||
}
|
||||
}
|
||||
@@ -145,6 +145,7 @@ func init() {
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
rootCmd.AddCommand(sshCmd)
|
||||
rootCmd.AddCommand(networksCMD)
|
||||
rootCmd.AddCommand(forwardingRulesCmd)
|
||||
rootCmd.AddCommand(debugCmd)
|
||||
|
||||
serviceCmd.AddCommand(runCmd, startCmd, stopCmd, restartCmd) // service control commands are subcommands of service
|
||||
|
||||
@@ -213,6 +213,15 @@ func (m *Manager) AllowNetbird() error {
|
||||
// Flush doesn't need to be implemented for this manager
|
||||
func (m *Manager) Flush() error { return nil }
|
||||
|
||||
func (m *Manager) AddDNATRule(rule firewall.ForwardRule) (firewall.Rule, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// DeleteDNATRule deletes a DNAT rule
|
||||
func (m *Manager) DeleteDNATRule(rule firewall.Rule) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getConntrackEstablished() []string {
|
||||
return []string{"-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"}
|
||||
}
|
||||
|
||||
@@ -22,5 +22,5 @@ func (r ForwardRule) GetRuleID() string {
|
||||
}
|
||||
|
||||
func (r ForwardRule) String() string {
|
||||
return r.GetRuleID()
|
||||
return fmt.Sprintf("protocol: %s, destinationPort: %s, translatedAddress: %s, translatedPort: %s", r.Protocol, r.DestinationPort.String(), r.TranslatedAddress.String(), r.TranslatedPort.String())
|
||||
}
|
||||
|
||||
@@ -329,6 +329,19 @@ func (m *Manager) Flush() error {
|
||||
return m.aclManager.Flush()
|
||||
}
|
||||
|
||||
// AddDNATRule adds a DNAT rule
|
||||
func (m *Manager) AddDNATRule(rule firewall.ForwardRule) (firewall.Rule, error) {
|
||||
r := &Rule{
|
||||
ruleID: rule.GetRuleID(),
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// DeleteDNATRule deletes a DNAT rule
|
||||
func (m *Manager) DeleteDNATRule(rule firewall.Rule) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) createWorkTable() (*nftables.Table, error) {
|
||||
tables, err := m.rConn.ListTablesOfFamily(nftables.TableFamilyIPv4)
|
||||
if err != nil {
|
||||
|
||||
@@ -253,6 +253,16 @@ func (m *Manager) SetLegacyManagement(isLegacy bool) error {
|
||||
// Flush doesn't need to be implemented for this manager
|
||||
func (m *Manager) Flush() error { return nil }
|
||||
|
||||
// AddDNATRule adds a DNAT rule
|
||||
func (m *Manager) AddDNATRule(rule firewall.ForwardRule) (firewall.Rule, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// DeleteDNATRule deletes a DNAT rule
|
||||
func (m *Manager) DeleteDNATRule(rule firewall.Rule) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DropOutgoing filter outgoing packets
|
||||
func (m *Manager) DropOutgoing(packetData []byte) bool {
|
||||
return m.processOutgoingHooks(packetData)
|
||||
|
||||
@@ -935,7 +935,9 @@ func (e *Engine) updateNetworkMap(networkMap *mgmProto.NetworkMap) error {
|
||||
}
|
||||
|
||||
// Ingress forward rules
|
||||
e.updateForwardRules(networkMap.GetForwardingRules())
|
||||
if err := e.updateForwardRules(networkMap.GetForwardingRules()); err != nil {
|
||||
log.Errorf("failed to update forward rules, err: %v", err)
|
||||
}
|
||||
|
||||
log.Debugf("got peers update from Management Service, total peers to connect to = %d", len(networkMap.GetRemotePeers()))
|
||||
|
||||
@@ -1755,12 +1757,20 @@ func (e *Engine) updateForwardRules(rules []*mgmProto.ForwardingRule) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// todo delete this before merge
|
||||
defer e.mocForwardRules()
|
||||
|
||||
if len(rules) == 0 && e.ingressGatewayMgr != nil {
|
||||
return e.ingressGatewayMgr.Close()
|
||||
err := e.ingressGatewayMgr.Close()
|
||||
e.ingressGatewayMgr = nil
|
||||
e.statusRecorder.SetIngressGwMgr(nil)
|
||||
return err
|
||||
}
|
||||
|
||||
if e.ingressGatewayMgr == nil {
|
||||
e.ingressGatewayMgr = ingressgw.NewManager(e.firewall)
|
||||
mgr := ingressgw.NewManager(e.firewall)
|
||||
e.ingressGatewayMgr = mgr
|
||||
e.statusRecorder.SetIngressGwMgr(mgr)
|
||||
}
|
||||
|
||||
var merr *multierror.Error
|
||||
|
||||
210
client/internal/engine_moc.go
Normal file
210
client/internal/engine_moc.go
Normal file
@@ -0,0 +1,210 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
firewallManager "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
"github.com/netbirdio/netbird/client/internal/ingressgw"
|
||||
)
|
||||
|
||||
func (e *Engine) mocForwardRules() {
|
||||
if e.ingressGatewayMgr == nil {
|
||||
e.ingressGatewayMgr = ingressgw.NewManager(e.firewall)
|
||||
}
|
||||
err := e.ingressGatewayMgr.Update(
|
||||
[]firewallManager.ForwardRule{
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: false, Values: []int{10000}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: false, Values: []int{20000}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10100, 10199}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20100, 20199}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10200, 10299}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20200, 20299}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10300, 10399}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20300, 20399}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10100, 10199}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20100, 20199}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10400, 10499}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20400, 20499}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10500, 10599}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20500, 20599}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10600, 10699}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20600, 20699}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10700, 10799}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20700, 20799}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10800, 10899}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20800, 20899}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{10900, 10999}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{20900, 20999}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11000, 11099}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21000, 21099}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11100, 11199}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21100, 21199}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11200, 11299}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21200, 21299}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11300, 11399}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21300, 21399}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11400, 11499}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21400, 21499}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11500, 11599}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21500, 21599}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11600, 11699}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21600, 21699}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11700, 11799}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21700, 21799}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11800, 11899}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21800, 21899}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{11900, 11999}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{21900, 21999}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12000, 12099}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22000, 22099}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12100, 12199}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22100, 22199}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12200, 12299}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22200, 22299}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12300, 12399}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22300, 22399}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12400, 12499}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22400, 22499}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12500, 12599}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22500, 22599}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12600, 12699}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22600, 22699}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12700, 12799}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22700, 22799}},
|
||||
},
|
||||
{
|
||||
Protocol: "tcp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12800, 12899}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.31.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22800, 22899}},
|
||||
},
|
||||
{
|
||||
Protocol: "udp",
|
||||
DestinationPort: firewallManager.Port{IsRange: true, Values: []int{12900, 12999}},
|
||||
TranslatedAddress: netip.MustParseAddr("100.64.10.206"),
|
||||
TranslatedPort: firewallManager.Port{IsRange: true, Values: []int{22900, 22999}},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("failed to update forwarding rules: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -2,65 +2,97 @@ package ingressgw
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
nberrors "github.com/netbirdio/netbird/client/errors"
|
||||
firewallManager "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
)
|
||||
|
||||
type RulePair struct {
|
||||
firewallManager.ForwardRule
|
||||
firewallManager.Rule
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
firewallManager firewallManager.Manager
|
||||
|
||||
fwRules map[string]firewallManager.Rule
|
||||
rules map[string]RulePair // keys is the ID of the ForwardRule
|
||||
rulesMu sync.Mutex
|
||||
}
|
||||
|
||||
func NewManager(firewall firewallManager.Manager) *Manager {
|
||||
return &Manager{
|
||||
firewallManager: firewall,
|
||||
fwRules: make(map[string]firewallManager.Rule),
|
||||
rules: make(map[string]RulePair),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Manager) Update(forwardRules []firewallManager.ForwardRule) error {
|
||||
h.rulesMu.Lock()
|
||||
defer h.rulesMu.Unlock()
|
||||
|
||||
var mErr *multierror.Error
|
||||
toDelete := make(map[string]firewallManager.Rule)
|
||||
for id, r := range h.fwRules {
|
||||
toDelete := make(map[string]RulePair)
|
||||
for id, r := range h.rules {
|
||||
toDelete[id] = r
|
||||
}
|
||||
|
||||
// Process new/updated rules
|
||||
for _, rule := range forwardRules {
|
||||
id := rule.GetRuleID()
|
||||
if _, ok := h.fwRules[id]; ok {
|
||||
for _, fwdRule := range forwardRules {
|
||||
id := fwdRule.GetRuleID()
|
||||
if _, ok := h.rules[id]; ok {
|
||||
delete(toDelete, id)
|
||||
continue
|
||||
}
|
||||
|
||||
rule, err := h.firewallManager.AddDNATRule(rule)
|
||||
rule, err := h.firewallManager.AddDNATRule(fwdRule)
|
||||
if err != nil {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("failed to add forward rule '%s': %v", rule, err))
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("failed to add forward rule '%s': %v", fwdRule.String(), err))
|
||||
continue
|
||||
}
|
||||
h.fwRules[id] = rule
|
||||
log.Infof("added forward rule '%s'", fwdRule)
|
||||
h.rules[id] = RulePair{
|
||||
ForwardRule: fwdRule,
|
||||
Rule: rule,
|
||||
}
|
||||
}
|
||||
|
||||
// Remove deleted rules
|
||||
for id, rule := range toDelete {
|
||||
if err := h.firewallManager.DeleteDNATRule(rule); err != nil {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete forward rule '%s': %v", rule, err))
|
||||
for id, rulePair := range toDelete {
|
||||
if err := h.firewallManager.DeleteDNATRule(rulePair.Rule); err != nil {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete forward rule '%s': %v", rulePair.ForwardRule.String(), err))
|
||||
}
|
||||
delete(h.fwRules, id)
|
||||
delete(h.rules, id)
|
||||
}
|
||||
|
||||
return nberrors.FormatErrorOrNil(mErr)
|
||||
}
|
||||
|
||||
func (h *Manager) Close() error {
|
||||
h.rulesMu.Lock()
|
||||
defer h.rulesMu.Unlock()
|
||||
|
||||
log.Infof("clean up all forward rules (%d)", len(h.rules))
|
||||
var mErr *multierror.Error
|
||||
for _, rule := range h.fwRules {
|
||||
if err := h.firewallManager.DeleteDNATRule(rule); err != nil {
|
||||
for _, rule := range h.rules {
|
||||
if err := h.firewallManager.DeleteDNATRule(rule.Rule); err != nil {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete forward rule '%s': %v", rule, err))
|
||||
}
|
||||
}
|
||||
return nberrors.FormatErrorOrNil(mErr)
|
||||
}
|
||||
|
||||
func (h *Manager) Rules() []firewallManager.ForwardRule {
|
||||
h.rulesMu.Lock()
|
||||
defer h.rulesMu.Unlock()
|
||||
|
||||
rules := make([]firewallManager.ForwardRule, 0, len(h.rules))
|
||||
for _, rulePair := range h.rules {
|
||||
rules = append(rules, rulePair.ForwardRule)
|
||||
}
|
||||
|
||||
return rules
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
gstatus "google.golang.org/grpc/status"
|
||||
|
||||
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
"github.com/netbirdio/netbird/client/iface/configurer"
|
||||
"github.com/netbirdio/netbird/client/internal/ingressgw"
|
||||
"github.com/netbirdio/netbird/client/internal/relay"
|
||||
"github.com/netbirdio/netbird/management/domain"
|
||||
relayClient "github.com/netbirdio/netbird/relay/client"
|
||||
@@ -157,6 +159,8 @@ type Status struct {
|
||||
peerListChangedForNotification bool
|
||||
|
||||
relayMgr *relayClient.Manager
|
||||
|
||||
ingressGwMgr *ingressgw.Manager
|
||||
}
|
||||
|
||||
// NewRecorder returns a new Status instance
|
||||
@@ -177,6 +181,12 @@ func (d *Status) SetRelayMgr(manager *relayClient.Manager) {
|
||||
d.relayMgr = manager
|
||||
}
|
||||
|
||||
func (d *Status) SetIngressGwMgr(ingressGwMgr *ingressgw.Manager) {
|
||||
d.mux.Lock()
|
||||
defer d.mux.Unlock()
|
||||
d.ingressGwMgr = ingressGwMgr
|
||||
}
|
||||
|
||||
// ReplaceOfflinePeers replaces
|
||||
func (d *Status) ReplaceOfflinePeers(replacement []State) {
|
||||
d.mux.Lock()
|
||||
@@ -718,6 +728,16 @@ func (d *Status) GetRelayStates() []relay.ProbeResult {
|
||||
return append(relayStates, relayState)
|
||||
}
|
||||
|
||||
func (d *Status) ForwardingRules() []firewall.ForwardRule {
|
||||
d.mux.Lock()
|
||||
defer d.mux.Unlock()
|
||||
if d.ingressGwMgr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return d.ingressGwMgr.Rules()
|
||||
}
|
||||
|
||||
func (d *Status) GetDNSStates() []NSGroupState {
|
||||
d.mux.Lock()
|
||||
defer d.mux.Unlock()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,8 @@ option go_package = "/proto";
|
||||
|
||||
package daemon;
|
||||
|
||||
message EmptyRequest {}
|
||||
|
||||
service DaemonService {
|
||||
// Login uses setup key to prepare configuration for the daemon.
|
||||
rpc Login(LoginRequest) returns (LoginResponse) {}
|
||||
@@ -37,6 +39,8 @@ service DaemonService {
|
||||
// Deselect specific routes
|
||||
rpc DeselectNetworks(SelectNetworksRequest) returns (SelectNetworksResponse) {}
|
||||
|
||||
rpc ForwardingRules(EmptyRequest) returns (ForwardingRulesResponse) {}
|
||||
|
||||
// DebugBundle creates a debug bundle
|
||||
rpc DebugBundle(DebugBundleRequest) returns (DebugBundleResponse) {}
|
||||
|
||||
@@ -251,6 +255,7 @@ message FullStatus {
|
||||
repeated NSGroupState dns_servers = 6;
|
||||
}
|
||||
|
||||
// Networks
|
||||
message ListNetworksRequest {
|
||||
}
|
||||
|
||||
@@ -271,7 +276,6 @@ message IPList {
|
||||
repeated string ips = 1;
|
||||
}
|
||||
|
||||
|
||||
message Network {
|
||||
string ID = 1;
|
||||
string range = 2;
|
||||
@@ -280,6 +284,32 @@ message Network {
|
||||
map<string, IPList> resolvedIPs = 5;
|
||||
}
|
||||
|
||||
// ForwardingRules
|
||||
message PortInfo {
|
||||
oneof portSelection {
|
||||
uint32 port = 1;
|
||||
Range range = 2;
|
||||
}
|
||||
|
||||
message Range {
|
||||
uint32 start = 1;
|
||||
uint32 end = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message ForwardingRule {
|
||||
string protocol = 1;
|
||||
PortInfo destinationPort = 2;
|
||||
string translatedAddress = 3;
|
||||
PortInfo translatedPort = 4;
|
||||
}
|
||||
|
||||
message ForwardingRulesResponse {
|
||||
repeated ForwardingRule rules = 1;
|
||||
}
|
||||
|
||||
|
||||
// DebugBundler
|
||||
message DebugBundleRequest {
|
||||
bool anonymize = 1;
|
||||
string status = 2;
|
||||
|
||||
@@ -37,6 +37,7 @@ type DaemonServiceClient interface {
|
||||
SelectNetworks(ctx context.Context, in *SelectNetworksRequest, opts ...grpc.CallOption) (*SelectNetworksResponse, error)
|
||||
// Deselect specific routes
|
||||
DeselectNetworks(ctx context.Context, in *SelectNetworksRequest, opts ...grpc.CallOption) (*SelectNetworksResponse, error)
|
||||
ForwardingRules(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*ForwardingRulesResponse, error)
|
||||
// DebugBundle creates a debug bundle
|
||||
DebugBundle(ctx context.Context, in *DebugBundleRequest, opts ...grpc.CallOption) (*DebugBundleResponse, error)
|
||||
// GetLogLevel gets the log level of the daemon
|
||||
@@ -142,6 +143,15 @@ func (c *daemonServiceClient) DeselectNetworks(ctx context.Context, in *SelectNe
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *daemonServiceClient) ForwardingRules(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*ForwardingRulesResponse, error) {
|
||||
out := new(ForwardingRulesResponse)
|
||||
err := c.cc.Invoke(ctx, "/daemon.DaemonService/ForwardingRules", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *daemonServiceClient) DebugBundle(ctx context.Context, in *DebugBundleRequest, opts ...grpc.CallOption) (*DebugBundleResponse, error) {
|
||||
out := new(DebugBundleResponse)
|
||||
err := c.cc.Invoke(ctx, "/daemon.DaemonService/DebugBundle", in, out, opts...)
|
||||
@@ -228,6 +238,7 @@ type DaemonServiceServer interface {
|
||||
SelectNetworks(context.Context, *SelectNetworksRequest) (*SelectNetworksResponse, error)
|
||||
// Deselect specific routes
|
||||
DeselectNetworks(context.Context, *SelectNetworksRequest) (*SelectNetworksResponse, error)
|
||||
ForwardingRules(context.Context, *EmptyRequest) (*ForwardingRulesResponse, error)
|
||||
// DebugBundle creates a debug bundle
|
||||
DebugBundle(context.Context, *DebugBundleRequest) (*DebugBundleResponse, error)
|
||||
// GetLogLevel gets the log level of the daemon
|
||||
@@ -276,6 +287,9 @@ func (UnimplementedDaemonServiceServer) SelectNetworks(context.Context, *SelectN
|
||||
func (UnimplementedDaemonServiceServer) DeselectNetworks(context.Context, *SelectNetworksRequest) (*SelectNetworksResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeselectNetworks not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) ForwardingRules(context.Context, *EmptyRequest) (*ForwardingRulesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ForwardingRules not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) DebugBundle(context.Context, *DebugBundleRequest) (*DebugBundleResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DebugBundle not implemented")
|
||||
}
|
||||
@@ -472,6 +486,24 @@ func _DaemonService_DeselectNetworks_Handler(srv interface{}, ctx context.Contex
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DaemonService_ForwardingRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(EmptyRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DaemonServiceServer).ForwardingRules(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/daemon.DaemonService/ForwardingRules",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DaemonServiceServer).ForwardingRules(ctx, req.(*EmptyRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DaemonService_DebugBundle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DebugBundleRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -641,6 +673,10 @@ var DaemonService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "DeselectNetworks",
|
||||
Handler: _DaemonService_DeselectNetworks_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ForwardingRules",
|
||||
Handler: _DaemonService_ForwardingRules_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DebugBundle",
|
||||
Handler: _DaemonService_DebugBundle_Handler,
|
||||
|
||||
46
client/server/forwardingrules.go
Normal file
46
client/server/forwardingrules.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
)
|
||||
|
||||
func (s *Server) ForwardingRules(context.Context, *proto.EmptyRequest) (*proto.ForwardingRulesResponse, error) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
rules := s.statusRecorder.ForwardingRules()
|
||||
|
||||
responseRules := make([]*proto.ForwardingRule, 0, len(rules))
|
||||
for _, rule := range rules {
|
||||
|
||||
respRule := &proto.ForwardingRule{
|
||||
Protocol: string(rule.Protocol),
|
||||
DestinationPort: portToProto(rule.DestinationPort),
|
||||
TranslatedAddress: rule.TranslatedAddress.String(),
|
||||
TranslatedPort: portToProto(rule.TranslatedPort),
|
||||
}
|
||||
responseRules = append(responseRules, respRule)
|
||||
|
||||
}
|
||||
|
||||
return &proto.ForwardingRulesResponse{Rules: responseRules}, nil
|
||||
}
|
||||
|
||||
func portToProto(port firewall.Port) *proto.PortInfo {
|
||||
var portInfo proto.PortInfo
|
||||
|
||||
if !port.IsRange {
|
||||
portInfo.PortSelection = &proto.PortInfo_Port{Port: uint32(port.Values[0])}
|
||||
} else {
|
||||
portInfo.PortSelection = &proto.PortInfo_Range_{
|
||||
Range: &proto.PortInfo_Range{
|
||||
Start: uint32(port.Values[0]),
|
||||
End: uint32(port.Values[1]),
|
||||
},
|
||||
}
|
||||
}
|
||||
return &portInfo
|
||||
}
|
||||
Reference in New Issue
Block a user