Compare commits

..

43 Commits

Author SHA1 Message Date
Star Brilliant
82c5f0d327 Merge pull request #185 from shahradelahi/feature/bind-to-interface
Some checks failed
Docker / docker (client) (push) Failing after 33s
Docker / docker (server) (push) Failing after 31s
Go build for Linux / Build (push) Failing after 2m40s
2026-03-17 14:06:24 +00:00
Star Brilliant
602b3d6322 Merge pull request #186 from vinnyperella/patch-2 2026-01-23 18:43:00 +00:00
Vinny
db0bd43256 chore: upgrade dependencies 2026-01-23 17:26:28 +00:00
Shahrad Elahi
06e3d67f79 feat: support dual-stack for interface binding 2026-01-23 16:04:57 +00:00
Shahrad Elahi
d27aef852d feat: add option to bind outgoing connections to a specific interface
This adds a new `interface` configuration option to `doh-client` that allows users to specify a network interface for all outgoing DNS queries (including bootstrap and passthrough traffic).
2026-01-23 01:41:28 +00:00
Star Brilliant
6c561eb412 Merge pull request #181 from vinnyperella/patch-1 2025-11-18 20:38:06 +00:00
Vinny
381bf28a69 chore: upgrade dependencies 2025-11-18 16:19:55 +00:00
Star Brilliant
0b0651a015 Merge pull request #178 from vinnyperella/patch-1 2025-09-16 16:12:40 +00:00
Vinny
3130a747f8 chore: upgrade dependencies 2025-09-16 13:17:20 +00:00
Star Brilliant
fe9f9f9ad2 Merge pull request #176 from vinnyperella/patch-1 2025-06-17 17:18:03 +00:00
Vinny
00c6af00ed chore: upgrade dependencies 2025-06-17 17:15:43 +00:00
Star Brilliant
04f3e029ac Merge pull request #172 from bfahrenfort/patch-1
config: Add captive portal domains
2025-05-28 21:10:00 +00:00
bfahrenfort
87b3eedded doh-client: lint 2025-05-28 15:26:28 -05:00
Star Brilliant
c57a45deaa Merge pull request #174 from m13253/m13253/restart-backoff
Move StartLimitIntervalSec=0 from [Service] to [Unit]
2025-05-28 00:37:56 +00:00
Star Brilliant
8bc06acc6e Move StartLimitIntervalSec=0 from [Service] to [Unit]
This solves the warning message:
> systemd[1]: /usr/lib/systemd/system/doh-client.service:16: Unknown key 'StartLimitIntervalSec' in section [Service], ignoring.
2025-05-24 12:45:26 +00:00
Star Brilliant
0263a32c22 Merge pull request #173 from vinnyperella/patch-1 2025-05-18 00:10:28 +00:00
Vinny
354d0377b3 chore: upgrade dependencies 2025-05-14 19:26:12 +00:00
Star Brilliant
59a47c881b Merge pull request #171 from m13253/m13253/restart-backoff
When systemd service fail to start, use an exponential backoff delay to restart it
2025-05-13 01:50:24 +00:00
bfahrenfort
dfba0c36c5 config: Add captive portal domains 2025-05-12 15:48:41 -05:00
Star Brilliant
03da3a801f When systemd service fail to start, use an exponential backoff delay to restart it
This solves an issue that on (at least) Fedora and if NetworkManager starts too slow, systemd may stop trying to start it.
2025-05-09 00:12:11 +00:00
GreyXor
f13dea391f chore: v2.3.10 2025-03-29 01:02:43 +01:00
GreyXor
45edaad516 chore: upgrade dependencies 2025-03-29 01:00:16 +01:00
Star Brilliant
2179ee0054 Merge pull request #169 from vinnyperella/patch-4
Update go.yml
2025-03-28 14:07:47 +00:00
Vinny
6ddb1ad401 Update go.yml
Updated actions checkout/cache to v4.
2025-03-28 14:04:53 +00:00
GreyXor
35e0835949 chore: v2.3.9 2025-03-28 12:20:42 +01:00
GreyXor
5c744889be chore: upgrade dependencies 2025-03-28 11:47:07 +01:00
GreyXor
cb1c336217 chore: upgrade dependencies 2025-02-20 10:41:30 +01:00
GreyXor
f82ac1118e feat: new version 2.3.8 2025-01-28 09:09:13 +01:00
GreyXor
e5fef5690e chore: upgrade package dependencies 2025-01-28 09:07:28 +01:00
GreyXor
9c997f1491 Merge pull request #166 from vinnyperella/patch-3
chore: update dependencies
2025-01-27 22:51:34 +01:00
Vinny
d33fc60182 chore: update dependencies 2025-01-27 15:01:08 -05:00
Vinny
89bb7e95a6 chore: update dependencies 2025-01-27 14:58:41 -05:00
GreyXor
c5a06988d5 chore: upgrade dependencies 2024-12-28 18:17:23 +01:00
Satish Gaikwad
ea57996685 Merge pull request #162 from m13253/add-multi-upstream-dns-servers 2024-12-20 08:41:18 -08:00
Satish Gaikwad
0a1aa98a01 Updated comment 2024-12-19 22:27:26 +00:00
Satish Gaikwad
7ca84d162f Updated comment 2024-12-19 22:24:23 +00:00
Satish Gaikwad
0ea5c5015f Added a note for multiple DNS server support in the container image 2024-12-17 18:56:10 +00:00
Satish Gaikwad
65424da23f Update example to use multiple upstream DNS servers
Update example to use multiple upstream DNS servers
2024-12-17 10:41:51 -08:00
GreyXor
d35e6a6117 chore: upgrade package dependencies 2024-11-14 12:47:00 +01:00
Star Brilliant
4a98f0997b Update to actions/upload-artifact@v4 2024-11-13 18:58:47 +00:00
GreyXor
b70babf43e chore: upgrade package dependencies 2024-11-09 09:00:22 +01:00
GreyXor
967c43016c chore: upgrade package dependencies 2024-08-10 08:39:30 +02:00
GreyXor
a10da0ed10 Pre-bump to next version 2.3.7 2024-07-05 18:14:09 +02:00
12 changed files with 246 additions and 40 deletions

