bird-lg-go/proxy/settings.go

107 lines
3.3 KiB
Go

package main
import (
"fmt"
"net"
"strings"
"github.com/google/shlex"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
type viperSettingType struct {
BirdSocket string `mapstructure:"bird_socket"`
Listen string `mapstructure:"listen"`
AllowedNets string `mapstructure:"allowed_ips"`
TracerouteBin string `mapstructure:"traceroute_bin"`
TracerouteFlags string `mapstructure:"traceroute_flags"`
TracerouteRaw bool `mapstructure:"traceroute_raw"`
}
// Parse settings with viper, and convert to legacy setting format
func parseSettings() {
viper.AddConfigPath(".")
viper.AddConfigPath("/etc/bird-lg")
viper.SetConfigName("bird-lgproxy")
viper.AllowEmptyEnv(true)
viper.AutomaticEnv()
viper.SetEnvPrefix("birdlg")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
// Legacy environment variables without prefixes
viper.BindEnv("bird_socket", "BIRD_SOCKET")
viper.BindEnv("listen", "BIRDLG_LISTEN", "BIRDLG_PROXY_PORT")
viper.BindEnv("allowed_ips", "ALLOWED_IPS")
pflag.String("bird", "/var/run/bird/bird.ctl", "socket file for bird, set either in parameter or environment variable BIRD_SOCKET")
viper.BindPFlag("bird_socket", pflag.Lookup("bird"))
pflag.String("listen", "8000", "listen address, set either in parameter or environment variable BIRDLG_PROXY_PORT")
viper.BindPFlag("listen", pflag.Lookup("listen"))
pflag.String("allowed", "", "IPs or networks allowed to access this proxy, separated by commas. Don't set to allow all IPs.")
viper.BindPFlag("allowed_ips", pflag.Lookup("allowed"))
pflag.String("traceroute_bin", "", "traceroute binary file, set either in parameter or environment variable BIRDLG_TRACEROUTE_BIN")
viper.BindPFlag("traceroute_bin", pflag.Lookup("traceroute_bin"))
pflag.String("traceroute_flags", "", "traceroute flags, supports multiple flags separated with space.")
viper.BindPFlag("traceroute_flags", pflag.Lookup("traceroute_flags"))
pflag.Bool("traceroute_raw", false, "whether to display traceroute outputs raw; set via parameter or environment variable BIRDLG_TRACEROUTE_RAW")
viper.BindPFlag("traceroute_raw", pflag.Lookup("traceroute_raw"))
pflag.Parse()
if err := viper.ReadInConfig(); err != nil {
println("Warning on reading config: " + err.Error())
}
viperSettings := viperSettingType{}
if err := viper.Unmarshal(&viperSettings); err != nil {
panic(err)
}
setting.birdSocket = viperSettings.BirdSocket
setting.listen = viperSettings.Listen
if viperSettings.AllowedNets != "" {
for _, arg := range strings.Split(viperSettings.AllowedNets, ",") {
// if argument is an IP address, convert to CIDR by adding a suitable mask
if !strings.Contains(arg, "/") {
if strings.Contains(arg, ":") {
// IPv6 address with /128 mask
arg += "/128"
} else {
// IPv4 address with /32 mask
arg += "/32"
}
}
// parse the network
_, netip, err := net.ParseCIDR(arg)
if err != nil {
fmt.Printf("Failed to parse CIDR %s: %s\n", arg, err.Error())
continue
}
setting.allowedNets = append(setting.allowedNets, netip)
}
} else {
setting.allowedNets = []*net.IPNet{}
}
var err error
setting.tr_bin = viperSettings.TracerouteBin
setting.tr_flags, err = shlex.Split(viperSettings.TracerouteFlags)
if err != nil {
panic(err)
}
setting.tr_raw = viperSettings.TracerouteRaw
fmt.Printf("%#v\n", setting)
}