Skip to content

Commit d85e24f

Browse files
authored
Allow for self reported ips to the lighthouse (slackhq#650)
1 parent 7672c70 commit d85e24f

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

examples/config.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ lighthouse:
8181
# Example to only advertise this subnet to the lighthouse.
8282
#"10.0.0.0/8": true
8383

84+
# advertise_addrs are routable addresses that will be included along with discovered addresses to report to the
85+
# lighthouse, the format is "ip:port". `port` can be `0`, in which case the actual listening port will be used in its
86+
# place, useful if `listen.port` is set to 0.
87+
# This option is mainly useful when there are static ip addresses the host can be reached at that nebula can not
88+
# typically discover on its own. Examples being port forwarding or multiple paths to the internet.
89+
#advertise_addrs:
90+
#- "1.1.1.1:4242"
91+
#- "1.2.3.4:0" # port will be replaced with the real listening port
92+
8493
# Port Nebula will be listening on. The default here is 4242. For a lighthouse node, the port should be defined,
8594
# however using port 0 will dynamically assign a port and is recommended for roaming nodes.
8695
listen:

lighthouse.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ import (
2626

2727
var ErrHostNotKnown = errors.New("host not known")
2828

29+
type netIpAndPort struct {
30+
ip net.IP
31+
port uint16
32+
}
33+
2934
type LightHouse struct {
3035
//TODO: We need a timer wheel to kick out vpnIps that haven't reported in a long time
3136
sync.RWMutex //Because we concurrently read and write to our maps
@@ -64,6 +69,8 @@ type LightHouse struct {
6469
updateUdp udp.EncWriter
6570
nebulaPort uint32 // 32 bits because protobuf does not have a uint16
6671

72+
atomicAdvertiseAddrs []netIpAndPort
73+
6774
metrics *MessageMetrics
6875
metricHolepunchTx metrics.Counter
6976
l *logrus.Logger
@@ -143,11 +150,45 @@ func (lh *LightHouse) GetLocalAllowList() *LocalAllowList {
143150
return (*LocalAllowList)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&lh.atomicLocalAllowList))))
144151
}
145152

153+
func (lh *LightHouse) GetAdvertiseAddrs() []netIpAndPort {
154+
return *(*[]netIpAndPort)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&lh.atomicAdvertiseAddrs))))
155+
}
156+
146157
func (lh *LightHouse) GetUpdateInterval() int64 {
147158
return atomic.LoadInt64(&lh.atomicInterval)
148159
}
149160

150161
func (lh *LightHouse) reload(c *config.C, initial bool) error {
162+
if initial || c.HasChanged("lighthouse.advertise_addrs") {
163+
rawAdvAddrs := c.GetStringSlice("lighthouse.advertise_addrs", []string{})
164+
advAddrs := make([]netIpAndPort, 0)
165+
166+
for i, rawAddr := range rawAdvAddrs {
167+
fIp, fPort, err := udp.ParseIPAndPort(rawAddr)
168+
if err != nil {
169+
return util.NewContextualError("Unable to parse lighthouse.advertise_addrs entry", m{"addr": rawAddr, "entry": i + 1}, err)
170+
}
171+
172+
if fPort == 0 {
173+
fPort = uint16(lh.nebulaPort)
174+
}
175+
176+
if ip4 := fIp.To4(); ip4 != nil && lh.myVpnNet.Contains(fIp) {
177+
lh.l.WithField("addr", rawAddr).WithField("entry", i+1).
178+
Warn("Ignoring lighthouse.advertise_addrs report because it is within the nebula network range")
179+
continue
180+
}
181+
182+
advAddrs = append(advAddrs, netIpAndPort{ip: fIp, port: fPort})
183+
}
184+
185+
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&lh.atomicAdvertiseAddrs)), unsafe.Pointer(&advAddrs))
186+
187+
if !initial {
188+
lh.l.Info("lighthouse.advertise_addrs has changed")
189+
}
190+
}
191+
151192
if initial || c.HasChanged("lighthouse.interval") {
152193
atomic.StoreInt64(&lh.atomicInterval, int64(c.GetInt("lighthouse.interval", 10)))
153194

@@ -535,6 +576,14 @@ func (lh *LightHouse) SendUpdate(f udp.EncWriter) {
535576
var v4 []*Ip4AndPort
536577
var v6 []*Ip6AndPort
537578

579+
for _, e := range lh.GetAdvertiseAddrs() {
580+
if ip := e.ip.To4(); ip != nil {
581+
v4 = append(v4, NewIp4AndPort(e.ip, uint32(e.port)))
582+
} else {
583+
v6 = append(v6, NewIp6AndPort(e.ip, uint32(e.port)))
584+
}
585+
}
586+
538587
lal := lh.GetLocalAllowList()
539588
for _, e := range *localIps(lh.l, lal) {
540589
if ip4 := e.To4(); ip4 != nil && ipMaskContains(lh.myVpnIp, lh.myVpnZeros, iputil.Ip2VpnIp(ip4)) {
@@ -548,6 +597,7 @@ func (lh *LightHouse) SendUpdate(f udp.EncWriter) {
548597
v6 = append(v6, NewIp6AndPort(e, lh.nebulaPort))
549598
}
550599
}
600+
551601
m := &NebulaMeta{
552602
Type: NebulaMeta_HostUpdateNotification,
553603
Details: &NebulaMetaDetails{

0 commit comments

Comments
 (0)