Skip to content

Commit 64f202f

Browse files
authored
Make 0.0.0.0/0 and ::/0 not mean any address family, add any for that (#1538)
1 parent 6d7cf61 commit 64f202f

File tree

3 files changed

+165
-113
lines changed

3 files changed

+165
-113
lines changed

examples/config.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,9 @@ firewall:
383383
# host: `any` or a literal hostname, ie `test-host`
384384
# group: `any` or a literal group name, ie `default-group`
385385
# groups: Same as group but accepts a list of values. Multiple values are AND'd together and a certificate would have to contain all groups to pass
386-
# cidr: a remote CIDR, `0.0.0.0/0` is any ipv4 and `::/0` is any ipv6.
387-
# local_cidr: a local CIDR, `0.0.0.0/0` is any ipv4 and `::/0` is any ipv6. This can be used to filter destinations when using unsafe_routes.
386+
# cidr: a remote CIDR, `0.0.0.0/0` is any ipv4 and `::/0` is any ipv6. `any` means any ip family and address.
387+
# local_cidr: a local CIDR, `0.0.0.0/0` is any ipv4 and `::/0` is any ipv6. `any` means any ip family and address.
388+
# This can be used to filter destinations when using unsafe_routes.
388389
# By default, this is set to only the VPN (overlay) networks assigned via the certificate networks field unless `default_local_cidr_any` is set to true.
389390
# If there are unsafe_routes present in this config file, `local_cidr` should be set appropriately for the intended us case.
390391
# ca_name: An issuing CA name

firewall.go

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
)
2424

2525
type FirewallInterface interface {
26-
AddRule(incoming bool, proto uint8, startPort int32, endPort int32, groups []string, host string, addr, localAddr netip.Prefix, caName string, caSha string) error
26+
AddRule(incoming bool, proto uint8, startPort int32, endPort int32, groups []string, host string, cidr, localCidr string, caName string, caSha string) error
2727
}
2828

