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/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/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/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 ## Development and contributing

View File

@@ -129,6 +129,7 @@ func _main(background context.Context, args []string) int {
ovpnConf, firewallConf, logger, client, fileManager, streamMerger, fatalOnError) ovpnConf, firewallConf, logger, client, fileManager, streamMerger, fatalOnError)
restartOpenvpn := openvpnLooper.Restart restartOpenvpn := openvpnLooper.Restart
portForward := openvpnLooper.PortForward portForward := openvpnLooper.PortForward
getOpenvpnSettings := openvpnLooper.GetSettings
getPortForwarded := openvpnLooper.GetPortForwarded getPortForwarded := openvpnLooper.GetPortForwarded
// wait for restartOpenvpn // wait for restartOpenvpn
go openvpnLooper.Run(ctx, wg) 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) go httpServer.Run(ctx, wg)
// Start openvpn for the first time // Start openvpn for the first time

View File

@@ -1,5 +1,10 @@
package models package models
import (
"fmt"
"strings"
)
type ( type (
// VPNDevice is the device name used to tunnel using Openvpn // VPNDevice is the device name used to tunnel using Openvpn
VPNDevice string VPNDevice string
@@ -14,7 +19,45 @@ type (
// TinyProxyLogLevel is the log level for TinyProxy // TinyProxyLogLevel is the log level for TinyProxy
TinyProxyLogLevel string TinyProxyLogLevel string
// VPNProvider is the name of the VPN provider to be used // 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 contains the network protocol to be used to communicate with the VPN servers
NetworkProtocol string 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 // ProviderSettings contains settings specific to a VPN provider
type ProviderSettings struct { type ProviderSettings struct {
Name VPNProvider Name VPNProvider `json:"name"`
ServerSelection ServerSelection ServerSelection ServerSelection `json:"serverSelection"`
ExtraConfigOptions ExtraConfigOptions ExtraConfigOptions ExtraConfigOptions `json:"extraConfig"`
PortForwarding PortForwarding PortForwarding PortForwarding `json:"portForwarding"`
} }
type ServerSelection struct { //nolint:maligned type ServerSelection struct { //nolint:maligned
// Common // Common
Protocol NetworkProtocol Protocol NetworkProtocol `json:"networkProtocol"`
TargetIP net.IP TargetIP net.IP `json:"targetIP,omitempty"`
// Cyberghost, PIA, Surfshark, Windscribe, Vyprvpn, NordVPN // Cyberghost, PIA, Surfshark, Windscribe, Vyprvpn, NordVPN
Region string Region string `json:"region"`
// Cyberghost // Cyberghost
Group string Group string `json:"group"`
// Mullvad // Mullvad
Country string Country string `json:"country"`
City string City string `json:"city"`
ISP string ISP string `json:"isp"`
Owned bool Owned bool `json:"owned"`
// Mullvad, Windscribe // Mullvad, Windscribe
CustomPort uint16 CustomPort uint16 `json:"customPort"`
// PIA
EncryptionPreset string
// NordVPN // NordVPN
Number uint16 Number uint16 `json:"number"`
// PIA
EncryptionPreset string `json:"encryptionPreset"`
} }
type ExtraConfigOptions struct { type ExtraConfigOptions struct {
ClientKey string // Cyberghost ClientKey string `json:"-"` // Cyberghost
EncryptionPreset string // PIA EncryptionPreset string `json:"encryptionPreset"` // PIA
} }
// PortForwarding contains settings for port forwarding // PortForwarding contains settings for port forwarding
type PortForwarding struct { type PortForwarding struct {
Enabled bool Enabled bool `json:"enabled"`
Filepath Filepath Filepath Filepath `json:"filepath"`
} }
func (p *PortForwarding) String() string { 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" "time"
"github.com/qdm12/golibs/logging" "github.com/qdm12/golibs/logging"
"github.com/qdm12/private-internet-access-docker/internal/settings"
) )
type Server interface { type Server interface {
@@ -15,21 +16,23 @@ type Server interface {
} }
type server struct { type server struct {
address string address string
logger logging.Logger logger logging.Logger
restartOpenvpn func() restartOpenvpn func()
restartUnbound func() restartUnbound func()
getPortForwarded func() uint16 getOpenvpnSettings func() settings.OpenVPN
getPortForwarded func() uint16
} }
func New(address string, logger logging.Logger, restartOpenvpn, restartUnbound func(), func New(address string, logger logging.Logger, restartOpenvpn, restartUnbound func(),
getPortForwarded func() uint16) Server { getOpenvpnSettings func() settings.OpenVPN, getPortForwarded func() uint16) Server {
return &server{ return &server{
address: address, address: address,
logger: logger.WithPrefix("http server: "), logger: logger.WithPrefix("http server: "),
restartOpenvpn: restartOpenvpn, restartOpenvpn: restartOpenvpn,
restartUnbound: restartUnbound, restartUnbound: restartUnbound,
getPortForwarded: getPortForwarded, getOpenvpnSettings: getOpenvpnSettings,
getPortForwarded: getPortForwarded,
} }
} }
@@ -66,6 +69,8 @@ func (s *server) makeHandler() http.HandlerFunc {
s.restartUnbound() s.restartUnbound()
case "/openvpn/portforwarded": case "/openvpn/portforwarded":
s.handleGetPortForwarded(w) s.handleGetPortForwarded(w)
case "/openvpn/settings":
s.handleGetOpenvpnSettings(w)
default: default:
routeDoesNotExist(s.logger, w, r) routeDoesNotExist(s.logger, w, r)
} }

View File

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