telebit/cmd/telebitd/telebitd.go

170 lines
4.6 KiB
Go
Raw Normal View History

package main
import (
2017-03-22 21:43:36 +00:00
"context"
"crypto/tls"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
2020-04-30 10:43:36 +00:00
"net/http"
"os"
2020-04-30 10:43:36 +00:00
telebit "git.coolaj86.com/coolaj86/go-telebitd"
"git.coolaj86.com/coolaj86/go-telebitd/relay"
"git.coolaj86.com/coolaj86/go-telebitd/server"
jwt "github.com/dgrijalva/jwt-go"
"github.com/spf13/viper"
lumberjack "gopkg.in/natefinch/lumberjack.v2"
2020-04-30 10:43:36 +00:00
_ "github.com/joho/godotenv/autoload"
)
var (
logfile = "stdout"
configPath = "./"
2020-04-30 10:43:36 +00:00
configFile = "telebit-relay"
loginfo *log.Logger
logdebug *log.Logger
logFlags = log.Ldate | log.Lmicroseconds | log.Lshortfile
argWssClientListener string
2020-04-30 10:43:36 +00:00
tcpPort int
argServerBinding string
argServerAdminBinding string
argServerExternalBinding string
argDeadTime int
2017-04-01 04:31:16 +00:00
connectionTable *server.Table
2020-04-30 10:43:36 +00:00
secretKey string
2020-04-28 06:26:00 +00:00
wssHostName = "localhost.rootprojects.org"
2020-04-28 07:16:16 +00:00
adminHostName = telebit.InvalidAdminDomain
idle int
dwell int
cancelcheck int
lbDefaultMethod string
2020-04-30 10:43:36 +00:00
nickname string
)
func init() {
flag.StringVar(&logfile, "log", logfile, "Log file (or stdout/stderr; empty for none)")
flag.StringVar(&configPath, "config-path", configPath, "Configuration File Path")
2020-04-30 10:43:36 +00:00
flag.StringVar(&secretKey, "secret", "", "a >= 16-character random string for JWT key signing")
}
var logoutput io.Writer
//Main -- main entry point
func main() {
flag.Parse()
2020-04-30 10:43:36 +00:00
if "" == secretKey {
secretKey = os.Getenv("TELEBIT_SECRET")
}
if len(secretKey) < 16 {
fmt.Fprintf(os.Stderr, "Invalid secret: %q. See --help for details.\n", secretKey)
os.Exit(1)
}
switch logfile {
case "stdout":
logoutput = os.Stdout
case "stderr":
logoutput = os.Stderr
case "":
logoutput = ioutil.Discard
default:
logoutput = &lumberjack.Logger{
Filename: logfile,
MaxSize: 100,
MaxAge: 120,
MaxBackups: 10,
}
}
// send the output io.Writing to the other packages
2017-04-01 04:31:16 +00:00
server.InitLogging(logoutput)
loginfo = log.New(logoutput, "INFO: main: ", logFlags)
logdebug = log.New(logoutput, "DEBUG: main:", logFlags)
viper.SetConfigName(configFile)
viper.AddConfigPath(configPath)
viper.AddConfigPath("./")
err := viper.ReadInConfig()
if err != nil {
panic(fmt.Errorf("fatal error config file: %s", err))
}
flag.IntVar(&argDeadTime, "dead-time-counter", 5, "deadtime counter in seconds")
wssHostName = viper.Get("rvpn.wssdomain").(string)
adminHostName = viper.Get("rvpn.admindomain").(string)
2020-04-30 10:43:36 +00:00
tcpPort = viper.GetInt("rvpn.port")
deadtime := viper.Get("rvpn.deadtime").(map[string]interface{})
idle = deadtime["idle"].(int)
dwell = deadtime["dwell"].(int)
cancelcheck = deadtime["cancelcheck"].(int)
lbDefaultMethod = viper.Get("rvpn.loadbalancing.defaultmethod").(string)
2020-04-30 10:43:36 +00:00
nickname = viper.Get("rvpn.serverName").(string)
loginfo.Println("startup")
ctx, cancelContext := context.WithCancel(context.Background())
defer cancelContext()
2017-04-01 04:31:16 +00:00
serverStatus := server.NewStatus(ctx)
serverStatus.AdminDomain = adminHostName
serverStatus.WssDomain = wssHostName
2020-04-30 10:43:36 +00:00
serverStatus.Name = nickname
2017-04-01 04:31:16 +00:00
serverStatus.DeadTime = server.NewStatusDeadTime(dwell, idle, cancelcheck)
serverStatus.LoadbalanceDefaultMethod = lbDefaultMethod
2020-04-30 10:43:36 +00:00
connectionTable := server.NewTable(dwell, idle, lbDefaultMethod)
tlsConfig := &tls.Config{
GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
// TODO
// 1. call out to greenlock for validation
// 2. push challenges through http channel
// 3. receive certificates (or don't)
certbundle, err := tls.LoadX509KeyPair("certs/fullchain.pem", "certs/privkey.pem")
if err != nil {
return nil, err
}
return &certbundle, nil
},
}
2020-04-30 10:43:36 +00:00
authorizer := func(r *http.Request) (*server.Authz, error) {
// do we have a valid wss_client?
tokenString := r.URL.Query().Get("access_token")
_, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
return nil, err
/*
tokenString := r.URL.Query().Get("access_token")
result, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
if err != nil || !result.Valid {
w.WriteHeader(http.StatusForbidden)
w.Write([]byte("Not Authorized"))
loginfo.Println("access_token invalid...closing connection")
return
}
// TODO
claims := result.Claims.(jwt.MapClaims)
domains, ok := claims["domains"].([]interface{})
*/
2020-04-30 10:43:36 +00:00
}
2020-04-30 10:43:36 +00:00
r := relay.New(ctx, tlsConfig, authorizer, serverStatus, connectionTable)
r.ListenAndServe(tcpPort)
}