Compare commits

...

27 Commits

Author SHA1 Message Date
Quentin McGaw
c74ec9a38b Revert back to Alpine 3.12 for 32 bit systems 2021-01-30 23:15:54 +00:00
Quentin McGaw
937d09f1c3 CI: Fix publish job CI 2021-01-23 16:58:46 +00:00
dependabot[bot]
3769092888 Bump github.com/stretchr/testify from 1.6.1 to 1.7.0 (#344) 2021-01-23 11:25:08 -05:00
Quentin McGaw
75281dee07 CI: remove risv64 as Alpine does not support it 2021-01-23 16:22:28 +00:00
Quentin McGaw
26a7c5eaef Feature: openvpn exits on TLS error 2021-01-22 13:36:56 +00:00
Quentin McGaw
1e8254fabf CI: Update golangci-lint to v1.35.2 2021-01-22 13:32:47 +00:00
Quentin McGaw
43b6509b43 Feature: upgrade to Alpine 3.13 2021-01-22 13:32:05 +00:00
Quentin McGaw
204c5b2446 Feature: add 10s ping with 60s exit ping for all 2021-01-22 13:30:06 +00:00
Quentin McGaw
7ab3347604 CI: Remove duplicate COPY in Dockerfile 2021-01-22 13:21:42 +00:00
Quentin McGaw
2f24a79d4d CI: Go mod tidy check 2021-01-22 13:20:54 +00:00
Quentin McGaw
819b1fe0f6 CI: Merge workflows in build.yml 2021-01-22 13:19:45 +00:00
Quentin McGaw
9f04b2d56c (fix) Update Nordvpn servers timestamp 2021-01-20 03:50:38 +00:00
Quentin McGaw
5eff5fac67 Update Nordvpn servers list 2021-01-20 03:44:55 +00:00
Quentin McGaw
d033d08c4d Maintenance: unit tests utils in provider package 2021-01-20 03:36:36 +00:00
Quentin McGaw
25644d061e Fix build (lint error) 2021-01-19 14:20:57 +00:00
Quentin McGaw
e7372f22cb Feature: OPENVPN_MSSFIX variable 2021-01-19 02:55:38 +00:00
Quentin McGaw
4530dd4fea Maintenance: OpenVPN BuildConf arity reduced 2021-01-19 02:42:16 +00:00
Quentin McGaw
072528af83 CI: Dockerfile fixes
- Pin xcputranslate version
- Update xcputranslate usage
- Set default BUILDPLATFORM to linux/amd64
2021-01-18 00:58:47 +00:00
Quentin McGaw
2c4d577f23 Maintenance: Update golibs and update params 2021-01-10 23:06:09 +00:00
Quentin McGaw
edd67e3473 Remove pull_request_target based workflow 2021-01-08 03:13:40 +00:00
Quentin McGaw
f389642dba Maintenance: Improve Go devcontainer settings 2021-01-08 02:27:48 +00:00
Quentin McGaw
b8690c7f83 CI: Change microbadger hook to gluetun 2021-01-08 02:25:41 +00:00
Quentin McGaw
06b809a492 Maintenance: Improve .dockerignore 2021-01-08 02:24:31 +00:00
Quentin McGaw
2ceda2faaa Documentation: Move sections to Wiki 2021-01-08 02:24:15 +00:00
Quentin McGaw
c7fc3afc21 Fix: DNS_KEEP_NAMESERVER behavior 2021-01-06 21:52:55 +00:00
Quentin McGaw
af57043afd Add docker and gomod to dependabot config 2021-01-06 04:23:09 +00:00
Quentin McGaw
4a85f3660c CI: Further reworking of workflows 2021-01-06 04:22:56 +00:00
65 changed files with 1601 additions and 1739 deletions

View File

@@ -31,25 +31,34 @@
"remote.extensionKind": {
"ms-azuretools.vscode-docker": "workspace"
},
"editor.codeActionsOnSaveTimeout": 3000,
"go.useLanguageServer": true,
"[go]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true,
},
// Optional: Disable snippets, as they conflict with completion ranking.
"editor.snippetSuggestions": "none"
},
"[go.mod]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true,
},
},
"gopls": {
"usePlaceholders": false,
"staticcheck": true
},
"go.autocompleteUnimportedPackages": true,
"go.gotoSymbol.includeImports": true,
"go.gotoSymbol.includeGoroot": true,
"gopls": {
"completeUnimported": true,
"deepCompletion": true,
"usePlaceholders": false
},
"go.lintTool": "golangci-lint",
"go.buildOnSave": "workspace",
"go.lintOnSave": "workspace",
"go.vetOnSave": "workspace",
"editor.formatOnSave": true,
"[go]": {
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"go.toolsEnvVars": {
"GOFLAGS": "-tags=",
// "CGO_ENABLED": 1 // for the race detector
@@ -57,7 +66,9 @@
"gopls.env": {
"GOFLAGS": "-tags="
},
"go.testEnvVars": {},
"go.testEnvVars": {
"": ""
},
"go.testFlags": [
"-v",
// "-race"

View File

@@ -1,10 +1,9 @@
.devcontainer
.git
.github
cmd
!cmd/gluetun
doc
docker-compose.yml
Dockerfile
LICENSE
README.md
title.svg

View File

@@ -13,17 +13,6 @@ Contributions are [released](https://help.github.com/articles/github-terms-of-se
## Resources
- [Gluetun guide on development](https://github.com/qdm12/gluetun/wiki/Development)
- [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
## Contributors
Thanks for all the contributions, whether small or not so small!
- [@JeordyR](https://github.com/JeordyR) for testing the Mullvad version and opening a [PR with a few fixes](https://github.com/qdm12/gluetun/pull/84/files) 👍
- [@rorph](https://github.com/rorph) for a [PR to pick a random region for PIA](https://github.com/qdm12/gluetun/pull/70) and a [PR to make the container work with kubernetes](https://github.com/qdm12/gluetun/pull/69)
- [@JesterEE](https://github.com/JesterEE) for a [PR to fix silly line endings in block lists back then](https://github.com/qdm12/gluetun/pull/55) 📎
- [@elmerfdz](https://github.com/elmerfdz) for a [PR to add timezone information to have correct log timestampts](https://github.com/qdm12/gluetun/pull/51) 🕙
- [@Juggels](https://github.com/Juggels) for a [PR to write the PIA forwarded port to a file](https://github.com/qdm12/gluetun/pull/43)
- [@gdlx](https://github.com/gdlx) for a [PR to fix and improve PIA port forwarding script](https://github.com/qdm12/gluetun/pull/32)
- [@janaz](https://github.com/janaz) for keeping an eye on [updating things in the Dockerfile](https://github.com/qdm12/gluetun/pull/8)

View File

@@ -5,3 +5,11 @@ updates:
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: docker
directory: /
schedule:
interval: "daily"
- package-ecosystem: gomod
directory: /
schedule:
interval: "daily"

View File

@@ -1,52 +0,0 @@
name: branch
on:
push:
branches:
- "*"
- "!master"
paths:
- .github/workflows/branch.yml
- cmd/**
- internal/**
- .dockerignore
- .golangci.yml
- Dockerfile
- go.mod
- go.sum
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- env:
DOCKER_BUILDKIT: "1"
run: docker build --target test .
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- env:
DOCKER_BUILDKIT: "1"
run: docker build --target lint .
docker:
runs-on: ubuntu-latest
needs: [test, lint]
steps:
- uses: actions/checkout@v2
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- name: Dockerhub login
run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u qmcgaw --password-stdin 2>&1
- name: Docker build
run: |
docker buildx build \
--platform=linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7,linux/s390x,linux/ppc64le \
--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
--build-arg COMMIT=`git rev-parse --short HEAD` \
--build-arg VERSION="branch-${GITHUB_REF##*/}" \
-t qmcgaw/gluetun:branch-${GITHUB_REF##*/} \
--push \
.

100
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,100 @@
name: CI
on:
push:
paths:
- .github/workflows/build.yml
- cmd/**
- internal/**
- pkg/**
- .dockerignore
- .golangci.yml
- Dockerfile
- go.mod
- go.sum
jobs:
verify:
runs-on: ubuntu-latest
env:
DOCKER_BUILDKIT: "1"
steps:
- uses: actions/checkout@v2
- name: Linting
run: docker build --target lint .
- name: Go mod tidy check
run: docker build --target tidy .
- name: Build test image
run: docker build --target test -t test-container .
- name: Run tests in test container
run: |
touch coverage.txt
docker run --rm \
-v "$(pwd)/coverage.txt:/tmp/gobuild/coverage.txt" \
test-container \
go test \
-race \
-coverpkg=./... \
-coverprofile=coverage.txt \
-covermode=atomic \
./...
# We run this here to use the caching of the previous steps
- if: github.event_name == 'push'
name: Build final image
run: docker build .
publish:
needs: [verify]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- uses: docker/login-action@v1
with:
username: qmcgaw
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Set variables
id: vars
env:
EVENT_NAME: ${{ github.event_name }}
run: |
BRANCH=${GITHUB_REF#refs/heads/}
TAG=${GITHUB_REF#refs/tags/}
echo ::set-output name=commit::$(git rev-parse --short HEAD)
echo ::set-output name=build_date::$(date -u +%Y-%m-%dT%H:%M:%SZ)
if [ "$TAG" != "$GITHUB_REF" ]; then
echo ::set-output name=version::$TAG
echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7,linux/s390x,linux/ppc64le
elif [ "$BRANCH" = "master" ]; then
echo ::set-output name=version::latest
echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7,linux/s390x,linux/ppc64le
else
echo ::set-output name=version::$BRANCH
echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7
fi
- name: Build and push final image
uses: docker/build-push-action@v2
with:
platforms: ${{ steps.vars.outputs.platforms }}
build-args: |
BUILD_DATE=${{ steps.vars.outputs.build_date }}
COMMIT=${{ steps.vars.outputs.commit }}
VERSION=${{ steps.vars.outputs.version }}
tags: |
qmcgaw/gluetun:${{ steps.vars.outputs.version }}
qmcgaw/private-internet-access:${{ steps.vars.outputs.version }}
push: true
- if: github.event_name == 'push' && github.event.ref == 'refs/heads/master'
name: Microbadger hook
run: curl -X POST https://hooks.microbadger.com/images/qmcgaw/gluetun/l-keGI7p4IhX4QuIDMFYKhsZ1L0=
continue-on-error: true

View File

@@ -12,7 +12,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v2.4.1
uses: peter-evans/dockerhub-description@v2
with:
username: qmcgaw
password: ${{ secrets.DOCKERHUB_PASSWORD }}

View File

@@ -9,10 +9,7 @@ jobs:
labeler:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Labeler
if: success()
uses: crazy-max/ghaction-github-labeler@v3.1.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v2
- uses: crazy-max/ghaction-github-labeler@v3
with:
yaml-file: .github/labels.yml

View File

@@ -1,53 +0,0 @@
name: latest
on:
push:
branches: [master]
paths:
- .github/workflows/latest.yml
- cmd/**
- internal/**
- .dockerignore
- .golangci.yml
- Dockerfile
- go.mod
- go.sum
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- env:
DOCKER_BUILDKIT: "1"
run: docker build --target test .
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- env:
DOCKER_BUILDKIT: "1"
run: docker build --target lint .
docker:
runs-on: ubuntu-latest
needs: [test, lint]
steps:
- uses: actions/checkout@v2
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- name: Dockerhub login
run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u qmcgaw --password-stdin 2>&1
- name: Docker buildx
run: |
docker buildx build \
--platform=linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7,linux/s390x,linux/ppc64le \
--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
--build-arg COMMIT=`git rev-parse --short HEAD` \
--build-arg VERSION=latest \
-t qmcgaw/private-internet-access:latest \
-t qmcgaw/gluetun:latest \
--push \
.
- run: curl -X POST https://hooks.microbadger.com/images/qmcgaw/private-internet-access/tQFy7AxtSUNANPe6aoVChYdsI_I=
continue-on-error: true

View File

@@ -9,8 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: reviewdog/action-misspell@master
- uses: reviewdog/action-misspell@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
locale: "US"
level: error

View File

@@ -1,40 +0,0 @@
name: pull request
on:
pull_request:
branches: [master]
paths:
- .github/workflows/pr.yml
- cmd/**
- internal/**
- .dockerignore
- .golangci.yml
- Dockerfile
- go.mod
- go.sum
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- env:
DOCKER_BUILDKIT: "1"
run: docker build --target test .
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- env:
DOCKER_BUILDKIT: "1"
run: docker build --target lint .
docker:
runs-on: ubuntu-latest
needs: [test, lint]
steps:
- uses: actions/checkout@v2
- name: Docker build
env:
DOCKER_BUILDKIT: "1"
run: docker build .

View File

@@ -1,51 +0,0 @@
name: release
on:
release:
types: [published]
paths:
- .github/workflows/release.yml
- cmd/**
- internal/**
- .dockerignore
- .golangci.yml
- Dockerfile
- go.mod
- go.sum
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- env:
DOCKER_BUILDKIT: "1"
run: docker build --target test .
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- env:
DOCKER_BUILDKIT: "1"
run: docker build --target lint .
docker:
runs-on: ubuntu-latest
needs: [test, lint]
steps:
- uses: actions/checkout@v2
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- name: Dockerhub login
run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u qmcgaw --password-stdin 2>&1
- name: Docker buildx
run: |
docker buildx build \
--platform=linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7,linux/s390x,linux/ppc64le \
--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
--build-arg COMMIT=`git rev-parse --short HEAD` \
--build-arg VERSION=${GITHUB_REF##*/} \
-t qmcgaw/private-internet-access:${GITHUB_REF##*/} \
-t qmcgaw/gluetun:${GITHUB_REF##*/} \
--push \
.

View File

@@ -1,5 +1,6 @@
ARG ALPINE_VERSION=3.12
ARG GO_VERSION=1.15
ARG BUILDPLATFORM=linux/amd64
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base
RUN apk --update add git
@@ -11,27 +12,36 @@ COPY cmd/ ./cmd/
COPY internal/ ./internal/
FROM --platform=$BUILDPLATFORM base AS test
# Note on the go race detector:
# - we set CGO_ENABLED=1 to have it enabled
# - we install g++ to support the race detector
ENV CGO_ENABLED=1
RUN apk --update add g++
RUN go test -race ./...
RUN apk --update --no-cache add g++
FROM --platform=$BUILDPLATFORM base AS lint
ARG GOLANGCI_LINT_VERSION=v1.34.1
ARG GOLANGCI_LINT_VERSION=v1.35.2
RUN wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | \
sh -s -- -b /usr/local/bin ${GOLANGCI_LINT_VERSION}
COPY .golangci.yml ./
RUN golangci-lint run --timeout=10m
FROM --platform=$BUILDPLATFORM base AS tidy
RUN git init && \
git config user.email ci@localhost && \
git config user.name ci && \
git add -A && git commit -m ci && \
sed -i '/\/\/ indirect/d' go.mod && \
go mod tidy && \
git diff --exit-code -- go.mod
FROM --platform=$BUILDPLATFORM base AS build
COPY --from=qmcgaw/xcputranslate /xcputranslate /usr/local/bin/xcputranslate
COPY --from=qmcgaw/xcputranslate:v0.4.0 /xcputranslate /usr/local/bin/xcputranslate
ARG TARGETPLATFORM
ARG VERSION=unknown
ARG BUILD_DATE="an unknown date"
ARG COMMIT=unknown
COPY cmd/ ./cmd/
COPY internal/ ./internal/
RUN GOARCH="$(echo ${TARGETPLATFORM} | xcputranslate -field arch)" \
GOARM="$(echo ${TARGETPLATFORM} | xcputranslate -field arm)" \
RUN GOARCH="$(xcputranslate -field arch -targetplatform ${TARGETPLATFORM})" \
GOARM="$(xcputranslate -field arm -targetplatform ${TARGETPLATFORM})" \
go build -trimpath -ldflags="-s -w \
-X 'main.version=$VERSION' \
-X 'main.buildDate=$BUILD_DATE' \

View File

@@ -89,26 +89,10 @@ The following points are all optional but should give you insights on all the po
- [HTTP control server](https://github.com/qdm12/gluetun/wiki/HTTP-Control-server) to automate things, restart Openvpn etc.
- Update the image with `docker pull qmcgaw/gluetun:latest`. See this [Wiki document](https://github.com/qdm12/gluetun/wiki/Docker-image-tags) for Docker tags available.
## Development
- 💻 [Contribute with code](https://github.com/qdm12/gluetun/wiki/Development) ([existing contributors 👍](https://github.com/qdm12/gluetun/blob/master/.github/CONTRIBUTING.md#Contributors))
- [List of issues and feature requests](https://github.com/qdm12/gluetun/issues)
- [Kanban board](https://github.com/qdm12/gluetun/projects/1)
## License
[![MIT](https://img.shields.io/github/license/qdm12/gluetun)](https://github.com/qdm12/gluetun/master/LICENSE)
## Support
- Sponsor me on [Github](https://github.com/sponsors/qdm12) or donate to [paypal.me/qmcgaw](https://www.paypal.me/qmcgaw)
[![https://github.com/sponsors/qdm12](https://raw.githubusercontent.com/qdm12/gluetun/master/doc/sponsors.jpg)](https://github.com/sponsors/qdm12)
[![https://www.paypal.me/qmcgaw](https://raw.githubusercontent.com/qdm12/gluetun/master/doc/paypal.jpg)](https://www.paypal.me/qmcgaw)
- Contribute to the issues and discussions on Github
- Many thanks to @Frepke, @Ralph521, G. Mendez, M. Otmar Weber, J. Perez, A. Cooper and **others** for supporting me financially 🥇👍
## Metadata
[![GitHub commit activity](https://img.shields.io/github/commit-activity/y/qdm12/gluetun.svg)](https://github.com/qdm12/gluetun/commits)

View File

@@ -152,7 +152,10 @@ func _main(background context.Context, buildInfo models.BuildInformation,
"IPtables": firewallConf.Version,
})
allSettings, err := settings.GetAllSettings(paramsReader)
allSettings, warnings, err := settings.GetAllSettings(paramsReader)
for _, warning := range warnings {
logger.Warn(warning)
}
if err != nil {
return err
}
@@ -408,7 +411,8 @@ func routeReadyEvents(ctx context.Context, wg *sync.WaitGroup, buildInfo models.
restartTickerCancel() // stop previous restart tickers
tickerWg.Wait()
restartTickerContext, restartTickerCancel = context.WithCancel(ctx)
tickerWg.Add(2) //nolint:gomnd
//nolint:gomnd
tickerWg.Add(2)
go unboundLooper.RunRestartTicker(restartTickerContext, tickerWg)
go updaterLooper.RunRestartTicker(restartTickerContext, tickerWg)
vpnDestination, err := routing.VPNDestinationIP()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

6
go.mod
View File

@@ -6,11 +6,11 @@ require (
github.com/fatih/color v1.10.0
github.com/golang/mock v1.4.4
github.com/kyokomi/emoji v2.2.4+incompatible
github.com/qdm12/dns v1.4.0-rc3
github.com/qdm12/golibs v0.0.0-20210102020307-17bc97def973
github.com/qdm12/dns v1.4.0-rc4
github.com/qdm12/golibs v0.0.0-20210110211000-0a3a4541ae09
github.com/qdm12/ss-server v0.1.0
github.com/qdm12/updated v0.0.0-20210102005021-dd457d77f94a
github.com/stretchr/testify v1.6.1
github.com/stretchr/testify v1.7.0
github.com/vishvananda/netlink v1.1.0
golang.org/x/sys v0.0.0-20201223074533-0d417f636930
)

8
go.sum
View File

@@ -92,11 +92,13 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/qdm12/dns v1.4.0-rc3 h1:pbzeygQtX1ElaAYPj0Dn9XictYZgNyJc1xS7bDMyQ6Y=
github.com/qdm12/dns v1.4.0-rc3/go.mod h1:JhUKBhuDRYBUQ2XwW/jbeWx/qS0sSJjIFjGTCFGP5I8=
github.com/qdm12/dns v1.4.0-rc4 h1:pCcFMqismbktPQX7yrtdmJZq30Y05JBfWRTXY1ZLVFw=
github.com/qdm12/dns v1.4.0-rc4/go.mod h1:JhUKBhuDRYBUQ2XwW/jbeWx/qS0sSJjIFjGTCFGP5I8=
github.com/qdm12/golibs v0.0.0-20201227203847-2fd99ffdfdba/go.mod h1:pikkTN7g7zRuuAnERwqW1yAFq6pYmxrxpjiwGvb0Ysc=
github.com/qdm12/golibs v0.0.0-20210102020307-17bc97def973 h1:5YeJALmDjvg2wSi6XB8MpQQekbT/eBnwGahJrh01HHQ=
github.com/qdm12/golibs v0.0.0-20210102020307-17bc97def973/go.mod h1:pikkTN7g7zRuuAnERwqW1yAFq6pYmxrxpjiwGvb0Ysc=
github.com/qdm12/golibs v0.0.0-20210110211000-0a3a4541ae09 h1:zP+ZRwV3GldgTWFgKNBQ2zoFA8mIczb+fvTvrX8LZRo=
github.com/qdm12/golibs v0.0.0-20210110211000-0a3a4541ae09/go.mod h1:pikkTN7g7zRuuAnERwqW1yAFq6pYmxrxpjiwGvb0Ysc=
github.com/qdm12/ss-server v0.1.0 h1:WV9MkHCDEWRwe4WpnYFeR/zcZAxYoTbfntLDnw9AQ50=
github.com/qdm12/ss-server v0.1.0/go.mod h1:ABVUkxubboL3vqBkOwDV9glX1/x7SnYrckBe5d+M/zw=
github.com/qdm12/updated v0.0.0-20210102005021-dd457d77f94a h1:gkyP+gMEeBgMgyRYGrVNcoy6cL1065IvXsyfB6xboIc=
@@ -114,6 +116,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=

7
internal/cli/ci.go Normal file
View File

@@ -0,0 +1,7 @@
package cli
import "context"
func (c *cli) CI(context context.Context) error {
return nil
}

View File

@@ -20,7 +20,7 @@ func (c *cli) OpenvpnConfig(os os.OS) error {
return err
}
paramsReader := params.NewReader(logger, os)
allSettings, err := settings.GetAllSettings(paramsReader)
allSettings, _, err := settings.GetAllSettings(paramsReader)
if err != nil {
return err
}
@@ -34,15 +34,7 @@ func (c *cli) OpenvpnConfig(os os.OS) error {
if err != nil {
return err
}
lines := providerConf.BuildConf(
connection,
allSettings.OpenVPN.Verbosity,
"nonroortuser",
allSettings.OpenVPN.Root,
allSettings.OpenVPN.Cipher,
allSettings.OpenVPN.Auth,
allSettings.OpenVPN.Provider.ExtraConfigOptions,
)
lines := providerConf.BuildConf(connection, "nonroortuser", allSettings.OpenVPN)
fmt.Println(strings.Join(lines, "\n"))
return nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@ func GetAllServers() (allServers models.AllServers) {
},
Nordvpn: models.NordvpnServers{
Version: 1,
Timestamp: 1599323261,
Timestamp: 1611096594,
Servers: NordvpnServers(),
},
Pia: models.PiaServers{

View File

@@ -128,7 +128,7 @@ func Test_timestamps(t *testing.T) {
"Nordvpn": {
servers: allServers.Nordvpn.Servers,
timestamp: allServers.Nordvpn.Timestamp,
digest: "9fc9a579",
digest: "5f70b19b",
},
"Private Internet Access": {
servers: allServers.Pia.Servers,

View File

@@ -92,6 +92,7 @@ func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup, dnsReadyCh chan<-
const fallback = false
l.useUnencryptedDNS(fallback) // TODO remove? Use default DNS by default for Docker resolution?
// TODO this one is kept if DNS_KEEP_NAMESERVER=on and should be replaced
select {
case <-l.start:

View File

@@ -119,15 +119,7 @@ func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
l.cancel()
return
}
lines := providerConf.BuildConf(
connection,
settings.Verbosity,
l.username,
settings.Root,
settings.Cipher,
settings.Auth,
settings.Provider.ExtraConfigOptions,
)
lines := providerConf.BuildConf(connection, l.username, settings)
if err := writeOpenvpnConf(lines, l.openFile); err != nil {
l.logger.Error(err)

View File

@@ -11,23 +11,23 @@ import (
// GetCyberghostGroup obtains the server group for the Cyberghost server from the
// environment variable CYBERGHOST_GROUP.
func (p *reader) GetCyberghostGroup() (group string, err error) {
s, err := p.envParams.GetValueIfInside("CYBERGHOST_GROUP",
func (r *reader) GetCyberghostGroup() (group string, err error) {
s, err := r.env.Inside("CYBERGHOST_GROUP",
constants.CyberghostGroupChoices(), libparams.Default("Premium UDP Europe"))
return s, err
}
// GetCyberghostRegions obtains the country names for the Cyberghost servers from the
// environment variable REGION.
func (p *reader) GetCyberghostRegions() (regions []string, err error) {
return p.envParams.GetCSVInPossibilities("REGION", constants.CyberghostRegionChoices())
func (r *reader) GetCyberghostRegions() (regions []string, err error) {
return r.env.CSVInside("REGION", constants.CyberghostRegionChoices())
}
// GetCyberghostClientKey obtains the client key to use for openvpn
// from the secret file /run/secrets/openvpn_clientkey or from the file
// /gluetun/client.key.
func (p *reader) GetCyberghostClientKey() (clientKey string, err error) {
b, err := p.getFromFileOrSecretFile("OPENVPN_CLIENTKEY", string(constants.ClientKey))
func (r *reader) GetCyberghostClientKey() (clientKey string, err error) {
b, err := r.getFromFileOrSecretFile("OPENVPN_CLIENTKEY", string(constants.ClientKey))
if err != nil {
return "", err
}
@@ -50,8 +50,8 @@ func extractClientKey(b []byte) (key string, err error) {
// GetCyberghostClientCertificate obtains the client certificate to use for openvpn
// from the secret file /run/secrets/openvpn_clientcrt or from the file
// /gluetun/client.crt.
func (p *reader) GetCyberghostClientCertificate() (clientCertificate string, err error) {
b, err := p.getFromFileOrSecretFile("OPENVPN_CLIENTCRT", string(constants.ClientCertificate))
func (r *reader) GetCyberghostClientCertificate() (clientCertificate string, err error) {
b, err := r.getFromFileOrSecretFile("OPENVPN_CLIENTCRT", string(constants.ClientCertificate))
if err != nil {
return "", err
}

View File

@@ -13,13 +13,13 @@ import (
// GetDNSOverTLS obtains if the DNS over TLS should be enabled
// from the environment variable DOT.
func (r *reader) GetDNSOverTLS() (DNSOverTLS bool, err error) { //nolint:gocritic
return r.envParams.GetOnOff("DOT", libparams.Default("on"))
return r.env.OnOff("DOT", libparams.Default("on"))
}
// GetDNSOverTLSProviders obtains the DNS over TLS providers to use
// from the environment variable DOT_PROVIDERS.
func (r *reader) GetDNSOverTLSProviders() (providers []string, err error) {
s, err := r.envParams.GetEnv("DOT_PROVIDERS", libparams.Default("cloudflare"))
s, err := r.env.Get("DOT_PROVIDERS", libparams.Default("cloudflare"))
if err != nil {
return nil, err
}
@@ -36,28 +36,28 @@ func (r *reader) GetDNSOverTLSProviders() (providers []string, err error) {
// GetDNSOverTLSVerbosity obtains the verbosity level to use for Unbound
// from the environment variable DOT_VERBOSITY.
func (r *reader) GetDNSOverTLSVerbosity() (verbosityLevel uint8, err error) {
n, err := r.envParams.GetEnvIntRange("DOT_VERBOSITY", 0, 5, libparams.Default("1"))
n, err := r.env.IntRange("DOT_VERBOSITY", 0, 5, libparams.Default("1"))
return uint8(n), err
}
// GetDNSOverTLSVerbosityDetails obtains the log level to use for Unbound
// from the environment variable DOT_VERBOSITY_DETAILS.
func (r *reader) GetDNSOverTLSVerbosityDetails() (verbosityDetailsLevel uint8, err error) {
n, err := r.envParams.GetEnvIntRange("DOT_VERBOSITY_DETAILS", 0, 4, libparams.Default("0"))
n, err := r.env.IntRange("DOT_VERBOSITY_DETAILS", 0, 4, libparams.Default("0"))
return uint8(n), err
}
// GetDNSOverTLSValidationLogLevel obtains the log level to use for Unbound DOT validation
// from the environment variable DOT_VALIDATION_LOGLEVEL.
func (r *reader) GetDNSOverTLSValidationLogLevel() (validationLogLevel uint8, err error) {
n, err := r.envParams.GetEnvIntRange("DOT_VALIDATION_LOGLEVEL", 0, 2, libparams.Default("0"))
n, err := r.env.IntRange("DOT_VALIDATION_LOGLEVEL", 0, 2, libparams.Default("0"))
return uint8(n), err
}
// GetDNSMaliciousBlocking obtains if malicious hostnames/IPs should be blocked
// from being resolved by Unbound, using the environment variable BLOCK_MALICIOUS.
func (r *reader) GetDNSMaliciousBlocking() (blocking bool, err error) {
return r.envParams.GetOnOff("BLOCK_MALICIOUS", libparams.Default("on"))
return r.env.OnOff("BLOCK_MALICIOUS", libparams.Default("on"))
}
// GetDNSSurveillanceBlocking obtains if surveillance hostnames/IPs should be blocked
@@ -65,26 +65,26 @@ func (r *reader) GetDNSMaliciousBlocking() (blocking bool, err error) {
// and BLOCK_NSA for retrocompatibility.
func (r *reader) GetDNSSurveillanceBlocking() (blocking bool, err error) {
// Retro-compatibility
s, err := r.envParams.GetEnv("BLOCK_NSA")
s, err := r.env.Get("BLOCK_NSA")
if err != nil {
return false, err
} else if len(s) != 0 {
r.logger.Warn("You are using the old environment variable BLOCK_NSA, please consider changing it to BLOCK_SURVEILLANCE") //nolint:lll
return r.envParams.GetOnOff("BLOCK_NSA", libparams.Compulsory())
return r.env.OnOff("BLOCK_NSA", libparams.Compulsory())
}
return r.envParams.GetOnOff("BLOCK_SURVEILLANCE", libparams.Default("off"))
return r.env.OnOff("BLOCK_SURVEILLANCE", libparams.Default("off"))
}
// GetDNSAdsBlocking obtains if ads hostnames/IPs should be blocked
// from being resolved by Unbound, using the environment variable BLOCK_ADS.
func (r *reader) GetDNSAdsBlocking() (blocking bool, err error) {
return r.envParams.GetOnOff("BLOCK_ADS", libparams.Default("off"))
return r.env.OnOff("BLOCK_ADS", libparams.Default("off"))
}
// GetDNSUnblockedHostnames obtains a list of hostnames to unblock from block lists
// from the comma separated list for the environment variable UNBLOCK.
func (r *reader) GetDNSUnblockedHostnames() (hostnames []string, err error) {
s, err := r.envParams.GetEnv("UNBLOCK")
s, err := r.env.Get("UNBLOCK")
if err != nil {
return nil, err
} else if len(s) == 0 {
@@ -92,7 +92,7 @@ func (r *reader) GetDNSUnblockedHostnames() (hostnames []string, err error) {
}
hostnames = strings.Split(s, ",")
for _, hostname := range hostnames {
if !r.verifier.MatchHostname(hostname) {
if !r.regex.MatchHostname(hostname) {
return nil, fmt.Errorf("hostname %q does not seem valid", hostname)
}
}
@@ -102,13 +102,13 @@ func (r *reader) GetDNSUnblockedHostnames() (hostnames []string, err error) {
// GetDNSOverTLSCaching obtains if Unbound caching should be enable or not
// from the environment variable DOT_CACHING.
func (r *reader) GetDNSOverTLSCaching() (caching bool, err error) {
return r.envParams.GetOnOff("DOT_CACHING", libparams.Default("on"))
return r.env.OnOff("DOT_CACHING", libparams.Default("on"))
}
// GetDNSOverTLSPrivateAddresses obtains if Unbound caching should be enable or not
// from the environment variable DOT_PRIVATE_ADDRESS.
func (r *reader) GetDNSOverTLSPrivateAddresses() (privateAddresses []string, err error) {
s, err := r.envParams.GetEnv("DOT_PRIVATE_ADDRESS")
s, err := r.env.Get("DOT_PRIVATE_ADDRESS")
if err != nil {
return nil, err
} else if len(s) == 0 {
@@ -128,13 +128,13 @@ func (r *reader) GetDNSOverTLSPrivateAddresses() (privateAddresses []string, err
// GetDNSOverTLSIPv6 obtains if Unbound should resolve ipv6 addresses using
// ipv6 DNS over TLS from the environment variable DOT_IPV6.
func (r *reader) GetDNSOverTLSIPv6() (ipv6 bool, err error) {
return r.envParams.GetOnOff("DOT_IPV6", libparams.Default("off"))
return r.env.OnOff("DOT_IPV6", libparams.Default("off"))
}
// GetDNSUpdatePeriod obtains the period to use to update the block lists and cryptographic files
// and restart Unbound from the environment variable DNS_UPDATE_PERIOD.
func (r *reader) GetDNSUpdatePeriod() (period time.Duration, err error) {
s, err := r.envParams.GetEnv("DNS_UPDATE_PERIOD", libparams.Default("24h"))
s, err := r.env.Get("DNS_UPDATE_PERIOD", libparams.Default("24h"))
if err != nil {
return period, err
}
@@ -144,7 +144,7 @@ func (r *reader) GetDNSUpdatePeriod() (period time.Duration, err error) {
// GetDNSPlaintext obtains the plaintext DNS address to use if DNS over TLS is disabled
// from the environment variable DNS_PLAINTEXT_ADDRESS.
func (r *reader) GetDNSPlaintext() (ip net.IP, err error) {
s, err := r.envParams.GetEnv("DNS_PLAINTEXT_ADDRESS", libparams.Default("1.1.1.1"))
s, err := r.env.Get("DNS_PLAINTEXT_ADDRESS", libparams.Default("1.1.1.1"))
if err != nil {
return nil, err
}
@@ -158,5 +158,5 @@ func (r *reader) GetDNSPlaintext() (ip net.IP, err error) {
// GetDNSKeepNameserver obtains if the nameserver present in /etc/resolv.conf
// should be kept instead of overridden, from the environment variable DNS_KEEP_NAMESERVER.
func (r *reader) GetDNSKeepNameserver() (on bool, err error) {
return r.envParams.GetOnOff("DNS_KEEP_NAMESERVER", libparams.Default("off"))
return r.env.OnOff("DNS_KEEP_NAMESERVER", libparams.Default("off"))
}

View File

@@ -10,13 +10,13 @@ import (
// GetFirewall obtains if the firewall should be enabled from the environment variable FIREWALL.
func (r *reader) GetFirewall() (enabled bool, err error) {
return r.envParams.GetOnOff("FIREWALL", libparams.Default("on"))
return r.env.OnOff("FIREWALL", libparams.Default("on"))
}
// GetAllowedVPNInputPorts obtains a list of input ports to allow from the
// VPN server side in the firewall, from the environment variable FIREWALL_VPN_INPUT_PORTS.
func (r *reader) GetVPNInputPorts() (ports []uint16, err error) {
s, err := r.envParams.GetEnv("FIREWALL_VPN_INPUT_PORTS", libparams.Default(""))
s, err := r.env.Get("FIREWALL_VPN_INPUT_PORTS", libparams.Default(""))
if err != nil {
return nil, err
}
@@ -40,7 +40,7 @@ func (r *reader) GetVPNInputPorts() (ports []uint16, err error) {
// GetInputPorts obtains a list of input ports to allow through the
// default interface in the firewall, from the environment variable FIREWALL_INPUT_PORTS.
func (r *reader) GetInputPorts() (ports []uint16, err error) {
s, err := r.envParams.GetEnv("FIREWALL_INPUT_PORTS", libparams.Default(""))
s, err := r.env.Get("FIREWALL_INPUT_PORTS", libparams.Default(""))
if err != nil {
return nil, err
}
@@ -64,5 +64,5 @@ func (r *reader) GetInputPorts() (ports []uint16, err error) {
// GetFirewallDebug obtains if the firewall should run in debug verbose mode
// from the environment variable FIREWALL_DEBUG.
func (r *reader) GetFirewallDebug() (debug bool, err error) {
return r.envParams.GetOnOff("FIREWALL_DEBUG", libparams.Default("off"))
return r.env.OnOff("FIREWALL_DEBUG", libparams.Default("off"))
}

View File

@@ -13,18 +13,18 @@ func (r *reader) GetHTTPProxy() (enabled bool, err error) {
[]string{"TINYPROXY", "PROXY"},
r.onRetroActive,
)
return r.envParams.GetOnOff("HTTPPROXY", retroKeysOption, libparams.Default("off"))
return r.env.OnOff("HTTPPROXY", retroKeysOption, libparams.Default("off"))
}
// GetHTTPProxyLog obtains the if http proxy requests should be logged from
// the environment variable HTTPPROXY_LOG, and using PROXY_LOG_LEVEL and
// TINYPROXY_LOG as retro-compatibility names.
func (r *reader) GetHTTPProxyLog() (log bool, err error) {
s, _ := r.envParams.GetEnv("HTTPPROXY_LOG")
s, _ := r.env.Get("HTTPPROXY_LOG")
if len(s) == 0 {
s, _ = r.envParams.GetEnv("PROXY_LOG_LEVEL")
s, _ = r.env.Get("PROXY_LOG_LEVEL")
if len(s) == 0 {
s, _ = r.envParams.GetEnv("TINYPROXY_LOG")
s, _ = r.env.Get("TINYPROXY_LOG")
if len(s) == 0 {
return false, nil // default log disabled
}
@@ -36,17 +36,17 @@ func (r *reader) GetHTTPProxyLog() (log bool, err error) {
return false, nil
}
}
return r.envParams.GetOnOff("HTTPPROXY_LOG", libparams.Default("off"))
return r.env.OnOff("HTTPPROXY_LOG", libparams.Default("off"))
}
// GetHTTPProxyPort obtains the HTTP proxy listening port from the environment variable
// HTTPPROXY_PORT, and using PROXY_PORT and TINYPROXY_PORT as retro-compatibility names.
func (r *reader) GetHTTPProxyPort() (port uint16, err error) {
func (r *reader) GetHTTPProxyPort() (port uint16, warning string, err error) {
retroKeysOption := libparams.RetroKeys(
[]string{"TINYPROXY_PORT", "PROXY_PORT"},
r.onRetroActive,
)
return r.envParams.GetPort("HTTPPROXY_PORT", retroKeysOption, libparams.Default("8888"))
return r.env.ListeningPort("HTTPPROXY_PORT", retroKeysOption, libparams.Default("8888"))
}
// GetHTTPProxyUser obtains the HTTP proxy server user.
@@ -76,5 +76,5 @@ func (r *reader) GetHTTPProxyPassword() (password string, err error) {
// GetHTTPProxyStealth obtains the HTTP proxy server stealth mode
// from the environment variable HTTPPROXY_STEALTH.
func (r *reader) GetHTTPProxyStealth() (stealth bool, err error) {
return r.envParams.GetOnOff("HTTPPROXY_STEALTH", libparams.Default("off"))
return r.env.OnOff("HTTPPROXY_STEALTH", libparams.Default("off"))
}

View File

@@ -8,30 +8,30 @@ import (
// GetMullvadCountries obtains the countries for the Mullvad servers from the
// environment variable COUNTRY.
func (r *reader) GetMullvadCountries() (countries []string, err error) {
return r.envParams.GetCSVInPossibilities("COUNTRY", constants.MullvadCountryChoices())
return r.env.CSVInside("COUNTRY", constants.MullvadCountryChoices())
}
// GetMullvadCity obtains the cities for the Mullvad servers from the
// environment variable CITY.
func (r *reader) GetMullvadCities() (cities []string, err error) {
return r.envParams.GetCSVInPossibilities("CITY", constants.MullvadCityChoices())
return r.env.CSVInside("CITY", constants.MullvadCityChoices())
}
// GetMullvadISPs obtains the ISPs for the Mullvad servers from the
// environment variable ISP.
func (r *reader) GetMullvadISPs() (isps []string, err error) {
return r.envParams.GetCSVInPossibilities("ISP", constants.MullvadISPChoices())
return r.env.CSVInside("ISP", constants.MullvadISPChoices())
}
// GetMullvadPort obtains the port to reach the Mullvad server on from the
// environment variable PORT.
func (r *reader) GetMullvadPort() (port uint16, err error) {
n, err := r.envParams.GetEnvIntRange("PORT", 0, 65535, libparams.Default("0"))
n, err := r.env.IntRange("PORT", 0, 65535, libparams.Default("0"))
return uint16(n), err
}
// GetMullvadOwned obtains if the server should be owned by Mullvad or not from the
// environment variable OWNED.
func (r *reader) GetMullvadOwned() (owned bool, err error) {
return r.envParams.GetYesNo("OWNED", libparams.Default("no"))
return r.env.YesNo("OWNED", libparams.Default("no"))
}

View File

@@ -10,7 +10,7 @@ import (
// GetNordvpnRegions obtains the regions (countries) for the NordVPN server from the
// environment variable REGION.
func (r *reader) GetNordvpnRegions() (regions []string, err error) {
return r.envParams.GetCSVInPossibilities("REGION", constants.NordvpnRegionChoices())
return r.env.CSVInside("REGION", constants.NordvpnRegionChoices())
}
// GetNordvpnRegion obtains the server numbers (optional) for the NordVPN servers from the
@@ -21,7 +21,7 @@ func (r *reader) GetNordvpnNumbers() (numbers []uint16, err error) {
possibilities[i] = fmt.Sprintf("%d", i)
}
possibilities[65536] = ""
values, err := r.envParams.GetCSVInPossibilities("SERVER_NUMBER", possibilities)
values, err := r.env.CSVInside("SERVER_NUMBER", possibilities)
if err != nil {
return nil, err
}

View File

@@ -27,26 +27,26 @@ func (r *reader) GetPassword() (s string, err error) {
// GetNetworkProtocol obtains the network protocol to use to connect to the
// VPN servers from the environment variable PROTOCOL.
func (r *reader) GetNetworkProtocol() (protocol models.NetworkProtocol, err error) {
s, err := r.envParams.GetValueIfInside("PROTOCOL", []string{"tcp", "udp"}, libparams.Default("udp"))
s, err := r.env.Inside("PROTOCOL", []string{"tcp", "udp"}, libparams.Default("udp"))
return models.NetworkProtocol(s), err
}
// GetOpenVPNVerbosity obtains the verbosity level for verbosity between 0 and 6
// from the environment variable OPENVPN_VERBOSITY.
func (r *reader) GetOpenVPNVerbosity() (verbosity int, err error) {
return r.envParams.GetEnvIntRange("OPENVPN_VERBOSITY", 0, 6, libparams.Default("1"))
return r.env.IntRange("OPENVPN_VERBOSITY", 0, 6, libparams.Default("1"))
}
// GetOpenVPNRoot obtains if openvpn should be run as root
// from the environment variable OPENVPN_ROOT.
func (r *reader) GetOpenVPNRoot() (root bool, err error) {
return r.envParams.GetYesNo("OPENVPN_ROOT", libparams.Default("no"))
return r.env.YesNo("OPENVPN_ROOT", libparams.Default("no"))
}
// GetTargetIP obtains the IP address to override over the list of IP addresses filtered
// from the environment variable OPENVPN_TARGET_IP.
func (r *reader) GetTargetIP() (ip net.IP, err error) {
s, err := r.envParams.GetEnv("OPENVPN_TARGET_IP")
s, err := r.env.Get("OPENVPN_TARGET_IP")
if len(s) == 0 {
return nil, nil
} else if err != nil {
@@ -62,17 +62,25 @@ func (r *reader) GetTargetIP() (ip net.IP, err error) {
// GetOpenVPNCipher obtains a custom cipher to use with OpenVPN
// from the environment variable OPENVPN_CIPHER.
func (r *reader) GetOpenVPNCipher() (cipher string, err error) {
return r.envParams.GetEnv("OPENVPN_CIPHER")
return r.env.Get("OPENVPN_CIPHER")
}
// GetOpenVPNAuth obtains a custom auth algorithm to use with OpenVPN
// from the environment variable OPENVPN_AUTH.
func (r *reader) GetOpenVPNAuth() (auth string, err error) {
return r.envParams.GetEnv("OPENVPN_AUTH")
return r.env.Get("OPENVPN_AUTH")
}
// GetOpenVPNIPv6 obtains if ipv6 should be tunneled through the
// openvpn tunnel from the environment variable OPENVPN_IPV6.
func (r *reader) GetOpenVPNIPv6() (ipv6 bool, err error) {
return r.envParams.GetOnOff("OPENVPN_IPV6", libparams.Default("off"))
return r.env.OnOff("OPENVPN_IPV6", libparams.Default("off"))
}
func (r *reader) GetOpenVPNMSSFix() (mssFix uint16, err error) {
n, err := r.env.IntRange("OPENVPN_MSSFIX", 0, 10000, libparams.Default("0"))
if err != nil {
return 0, err
}
return uint16(n), nil
}

View File

@@ -55,6 +55,7 @@ type Reader interface {
GetOpenVPNCipher() (cipher string, err error)
GetOpenVPNAuth() (auth string, err error)
GetOpenVPNIPv6() (tunnel bool, err error)
GetOpenVPNMSSFix() (mssFix uint16, err error)
// PIA getters
GetPortForwarding() (activated bool, err error)
@@ -102,14 +103,14 @@ type Reader interface {
// Shadowsocks getters
GetShadowSocks() (activated bool, err error)
GetShadowSocksLog() (activated bool, err error)
GetShadowSocksPort() (port uint16, err error)
GetShadowSocksPort() (port uint16, warning string, err error)
GetShadowSocksPassword() (password string, err error)
GetShadowSocksMethod() (method string, err error)
// HTTP proxy getters
GetHTTPProxy() (activated bool, err error)
GetHTTPProxyLog() (log bool, err error)
GetHTTPProxyPort() (port uint16, err error)
GetHTTPProxyPort() (port uint16, warning string, err error)
GetHTTPProxyUser() (user string, err error)
GetHTTPProxyPassword() (password string, err error)
GetHTTPProxyStealth() (stealth bool, err error)
@@ -118,7 +119,7 @@ type Reader interface {
GetPublicIPPeriod() (period time.Duration, err error)
// Control server
GetControlServerPort() (port uint16, err error)
GetControlServerPort() (port uint16, warning string, err error)
GetControlServerLog() (enabled bool, err error)
GetVersionInformation() (enabled bool, err error)
@@ -127,26 +128,26 @@ type Reader interface {
}
type reader struct {
envParams libparams.EnvParams
logger logging.Logger
verifier verification.Verifier
os os.OS
env libparams.Env
logger logging.Logger
regex verification.Regex
os os.OS
}
// Newreader returns a paramsReadeer object to read parameters from
// environment variables.
func NewReader(logger logging.Logger, os os.OS) Reader {
return &reader{
envParams: libparams.NewEnvParams(),
logger: logger,
verifier: verification.NewVerifier(),
os: os,
env: libparams.NewEnv(),
logger: logger,
regex: verification.NewRegex(),
os: os,
}
}
// GetVPNSP obtains the VPN service provider to use from the environment variable VPNSP.
func (r *reader) GetVPNSP() (vpnServiceProvider models.VPNProvider, err error) {
s, err := r.envParams.GetValueIfInside(
s, err := r.env.Inside(
"VPNSP",
[]string{
"pia", "private internet access",
@@ -160,7 +161,7 @@ func (r *reader) GetVPNSP() (vpnServiceProvider models.VPNProvider, err error) {
}
func (r *reader) GetVersionInformation() (enabled bool, err error) {
return r.envParams.GetOnOff("VERSION_INFORMATION", libparams.Default("on"))
return r.env.OnOff("VERSION_INFORMATION", libparams.Default("on"))
}
func (r *reader) onRetroActive(oldKey, newKey string) {

View File

@@ -12,7 +12,7 @@ import (
// side is enabled or not from the environment variable PORT_FORWARDING
// Only valid for older PIA servers for now.
func (r *reader) GetPortForwarding() (activated bool, err error) {
s, err := r.envParams.GetEnv("PORT_FORWARDING", libparams.Default("off"))
s, err := r.env.Get("PORT_FORWARDING", libparams.Default("off"))
if err != nil {
return false, err
}
@@ -28,7 +28,7 @@ func (r *reader) GetPortForwarding() (activated bool, err error) {
// GetPortForwardingStatusFilepath obtains the port forwarding status file path
// from the environment variable PORT_FORWARDING_STATUS_FILE.
func (r *reader) GetPortForwardingStatusFilepath() (filepath models.Filepath, err error) {
filepathStr, err := r.envParams.GetPath(
filepathStr, err := r.env.Path(
"PORT_FORWARDING_STATUS_FILE",
libparams.Default("/tmp/gluetun/forwarded_port"),
libparams.CaseSensitiveValue())
@@ -40,7 +40,7 @@ func (r *reader) GetPortForwardingStatusFilepath() (filepath models.Filepath, er
// retro compatibility.
func (r *reader) GetPIAEncryptionPreset() (preset string, err error) {
// Retro-compatibility
s, err := r.envParams.GetValueIfInside("ENCRYPTION", []string{
s, err := r.env.Inside("ENCRYPTION", []string{
constants.PIAEncryptionPresetNormal,
constants.PIAEncryptionPresetStrong})
if err != nil {
@@ -49,7 +49,7 @@ func (r *reader) GetPIAEncryptionPreset() (preset string, err error) {
r.logger.Warn("You are using the old environment variable ENCRYPTION, please consider changing it to PIA_ENCRYPTION")
return s, nil
}
return r.envParams.GetValueIfInside(
return r.env.Inside(
"PIA_ENCRYPTION",
[]string{
constants.PIAEncryptionPresetNormal,
@@ -61,5 +61,5 @@ func (r *reader) GetPIAEncryptionPreset() (preset string, err error) {
// GetPIARegions obtains the regions for the PIA servers from the
// environment variable REGION.
func (r *reader) GetPIARegions() (regions []string, err error) {
return r.envParams.GetCSVInPossibilities("REGION", constants.PIAGeoChoices())
return r.env.CSVInside("REGION", constants.PIAGeoChoices())
}

View File

@@ -8,7 +8,7 @@ import (
// GetPrivadoHostnames obtains the hostnames for the Privado server from the
// environment variable SERVER_HOSTNAME.
func (r *reader) GetPrivadoHostnames() (hosts []string, err error) {
return r.envParams.GetCSVInPossibilities("SERVER_HOSTNAME",
return r.env.CSVInside("SERVER_HOSTNAME",
constants.PrivadoHostnameChoices(),
libparams.RetroKeys([]string{"HOSTNAME"}, r.onRetroActive))
}

View File

@@ -10,7 +10,7 @@ import (
// GetPublicIPPeriod obtains the period to fetch the IP address periodically.
// Set to 0 to disable.
func (r *reader) GetPublicIPPeriod() (period time.Duration, err error) {
s, err := r.envParams.GetEnv("PUBLICIP_PERIOD", libparams.Default("12h"))
s, err := r.env.Get("PUBLICIP_PERIOD", libparams.Default("12h"))
if err != nil {
return 0, err
}
@@ -21,7 +21,7 @@ func (r *reader) GetPublicIPPeriod() (period time.Duration, err error) {
// from the environment variable PUBLICIP_FILE with retro-compatible
// environment variable IP_STATUS_FILE.
func (r *reader) GetPublicIPFilepath() (filepath models.Filepath, err error) {
filepathStr, err := r.envParams.GetPath("PUBLICIP_FILE",
filepathStr, err := r.env.Path("PUBLICIP_FILE",
libparams.RetroKeys([]string{"IP_STATUS_FILE"}, r.onRetroActive),
libparams.Default("/tmp/gluetun/ip"), libparams.CaseSensitiveValue())
return models.Filepath(filepathStr), err

View File

@@ -7,17 +7,17 @@ import (
// GetPurevpnRegions obtains the regions (continents) for the PureVPN servers from the
// environment variable REGION.
func (r *reader) GetPurevpnRegions() (regions []string, err error) {
return r.envParams.GetCSVInPossibilities("REGION", constants.PurevpnRegionChoices())
return r.env.CSVInside("REGION", constants.PurevpnRegionChoices())
}
// GetPurevpnCountries obtains the countries for the PureVPN servers from the
// environment variable COUNTRY.
func (r *reader) GetPurevpnCountries() (countries []string, err error) {
return r.envParams.GetCSVInPossibilities("COUNTRY", constants.PurevpnCountryChoices())
return r.env.CSVInside("COUNTRY", constants.PurevpnCountryChoices())
}
// GetPurevpnCities obtains the cities for the PureVPN servers from the
// environment variable CITY.
func (r *reader) GetPurevpnCities() (cities []string, err error) {
return r.envParams.GetCSVInPossibilities("CITY", constants.PurevpnCityChoices())
return r.env.CSVInside("CITY", constants.PurevpnCityChoices())
}

View File

@@ -16,7 +16,7 @@ func (r *reader) GetOutboundSubnets() (outboundSubnets []net.IPNet, err error) {
[]string{"EXTRA_SUBNETS"},
r.onRetroActive,
)
s, err := r.envParams.GetEnv(key, retroOption)
s, err := r.env.Get(key, retroOption)
if err != nil {
return nil, err
} else if s == "" {

View File

@@ -19,19 +19,19 @@ var (
)
func (r *reader) getFromEnvOrSecretFile(envKey string, compulsory bool, retroKeys []string) (value string, err error) {
envOptions := []libparams.GetEnvSetter{
envOptions := []libparams.OptionSetter{
libparams.Compulsory(), // to fallback on file reading
libparams.CaseSensitiveValue(),
libparams.Unset(),
libparams.RetroKeys(retroKeys, r.onRetroActive),
}
value, envErr := r.envParams.GetEnv(envKey, envOptions...)
value, envErr := r.env.Get(envKey, envOptions...)
if envErr == nil {
return value, nil
}
defaultSecretFile := "/run/secrets/" + strings.ToLower(envKey)
filepath, err := r.envParams.GetEnv(envKey+"_SECRETFILE",
filepath, err := r.env.Get(envKey+"_SECRETFILE",
libparams.CaseSensitiveValue(),
libparams.Default(defaultSecretFile),
)
@@ -67,7 +67,7 @@ func (r *reader) getFromEnvOrSecretFile(envKey string, compulsory bool, retroKey
func (r *reader) getFromFileOrSecretFile(secretName, filepath string) (
b []byte, err error) {
defaultSecretFile := "/run/secrets/" + strings.ToLower(secretName)
secretFilepath, err := r.envParams.GetEnv(strings.ToUpper(secretName)+"_SECRETFILE",
secretFilepath, err := r.env.Get(strings.ToUpper(secretName)+"_SECRETFILE",
libparams.CaseSensitiveValue(),
libparams.Default(defaultSecretFile),
)

View File

@@ -4,14 +4,10 @@ import (
libparams "github.com/qdm12/golibs/params"
)
func (r *reader) GetControlServerPort() (port uint16, err error) {
n, err := r.envParams.GetEnvIntRange("HTTP_CONTROL_SERVER_PORT", 1, 65535, libparams.Default("8000"))
if err != nil {
return 0, err
}
return uint16(n), nil
func (r *reader) GetControlServerPort() (port uint16, warning string, err error) {
return r.env.ListeningPort("HTTP_CONTROL_SERVER_PORT", libparams.Default("8000"))
}
func (r *reader) GetControlServerLog() (enabled bool, err error) {
return r.envParams.GetOnOff("HTTP_CONTROL_SERVER_LOG", libparams.Default("on"))
return r.env.OnOff("HTTP_CONTROL_SERVER_LOG", libparams.Default("on"))
}

View File

@@ -1,35 +1,25 @@
package params
import (
"strconv"
libparams "github.com/qdm12/golibs/params"
)
// GetShadowSocks obtains if ShadowSocks is on from the environment variable
// SHADOWSOCKS.
func (r *reader) GetShadowSocks() (activated bool, err error) {
return r.envParams.GetOnOff("SHADOWSOCKS", libparams.Default("off"))
return r.env.OnOff("SHADOWSOCKS", libparams.Default("off"))
}
// GetShadowSocksLog obtains the ShadowSocks log level from the environment variable
// SHADOWSOCKS_LOG.
func (r *reader) GetShadowSocksLog() (activated bool, err error) {
return r.envParams.GetOnOff("SHADOWSOCKS_LOG", libparams.Default("off"))
return r.env.OnOff("SHADOWSOCKS_LOG", libparams.Default("off"))
}
// GetShadowSocksPort obtains the ShadowSocks listening port from the environment variable
// SHADOWSOCKS_PORT.
func (r *reader) GetShadowSocksPort() (port uint16, err error) {
portStr, err := r.envParams.GetEnv("SHADOWSOCKS_PORT", libparams.Default("8388"))
if err != nil {
return 0, err
}
if err := r.verifier.VerifyPort(portStr); err != nil {
return 0, err
}
portUint64, err := strconv.ParseUint(portStr, 10, 16)
return uint16(portUint64), err
func (r *reader) GetShadowSocksPort() (port uint16, warning string, err error) {
return r.env.ListeningPort("SHADOWSOCKS_PORT", libparams.Default("8388"))
}
// GetShadowSocksPassword obtains the ShadowSocks server password.
@@ -43,5 +33,5 @@ func (r *reader) GetShadowSocksPassword() (password string, err error) {
// GetShadowSocksMethod obtains the ShadowSocks method to use from the environment variable
// SHADOWSOCKS_METHOD.
func (r *reader) GetShadowSocksMethod() (method string, err error) {
return r.envParams.GetEnv("SHADOWSOCKS_METHOD", libparams.Default("chacha20-ietf-poly1305"))
return r.env.Get("SHADOWSOCKS_METHOD", libparams.Default("chacha20-ietf-poly1305"))
}

View File

@@ -7,5 +7,5 @@ import (
// GetSurfsharkRegions obtains the regions for the Surfshark servers from the
// environment variable REGION.
func (r *reader) GetSurfsharkRegions() (regions []string, err error) {
return r.envParams.GetCSVInPossibilities("REGION", constants.SurfsharkRegionChoices())
return r.env.CSVInside("REGION", constants.SurfsharkRegionChoices())
}

View File

@@ -7,7 +7,7 @@ import (
// GetPUID obtains the user ID to use from the environment variable PUID
// with retro compatible variable UID.
func (r *reader) GetPUID() (ppuid int, err error) {
return r.envParams.GetEnvIntRange("PUID", 0, 65535,
return r.env.IntRange("PUID", 0, 65535,
libparams.Default("1000"),
libparams.RetroKeys([]string{"UID"}, r.onRetroActive))
}
@@ -15,12 +15,12 @@ func (r *reader) GetPUID() (ppuid int, err error) {
// GetGID obtains the group ID to use from the environment variable PGID
// with retro compatible variable PGID.
func (r *reader) GetPGID() (pgid int, err error) {
return r.envParams.GetEnvIntRange("PGID", 0, 65535,
return r.env.IntRange("PGID", 0, 65535,
libparams.Default("1000"),
libparams.RetroKeys([]string{"GID"}, r.onRetroActive))
}
// GetTZ obtains the timezone from the environment variable TZ.
func (r *reader) GetTimezone() (timezone string, err error) {
return r.envParams.GetEnv("TZ")
return r.env.Get("TZ")
}

View File

@@ -9,7 +9,7 @@ import (
// GetUpdaterPeriod obtains the period to fetch the servers information when the tunnel is up.
// Set to 0 to disable.
func (r *reader) GetUpdaterPeriod() (period time.Duration, err error) {
s, err := r.envParams.GetEnv("UPDATER_PERIOD", libparams.Default("0"))
s, err := r.env.Get("UPDATER_PERIOD", libparams.Default("0"))
if err != nil {
return 0, err
}

View File

@@ -7,5 +7,5 @@ import (
// GetVyprvpnRegions obtains the regions for the Vyprvpn servers from the
// environment variable REGION.
func (r *reader) GetVyprvpnRegions() (regions []string, err error) {
return r.envParams.GetCSVInPossibilities("REGION", constants.VyprvpnRegionChoices())
return r.env.CSVInside("REGION", constants.VyprvpnRegionChoices())
}

View File

@@ -11,19 +11,19 @@ import (
// GetWindscribeRegions obtains the regions for the Windscribe servers from the
// environment variable REGION.
func (r *reader) GetWindscribeRegions() (regions []string, err error) {
return r.envParams.GetCSVInPossibilities("REGION", constants.WindscribeRegionChoices())
return r.env.CSVInside("REGION", constants.WindscribeRegionChoices())
}
// GetWindscribeCities obtains the cities for the Windscribe servers from the
// environment variable CITY.
func (r *reader) GetWindscribeCities() (cities []string, err error) {
return r.envParams.GetCSVInPossibilities("CITY", constants.WindscribeCityChoices())
return r.env.CSVInside("CITY", constants.WindscribeCityChoices())
}
// GetWindscribeHostnames obtains the hostnames for the Windscribe servers from the
// environment variable SERVER_HOSTNAME.
func (r *reader) GetWindscribeHostnames() (hostnames []string, err error) {
return r.envParams.GetCSVInPossibilities("SERVER_HOSTNAME",
return r.env.CSVInside("SERVER_HOSTNAME",
constants.WindscribeHostnameChoices(),
libparams.RetroKeys([]string{"HOSTNAME"}, r.onRetroActive),
)
@@ -33,7 +33,7 @@ func (r *reader) GetWindscribeHostnames() (hostnames []string, err error) {
// environment variable PORT.
//nolint:gomnd
func (r *reader) GetWindscribePort(protocol models.NetworkProtocol) (port uint16, err error) {
n, err := r.envParams.GetEnvIntRange("PORT", 0, 65535, libparams.Default("0"))
n, err := r.env.IntRange("PORT", 0, 65535, libparams.Default("0"))
if err != nil {
return 0, err
}

View File

@@ -6,11 +6,13 @@ import (
"math/rand"
"net"
"net/http"
"strconv"
"strings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -62,13 +64,13 @@ func (c *cyberghost) GetOpenVPNConnection(selection models.ServerSelection) (
return pickRandomConnection(connections, c.randSource), nil
}
func (c *cyberghost) BuildConf(connection models.OpenVPNConnection, verbosity int,
username string, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
func (c *cyberghost) BuildConf(connection models.OpenVPNConnection,
username string, settings settings.OpenVPN) (lines []string) {
if len(settings.Cipher) == 0 {
settings.Cipher = aes256cbc
}
if len(auth) == 0 {
auth = sha256
if len(settings.Auth) == 0 {
settings.Auth = sha256
}
lines = []string{
"client",
@@ -77,11 +79,14 @@ func (c *cyberghost) BuildConf(connection models.OpenVPNConnection, verbosity in
"persist-key",
"persist-tun",
"remote-cert-tls server",
"ping 10",
"ping-exit 60",
"ping-timer-rem",
"tls-exit",
// Cyberghost specific
// "redirect-gateway def1",
"ncp-disable",
"ping 5",
"explicit-exit-notify 2",
"script-security 2",
"route-delay 5",
@@ -94,19 +99,22 @@ func (c *cyberghost) BuildConf(connection models.OpenVPNConnection, verbosity in
"suppress-timestamps",
// Modified variables
fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("verb %d", settings.Verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", connection.Protocol),
fmt.Sprintf("remote %s %d", connection.IP, connection.Port),
fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("auth %s", auth),
fmt.Sprintf("cipher %s", settings.Cipher),
fmt.Sprintf("auth %s", settings.Auth),
}
if strings.HasSuffix(cipher, "-gcm") {
if strings.HasSuffix(settings.Cipher, "-gcm") {
lines = append(lines, "ncp-ciphers AES-256-GCM:AES-256-CBC:AES-128-GCM")
}
if !root {
if !settings.Root {
lines = append(lines, "user "+username)
}
if settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
}
lines = append(lines, []string{
"<ca>",
"-----BEGIN CERTIFICATE-----",
@@ -117,14 +125,14 @@ func (c *cyberghost) BuildConf(connection models.OpenVPNConnection, verbosity in
lines = append(lines, []string{
"<cert>",
"-----BEGIN CERTIFICATE-----",
extras.ClientCertificate,
settings.Provider.ExtraConfigOptions.ClientCertificate,
"-----END CERTIFICATE-----",
"</cert>",
}...)
lines = append(lines, []string{
"<key>",
"-----BEGIN PRIVATE KEY-----",
extras.ClientKey,
settings.Provider.ExtraConfigOptions.ClientKey,
"-----END PRIVATE KEY-----",
"</key>",
"",

View File

@@ -6,10 +6,12 @@ import (
"math/rand"
"net"
"net/http"
"strconv"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -73,9 +75,9 @@ func (m *mullvad) GetOpenVPNConnection(selection models.ServerSelection) (
}
func (m *mullvad) BuildConf(connection models.OpenVPNConnection,
verbosity int, username string, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
username string, settings settings.OpenVPN) (lines []string) {
if len(settings.Cipher) == 0 {
settings.Cipher = aes256cbc
}
lines = []string{
"client",
@@ -83,10 +85,12 @@ func (m *mullvad) BuildConf(connection models.OpenVPNConnection,
"nobind",
"persist-key",
"remote-cert-tls server",
"ping 10",
"ping-exit 60",
"ping-timer-rem",
"tls-exit",
// Mullvad specific
"ping 10",
"ping-restart 60",
"sndbuf 524288",
"rcvbuf 524288",
"tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
@@ -101,21 +105,24 @@ func (m *mullvad) BuildConf(connection models.OpenVPNConnection,
"suppress-timestamps",
// Modified variables
fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("verb %d", settings.Verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", connection.Protocol),
fmt.Sprintf("remote %s %d", connection.IP, connection.Port),
fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("cipher %s", settings.Cipher),
}
if extras.OpenVPNIPv6 {
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
lines = append(lines, "tun-ipv6")
} else {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
if !root {
if !settings.Root {
lines = append(lines, "user "+username)
}
if settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
}
lines = append(lines, []string{
"<ca>",
"-----BEGIN CERTIFICATE-----",

View File

@@ -6,10 +6,12 @@ import (
"math/rand"
"net"
"net/http"
"strconv"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -78,13 +80,18 @@ func (n *nordvpn) GetOpenVPNConnection(selection models.ServerSelection) (
return pickRandomConnection(connections, n.randSource), nil
}
func (n *nordvpn) BuildConf(connection models.OpenVPNConnection, verbosity int, username string, root bool,
cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
func (n *nordvpn) BuildConf(connection models.OpenVPNConnection,
username string, settings settings.OpenVPN) (lines []string) {
if len(settings.Cipher) == 0 {
settings.Cipher = aes256cbc
}
if len(auth) == 0 {
auth = "sha512"
if len(settings.Auth) == 0 {
settings.Auth = "sha512"
}
const defaultMSSFix = 1450
if settings.MSSFix == 0 {
settings.MSSFix = defaultMSSFix
}
lines = []string{
"client",
@@ -92,14 +99,15 @@ func (n *nordvpn) BuildConf(connection models.OpenVPNConnection, verbosity int,
"nobind",
"persist-key",
"remote-cert-tls server",
"ping 10",
"ping-exit 60",
"ping-timer-rem",
"tls-exit",
// Nordvpn specific
"tun-mtu 1500",
"tun-mtu-extra 32",
"mssfix 1450",
"ping 15",
"ping-restart 0",
"ping-timer-rem",
"mssfix " + strconv.Itoa(int(settings.MSSFix)),
"reneg-sec 0",
"comp-lzo no",
"fast-io",
@@ -113,14 +121,14 @@ func (n *nordvpn) BuildConf(connection models.OpenVPNConnection, verbosity int,
"suppress-timestamps",
// Modified variables
fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("verb %d", settings.Verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", connection.Protocol),
fmt.Sprintf("remote %s %d", connection.IP.String(), connection.Port),
fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("auth %s", auth),
fmt.Sprintf("cipher %s", settings.Cipher),
fmt.Sprintf("auth %s", settings.Auth),
}
if !root {
if !settings.Root {
lines = append(lines, "user "+username)
}
lines = append(lines, []string{

View File

@@ -12,6 +12,7 @@ import (
"net"
"net/http"
"net/url"
"strconv"
"strings"
"time"
@@ -19,6 +20,7 @@ import (
"github.com/qdm12/gluetun/internal/firewall"
gluetunLog "github.com/qdm12/gluetun/internal/logging"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -109,11 +111,11 @@ func (p *pia) GetOpenVPNConnection(selection models.ServerSelection) (
return connection, nil
}
func (p *pia) BuildConf(connection models.OpenVPNConnection, verbosity int, username string, root bool,
cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
func (p *pia) BuildConf(connection models.OpenVPNConnection,
username string, settings settings.OpenVPN) (lines []string) {
var X509CRL, certificate string
var defaultCipher, defaultAuth string
if extras.EncryptionPreset == constants.PIAEncryptionPresetNormal {
if settings.Provider.ExtraConfigOptions.EncryptionPreset == constants.PIAEncryptionPresetNormal {
defaultCipher = "aes-128-cbc"
defaultAuth = "sha1"
X509CRL = constants.PiaX509CRLNormal
@@ -124,11 +126,11 @@ func (p *pia) BuildConf(connection models.OpenVPNConnection, verbosity int, user
X509CRL = constants.PiaX509CRLStrong
certificate = constants.PIACertificateStrong
}
if len(cipher) == 0 {
cipher = defaultCipher
if len(settings.Cipher) == 0 {
settings.Cipher = defaultCipher
}
if len(auth) == 0 {
auth = defaultAuth
if len(settings.Auth) == 0 {
settings.Auth = defaultAuth
}
lines = []string{
"client",
@@ -136,9 +138,12 @@ func (p *pia) BuildConf(connection models.OpenVPNConnection, verbosity int, user
"nobind",
"persist-key",
"remote-cert-tls server",
"ping 10",
"ping-exit 60",
"ping-timer-rem",
"tls-exit",
// PIA specific
"ping 300", // Ping every 5 minutes to prevent a timeout error
"reneg-sec 0",
"compress", // allow PIA server to choose the compression to use
@@ -150,19 +155,22 @@ func (p *pia) BuildConf(connection models.OpenVPNConnection, verbosity int, user
"suppress-timestamps",
// Modified variables
fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("verb %d", settings.Verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", connection.Protocol),
fmt.Sprintf("remote %s %d", connection.IP, connection.Port),
fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("auth %s", auth),
fmt.Sprintf("cipher %s", settings.Cipher),
fmt.Sprintf("auth %s", settings.Auth),
}
if strings.HasSuffix(cipher, "-gcm") {
if strings.HasSuffix(settings.Cipher, "-gcm") {
lines = append(lines, "ncp-disable")
}
if !root {
if !settings.Root {
lines = append(lines, "user "+username)
}
if settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
}
lines = append(lines, []string{
"<crl-verify>",
"-----BEGIN X509 CRL-----",

View File

@@ -6,10 +6,12 @@ import (
"math/rand"
"net"
"net/http"
"strconv"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -70,19 +72,23 @@ func (s *privado) GetOpenVPNConnection(selection models.ServerSelection) (
return pickRandomConnection(connections, s.randSource), nil
}
func (s *privado) BuildConf(connection models.OpenVPNConnection, verbosity int, username string, root bool,
cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
func (s *privado) BuildConf(connection models.OpenVPNConnection,
username string, settings settings.OpenVPN) (lines []string) {
if len(settings.Cipher) == 0 {
settings.Cipher = aes256cbc
}
if len(auth) == 0 {
auth = sha256
if len(settings.Auth) == 0 {
settings.Auth = sha256
}
lines = []string{
"client",
"dev tun",
"nobind",
"persist-key",
"ping 10",
"ping-exit 60",
"ping-timer-rem",
"tls-exit",
// Privado specific
"tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
@@ -96,16 +102,19 @@ func (s *privado) BuildConf(connection models.OpenVPNConnection, verbosity int,
"suppress-timestamps",
// Modified variables
fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("verb %d", settings.Verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", connection.Protocol),
fmt.Sprintf("remote %s %d", connection.IP, connection.Port),
fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("auth %s", auth),
fmt.Sprintf("cipher %s", settings.Cipher),
fmt.Sprintf("auth %s", settings.Auth),
}
if !root {
if !settings.Root {
lines = append(lines, "user "+username)
}
if settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
}
lines = append(lines, []string{
"<ca>",
"-----BEGIN CERTIFICATE-----",

View File

@@ -8,6 +8,7 @@ import (
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -15,8 +16,7 @@ import (
// Provider contains methods to read and modify the openvpn configuration to connect as a client.
type Provider interface {
GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error)
BuildConf(connection models.OpenVPNConnection, verbosity int, username string,
root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string)
BuildConf(connection models.OpenVPNConnection, username string, settings settings.OpenVPN) (lines []string)
PortForward(ctx context.Context, client *http.Client,
openFile os.OpenFileFunc, pfLogger logging.Logger, gateway net.IP, fw firewall.Configurator,
syncState func(port uint16) (pfFilepath models.Filepath))

View File

@@ -6,10 +6,12 @@ import (
"math/rand"
"net"
"net/http"
"strconv"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -72,10 +74,10 @@ func (p *purevpn) GetOpenVPNConnection(selection models.ServerSelection) (
return pickRandomConnection(connections, p.randSource), nil
}
func (p *purevpn) BuildConf(connection models.OpenVPNConnection, verbosity int, username string, root bool,
cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
func (p *purevpn) BuildConf(connection models.OpenVPNConnection,
username string, settings settings.OpenVPN) (lines []string) {
if len(settings.Cipher) == 0 {
settings.Cipher = aes256cbc
}
lines = []string{
"client",
@@ -83,6 +85,10 @@ func (p *purevpn) BuildConf(connection models.OpenVPNConnection, verbosity int,
"nobind",
"persist-key",
"remote-cert-tls server",
"ping 10",
"ping-exit 60",
"ping-timer-rem",
"tls-exit",
// Purevpn specific
"key-direction 1",
@@ -101,15 +107,18 @@ func (p *purevpn) BuildConf(connection models.OpenVPNConnection, verbosity int,
"suppress-timestamps",
// Modified variables
fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("verb %d", settings.Verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", connection.Protocol),
fmt.Sprintf("remote %s %d", connection.IP.String(), connection.Port),
fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("cipher %s", settings.Cipher),
}
if !root {
if !settings.Root {
lines = append(lines, "user "+username)
}
if settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
}
lines = append(lines, []string{
"<ca>",
"-----BEGIN CERTIFICATE-----",
@@ -140,8 +149,8 @@ func (p *purevpn) BuildConf(connection models.OpenVPNConnection, verbosity int,
"</tls-auth>",
"",
}...)
if len(auth) > 0 {
lines = append(lines, "auth "+auth)
if len(settings.Auth) > 0 {
lines = append(lines, "auth "+settings.Auth)
}
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")

View File

@@ -6,10 +6,12 @@ import (
"math/rand"
"net"
"net/http"
"strconv"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -73,28 +75,35 @@ func (s *surfshark) GetOpenVPNConnection(selection models.ServerSelection) (
return pickRandomConnection(connections, s.randSource), nil
}
func (s *surfshark) BuildConf(connection models.OpenVPNConnection, verbosity int, username string, root bool,
cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
func (s *surfshark) BuildConf(connection models.OpenVPNConnection,
username string, settings settings.OpenVPN) (lines []string) {
if len(settings.Cipher) == 0 {
settings.Cipher = aes256cbc
}
if len(auth) == 0 {
auth = "SHA512"
if len(settings.Auth) == 0 {
settings.Auth = "SHA512"
}
const defaultMSSFix = 1450
if settings.MSSFix == 0 {
settings.MSSFix = defaultMSSFix
}
lines = []string{
"client",
"dev tun",
"nobind",
"persist-key",
"remote-cert-tls server",
"ping 10",
"ping-exit 60",
"ping-timer-rem",
"tls-exit",
// Surfshark specific
"tun-mtu 1500",
"tun-mtu-extra 32",
"mssfix 1450",
"ping 15",
"ping-restart 60",
"ping-timer-rem",
"mssfix " + strconv.Itoa(int(settings.MSSFix)),
"reneg-sec 0",
"fast-io",
"key-direction 1",
@@ -109,14 +118,14 @@ func (s *surfshark) BuildConf(connection models.OpenVPNConnection, verbosity int
"suppress-timestamps",
// Modified variables
fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("verb %d", settings.Verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", connection.Protocol),
fmt.Sprintf("remote %s %d", connection.IP, connection.Port),
fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("auth %s", auth),
fmt.Sprintf("cipher %s", settings.Cipher),
fmt.Sprintf("auth %s", settings.Auth),
}
if !root {
if !settings.Root {
lines = append(lines, "user "+username)
}
lines = append(lines, []string{

View File

@@ -0,0 +1,54 @@
package provider
import (
"math/rand"
"testing"
"github.com/qdm12/gluetun/internal/models"
"github.com/stretchr/testify/assert"
)
func Test_pickRandomConnection(t *testing.T) {
t.Parallel()
connections := []models.OpenVPNConnection{
{Port: 1}, {Port: 2}, {Port: 3}, {Port: 4},
}
source := rand.NewSource(0)
connection := pickRandomConnection(connections, source)
assert.Equal(t, models.OpenVPNConnection{Port: 3}, connection)
connection = pickRandomConnection(connections, source)
assert.Equal(t, models.OpenVPNConnection{Port: 3}, connection)
connection = pickRandomConnection(connections, source)
assert.Equal(t, models.OpenVPNConnection{Port: 2}, connection)
}
func Test_filterByPossibilities(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
value string
possibilities []string
filtered bool
}{
"no possibilities": {},
"value not in possibilities": {
value: "c",
possibilities: []string{"a", "b"},
filtered: true,
},
"value in possibilities": {
value: "c",
possibilities: []string{"a", "b", "c"},
},
}
for name, testCase := range testCases {
testCase := testCase
t.Run(name, func(t *testing.T) {
filtered := filterByPossibilities(testCase.value, testCase.possibilities)
assert.Equal(t, testCase.filtered, filtered)
})
}
}

View File

@@ -6,10 +6,12 @@ import (
"math/rand"
"net"
"net/http"
"strconv"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -69,13 +71,13 @@ func (v *vyprvpn) GetOpenVPNConnection(selection models.ServerSelection) (
return pickRandomConnection(connections, v.randSource), nil
}
func (v *vyprvpn) BuildConf(connection models.OpenVPNConnection, verbosity int, username string,
root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
func (v *vyprvpn) BuildConf(connection models.OpenVPNConnection,
username string, settings settings.OpenVPN) (lines []string) {
if len(settings.Cipher) == 0 {
settings.Cipher = aes256cbc
}
if len(auth) == 0 {
auth = "SHA256"
if len(settings.Auth) == 0 {
settings.Auth = "SHA256"
}
lines = []string{
"client",
@@ -83,10 +85,13 @@ func (v *vyprvpn) BuildConf(connection models.OpenVPNConnection, verbosity int,
"nobind",
"persist-key",
"remote-cert-tls server",
"ping 10",
"ping-exit 60",
"ping-timer-rem",
"tls-exit",
// Vyprvpn specific
"comp-lzo",
"keepalive 10 60",
// "verify-x509-name lu1.vyprvpn.com name",
"tls-cipher 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
@@ -98,16 +103,19 @@ func (v *vyprvpn) BuildConf(connection models.OpenVPNConnection, verbosity int,
"suppress-timestamps",
// Modified variables
fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("verb %d", settings.Verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", connection.Protocol),
fmt.Sprintf("remote %s %d", connection.IP, connection.Port),
fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("auth %s", auth),
fmt.Sprintf("cipher %s", settings.Cipher),
fmt.Sprintf("auth %s", settings.Auth),
}
if !root {
if !settings.Root {
lines = append(lines, "user "+username)
}
if settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
}
lines = append(lines, []string{
"<ca>",
"-----BEGIN CERTIFICATE-----",

View File

@@ -6,11 +6,13 @@ import (
"math/rand"
"net"
"net/http"
"strconv"
"strings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/os"
)
@@ -72,13 +74,13 @@ func (w *windscribe) GetOpenVPNConnection(selection models.ServerSelection) (con
return pickRandomConnection(connections, w.randSource), nil
}
func (w *windscribe) BuildConf(connection models.OpenVPNConnection, verbosity int, username string,
root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
func (w *windscribe) BuildConf(connection models.OpenVPNConnection,
username string, settings settings.OpenVPN) (lines []string) {
if len(settings.Cipher) == 0 {
settings.Cipher = aes256cbc
}
if len(auth) == 0 {
auth = "sha512"
if len(settings.Auth) == 0 {
settings.Auth = "sha512"
}
lines = []string{
"client",
@@ -86,6 +88,10 @@ func (w *windscribe) BuildConf(connection models.OpenVPNConnection, verbosity in
"nobind",
"persist-key",
"remote-cert-tls server",
"ping 10",
"ping-exit 60",
"ping-timer-rem",
"tls-exit",
// Windscribe specific
"comp-lzo",
@@ -100,19 +106,22 @@ func (w *windscribe) BuildConf(connection models.OpenVPNConnection, verbosity in
"suppress-timestamps",
// Modified variables
fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("verb %d", settings.Verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", connection.Protocol),
fmt.Sprintf("remote %s %d", connection.IP, connection.Port),
fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("auth %s", auth),
fmt.Sprintf("cipher %s", settings.Cipher),
fmt.Sprintf("auth %s", settings.Auth),
}
if strings.HasSuffix(cipher, "-gcm") {
if strings.HasSuffix(settings.Cipher, "-gcm") {
lines = append(lines, "ncp-ciphers AES-256-GCM:AES-256-CBC:AES-128-GCM")
}
if !root {
if !settings.Root {
lines = append(lines, "user "+username)
}
if settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
}
lines = append(lines, []string{
"<ca>",
"-----BEGIN CERTIFICATE-----",

View File

@@ -42,30 +42,30 @@ func (h *HTTPProxy) String() string {
}
// GetHTTPProxySettings obtains HTTPProxy settings from environment variables using the params package.
func GetHTTPProxySettings(paramsReader params.Reader) (settings HTTPProxy, err error) {
func GetHTTPProxySettings(paramsReader params.Reader) (settings HTTPProxy, warning string, err error) {
settings.Enabled, err = paramsReader.GetHTTPProxy()
if err != nil || !settings.Enabled {
return settings, err
}
settings.Port, err = paramsReader.GetHTTPProxyPort()
if err != nil {
return settings, err
return settings, "", err
}
settings.User, err = paramsReader.GetHTTPProxyUser()
if err != nil {
return settings, err
return settings, "", err
}
settings.Password, err = paramsReader.GetHTTPProxyPassword()
if err != nil {
return settings, err
return settings, "", err
}
settings.Stealth, err = paramsReader.GetHTTPProxyStealth()
if err != nil {
return settings, err
return settings, "", err
}
settings.Log, err = paramsReader.GetHTTPProxyLog()
if err != nil {
return settings, err
return settings, "", err
}
return settings, nil
settings.Port, warning, err = paramsReader.GetHTTPProxyPort()
if err != nil {
return settings, warning, err
}
return settings, warning, nil
}

View File

@@ -14,6 +14,7 @@ type OpenVPN struct {
User string `json:"user"`
Password string `json:"password"`
Verbosity int `json:"verbosity"`
MSSFix uint16 `json:"mssfix"`
Root bool `json:"run_as_root"`
Cipher string `json:"cipher"`
Auth string `json:"auth"`
@@ -52,6 +53,10 @@ func GetOpenVPNSettings(paramsReader params.Reader, vpnProvider models.VPNProvid
if err != nil {
return settings, err
}
settings.MSSFix, err = paramsReader.GetOpenVPNMSSFix()
if err != nil {
return settings, err
}
switch vpnProvider {
case constants.PrivateInternetAccess:
settings.Provider, err = GetPIASettings(paramsReader)

View File

@@ -20,7 +20,7 @@ func Test_OpenVPN_JSON(t *testing.T) {
data, err := json.Marshal(in)
require.NoError(t, err)
//nolint:lll
assert.Equal(t, `{"user":"","password":"","verbosity":0,"run_as_root":true,"cipher":"","auth":"","provider":{"name":"name","server_selection":{"network_protocol":"","regions":null,"group":"","countries":null,"cities":null,"hostnames":null,"isps":null,"owned":false,"custom_port":0,"numbers":null,"encryption_preset":""},"extra_config":{"encryption_preset":"","openvpn_ipv6":false},"port_forwarding":{"enabled":false,"filepath":""}}}`, string(data))
assert.Equal(t, `{"user":"","password":"","verbosity":0,"mssfix":0,"run_as_root":true,"cipher":"","auth":"","provider":{"name":"name","server_selection":{"network_protocol":"","regions":null,"group":"","countries":null,"cities":null,"hostnames":null,"isps":null,"owned":false,"custom_port":0,"numbers":null,"encryption_preset":""},"extra_config":{"encryption_preset":"","openvpn_ipv6":false},"port_forwarding":{"enabled":false,"filepath":""}}}`, string(data))
var out OpenVPN
err = json.Unmarshal(data, &out)
require.NoError(t, err)

View File

@@ -24,14 +24,14 @@ func (c *ControlServer) String() string {
// GetControlServerSettings obtains the HTTP control server settings from
// environment variables using the params package.
func GetControlServerSettings(paramsReader params.Reader) (settings ControlServer, err error) {
settings.Port, err = paramsReader.GetControlServerPort()
if err != nil {
return settings, err
}
func GetControlServerSettings(paramsReader params.Reader) (settings ControlServer, warning string, err error) {
settings.Log, err = paramsReader.GetControlServerLog()
if err != nil {
return settings, err
return settings, "", err
}
return settings, nil
settings.Port, warning, err = paramsReader.GetControlServerPort()
if err != nil {
return settings, warning, err
}
return settings, warning, nil
}

View File

@@ -50,50 +50,64 @@ func (s *Settings) String() string {
// GetAllSettings obtains all settings for the program and returns an error as soon
// as an error is encountered reading them.
func GetAllSettings(paramsReader params.Reader) (settings Settings, err error) {
func GetAllSettings(paramsReader params.Reader) (settings Settings, warnings []string, err error) {
settings.VPNSP, err = paramsReader.GetVPNSP()
if err != nil {
return settings, err
return settings, nil, err
}
settings.OpenVPN, err = GetOpenVPNSettings(paramsReader, settings.VPNSP)
if err != nil {
return settings, err
return settings, nil, err
}
settings.DNS, err = GetDNSSettings(paramsReader)
if err != nil {
return settings, err
return settings, nil, err
}
settings.Firewall, err = GetFirewallSettings(paramsReader)
if err != nil {
return settings, err
}
settings.HTTPProxy, err = GetHTTPProxySettings(paramsReader)
if err != nil {
return settings, err
}
settings.ShadowSocks, err = GetShadowSocksSettings(paramsReader)
if err != nil {
return settings, err
return settings, nil, err
}
settings.System, err = GetSystemSettings(paramsReader)
if err != nil {
return settings, err
return settings, nil, err
}
settings.PublicIP, err = getPublicIPSettings(paramsReader)
if err != nil {
return settings, err
return settings, nil, err
}
settings.VersionInformation, err = paramsReader.GetVersionInformation()
if err != nil {
return settings, err
return settings, nil, err
}
settings.Updater, err = GetUpdaterSettings(paramsReader)
if err != nil {
return settings, err
return settings, nil, err
}
var warning string
settings.HTTPProxy, warning, err = GetHTTPProxySettings(paramsReader)
if warning != "" {
warnings = append(warnings, warning)
}
settings.ControlServer, err = GetControlServerSettings(paramsReader)
if err != nil {
return settings, err
return settings, warnings, err
}
return settings, nil
settings.ShadowSocks, warning, err = GetShadowSocksSettings(paramsReader)
if warning != "" {
warnings = append(warnings, warning)
}
if err != nil {
return settings, warnings, err
}
settings.ControlServer, warning, err = GetControlServerSettings(paramsReader)
if warning != "" {
warnings = append(warnings, warning)
}
if err != nil {
return settings, warnings, err
}
return settings, warnings, nil
}

View File

@@ -35,26 +35,26 @@ func (s *ShadowSocks) String() string {
}
// GetShadowSocksSettings obtains ShadowSocks settings from environment variables using the params package.
func GetShadowSocksSettings(paramsReader params.Reader) (settings ShadowSocks, err error) {
func GetShadowSocksSettings(paramsReader params.Reader) (settings ShadowSocks, warning string, err error) {
settings.Enabled, err = paramsReader.GetShadowSocks()
if err != nil || !settings.Enabled {
return settings, err
}
settings.Port, err = paramsReader.GetShadowSocksPort()
if err != nil {
return settings, err
return settings, "", err
}
settings.Password, err = paramsReader.GetShadowSocksPassword()
if err != nil {
return settings, err
return settings, "", err
}
settings.Log, err = paramsReader.GetShadowSocksLog()
if err != nil {
return settings, err
return settings, "", err
}
settings.Method, err = paramsReader.GetShadowSocksMethod()
if err != nil {
return settings, err
return settings, "", err
}
return settings, nil
settings.Port, warning, err = paramsReader.GetShadowSocksPort()
if err != nil {
return settings, warning, err
}
return settings, warning, nil
}