Openvpn get settings http route
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
41
internal/models/alias_test.go
Normal file
41
internal/models/alias_test.go
Normal 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)
|
||||||
|
}
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
27
internal/settings/openvpn_test.go
Normal file
27
internal/settings/openvpn_test.go
Normal 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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user