Openvpn get settings http route

This commit is contained in:
Quentin McGaw
2020-07-19 14:26:24 +00:00
parent 29f74df450
commit 4baf0420d6
9 changed files with 172 additions and 41 deletions

View File

@@ -378,6 +378,7 @@ A built-in HTTP server listens on port `8000` to modify the state of the contain
- `http://<your-docker-host-ip>:8000/openvpn/actions/restart` restarts the openvpn process
- `http://<your-docker-host-ip>:8000/unbound/actions/restart` re-downloads the DNS files (crypto and block lists) and restarts the unbound process
- `http://<your-docker-host-ip>:8000/openvpn/portforwarded` to get your port forwarded as JSON. You can use **jq** to parse JSON on linux.
- `http://<your-docker-host-ip>:8000/openvpn/settings` to get your openvpn settings as a JSON object.
## Development and contributing

View File

@@ -129,6 +129,7 @@ func _main(background context.Context, args []string) int {
ovpnConf, firewallConf, logger, client, fileManager, streamMerger, fatalOnError)
restartOpenvpn := openvpnLooper.Restart
portForward := openvpnLooper.PortForward
getOpenvpnSettings := openvpnLooper.GetSettings
getPortForwarded := openvpnLooper.GetPortForwarded
// wait for restartOpenvpn
go openvpnLooper.Run(ctx, wg)
@@ -177,7 +178,7 @@ func _main(background context.Context, args []string) int {
}
}()
httpServer := server.New("0.0.0.0:8000", logger, restartOpenvpn, restartUnbound, getPortForwarded)
httpServer := server.New("0.0.0.0:8000", logger, restartOpenvpn, restartUnbound, getOpenvpnSettings, getPortForwarded)
go httpServer.Run(ctx, wg)
// Start openvpn for the first time

View File

