1
0
Fork 0
mirror of https://github.com/binwiederhier/ntfy.git synced 2025-05-20 22:08:20 +02:00

refactor visitor IPs and allow exempting IP Ranges

Use netip.Addr instead of storing addresses as strings. This requires
conversions at the database level and in tests, but is more memory
efficient otherwise, and facilitates the following.

Parse rate limit exemptions as netip.Prefix. This allows storing IP
ranges in the exemption list. Regular IP addresses (entered explicitly
or resolved from hostnames) are IPV4/32, denoting a range of one
address.
This commit is contained in:
Karmanyaah Malhotra 2022-10-05 15:42:07 -05:00
parent e0ad926ce9
commit c2382d29a1
12 changed files with 106 additions and 42 deletions

View file

@ -5,16 +5,18 @@ package cmd
import (
"errors"
"fmt"
"heckel.io/ntfy/log"
"io/fs"
"math"
"net"
"net/netip"
"os"
"os/signal"
"strings"
"syscall"
"time"
"heckel.io/ntfy/log"
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc"
"heckel.io/ntfy/server"
@ -208,15 +210,15 @@ func execServe(c *cli.Context) error {
}
// Resolve hosts
visitorRequestLimitExemptIPs := make([]string, 0)
visitorRequestLimitExemptIPs := make([]netip.Prefix, 0)
for _, host := range visitorRequestLimitExemptHosts {
ips, err := net.LookupIP(host)
ips, err := parseIPHostPrefix(host)
if err != nil {
log.Warn("cannot resolve host %s: %s, ignoring visitor request exemption", host, err.Error())
continue
}
for _, ip := range ips {
visitorRequestLimitExemptIPs = append(visitorRequestLimitExemptIPs, ip.String())
visitorRequestLimitExemptIPs = append(visitorRequestLimitExemptIPs, ip)
}
}
@ -303,6 +305,33 @@ func sigHandlerConfigReload(config string) {
}
}
func parseIPHostPrefix(host string) (prefixes []netip.Prefix, err error) {
//try parsing as prefix
prefix, err := netip.ParsePrefix(host)
if err == nil {
prefixes = append(prefixes, prefix.Masked()) // masked and canonical for easy of debugging, shouldn't matter
return prefixes, nil // success
}
// not a prefix, parse as host or IP
// LookupHost forwards through if it's an IP
ips, err := net.LookupHost(host)
if err == nil {
for _, i := range ips {
ip, err := netip.ParseAddr(i)
if err == nil {
prefix, err := ip.Prefix(ip.BitLen())
if err != nil {
return prefixes, errors.New(fmt.Sprint("ip", ip, " successfully parsed as IP but unable to turn into prefix. THIS SHOULD NEVER HAPPEN. err:", err.Error()))
}
prefixes = append(prefixes, prefix.Masked()) //also masked canonical ip
}
}
}
return
}
func reloadLogLevel(inputSource altsrc.InputSourceContext) {
newLevelStr, err := inputSource.String("log-level")
if err != nil {