diff --git a/cmd/main.go b/cmd/main.go index 71407a5e..ca361933 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -57,8 +57,11 @@ func main() { e.FatalOnError(err) logger.Info(allSettings.String()) - err = ovpnConf.CheckTUN() - e.FatalOnError(err) + if err := ovpnConf.CheckTUN(); err != nil { + logger.Warn(err) + err = ovpnConf.CreateTUN() + e.FatalOnError(err) + } err = ovpnConf.WriteAuthFile(allSettings.PIA.User, allSettings.PIA.Password, uid, gid) e.FatalOnError(err) diff --git a/internal/openvpn/openvpn.go b/internal/openvpn/openvpn.go index c7bfa141..ee3d4730 100644 --- a/internal/openvpn/openvpn.go +++ b/internal/openvpn/openvpn.go @@ -7,6 +7,7 @@ import ( "github.com/qdm12/golibs/command" "github.com/qdm12/golibs/files" "github.com/qdm12/golibs/logging" + "golang.org/x/sys/unix" ) const logPrefix = "openvpn configurator" @@ -15,6 +16,7 @@ type Configurator interface { Version() (string, error) WriteAuthFile(user, password string, uid, gid int) error CheckTUN() error + CreateTUN() error Start() (stdout io.ReadCloser, err error) } @@ -23,6 +25,8 @@ type configurator struct { logger logging.Logger commander command.Commander openFile func(name string, flag int, perm os.FileMode) (*os.File, error) + mkDev func(major uint32, minor uint32) uint64 + mkNod func(path string, mode uint32, dev int) error } func NewConfigurator(logger logging.Logger, fileManager files.FileManager) Configurator { @@ -31,5 +35,7 @@ func NewConfigurator(logger logging.Logger, fileManager files.FileManager) Confi logger: logger, commander: command.NewCommander(), openFile: os.OpenFile, + mkDev: unix.Mkdev, + mkNod: unix.Mknod, } } diff --git a/internal/openvpn/tun.go b/internal/openvpn/tun.go index 5ccf7d39..a2a5f7d6 100644 --- a/internal/openvpn/tun.go +++ b/internal/openvpn/tun.go @@ -5,6 +5,7 @@ import ( "os" "github.com/qdm12/private-internet-access-docker/internal/constants" + "golang.org/x/sys/unix" ) // CheckTUN checks the tunnel device is present and accessible @@ -19,3 +20,18 @@ func (c *configurator) CheckTUN() error { } return nil } + +func (c *configurator) CreateTUN() error { + c.logger.Info("%s: creating %s", logPrefix, constants.TunnelDevice) + if err := c.fileManager.CreateDir("/dev/net"); err != nil { + return err + } + dev := c.mkDev(10, 200) + if err := c.mkNod(string(constants.TunnelDevice), unix.S_IFCHR, int(dev)); err != nil { + return err + } + if err := c.fileManager.SetUserPermissions(string(constants.TunnelDevice), 666); err != nil { + return err + } + return nil +}