@@ -1,5 +1,10 @@
package models
import (
"fmt"
"strings"
)
type (
// VPNDevice is the device name used to tunnel using Openvpn
VPNDevice string
@@ -14,7 +19,45 @@ type (
// TinyProxyLogLevel is the log level for TinyProxy
TinyProxyLogLevel string
// VPNProvider is the name of the VPN provider to be used
VPNProvider string // TODO
VPNProvider string
// NetworkProtocol contains the network protocol to be used to communicate with the VPN servers
NetworkProtocol string
)
func marshalJSONString(s string) (data []byte, err error) {
return []byte(fmt.Sprintf("%q", s)), nil
}
func unmarshalJSONString(data []byte) (s string) {
s = string(data)
s = strings.TrimPrefix(s, "\"")
s = strings.TrimSuffix(s, "\"")
return s
}
func (v *VPNProvider) MarshalJSON() ([]byte, error) {
return marshalJSONString(string(*v))
}
func (v *VPNProvider) UnmarshalJSON(data []byte) error {
*v = VPNProvider(unmarshalJSONString(data))
return nil
}
func (n *NetworkProtocol) MarshalJSON() ([]byte, error) {
return marshalJSONString(string(*n))
}
func (n *NetworkProtocol) UnmarshalJSON(data []byte) error {
*n = NetworkProtocol(unmarshalJSONString(data))
return nil
}
func (f *Filepath) MarshalJSON() ([]byte, error) {
return marshalJSONString(string(*f))
}
func (f *Filepath) UnmarshalJSON(data []byte) error {
*f = Filepath(unmarshalJSONString(data))
return nil
}

View File

@@ -0,0 +1,41 @@
package models
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_VPNProvider_JSON(t *testing.T) {
t.Parallel()
v := VPNProvider("name")
data, err := v.MarshalJSON()
require.NoError(t, err)
assert.Equal(t, []byte{0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22}, data)
err = v.UnmarshalJSON(data)
require.NoError(t, err)
assert.Equal(t, VPNProvider("name"), v)
}
func Test_NetworkProtocol_JSON(t *testing.T) {
t.Parallel()
v := NetworkProtocol("name")
data, err := v.MarshalJSON()
require.NoError(t, err)
assert.Equal(t, []byte{0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22}, data)
err = v.UnmarshalJSON(data)
require.NoError(t, err)
assert.Equal(t, NetworkProtocol("name"), v)
}
func Test_Filepath_JSON(t *testing.T) {
t.Parallel()
v := Filepath("name")
data, err := v.MarshalJSON()
require.NoError(t, err)
assert.Equal(t, []byte{0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22}, data)
err = v.UnmarshalJSON(data)
require.NoError(t, err)
assert.Equal(t, Filepath("name"), v)
}

View File

@@ -8,48 +8,48 @@ import (
// ProviderSettings contains settings specific to a VPN provider
type ProviderSettings struct {
Name VPNProvider
ServerSelection ServerSelection
ExtraConfigOptions ExtraConfigOptions
PortForwarding PortForwarding
Name VPNProvider `json:"name"`
ServerSelection ServerSelection `json:"serverSelection"`
ExtraConfigOptions ExtraConfigOptions `json:"extraConfig"`
PortForwarding PortForwarding `json:"portForwarding"`
}
type ServerSelection struct { //nolint:maligned
// Common
Protocol NetworkProtocol
TargetIP net.IP
Protocol NetworkProtocol `json:"networkProtocol"`
TargetIP net.IP `json:"targetIP,omitempty"`
// Cyberghost, PIA, Surfshark, Windscribe, Vyprvpn, NordVPN
Region string
Region string `json:"region"`
// Cyberghost
Group string
Group string `json:"group"`
// Mullvad
Country string
City string
ISP string
Owned bool
Country string `json:"country"`
City string `json:"city"`
ISP string `json:"isp"`
Owned bool `json:"owned"`
// Mullvad, Windscribe
CustomPort uint16
// PIA
EncryptionPreset string
CustomPort uint16 `json:"customPort"`
// NordVPN
Number uint16
Number uint16 `json:"number"`
// PIA
EncryptionPreset string `json:"encryptionPreset"`
}
type ExtraConfigOptions struct {
ClientKey string // Cyberghost
EncryptionPreset string // PIA
ClientKey string `json:"-"` // Cyberghost
EncryptionPreset string `json:"encryptionPreset"` // PIA
}
// PortForwarding contains settings for port forwarding
type PortForwarding struct {
Enabled bool
Filepath Filepath
Enabled bool `json:"enabled"`
Filepath Filepath `json:"filepath"`
}
func (p *PortForwarding) String() string {

View File

@@ -21,3 +21,16 @@ func (s *server) handleGetPortForwarded(w http.ResponseWriter) {
}
}
func (s *server) handleGetOpenvpnSettings(w http.ResponseWriter) {
settings := s.getOpenvpnSettings()
data, err := json.Marshal(settings)
if err != nil {
s.logger.Warn(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if _, err := w.Write(data); err != nil {
s.logger.Warn(err)
w.WriteHeader(http.StatusInternalServerError)
}
}

View File

@@ -8,6 +8,7 @@ import (
"time"
"github.com/qdm12/golibs/logging"
"github.com/qdm12/private-internet-access-docker/internal/settings"
)
type Server interface {
@@ -19,16 +20,18 @@ type server struct {
logger logging.Logger
restartOpenvpn func()
restartUnbound func()
getOpenvpnSettings func() settings.OpenVPN
getPortForwarded func() uint16
}
func New(address string, logger logging.Logger, restartOpenvpn, restartUnbound func(),
getPortForwarded func() uint16) Server {
getOpenvpnSettings func() settings.OpenVPN, getPortForwarded func() uint16) Server {
return &server{
address: address,
logger: logger.WithPrefix("http server: "),
restartOpenvpn: restartOpenvpn,
restartUnbound: restartUnbound,
getOpenvpnSettings: getOpenvpnSettings,
getPortForwarded: getPortForwarded,
}
}
@@ -66,6 +69,8 @@ func (s *server) makeHandler() http.HandlerFunc {
s.restartUnbound()
case "/openvpn/portforwarded":
s.handleGetPortForwarded(w)
case "/openvpn/settings":
s.handleGetOpenvpnSettings(w)
default:
routeDoesNotExist(s.logger, w, r)
}

View File

@@ -11,13 +11,13 @@ import (
// OpenVPN contains settings to configure the OpenVPN client
type OpenVPN struct {
User string
Password string
Verbosity int
Root bool
Cipher string
Auth string
Provider models.ProviderSettings
User string `json:"user"`
Password string `json:"-"`
Verbosity int `json:"verbosity"`
Root bool `json:"runAsRoot"`
Cipher string `json:"cipher"`
Auth string `json:"auth"`
Provider models.ProviderSettings `json:"provider"`
}
// GetOpenVPNSettings obtains the OpenVPN settings using the params functions

View File

@@ -0,0 +1,27 @@
package settings
import (
"encoding/json"
"testing"
"github.com/qdm12/private-internet-access-docker/internal/models"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_OpenVPN_JSON(t *testing.T) {
t.Parallel()
in := OpenVPN{
Root: true,
Provider: models.ProviderSettings{
Name: "name",
},
}
data, err := json.Marshal(in)
require.NoError(t, err)
assert.Equal(t, `{"user":"","verbosity":0,"runAsRoot":true,"cipher":"","auth":"","provider":{"name":"name","serverSelection":{"networkProtocol":"","region":"","group":"","country":"","city":"","isp":"","owned":false,"customPort":0,"number":0,"encryptionPreset":""},"extraConfig":{"encryptionPreset":""},"portForwarding":{"enabled":false,"filepath":""}}}`, string(data))
var out OpenVPN
err = json.Unmarshal(data, &out)
require.NoError(t, err)
assert.Equal(t, in, out)
}