2020-05-27 08:53:26 +00:00
|
|
|
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
dns01 "git.coolaj86.com/coolaj86/go-telebitd/mplexer/dns01"
|
|
|
|
|
|
|
|
jwt "github.com/dgrijalva/jwt-go"
|
|
|
|
"github.com/go-acme/lego/v3/challenge"
|
|
|
|
_ "github.com/joho/godotenv/autoload"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
// GitRev refers to the abbreviated commit hash
|
|
|
|
GitRev = "0000000"
|
|
|
|
// GitVersion refers to the most recent tag, plus any commits made since then
|
|
|
|
GitVersion = "v0.0.0-pre0+0000000"
|
|
|
|
// GitTimestamp refers to the timestamp of the most recent commit
|
|
|
|
GitTimestamp = "0000-00-00T00:00:00+0000"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
var err error
|
|
|
|
var provider challenge.Provider = nil
|
|
|
|
var domains []string
|
|
|
|
|
|
|
|
// TODO replace the websocket connection with a mock server
|
2020-07-17 05:41:04 +00:00
|
|
|
acmeRelay := flag.String("acme-relay-url", "", "the base url of the ACME DNS-01 relay, if not the same as the tunnel relay")
|
2020-05-27 08:53:26 +00:00
|
|
|
secret := flag.String("secret", "", "the same secret used by telebit-relay (used for JWT authentication)")
|
|
|
|
token := flag.String("token", "", "a pre-generated token to give the server (instead of generating one with --secret)")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
if len(os.Args) >= 2 {
|
|
|
|
if "version" == os.Args[1] {
|
|
|
|
fmt.Printf("telebit %s %s %s", GitVersion, GitRev, GitTimestamp)
|
|
|
|
os.Exit(0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if "" == *token {
|
|
|
|
if "" == *secret {
|
|
|
|
*secret = os.Getenv("SECRET")
|
|
|
|
}
|
|
|
|
*token, err = getToken(*secret, domains)
|
|
|
|
}
|
|
|
|
if nil != err {
|
|
|
|
fmt.Fprintf(os.Stderr, "neither secret nor token provided")
|
|
|
|
os.Exit(1)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if "" == *acmeRelay {
|
|
|
|
panic(errors.New("ACME relay should be specified"))
|
|
|
|
}
|
|
|
|
|
|
|
|
endpoint := *acmeRelay
|
|
|
|
if strings.HasSuffix(endpoint, "/") {
|
|
|
|
endpoint = endpoint[:len(endpoint)-1]
|
|
|
|
}
|
|
|
|
endpoint += "/api/dns/"
|
|
|
|
if provider, err = newAPIDNSProvider(endpoint, *token); nil != err {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = provider.Present(os.Getenv("HOSTNAME"), "xxx", "yyy")
|
|
|
|
if nil != err {
|
|
|
|
fmt.Fprintf(os.Stderr, err.Error())
|
|
|
|
}
|
|
|
|
err = provider.Present(os.Getenv("HOSTNAME"), "xxx", "yyy")
|
|
|
|
if nil != err {
|
|
|
|
fmt.Fprintf(os.Stderr, err.Error())
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println("quite possibly successful")
|
|
|
|
}
|
|
|
|
|
|
|
|
// newAPIDNSProvider is for the sake of demoing the tunnel
|
|
|
|
func newAPIDNSProvider(baseURL string, token string) (*dns01.DNSProvider, error) {
|
|
|
|
config := dns01.NewDefaultConfig()
|
|
|
|
config.Token = token
|
|
|
|
endpoint, err := url.Parse(baseURL)
|
|
|
|
if nil != err {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
config.Endpoint = endpoint
|
|
|
|
return dns01.NewDNSProviderConfig(config)
|
|
|
|
}
|
|
|
|
|
|
|
|
func getToken(secret string, domains []string) (token string, err error) {
|
|
|
|
tokenData := jwt.MapClaims{"domains": domains}
|
|
|
|
|
|
|
|
jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, tokenData)
|
|
|
|
if token, err = jwtToken.SignedString([]byte(secret)); err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return token, nil
|
|
|
|
}
|