View File

@@ -10,18 +10,18 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.21
go-version: 1.25.6
id: go
- name: Check out repository
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Linux build
run: |
make
- name: Upload Linux build
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: linux-amd64
path: |
@@ -29,7 +29,7 @@ jobs:
doh-server/doh-server
- name: Cache
uses: actions/cache@v2
uses: actions/cache@v4
with:
# A directory to store and save the cache
path: ~/go/pkg/mod

36
.golangci.yml Normal file
View File

@@ -0,0 +1,36 @@
---
issues:
fix: true
linters:
enable-all: true
disable:
- importas
- depguard
- lll
- exhaustruct
- perfsprint
- gochecknoinits
- wsl
- exportloopref
linters-settings:
revive:
enable-all-rules: true
rules:
- name: line-length-limit
disabled: true
gocritic:
enabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
govet:
enable-all: true
gci:
sections:
- standard
- default
- prefix(github.com/m13253/dns-over-https/v2)
gofumpt:
extra-rules: true

View File

@@ -58,7 +58,7 @@ sudo make uninstall
```bash
docker run -d --name doh-server \
-p 8053:8053 \
-e UPSTREAM_DNS_SERVER="udp:8.8.8.8:53" \
-e UPSTREAM_DNS_SERVER="udp:208.67.222.222:53,udp:208.67.220.220:53" \
-e DOH_HTTP_PREFIX="/dns-query" \
-e DOH_SERVER_LISTEN=":8053" \
-e DOH_SERVER_TIMEOUT="10" \
@@ -66,6 +66,7 @@ docker run -d --name doh-server \
-e DOH_SERVER_VERBOSE="false" \
satishweb/doh-server
```
Note: Multiple Upstream DNS server support was added in the container image on 2024-12-19.
Feeling adventurous? Try the latest build:

View File

