add --expires-in to signjwt
This commit is contained in:
parent
cfe3820fea
commit
ce39066bc8
31
README.md
31
README.md
|
@ -104,13 +104,22 @@ Copy `examples/mgmt.env` as `.env` in the working directory.
|
|||
Create a token with the same `SECRET` used with the `mgmt` server,
|
||||
and add a device by its `subdomain`.
|
||||
|
||||
To build `signjwt`:
|
||||
|
||||
```bash
|
||||
go build -mod=vendor -ldflags "-s -w" -o signjwt cmd/signjwt/*.go
|
||||
```
|
||||
|
||||
To generate an `admin` token:
|
||||
|
||||
```bash
|
||||
VERDOR_ID="test-id"
|
||||
SECRET="xxxxxxxxxxx"
|
||||
TOKEN=$(go run -mod=vendor cmd/signjwt/*.go \
|
||||
TOKEN=$(./signjwt \
|
||||
--expires-in 15m \
|
||||
--vendor-id $VENDOR_ID \
|
||||
--secret $SECRET \
|
||||
--machine-id $SECRET
|
||||
--machine-ppid $SECRET
|
||||
)
|
||||
```
|
||||
|
||||
|
@ -240,3 +249,21 @@ EOF
|
|||
|
||||
python3 -m http.server 3000
|
||||
```
|
||||
|
||||
## Glossary
|
||||
|
||||
```
|
||||
--vendor-id $VENDOR_ID an arbitrary id used as part of authentication
|
||||
--secret $SECRET the secret for creating JWTs
|
||||
--auth-url $AUTH_URL the full url prefix of the server that will validate tokens
|
||||
--tunnel-relay-url $TUNNEL_RELAY_URL the full url of the websocket tunnel server
|
||||
--locals $LOCALS a list of `scheme:domainname:port`
|
||||
for forwarding incoming `domainname` to local `port`
|
||||
--port-forwards $PORT_FORWARDS a list of `remote:local` tcp port-forwarding
|
||||
--verbose $VERBOSE logs everything, including abbreviated data (as hex)
|
||||
$VERBOSE_BYTES logs full data (as hex)
|
||||
$VERBOSE_RAW logs full data (as string)
|
||||
--acme-agree $ACME_AGREE agree to the ACME service agreement
|
||||
--acme-email $ACME_EMAIL the webmaster email for ACME notices
|
||||
--acme-relay-url $ACME_RELAY_URL the server that will relay ACME DNS-01 requests
|
||||
```
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"git.coolaj86.com/coolaj86/go-telebitd/mgmt/authstore"
|
||||
telebit "git.coolaj86.com/coolaj86/go-telebitd/mplexer"
|
||||
|
@ -16,6 +17,15 @@ import (
|
|||
_ "github.com/joho/godotenv/autoload"
|
||||
)
|
||||
|
||||
var durAbbrs = map[byte]bool{
|
||||
's': true, // second
|
||||
'm': true, // minute
|
||||
'h': true, // hour
|
||||
'd': true, // day
|
||||
'w': true, // week
|
||||
// month and year cannot be measured
|
||||
}
|
||||
|
||||
func main() {
|
||||
var secret, clientSecret, relaySecret string
|
||||
|
||||
|
@ -23,6 +33,7 @@ func main() {
|
|||
machineID := flag.String("machine-id", "", "spoof the raw machine id")
|
||||
vendorID := flag.String("vendor-id", "", "a unique identifier for a deploy target environment")
|
||||
authURL := flag.String("auth-url", "", "the base url for authentication, if not the same as the tunnel relay")
|
||||
humanExp := flag.String("expires-in", "15m", "set the token to expire <x> units after `iat` (issued at)")
|
||||
getMachinePPID := flag.Bool("machine-ppid-only", false, "just print the machine ppid, not the token")
|
||||
flag.StringVar(&secret, "secret", "", "either the remote server or the tunnel relay secret (used for JWT authentication)")
|
||||
flag.Parse()
|
||||
|
@ -31,6 +42,34 @@ func main() {
|
|||
*authURL = os.Getenv("AUTH_URL")
|
||||
}
|
||||
|
||||
humanExpLen := len(*humanExp)
|
||||
if 0 == humanExpLen {
|
||||
fmt.Fprintf(os.Stderr, "Invalid --expires-in: %q (minimum: 5s)", *humanExp)
|
||||
}
|
||||
expNum, _ := strconv.Atoi((*humanExp)[:humanExpLen-1])
|
||||
expSuffix := (*humanExp)[humanExpLen-1:]
|
||||
switch expSuffix {
|
||||
case "w":
|
||||
expNum *= 7
|
||||
fallthrough
|
||||
case "d":
|
||||
expNum *= 24
|
||||
fallthrough
|
||||
case "h":
|
||||
expNum *= 60
|
||||
fallthrough
|
||||
case "m":
|
||||
expNum *= 60
|
||||
fallthrough
|
||||
case "s":
|
||||
// do nothing
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Invalid --expires-in: %q (minimum: 5s)", *humanExp)
|
||||
}
|
||||
if expNum < 5 {
|
||||
fmt.Fprintf(os.Stderr, "Invalid --expires-in: %q (minimum: 5s)", *humanExp)
|
||||
}
|
||||
|
||||
if 0 == len(*vendorID) {
|
||||
*vendorID = os.Getenv("VENDOR_ID")
|
||||
}
|
||||
|
@ -99,7 +138,7 @@ func main() {
|
|||
fmt.Fprintf(os.Stderr, "[debug] ppid = %s\n", ppid)
|
||||
fmt.Fprintf(os.Stderr, "[debug] pub = %s\n", pub)
|
||||
|
||||
tok, err := authstore.HMACToken(ppid)
|
||||
tok, err := authstore.HMACToken(ppid, expNum)
|
||||
if nil != err {
|
||||
fmt.Fprintf(os.Stderr, "signing error: %s\n", err)
|
||||
os.Exit(1)
|
||||
|
|
|
@ -14,6 +14,7 @@ AUTH_URL="${AUTH_URL:-"http://localhost:3000/api"}"
|
|||
|
||||
echo "RELAY_SECRET: $RELAY_SECRET"
|
||||
TOKEN=$(go run cmd/signjwt/*.go \
|
||||
--expires-in 1m \
|
||||
--vendor-id "$VENDOR_ID" \
|
||||
--secret "$RELAY_SECRET" \
|
||||
--machine-ppid "$RELAY_SECRET"
|
||||
|
|
|
@ -51,12 +51,19 @@ func ToPublicKeyString(secret string) string {
|
|||
return pub
|
||||
}
|
||||
|
||||
func HMACToken(secret string) (token string, err error) {
|
||||
func HMACToken(secret string, maybeExp ...int) (token string, err error) {
|
||||
keyID := ToPublicKeyString(secret)
|
||||
if dbg.Debug {
|
||||
fmt.Fprintf(os.Stderr, "[debug] keyID=%s\n", keyID)
|
||||
}
|
||||
|
||||
var exp int64
|
||||
if 0 == len(maybeExp) || 0 == maybeExp[0] {
|
||||
exp = time.Now().Add(5 * time.Minute).Unix()
|
||||
} else {
|
||||
exp = time.Now().Add(time.Duration(maybeExp[0]) * time.Second).Unix()
|
||||
}
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, _ = rand.Read(b)
|
||||
claims := &jwt.StandardClaims{
|
||||
|
@ -64,7 +71,7 @@ func HMACToken(secret string) (token string, err error) {
|
|||
Subject: "", // TODO
|
||||
Issuer: "", // TODO
|
||||
IssuedAt: time.Now().Unix(),
|
||||
ExpiresAt: time.Now().Add(5 * time.Minute).Unix(),
|
||||
ExpiresAt: exp,
|
||||
}
|
||||
|
||||
jwtToken := &jwt.Token{
|
||||
|
|
Loading…
Reference in New Issue