2929
type conn struct {
@@ -248,30 +248,19 @@ func NewFirewallFromConfig(l *logrus.Logger, cs *CertState, c *config.C) (*Firew
248248
}
249249

250250
// AddRule properly creates the in memory rule structure for a firewall table.
251-
func (f *Firewall) AddRule(incoming bool, proto uint8, startPort int32, endPort int32, groups []string, host string, ip, localIp netip.Prefix, caName string, caSha string) error {
252-
// Under gomobile, stringing a nil pointer with fmt causes an abort in debug mode for iOS
253-
// https://github.com/golang/go/issues/14131
254-
sIp := ""
255-
if ip.IsValid() {
256-
sIp = ip.String()
257-
}
258-
lIp := ""
259-
if localIp.IsValid() {
260-
lIp = localIp.String()
261-
}
262-
251+
func (f *Firewall) AddRule(incoming bool, proto uint8, startPort int32, endPort int32, groups []string, host string, cidr, localCidr, caName string, caSha string) error {
263252
// We need this rule string because we generate a hash. Removing this will break firewall reload.
264253
ruleString := fmt.Sprintf(
265254
"incoming: %v, proto: %v, startPort: %v, endPort: %v, groups: %v, host: %v, ip: %v, localIp: %v, caName: %v, caSha: %s",
266-
incoming, proto, startPort, endPort, groups, host, sIp, lIp, caName, caSha,
255+
incoming, proto, startPort, endPort, groups, host, cidr, localCidr, caName, caSha,
267256
)
268257
f.rules += ruleString + "\n"
269258

270259
direction := "incoming"
271260
if !incoming {
272261
direction = "outgoing"
273262
}
274-
f.l.WithField("firewallRule", m{"direction": direction, "proto": proto, "startPort": startPort, "endPort": endPort, "groups": groups, "host": host, "ip": sIp, "localIp": lIp, "caName": caName, "caSha": caSha}).
263+
f.l.WithField("firewallRule", m{"direction": direction, "proto": proto, "startPort": startPort, "endPort": endPort, "groups": groups, "host": host, "cidr": cidr, "localCidr": localCidr, "caName": caName, "caSha": caSha}).
275264
Info("Firewall rule added")
276265

277266
var (
@@ -298,7 +287,7 @@ func (f *Firewall) AddRule(incoming bool, proto uint8, startPort int32, endPort
298287
return fmt.Errorf("unknown protocol %v", proto)
299288
}
300289

301-
return fp.addRule(f, startPort, endPort, groups, host, ip, localIp, caName, caSha)
290+
return fp.addRule(f, startPort, endPort, groups, host, cidr, localCidr, caName, caSha)
302291
}
303292

304293
// GetRuleHash returns a hash representation of all inbound and outbound rules
@@ -379,17 +368,15 @@ func AddFirewallRulesFromConfig(l *logrus.Logger, inbound bool, c *config.C, fw
379368
return fmt.Errorf("%s rule #%v; proto was not understood; `%s`", table, i, r.Proto)
380369
}
381370

382-
var cidr netip.Prefix
383-
if r.Cidr != "" {
384-
cidr, err = netip.ParsePrefix(r.Cidr)
371+
if r.Cidr != "" && r.Cidr != "any" {
372+
_, err = netip.ParsePrefix(r.Cidr)
385373
if err != nil {
386374
return fmt.Errorf("%s rule #%v; cidr did not parse; %s", table, i, err)
387375
}
388376
}
389377

390-
var localCidr netip.Prefix
391-
if r.LocalCidr != "" {
392-
localCidr, err = netip.ParsePrefix(r.LocalCidr)
378+
if r.LocalCidr != "" && r.LocalCidr != "any" {
379+
_, err = netip.ParsePrefix(r.LocalCidr)
393380
if err != nil {
394381
return fmt.Errorf("%s rule #%v; local_cidr did not parse; %s", table, i, err)
395382
}
@@ -399,7 +386,7 @@ func AddFirewallRulesFromConfig(l *logrus.Logger, inbound bool, c *config.C, fw
399386
l.Warnf("%s rule #%v; %s", table, i, warning)
400387
}
401388

402-
err = fw.AddRule(inbound, proto, startPort, endPort, r.Groups, r.Host, cidr, localCidr, r.CAName, r.CASha)
389+
err = fw.AddRule(inbound, proto, startPort, endPort, r.Groups, r.Host, r.Cidr, r.LocalCidr, r.CAName, r.CASha)
403390
if err != nil {
404391
return fmt.Errorf("%s rule #%v; `%s`", table, i, err)
405392
}
@@ -646,7 +633,7 @@ func (ft *FirewallTable) match(p firewall.Packet, incoming bool, c *cert.CachedC
646633
return false
647634
}
648635

649-
func (fp firewallPort) addRule(f *Firewall, startPort int32, endPort int32, groups []string, host string, ip, localIp netip.Prefix, caName string, caSha string) error {
636+
func (fp firewallPort) addRule(f *Firewall, startPort int32, endPort int32, groups []string, host string, cidr, localCidr, caName string, caSha string) error {
650637
if startPort > endPort {
651638
return fmt.Errorf("start port was lower than end port")
652639
}
@@ -659,7 +646,7 @@ func (fp firewallPort) addRule(f *Firewall, startPort int32, endPort int32, grou
659646
}
660647
}
661648

662-
if err := fp[i].addRule(f, groups, host, ip, localIp, caName, caSha); err != nil {
649+
if err := fp[i].addRule(f, groups, host, cidr, localCidr, caName, caSha); err != nil {
663650
return err
664651
}
665652
}
@@ -690,7 +677,7 @@ func (fp firewallPort) match(p firewall.Packet, incoming bool, c *cert.CachedCer
690677
return fp[firewall.PortAny].match(p, c, caPool)
691678
}
692679

693-
func (fc *FirewallCA) addRule(f *Firewall, groups []string, host string, ip, localIp netip.Prefix, caName, caSha string) error {
680+
func (fc *FirewallCA) addRule(f *Firewall, groups []string, host string, cidr, localCidr, caName, caSha string) error {
694681
fr := func() *FirewallRule {
695682
return &FirewallRule{
696683
Hosts: make(map[string]*firewallLocalCIDR),
@@ -704,14 +691,14 @@ func (fc *FirewallCA) addRule(f *Firewall, groups []string, host string, ip, loc
704691
fc.Any = fr()
705692
}
706693

707-
return fc.Any.addRule(f, groups, host, ip, localIp)
694+
return fc.Any.addRule(f, groups, host, cidr, localCidr)
708695
}
709696

710697
if caSha != "" {
711698
if _, ok := fc.CAShas[caSha]; !ok {
712699
fc.CAShas[caSha] = fr()
713700
}
714-
err := fc.CAShas[caSha].addRule(f, groups, host, ip, localIp)
701+
err := fc.CAShas[caSha].addRule(f, groups, host, cidr, localCidr)
715702
if err != nil {
716703
return err
717704
}
@@ -721,7 +708,7 @@ func (fc *FirewallCA) addRule(f *Firewall, groups []string, host string, ip, loc
721708
if _, ok := fc.CANames[caName]; !ok {
722709
fc.CANames[caName] = fr()
723710
}
724-
err := fc.CANames[caName].addRule(f, groups, host, ip, localIp)
711+
err := fc.CANames[caName].addRule(f, groups, host, cidr, localCidr)
725712
if err != nil {
726713
return err
727714
}
@@ -753,24 +740,24 @@ func (fc *FirewallCA) match(p firewall.Packet, c *cert.CachedCertificate, caPool
753740
return fc.CANames[s.Certificate.Name()].match(p, c)
754741
}
755742

756-
func (fr *FirewallRule) addRule(f *Firewall, groups []string, host string, ip, localCIDR netip.Prefix) error {
743+
func (fr *FirewallRule) addRule(f *Firewall, groups []string, host, cidr, localCidr string) error {
757744
flc := func() *firewallLocalCIDR {
758745
return &firewallLocalCIDR{
759746
LocalCIDR: new(bart.Lite),
760747
}
761748
}
762749

763-
if fr.isAny(groups, host, ip) {
750+
if fr.isAny(groups, host, cidr) {
764751
if fr.Any == nil {
765752
fr.Any = flc()
766753
}
767754

768-
return fr.Any.addRule(f, localCIDR)
755+
return fr.Any.addRule(f, localCidr)
769756
}
770757

771758
if len(groups) > 0 {
772759
nlc := flc()
773-
err := nlc.addRule(f, localCIDR)
760+
err := nlc.addRule(f, localCidr)
774761
if err != nil {
775762
return err
776763
}
@@ -786,30 +773,34 @@ func (fr *FirewallRule) addRule(f *Firewall, groups []string, host string, ip, l
786773
if nlc == nil {
787774
nlc = flc()
788775
}
789-
err := nlc.addRule(f, localCIDR)
776+
err := nlc.addRule(f, localCidr)
790777
if err != nil {
791778
return err
792779
}
793780
fr.Hosts[host] = nlc
794781
}
795782

796-
if ip.IsValid() {
797-
nlc, _ := fr.CIDR.Get(ip)
783+
if cidr != "" {
784+
c, err := netip.ParsePrefix(cidr)
785+
if err != nil {
786+
return err
787+
}
788+
nlc, _ := fr.CIDR.Get(c)
798789
if nlc == nil {
799790
nlc = flc()
800791
}
801-
err := nlc.addRule(f, localCIDR)
792+
err = nlc.addRule(f, localCidr)
802793
if err != nil {
803794
return err
804795
}
805-
fr.CIDR.Insert(ip, nlc)
796+
fr.CIDR.Insert(c, nlc)
806797
}
807798

808799
return nil
809800
}
810801

811-
func (fr *FirewallRule) isAny(groups []string, host string, ip netip.Prefix) bool {
812-
if len(groups) == 0 && host == "" && !ip.IsValid() {
802+
func (fr *FirewallRule) isAny(groups []string, host string, cidr string) bool {
803+
if len(groups) == 0 && host == "" && cidr == "" {
813804
return true
814805
}
815806

@@ -823,7 +814,7 @@ func (fr *FirewallRule) isAny(groups []string, host string, ip netip.Prefix) boo
823814
return true
824815
}
825816

826-
if ip.IsValid() && ip.Bits() == 0 {
817+
if cidr == "any" {
827818
return true
828819
}
829820

@@ -875,8 +866,13 @@ func (fr *FirewallRule) match(p firewall.Packet, c *cert.CachedCertificate) bool
875866
return false
876867
}
877868

878-
func (flc *firewallLocalCIDR) addRule(f *Firewall, localIp netip.Prefix) error {
879-
if !localIp.IsValid() {
869+
func (flc *firewallLocalCIDR) addRule(f *Firewall, localCidr string) error {
870+
if localCidr == "any" {
871+
flc.Any = true
872+
return nil
873+
}
874+
875+
if localCidr == "" {
880876
if !f.hasUnsafeNetworks || f.defaultLocalCIDRAny {
881877
flc.Any = true
882878
return nil
@@ -887,12 +883,13 @@ func (flc *firewallLocalCIDR) addRule(f *Firewall, localIp netip.Prefix) error {
887883
}
888884
return nil
889885

890-
} else if localIp.Bits() == 0 {
891-
flc.Any = true
892-
return nil
893886
}
894887

895-
flc.LocalCIDR.Insert(localIp)
888+
c, err := netip.ParsePrefix(localCidr)
889+
if err != nil {
890+
return err
891+
}
892+
flc.LocalCIDR.Insert(c)
896893
return nil
897894
}
898895

0 commit comments

Comments
 (0)