@@ -90,6 +90,29 @@ func NewClient(conf *config.Config) (c *Client, err error) {
Net: "tcp",
Timeout: time.Duration(conf.Other.Timeout) * time.Second,
}
if c.conf.Other.Interface != "" {
localV4, localV6, err := c.getInterfaceIPs()
if err != nil {
return nil, fmt.Errorf("failed to get interface IPs for %s: %v", c.conf.Other.Interface, err)
}
var localAddr net.IP
if localV4 != nil {
localAddr = localV4
} else {
localAddr = localV6
}
c.udpClient.Dialer = &net.Dialer{
Timeout: time.Duration(conf.Other.Timeout) * time.Second,
LocalAddr: &net.UDPAddr{IP: localAddr},
}
c.tcpClient.Dialer = &net.Dialer{
Timeout: time.Duration(conf.Other.Timeout) * time.Second,
LocalAddr: &net.TCPAddr{IP: localAddr},
}
}
for _, addr := range conf.Listen {
c.udpServers = append(c.udpServers, &dns.Server{
Addr: addr,
@@ -120,6 +143,38 @@ func NewClient(conf *config.Config) (c *Client, err error) {
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
var d net.Dialer
if c.conf.Other.Interface != "" {
localV4, localV6, err := c.getInterfaceIPs()
if err != nil {
log.Printf("Bootstrap dial warning: %v", err)
} else {
numServers := len(c.bootstrap)
bootstrap := c.bootstrap[rand.Intn(numServers)]
host, _, _ := net.SplitHostPort(bootstrap)
ip := net.ParseIP(host)
if ip != nil {
if ip.To4() != nil {
if localV4 != nil {
if strings.HasPrefix(network, "udp") {
d.LocalAddr = &net.UDPAddr{IP: localV4}
} else {
d.LocalAddr = &net.TCPAddr{IP: localV4}
}
}
} else {
if localV6 != nil {
if strings.HasPrefix(network, "udp") {
d.LocalAddr = &net.UDPAddr{IP: localV6}
} else {
d.LocalAddr = &net.TCPAddr{IP: localV6}
}
}
}
}
conn, err := d.DialContext(ctx, network, bootstrap)
return conn, err
}
}
numServers := len(c.bootstrap)
bootstrap := c.bootstrap[rand.Intn(numServers)]
conn, err := d.DialContext(ctx, network, bootstrap)
@@ -235,14 +290,72 @@ func (c *Client) newHTTPClient() error {
if c.httpTransport != nil {
c.httpTransport.CloseIdleConnections()
}
dialer := &net.Dialer{
localV4, localV6, err := c.getInterfaceIPs()
if err != nil {
log.Printf("Interface binding error: %v", err)
return err
}
baseDialer := &net.Dialer{
Timeout: time.Duration(c.conf.Other.Timeout) * time.Second,
KeepAlive: 30 * time.Second,
// DualStack: true,
Resolver: c.bootstrapResolver,
Resolver: c.bootstrapResolver,
}
c.httpTransport = &http.Transport{
DialContext: dialer.DialContext,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
if c.conf.Other.Interface == "" {
return baseDialer.DialContext(ctx, network, addr)
}
if network == "tcp4" && localV4 != nil {
d := *baseDialer
d.LocalAddr = &net.TCPAddr{IP: localV4}
return d.DialContext(ctx, network, addr)
}
if network == "tcp6" && localV6 != nil {
d := *baseDialer
d.LocalAddr = &net.TCPAddr{IP: localV6}
return d.DialContext(ctx, network, addr)
}
// Manual Dual-Stack: Resolve host and try compatible families sequentially
host, port, _ := net.SplitHostPort(addr)
ips, err := c.bootstrapResolver.LookupIPAddr(ctx, host)
if err != nil {
return nil, err
}
var lastErr error
for _, ip := range ips {
d := *baseDialer
targetAddr := net.JoinHostPort(ip.String(), port)
if ip.IP.To4() != nil {
if localV4 == nil {
continue
}
d.LocalAddr = &net.TCPAddr{IP: localV4}
} else {
if localV6 == nil {
continue
}
d.LocalAddr = &net.TCPAddr{IP: localV6}
}
conn, err := d.DialContext(ctx, "tcp", targetAddr)
if err == nil {
return conn, nil
}
lastErr = err
}
if lastErr != nil {
return nil, lastErr
}
return nil, fmt.Errorf("connection to %s failed: no matching local/remote IP families on interface %s", addr, c.conf.Other.Interface)
},
ExpectContinueTimeout: 1 * time.Second,
IdleConnTimeout: 90 * time.Second,
MaxIdleConns: 100,
@@ -251,15 +364,18 @@ func (c *Client) newHTTPClient() error {
TLSHandshakeTimeout: time.Duration(c.conf.Other.Timeout) * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: c.conf.Other.TLSInsecureSkipVerify},
}
if c.conf.Other.NoIPv6 {
originalDial := c.httpTransport.DialContext
c.httpTransport.DialContext = func(ctx context.Context, network, address string) (net.Conn, error) {
if strings.HasPrefix(network, "tcp") {
network = "tcp4"
}
return dialer.DialContext(ctx, network, address)
return originalDial(ctx, network, address)
}
}
err := http2.ConfigureTransport(c.httpTransport)
err = http2.ConfigureTransport(c.httpTransport)
if err != nil {
return err
}
@@ -485,3 +601,38 @@ func (c *Client) findClientIP(w dns.ResponseWriter, r *dns.Msg) (ednsClientAddre
}
return
}
// getInterfaceIPs returns the first valid IPv4 and IPv6 addresses found on the interface
func (c *Client) getInterfaceIPs() (v4, v6 net.IP, err error) {
if c.conf.Other.Interface == "" {
return nil, nil, nil
}
ifi, err := net.InterfaceByName(c.conf.Other.Interface)
if err != nil {
return nil, nil, err
}
addrs, err := ifi.Addrs()
if err != nil {
return nil, nil, err
}
for _, addr := range addrs {
ip, _, err := net.ParseCIDR(addr.String())
if err != nil {
continue
}
if ip4 := ip.To4(); ip4 != nil {
if v4 == nil {
v4 = ip4
}
} else {
if v6 == nil && !c.conf.Other.NoIPv6 {
v6 = ip
}
}
}
if v4 == nil && v6 == nil {
return nil, nil, fmt.Errorf("no valid IP addresses found on interface %s", c.conf.Other.Interface)
}
return v4, v6, nil
}

View File

@@ -50,6 +50,7 @@ type others struct {
Bootstrap []string `toml:"bootstrap"`
Passthrough []string `toml:"passthrough"`
Timeout uint `toml:"timeout"`
Interface string `toml:"interface"`
NoCookies bool `toml:"no_cookies"`
NoECS bool `toml:"no_ecs"`
NoIPv6 bool `toml:"no_ipv6"`

View File

@@ -81,7 +81,9 @@ passthrough = [
"captive.apple.com",
"connectivitycheck.gstatic.com",
"detectportal.firefox.com",
"globalreachtech.com",
"msftconnecttest.com",
"network-auth.com",
"nmcheck.gnome.org",
"pool.ntp.org",
@@ -95,6 +97,11 @@ passthrough = [
# Timeout for upstream request in seconds
timeout = 30
# Interface to bind to for outgoing connections.
# If empty, the system default route is used (usually eth0 or wlan0).
# Example: "eth1", "wlan0"
interface = ""
# Disable HTTP Cookies
#
# Cookies may be useful if your upstream resolver is protected by some

View File

@@ -24,6 +24,6 @@
package main
const (
VERSION = "2.3.6"
VERSION = "2.3.10"
USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
)

View File

@@ -24,6 +24,6 @@
package main
const (
VERSION = "2.3.6"
VERSION = "2.3.10"
USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
)

18
go.mod
View File

@@ -1,20 +1,20 @@
module github.com/m13253/dns-over-https/v2
go 1.20
go 1.24.0
require (
github.com/BurntSushi/toml v1.4.0
github.com/BurntSushi/toml v1.6.0
github.com/gorilla/handlers v1.5.2
github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc
github.com/miekg/dns v1.1.61
golang.org/x/net v0.27.0
github.com/miekg/dns v1.1.70
golang.org/x/net v0.49.0
)
require (
github.com/felixge/httpsnoop v1.0.4 // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/tools v0.22.0 // indirect
golang.org/x/mod v0.32.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect
golang.org/x/tools v0.41.0 // indirect
)

36
go.sum
View File

@@ -1,26 +1,30 @@
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc h1:RhT2pjLo3EVRmldbEcBdeRA7CGPWsNEJC+Y/N1aXQbg=
github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc/go.mod h1:BaIJzjD2ZnHmx2acPF6XfGLPzNCMiBbMRqJr+8/8uRI=
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
github.com/miekg/dns v1.1.70 h1:DZ4u2AV35VJxdD9Fo9fIWm119BsQL5cZU1cQ9s0LkqA=
github.com/miekg/dns v1.1.70/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -4,13 +4,16 @@ Documentation=https://github.com/m13253/dns-over-https
After=network.target
Before=nss-lookup.target
Wants=nss-lookup.target
StartLimitIntervalSec=0
[Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE
ExecStart=/usr/local/bin/doh-client -conf /etc/dns-over-https/doh-client.conf
LimitNOFILE=1048576
Restart=always
RestartSec=3
RestartSec=1s
RestartMaxDelaySec=76s
RestartSteps=9
Type=simple
DynamicUser=yes

View File

@@ -2,13 +2,16 @@
Description=DNS-over-HTTPS Server
Documentation=https://github.com/m13253/dns-over-https
After=network.target
StartLimitIntervalSec=0
[Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE
ExecStart=/usr/local/bin/doh-server -conf /etc/dns-over-https/doh-server.conf
LimitNOFILE=1048576
Restart=always
RestartSec=3
RestartSec=1s
RestartMaxDelaySec=76s
RestartSteps=9
Type=simple
DynamicUser=yes