Rewrite of the entrypoint in Golang (#71)
- General improvements
- Parallel download of only needed files at start
- Prettier console output with all streams merged (openvpn, unbound, shadowsocks etc.)
- Simplified Docker final image
- Faster bootup
- DNS over TLS
- Finer grain blocking at DNS level: malicious, ads and surveillance
- Choose your DNS over TLS providers
- Ability to use multiple DNS over TLS providers for DNS split horizon
- Environment variables for DNS logging
- DNS block lists needed are downloaded and built automatically at start, in parallel
- PIA
- A random region is selected if the REGION parameter is left empty (thanks @rorph for your PR)
- Routing and iptables adjusted so it can work as a Kubernetes pod sidecar (thanks @rorph for your PR)
This commit is contained in:
61
internal/pia/download.go
Normal file
61
internal/pia/download.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package pia
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/private-internet-access-docker/internal/constants"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
func (c *configurator) DownloadOvpnConfig(encryption models.PIAEncryption,
|
||||
protocol models.NetworkProtocol, region models.PIARegion) (lines []string, err error) {
|
||||
c.logger.Info("%s: downloading openvpn configuration files", logPrefix)
|
||||
URL := buildZipURL(encryption, protocol)
|
||||
content, status, err := c.client.GetContent(URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if status != 200 {
|
||||
return nil, fmt.Errorf("HTTP Get %s resulted in HTTP status code %d", URL, status)
|
||||
}
|
||||
filename := fmt.Sprintf("%s.ovpn", region)
|
||||
fileContent, err := getFileInZip(content, filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", URL, err)
|
||||
}
|
||||
lines = strings.Split(string(fileContent), "\n")
|
||||
return lines, nil
|
||||
}
|
||||
|
||||
func buildZipURL(encryption models.PIAEncryption, protocol models.NetworkProtocol) (URL string) {
|
||||
URL = string(constants.PIAOpenVPNURL) + "/openvpn"
|
||||
if encryption == constants.PIAEncryptionStrong {
|
||||
URL += "-strong"
|
||||
}
|
||||
if protocol == constants.TCP {
|
||||
URL += "-tcp"
|
||||
}
|
||||
return URL + ".zip"
|
||||
}
|
||||
|
||||
func getFileInZip(zipContent []byte, filename string) (fileContent []byte, err error) {
|
||||
contentLength := int64(len(zipContent))
|
||||
r, err := zip.NewReader(bytes.NewReader(zipContent), contentLength)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, f := range r.File {
|
||||
if f.Name == filename {
|
||||
readCloser, err := f.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer readCloser.Close()
|
||||
return ioutil.ReadAll(readCloser)
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("%s not found in zip archive file", filename)
|
||||
}
|
||||
31
internal/pia/modify.go
Normal file
31
internal/pia/modify.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package pia
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/private-internet-access-docker/internal/constants"
|
||||
)
|
||||
|
||||
func (c *configurator) ModifyLines(lines []string, IPs []net.IP, port uint16) (modifiedLines []string) {
|
||||
c.logger.Info("%s: adapting openvpn configuration for server IP addresses and port %d", logPrefix, port)
|
||||
// Remove lines
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, "privateinternetaccess.com") ||
|
||||
strings.Contains(line, "resolv-retry") {
|
||||
continue
|
||||
}
|
||||
modifiedLines = append(modifiedLines, line)
|
||||
}
|
||||
// Add lines
|
||||
for _, IP := range IPs {
|
||||
modifiedLines = append(modifiedLines, fmt.Sprintf("remote %s %d", IP.String(), port))
|
||||
}
|
||||
modifiedLines = append(modifiedLines, "auth-user-pass "+string(constants.OpenVPNAuthConf))
|
||||
modifiedLines = append(modifiedLines, "auth-retry nointeract")
|
||||
modifiedLines = append(modifiedLines, "pull-filter ignore \"auth-token\"") // prevent auth failed loops
|
||||
modifiedLines = append(modifiedLines, "user nonrootuser")
|
||||
modifiedLines = append(modifiedLines, "mute-replay-warnings")
|
||||
return modifiedLines
|
||||
}
|
||||
31
internal/pia/modify_test.go
Normal file
31
internal/pia/modify_test.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package pia
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
loggingMocks "github.com/qdm12/golibs/logging/mocks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_ModifyLines(t *testing.T) {
|
||||
t.Parallel()
|
||||
original, err := ioutil.ReadFile("testdata/ovpn.golden")
|
||||
require.NoError(t, err)
|
||||
originalLines := strings.Split(string(original), "\n")
|
||||
expected, err := ioutil.ReadFile("testdata/ovpn.modified.golden")
|
||||
require.NoError(t, err)
|
||||
expectedLines := strings.Split(string(expected), "\n")
|
||||
|
||||
var port uint16 = 3000
|
||||
IPs := []net.IP{net.IP{100, 10, 10, 10}, net.IP{100, 20, 20, 20}}
|
||||
logger := &loggingMocks.Logger{}
|
||||
logger.On("Info", "%s: adapting openvpn configuration for server IP addresses and port %d", logPrefix, port).Once()
|
||||
c := &configurator{logger: logger}
|
||||
modifiedLines := c.ModifyLines(originalLines, IPs, port)
|
||||
assert.Equal(t, expectedLines, modifiedLines)
|
||||
logger.AssertExpectations(t)
|
||||
}
|
||||
54
internal/pia/parse.go
Normal file
54
internal/pia/parse.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package pia
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/private-internet-access-docker/internal/constants"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
func (c *configurator) ParseConfig(lines []string) (IPs []net.IP, port uint16, device models.VPNDevice, err error) {
|
||||
c.logger.Info("%s: parsing openvpn configuration", logPrefix)
|
||||
remoteLineFound := false
|
||||
deviceLineFound := false
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "remote ") {
|
||||
remoteLineFound = true
|
||||
words := strings.Fields(line)
|
||||
if len(words) != 3 {
|
||||
return nil, 0, "", fmt.Errorf("line %q misses information", line)
|
||||
}
|
||||
host := words[1]
|
||||
if err := c.verifyPort(words[2]); err != nil {
|
||||
return nil, 0, "", fmt.Errorf("line %q has an invalid port: %w", line, err)
|
||||
}
|
||||
portUint64, _ := strconv.ParseUint(words[2], 10, 16)
|
||||
port = uint16(portUint64)
|
||||
IPs, err = c.lookupIP(host)
|
||||
if err != nil {
|
||||
return nil, 0, "", err
|
||||
}
|
||||
} else if strings.HasPrefix(line, "dev ") {
|
||||
deviceLineFound = true
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) != 2 {
|
||||
return nil, 0, "", fmt.Errorf("line %q misses information", line)
|
||||
}
|
||||
device = models.VPNDevice(fields[1] + "0")
|
||||
if device != constants.TUN && device != constants.TAP {
|
||||
return nil, 0, "", fmt.Errorf("device %q is not valid", device)
|
||||
}
|
||||
}
|
||||
}
|
||||
if remoteLineFound && deviceLineFound {
|
||||
c.logger.Info("%s: Found %d PIA server IP addresses, port %d and device %s", logPrefix, len(IPs), port, device)
|
||||
return IPs, port, device, nil
|
||||
} else if !remoteLineFound {
|
||||
return nil, 0, "", fmt.Errorf("remote line not found in Openvpn configuration")
|
||||
} else {
|
||||
return nil, 0, "", fmt.Errorf("device line not found in Openvpn configuration")
|
||||
}
|
||||
}
|
||||
99
internal/pia/parse_test.go
Normal file
99
internal/pia/parse_test.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package pia
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
loggingMocks "github.com/qdm12/golibs/logging/mocks"
|
||||
"github.com/qdm12/golibs/verification"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/constants"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_ParseConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
original, err := ioutil.ReadFile("testdata/ovpn.golden")
|
||||
require.NoError(t, err)
|
||||
exampleLines := strings.Split(string(original), "\n")
|
||||
tests := map[string]struct {
|
||||
lines []string
|
||||
lookupIPs []net.IP
|
||||
lookupIPErr error
|
||||
IPs []net.IP
|
||||
port uint16
|
||||
device models.VPNDevice
|
||||
err error
|
||||
}{
|
||||
"no data": {
|
||||
err: fmt.Errorf("remote line not found in Openvpn configuration"),
|
||||
},
|
||||
"bad remote line": {
|
||||
lines: []string{"remote field2"},
|
||||
err: fmt.Errorf("line \"remote field2\" misses information"),
|
||||
},
|
||||
"bad remote port": {
|
||||
lines: []string{"remote field2 port"},
|
||||
err: fmt.Errorf("line \"remote field2 port\" has an invalid port: port \"port\" is not a valid integer"),
|
||||
},
|
||||
"lookupIP error": {
|
||||
lines: []string{"remote host 1000"},
|
||||
lookupIPErr: fmt.Errorf("lookup error"),
|
||||
err: fmt.Errorf("lookup error"),
|
||||
},
|
||||
"missing dev line": {
|
||||
lines: []string{"remote host 1994"},
|
||||
err: fmt.Errorf("device line not found in Openvpn configuration"),
|
||||
},
|
||||
"bad dev line": {
|
||||
lines: []string{"dev field2 field3"},
|
||||
err: fmt.Errorf("line \"dev field2 field3\" misses information"),
|
||||
},
|
||||
"bad device": {
|
||||
lines: []string{"dev xx"},
|
||||
err: fmt.Errorf("device \"xx0\" is not valid"),
|
||||
},
|
||||
"valid lines": {
|
||||
lines: []string{"remote host 1194", "dev tap", "blabla"},
|
||||
port: 1194,
|
||||
device: constants.TAP,
|
||||
},
|
||||
"real data": {
|
||||
lines: exampleLines,
|
||||
lookupIPs: []net.IP{{100, 100, 100, 100}, {100, 100, 200, 200}},
|
||||
IPs: []net.IP{{100, 100, 100, 100}, {100, 100, 200, 200}},
|
||||
port: 1198,
|
||||
device: constants.TUN,
|
||||
},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
logger := &loggingMocks.Logger{}
|
||||
logger.On("Info", "%s: parsing openvpn configuration", logPrefix).Once()
|
||||
if tc.err == nil {
|
||||
logger.On("Info", "%s: Found %d PIA server IP addresses, port %d and device %s", logPrefix, len(tc.IPs), tc.port, tc.device).Once()
|
||||
}
|
||||
lookupIP := func(host string) ([]net.IP, error) {
|
||||
return tc.lookupIPs, tc.lookupIPErr
|
||||
}
|
||||
c := &configurator{logger: logger, verifyPort: verification.NewVerifier().VerifyPort, lookupIP: lookupIP}
|
||||
IPs, port, device, err := c.ParseConfig(tc.lines)
|
||||
if tc.err != nil {
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, tc.err.Error(), err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
assert.Equal(t, tc.IPs, IPs)
|
||||
assert.Equal(t, tc.port, port)
|
||||
assert.Equal(t, tc.device, device)
|
||||
logger.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
41
internal/pia/pia.go
Normal file
41
internal/pia/pia.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package pia
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/qdm12/golibs/crypto/random"
|
||||
"github.com/qdm12/golibs/files"
|
||||
"github.com/qdm12/golibs/logging"
|
||||
"github.com/qdm12/golibs/network"
|
||||
"github.com/qdm12/golibs/verification"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/firewall"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
const logPrefix = "PIA configurator"
|
||||
|
||||
// Configurator contains methods to download, read and modify the openvpn configuration to connect as a client
|
||||
type Configurator interface {
|
||||
DownloadOvpnConfig(encryption models.PIAEncryption,
|
||||
protocol models.NetworkProtocol, region models.PIARegion) (lines []string, err error)
|
||||
ParseConfig(lines []string) (IPs []net.IP, port uint16, device models.VPNDevice, err error)
|
||||
ModifyLines(lines []string, IPs []net.IP, port uint16) (modifiedLines []string)
|
||||
GetPortForward() (port uint16, err error)
|
||||
WritePortForward(filepath models.Filepath, port uint16) (err error)
|
||||
AllowPortForwardFirewall(device models.VPNDevice, port uint16) (err error)
|
||||
}
|
||||
|
||||
type configurator struct {
|
||||
client network.Client
|
||||
fileManager files.FileManager
|
||||
firewall firewall.Configurator
|
||||
logger logging.Logger
|
||||
random random.Random
|
||||
verifyPort func(port string) error
|
||||
lookupIP func(host string) ([]net.IP, error)
|
||||
}
|
||||
|
||||
// NewConfigurator returns a new Configurator object
|
||||
func NewConfigurator(client network.Client, fileManager files.FileManager, firewall firewall.Configurator, logger logging.Logger) Configurator {
|
||||
return &configurator{client, fileManager, firewall, logger, random.NewRandom(), verification.NewVerifier().VerifyPort, net.LookupIP}
|
||||
}
|
||||
46
internal/pia/portforward.go
Normal file
46
internal/pia/portforward.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package pia
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/qdm12/private-internet-access-docker/internal/constants"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
func (c *configurator) GetPortForward() (port uint16, err error) {
|
||||
c.logger.Info("%s: Obtaining port to be forwarded", logPrefix)
|
||||
b, err := c.random.GenerateRandomBytes(32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
clientID := hex.EncodeToString(b)
|
||||
url := fmt.Sprintf("%s/?client_id=%s", constants.PIAPortForwardURL, clientID)
|
||||
content, status, err := c.client.GetContent(url)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else if status != 200 {
|
||||
return 0, fmt.Errorf("status is %d for %s; does your PIA server support port forwarding?", status, url)
|
||||
} else if len(content) == 0 {
|
||||
return 0, fmt.Errorf("port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding")
|
||||
}
|
||||
body := struct {
|
||||
Port uint16 `json:"port"`
|
||||
}{}
|
||||
if err := json.Unmarshal(content, &body); err != nil {
|
||||
return 0, fmt.Errorf("port forwarding response: %w", err)
|
||||
}
|
||||
c.logger.Info("%s: Port forwarded is %d", logPrefix, port)
|
||||
return body.Port, nil
|
||||
}
|
||||
|
||||
func (c *configurator) WritePortForward(filepath models.Filepath, port uint16) (err error) {
|
||||
c.logger.Info("%s: Writing forwarded port to %s", logPrefix, filepath)
|
||||
return c.fileManager.WriteLinesToFile(string(filepath), []string{fmt.Sprintf("%d", port)})
|
||||
}
|
||||
|
||||
func (c *configurator) AllowPortForwardFirewall(device models.VPNDevice, port uint16) (err error) {
|
||||
c.logger.Info("%s: Allowing forwarded port %d through firewall", logPrefix, port)
|
||||
return c.firewall.AllowInputTrafficOnPort(device, port)
|
||||
}
|
||||
72
internal/pia/testdata/ovpn.golden
vendored
Normal file
72
internal/pia/testdata/ovpn.golden
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
client
|
||||
dev tun
|
||||
proto udp
|
||||
remote belgium.privateinternetaccess.com 1198
|
||||
resolv-retry infinite
|
||||
nobind
|
||||
persist-key
|
||||
persist-tun
|
||||
cipher aes-128-cbc
|
||||
auth sha1
|
||||
tls-client
|
||||
remote-cert-tls server
|
||||
|
||||
auth-user-pass
|
||||
compress
|
||||
verb 1
|
||||
reneg-sec 0
|
||||
<crl-verify>
|
||||
-----BEGIN X509 CRL-----
|
||||
MIICWDCCAUAwDQYJKoZIhvcNAQENBQAwgegxCzAJBgNVBAYTAlVTMQswCQYDVQQI
|
||||
EwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRl
|
||||
cm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAw
|
||||
HgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0
|
||||
ZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRl
|
||||
aW50ZXJuZXRhY2Nlc3MuY29tFw0xNjA3MDgxOTAwNDZaFw0zNjA3MDMxOTAwNDZa
|
||||
MCYwEQIBARcMMTYwNzA4MTkwMDQ2MBECAQYXDDE2MDcwODE5MDA0NjANBgkqhkiG
|
||||
9w0BAQ0FAAOCAQEAQZo9X97ci8EcPYu/uK2HB152OZbeZCINmYyluLDOdcSvg6B5
|
||||
jI+ffKN3laDvczsG6CxmY3jNyc79XVpEYUnq4rT3FfveW1+Ralf+Vf38HdpwB8EW
|
||||
B4hZlQ205+21CALLvZvR8HcPxC9KEnev1mU46wkTiov0EKc+EdRxkj5yMgv0V2Re
|
||||
ze7AP+NQ9ykvDScH4eYCsmufNpIjBLhpLE2cuZZXBLcPhuRzVoU3l7A9lvzG9mjA
|
||||
5YijHJGHNjlWFqyrn1CfYS6koa4TGEPngBoAziWRbDGdhEgJABHrpoaFYaL61zqy
|
||||
MR6jC0K2ps9qyZAN74LEBedEfK7tBOzWMwr58A==
|
||||
-----END X509 CRL-----
|
||||
</crl-verify>
|
||||
|
||||
<ca>
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFqzCCBJOgAwIBAgIJAKZ7D5Yv87qDMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD
|
||||
VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV
|
||||
BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu
|
||||
dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx
|
||||
IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB
|
||||
FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzM1
|
||||
MThaFw0zNDA0MTIxNzM1MThaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
|
||||
EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg
|
||||
QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE
|
||||
AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50
|
||||
ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy
|
||||
bmV0YWNjZXNzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPXD
|
||||
L1L9tX6DGf36liA7UBTy5I869z0UVo3lImfOs/GSiFKPtInlesP65577nd7UNzzX
|
||||
lH/P/CnFPdBWlLp5ze3HRBCc/Avgr5CdMRkEsySL5GHBZsx6w2cayQ2EcRhVTwWp
|
||||
cdldeNO+pPr9rIgPrtXqT4SWViTQRBeGM8CDxAyTopTsobjSiYZCF9Ta1gunl0G/
|
||||
8Vfp+SXfYCC+ZzWvP+L1pFhPRqzQQ8k+wMZIovObK1s+nlwPaLyayzw9a8sUnvWB
|
||||
/5rGPdIYnQWPgoNlLN9HpSmsAcw2z8DXI9pIxbr74cb3/HSfuYGOLkRqrOk6h4RC
|
||||
OfuWoTrZup1uEOn+fw8CAwEAAaOCAVQwggFQMB0GA1UdDgQWBBQv63nQ/pJAt5tL
|
||||
y8VJcbHe22ZOsjCCAR8GA1UdIwSCARYwggESgBQv63nQ/pJAt5tLy8VJcbHe22ZO
|
||||
sqGB7qSB6zCB6DELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRMwEQYDVQQHEwpM
|
||||
b3NBbmdlbGVzMSAwHgYDVQQKExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4G
|
||||
A1UECxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBAMTF1ByaXZhdGUg
|
||||
SW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQpExdQcml2YXRlIEludGVybmV0IEFjY2Vz
|
||||
czEvMC0GCSqGSIb3DQEJARYgc2VjdXJlQHByaXZhdGVpbnRlcm5ldGFjY2Vzcy5j
|
||||
b22CCQCmew+WL/O6gzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQAn
|
||||
a5PgrtxfwTumD4+3/SYvwoD66cB8IcK//h1mCzAduU8KgUXocLx7QgJWo9lnZ8xU
|
||||
ryXvWab2usg4fqk7FPi00bED4f4qVQFVfGfPZIH9QQ7/48bPM9RyfzImZWUCenK3
|
||||
7pdw4Bvgoys2rHLHbGen7f28knT2j/cbMxd78tQc20TIObGjo8+ISTRclSTRBtyC
|
||||
GohseKYpTS9himFERpUgNtefvYHbn70mIOzfOJFTVqfrptf9jXa9N8Mpy3ayfodz
|
||||
1wiqdteqFXkTYoSDctgKMiZ6GdocK9nMroQipIQtpnwd4yBDWIyC6Bvlkrq5TQUt
|
||||
YDQ8z9v+DMO6iwyIDRiU
|
||||
-----END CERTIFICATE-----
|
||||
</ca>
|
||||
|
||||
disable-occ
|
||||
78
internal/pia/testdata/ovpn.modified.golden
vendored
Normal file
78
internal/pia/testdata/ovpn.modified.golden
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
client
|
||||
dev tun
|
||||
proto udp
|
||||
nobind
|
||||
persist-key
|
||||
persist-tun
|
||||
cipher aes-128-cbc
|
||||
auth sha1
|
||||
tls-client
|
||||
remote-cert-tls server
|
||||
|
||||
auth-user-pass
|
||||
compress
|
||||
verb 1
|
||||
reneg-sec 0
|
||||
<crl-verify>
|
||||
-----BEGIN X509 CRL-----
|
||||
MIICWDCCAUAwDQYJKoZIhvcNAQENBQAwgegxCzAJBgNVBAYTAlVTMQswCQYDVQQI
|
||||
EwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRl
|
||||
cm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAw
|
||||
HgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0
|
||||
ZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRl
|
||||
aW50ZXJuZXRhY2Nlc3MuY29tFw0xNjA3MDgxOTAwNDZaFw0zNjA3MDMxOTAwNDZa
|
||||
MCYwEQIBARcMMTYwNzA4MTkwMDQ2MBECAQYXDDE2MDcwODE5MDA0NjANBgkqhkiG
|
||||
9w0BAQ0FAAOCAQEAQZo9X97ci8EcPYu/uK2HB152OZbeZCINmYyluLDOdcSvg6B5
|
||||
jI+ffKN3laDvczsG6CxmY3jNyc79XVpEYUnq4rT3FfveW1+Ralf+Vf38HdpwB8EW
|
||||
B4hZlQ205+21CALLvZvR8HcPxC9KEnev1mU46wkTiov0EKc+EdRxkj5yMgv0V2Re
|
||||
ze7AP+NQ9ykvDScH4eYCsmufNpIjBLhpLE2cuZZXBLcPhuRzVoU3l7A9lvzG9mjA
|
||||
5YijHJGHNjlWFqyrn1CfYS6koa4TGEPngBoAziWRbDGdhEgJABHrpoaFYaL61zqy
|
||||
MR6jC0K2ps9qyZAN74LEBedEfK7tBOzWMwr58A==
|
||||
-----END X509 CRL-----
|
||||
</crl-verify>
|
||||
|
||||
<ca>
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFqzCCBJOgAwIBAgIJAKZ7D5Yv87qDMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD
|
||||
VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV
|
||||
BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu
|
||||
dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx
|
||||
IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB
|
||||
FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzM1
|
||||
MThaFw0zNDA0MTIxNzM1MThaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
|
||||
EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg
|
||||
QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE
|
||||
AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50
|
||||
ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy
|
||||
bmV0YWNjZXNzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPXD
|
||||
L1L9tX6DGf36liA7UBTy5I869z0UVo3lImfOs/GSiFKPtInlesP65577nd7UNzzX
|
||||
lH/P/CnFPdBWlLp5ze3HRBCc/Avgr5CdMRkEsySL5GHBZsx6w2cayQ2EcRhVTwWp
|
||||
cdldeNO+pPr9rIgPrtXqT4SWViTQRBeGM8CDxAyTopTsobjSiYZCF9Ta1gunl0G/
|
||||
8Vfp+SXfYCC+ZzWvP+L1pFhPRqzQQ8k+wMZIovObK1s+nlwPaLyayzw9a8sUnvWB
|
||||
/5rGPdIYnQWPgoNlLN9HpSmsAcw2z8DXI9pIxbr74cb3/HSfuYGOLkRqrOk6h4RC
|
||||
OfuWoTrZup1uEOn+fw8CAwEAAaOCAVQwggFQMB0GA1UdDgQWBBQv63nQ/pJAt5tL
|
||||
y8VJcbHe22ZOsjCCAR8GA1UdIwSCARYwggESgBQv63nQ/pJAt5tLy8VJcbHe22ZO
|
||||
sqGB7qSB6zCB6DELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRMwEQYDVQQHEwpM
|
||||
b3NBbmdlbGVzMSAwHgYDVQQKExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4G
|
||||
A1UECxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBAMTF1ByaXZhdGUg
|
||||
SW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQpExdQcml2YXRlIEludGVybmV0IEFjY2Vz
|
||||
czEvMC0GCSqGSIb3DQEJARYgc2VjdXJlQHByaXZhdGVpbnRlcm5ldGFjY2Vzcy5j
|
||||
b22CCQCmew+WL/O6gzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQAn
|
||||
a5PgrtxfwTumD4+3/SYvwoD66cB8IcK//h1mCzAduU8KgUXocLx7QgJWo9lnZ8xU
|
||||
ryXvWab2usg4fqk7FPi00bED4f4qVQFVfGfPZIH9QQ7/48bPM9RyfzImZWUCenK3
|
||||
7pdw4Bvgoys2rHLHbGen7f28knT2j/cbMxd78tQc20TIObGjo8+ISTRclSTRBtyC
|
||||
GohseKYpTS9himFERpUgNtefvYHbn70mIOzfOJFTVqfrptf9jXa9N8Mpy3ayfodz
|
||||
1wiqdteqFXkTYoSDctgKMiZ6GdocK9nMroQipIQtpnwd4yBDWIyC6Bvlkrq5TQUt
|
||||
YDQ8z9v+DMO6iwyIDRiU
|
||||
-----END CERTIFICATE-----
|
||||
</ca>
|
||||
|
||||
disable-occ
|
||||
|
||||
remote 100.10.10.10 3000
|
||||
remote 100.20.20.20 3000
|
||||
auth-user-pass /etc/openvpn/auth.conf
|
||||
auth-retry nointeract
|
||||
pull-filter ignore "auth-token"
|
||||
user nonrootuser
|
||||
mute-replay-warnings
|
||||
Reference in New Issue
Block a user