mirror of
https://github.com/speatzle/nfsense.git
synced 2025-05-11 19:08:20 +00:00
Add DNS Server Backend
This commit is contained in:
parent
ccc7745099
commit
6635d9ed74
6 changed files with 204 additions and 0 deletions
81
internal/api/service/dns_server.go
Normal file
81
internal/api/service/dns_server.go
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"nfsense.net/nfsense/internal/definitions/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetDNSServerParameters struct {
|
||||||
|
ID uint
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetDNSServerResult struct {
|
||||||
|
service.DNSServer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Service) GetDNSServer(ctx context.Context, params GetDNSServerParameters) (GetDNSServerResult, error) {
|
||||||
|
if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Service.DNSServers) {
|
||||||
|
return GetDNSServerResult{}, fmt.Errorf("DNSServer does not Exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetDNSServerResult{
|
||||||
|
DNSServer: f.ConfigManager.GetPendingConfig().Service.DNSServers[params.ID],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetDNSServersResult struct {
|
||||||
|
DNSServers []service.DNSServer `json:"dns_servers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Service) GetDNSServers(ctx context.Context, params struct{}) (GetDNSServersResult, error) {
|
||||||
|
return GetDNSServersResult{
|
||||||
|
DNSServers: f.ConfigManager.GetPendingConfig().Service.DNSServers,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateDNSServerParameters struct {
|
||||||
|
service.DNSServer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Service) CreateDNSServer(ctx context.Context, params CreateDNSServerParameters) (struct{}, error) {
|
||||||
|
t, conf := f.ConfigManager.StartTransaction()
|
||||||
|
defer t.Discard()
|
||||||
|
|
||||||
|
conf.Service.DNSServers = append(conf.Service.DNSServers, params.DNSServer)
|
||||||
|
return struct{}{}, t.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateDNSServerParameters struct {
|
||||||
|
Index uint64 `json:"index"`
|
||||||
|
DNSServer service.DNSServer `json:"dns_server"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Service) UpdateDNSServer(ctx context.Context, params UpdateDNSServerParameters) (struct{}, error) {
|
||||||
|
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.DNSServers) {
|
||||||
|
return struct{}{}, fmt.Errorf("DNSServer does not Exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
t, conf := f.ConfigManager.StartTransaction()
|
||||||
|
defer t.Discard()
|
||||||
|
|
||||||
|
conf.Service.DNSServers[params.Index] = params.DNSServer
|
||||||
|
return struct{}{}, t.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteDNSServerParameters struct {
|
||||||
|
Index uint64 `json:"index"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Service) DeleteDNSServer(ctx context.Context, params DeleteDNSServerParameters) (struct{}, error) {
|
||||||
|
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.DNSServers) {
|
||||||
|
return struct{}{}, fmt.Errorf("DNSServer does not Exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
t, conf := f.ConfigManager.StartTransaction()
|
||||||
|
defer t.Discard()
|
||||||
|
|
||||||
|
conf.Service.DNSServers = append(conf.Service.DNSServers[:params.Index], conf.Service.DNSServers[params.Index+1:]...)
|
||||||
|
return struct{}{}, t.Commit()
|
||||||
|
}
|
54
internal/unbound/apply.go
Normal file
54
internal/unbound/apply.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package unbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
systemctl "github.com/coreos/go-systemd/v22/dbus"
|
||||||
|
"nfsense.net/nfsense/internal/definitions/config"
|
||||||
|
"nfsense.net/nfsense/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
const unboundServerFile = "/etc/unbound/unbound.conf"
|
||||||
|
|
||||||
|
func ApplyDNSServerConfiguration(currentConfig config.Config, pendingConfig config.Config) error {
|
||||||
|
|
||||||
|
serverConf, err := GenerateUnboundServerConfiguration(pendingConfig)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Generating Unbound Server Configuration: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = util.OverwriteFile(unboundServerFile, serverConf)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Writing server Configuration: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := systemctl.NewSystemConnectionContext(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Opening Dbus Connection: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pendingConfig.Service.DNSServers) == 0 {
|
||||||
|
// if there are no servers stop the service instead
|
||||||
|
_, err := conn.StopUnitContext(context.Background(), "unbound.service", "replace", nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("stopping unbound.service: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = conn.DisableUnitFilesContext(context.Background(), []string{"unbound.service"}, false)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("disableing unbound.service: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, err := conn.ReloadOrRestartUnitContext(context.Background(), "unbound.service", "replace", nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("restarting unbound.service: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = conn.EnableUnitFilesContext(context.Background(), []string{"unbound.service"}, false, true)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("enableing unbound.service: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
17
internal/unbound/server.go
Normal file
17
internal/unbound/server.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package unbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"nfsense.net/nfsense/internal/definitions/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GenerateUnboundServerConfiguration(conf config.Config) (string, error) {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
err := templates.ExecuteTemplate(buf, "server.tmpl", conf)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("executing server.tmpl template: %w", err)
|
||||||
|
}
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
35
internal/unbound/template.go
Normal file
35
internal/unbound/template.go
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package unbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"nfsense.net/nfsense/internal/definitions/config"
|
||||||
|
"nfsense.net/nfsense/internal/definitions/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed template
|
||||||
|
var templateFS embed.FS
|
||||||
|
var templates *template.Template
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var err error
|
||||||
|
templates, err = template.New("").Funcs(template.FuncMap{
|
||||||
|
"getInterfaceNetworkAddressCIDR": getInterfaceNetworkAddressCIDR,
|
||||||
|
"getInterfaceName": getInterfaceName,
|
||||||
|
}).ParseFS(templateFS, "template/*.tmpl")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInterfaceNetworkAddressCIDR(conf config.Config, name string) string {
|
||||||
|
return conf.Network.Interfaces[name].Address.Masked().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInterfaceName(conf config.Config, name string) string {
|
||||||
|
if conf.Network.Interfaces[name].Type == network.Hardware {
|
||||||
|
return *conf.Network.Interfaces[name].HardwareDevice
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
15
internal/unbound/template/server.tmpl
Normal file
15
internal/unbound/template/server.tmpl
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
server:
|
||||||
|
|
||||||
|
# Listen Interfaces
|
||||||
|
{{- range $i, $server := .Service.NTPServers }}
|
||||||
|
interface: {{ getInterfaceName $ $server.Interface }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
# Allowed Networks
|
||||||
|
{{- range $i, $server := .Service.NTPServers }}
|
||||||
|
access-control: {{ getInterfaceNetworkAddressCIDR $ $server.Interface }} allow
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
|
||||||
|
remote-control:
|
||||||
|
control-enable: yes
|
2
main.go
2
main.go
|
@ -22,6 +22,7 @@ import (
|
||||||
"nfsense.net/nfsense/internal/jsonrpc"
|
"nfsense.net/nfsense/internal/jsonrpc"
|
||||||
"nfsense.net/nfsense/internal/networkd"
|
"nfsense.net/nfsense/internal/networkd"
|
||||||
"nfsense.net/nfsense/internal/server"
|
"nfsense.net/nfsense/internal/server"
|
||||||
|
"nfsense.net/nfsense/internal/unbound"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -106,4 +107,5 @@ func RegisterApplyFunctions(configManager *config.ConfigManager) {
|
||||||
configManager.RegisterApplyFunction(networkd.ApplyNetworkdConfiguration)
|
configManager.RegisterApplyFunction(networkd.ApplyNetworkdConfiguration)
|
||||||
configManager.RegisterApplyFunction(dhcp.ApplyDHCPServerConfiguration)
|
configManager.RegisterApplyFunction(dhcp.ApplyDHCPServerConfiguration)
|
||||||
configManager.RegisterApplyFunction(chrony.ApplyNTPConfiguration)
|
configManager.RegisterApplyFunction(chrony.ApplyNTPConfiguration)
|
||||||
|
configManager.RegisterApplyFunction(unbound.ApplyDNSServerConfiguration)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue