prepairing for production
Some checks failed
Build and Package OPKG / Build aarch64 (push) Failing after 28s
Build and Package OPKG / Build armv5 (push) Failing after 16s
Build and Package OPKG / Build armv7 (push) Failing after 20s
Build and Package OPKG / Build mips (push) Failing after 18s
Build and Package OPKG / Build mipsel (push) Failing after 15s
Some checks failed
Build and Package OPKG / Build aarch64 (push) Failing after 28s
Build and Package OPKG / Build armv5 (push) Failing after 16s
Build and Package OPKG / Build armv7 (push) Failing after 20s
Build and Package OPKG / Build mips (push) Failing after 18s
Build and Package OPKG / Build mipsel (push) Failing after 15s
This commit is contained in:
parent
1419285de3
commit
8369de6845
29
.github/workflows/build.yml
vendored
29
.github/workflows/build.yml
vendored
@ -7,7 +7,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
run-name: Build ${{ matrix.arch }}
|
name: Build ${{ matrix.arch }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@ -46,33 +46,12 @@ jobs:
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y fakeroot
|
sudo apt-get install -y fakeroot
|
||||||
|
|
||||||
- name: Build binary
|
- name: Build and Package
|
||||||
run: |
|
run: |
|
||||||
go mod tidy
|
ARCH=${{ matrix.arch }} GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} GOMIPS=${{ matrix.gomips }} GOARM=${{ matrix.goarm }} make
|
||||||
GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} GOMIPS=${{ matrix.gomips }} GOARM=${{ matrix.goarm }} go build -o kvas2-${{ matrix.arch }} -v -a -trimpath -ldflags="-w -s" .
|
|
||||||
|
|
||||||
- name: Package as OPKG
|
|
||||||
run: |
|
|
||||||
mkdir -p build/${{ matrix.arch }}/control
|
|
||||||
echo 'Package: kvas2' > build/${{ matrix.arch }}/control/control
|
|
||||||
echo 'Version: 0.0.1' >> build/${{ matrix.arch }}/control/control
|
|
||||||
echo 'Architecture: ${{ matrix.arch }}' >> build/${{ matrix.arch }}/control/control
|
|
||||||
echo 'Maintainer: Vladimir Avtsenov <vladimir.lsk.cool@gmail.com>' >> build/${{ matrix.arch }}/control/control
|
|
||||||
echo 'Description: kvas2' >> build/${{ matrix.arch }}/control/control
|
|
||||||
echo 'Section: base' >> build/${{ matrix.arch }}/control/control
|
|
||||||
echo 'Priority: optional' >> build/${{ matrix.arch }}/control/control
|
|
||||||
echo 'Depends: libc, iptables, socat' >> build/${{ matrix.arch }}/control/control
|
|
||||||
mkdir -p build/${{ matrix.arch }}/data/opt/usr/bin
|
|
||||||
cp kvas2-${{ matrix.arch }} build/${{ matrix.arch }}/data/opt/usr/bin/kvas2
|
|
||||||
cp -r opt build/${{ matrix.arch }}/data/
|
|
||||||
chmod +x build/${{ matrix.arch }}/data/opt/usr/bin/kvas2
|
|
||||||
fakeroot sh -c "tar -C build/${{ matrix.arch }}/control -cvf build/${{ matrix.arch }}/control.tar ."
|
|
||||||
fakeroot sh -c "tar -C build/${{ matrix.arch }}/data -cvf build/${{ matrix.arch }}/data.tar ."
|
|
||||||
echo '2.0' > build/${{ matrix.arch }}/debian-binary
|
|
||||||
ar r build/kvas2_${{ matrix.arch }}.ipk build/${{ matrix.arch }}/debian-binary build/${{ matrix.arch }}/control.tar build/${{ matrix.arch }}/data.tar
|
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: kvas2_${{ matrix.arch }}.ipk
|
name: kvas2_${{ matrix.arch }}.ipk
|
||||||
path: build/kvas2_${{ matrix.arch }}.ipk
|
path: .build/kvas2_${{ matrix.arch }}.ipk
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
kvas2-go
|
/.build
|
||||||
config.yaml
|
|
||||||
|
40
Makefile
Normal file
40
Makefile
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
APP_NAME = kvas2
|
||||||
|
APP_DESCRIPTION = DNS-based routing application
|
||||||
|
APP_MAINTAINER = Vladimir Avtsenov <vladimir.lsk.cool@gmail.com>
|
||||||
|
|
||||||
|
TAG = $(shell git describe --tags --abbrev=0)
|
||||||
|
COMMIT = $(shell git rev-parse --short HEAD)
|
||||||
|
COMMITS_SINCE_TAG = $(shell git rev-list ${TAG}..HEAD --count || echo "0")
|
||||||
|
VERSION ?= $(TAG)
|
||||||
|
|
||||||
|
ARCH ?= mipsel
|
||||||
|
GOOS ?= linux
|
||||||
|
GOARCH ?= mipsle
|
||||||
|
GOMIPS ?= softfloat
|
||||||
|
GOARM ?=
|
||||||
|
|
||||||
|
PKG_DIR = ./.build/$(ARCH)
|
||||||
|
BIN_DIR = $(PKG_DIR)/data/opt/usr/bin
|
||||||
|
PARAMS = -v -a -trimpath -ldflags="-X 'kvas2/constant.Version=$(VERSION)' -X 'kvas2/constant.Commit=$(COMMIT)' -w -s"
|
||||||
|
|
||||||
|
all: build_daemon package
|
||||||
|
|
||||||
|
build_daemon:
|
||||||
|
GOOS=$(GOOS) GOARCH=$(GOARCH) GOMIPS=$(GOMIPS) GOARM=$(GOARM) go build $(PARAMS) -o $(BIN_DIR)/kvas2d ./cmd/kvas2d
|
||||||
|
|
||||||
|
package:
|
||||||
|
@mkdir -p $(PKG_DIR)/control
|
||||||
|
@echo '2.0' > $(PKG_DIR)/debian-binary
|
||||||
|
@echo 'Package: $(APP_NAME)' > $(PKG_DIR)/control/control
|
||||||
|
@echo 'Version: $(VERSION)-$(COMMITS_SINCE_TAG)' >> $(PKG_DIR)/control/control
|
||||||
|
@echo 'Architecture: $(ARCH)' >> $(PKG_DIR)/control/control
|
||||||
|
@echo 'Maintainer: $(APP_MAINTAINER)' >> $(PKG_DIR)/control/control
|
||||||
|
@echo 'Description: $(APP_DESCRIPTION)' >> $(PKG_DIR)/control/control
|
||||||
|
@echo 'Section: base' >> $(PKG_DIR)/control/control
|
||||||
|
@echo 'Priority: optional' >> $(PKG_DIR)/control/control
|
||||||
|
@echo 'Depends: libc, iptables, socat' >> $(PKG_DIR)/control/control
|
||||||
|
@mkdir -p $(PKG_DIR)/data/opt/usr/bin
|
||||||
|
@cp -r ./opt/* $(PKG_DIR)/data/
|
||||||
|
@fakeroot sh -c "tar -C $(PKG_DIR)/control -cvf $(PKG_DIR)/control.tar ."
|
||||||
|
@fakeroot sh -c "tar -C $(PKG_DIR)/data -cvf $(PKG_DIR)/data.tar ."
|
||||||
|
@ar r $(PKG_DIR)/$(APP_NAME)_$(ARCH).ipk $(PKG_DIR)/debian-binary $(PKG_DIR)/control.tar $(PKG_DIR)/data.tar
|
24
README.md
24
README.md
@ -1,25 +1,3 @@
|
|||||||
# kvas2-go
|
# kvas2
|
||||||
|
|
||||||
Better implementation of [KVAS](https://github.com/qzeleza/kvas)
|
Better implementation of [KVAS](https://github.com/qzeleza/kvas)
|
||||||
|
|
||||||
Realized features:
|
|
||||||
- [x] DNS Proxy (UDP)
|
|
||||||
- [x] DNS Proxy (TCP)
|
|
||||||
- [x] Records memory
|
|
||||||
- [x] IPTables rules for rebind DNS server port
|
|
||||||
- [X] IPSet integration
|
|
||||||
- [X] IP integration
|
|
||||||
- [X] IPTables rules to IPSet
|
|
||||||
- [X] Catch interface up/down
|
|
||||||
- [X] Catch `netfilter.d` event
|
|
||||||
- [X] Rule composer (CRUD)
|
|
||||||
- [ ] GORM integration
|
|
||||||
- [X] Listing of interfaces
|
|
||||||
- [ ] HTTP API
|
|
||||||
- [ ] HTTP GUI
|
|
||||||
- [ ] CLI
|
|
||||||
- [X] (Keenetic) Support for custom interfaces
|
|
||||||
- [ ] It is not a concept now... REFACTORING TIME!!!
|
|
||||||
- [ ] (Keenetic) Getting readable names of interfaces from Keenetic NDMS
|
|
||||||
- [ ] HTTP Auth
|
|
||||||
- [ ] IPv6 support
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
GOOS=linux GOMIPS=softfloat GOARCH=mipsle go build -v -a -trimpath -ldflags="-w -s" .
|
|
173
cmd/kvas2d/main.go
Normal file
173
cmd/kvas2d/main.go
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"kvas2"
|
||||||
|
"kvas2/constant"
|
||||||
|
"kvas2/models"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const cfgFolderLocation = "/opt/var/lib/kvas2"
|
||||||
|
const cfgFileLocation = cfgFolderLocation + "/config.yaml"
|
||||||
|
const pidFileLocation = "/opt/var/run/kvas2.pid"
|
||||||
|
|
||||||
|
func checkPIDFile() error {
|
||||||
|
data, err := os.ReadFile(pidFileLocation)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pid, err := strconv.Atoi(string(data))
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("invalid PID file content")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := syscall.Kill(pid, 0); err == nil {
|
||||||
|
return fmt.Errorf("process %d is already running", pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = os.Remove(pidFileLocation)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createPIDFile() error {
|
||||||
|
pid := os.Getpid()
|
||||||
|
return os.WriteFile(pidFileLocation, []byte(strconv.Itoa(pid)), 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
func removePIDFile() {
|
||||||
|
_ = os.Remove(pidFileLocation)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||||
|
log.Info().
|
||||||
|
Str("version", constant.Version).
|
||||||
|
Str("commit", constant.Commit).
|
||||||
|
Msg("starting kvas2 daemon")
|
||||||
|
|
||||||
|
if err := checkPIDFile(); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("failed to start kvas2 daemon")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := createPIDFile(); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("failed to create PID file")
|
||||||
|
}
|
||||||
|
defer removePIDFile()
|
||||||
|
|
||||||
|
cfg := models.ConfigFile{}
|
||||||
|
|
||||||
|
cfgFile, err := os.ReadFile(cfgFileLocation)
|
||||||
|
if err == nil {
|
||||||
|
err = yaml.Unmarshal(cfgFile, &cfg)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("failed to parse config.yaml")
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
|
log.Fatal().Err(err).Msg("failed to read config.yaml")
|
||||||
|
}
|
||||||
|
cfg = models.ConfigFile{
|
||||||
|
AppConfig: models.AppConfig{
|
||||||
|
LogLevel: "info",
|
||||||
|
AdditionalTTL: 216000,
|
||||||
|
ChainPrefix: "KVAS2_",
|
||||||
|
IPSetPrefix: "kvas2_",
|
||||||
|
LinkName: "br0",
|
||||||
|
TargetDNSServerAddress: "127.0.0.1",
|
||||||
|
TargetDNSServerPort: 53,
|
||||||
|
ListenDNSPort: 3553,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
out, err := yaml.Marshal(cfg)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("failed to serialize config.yaml")
|
||||||
|
}
|
||||||
|
err = os.MkdirAll(cfgFolderLocation, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("failed to create config directory")
|
||||||
|
}
|
||||||
|
err = os.WriteFile(cfgFileLocation, out, 0600)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("failed to save config.yaml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch cfg.AppConfig.LogLevel {
|
||||||
|
case "trace":
|
||||||
|
zerolog.SetGlobalLevel(zerolog.TraceLevel)
|
||||||
|
case "debug":
|
||||||
|
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||||
|
case "info":
|
||||||
|
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||||
|
case "warn":
|
||||||
|
zerolog.SetGlobalLevel(zerolog.WarnLevel)
|
||||||
|
case "error":
|
||||||
|
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
|
||||||
|
case "fatal":
|
||||||
|
zerolog.SetGlobalLevel(zerolog.FatalLevel)
|
||||||
|
case "panic":
|
||||||
|
zerolog.SetGlobalLevel(zerolog.PanicLevel)
|
||||||
|
case "nolevel":
|
||||||
|
zerolog.SetGlobalLevel(zerolog.NoLevel)
|
||||||
|
case "disabled":
|
||||||
|
zerolog.SetGlobalLevel(zerolog.Disabled)
|
||||||
|
default:
|
||||||
|
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
app, err := kvas2.New(cfg)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("failed to initialize application")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
log.Info().Msg("starting service")
|
||||||
|
|
||||||
|
/*
|
||||||
|
Starting app with graceful shutdown
|
||||||
|
*/
|
||||||
|
appResult := make(chan error)
|
||||||
|
go func() {
|
||||||
|
appResult <- app.Start(ctx)
|
||||||
|
}()
|
||||||
|
|
||||||
|
c := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|
||||||
|
var once sync.Once
|
||||||
|
closeEvent := func() {
|
||||||
|
log.Info().Msg("shutting down service")
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case err, _ := <-appResult:
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("failed to start application")
|
||||||
|
}
|
||||||
|
log.Info().Msg("exiting application")
|
||||||
|
return
|
||||||
|
case <-c:
|
||||||
|
once.Do(closeEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
constant/version.go
Normal file
6
constant/version.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package constant
|
||||||
|
|
||||||
|
var (
|
||||||
|
Version = "unattached"
|
||||||
|
Commit = "undef"
|
||||||
|
)
|
@ -5,9 +5,9 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"kvas2-go/models"
|
"kvas2/models"
|
||||||
"kvas2-go/netfilter-helper"
|
"kvas2/netfilter-helper"
|
||||||
"kvas2-go/records"
|
"kvas2/records"
|
||||||
|
|
||||||
"github.com/coreos/go-iptables/iptables"
|
"github.com/coreos/go-iptables/iptables"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
67
kvas2.go
67
kvas2.go
@ -1,4 +1,4 @@
|
|||||||
package main
|
package kvas2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -12,11 +12,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"kvas2-go/dns-mitm-proxy"
|
"kvas2/dns-mitm-proxy"
|
||||||
"kvas2-go/group"
|
"kvas2/group"
|
||||||
"kvas2-go/models"
|
"kvas2/models"
|
||||||
"kvas2-go/netfilter-helper"
|
"kvas2/netfilter-helper"
|
||||||
"kvas2-go/records"
|
"kvas2/records"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@ -63,14 +63,13 @@ type App struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) handleLink(event netlink.LinkUpdate) {
|
func (a *App) handleLink(event netlink.LinkUpdate) {
|
||||||
log.Trace().
|
|
||||||
Str("interface", event.Link.Attrs().Name).
|
|
||||||
Str("operstatestr", event.Attrs().OperState.String()).
|
|
||||||
Int("operstate", int(event.Attrs().OperState)).
|
|
||||||
Int("change", int(event.Change)).
|
|
||||||
Msg("interface event")
|
|
||||||
switch event.Change {
|
switch event.Change {
|
||||||
case 0x00000001:
|
case 0x00000001:
|
||||||
|
log.Trace().
|
||||||
|
Str("interface", event.Link.Attrs().Name).
|
||||||
|
Int("change", int(event.Change)).
|
||||||
|
Msg("interface event")
|
||||||
ifaceName := event.Link.Attrs().Name
|
ifaceName := event.Link.Attrs().Name
|
||||||
for _, group := range a.Groups {
|
for _, group := range a.Groups {
|
||||||
if group.Interface != ifaceName {
|
if group.Interface != ifaceName {
|
||||||
@ -172,7 +171,7 @@ func (a *App) start(ctx context.Context) (err error) {
|
|||||||
/*
|
/*
|
||||||
Socket (for netfilter.d events)
|
Socket (for netfilter.d events)
|
||||||
*/
|
*/
|
||||||
socketPath := "/opt/var/run/kvas2-go.sock"
|
socketPath := "/opt/var/run/kvas2.sock"
|
||||||
err = os.Remove(socketPath)
|
err = os.Remove(socketPath)
|
||||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||||
return fmt.Errorf("failed to remove existed UNIX socket: %w", err)
|
return fmt.Errorf("failed to remove existed UNIX socket: %w", err)
|
||||||
@ -302,7 +301,7 @@ func (a *App) AddGroup(groupModel *models.Group) error {
|
|||||||
}
|
}
|
||||||
a.Groups = append(a.Groups, grp)
|
a.Groups = append(a.Groups, grp)
|
||||||
|
|
||||||
log.Trace().Str("id", grp.ID.String()).Str("name", grp.Name).Msg("added group")
|
log.Debug().Str("id", grp.ID.String()).Str("name", grp.Name).Msg("added group")
|
||||||
|
|
||||||
return grp.Sync(a.Records)
|
return grp.Sync(a.Records)
|
||||||
}
|
}
|
||||||
@ -326,11 +325,20 @@ func (a *App) ListInterfaces() ([]net.Interface, error) {
|
|||||||
return interfaceNames, nil
|
return interfaceNames, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) processARecord(aRecord dns.A) {
|
func (a *App) processARecord(aRecord dns.A, clientAddr net.Addr, network *string) {
|
||||||
|
var clientAddrStr, networkStr string
|
||||||
|
if clientAddr != nil {
|
||||||
|
clientAddrStr = clientAddr.String()
|
||||||
|
}
|
||||||
|
if network != nil {
|
||||||
|
networkStr = *network
|
||||||
|
}
|
||||||
log.Trace().
|
log.Trace().
|
||||||
Str("name", aRecord.Hdr.Name).
|
Str("name", aRecord.Hdr.Name).
|
||||||
Str("address", aRecord.A.String()).
|
Str("address", aRecord.A.String()).
|
||||||
Int("ttl", int(aRecord.Hdr.Ttl)).
|
Int("ttl", int(aRecord.Hdr.Ttl)).
|
||||||
|
Str("clientAddr", clientAddrStr).
|
||||||
|
Str("network", networkStr).
|
||||||
Msg("processing a record")
|
Msg("processing a record")
|
||||||
|
|
||||||
ttlDuration := aRecord.Hdr.Ttl + a.Config.AdditionalTTL
|
ttlDuration := aRecord.Hdr.Ttl + a.Config.AdditionalTTL
|
||||||
@ -356,11 +364,10 @@ func (a *App) processARecord(aRecord dns.A) {
|
|||||||
Err(err).
|
Err(err).
|
||||||
Msg("failed to add address")
|
Msg("failed to add address")
|
||||||
} else {
|
} else {
|
||||||
log.Trace().
|
log.Debug().
|
||||||
Str("address", aRecord.A.String()).
|
Str("address", aRecord.A.String()).
|
||||||
Str("aRecordDomain", aRecord.Hdr.Name).
|
Str("aRecordDomain", aRecord.Hdr.Name).
|
||||||
Str("cNameDomain", name).
|
Str("cNameDomain", name).
|
||||||
Err(err).
|
|
||||||
Msg("add address")
|
Msg("add address")
|
||||||
}
|
}
|
||||||
break Rule
|
break Rule
|
||||||
@ -369,11 +376,20 @@ func (a *App) processARecord(aRecord dns.A) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) processCNameRecord(cNameRecord dns.CNAME) {
|
func (a *App) processCNameRecord(cNameRecord dns.CNAME, clientAddr net.Addr, network *string) {
|
||||||
|
var clientAddrStr, networkStr string
|
||||||
|
if clientAddr != nil {
|
||||||
|
clientAddrStr = clientAddr.String()
|
||||||
|
}
|
||||||
|
if network != nil {
|
||||||
|
networkStr = *network
|
||||||
|
}
|
||||||
log.Trace().
|
log.Trace().
|
||||||
Str("name", cNameRecord.Hdr.Name).
|
Str("name", cNameRecord.Hdr.Name).
|
||||||
Str("cname", cNameRecord.Target).
|
Str("cname", cNameRecord.Target).
|
||||||
Int("ttl", int(cNameRecord.Hdr.Ttl)).
|
Int("ttl", int(cNameRecord.Hdr.Ttl)).
|
||||||
|
Str("clientAddr", clientAddrStr).
|
||||||
|
Str("network", networkStr).
|
||||||
Msg("processing cname record")
|
Msg("processing cname record")
|
||||||
|
|
||||||
ttlDuration := cNameRecord.Hdr.Ttl + a.Config.AdditionalTTL
|
ttlDuration := cNameRecord.Hdr.Ttl + a.Config.AdditionalTTL
|
||||||
@ -402,10 +418,9 @@ func (a *App) processCNameRecord(cNameRecord dns.CNAME) {
|
|||||||
Err(err).
|
Err(err).
|
||||||
Msg("failed to add address")
|
Msg("failed to add address")
|
||||||
} else {
|
} else {
|
||||||
log.Trace().
|
log.Debug().
|
||||||
Str("address", aRecord.Address.String()).
|
Str("address", aRecord.Address.String()).
|
||||||
Str("cNameDomain", name).
|
Str("cNameDomain", name).
|
||||||
Err(err).
|
|
||||||
Msg("add address")
|
Msg("add address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -415,19 +430,19 @@ func (a *App) processCNameRecord(cNameRecord dns.CNAME) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) handleRecord(rr dns.RR) {
|
func (a *App) handleRecord(rr dns.RR, clientAddr net.Addr, network *string) {
|
||||||
switch v := rr.(type) {
|
switch v := rr.(type) {
|
||||||
case *dns.A:
|
case *dns.A:
|
||||||
a.processARecord(*v)
|
a.processARecord(*v, clientAddr, network)
|
||||||
case *dns.CNAME:
|
case *dns.CNAME:
|
||||||
a.processCNameRecord(*v)
|
a.processCNameRecord(*v, clientAddr, network)
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) handleMessage(msg dns.Msg) {
|
func (a *App) handleMessage(msg dns.Msg, clientAddr net.Addr, network *string) {
|
||||||
for _, rr := range msg.Answer {
|
for _, rr := range msg.Answer {
|
||||||
a.handleRecord(rr)
|
a.handleRecord(rr, clientAddr, network)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,7 +525,7 @@ func New(config models.ConfigFile) (*App, error) {
|
|||||||
}
|
}
|
||||||
respMsg.Answer = respMsg.Answer[:idx]
|
respMsg.Answer = respMsg.Answer[:idx]
|
||||||
|
|
||||||
app.handleMessage(respMsg)
|
app.handleMessage(respMsg, clientAddr, &network)
|
||||||
|
|
||||||
return &respMsg, nil
|
return &respMsg, nil
|
||||||
}
|
}
|
||||||
|
64
main.go
64
main.go
@ -1,64 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"kvas2-go/models"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
|
||||||
|
|
||||||
cfgFile, err := os.ReadFile("config.yaml")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("failed to read config.yaml")
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := models.ConfigFile{}
|
|
||||||
err = yaml.Unmarshal(cfgFile, &cfg)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("failed to parse config.yaml")
|
|
||||||
}
|
|
||||||
|
|
||||||
app, err := New(cfg)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("failed to initialize application")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
|
|
||||||
log.Info().Msg("starting service")
|
|
||||||
|
|
||||||
/*
|
|
||||||
Starting app with graceful shutdown
|
|
||||||
*/
|
|
||||||
appResult := make(chan error)
|
|
||||||
go func() {
|
|
||||||
appResult <- app.Start(ctx)
|
|
||||||
}()
|
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case err, _ := <-appResult:
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("failed to start application")
|
|
||||||
}
|
|
||||||
log.Info().Msg("exiting application")
|
|
||||||
return
|
|
||||||
case <-c:
|
|
||||||
log.Info().Msg("shutting down service")
|
|
||||||
cancel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,6 +6,7 @@ type ConfigFile struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AppConfig struct {
|
type AppConfig struct {
|
||||||
|
LogLevel string `yaml:"logLevel"`
|
||||||
AdditionalTTL uint32 `yaml:"additionalTTL"`
|
AdditionalTTL uint32 `yaml:"additionalTTL"`
|
||||||
ChainPrefix string `yaml:"chainPrefix"`
|
ChainPrefix string `yaml:"chainPrefix"`
|
||||||
IPSetPrefix string `yaml:"ipsetPrefix"`
|
IPSetPrefix string `yaml:"ipsetPrefix"`
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
SOCKET_PATH="/opt/var/run/kvas2-go.sock"
|
SOCKET_PATH="/opt/var/run/kvas2.sock"
|
||||||
if [ ! -S "$SOCKET_PATH" ]; then
|
if [ ! -S "$SOCKET_PATH" ]; then
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
Loading…
x
Reference in New Issue
Block a user