Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e890c50da6 | ||
|
|
ddd9f4d021 | ||
|
|
7e58b4baee | ||
|
|
a21fbb9a4f | ||
|
|
3b7d27c919 | ||
|
|
68ddbfc0fe | ||
|
|
a2047cb800 | ||
|
|
fdd499146c | ||
|
|
37900341cf | ||
|
|
36bb368cad | ||
|
|
f9bdb219d0 | ||
|
|
0374c14e42 | ||
|
|
a035a151bd | ||
|
|
e69966381d | ||
|
|
94dfb2b1f2 | ||
|
|
92011205be | ||
|
|
c9707646bd | ||
|
|
c50705736b | ||
|
|
ec284c17f4 | ||
|
|
ad6c52dc4c | ||
|
|
5f182febae | ||
|
|
86d82c1098 | ||
|
|
842b9004da | ||
|
|
6ac7ca4f0f | ||
|
|
ddfcbe1bee | ||
|
|
88fd9388e4 | ||
|
|
69aafa53c9 | ||
|
|
3473fe9c15 | ||
|
|
c655500045 | ||
|
|
96a8015af6 | ||
|
|
ddd3876f92 | ||
|
|
f1f34722ee | ||
|
|
937c667ca8 | ||
|
|
3c45f57aaa | ||
|
|
30640eefe2 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -59,7 +59,7 @@ jobs:
|
||||
- name: Run tests in test container
|
||||
run: |
|
||||
touch coverage.txt
|
||||
docker run --rm \
|
||||
docker run --rm --device /dev/net/tun \
|
||||
-v "$(pwd)/coverage.txt:/tmp/gobuild/coverage.txt" \
|
||||
test-container
|
||||
|
||||
|
||||
2
.github/workflows/markdown.yml
vendored
2
.github/workflows/markdown.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: DavidAnson/markdownlint-cli2-action@v16
|
||||
- uses: DavidAnson/markdownlint-cli2-action@v18
|
||||
with:
|
||||
globs: "**.md"
|
||||
config: .markdownlint.json
|
||||
|
||||
@@ -29,7 +29,6 @@ linters:
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- bodyclose
|
||||
- canonicalheader
|
||||
- containedctx
|
||||
- copyloopvar
|
||||
- decorder
|
||||
|
||||
@@ -106,7 +106,7 @@ ENV VPN_SERVICE_PROVIDER=pia \
|
||||
WIREGUARD_PERSISTENT_KEEPALIVE_INTERVAL=0 \
|
||||
WIREGUARD_ADDRESSES= \
|
||||
WIREGUARD_ADDRESSES_SECRETFILE=/run/secrets/wireguard_addresses \
|
||||
WIREGUARD_MTU=1400 \
|
||||
WIREGUARD_MTU=1320 \
|
||||
WIREGUARD_IMPLEMENTATION=auto \
|
||||
# VPN server filtering
|
||||
SERVER_REGIONS= \
|
||||
@@ -125,6 +125,8 @@ ENV VPN_SERVICE_PROVIDER=pia \
|
||||
VPN_PORT_FORWARDING_STATUS_FILE="/tmp/gluetun/forwarded_port" \
|
||||
VPN_PORT_FORWARDING_USERNAME= \
|
||||
VPN_PORT_FORWARDING_PASSWORD= \
|
||||
VPN_PORT_FORWARDING_UP_COMMAND= \
|
||||
VPN_PORT_FORWARDING_DOWN_COMMAND= \
|
||||
# # Cyberghost only:
|
||||
OPENVPN_CERT= \
|
||||
OPENVPN_KEY= \
|
||||
|
||||
@@ -98,11 +98,13 @@ func main() {
|
||||
errorCh <- _main(ctx, buildInfo, args, logger, reader, tun, netLinker, cmder, cli)
|
||||
}()
|
||||
|
||||
// Wait for OS signal or run error
|
||||
var err error
|
||||
select {
|
||||
case signal := <-signalCh:
|
||||
case receivedSignal := <-signalCh:
|
||||
signal.Stop(signalCh)
|
||||
fmt.Println("")
|
||||
logger.Warn("Caught OS signal " + signal.String() + ", shutting down")
|
||||
logger.Warn("Caught OS signal " + receivedSignal.String() + ", shutting down")
|
||||
cancel()
|
||||
case err = <-errorCh:
|
||||
close(errorCh)
|
||||
@@ -113,15 +115,14 @@ func main() {
|
||||
cancel()
|
||||
}
|
||||
|
||||
// Shutdown timed sequence, and force exit on second OS signal
|
||||
const shutdownGracePeriod = 5 * time.Second
|
||||
timer := time.NewTimer(shutdownGracePeriod)
|
||||
select {
|
||||
case shutdownErr := <-errorCh:
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
timer.Stop()
|
||||
if shutdownErr != nil {
|
||||
logger.Warnf("Shutdown not completed gracefully: %s", shutdownErr)
|
||||
logger.Warnf("Shutdown failed: %s", shutdownErr)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -133,9 +134,6 @@ func main() {
|
||||
case <-timer.C:
|
||||
logger.Warn("Shutdown timed out")
|
||||
os.Exit(1)
|
||||
case signal := <-signalCh:
|
||||
logger.Warn("Caught OS signal " + signal.String() + ", forcing shut down")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,7 +380,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
|
||||
portForwardLogger := logger.New(log.SetComponent("port forwarding"))
|
||||
portForwardLooper := portforward.NewLoop(allSettings.VPN.Provider.PortForwarding,
|
||||
routingConf, httpClient, firewallConf, portForwardLogger, puid, pgid)
|
||||
routingConf, httpClient, firewallConf, portForwardLogger, cmder, puid, pgid)
|
||||
portForwardRunError, err := portForwardLooper.Start(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("starting port forwarding loop: %w", err)
|
||||
|
||||
52
go.mod
52
go.mod
@@ -3,27 +3,27 @@ module github.com/qdm12/gluetun
|
||||
go 1.23
|
||||
|
||||
require (
|
||||
github.com/breml/rootcerts v0.2.17
|
||||
github.com/fatih/color v1.17.0
|
||||
github.com/breml/rootcerts v0.2.19
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/klauspost/compress v1.17.9
|
||||
github.com/klauspost/compress v1.17.11
|
||||
github.com/klauspost/pgzip v1.2.6
|
||||
github.com/pelletier/go-toml/v2 v2.2.2
|
||||
github.com/qdm12/dns/v2 v2.0.0-rc6
|
||||
github.com/qdm12/gosettings v0.4.2
|
||||
github.com/pelletier/go-toml/v2 v2.2.3
|
||||
github.com/qdm12/dns/v2 v2.0.0-rc8
|
||||
github.com/qdm12/gosettings v0.4.4
|
||||
github.com/qdm12/goshutdown v0.3.0
|
||||
github.com/qdm12/gosplash v0.2.0
|
||||
github.com/qdm12/gotree v0.3.0
|
||||
github.com/qdm12/log v0.1.0
|
||||
github.com/qdm12/ss-server v0.6.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/ulikunitz/xz v0.5.11
|
||||
github.com/vishvananda/netlink v1.2.1
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||
golang.org/x/net v0.28.0
|
||||
golang.org/x/sys v0.24.0
|
||||
golang.org/x/text v0.17.0
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
|
||||
golang.org/x/net v0.31.0
|
||||
golang.org/x/sys v0.27.0
|
||||
golang.org/x/text v0.20.0
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
@@ -31,32 +31,32 @@ require (
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/josharian/native v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mdlayher/genetlink v1.3.2 // indirect
|
||||
github.com/mdlayher/netlink v1.7.2 // indirect
|
||||
github.com/mdlayher/socket v0.4.1 // indirect
|
||||
github.com/miekg/dns v1.1.55 // indirect
|
||||
github.com/miekg/dns v1.1.62 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.16.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.10.1 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.60.1 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/qdm12/goservices v0.1.0 // indirect
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
golang.org/x/crypto v0.29.0 // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/sync v0.9.0 // indirect
|
||||
golang.org/x/tools v0.26.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.69 // indirect
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.69 // indirect
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.70 // indirect
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 // indirect
|
||||
)
|
||||
|
||||
125
go.sum
125
go.sum
@@ -1,30 +1,23 @@
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/breml/rootcerts v0.2.17 h1:0/M2BE2Apw0qEJCXDOkaiu7d5Sx5ObNfe1BkImJ4u1I=
|
||||
github.com/breml/rootcerts v0.2.17/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/breml/rootcerts v0.2.19 h1:3D/qwAC1xoh82GmZ21mYzQ1NaLOICUVntIo+MRZYr4U=
|
||||
github.com/breml/rootcerts v0.2.19/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
|
||||
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
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/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -36,34 +29,36 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw=
|
||||
github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o=
|
||||
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
|
||||
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
|
||||
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
|
||||
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
||||
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
|
||||
github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
||||
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
||||
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
|
||||
github.com/qdm12/dns/v2 v2.0.0-rc6 h1:h5KpuqZ3IMoSbz2a0OkHzIVc9/jk2vuIm9RoKJuaI78=
|
||||
github.com/qdm12/dns/v2 v2.0.0-rc6/go.mod h1:Oh34IJIG55BgHoACOf+cgZCgDiFuiJZ6r6gQW58FN+k=
|
||||
github.com/qdm12/gosettings v0.4.2 h1:Gb39NScPr7OQV+oy0o1OD7A121udITDJuUGa7ljDF58=
|
||||
github.com/qdm12/gosettings v0.4.2/go.mod h1:CPrt2YC4UsURTrslmhxocVhMCW03lIrqdH2hzIf5prg=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
|
||||
github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/qdm12/dns/v2 v2.0.0-rc8 h1:kbgKPkbT+79nScfuZ0ZcVhksTGo8IUqQ8TTQGnQlZ18=
|
||||
github.com/qdm12/dns/v2 v2.0.0-rc8/go.mod h1:VaF02KWEL7xNV4oKfG4N9nEv/kR6bqyIcBReCV5NJhw=
|
||||
github.com/qdm12/goservices v0.1.0 h1:9sODefm/yuIGS7ynCkEnNlMTAYn9GzPhtcK4F69JWvc=
|
||||
github.com/qdm12/goservices v0.1.0/go.mod h1:/JOFsAnHFiSjyoXxa5FlfX903h20K5u/3rLzCjYVMck=
|
||||
github.com/qdm12/gosettings v0.4.4 h1:SM6tOZDf6k8qbjWU8KWyBF4mWIixfsKCfh9DGRLHlj4=
|
||||
github.com/qdm12/gosettings v0.4.4/go.mod h1:CPrt2YC4UsURTrslmhxocVhMCW03lIrqdH2hzIf5prg=
|
||||
github.com/qdm12/goshutdown v0.3.0 h1:pqBpJkdwlZlfTEx4QHtS8u8CXx6pG0fVo6S1N0MpSEM=
|
||||
github.com/qdm12/goshutdown v0.3.0/go.mod h1:EqZ46No00kCTZ5qzdd3qIzY6ayhMt24QI8Mh8LVQYmM=
|
||||
github.com/qdm12/gosplash v0.2.0 h1:DOxCEizbW6ZG+FgpH2oK1atT6bM8MHL9GZ2ywSS4zZY=
|
||||
@@ -76,17 +71,10 @@ github.com/qdm12/ss-server v0.6.0 h1:OaOdCIBXx0z3DGHPT6Th0v88vGa3MtAS4oRgUsDHGZE
|
||||
github.com/qdm12/ss-server v0.6.0/go.mod h1:0BO/zEmtTiLDlmQEcjtoHTC+w+cWxwItjBuGP6TWM78=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
|
||||
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/vishvananda/netlink v1.2.1 h1:pfLv/qlJUwOTPvtWREA7c3PI4u81YkqZw1DYhI2HmLA=
|
||||
@@ -99,23 +87,22 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -125,23 +112,22 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
|
||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
@@ -149,21 +135,18 @@ golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uI
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ=
|
||||
gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.69 h1:N0m3tKYbkRMmDobh/47ngz+AWeV7PcfXMDi8xu3Vrag=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.69/go.mod h1:Tk5Ip2TuxaWGpccL7//rAsLRH6RQ/jfqTGxuN/+i/FQ=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.69 h1:IdrOs1ZgwGw5CI+BH6GgVVlOt+LAXoPyh7enr8lfaXs=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.69/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.70 h1:QnLPkuDWWbD5C+3DUA2IUXai5TK6w2zff+MAGccqdsw=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.70/go.mod h1:/iBwcj9nbLejQitYvUm9caurITQ6WyNHibJk6Q9fiS4=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 h1:HsB2G/rEQiYyo1bGoQqHZ/Bvd6x1rERQTNdPr1FyWjI=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.70/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
|
||||
|
||||
150
internal/command/split.go
Normal file
150
internal/command/split.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCommandEmpty = errors.New("command is empty")
|
||||
ErrSingleQuoteUnterminated = errors.New("unterminated single-quoted string")
|
||||
ErrDoubleQuoteUnterminated = errors.New("unterminated double-quoted string")
|
||||
ErrEscapeUnterminated = errors.New("unterminated backslash-escape")
|
||||
)
|
||||
|
||||
// Split splits a command string into a slice of arguments.
|
||||
// This is especially important for commands such as:
|
||||
// /bin/sh -c "echo hello"
|
||||
// which should be split into: ["/bin/sh", "-c", "echo hello"]
|
||||
// It supports backslash-escapes, single-quotes and double-quotes.
|
||||
// It does not support:
|
||||
// - the $" quoting style.
|
||||
// - expansion (brace, shell or pathname).
|
||||
func Split(command string) (words []string, err error) {
|
||||
if command == "" {
|
||||
return nil, fmt.Errorf("%w", ErrCommandEmpty)
|
||||
}
|
||||
|
||||
const bufferSize = 1024
|
||||
buffer := bytes.NewBuffer(make([]byte, bufferSize))
|
||||
|
||||
startIndex := 0
|
||||
|
||||
for startIndex < len(command) {
|
||||
// skip any split characters at the start
|
||||
character, runeSize := utf8.DecodeRuneInString(command[startIndex:])
|
||||
switch {
|
||||
case strings.ContainsRune(" \n\t", character):
|
||||
startIndex += runeSize
|
||||
case character == '\\':
|
||||
// Look ahead to eventually skip an escaped newline
|
||||
if command[startIndex+runeSize:] == "" {
|
||||
return nil, fmt.Errorf("%w: %q", ErrEscapeUnterminated, command)
|
||||
}
|
||||
character, runeSize := utf8.DecodeRuneInString(command[startIndex+runeSize:])
|
||||
if character == '\n' {
|
||||
startIndex += runeSize + runeSize // backslash and newline
|
||||
}
|
||||
default:
|
||||
var word string
|
||||
buffer.Reset()
|
||||
word, startIndex, err = splitWord(command, startIndex, buffer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("splitting word in %q: %w", command, err)
|
||||
}
|
||||
words = append(words, word)
|
||||
}
|
||||
}
|
||||
return words, nil
|
||||
}
|
||||
|
||||
// WARNING: buffer must be cleared before calling this function.
|
||||
func splitWord(input string, startIndex int, buffer *bytes.Buffer) (
|
||||
word string, newStartIndex int, err error,
|
||||
) {
|
||||
cursor := startIndex
|
||||
for cursor < len(input) {
|
||||
character, runeLength := utf8.DecodeRuneInString(input[cursor:])
|
||||
cursor += runeLength
|
||||
if character == '"' ||
|
||||
character == '\'' ||
|
||||
character == '\\' ||
|
||||
character == ' ' ||
|
||||
character == '\n' ||
|
||||
character == '\t' {
|
||||
buffer.WriteString(input[startIndex : cursor-runeLength])
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.ContainsRune(" \n\t", character): // spacing character
|
||||
return buffer.String(), cursor, nil
|
||||
case character == '"':
|
||||
return handleDoubleQuoted(input, cursor, buffer)
|
||||
case character == '\'':
|
||||
return handleSingleQuoted(input, cursor, buffer)
|
||||
case character == '\\':
|
||||
return handleEscaped(input, cursor, buffer)
|
||||
}
|
||||
}
|
||||
|
||||
buffer.WriteString(input[startIndex:])
|
||||
return buffer.String(), len(input), nil
|
||||
}
|
||||
|
||||
func handleDoubleQuoted(input string, startIndex int, buffer *bytes.Buffer) (
|
||||
word string, newStartIndex int, err error,
|
||||
) {
|
||||
cursor := startIndex
|
||||
for cursor < len(input) {
|
||||
nextCharacter, nextRuneLength := utf8.DecodeRuneInString(input[cursor:])
|
||||
cursor += nextRuneLength
|
||||
switch nextCharacter {
|
||||
case '"': // end of the double quoted string
|
||||
buffer.WriteString(input[startIndex : cursor-nextRuneLength])
|
||||
return splitWord(input, cursor, buffer)
|
||||
case '\\': // escaped character
|
||||
escapedCharacter, escapedRuneLength := utf8.DecodeRuneInString(input[cursor:])
|
||||
cursor += escapedRuneLength
|
||||
if !strings.ContainsRune("$`\"\n\\", escapedCharacter) {
|
||||
break
|
||||
}
|
||||
buffer.WriteString(input[startIndex : cursor-nextRuneLength-escapedRuneLength])
|
||||
if escapedCharacter != '\n' {
|
||||
// skip backslash entirely for the newline character
|
||||
buffer.WriteRune(escapedCharacter)
|
||||
}
|
||||
startIndex = cursor
|
||||
}
|
||||
}
|
||||
return "", 0, fmt.Errorf("%w", ErrDoubleQuoteUnterminated)
|
||||
}
|
||||
|
||||
func handleSingleQuoted(input string, startIndex int, buffer *bytes.Buffer) (
|
||||
word string, newStartIndex int, err error,
|
||||
) {
|
||||
closingQuoteIndex := strings.IndexRune(input[startIndex:], '\'')
|
||||
if closingQuoteIndex == -1 {
|
||||
return "", 0, fmt.Errorf("%w", ErrSingleQuoteUnterminated)
|
||||
}
|
||||
buffer.WriteString(input[startIndex : startIndex+closingQuoteIndex])
|
||||
const singleQuoteRuneLength = 1
|
||||
startIndex += closingQuoteIndex + singleQuoteRuneLength
|
||||
return splitWord(input, startIndex, buffer)
|
||||
}
|
||||
|
||||
func handleEscaped(input string, startIndex int, buffer *bytes.Buffer) (
|
||||
word string, newStartIndex int, err error,
|
||||
) {
|
||||
if input[startIndex:] == "" {
|
||||
return "", 0, fmt.Errorf("%w", ErrEscapeUnterminated)
|
||||
}
|
||||
character, runeLength := utf8.DecodeRuneInString(input[startIndex:])
|
||||
if character != '\n' { // backslash-escaped newline is ignored
|
||||
buffer.WriteString(input[startIndex : startIndex+runeLength])
|
||||
}
|
||||
startIndex += runeLength
|
||||
return splitWord(input, startIndex, buffer)
|
||||
}
|
||||
110
internal/command/split_test.go
Normal file
110
internal/command/split_test.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_Split(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
command string
|
||||
words []string
|
||||
errWrapped error
|
||||
errMessage string
|
||||
}{
|
||||
"empty": {
|
||||
command: "",
|
||||
errWrapped: ErrCommandEmpty,
|
||||
errMessage: "command is empty",
|
||||
},
|
||||
"concrete_sh_command": {
|
||||
command: `/bin/sh -c "echo 123"`,
|
||||
words: []string{"/bin/sh", "-c", "echo 123"},
|
||||
},
|
||||
"single_word": {
|
||||
command: "word1",
|
||||
words: []string{"word1"},
|
||||
},
|
||||
"two_words_single_space": {
|
||||
command: "word1 word2",
|
||||
words: []string{"word1", "word2"},
|
||||
},
|
||||
"two_words_multiple_space": {
|
||||
command: "word1 word2",
|
||||
words: []string{"word1", "word2"},
|
||||
},
|
||||
"two_words_no_expansion": {
|
||||
command: "word1* word2?",
|
||||
words: []string{"word1*", "word2?"},
|
||||
},
|
||||
"escaped_single quote": {
|
||||
command: "ain\\'t good",
|
||||
words: []string{"ain't", "good"},
|
||||
},
|
||||
"escaped_single_quote_all_single_quoted": {
|
||||
command: "'ain'\\''t good'",
|
||||
words: []string{"ain't good"},
|
||||
},
|
||||
"empty_single_quoted": {
|
||||
command: "word1 '' word2",
|
||||
words: []string{"word1", "", "word2"},
|
||||
},
|
||||
"escaped_newline": {
|
||||
command: "word1\\\nword2",
|
||||
words: []string{"word1word2"},
|
||||
},
|
||||
"quoted_newline": {
|
||||
command: "text \"with\na\" quoted newline",
|
||||
words: []string{"text", "with\na", "quoted", "newline"},
|
||||
},
|
||||
"quoted_escaped_newline": {
|
||||
command: "\"word1\\d\\\\\\\" word2\\\nword3 word4\"",
|
||||
words: []string{"word1\\d\\\" word2word3 word4"},
|
||||
},
|
||||
"escaped_separated_newline": {
|
||||
command: "word1 \\\n word2",
|
||||
words: []string{"word1", "word2"},
|
||||
},
|
||||
"double_quotes_no_spacing": {
|
||||
command: "word1\"word2\"word3",
|
||||
words: []string{"word1word2word3"},
|
||||
},
|
||||
"unterminated_single_quote": {
|
||||
command: "'abc'\\''def",
|
||||
errWrapped: ErrSingleQuoteUnterminated,
|
||||
errMessage: `splitting word in "'abc'\\''def": unterminated single-quoted string`,
|
||||
},
|
||||
"unterminated_double_quote": {
|
||||
command: "\"abc'def",
|
||||
errWrapped: ErrDoubleQuoteUnterminated,
|
||||
errMessage: `splitting word in "\"abc'def": unterminated double-quoted string`,
|
||||
},
|
||||
"unterminated_escape": {
|
||||
command: "abc\\",
|
||||
errWrapped: ErrEscapeUnterminated,
|
||||
errMessage: `splitting word in "abc\\": unterminated backslash-escape`,
|
||||
},
|
||||
"unterminated_escape_only": {
|
||||
command: " \\",
|
||||
errWrapped: ErrEscapeUnterminated,
|
||||
errMessage: `unterminated backslash-escape: " \\"`,
|
||||
},
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
words, err := Split(testCase.command)
|
||||
|
||||
assert.Equal(t, testCase.words, words)
|
||||
assert.ErrorIs(t, err, testCase.errWrapped)
|
||||
if testCase.errWrapped != nil {
|
||||
assert.EqualError(t, err, testCase.errMessage)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,14 @@ type PortForwarding struct {
|
||||
// to write to a file. It cannot be nil for the
|
||||
// internal state
|
||||
Filepath *string `json:"status_file_path"`
|
||||
// UpCommand is the command to use when the port forwarding is up.
|
||||
// It can be the empty string to indicate not to run a command.
|
||||
// It cannot be nil in the internal state.
|
||||
UpCommand *string `json:"up_command"`
|
||||
// DownCommand is the command to use after the port forwarding goes down.
|
||||
// It can be the empty string to indicate to NOT run a command.
|
||||
// It cannot be nil in the internal state.
|
||||
DownCommand *string `json:"down_command"`
|
||||
// ListeningPort is the port traffic would be redirected to from the
|
||||
// forwarded port. The redirection is disabled if it is set to 0, which
|
||||
// is its default as well.
|
||||
@@ -84,6 +92,8 @@ func (p *PortForwarding) Copy() (copied PortForwarding) {
|
||||
Enabled: gosettings.CopyPointer(p.Enabled),
|
||||
Provider: gosettings.CopyPointer(p.Provider),
|
||||
Filepath: gosettings.CopyPointer(p.Filepath),
|
||||
UpCommand: gosettings.CopyPointer(p.UpCommand),
|
||||
DownCommand: gosettings.CopyPointer(p.DownCommand),
|
||||
ListeningPort: gosettings.CopyPointer(p.ListeningPort),
|
||||
Username: p.Username,
|
||||
Password: p.Password,
|
||||
@@ -94,6 +104,8 @@ func (p *PortForwarding) OverrideWith(other PortForwarding) {
|
||||
p.Enabled = gosettings.OverrideWithPointer(p.Enabled, other.Enabled)
|
||||
p.Provider = gosettings.OverrideWithPointer(p.Provider, other.Provider)
|
||||
p.Filepath = gosettings.OverrideWithPointer(p.Filepath, other.Filepath)
|
||||
p.UpCommand = gosettings.OverrideWithPointer(p.UpCommand, other.UpCommand)
|
||||
p.DownCommand = gosettings.OverrideWithPointer(p.DownCommand, other.DownCommand)
|
||||
p.ListeningPort = gosettings.OverrideWithPointer(p.ListeningPort, other.ListeningPort)
|
||||
p.Username = gosettings.OverrideWithComparable(p.Username, other.Username)
|
||||
p.Password = gosettings.OverrideWithComparable(p.Password, other.Password)
|
||||
@@ -103,6 +115,8 @@ func (p *PortForwarding) setDefaults() {
|
||||
p.Enabled = gosettings.DefaultPointer(p.Enabled, false)
|
||||
p.Provider = gosettings.DefaultPointer(p.Provider, "")
|
||||
p.Filepath = gosettings.DefaultPointer(p.Filepath, "/tmp/gluetun/forwarded_port")
|
||||
p.UpCommand = gosettings.DefaultPointer(p.UpCommand, "")
|
||||
p.DownCommand = gosettings.DefaultPointer(p.DownCommand, "")
|
||||
p.ListeningPort = gosettings.DefaultPointer(p.ListeningPort, 0)
|
||||
}
|
||||
|
||||
@@ -135,6 +149,13 @@ func (p PortForwarding) toLinesNode() (node *gotree.Node) {
|
||||
}
|
||||
node.Appendf("Forwarded port file path: %s", filepath)
|
||||
|
||||
if *p.UpCommand != "" {
|
||||
node.Appendf("Forwarded port up command: %s", *p.UpCommand)
|
||||
}
|
||||
if *p.DownCommand != "" {
|
||||
node.Appendf("Forwarded port down command: %s", *p.DownCommand)
|
||||
}
|
||||
|
||||
if p.Username != "" {
|
||||
credentialsNode := node.Appendf("Credentials:")
|
||||
credentialsNode.Appendf("Username: %s", p.Username)
|
||||
@@ -163,6 +184,12 @@ func (p *PortForwarding) read(r *reader.Reader) (err error) {
|
||||
"PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING_STATUS_FILE",
|
||||
))
|
||||
|
||||
p.UpCommand = r.Get("VPN_PORT_FORWARDING_UP_COMMAND",
|
||||
reader.ForceLowercase(false))
|
||||
|
||||
p.DownCommand = r.Get("VPN_PORT_FORWARDING_DOWN_COMMAND",
|
||||
reader.ForceLowercase(false))
|
||||
|
||||
p.ListeningPort, err = r.Uint16Ptr("VPN_PORT_FORWARDING_LISTENING_PORT")
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -39,9 +39,12 @@ type Wireguard struct {
|
||||
PersistentKeepaliveInterval *time.Duration `json:"persistent_keep_alive_interval"`
|
||||
// Maximum Transmission Unit (MTU) of the Wireguard interface.
|
||||
// It cannot be zero in the internal state, and defaults to
|
||||
// 1400. Note it is not the wireguard-go MTU default of 1420
|
||||
// 1320. Note it is not the wireguard-go MTU default of 1420
|
||||
// because this impacts bandwidth a lot on some VPN providers,
|
||||
// see https://github.com/qdm12/gluetun/issues/1650.
|
||||
// It has been lowered to 1320 following quite a bit of
|
||||
// investigation in the issue:
|
||||
// https://github.com/qdm12/gluetun/issues/2533.
|
||||
MTU uint16 `json:"mtu"`
|
||||
// Implementation is the Wireguard implementation to use.
|
||||
// It can be "auto", "userspace" or "kernelspace".
|
||||
@@ -191,7 +194,7 @@ func (w *Wireguard) setDefaults(vpnProvider string) {
|
||||
w.AllowedIPs = gosettings.DefaultSlice(w.AllowedIPs, defaultAllowedIPs)
|
||||
w.PersistentKeepaliveInterval = gosettings.DefaultPointer(w.PersistentKeepaliveInterval, 0)
|
||||
w.Interface = gosettings.DefaultComparable(w.Interface, "wg0")
|
||||
const defaultMTU = 1400
|
||||
const defaultMTU = 1320
|
||||
w.MTU = gosettings.DefaultComparable(w.MTU, defaultMTU)
|
||||
w.Implementation = gosettings.DefaultComparable(w.Implementation, "auto")
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/dns/v2/pkg/dot"
|
||||
"github.com/qdm12/dns/v2/pkg/middlewares/filter/mapfilter"
|
||||
"github.com/qdm12/dns/v2/pkg/server"
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/dns/state"
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
type Loop struct {
|
||||
statusManager *loopstate.State
|
||||
state *state.State
|
||||
server *dot.Server
|
||||
server *server.Server
|
||||
filter *mapfilter.Filter
|
||||
resolvConf string
|
||||
client *http.Client
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
filtermiddleware "github.com/qdm12/dns/v2/pkg/middlewares/filter"
|
||||
"github.com/qdm12/dns/v2/pkg/middlewares/filter/mapfilter"
|
||||
"github.com/qdm12/dns/v2/pkg/provider"
|
||||
"github.com/qdm12/dns/v2/pkg/server"
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||
)
|
||||
|
||||
@@ -23,53 +24,51 @@ func (l *Loop) SetSettings(ctx context.Context, settings settings.DNS) (
|
||||
|
||||
func buildDoTSettings(settings settings.DNS,
|
||||
filter *mapfilter.Filter, logger Logger) (
|
||||
dotSettings dot.ServerSettings, err error,
|
||||
serverSettings server.Settings, err error,
|
||||
) {
|
||||
var middlewares []dot.Middleware
|
||||
serverSettings.Logger = logger
|
||||
|
||||
var dotSettings dot.Settings
|
||||
providersData := provider.NewProviders()
|
||||
dotSettings.UpstreamResolvers = make([]provider.Provider, len(settings.DoT.Providers))
|
||||
for i := range settings.DoT.Providers {
|
||||
var err error
|
||||
dotSettings.UpstreamResolvers[i], err = providersData.Get(settings.DoT.Providers[i])
|
||||
if err != nil {
|
||||
panic(err) // this should already had been checked
|
||||
}
|
||||
}
|
||||
dotSettings.IPVersion = "ipv4"
|
||||
if *settings.DoT.IPv6 {
|
||||
dotSettings.IPVersion = "ipv6"
|
||||
}
|
||||
|
||||
serverSettings.Dialer, err = dot.New(dotSettings)
|
||||
if err != nil {
|
||||
return server.Settings{}, fmt.Errorf("creating DNS over TLS dialer: %w", err)
|
||||
}
|
||||
|
||||
if *settings.DoT.Caching {
|
||||
lruCache, err := lru.New(lru.Settings{})
|
||||
if err != nil {
|
||||
return dot.ServerSettings{}, fmt.Errorf("creating LRU cache: %w", err)
|
||||
return server.Settings{}, fmt.Errorf("creating LRU cache: %w", err)
|
||||
}
|
||||
cacheMiddleware, err := cachemiddleware.New(cachemiddleware.Settings{
|
||||
Cache: lruCache,
|
||||
})
|
||||
if err != nil {
|
||||
return dot.ServerSettings{}, fmt.Errorf("creating cache middleware: %w", err)
|
||||
return server.Settings{}, fmt.Errorf("creating cache middleware: %w", err)
|
||||
}
|
||||
middlewares = append(middlewares, cacheMiddleware)
|
||||
serverSettings.Middlewares = append(serverSettings.Middlewares, cacheMiddleware)
|
||||
}
|
||||
|
||||
filterMiddleware, err := filtermiddleware.New(filtermiddleware.Settings{
|
||||
Filter: filter,
|
||||
})
|
||||
if err != nil {
|
||||
return dot.ServerSettings{}, fmt.Errorf("creating filter middleware: %w", err)
|
||||
return server.Settings{}, fmt.Errorf("creating filter middleware: %w", err)
|
||||
}
|
||||
middlewares = append(middlewares, filterMiddleware)
|
||||
serverSettings.Middlewares = append(serverSettings.Middlewares, filterMiddleware)
|
||||
|
||||
providersData := provider.NewProviders()
|
||||
providers := make([]provider.Provider, len(settings.DoT.Providers))
|
||||
for i := range settings.DoT.Providers {
|
||||
var err error
|
||||
providers[i], err = providersData.Get(settings.DoT.Providers[i])
|
||||
if err != nil {
|
||||
panic(err) // this should already had been checked
|
||||
}
|
||||
}
|
||||
|
||||
ipVersion := "ipv4"
|
||||
if *settings.DoT.IPv6 {
|
||||
ipVersion = "ipv6"
|
||||
}
|
||||
return dot.ServerSettings{
|
||||
Resolver: dot.ResolverSettings{
|
||||
UpstreamResolvers: providers,
|
||||
IPVersion: ipVersion,
|
||||
Warner: logger,
|
||||
},
|
||||
Middlewares: middlewares,
|
||||
Logger: logger,
|
||||
}, nil
|
||||
return serverSettings, nil
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/qdm12/dns/v2/pkg/check"
|
||||
"github.com/qdm12/dns/v2/pkg/dot"
|
||||
"github.com/qdm12/dns/v2/pkg/nameserver"
|
||||
"github.com/qdm12/dns/v2/pkg/server"
|
||||
)
|
||||
|
||||
var errUpdateBlockLists = errors.New("cannot update filter block lists")
|
||||
@@ -25,12 +25,12 @@ func (l *Loop) setupServer(ctx context.Context) (runError <-chan error, err erro
|
||||
return nil, fmt.Errorf("building DoT settings: %w", err)
|
||||
}
|
||||
|
||||
server, err := dot.NewServer(dotSettings)
|
||||
server, err := server.New(dotSettings)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating DoT server: %w", err)
|
||||
}
|
||||
|
||||
runError, err = server.Start()
|
||||
runError, err = server.Start(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("starting server: %w", err)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ type chainRule struct {
|
||||
packets uint64
|
||||
bytes uint64
|
||||
target string // "ACCEPT", "DROP", "REJECT" or "REDIRECT"
|
||||
protocol string // "tcp", "udp" or "" for all protocols.
|
||||
protocol string // "icmp", "tcp", "udp" or "" for all protocols.
|
||||
inputInterface string // input interface, for example "tun0" or "*""
|
||||
outputInterface string // output interface, for example "eth0" or "*""
|
||||
source netip.Prefix // source IP CIDR, for example 0.0.0.0/0. Must be valid.
|
||||
@@ -324,6 +324,8 @@ var ErrProtocolUnknown = errors.New("unknown protocol")
|
||||
func parseProtocol(s string) (protocol string, err error) {
|
||||
switch s {
|
||||
case "0":
|
||||
case "1":
|
||||
protocol = "icmp"
|
||||
case "6":
|
||||
protocol = "tcp"
|
||||
case "17":
|
||||
|
||||
@@ -56,7 +56,8 @@ num pkts bytes target prot opt in out source destinati
|
||||
num pkts bytes target prot opt in out source destination
|
||||
1 0 0 ACCEPT 17 -- tun0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:55405
|
||||
2 0 0 ACCEPT 6 -- tun0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:55405
|
||||
3 0 0 DROP 0 -- tun0 * 1.2.3.4 0.0.0.0/0
|
||||
3 0 0 ACCEPT 1 -- tun0 * 0.0.0.0/0 0.0.0.0/0
|
||||
4 0 0 DROP 0 -- tun0 * 1.2.3.4 0.0.0.0/0
|
||||
`,
|
||||
table: chain{
|
||||
name: "INPUT",
|
||||
@@ -92,6 +93,17 @@ num pkts bytes target prot opt in out source destinati
|
||||
lineNumber: 3,
|
||||
packets: 0,
|
||||
bytes: 0,
|
||||
target: "ACCEPT",
|
||||
protocol: "icmp",
|
||||
inputInterface: "tun0",
|
||||
outputInterface: "*",
|
||||
source: netip.MustParsePrefix("0.0.0.0/0"),
|
||||
destination: netip.MustParsePrefix("0.0.0.0/0"),
|
||||
},
|
||||
{
|
||||
lineNumber: 4,
|
||||
packets: 0,
|
||||
bytes: 0,
|
||||
target: "DROP",
|
||||
protocol: "",
|
||||
inputInterface: "tun0",
|
||||
|
||||
@@ -92,7 +92,7 @@ func testIptablesPath(ctx context.Context, path string,
|
||||
// Set policy as the existing policy so no mutation is done.
|
||||
// This is an extra check for some buggy kernels where setting the policy
|
||||
// does not work.
|
||||
cmd = exec.CommandContext(ctx, path, "-L", "INPUT")
|
||||
cmd = exec.CommandContext(ctx, path, "-nL", "INPUT")
|
||||
output, err = runner.Run(cmd)
|
||||
if err != nil {
|
||||
unsupportedMessage = fmt.Sprintf("%s (%s)", output, err)
|
||||
|
||||
@@ -24,7 +24,7 @@ func newDeleteTestRuleMatcher(path string) *cmdMatcher {
|
||||
|
||||
func newListInputRulesMatcher(path string) *cmdMatcher {
|
||||
return newCmdMatcher(path,
|
||||
"^-L$", "^INPUT$")
|
||||
"^-nL$", "^INPUT$")
|
||||
}
|
||||
|
||||
func newSetPolicyMatcher(path, inputPolicy string) *cmdMatcher { //nolint:unparam
|
||||
|
||||
@@ -2,9 +2,11 @@ package healthcheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -51,7 +53,7 @@ func (s *Server) runHealthcheckLoop(ctx context.Context, done chan<- struct{}) {
|
||||
select {
|
||||
case <-s.vpn.healthyTimer.C:
|
||||
timeoutIndex = 0 // retry next with the smallest timeout
|
||||
s.onUnhealthyVPN(ctx)
|
||||
s.onUnhealthyVPN(ctx, err.Error())
|
||||
default:
|
||||
}
|
||||
case previousErr == nil && err == nil: // Nth success
|
||||
@@ -79,6 +81,22 @@ func (s *Server) healthCheck(ctx context.Context) (err error) {
|
||||
return fmt.Errorf("dialing: %w", err)
|
||||
}
|
||||
|
||||
if strings.HasSuffix(address, ":443") {
|
||||
host, _, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
return fmt.Errorf("splitting host and port: %w", err)
|
||||
}
|
||||
tlsConfig := &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
ServerName: host,
|
||||
}
|
||||
tlsConnection := tls.Client(connection, tlsConfig)
|
||||
err = tlsConnection.HandshakeContext(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("running TLS handshake: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = connection.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("closing connection: %w", err)
|
||||
|
||||
@@ -13,9 +13,9 @@ type vpnHealth struct {
|
||||
healthyTimer *time.Timer
|
||||
}
|
||||
|
||||
func (s *Server) onUnhealthyVPN(ctx context.Context) {
|
||||
func (s *Server) onUnhealthyVPN(ctx context.Context, lastErrMessage string) {
|
||||
s.logger.Info("program has been unhealthy for " +
|
||||
s.vpn.healthyWait.String() + ": restarting VPN")
|
||||
s.vpn.healthyWait.String() + ": restarting VPN (healthcheck error: " + lastErrMessage + ")")
|
||||
s.logger.Info("👉 See https://github.com/qdm12/gluetun-wiki/blob/main/faq/healthcheck.md")
|
||||
s.logger.Info("DO NOT OPEN AN ISSUE UNLESS YOU READ AND TRIED EACH POSSIBLE SOLUTION")
|
||||
_, _ = s.vpn.loop.ApplyStatus(ctx, constants.Stopped)
|
||||
|
||||
@@ -2,6 +2,7 @@ package natpmp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -23,14 +24,15 @@ func Test_Client_ExternalAddress(t *testing.T) {
|
||||
durationSinceStartOfEpoch time.Duration
|
||||
externalIPv4Address netip.Addr
|
||||
err error
|
||||
errMessage string
|
||||
errMessageRegex string
|
||||
}{
|
||||
"failure": {
|
||||
ctx: canceledCtx,
|
||||
gateway: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
|
||||
initialConnDuration: initialConnectionDuration,
|
||||
err: context.Canceled,
|
||||
errMessage: "executing remote procedure call: reading from udp connection: context canceled",
|
||||
err: net.ErrClosed,
|
||||
errMessageRegex: "executing remote procedure call: setting connection deadline: " +
|
||||
"set udp 127.0.0.1:[1-9][0-9]{1,4}: use of closed network connection",
|
||||
},
|
||||
"success": {
|
||||
ctx: context.Background(),
|
||||
@@ -60,7 +62,7 @@ func Test_Client_ExternalAddress(t *testing.T) {
|
||||
durationSinceStartOfEpoch, externalIPv4Address, err := client.ExternalAddress(testCase.ctx, testCase.gateway)
|
||||
assert.ErrorIs(t, err, testCase.err)
|
||||
if testCase.err != nil {
|
||||
assert.EqualError(t, err, testCase.errMessage)
|
||||
assert.Regexp(t, testCase.errMessageRegex, err.Error())
|
||||
}
|
||||
assert.Equal(t, testCase.durationSinceStartOfEpoch, durationSinceStartOfEpoch)
|
||||
assert.Equal(t, testCase.externalIPv4Address, externalIPv4Address)
|
||||
|
||||
@@ -45,8 +45,10 @@ func (c *Client) rpc(ctx context.Context, gateway netip.Addr,
|
||||
cancel()
|
||||
<-endGoroutineDone
|
||||
}()
|
||||
ctxListeningReady := make(chan struct{})
|
||||
go func() {
|
||||
defer close(endGoroutineDone)
|
||||
close(ctxListeningReady)
|
||||
// Context is canceled either by the parent context or
|
||||
// when this function returns.
|
||||
<-ctx.Done()
|
||||
@@ -60,6 +62,7 @@ func (c *Client) rpc(ctx context.Context, gateway netip.Addr,
|
||||
}
|
||||
err = fmt.Errorf("%w; closing connection: %w", err, closeErr)
|
||||
}()
|
||||
<-ctxListeningReady // really to make unit testing reliable
|
||||
|
||||
const maxResponseSize = 16
|
||||
response = make([]byte, maxResponseSize)
|
||||
|
||||
@@ -77,7 +77,18 @@ func netlinkRuleToRule(netlinkRule netlink.Rule) (rule Rule) {
|
||||
}
|
||||
|
||||
func ruleDbgMsg(add bool, rule Rule) (debugMessage string) {
|
||||
debugMessage = "ip rule"
|
||||
debugMessage = "ip"
|
||||
|
||||
switch rule.Family {
|
||||
case FamilyV4:
|
||||
debugMessage += " -f inet"
|
||||
case FamilyV6:
|
||||
debugMessage += " -f inet6"
|
||||
default:
|
||||
debugMessage += " -f " + fmt.Sprint(rule.Family)
|
||||
}
|
||||
|
||||
debugMessage += " rule"
|
||||
|
||||
if add {
|
||||
debugMessage += " add"
|
||||
|
||||
@@ -15,26 +15,28 @@ func Test_ruleDbgMsg(t *testing.T) {
|
||||
dbgMsg string
|
||||
}{
|
||||
"default values": {
|
||||
dbgMsg: "ip rule del pref 0",
|
||||
dbgMsg: "ip -f 0 rule del pref 0",
|
||||
},
|
||||
"add rule": {
|
||||
add: true,
|
||||
rule: Rule{
|
||||
Family: FamilyV4,
|
||||
Src: makeNetipPrefix(1),
|
||||
Dst: makeNetipPrefix(2),
|
||||
Table: 100,
|
||||
Priority: 101,
|
||||
},
|
||||
dbgMsg: "ip rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 100 pref 101",
|
||||
dbgMsg: "ip -f inet rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 100 pref 101",
|
||||
},
|
||||
"del rule": {
|
||||
rule: Rule{
|
||||
Family: FamilyV4,
|
||||
Src: makeNetipPrefix(1),
|
||||
Dst: makeNetipPrefix(2),
|
||||
Table: 100,
|
||||
Priority: 101,
|
||||
},
|
||||
dbgMsg: "ip rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 100 pref 101",
|
||||
dbgMsg: "ip -f inet rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 100 pref 101",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package portforward
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
@@ -29,3 +30,8 @@ type Logger interface {
|
||||
Warn(s string)
|
||||
Error(s string)
|
||||
}
|
||||
|
||||
type Cmder interface {
|
||||
Start(cmd *exec.Cmd) (stdoutLines, stderrLines <-chan string,
|
||||
waitError <-chan error, startErr error)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ type Loop struct {
|
||||
client *http.Client
|
||||
portAllower PortAllower
|
||||
logger Logger
|
||||
cmder Cmder
|
||||
// Fixed parameters
|
||||
uid, gid int
|
||||
// Internal channels and locks
|
||||
@@ -34,7 +35,7 @@ type Loop struct {
|
||||
|
||||
func NewLoop(settings settings.PortForwarding, routing Routing,
|
||||
client *http.Client, portAllower PortAllower,
|
||||
logger Logger, uid, gid int,
|
||||
logger Logger, cmder Cmder, uid, gid int,
|
||||
) *Loop {
|
||||
return &Loop{
|
||||
settings: Settings{
|
||||
@@ -42,6 +43,8 @@ func NewLoop(settings settings.PortForwarding, routing Routing,
|
||||
Service: service.Settings{
|
||||
Enabled: settings.Enabled,
|
||||
Filepath: *settings.Filepath,
|
||||
UpCommand: *settings.UpCommand,
|
||||
DownCommand: *settings.DownCommand,
|
||||
ListeningPort: *settings.ListeningPort,
|
||||
},
|
||||
},
|
||||
@@ -49,6 +52,7 @@ func NewLoop(settings settings.PortForwarding, routing Routing,
|
||||
client: client,
|
||||
portAllower: portAllower,
|
||||
logger: logger,
|
||||
cmder: cmder,
|
||||
uid: uid,
|
||||
gid: gid,
|
||||
}
|
||||
@@ -115,7 +119,7 @@ func (l *Loop) run(runCtx context.Context, runDone chan<- struct{},
|
||||
*serviceSettings.Enabled = *serviceSettings.Enabled && *l.settings.VPNIsUp
|
||||
|
||||
l.service = service.New(serviceSettings, l.routing, l.client,
|
||||
l.portAllower, l.logger, l.uid, l.gid)
|
||||
l.portAllower, l.logger, l.cmder, l.uid, l.gid)
|
||||
|
||||
var err error
|
||||
serviceRunError, err = l.service.Start(runCtx)
|
||||
|
||||
59
internal/portforward/service/command.go
Normal file
59
internal/portforward/service/command.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/command"
|
||||
)
|
||||
|
||||
func runCommand(ctx context.Context, cmder Cmder, logger Logger,
|
||||
commandTemplate string, ports []uint16,
|
||||
) (err error) {
|
||||
portStrings := make([]string, len(ports))
|
||||
for i, port := range ports {
|
||||
portStrings[i] = fmt.Sprint(int(port))
|
||||
}
|
||||
portsString := strings.Join(portStrings, ",")
|
||||
commandString := strings.ReplaceAll(commandTemplate, "{{PORTS}}", portsString)
|
||||
args, err := command.Split(commandString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing command: %w", err)
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, args[0], args[1:]...) // #nosec G204
|
||||
stdout, stderr, waitError, err := cmder.Start(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
streamCtx, streamCancel := context.WithCancel(context.Background())
|
||||
streamDone := make(chan struct{})
|
||||
go streamLines(streamCtx, streamDone, logger, stdout, stderr)
|
||||
|
||||
err = <-waitError
|
||||
streamCancel()
|
||||
<-streamDone
|
||||
return err
|
||||
}
|
||||
|
||||
func streamLines(ctx context.Context, done chan<- struct{},
|
||||
logger Logger, stdout, stderr <-chan string,
|
||||
) {
|
||||
defer close(done)
|
||||
|
||||
var line string
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case line = <-stdout:
|
||||
logger.Info(line)
|
||||
case line = <-stderr:
|
||||
logger.Error(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
28
internal/portforward/service/command_test.go
Normal file
28
internal/portforward/service/command_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
//go:build linux
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
"github.com/qdm12/gluetun/internal/command"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_Service_runCommand(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctrl := gomock.NewController(t)
|
||||
|
||||
ctx := context.Background()
|
||||
cmder := command.New()
|
||||
const commandTemplate = `/bin/sh -c "echo {{PORTS}}"`
|
||||
ports := []uint16{1234, 5678}
|
||||
logger := NewMockLogger(ctrl)
|
||||
logger.EXPECT().Info("1234,5678")
|
||||
|
||||
err := runCommand(ctx, cmder, logger, commandTemplate, ports)
|
||||
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
"os/exec"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
)
|
||||
@@ -32,3 +33,8 @@ type PortForwarder interface {
|
||||
ports []uint16, err error)
|
||||
KeepPortForward(ctx context.Context, objects utils.PortForwardObjects) (err error)
|
||||
}
|
||||
|
||||
type Cmder interface {
|
||||
Start(cmd *exec.Cmd) (stdoutLines, stderrLines <-chan string,
|
||||
waitError <-chan error, startErr error)
|
||||
}
|
||||
|
||||
3
internal/portforward/service/mocks_generate_test.go
Normal file
3
internal/portforward/service/mocks_generate_test.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package service
|
||||
|
||||
//go:generate mockgen -destination=mocks_test.go -package=$GOPACKAGE . Logger
|
||||
82
internal/portforward/service/mocks_test.go
Normal file
82
internal/portforward/service/mocks_test.go
Normal file
@@ -0,0 +1,82 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/qdm12/gluetun/internal/portforward/service (interfaces: Logger)
|
||||
|
||||
// Package service is a generated GoMock package.
|
||||
package service
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockLogger is a mock of Logger interface.
|
||||
type MockLogger struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockLoggerMockRecorder
|
||||
}
|
||||
|
||||
// MockLoggerMockRecorder is the mock recorder for MockLogger.
|
||||
type MockLoggerMockRecorder struct {
|
||||
mock *MockLogger
|
||||
}
|
||||
|
||||
// NewMockLogger creates a new mock instance.
|
||||
func NewMockLogger(ctrl *gomock.Controller) *MockLogger {
|
||||
mock := &MockLogger{ctrl: ctrl}
|
||||
mock.recorder = &MockLoggerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockLogger) EXPECT() *MockLoggerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Debug mocks base method.
|
||||
func (m *MockLogger) Debug(arg0 string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Debug", arg0)
|
||||
}
|
||||
|
||||
// Debug indicates an expected call of Debug.
|
||||
func (mr *MockLoggerMockRecorder) Debug(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockLogger)(nil).Debug), arg0)
|
||||
}
|
||||
|
||||
// Error mocks base method.
|
||||
func (m *MockLogger) Error(arg0 string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Error", arg0)
|
||||
}
|
||||
|
||||
// Error indicates an expected call of Error.
|
||||
func (mr *MockLoggerMockRecorder) Error(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockLogger)(nil).Error), arg0)
|
||||
}
|
||||
|
||||
// Info mocks base method.
|
||||
func (m *MockLogger) Info(arg0 string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Info", arg0)
|
||||
}
|
||||
|
||||
// Info indicates an expected call of Info.
|
||||
func (mr *MockLoggerMockRecorder) Info(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockLogger)(nil).Info), arg0)
|
||||
}
|
||||
|
||||
// Warn mocks base method.
|
||||
func (m *MockLogger) Warn(arg0 string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Warn", arg0)
|
||||
}
|
||||
|
||||
// Warn indicates an expected call of Warn.
|
||||
func (mr *MockLoggerMockRecorder) Warn(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Warn", reflect.TypeOf((*MockLogger)(nil).Warn), arg0)
|
||||
}
|
||||
@@ -19,6 +19,7 @@ type Service struct {
|
||||
client *http.Client
|
||||
portAllower PortAllower
|
||||
logger Logger
|
||||
cmder Cmder
|
||||
// Internal channels and locks
|
||||
startStopMutex sync.Mutex
|
||||
keepPortCancel context.CancelFunc
|
||||
@@ -26,7 +27,7 @@ type Service struct {
|
||||
}
|
||||
|
||||
func New(settings Settings, routing Routing, client *http.Client,
|
||||
portAllower PortAllower, logger Logger, puid, pgid int,
|
||||
portAllower PortAllower, logger Logger, cmder Cmder, puid, pgid int,
|
||||
) *Service {
|
||||
return &Service{
|
||||
// Fixed parameters
|
||||
@@ -38,6 +39,7 @@ func New(settings Settings, routing Routing, client *http.Client,
|
||||
client: client,
|
||||
portAllower: portAllower,
|
||||
logger: logger,
|
||||
cmder: cmder,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ type Settings struct {
|
||||
Enabled *bool
|
||||
PortForwarder PortForwarder
|
||||
Filepath string
|
||||
UpCommand string
|
||||
DownCommand string
|
||||
Interface string // needed for PIA, PrivateVPN and ProtonVPN, tun0 for example
|
||||
ServerName string // needed for PIA
|
||||
CanPortForward bool // needed for PIA
|
||||
@@ -24,6 +26,8 @@ func (s Settings) Copy() (copied Settings) {
|
||||
copied.Enabled = gosettings.CopyPointer(s.Enabled)
|
||||
copied.PortForwarder = s.PortForwarder
|
||||
copied.Filepath = s.Filepath
|
||||
copied.UpCommand = s.UpCommand
|
||||
copied.DownCommand = s.DownCommand
|
||||
copied.Interface = s.Interface
|
||||
copied.ServerName = s.ServerName
|
||||
copied.CanPortForward = s.CanPortForward
|
||||
@@ -37,6 +41,8 @@ func (s *Settings) OverrideWith(update Settings) {
|
||||
s.Enabled = gosettings.OverrideWithPointer(s.Enabled, update.Enabled)
|
||||
s.PortForwarder = gosettings.OverrideWithComparable(s.PortForwarder, update.PortForwarder)
|
||||
s.Filepath = gosettings.OverrideWithComparable(s.Filepath, update.Filepath)
|
||||
s.UpCommand = gosettings.OverrideWithComparable(s.UpCommand, update.UpCommand)
|
||||
s.DownCommand = gosettings.OverrideWithComparable(s.DownCommand, update.DownCommand)
|
||||
s.Interface = gosettings.OverrideWithComparable(s.Interface, update.Interface)
|
||||
s.ServerName = gosettings.OverrideWithComparable(s.ServerName, update.ServerName)
|
||||
s.CanPortForward = gosettings.OverrideWithComparable(s.CanPortForward, update.CanPortForward)
|
||||
|
||||
@@ -73,6 +73,14 @@ func (s *Service) Start(ctx context.Context) (runError <-chan error, err error)
|
||||
s.ports = ports
|
||||
s.portMutex.Unlock()
|
||||
|
||||
if s.settings.UpCommand != "" {
|
||||
err = runCommand(ctx, s.cmder, s.logger, s.settings.UpCommand, ports)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("running up command: %w", err)
|
||||
s.logger.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
keepPortCtx, keepPortCancel := context.WithCancel(context.Background())
|
||||
s.keepPortCancel = keepPortCancel
|
||||
runErrorCh := make(chan error)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (s *Service) Stop() (err error) {
|
||||
@@ -30,6 +31,17 @@ func (s *Service) cleanup() (err error) {
|
||||
s.portMutex.Lock()
|
||||
defer s.portMutex.Unlock()
|
||||
|
||||
if s.settings.DownCommand != "" {
|
||||
const downTimeout = 60 * time.Second
|
||||
ctx, cancel := context.WithTimeout(context.Background(), downTimeout)
|
||||
defer cancel()
|
||||
err = runCommand(ctx, s.cmder, s.logger, s.settings.DownCommand, s.ports)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("running down command: %w", err)
|
||||
s.logger.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
for _, port := range s.ports {
|
||||
err = s.portAllower.RemoveAllowedPort(context.Background(), port)
|
||||
if err != nil {
|
||||
|
||||
@@ -19,9 +19,10 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES256cbc,
|
||||
openvpn.AES128gcm,
|
||||
},
|
||||
Auth: openvpn.SHA256,
|
||||
Ping: 10,
|
||||
CAs: []string{"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"}, //nolint:lll
|
||||
Auth: openvpn.SHA256,
|
||||
MssFix: 1320,
|
||||
Ping: 10,
|
||||
CAs: []string{"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"}, //nolint:lll
|
||||
}
|
||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
Ciphers: []string{
|
||||
openvpn.AES256gcm,
|
||||
},
|
||||
MssFix: 1320,
|
||||
Ping: 5,
|
||||
RemoteCertTLS: true,
|
||||
CAs: []string{"MIIDZzCCAk+gAwIBAgIUVwHEFE6geihigDSNkBppm2Zamx0wDQYJKoZIhvcNAQELBQAwQzELMAkGA1UEBhMCQ0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxEDAOBgNVBAoMB0dsdWV0dW4wHhcNMjIwNzAxMTY1MzE5WhcNMjcwNjMwMTY1MzE5WjBDMQswCQYDVQQGEwJDQTEPMA0GA1UECAwGUXVlYmVjMREwDwYDVQQHDAhNb250cmVhbDEQMA4GA1UECgwHR2x1ZXR1bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALmJRhTUr+87NFkHL2PWjIz7efHqQgrWuDQt8oOBHvl0Hm72N+ckO+5Q0zG4XtqlpBjFjGUSjfNUWSrRztbXlMmzDcjHKjYHUPepJpoF100fK2q3XPiFRl6sEXzYeOdFgpaTdmGHS6DL9aWeCoYA/k6NV8YqHXujr14gOYOAWG6cRimpTJf8DtEDcxtp1w6fOEoN0b5PvV7dcpLiva8LYyZKPvFYBzlc5BZxOLvq6bvhQm54R6zoHFpaKOf7FeqhxI6KOQu4IPwU12YBlOP5CbkMAQ1cWWVQ4pnh0Hwh71Sjm848jS/OcammNzsp4xWaKt/pzcix3fpJt/MDP/9fxA8CAwEAAaNTMFEwHQYDVR0OBBYEFCIQ9l28Yy1/3qJvFarXjhKdG9tVMB8GA1UdIwQYMBaAFCIQ9l28Yy1/3qJvFarXjhKdG9tVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAKLPmLTppXYTTOOxHhTMyHI0oTl7ID2PQfJsref+jDshB3hib98BC17b9ESpLnwx7ugg17NRl7RYutxjuVw/CK/gwAnTMg3D3mdAnKkMRr3UxnD89KprLIpf7WQCmyJaxalsD5jjgl3kuGM7jf2FJNxQz5RrXBGlQHa465ouov+Rp5v/K5Umyt6wsCZXEbOF0SdUhEGU3nxVbFsoPimNYSHHwc29USnQmyW1O/drFDoTcOK4GdHFEVkrHQgqwU8ay1fYGYfIUDhsV/5AAWgQC41r9FWr+VQgyJC94qmDg0c46RE123dL/YifVUl2DKuJ0aOY+OkSgwknKZ+FQd+8d6k="}, //nolint:lll
|
||||
|
||||
@@ -18,6 +18,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES256cbc,
|
||||
},
|
||||
Auth: openvpn.SHA256,
|
||||
MssFix: 1320,
|
||||
Ping: 10,
|
||||
CAs: []string{"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"}, //nolint:lll
|
||||
TLSCipher: "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA", //nolint:lll
|
||||
|
||||
@@ -20,6 +20,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
CAs: []string{"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"}, //nolint:lll
|
||||
Cert: "MIIGMjCCBBqgAwIBAgICAQIwDQYJKoZIhvcNAQELBQAwgZIxCzAJBgNVBAYTAlVLMQ8wDQYDVQQIDAZMb25kb24xDzANBgNVBAcMBkxvbmRvbjETMBEGA1UECgwKUHJpdmF4IEx0ZDEUMBIGA1UECwwLSE1BIFBybyBWUE4xFjAUBgNVBAMMDWhpZGVteWFzcy5jb20xHjAcBgkqhkiG9w0BCQEWD2luZm9AcHJpdmF4LmNvbTAeFw0xNjEwMTgxNDE4MThaFw0yNjEwMTUxNDE4MThaMIGNMQswCQYDVQQGEwJVSzEPMA0GA1UECAwGTG9uZG9uMQ8wDQYDVQQHDAZMb25kb24xEzARBgNVBAoMClByaXZheCBMdGQxFDASBgNVBAsMC0hNQSBQcm8gVlBOMREwDwYDVQQDDAhobWF1c2VyMjEeMBwGCSqGSIb3DQEJARYPaW5mb0Bwcml2YXguY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5XY3ERJYWs/YIeBoybivNlu+M32rJs+CAZsh7BnnetTxytI4ngsMRoqXETuis8udp2hsqEHsglLR9tlk9C8yCuKhxbkpdrXFWdISmUq5sa7/wqg/zJF1AZm5Jy0oHNyTHfG6XW61I/h9IN5dmcR9YLir8DVDBNllbtt0z+DnvOhYJOqC30ENahWkTmNKl1cT7EBrR5slddiBJleAb08z77pwsD310e6jWTBySsBcPy+xu/Jj2QgVil/3mstZZDI+noFzs3SkTFBkha/lNTP7NODBQ6m39iaJxz6ZR1xE3v7XU0H5WnpZIcQ2+kmu5Krk2y1GYMKL+9oaotXFPz9v+QIDAQABo4IBkzCCAY8wCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCB4AwCwYDVR0PBAQDAgeAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU2LKFPHjFUzLfsHIMWi0VukhBgTEwgccGA1UdIwSBvzCBvIAU4MZR0iTa8SoTWOJeoOmtynuk8/ehgZikgZUwgZIxCzAJBgNVBAYTAlVLMQ8wDQYDVQQIDAZMb25kb24xDzANBgNVBAcMBkxvbmRvbjETMBEGA1UECgwKUHJpdmF4IEx0ZDEUMBIGA1UECwwLSE1BIFBybyBWUE4xFjAUBgNVBAMMDWhpZGVteWFzcy5jb20xHjAcBgkqhkiG9w0BCQEWD2luZm9AcHJpdmF4LmNvbYIJAOmTY3hf1Bb6MBoGA1UdEQQTMBGBD2luZm9AcHJpdmF4LmNvbTAaBgNVHRIEEzARgQ9pbmZvQHByaXZheC5jb20wEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggIBAKeGVnbL3yu2fh1T0ATbgyHx9rnFGRW1o/xfF5ssfRInlopsGDejrk9goyJErVxuzSzLp8AhxSOrVZJp6Tlpssj3B4FbGB0BIH+LcrID9pb+r2LqrTeYfMwYo6zRLNQ5NmMyxQCf6XrdxihUTiZBV31LKlWNkhOLMlHr2eXwAEXjqYMXjYwN+WE8I7SlUm5WCwj7PTiF7BpdDP5Ut4y5Dj8A2m1zXt36rr5hxvbgo2JAeFwVEG4ch67PI+uM0G2GilxnjuK2wKgjBKFMAUfLs7tigzSgx8PEfYCc+bgWpPyfG5hYM9n94zd2VTDN4sam12Bxvhw8zn20L6eT+Skfa8BN7eesrV5opABt/IImZ4Q1HShKKc5EiBN8CKGDydojkNrXuFfsyv7S9VHch0e5cS+Annhr4ARaH0O5fPOD5PBVajdbV6/Rf7NzB5b/raJcUK5BD6KWWRCsmaNYzaabJjUpCmigrOMmkdAxeKCY/oEFpU3+7VeKfNyxBTIiGFt5RjNqTQXmMVjiRN97VN7fqAaFTQB2OF7E3hrtqU9jXkeN8Tvu/FF0LNyt87orewecC0Ujz7Hto9fchPH0roP+DVzoAEP8axD9RV5pM/kgubu3hMD6lLsbx4GOD11GQplvuygURxAYsyjbgFydbk1ZIpeE2OeGXXrfuQWFbNtjLJTu", //nolint:lll
|
||||
RSAKey: "MIIEpAIBAAKCAQEA5XY3ERJYWs/YIeBoybivNlu+M32rJs+CAZsh7BnnetTxytI4ngsMRoqXETuis8udp2hsqEHsglLR9tlk9C8yCuKhxbkpdrXFWdISmUq5sa7/wqg/zJF1AZm5Jy0oHNyTHfG6XW61I/h9IN5dmcR9YLir8DVDBNllbtt0z+DnvOhYJOqC30ENahWkTmNKl1cT7EBrR5slddiBJleAb08z77pwsD310e6jWTBySsBcPy+xu/Jj2QgVil/3mstZZDI+noFzs3SkTFBkha/lNTP7NODBQ6m39iaJxz6ZR1xE3v7XU0H5WnpZIcQ2+kmu5Krk2y1GYMKL+9oaotXFPz9v+QIDAQABAoIBAQCcMcssOMOiFWc3MC3EWo4SP4MKQ9n0Uj5Z34LI151FdJyehlj54+VYQ1Cv71tCbjED2sZUBoP69mtsT/EzcsjqtfiOwgrifrs2+BOm+0HKHKiGlcbP9peiHkT10PxEITWXpYtJvGlbcfOjIxqt6B28cBjCK09ShrVQL9ylAKBearRRUacszppntMNTMtN/uG48ZR9Wm+xAczImdG6CrG5sLI/++JwM5PDChLvn5JgMGyOfQZdjNe1oSOVLmqFeG5uu/FS4oMon9+HtfjHJr4ZgA1yQ2wQh3GvEjlP8zwHxEpRJYbxpj6ZbjHZJ2HLX/Gcd9/cXiN8+fQ2zPIYQyG9dAoGBAPUUmt2nJNvl7gj0GbZZ3XR9o+hvj7bJ74W2NhMrw6kjrrzHTAUQd1sBQS8szAQCLqf2ou1aw9AMMBdsLAHydXxvbH7IBAla7rKr23iethtSfjhTNSgQLJHVZlNHfp3hzNtCQZ7j0qVjrteNotrdVF7kKPHDXAK00ICy6SPNjvrXAoGBAO+vdnO15jLeZbbi3lQNS4r8oCadyqyX7ouKE6MtKNhiPsNPGqHKiGcKs/+QylVgYvSmm7TgpsCAiEYeLSPT+Yq3y7HtwVpULlpfAhEJXmvn/6hGpOizx1WNGWhw7nHPWPDzf+jqCGzHdhK0aEZR3MZZQ+U+uKfGiJ8vrvgB7eGvAoGAWxxp5nU48rcsIw/8bxpBhgkfYk33M5EnBqKSv9XJS5wEXhIJZOiWNrLktNEGl4boKXE7aNoRacreJhcE1UR6AOS7hPZ+6atwiePyF4mJUeb9HZtxa493wk9/Vv6BR9il++1Jz/QKX4oLef8hyBP4Rb60qgxirG7kBLR+j9zfhskCgYEAzA5y5xIeuIIU0H4XUDG9dcebxSSjbwsuYIgeLdb9pjMGQhsvjjyyoh8/nT20tLkJpkXN3FFCRjNnUWLRhWYrVkkh1wqWiYOPrwqh5MU4KN/sDWSPcznTY+drkTpMFoKzsvdrl2zf3VR3FneXKv742bkXj601Ykko+XWMHcLutisCgYBSq8IrsjzfaTQiTGI9a7WWsvzK92bq7Abnfq7swAXWcJd/bnjTQKLrrvt2bmwNvlWKAb3c69BFMn0X4t4PuN0iJQ39D6aQAEaM7HwWAmjf5TbodbmgbGxdsUB4xcCIQQ1mvTkigXWrCg0YAD2GZSoaslXAAVv6nR5qWEIa0Hx9GA==", //nolint:lll
|
||||
MssFix: 1320,
|
||||
Ping: 5,
|
||||
}
|
||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
||||
|
||||
@@ -10,15 +10,21 @@ import (
|
||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
settings settings.OpenVPN, ipv6Supported bool,
|
||||
) (lines []string) {
|
||||
//nolint:mnd
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
AuthUserPass: true,
|
||||
Ciphers: []string{
|
||||
openvpn.AES256gcm,
|
||||
openvpn.AES256cbc,
|
||||
},
|
||||
Auth: openvpn.SHA256,
|
||||
VerifyX509Type: "name",
|
||||
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
|
||||
CAs: []string{"MIIErTCCA5WgAwIBAgIJAMYKzSS8uPKDMA0GCSqGSIb3DQEBDQUAMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb20wHhcNMTIwMTExMTkzMjIwWhcNMjgxMTAyMTkzMjIwWjCBlTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkZMMRQwEgYDVQQHEwtXaW50ZXIgUGFyazERMA8GA1UEChMISVBWYW5pc2gxFTATBgNVBAsTDElQVmFuaXNoIFZQTjEUMBIGA1UEAxMLSVBWYW5pc2ggQ0ExIzAhBgkqhkiG9w0BCQEWFHN1cHBvcnRAaXB2YW5pc2guY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt9DBWNr/IKOuY3TmDP5x7vYZR0DGxLbXU8TyAzBbjUtFFMbhxlHiXVQrZHmgzih94x7BgXM7tWpmMKYVb+gNaqMdWE680Qm3nOwmhy/dulXDkEHAwD05i/iTx4ZaUdtV2vsKBxRg1vdC4AEiwD7bqV4HOi13xcG971aQ55Mj1KeCdA0aNvpat1LWx2jjWxsfI8s2Lv5Fkoi1HO1+vTnnaEsJZrBgAkLXpItqP29Lik3/OBIvkBIxlKrhiVPixE5qNiD+eSPirsmROvsyIonoJtuY4Dw5K6pcNlKyYiwo1IOFYU3YxffwFJk+bSW4WVBhsdf5dGxq/uOHmuz5gdwxCwIDAQABo4H9MIH6MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFEv9FCWJHefBcIPX9p8RHCVOGe6uMIHKBgNVHSMEgcIwgb+AFEv9FCWJHefBcIPX9p8RHCVOGe6uoYGbpIGYMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb22CCQDGCs0kvLjygzANBgkqhkiG9w0BAQ0FAAOCAQEAI2dkh/43ksV2fdYpVGhYaFZPVqCJoToCez0IvOmLeLGzow+EOSrY508oyjYeNP4VJEjApqo0NrMbKl8g/8bpLBcotOCF1c1HZ+y9v7648uumh01SMjsbBeHOuQcLb+7gX6c0pEmxWv8qj5JiW3/1L1bktnjW5Yp5oFkFSMXjOnIoYKHyKLjN2jtwH6XowUNYpg4qVtKU0CXPdOznWcd9/zSfa393HwJPeeVLbKYaFMC4IEbIUmKYtWyoJ9pJ58smU3pWsHZUg9Zc0LZZNjkNlBdQSLmUHAJ33Bd7pJS0JQeiWviC+4UTmzEWRKa7pDGnYRYNu2cUo0/voStphv8EVA=="}, //nolint:lll
|
||||
CAs: []string{"MIIErzCCA5egAwIBAgIJAMYKzSS8uPKDMA0GCSqGSIb3DQEBDQUAMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb20wIBcNMjIwNTA5MjAyMDQ1WhgPMjA4MjA0MjQyMDIwNDVaMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC30MFY2v8go65jdOYM/nHu9hlHQMbEttdTxPIDMFuNS0UUxuHGUeJdVCtkeaDOKH3jHsGBczu1amYwphVv6A1qox1YTrzRCbec7CaHL926VcOQQcDAPTmL+JPHhlpR21Xa+woHFGDW90LgASLAPtupXgc6LXfFwb3vVpDnkyPUp4J0DRo2+lq3UtbHaONbGx8jyzYu/kWSiLUc7X69OedoSwlmsGACQteki2o/b0uKTf84Ei+QEjGUquGJU+LETmo2IP55I+KuyZE6+zIiiegm25jgPDkrqlw2UrJiLCjUg4VhTdjF9/AUmT5tJbhZUGGx1/l0bGr+44ea7PmB3DELAgMBAAGjgf0wgfowDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUS/0UJYkd58Fwg9f2nxEcJU4Z7q4wgcoGA1UdIwSBwjCBv4AUS/0UJYkd58Fwg9f2nxEcJU4Z7q6hgZukgZgwgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJGTDEUMBIGA1UEBxMLV2ludGVyIFBhcmsxETAPBgNVBAoTCElQVmFuaXNoMRUwEwYDVQQLEwxJUFZhbmlzaCBWUE4xFDASBgNVBAMTC0lQVmFuaXNoIENBMSMwIQYJKoZIhvcNAQkBFhRzdXBwb3J0QGlwdmFuaXNoLmNvbYIJAMYKzSS8uPKDMA0GCSqGSIb3DQEBDQUAA4IBAQCc9JV7IR8BfBrF/BQTXg0SZMZyyMAxR2jfW9qMHKSeJuZVVjfHiqoynEgBCNbn71wZWv3OF/Thu9BJ4GiYJ2Bc9nIa90D1NGYgiOVYLGXfUUqy5FgfrsWh0Go5oYm9l7W9pWfIifwsaZynkY0rTIHn32FF0H3+wZrGrEUzVL6qi+KD8iR3cBbLT+xUzulMTBp4JYaQnxpV4fZNS0ZsNrWKFWz4Iz1SSBcsnvUhfWs1aKx4yOJQx33Pc+KwpUI+meTlMjoh+AoTriooKU2MbOqLQl32y3pR0MP3fX4HDVFRylxdckEc+VryGNHQLUJiIBKBCORih/YiRhtEhpoBxmkw"}, //nolint:lll
|
||||
MssFix: 1320,
|
||||
ExtraLines: []string{
|
||||
"comp-lzo", // Explicitly disable compression
|
||||
},
|
||||
}
|
||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
||||
servers []models.Server, err error,
|
||||
) {
|
||||
const url = "https://configs.ipvanish.com/configs/configs.zip"
|
||||
const url = "https://configs.ipvanish.com/openvpn/v2.6.0-0/configs.zip"
|
||||
contents, err := u.unzipper.FetchAndExtract(ctx, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -194,7 +194,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
unzipper := common.NewMockUnzipper(ctrl)
|
||||
const zipURL = "https://configs.ipvanish.com/configs/configs.zip"
|
||||
const zipURL = "https://configs.ipvanish.com/openvpn/v2.6.0-0/configs.zip"
|
||||
unzipper.EXPECT().FetchAndExtract(ctx, zipURL).
|
||||
Return(testCase.unzipContents, testCase.unzipErr)
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
Ciphers: []string{
|
||||
openvpn.AES256cbc,
|
||||
},
|
||||
MssFix: 1320,
|
||||
Ping: 5,
|
||||
RemoteCertTLS: true,
|
||||
VerifyX509Type: "name-prefix",
|
||||
|
||||
@@ -18,6 +18,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES128gcm,
|
||||
openvpn.AES256gcm,
|
||||
},
|
||||
MssFix: 1320,
|
||||
Ping: 10,
|
||||
RemoteCertTLS: true,
|
||||
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
|
||||
|
||||
@@ -21,8 +21,8 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
MssFix: 1450,
|
||||
Ping: 5,
|
||||
CAs: []string{"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"}, //nolint:lll
|
||||
Cert: "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", //nolint:lll
|
||||
Key: "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", //nolint:lll
|
||||
Cert: "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", //nolint:lll
|
||||
Key: "MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCUJXPegG4WvSm2902t3HQMz34rekXXWGwVgTKv445dKBffHsJfSEQn51wqFg/afuXbufV6ZrAUXJZCY0h6girgKsvNX8u1SUIW+a8f/dudZgRt51UaqtUFf7PKST/7ecUQZbTmIxcHihuXrhPAl48vuEtR+UmCuzFCrDmqp5qEYGDk9x5CvT1QbfmVrD64OIwCb4TUbtWD6QNZzDbDKSbvjj7/1tsXgz1XX6lRbyq+HTAXVAsuqAWwymR7uQR4mHk/GPlUonioq+uqUIwawY0azBE+JAcO8xDPJPZOGhrDpQRi6xkQVKkrYMHrXBAWYUjDPAWZN6EnHfGNvSVJqq3MYE7OAEExO2+M4cVdCYmRZG+XKaspvPKgwIDwXdrM6gQbR4gHUMeNmJ9tOKz/gg77ujz7/aLlozzlCeMLODkAR0qNhXgqdAFWfcrQIWWRAwormR2anAnxPrOpOv0wGbabVnMI/lpqMqPA5WGR1zqe8vkce9kxFOA1g9x7lJ1L1SC6oFhZgvkZt0ZXrRb8ztVp2pne9L+XxXoxArcoEl79x5JMV8azS2QpTKmejQvryDjFPkx5sAxTxwXgoP9gvzJe0lO/pHKsDoS3vIosATWkU3d8VsVzoRpftUs0NTMADb7Xk7+UHdjLi6TKc3T/HdoT2NxHtVB0ydkjZ1WeEE+c8wIDAQABAoICAGNz8SFB3qXtP3/Q7Zj2EgI3mV/eqdwzQ/v7y+dAQGZRcBUdNSd6ACc5rimivenUnsKvSBhvr2076rOOqy1zDQ2ILWEmGj8NewypeeNkLHax8e9GCV/ppzAV1sDKA+XyjVTAsnx8ug0ZrgRZnHECTeGfOxFA5RSaTiuQKvZhpd2QRfvv2aS8HdlMuuy7wS8y5usLqoRiE3yGhPVXnrvNeJIBUFG4D0TtmdR6J9S/aFZQieRfS1J7Abb5aBOW1WWQFnVBcsBagd3Z7E9d23Bq1ytSK5En5oUmr/YfvioYZDdLJHKzmRPZgefZANXb7ADaNlq6hJejPNBhzbN1cv7NUfaIgRjJCWOBL16SLQx/q7B614RGHpBmIF6GGdu/U6UBdd838qTSk8FtTh+4EMaMixzEqWA2MHznEGUssOM0XhRrQFXP+z8uSQd+aAqUJxbc5Sk3gC5FVetDc+cI/L7KrVjQh9RkFRaDVW1/+oPJvz0NWJHKQFRbNPFcpcJRGSODsZsA7VDTQV/pF9EPMkfCWvzLbq9rGzkUSd05cOlVurysebRP4oLjMhw1gARhopgbjc7aPrkp7XlgTItJqT7A0VLhP/q6cXuU2CeYJa7OVL/GvPddg+eM3e0VIgummCknrzH+lbBScU/Bek3m7XWK4ONUfR9qhJFXwHtmyvWxL1NhAoIBAQDFdUqliT3r58is1iqIuR+Lwbk8z8aXSJmCCTGVW2+KyiPbdVO6ywgyfn7h7lVrj4v/HFGggRYe5TR9ojYYw4aHGPODnaeq9qX8ZZHB7rx2LQzWgLXpm2hnpIK5YqIZbhe+oEJ2573wf8IatR3e3pXJvHKLz7yEDdASK+/bkGzizDW9jO+lbDQb3V4dTRgXTvXNSpp+0k4kPo8m4qrJb4SFjqF2Ss6Qzz2FbHmu/HBNTV1KjKQk0Fa8blAEAoinxtXbHMb8FYctcNvwMcRn2W9jL4xgNW3OW1cp2kVdlF35de5MQNZ+1XHJAfvgNedRFUoT+wN/FYEXHmIKog1hjqz/AoIBAQDAEXtJ8rFnlG3q/g3pM2iRez/PSAr6XlWwa05EBUlHhBHUGcu88fRMIhywiUeslmyjAJxmw4eNwuRl3GzqAysS9GflCHvLQGu1Uwl30r+UZ5fa+TbfJELSRPh8mdWfBFJbGHR8XEpokVXsrZhHAsijyvijAhXW/OqFOOtLxy60Y6fCmoazG4etwJGfOUUGRXOedF/MVL5DTUQKt2coj0m8N3kET1pBwZbB7k0Zmn4q47Yb172o/M0hpXBpSoh6wbNDreHzWqpG7gjPXRbJ6gIWB0p27XcNBJE4VO3ElPm7st8w36/Rgo7haqX6CCle09WJwlum1YVfoLFCmLn4qywNAoIBAAgeraYnAaPc0TTCTdd3fWOa4MouZSU9eAqP5DkXHHwhmd3hckMBLGIfL4qM6XhV29TuzjCCfm1g0YrFC+Jyz+poTUNBTW7LW8IITzkhXyCg86Eyg8iKen2glzuWYcIX8+QD5RfMqdPk/Q9qGUNb9d7o3/D95uurQb4tjlyCEOg2q5MS45vy2iW3MbKUxAPZXGRHyBik/0+gPvTDZ3CHJHT1i5A4vUvZKdd9wXc/rEKRht+U7v8QjjCLfMDddc8obwzmnwwounlU5cZ31XLLzzfN8cDXEZ/lw6zV6/pQKpkij10VYXyvvFEewsPSk6OS84vky50DPl68Ah4b0d8MJfMCggEBAKvsOga0VfZYl5dcd8lBuh1XTIPXgfQgkuVK+BDNBo4cevT3bjagAcRQWIvxJhYnw/CYcGdQKLtNM7K1/0vtMBZUbddGo8EI1iDFxljabaCCphxdLa/JvoKHOEIYVW50qN9f4Y0b84LsbRRhQ0h1BnIPEkafbDs3wxkjHQOEtJrGBXmdZmtWfjmagP8cfVuiuV6h3sqBJJoLxJcvGgjlUeRHZ2zjNvBbP/4xuBPuBXeQwwbjM6LbPycZ9qhZDheL4VH4iKOTiY3aLkqnkemFLP7Y4d/YqdMePntFElv/2hcYgs41vCR2kDzYgN9xhM6cIa2hKvcIc81ogqMRII6lcdUCggEBAKwHumHjFOMAs1ARmBuq+6LkOptsoPJw8Blfykmpk+V+/Ycy2pDGmtCr6tYhhcGm31wQLYpCADN+EAkWevf2/zSrIVAIrtAwq/aF1+p5vPiglU/A5G9mkewC+FeYinnvM8UPWZKFhOrXgbFNfdP73ejjIuiWekWd8EbhWwwNS4AxK+NaYEKcbfIyYR1flhyfVvBq9JdM8m2Mp1hEWPogRFls973yuRNTo8wG76SY7kTn7XGnNO6a8Ijyddbi17Kaek091ydtsrQbUBe+W1UMZgJODqr+IJEEjpgOMTM4lu9iS4ckb6kSPI4EX2NmRjQOqFpA0QmxIC7gWj2GmJYAE5U=", //nolint:lll
|
||||
TLSCrypt: "d10a8e2641f5834f6c5e04a6ee9a798553d338fa2836ef2a91057c1f6174a3a12b36f16d1110b20e42ae94d3bd579213e9c3770be6c74804348dddba876945a5a3ab7660f9436f85f331641f6efc81315f0d12b2766a9f15c10a53cf9ba32dc80f03b5f15a6cc6987bda795dbe83443ec81f3d5e161cd47fab6b1f125b3adeee1eae33370d018594e0ff6b25b815228d27371b32c82a95f4929d3abb5fa36e57bf1f42353542568fbb8233f4645f05820275f79570cb8bbcf8010fc5d20f07d031a8227d45daf7349e34158c91a3d4e5add19cfa02f683f87609f6525fa0594016d11abf2de649f83ad54edd3e74e032e34b1bca685b8499916826d9aee11c13", //nolint:lll
|
||||
TLSCipher: "TLS_CHACHA20_POLY1305_SHA256:TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS_AES_256_GCM_SHA384:TLS-RSA-WITH-AES-256-CBC-SHA", //nolint:lll
|
||||
TunMTU: 1500,
|
||||
|
||||
@@ -17,6 +17,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES256cbc,
|
||||
},
|
||||
Auth: openvpn.SHA256,
|
||||
MssFix: 1320,
|
||||
Ping: 10,
|
||||
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
|
||||
VerifyX509Type: "name",
|
||||
|
||||
@@ -11,10 +11,12 @@ import (
|
||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
settings settings.OpenVPN, ipv6Supported bool,
|
||||
) (lines []string) {
|
||||
//nolint:mnd
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
RemoteCertTLS: true,
|
||||
RenegDisabled: true,
|
||||
AuthUserPass: true,
|
||||
MssFix: 1320,
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
settings settings.OpenVPN, ipv6Supported bool,
|
||||
) (lines []string) {
|
||||
//nolint:mnd
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
RemoteCertTLS: true,
|
||||
AuthUserPass: true,
|
||||
@@ -19,6 +20,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
Auth: openvpn.SHA256,
|
||||
CAs: []string{"MIIErTCCA5WgAwIBAgIJAPp3HmtYGCIOMA0GCSqGSIb3DQEBCwUAMIGVMQswCQYDVQQGEwJTRTELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN0b2NraG9sbTETMBEGA1UEChMKUHJpdmF0ZVZQTjEWMBQGA1UEAxMNUHJpdmF0ZVZQTiBDQTETMBEGA1UEKRMKUHJpdmF0ZVZQTjEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBwcml2YXR2cG4uc2UwHhcNMTcwNTI0MjAxNTM3WhcNMjcwNTIyMjAxNTM3WjCBlTELMAkGA1UEBhMCU0UxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTdG9ja2hvbG0xEzARBgNVBAoTClByaXZhdGVWUE4xFjAUBgNVBAMTDVByaXZhdGVWUE4gQ0ExEzARBgNVBCkTClByaXZhdGVWUE4xIzAhBgkqhkiG9w0BCQEWFHN1cHBvcnRAcHJpdmF0dnBuLnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwjqTWbKk85WN8nd1TaBgBnBHceQWosp8mMHr4xWMTLagWRcq2Modfy7RPnBo9kyn5j/ZZwL/21gLWJbxidurGyZZdEV9Wb5KQl3DUNxa19kwAbkkEchdES61e99MjmQlWq4vGPXAHjEuDxOZ906AXglCyAvQoXcYW0mNm9yybWllVp1aBrCaZQrNYr7eoFvolqJXdQQ3FFsTBCYa5bHJcKQLBfsiqdJ/BAxhNkQtcmWNSgLy16qoxQpCsxNCxAcYnasuL4rwOP+RazBkJTPXA/2neCJC5rt+sXR9CSfiXdJGwMpYso5m31ZEd7JL2+is0FeAZ6ETrKMnEZMsTpTkdwIDAQABo4H9MIH6MB0GA1UdDgQWBBRCkBlC94zCY6VNncMnK36JxT7bazCBygYDVR0jBIHCMIG/gBRCkBlC94zCY6VNncMnK36JxT7ba6GBm6SBmDCBlTELMAkGA1UEBhMCU0UxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTdG9ja2hvbG0xEzARBgNVBAoTClByaXZhdGVWUE4xFjAUBgNVBAMTDVByaXZhdGVWUE4gQ0ExEzARBgNVBCkTClByaXZhdGVWUE4xIzAhBgkqhkiG9w0BCQEWFHN1cHBvcnRAcHJpdmF0dnBuLnNlggkA+ncea1gYIg4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAayugvExKDHar7t1zyYn99Vt1NMf46J8x4Dt9TNjBml5mR9nKvWmreMUuuOhLaO8Da466KGdXeDFNLcBYZd/J2iTawE6/3fmrML9H2sa+k/+E4uU5nQ84ZGOwCinCkMalVjM8EZ0/H2RZvLAVUnvPuUz2JfJhmiRkbeE75fVuqpAm9qdE+/7lg3oICYzxa6BJPxT+Imdjy3Q/FWdsXqX6aallhohPAZlMZgZL4eXECnV8rAfzyjOJggkMDZQt3Flc0Y4iDMfzrEhSOWMkNFBFwjK0F/dnhsX+fPX6GGRpUZgZcCt/hWvypqc05/SnrdKM/vV/jV/yZe0NVzY7S8Ur5g=="}, //nolint:lll
|
||||
TLSAuth: "f035a3acaeffb5aedb5bc920bca26ca7ac701da88249008e03563eba6af6d2625ac8ba1e5e0921f76be004c24ae4fd43e42caf0f84269ad44d8d4c14ba45b1386f251c7330d8cc56afd16d516835645651ef7e87a723ac78ae0d49da5b2f2d78ceafcff7a6367d0712628a6547e5fc8fef93c87f7bcd6107c7b1ae68396e944aadae50111d01a5d0c67223d667bdbf1bf434bdef03644ecc5386e102724eef3872f66547eb66dc0fea8286069cb082a41c89083b28fe9f4cec25d48017f26c4fd85b25ddf2ae5448dd2bccf3eef2aacf42ef1e88c3248c689423d0b05a641e9e79dd6b9b5c40f0cc21ffdc891b9eee951477b537261cb56a958a4f490d961ecb", //nolint:lll
|
||||
MssFix: 1320,
|
||||
UDPLines: []string{
|
||||
"key-direction 1",
|
||||
},
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
settings settings.OpenVPN, ipv6Supported bool,
|
||||
) (lines []string) {
|
||||
//nolint:mnd
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
RemoteCertTLS: true,
|
||||
AuthUserPass: true,
|
||||
@@ -17,12 +18,12 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES256gcm,
|
||||
},
|
||||
KeyDirection: "1",
|
||||
//nolint:mnd
|
||||
Ping: 10,
|
||||
CAs: []string{"MIIE6DCCA9CgAwIBAgIJAMjXFoeo5uSlMA0GCSqGSIb3DQEBCwUAMIGoMQswCQYDVQQGEwJISzEQMA4GA1UECBMHQ2VudHJhbDELMAkGA1UEBxMCSEsxGDAWBgNVBAoTD1NlY3VyZS1TZXJ2ZXJDQTELMAkGA1UECxMCSVQxGDAWBgNVBAMTD1NlY3VyZS1TZXJ2ZXJDQTEYMBYGA1UEKRMPU2VjdXJlLVNlcnZlckNBMR8wHQYJKoZIhvcNAQkBFhBtYWlsQGhvc3QuZG9tYWluMB4XDTE2MDExNTE1MzQwOVoXDTI2MDExMjE1MzQwOVowgagxCzAJBgNVBAYTAkhLMRAwDgYDVQQIEwdDZW50cmFsMQswCQYDVQQHEwJISzEYMBYGA1UEChMPU2VjdXJlLVNlcnZlckNBMQswCQYDVQQLEwJJVDEYMBYGA1UEAxMPU2VjdXJlLVNlcnZlckNBMRgwFgYDVQQpEw9TZWN1cmUtU2VydmVyQ0ExHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDluufhyLlyvXzPUL16kAWAdivl1roQv3QHbuRshyKacf/1Er1JqEbtW3Mx9Fvr/u27qU2W8lQI6DaJhU2BfijPe/KHkib55mvHzIVvoexxya26nk79F2c+d9PnuuMdThWQO3El5a/i2AASnM7T7piIBT2WRZW2i8RbfJaTT7G7LP7OpMKIV1qyBg/cWoO7cIWQW4jmzqrNryIkF0AzStLN1DxvnQZwgXBGv0CwuAkfQuNSLu0PQgPp0PhdukNZFllv5D29IhPr0Z+kwPtrAgPQo+lHlOBHBMUpDT4XChTPeAvMaUSBsqmonAE8UUHEabWrqYN/kWNHCNkYXMkiVmK1AgMBAAGjggERMIIBDTAdBgNVHQ4EFgQU456ijsFrYnzHBShLAPpOUqQ+Z2cwgd0GA1UdIwSB1TCB0oAU456ijsFrYnzHBShLAPpOUqQ+Z2ehga6kgaswgagxCzAJBgNVBAYTAkhLMRAwDgYDVQQIEwdDZW50cmFsMQswCQYDVQQHEwJISzEYMBYGA1UEChMPU2VjdXJlLVNlcnZlckNBMQswCQYDVQQLEwJJVDEYMBYGA1UEAxMPU2VjdXJlLVNlcnZlckNBMRgwFgYDVQQpEw9TZWN1cmUtU2VydmVyQ0ExHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW6CCQDI1xaHqObkpTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvga2HMwOtUxWH/inL2qk24KX2pxLg939JNhqoyNrUpbDHag5xPQYXUmUpKrNJZ0z+o/ZnNUPHydTSXE7Z7E45J0GDN5E7g4pakndKnDLSjp03NgGsCGW+cXnz6UBPM5FStFvGdDeModeSUyoS9fjk+mYROvmiy5EiVDP91sKGcPLR7Ym0M7zl2aaqV7bb98HmMoBOxpeZQinof67nKrCsgz/xjktWFgcmPl4/PQSsmqQD0fTtWxGuRX+FzwvF2OCMCAJgp1RqJNlk2g50/kBIoJVPPCfjDFeDU5zGaWGSQ9+z1L6/z7VXdjUiHL0ouOcHwbiS4ZjTr9nMn6WdAHU2"}, //nolint:lll
|
||||
Cert: "MIIEnzCCA4egAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBqDELMAkGA1UEBhMCSEsxEDAOBgNVBAgTB0NlbnRyYWwxCzAJBgNVBAcTAkhLMRgwFgYDVQQKEw9TZWN1cmUtU2VydmVyQ0ExCzAJBgNVBAsTAklUMRgwFgYDVQQDEw9TZWN1cmUtU2VydmVyQ0ExGDAWBgNVBCkTD1NlY3VyZS1TZXJ2ZXJDQTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0LmRvbWFpbjAeFw0xNjAxMTUxNjE1MzhaFw0yNjAxMTIxNjE1MzhaMIGdMQswCQYDVQQGEwJISzEQMA4GA1UECBMHQ2VudHJhbDELMAkGA1UEBxMCSEsxFjAUBgNVBAoTDVNlY3VyZS1DbGllbnQxCzAJBgNVBAsTAklUMRYwFAYDVQQDEw1TZWN1cmUtQ2xpZW50MREwDwYDVQQpEwhjaGFuZ2VtZTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0LmRvbWFpbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxsnyn4v6xxDPnuDaYS0b9M1N8nxgg7OBPBlK+FWRxdTQ8yxt5U5CZGm7riVp7fya2J2iPZIgmHQEv/KbxztsHAVlYSfYYlalrnhEL3bDP2tY+N43AwB1k5BrPq2s1pPLT2XG951drDKG4PUuFHUP1sHzW5oQlfVCmxgIMAP8OYkCAwEAAaOCAV8wggFbMAkGA1UdEwQCMAAwLQYJYIZIAYb4QgENBCAWHkVhc3ktUlNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU9MwUnUDbQKKZKjoeieD2OD5NlAEwgd0GA1UdIwSB1TCB0oAU456ijsFrYnzHBShLAPpOUqQ+Z2ehga6kgaswgagxCzAJBgNVBAYTAkhLMRAwDgYDVQQIEwdDZW50cmFsMQswCQYDVQQHEwJISzEYMBYGA1UEChMPU2VjdXJlLVNlcnZlckNBMQswCQYDVQQLEwJJVDEYMBYGA1UEAxMPU2VjdXJlLVNlcnZlckNBMRgwFgYDVQQpEw9TZWN1cmUtU2VydmVyQ0ExHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW6CCQDI1xaHqObkpTATBgNVHSUEDDAKBggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAFyFo2VUX/UFixsdPdK9/Yt6mkCWc+XS1xbapGXXb9U1d+h1iBCIV9odUHgNCXWpz1hR5Uu/OCzaZ0asLE4IFMZlQmJs8sMT0c1tfPPGW45vxbL0lhqnQ8PNcBH7huNK7VFjUh4szXRKmaQPaM4S91R3L4CaNfVeHfAg7mN2m9Zn5Gto1Q1/CFMGKu2hxwGEw5p+X1czBWEvg/O09ckx/ggkkI1NcZsNiYQ+6Pz8DdGGX3+05YwLZu94+O6iIMrzxl/il0eK83g3YPbsOrASARvw6w/8sOnJCK5eOacl21oww875KisnYdWjHB1FiI+VzQ1/gyoDsL5kPTJVuu2CoG8=", //nolint:lll
|
||||
Key: "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMbJ8p+L+scQz57g2mEtG/TNTfJ8YIOzgTwZSvhVkcXU0PMsbeVOQmRpu64lae38mtidoj2SIJh0BL/ym8c7bBwFZWEn2GJWpa54RC92wz9rWPjeNwMAdZOQaz6trNaTy09lxvedXawyhuD1LhR1D9bB81uaEJX1QpsYCDAD/DmJAgMBAAECgYEAvTHbDupE5U0krUvHzBEIuHblptGlcfNYHoDcD3oxYR3pOGeiuElBexv+mgHVzcFLBrsQfJUlHLPfCWi3xmjRvDQcr7N7U1u7NIzazy/PpRBaKolMRiM1KMYi2DG0i4ZONwFT8bvNHOIrZzCLY54KDrqOn55OzC70WYjWh4t5evkCQQDkkzZUAeskBC9+JP/zLps8jhwfoLBWGw/zbC9ePDmX0N8MTZdcUpg6KUTf1wbkLUyVtIRjS2ao6qu1jWG6K0x3AkEA3qPWyaWQWCynhNDqu2U1cPb2kh5AJip+gqxO3emikAdajsSxeoyEC2AfyBITbeB1tvCUZH17J4i/0+OFTEQp/wJAb/zEOGJ8PzghwK8GC7JA8mk51DEZVAaMSRovFv9wxDXcoh191AjPdmdzzCuAv9iF1i8MUc3GbWoUWK39PIYsPwJAWh63sqfx5b8tj/WBDpnJKBDPfhYAoXJSA1L8GZeY1fQkE+ZKcPCwAmrGcpXeh3t0Krj3WDXyw+32uC5Apr5wwQJAPZwOOReaC4YNfBPZN9BdHvVjOYGGUffpI+X+hWpLRnQFJteAi+eqwyk0Oi0SkJB+a7jcerK2d7q7xhec5WHlng==", //nolint:lll
|
||||
TLSAuth: "e30af995f56d07426d9ba1f824730521d4283db4b4d0cdda9c6e8759a3799dcb7939b6a5989160c9660de0f6125cbb1f585b41c074b2fe88ecfcf17eab9a33be1352379cdf74952b588fb161a93e13df9135b2b29038231e02d657a6225705e6868ccb0c384ed11614690a1894bfbeb274cebf1fe9c2329bdd5c8a40fe8820624d2ea7540cd79ab76892db51fc371a3ac5fc9573afecb3fffe3281e61d72e91579d9b03d8cbf7909b3aebf4d90850321ee6b7d0a7846d15c27d8290e031e951e19438a4654663cad975e138f5bc5af89c737ad822f27e19057731f41e1e254cc9c95b7175c622422cde9f1f2cfd3510add94498b4d7133d3729dd214a16b27fb", //nolint:lll
|
||||
MssFix: 1320,
|
||||
Ping: 10,
|
||||
CAs: []string{"MIIE6DCCA9CgAwIBAgIJAMjXFoeo5uSlMA0GCSqGSIb3DQEBCwUAMIGoMQswCQYDVQQGEwJISzEQMA4GA1UECBMHQ2VudHJhbDELMAkGA1UEBxMCSEsxGDAWBgNVBAoTD1NlY3VyZS1TZXJ2ZXJDQTELMAkGA1UECxMCSVQxGDAWBgNVBAMTD1NlY3VyZS1TZXJ2ZXJDQTEYMBYGA1UEKRMPU2VjdXJlLVNlcnZlckNBMR8wHQYJKoZIhvcNAQkBFhBtYWlsQGhvc3QuZG9tYWluMB4XDTE2MDExNTE1MzQwOVoXDTI2MDExMjE1MzQwOVowgagxCzAJBgNVBAYTAkhLMRAwDgYDVQQIEwdDZW50cmFsMQswCQYDVQQHEwJISzEYMBYGA1UEChMPU2VjdXJlLVNlcnZlckNBMQswCQYDVQQLEwJJVDEYMBYGA1UEAxMPU2VjdXJlLVNlcnZlckNBMRgwFgYDVQQpEw9TZWN1cmUtU2VydmVyQ0ExHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDluufhyLlyvXzPUL16kAWAdivl1roQv3QHbuRshyKacf/1Er1JqEbtW3Mx9Fvr/u27qU2W8lQI6DaJhU2BfijPe/KHkib55mvHzIVvoexxya26nk79F2c+d9PnuuMdThWQO3El5a/i2AASnM7T7piIBT2WRZW2i8RbfJaTT7G7LP7OpMKIV1qyBg/cWoO7cIWQW4jmzqrNryIkF0AzStLN1DxvnQZwgXBGv0CwuAkfQuNSLu0PQgPp0PhdukNZFllv5D29IhPr0Z+kwPtrAgPQo+lHlOBHBMUpDT4XChTPeAvMaUSBsqmonAE8UUHEabWrqYN/kWNHCNkYXMkiVmK1AgMBAAGjggERMIIBDTAdBgNVHQ4EFgQU456ijsFrYnzHBShLAPpOUqQ+Z2cwgd0GA1UdIwSB1TCB0oAU456ijsFrYnzHBShLAPpOUqQ+Z2ehga6kgaswgagxCzAJBgNVBAYTAkhLMRAwDgYDVQQIEwdDZW50cmFsMQswCQYDVQQHEwJISzEYMBYGA1UEChMPU2VjdXJlLVNlcnZlckNBMQswCQYDVQQLEwJJVDEYMBYGA1UEAxMPU2VjdXJlLVNlcnZlckNBMRgwFgYDVQQpEw9TZWN1cmUtU2VydmVyQ0ExHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW6CCQDI1xaHqObkpTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvga2HMwOtUxWH/inL2qk24KX2pxLg939JNhqoyNrUpbDHag5xPQYXUmUpKrNJZ0z+o/ZnNUPHydTSXE7Z7E45J0GDN5E7g4pakndKnDLSjp03NgGsCGW+cXnz6UBPM5FStFvGdDeModeSUyoS9fjk+mYROvmiy5EiVDP91sKGcPLR7Ym0M7zl2aaqV7bb98HmMoBOxpeZQinof67nKrCsgz/xjktWFgcmPl4/PQSsmqQD0fTtWxGuRX+FzwvF2OCMCAJgp1RqJNlk2g50/kBIoJVPPCfjDFeDU5zGaWGSQ9+z1L6/z7VXdjUiHL0ouOcHwbiS4ZjTr9nMn6WdAHU2"}, //nolint:lll
|
||||
Cert: "MIIEnzCCA4egAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBqDELMAkGA1UEBhMCSEsxEDAOBgNVBAgTB0NlbnRyYWwxCzAJBgNVBAcTAkhLMRgwFgYDVQQKEw9TZWN1cmUtU2VydmVyQ0ExCzAJBgNVBAsTAklUMRgwFgYDVQQDEw9TZWN1cmUtU2VydmVyQ0ExGDAWBgNVBCkTD1NlY3VyZS1TZXJ2ZXJDQTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0LmRvbWFpbjAeFw0xNjAxMTUxNjE1MzhaFw0yNjAxMTIxNjE1MzhaMIGdMQswCQYDVQQGEwJISzEQMA4GA1UECBMHQ2VudHJhbDELMAkGA1UEBxMCSEsxFjAUBgNVBAoTDVNlY3VyZS1DbGllbnQxCzAJBgNVBAsTAklUMRYwFAYDVQQDEw1TZWN1cmUtQ2xpZW50MREwDwYDVQQpEwhjaGFuZ2VtZTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0LmRvbWFpbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxsnyn4v6xxDPnuDaYS0b9M1N8nxgg7OBPBlK+FWRxdTQ8yxt5U5CZGm7riVp7fya2J2iPZIgmHQEv/KbxztsHAVlYSfYYlalrnhEL3bDP2tY+N43AwB1k5BrPq2s1pPLT2XG951drDKG4PUuFHUP1sHzW5oQlfVCmxgIMAP8OYkCAwEAAaOCAV8wggFbMAkGA1UdEwQCMAAwLQYJYIZIAYb4QgENBCAWHkVhc3ktUlNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU9MwUnUDbQKKZKjoeieD2OD5NlAEwgd0GA1UdIwSB1TCB0oAU456ijsFrYnzHBShLAPpOUqQ+Z2ehga6kgaswgagxCzAJBgNVBAYTAkhLMRAwDgYDVQQIEwdDZW50cmFsMQswCQYDVQQHEwJISzEYMBYGA1UEChMPU2VjdXJlLVNlcnZlckNBMQswCQYDVQQLEwJJVDEYMBYGA1UEAxMPU2VjdXJlLVNlcnZlckNBMRgwFgYDVQQpEw9TZWN1cmUtU2VydmVyQ0ExHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW6CCQDI1xaHqObkpTATBgNVHSUEDDAKBggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAFyFo2VUX/UFixsdPdK9/Yt6mkCWc+XS1xbapGXXb9U1d+h1iBCIV9odUHgNCXWpz1hR5Uu/OCzaZ0asLE4IFMZlQmJs8sMT0c1tfPPGW45vxbL0lhqnQ8PNcBH7huNK7VFjUh4szXRKmaQPaM4S91R3L4CaNfVeHfAg7mN2m9Zn5Gto1Q1/CFMGKu2hxwGEw5p+X1czBWEvg/O09ckx/ggkkI1NcZsNiYQ+6Pz8DdGGX3+05YwLZu94+O6iIMrzxl/il0eK83g3YPbsOrASARvw6w/8sOnJCK5eOacl21oww875KisnYdWjHB1FiI+VzQ1/gyoDsL5kPTJVuu2CoG8=", //nolint:lll
|
||||
Key: "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMbJ8p+L+scQz57g2mEtG/TNTfJ8YIOzgTwZSvhVkcXU0PMsbeVOQmRpu64lae38mtidoj2SIJh0BL/ym8c7bBwFZWEn2GJWpa54RC92wz9rWPjeNwMAdZOQaz6trNaTy09lxvedXawyhuD1LhR1D9bB81uaEJX1QpsYCDAD/DmJAgMBAAECgYEAvTHbDupE5U0krUvHzBEIuHblptGlcfNYHoDcD3oxYR3pOGeiuElBexv+mgHVzcFLBrsQfJUlHLPfCWi3xmjRvDQcr7N7U1u7NIzazy/PpRBaKolMRiM1KMYi2DG0i4ZONwFT8bvNHOIrZzCLY54KDrqOn55OzC70WYjWh4t5evkCQQDkkzZUAeskBC9+JP/zLps8jhwfoLBWGw/zbC9ePDmX0N8MTZdcUpg6KUTf1wbkLUyVtIRjS2ao6qu1jWG6K0x3AkEA3qPWyaWQWCynhNDqu2U1cPb2kh5AJip+gqxO3emikAdajsSxeoyEC2AfyBITbeB1tvCUZH17J4i/0+OFTEQp/wJAb/zEOGJ8PzghwK8GC7JA8mk51DEZVAaMSRovFv9wxDXcoh191AjPdmdzzCuAv9iF1i8MUc3GbWoUWK39PIYsPwJAWh63sqfx5b8tj/WBDpnJKBDPfhYAoXJSA1L8GZeY1fQkE+ZKcPCwAmrGcpXeh3t0Krj3WDXyw+32uC5Apr5wwQJAPZwOOReaC4YNfBPZN9BdHvVjOYGGUffpI+X+hWpLRnQFJteAi+eqwyk0Oi0SkJB+a7jcerK2d7q7xhec5WHlng==", //nolint:lll
|
||||
TLSAuth: "e30af995f56d07426d9ba1f824730521d4283db4b4d0cdda9c6e8759a3799dcb7939b6a5989160c9660de0f6125cbb1f585b41c074b2fe88ecfcf17eab9a33be1352379cdf74952b588fb161a93e13df9135b2b29038231e02d657a6225705e6868ccb0c384ed11614690a1894bfbeb274cebf1fe9c2329bdd5c8a40fe8820624d2ea7540cd79ab76892db51fc371a3ac5fc9573afecb3fffe3281e61d72e91579d9b03d8cbf7909b3aebf4d90850321ee6b7d0a7846d15c27d8290e031e951e19438a4654663cad975e138f5bc5af89c737ad822f27e19057731f41e1e254cc9c95b7175c622422cde9f1f2cfd3510add94498b4d7133d3729dd214a16b27fb", //nolint:lll
|
||||
}
|
||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
) (lines []string) {
|
||||
const pingSeconds = 10
|
||||
const bufSize = 393216
|
||||
const mssFix = 1320
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
RemoteCertTLS: true,
|
||||
AuthUserPass: true,
|
||||
@@ -19,6 +20,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES256gcm,
|
||||
openvpn.AES256cbc,
|
||||
},
|
||||
MssFix: mssFix,
|
||||
Ping: pingSeconds,
|
||||
SndBuf: bufSize,
|
||||
RcvBuf: bufSize,
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
settings settings.OpenVPN, ipv6Supported bool,
|
||||
) (lines []string) {
|
||||
//nolint:mnd
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
RemoteCertTLS: true,
|
||||
AuthUserPass: true,
|
||||
@@ -19,7 +20,8 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES128cbc, // For OpenVPN 2.5, see https://github.com/qdm12/gluetun/issues/2271#issuecomment-2103349935
|
||||
},
|
||||
Auth: openvpn.SHA256,
|
||||
TunMTUExtra: 32, //nolint:mnd
|
||||
MssFix: 1320,
|
||||
TunMTUExtra: 32,
|
||||
KeyDirection: "1",
|
||||
CAs: []string{
|
||||
"MIIDMTCCAhmgAwIBAgIJAKnGGJK6qLqSMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNVBAMMCVRHLVZQTi1DQTAgFw0xOTA1MjExNDIzMTFaGA8yMDU5MDUxMTE0MjMxMVowFDESMBAGA1UEAwwJVEctVlBOLUNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlv0UgPD3xVAvhhP6q1HCmeAWbH+9HPkyQ2P6qM5oHY5dntjmq8YT48FZGHWv7+s9O47v6Bv7rEc4UwQx15cc2LByivX2JwmE8JACvNfwEnZXYAPq9WU3ZgRrAGvA09ItuLqK2fQ4A7h8bFhmyxCbSzP1sSIT/zJY6ebuh5rDQSMJRMaoI0t1zorEZ7PlEmh+o0w5GPs0D0vY50UcnEzB4GOdWC9pJREwEqppWYLN7RRdG8JyIqmA59mhARCnQFUo38HWic4trxFe71jtD7YInNV7ShQtg0S0sXo36Rqfz72Jo08qqI70dNs5DN1aGNkQ/tRK9DhL5DLmTkaCw7mEFQIDAQABo4GDMIGAMB0GA1UdDgQWBBR7DcymXBp6u/jAaZOPUjUhEyhXfjBEBgNVHSMEPTA7gBR7DcymXBp6u/jAaZOPUjUhEyhXfqEYpBYwFDESMBAGA1UEAwwJVEctVlBOLUNBggkAqcYYkrqoupIwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAE79ngbdSlP7IBbfnJ+2Ju7vqt9/GyhcsYtjibp6gsMUxKlD8HuvlSGj5kNO5wiwN7XXqsjYtJfdhmzzVbXksi8Fnbnfa8GhFl4IAjLJ5cxaWOxjr6wx2AhIs+BVVARjaU7iTK91RXJnl6u7UDHTkQylBTl7wgpMeG6GjhaHfcOL1t7D2w8x23cTO+p+n53P3cBq+9TiAUORdzXJvbCxlPMDSDArsgBjC57W7dtdnZo7gTfQG77JTDFBeSwPwLF7PjBB4S6rzU/4fcYwy83XKP6zDn9tgUJDnpFb/7jJ/PbNkK4BWYJp3XytOtt66v9SEKw+v/fJ+VkjU16vE/9Q3h4=", //nolint:lll
|
||||
|
||||
@@ -14,6 +14,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
RemoteCertTLS: true,
|
||||
AuthUserPass: true,
|
||||
MssFix: 1320,
|
||||
Ping: 10,
|
||||
// note DES-CBC is not added since it's quite unsecure
|
||||
Ciphers: []string{openvpn.AES256cbc, openvpn.AES128cbc},
|
||||
|
||||
@@ -10,10 +10,12 @@ import (
|
||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
settings settings.OpenVPN, ipv6Supported bool,
|
||||
) (lines []string) {
|
||||
//nolint:mnd
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
RemoteCertTLS: true,
|
||||
AuthUserPass: false,
|
||||
Ping: 5, //nolint:mnd
|
||||
MssFix: 1320,
|
||||
Ping: 5,
|
||||
RenegDisabled: true,
|
||||
Ciphers: []string{openvpn.AES256cbc},
|
||||
Auth: openvpn.SHA512,
|
||||
|
||||
@@ -18,6 +18,7 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES256cbc,
|
||||
},
|
||||
Auth: openvpn.SHA256,
|
||||
MssFix: 1320,
|
||||
Ping: 10,
|
||||
CAs: []string{"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"}, //nolint:lll
|
||||
TLSCipher: "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA", //nolint:lll
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
settings settings.OpenVPN, ipv6Supported bool,
|
||||
) (lines []string) {
|
||||
//nolint:mnd
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
RemoteCertTLS: true,
|
||||
AuthUserPass: true,
|
||||
@@ -17,7 +18,8 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES256gcm,
|
||||
},
|
||||
Auth: openvpn.SHA512,
|
||||
Ping: 30, //nolint:mnd
|
||||
MssFix: 1320,
|
||||
Ping: 30,
|
||||
RenegDisabled: true,
|
||||
CAs: []string{"MIIDQjCCAiqgAwIBAgIUPppqnRZfvGGrT4GjXFE4Q29QzgowDQYJKoZIhvcNAQELBQAwEzERMA8GA1UEAwwIQ2hhbmdlTWUwHhcNMTkxMTA1MjMzMzIzWhcNMjkxMTAyMjMzMzIzWjATMREwDwYDVQQDDAhDaGFuZ2VNZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL5DFBJlTqhXukJFWlI8TNW9+HEQCZXhyVFvQhJFF2xIGVNx51XzqxiRANjVJZJrA68kV8az0v2Dxj0SFnRWDR6pOjjdp2CyHFcgHyfv+4MrsreAtkue86bB/1ECPWaoIwtaLnwI6SEmFZl98RlI9v4M/8IE4chOnMrM/F22+2OXI//TduvTcbyOMUiiouIP8UG1FB3J5FyuaW6qPZz2G0efDoaOI+E9LSxE87OoFrII7UqdHlWxRb3nUuPU1Ee4rN/d4tFyP4AvPKfsGhVOwyGG21IdRnbXIuDi0xytkCGOZ4j2bq5zqudnp4Izt6yJgdzZpQQWK3kSHB3qTT/Yzl8CAwEAAaOBjTCBijAdBgNVHQ4EFgQUXYkoo4WbkkvbgLVdGob9RScRf3AwTgYDVR0jBEcwRYAUXYkoo4WbkkvbgLVdGob9RScRf3ChF6QVMBMxETAPBgNVBAMMCENoYW5nZU1lghQ+mmqdFl+8YatPgaNcUThDb1DOCjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAOr1XmyWBRYfTQPNvZZ+DjCfiRYzLOi2AGefZt/jETqPDF8deVbyL1fLhXZzuX+5Etlsil3PflJjpzc/FSeZRuYRaShtwF3j6I08Eww9rBkaCnsukMUcLtMOvhdAU8dUakcRA2wkQ7Z+TWdMBv5+/6MnX10An1fIz7bAy3btMEOPTEFLo8Bst1SxJtUMaqhUteSOJ1VorpK3CWfOFaXxbJAb4E0+3zt6Vsc8mY5tt6wAi8IqiN4WD79ZdvKxENK4FMkR1kNpBY97mvdf82rzpwiBuJgN5ywmH78Ghj+9T8nI6/UIqJ1y22IRYGv6dMif8fHo5WWhCv3qmCqqY8vwuxw=="}, //nolint:lll
|
||||
Cert: "MIIDTDCCAjSgAwIBAgIRAKxt8SMIXezjmHm2KDCAQdIwDQYJKoZIhvcNAQELBQAwEzERMA8GA1UEAwwIQ2hhbmdlTWUwHhcNMTkxMTA1MjMzMzI0WhcNMjkxMTAyMjMzMzI0WjAOMQwwCgYDVQQDDAN0Y3AwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvEwY2erLhMm3Mpsnybm3G6zvGyeblUAaehQVEUs+KM2/5np0Ovx0y8Iz9pIC9ITaWM0B3dM6uBsNEtylZIe4Dd9aFujunSeCFsLRf8i9AbrUombpQ6P4jzYFBxwcEw//UShwa4HZI6JuSYikdpx/dyXdBH2skahwDVc8VUFdBLLSglfKGbuzP9GsdSwQCeBRWgA3dvIzIkQkBwfnt9WQKUfRAe8e5NybaAn8Yuu9sjLkQe6eyV7toxkZTcEXdABG2vtdTEzlAsQilZzIxg3jcdeEgMgRKngng+YNP0rR5nofZ1iDlp+vBj0nuqTTJLHMrRWPIc7bdYFD/f2J49WORAgMBAAGjgZ8wgZwwCQYDVR0TBAIwADAdBgNVHQ4EFgQUmSAFmCo1FAKVq8RQF7jMxMxcMtUwTgYDVR0jBEcwRYAUXYkoo4WbkkvbgLVdGob9RScRf3ChF6QVMBMxETAPBgNVBAMMCENoYW5nZU1lghQ+mmqdFl+8YatPgaNcUThDb1DOCjATBgNVHSUEDDAKBggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBADPqdEgL+0kou8P974QEaNg1XOAXpwP0NNqbkZ/Oj9+Lp96YAhAHOAJig+RWbBktK8zu8oUUGR1qLXAWCmirlXErVuBRnadTEh3A7SOuY02BcsYAtpQ2EU9j5K/LV7nTfagkVdWy7x/av361UD4t9fv1j4YYTh4XLRp7KVXs6AGZ7T1hqPYFMUIoPpFhPzFxH4euJjfazr4SkTR6k6Vhw3pyFd6HP65vcqpzHGxFytSa8HtltBk2DpzIf8yV9TEy+gOXFaaGss0YKQ5OU1ieqZRuLVEGiu17lByYiQGyemIETJbdkyiSg93dDJRxjaTk7c8CEdpipt07ndSIPldMtXA=", //nolint:lll
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
settings settings.OpenVPN, ipv6Supported bool,
|
||||
) (lines []string) {
|
||||
//nolint:mnd
|
||||
providerSettings := utils.OpenVPNProviderSettings{
|
||||
RemoteCertTLS: true,
|
||||
AuthUserPass: true,
|
||||
@@ -19,7 +20,8 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||
openvpn.AES128gcm,
|
||||
},
|
||||
Auth: openvpn.SHA512,
|
||||
Ping: 10, //nolint:mnd
|
||||
MssFix: 1320,
|
||||
Ping: 10,
|
||||
VerifyX509Type: "name",
|
||||
KeyDirection: "1",
|
||||
RenegDisabled: true,
|
||||
|
||||
@@ -3,7 +3,11 @@ package api
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -16,6 +20,8 @@ const (
|
||||
IP2Location Provider = "ip2location"
|
||||
)
|
||||
|
||||
const echoipPrefix = "echoip#"
|
||||
|
||||
type NameToken struct {
|
||||
Name string
|
||||
Token string
|
||||
@@ -30,15 +36,19 @@ func New(nameTokenPairs []NameToken, client *http.Client) (
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing API name: %w", err)
|
||||
}
|
||||
switch provider {
|
||||
case Cloudflare:
|
||||
switch {
|
||||
case provider == Cloudflare:
|
||||
fetchers[i] = newCloudflare(client)
|
||||
case IfConfigCo:
|
||||
fetchers[i] = newIfConfigCo(client)
|
||||
case IPInfo:
|
||||
case provider == IfConfigCo:
|
||||
const ifConfigCoURL = "https://ifconfig.co"
|
||||
fetchers[i] = newEchoip(client, ifConfigCoURL)
|
||||
case provider == IPInfo:
|
||||
fetchers[i] = newIPInfo(client, nameTokenPair.Token)
|
||||
case IP2Location:
|
||||
case provider == IP2Location:
|
||||
fetchers[i] = newIP2Location(client, nameTokenPair.Token)
|
||||
case strings.HasPrefix(string(provider), echoipPrefix):
|
||||
url := strings.TrimPrefix(string(provider), echoipPrefix)
|
||||
fetchers[i] = newEchoip(client, url)
|
||||
default:
|
||||
panic("provider not valid: " + provider)
|
||||
}
|
||||
@@ -46,20 +56,88 @@ func New(nameTokenPairs []NameToken, client *http.Client) (
|
||||
return fetchers, nil
|
||||
}
|
||||
|
||||
var regexEchoipURL = regexp.MustCompile(`^http(s|):\/\/.+$`)
|
||||
|
||||
var ErrProviderNotValid = errors.New("API name is not valid")
|
||||
|
||||
func ParseProvider(s string) (provider Provider, err error) {
|
||||
switch strings.ToLower(s) {
|
||||
case "cloudflare":
|
||||
return Cloudflare, nil
|
||||
case string(IfConfigCo):
|
||||
return IfConfigCo, nil
|
||||
case "ipinfo":
|
||||
return IPInfo, nil
|
||||
case "ip2location":
|
||||
return IP2Location, nil
|
||||
default:
|
||||
return "", fmt.Errorf(`%w: %q can only be "cloudflare", "ifconfigco", "ip2location" or "ipinfo"`,
|
||||
ErrProviderNotValid, s)
|
||||
possibleProviders := []Provider{
|
||||
Cloudflare,
|
||||
IfConfigCo,
|
||||
IP2Location,
|
||||
IPInfo,
|
||||
}
|
||||
stringToProvider := make(map[string]Provider, len(possibleProviders))
|
||||
for _, provider := range possibleProviders {
|
||||
stringToProvider[string(provider)] = provider
|
||||
}
|
||||
provider, ok := stringToProvider[strings.ToLower(s)]
|
||||
if ok {
|
||||
return provider, nil
|
||||
}
|
||||
|
||||
customPrefixToURLRegex := map[string]*regexp.Regexp{
|
||||
echoipPrefix: regexEchoipURL,
|
||||
}
|
||||
for prefix, urlRegex := range customPrefixToURLRegex {
|
||||
match, err := checkCustomURL(s, prefix, urlRegex)
|
||||
if !match {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return Provider(s), nil
|
||||
}
|
||||
|
||||
providerStrings := make([]string, 0, len(stringToProvider)+len(customPrefixToURLRegex))
|
||||
for _, providerString := range slices.Sorted(maps.Keys(stringToProvider)) {
|
||||
providerStrings = append(providerStrings, `"`+providerString+`"`)
|
||||
}
|
||||
for _, prefix := range slices.Sorted(maps.Keys(customPrefixToURLRegex)) {
|
||||
providerStrings = append(providerStrings, "a custom "+prefix+" url")
|
||||
}
|
||||
|
||||
return "", fmt.Errorf(`%w: %q can only be %s`,
|
||||
ErrProviderNotValid, s, orStrings(providerStrings))
|
||||
}
|
||||
|
||||
var ErrCustomURLNotValid = errors.New("custom URL is not valid")
|
||||
|
||||
func checkCustomURL(s, prefix string, regex *regexp.Regexp) (match bool, err error) {
|
||||
if !strings.HasPrefix(s, prefix) {
|
||||
return false, nil
|
||||
}
|
||||
s = strings.TrimPrefix(s, prefix)
|
||||
_, err = url.Parse(s)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("%s %w: %w", prefix, ErrCustomURLNotValid, err)
|
||||
}
|
||||
|
||||
if regex.MatchString(s) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return true, fmt.Errorf("%s %w: %q does not match regular expression: %s",
|
||||
prefix, ErrCustomURLNotValid, s, regex)
|
||||
}
|
||||
|
||||
func orStrings(strings []string) (result string) {
|
||||
return joinStrings(strings, "or")
|
||||
}
|
||||
|
||||
func joinStrings(strings []string, lastJoin string) (result string) {
|
||||
if len(strings) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
result = strings[0]
|
||||
for i := 1; i < len(strings); i++ {
|
||||
if i < len(strings)-1 {
|
||||
result += ", " + strings[i]
|
||||
} else {
|
||||
result += " " + lastJoin + " " + strings[i]
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
68
internal/publicip/api/api_test.go
Normal file
68
internal/publicip/api/api_test.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_ParseProvider(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
s string
|
||||
provider Provider
|
||||
errWrapped error
|
||||
errMessage string
|
||||
}{
|
||||
"empty": {
|
||||
errWrapped: ErrProviderNotValid,
|
||||
errMessage: `API name is not valid: "" can only be ` +
|
||||
`"cloudflare", "ifconfigco", "ip2location", "ipinfo" or a custom echoip# url`,
|
||||
},
|
||||
"invalid": {
|
||||
s: "xyz",
|
||||
errWrapped: ErrProviderNotValid,
|
||||
errMessage: `API name is not valid: "xyz" can only be ` +
|
||||
`"cloudflare", "ifconfigco", "ip2location", "ipinfo" or a custom echoip# url`,
|
||||
},
|
||||
"ipinfo": {
|
||||
s: "ipinfo",
|
||||
provider: IPInfo,
|
||||
},
|
||||
"IpInfo": {
|
||||
s: "IpInfo",
|
||||
provider: IPInfo,
|
||||
},
|
||||
"echoip_url_empty": {
|
||||
s: "echoip#",
|
||||
errWrapped: ErrCustomURLNotValid,
|
||||
errMessage: `echoip# custom URL is not valid: "" ` +
|
||||
`does not match regular expression: ^http(s|):\/\/.+$`,
|
||||
},
|
||||
"echoip_url_invalid": {
|
||||
s: "echoip#postgres://localhost:3451",
|
||||
errWrapped: ErrCustomURLNotValid,
|
||||
errMessage: `echoip# custom URL is not valid: "postgres://localhost:3451" ` +
|
||||
`does not match regular expression: ^http(s|):\/\/.+$`,
|
||||
},
|
||||
"echoip_url_valid": {
|
||||
s: "echoip#http://localhost:3451",
|
||||
provider: Provider("echoip#http://localhost:3451"),
|
||||
},
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
provider, err := ParseProvider(testCase.s)
|
||||
|
||||
assert.Equal(t, testCase.provider, provider)
|
||||
assert.ErrorIs(t, err, testCase.errWrapped)
|
||||
if testCase.errWrapped != nil {
|
||||
assert.EqualError(t, err, testCase.errMessage)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -6,39 +6,45 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
type ifConfigCo struct {
|
||||
type echoip struct {
|
||||
client *http.Client
|
||||
url string
|
||||
}
|
||||
|
||||
func newIfConfigCo(client *http.Client) *ifConfigCo {
|
||||
return &ifConfigCo{
|
||||
func newEchoip(client *http.Client, url string) *echoip {
|
||||
return &echoip{
|
||||
client: client,
|
||||
url: url,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *ifConfigCo) String() string {
|
||||
return string(IfConfigCo)
|
||||
func (e *echoip) String() string {
|
||||
s := e.url
|
||||
s = strings.TrimPrefix(s, "http://")
|
||||
s = strings.TrimPrefix(s, "https://")
|
||||
return s
|
||||
}
|
||||
|
||||
func (i *ifConfigCo) CanFetchAnyIP() bool {
|
||||
func (e *echoip) CanFetchAnyIP() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *ifConfigCo) Token() string {
|
||||
func (e *echoip) Token() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// FetchInfo obtains information on the ip address provided
|
||||
// using the ifconfig.co/json API. If the ip is the zero value,
|
||||
// using the echoip API at the url given. If the ip is the zero value,
|
||||
// the public IP address of the machine is used as the IP.
|
||||
func (i *ifConfigCo) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
func (e *echoip) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
result models.PublicIP, err error,
|
||||
) {
|
||||
url := "https://ifconfig.co/json"
|
||||
url := e.url + "/json"
|
||||
if ip.IsValid() {
|
||||
url += "?ip=" + ip.String()
|
||||
}
|
||||
@@ -48,7 +54,7 @@ func (i *ifConfigCo) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
return result, err
|
||||
}
|
||||
|
||||
response, err := i.client.Do(request)
|
||||
response, err := e.client.Do(request)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -26,7 +26,7 @@ func (r *Routing) addIPRule(src, dst netip.Prefix, table, priority int) error {
|
||||
}
|
||||
|
||||
if err := r.netLinker.RuleAdd(rule); err != nil {
|
||||
return fmt.Errorf("adding rule %s: %w", rule, err)
|
||||
return fmt.Errorf("adding %s: %w", rule, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func Test_Routing_addIPRule(t *testing.T) {
|
||||
ruleToAdd: makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 99, 99),
|
||||
err: errDummy,
|
||||
},
|
||||
err: errors.New("adding rule ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99: dummy error"),
|
||||
err: errors.New("adding ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99: dummy error"),
|
||||
},
|
||||
"add rule success": {
|
||||
src: makeNetipPrefix(1),
|
||||
|
||||
@@ -27,7 +27,7 @@ func (a *apiKeyMethod) equal(other authorizationChecker) bool {
|
||||
}
|
||||
|
||||
func (a *apiKeyMethod) isAuthorized(_ http.Header, request *http.Request) bool {
|
||||
xAPIKey := request.Header.Get("X-API-Key") //nolint:canonicalheader
|
||||
xAPIKey := request.Header.Get("X-API-Key")
|
||||
if xAPIKey == "" {
|
||||
xAPIKey = request.URL.Query().Get("api_key")
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func (h *authHandler) warnIfUnprotectedByDefault(role internalRole, route string
|
||||
}
|
||||
h.logger.Warnf("route %s is unprotected by default, "+
|
||||
"please set up authentication following the documentation at "+
|
||||
"https://github.com/qdm12/gluetun-wiki/setup/advanced/control-server.md#authentication "+
|
||||
"https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md#authentication "+
|
||||
"since this will become no longer publicly accessible after release v3.40.",
|
||||
route)
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func Test_authHandler_ServeHTTP(t *testing.T) {
|
||||
logger := NewMockDebugLogger(ctrl)
|
||||
logger.EXPECT().Warnf("route %s is unprotected by default, "+
|
||||
"please set up authentication following the documentation at "+
|
||||
"https://github.com/qdm12/gluetun-wiki/setup/advanced/control-server.md#authentication "+
|
||||
"https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md#authentication "+
|
||||
"since this will become no longer publicly accessible after release v3.40.",
|
||||
"GET /v1/vpn/status")
|
||||
logger.EXPECT().Debugf("access to route %s authorized for role %s",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,9 @@ func (t *Tun) Create(path string) (err error) {
|
||||
|
||||
fd, err := unix.Open(path, 0, 0)
|
||||
if err != nil {
|
||||
if err.Error() == "operation not permitted" {
|
||||
err = fmt.Errorf("%w (did you specify --device /dev/net/tun to your container command?)", err)
|
||||
}
|
||||
return fmt.Errorf("unix opening TUN device file: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -118,5 +118,5 @@ func Test_netlink_Wireguard_addRule(t *testing.T) {
|
||||
_ = nilCleanup() // in case it succeeds
|
||||
}
|
||||
require.Error(t, err)
|
||||
assert.EqualError(t, err, "adding rule ip rule 10000: from all to all table 999: file exists")
|
||||
assert.EqualError(t, err, "adding ip rule 10000: from all to all table 999: file exists")
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package wireguard
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/netlink"
|
||||
)
|
||||
@@ -16,7 +17,11 @@ func (w *Wireguard) addRule(rulePriority int, firewallMark uint32,
|
||||
rule.Table = int(firewallMark)
|
||||
rule.Family = family
|
||||
if err := w.netlink.RuleAdd(rule); err != nil {
|
||||
return nil, fmt.Errorf("adding rule %s: %w", rule, err)
|
||||
if strings.HasSuffix(err.Error(), "file exists") {
|
||||
w.logger.Info("if you are using Kubernetes, this may fix the error below: " +
|
||||
"https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/kubernetes.md#adding-ipv6-rule--file-exists")
|
||||
}
|
||||
return nil, fmt.Errorf("adding %s: %w", rule, err)
|
||||
}
|
||||
|
||||
cleanup = func() error {
|
||||
|
||||
@@ -45,7 +45,7 @@ func Test_Wireguard_addRule(t *testing.T) {
|
||||
Family: family,
|
||||
},
|
||||
ruleAddErr: errDummy,
|
||||
err: errors.New("adding rule ip rule 987: from all to all table 456: dummy"),
|
||||
err: errors.New("adding ip rule 987: from all to all table 456: dummy"),
|
||||
},
|
||||
"rule delete error": {
|
||||
expectedRule: netlink.Rule{
|
||||
|
||||
Reference in New Issue
Block a user