add system service
This commit is contained in:
parent
5deeab6fe2
commit
1635cbad9b
|
@ -34,6 +34,7 @@ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -mod vendor -ldflags "-H window
|
||||||
```
|
```
|
||||||
|
|
||||||
The binary can be built with `VENDOR_ID` and `CLIENT_SECRET` built into the binary.
|
The binary can be built with `VENDOR_ID` and `CLIENT_SECRET` built into the binary.
|
||||||
|
You can also change the `serviceName` and `serviceDescription` at build time.
|
||||||
See `examples/run-as-client.sh`.
|
See `examples/run-as-client.sh`.
|
||||||
|
|
||||||
### Configure
|
### Configure
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"git.rootprojects.org/root/telebit/dbg"
|
"git.rootprojects.org/root/telebit/dbg"
|
||||||
tbDns01 "git.rootprojects.org/root/telebit/internal/dns01"
|
tbDns01 "git.rootprojects.org/root/telebit/internal/dns01"
|
||||||
"git.rootprojects.org/root/telebit/internal/http01"
|
"git.rootprojects.org/root/telebit/internal/http01"
|
||||||
|
"git.rootprojects.org/root/telebit/internal/service"
|
||||||
"git.rootprojects.org/root/telebit/iplist"
|
"git.rootprojects.org/root/telebit/iplist"
|
||||||
"git.rootprojects.org/root/telebit/mgmt"
|
"git.rootprojects.org/root/telebit/mgmt"
|
||||||
"git.rootprojects.org/root/telebit/mgmt/authstore"
|
"git.rootprojects.org/root/telebit/mgmt/authstore"
|
||||||
|
@ -61,8 +62,15 @@ var (
|
||||||
GitVersion = "v0.0.0-pre0+0000000"
|
GitVersion = "v0.0.0-pre0+0000000"
|
||||||
// GitTimestamp refers to the timestamp of the most recent commit
|
// GitTimestamp refers to the timestamp of the most recent commit
|
||||||
GitTimestamp = "0000-00-00T00:00:00+0000"
|
GitTimestamp = "0000-00-00T00:00:00+0000"
|
||||||
|
|
||||||
|
// serviceName is the service name
|
||||||
|
serviceName = "telebit"
|
||||||
|
|
||||||
|
// serviceDesc
|
||||||
|
serviceDesc = "securely relay traffic through telebit.io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Forward describes how to route a network connection
|
||||||
type Forward struct {
|
type Forward struct {
|
||||||
scheme string
|
scheme string
|
||||||
pattern string
|
pattern string
|
||||||
|
@ -81,6 +89,23 @@ var VendorID string
|
||||||
var ClientSecret string
|
var ClientSecret string
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
if len(os.Args) >= 2 {
|
||||||
|
if "version" == strings.TrimLeft(os.Args[1], "-") {
|
||||||
|
fmt.Printf("telebit %s (%s) %s\n", GitVersion, GitRev[:7], GitTimestamp)
|
||||||
|
os.Exit(exitOk)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(os.Args) >= 2 {
|
||||||
|
if "install" == os.Args[1] {
|
||||||
|
if err := service.Install(); nil != err {
|
||||||
|
fmt.Fprintf(os.Stderr, "%v", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var domains []string
|
var domains []string
|
||||||
var forwards []Forward
|
var forwards []Forward
|
||||||
var portForwards []Forward
|
var portForwards []Forward
|
||||||
|
@ -126,13 +151,6 @@ func main() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(os.Args) >= 2 {
|
|
||||||
if "version" == os.Args[1] {
|
|
||||||
fmt.Printf("telebit %s %s %s\n", GitVersion, GitRev[:7], GitTimestamp)
|
|
||||||
os.Exit(exitOk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(*acmeDirectory) > 0 {
|
if len(*acmeDirectory) > 0 {
|
||||||
if *acmeStaging {
|
if *acmeStaging {
|
||||||
fmt.Fprintf(os.Stderr, "pick either acme-directory or acme-staging\n")
|
fmt.Fprintf(os.Stderr, "pick either acme-directory or acme-staging\n")
|
||||||
|
@ -829,19 +847,6 @@ func getACMEProvider(acmeRelay, token *string) (challenge.Provider, error) {
|
||||||
return provider, nil
|
return provider, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ACMEProvider struct {
|
|
||||||
BaseURL string
|
|
||||||
provider challenge.Provider
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ACMEProvider) Present(domain, token, keyAuth string) error {
|
|
||||||
return p.provider.Present(domain, token, keyAuth)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ACMEProvider) CleanUp(domain, token, keyAuth string) error {
|
|
||||||
return p.provider.CleanUp(domain, token, keyAuth)
|
|
||||||
}
|
|
||||||
|
|
||||||
// newDuckDNSProvider is for the sake of demoing the tunnel
|
// newDuckDNSProvider is for the sake of demoing the tunnel
|
||||||
func newDuckDNSProvider(token string) (*duckdns.DNSProvider, error) {
|
func newDuckDNSProvider(token string) (*duckdns.DNSProvider, error) {
|
||||||
config := duckdns.NewDefaultConfig()
|
config := duckdns.NewDefaultConfig()
|
||||||
|
|
|
@ -9,7 +9,7 @@ source .env
|
||||||
VENDOR_ID="${VENDOR_ID:-"${VENDOR_ID:-"test-id"}"}"
|
VENDOR_ID="${VENDOR_ID:-"${VENDOR_ID:-"test-id"}"}"
|
||||||
CLIENT_SECRET="${CLIENT_SECRET:-}"
|
CLIENT_SECRET="${CLIENT_SECRET:-}"
|
||||||
#go build -mod=vendor -o ./telebit \
|
#go build -mod=vendor -o ./telebit \
|
||||||
# -ldflags="-X 'main.VendorID=$VENDOR_ID' -X 'main.ClientSecret=$CLIENT_SECRET'" \
|
# -ldflags="-X 'main.VendorID=$VENDOR_ID' -X 'main.ClientSecret=$CLIENT_SECRET' -X 'main.serviceName=telebit' -X 'main.serviceDesc=securely tunnel through telebit.io'" \
|
||||||
# cmd/telebit/*.go
|
# cmd/telebit/*.go
|
||||||
go build -mod=vendor -o telebit \
|
go build -mod=vendor -o telebit \
|
||||||
cmd/telebit/*.go
|
cmd/telebit/*.go
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -21,7 +21,7 @@ require (
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.6.1
|
||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
|
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae
|
||||||
golang.org/x/text v0.3.3 // indirect
|
golang.org/x/text v0.3.3 // indirect
|
||||||
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f // indirect
|
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Install ensures a systemd service is active
|
||||||
|
func Install() error {
|
||||||
|
return errors.New("'install' not supported for system services on this platform")
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
// +build !darwin,!linux,!windows
|
||||||
|
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Install ensures a windows service is active
|
||||||
|
func Install() error {
|
||||||
|
return errors.New("not supported for system services on this platform")
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows/svc/eventlog"
|
||||||
|
"golang.org/x/sys/windows/svc/mgr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Install ensures a windows service is active
|
||||||
|
func Install(name, desc string) error {
|
||||||
|
exepath, err := getExecPath(os.Args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return installService(name, desc, exepath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getExecPath(exepath string) (string, error) {
|
||||||
|
p, err := filepath.Abs(exepath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
fi, err := os.Stat(p)
|
||||||
|
if err == nil {
|
||||||
|
if fi.Mode().IsRegular() {
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == len(filepath.Ext(p)) {
|
||||||
|
var err error
|
||||||
|
p += ".exe"
|
||||||
|
fi, err = os.Stat(p)
|
||||||
|
if nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !fi.Mode().IsRegular() {
|
||||||
|
// this should never happen
|
||||||
|
return "", errors.New("not a regular file")
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func install(name, desc, exepath string) error {
|
||||||
|
m, err := mgr.Connect()
|
||||||
|
if nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer m.Disconnect()
|
||||||
|
|
||||||
|
s, err := m.OpenService(name)
|
||||||
|
if nil == err {
|
||||||
|
s.Close()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: desc}, "is", "auto-started")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info)
|
||||||
|
if nil != err {
|
||||||
|
s.Delete()
|
||||||
|
return fmt.Errorf("could not install system service: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Install ensures a systemd service is active
|
||||||
|
func Install() error {
|
||||||
|
return errors.New("'install' not supported for system services on this platform")
|
||||||
|
}
|
|
@ -162,6 +162,9 @@ golang.org/x/sys/internal/unsafeheader
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
golang.org/x/sys/windows/registry
|
golang.org/x/sys/windows/registry
|
||||||
|
golang.org/x/sys/windows/svc
|
||||||
|
golang.org/x/sys/windows/svc/eventlog
|
||||||
|
golang.org/x/sys/windows/svc/mgr
|
||||||
# golang.org/x/text v0.3.3
|
# golang.org/x/text v0.3.3
|
||||||
## explicit
|
## explicit
|
||||||
golang.org/x/text/secure/bidirule
|
golang.org/x/text/secure/bidirule
|
||||||
|
|
Loading…
Reference in New Issue