Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ENV options with refactor Config load #29

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,24 @@ Alternatively, you can run in simple mode, with .adnl domain, if you don't have

Now anyone can access your TON Site! Using ADNL address or domain.

If you want to change some settings, like proxy pass url - open `config.json` file, edit and restart proxy. Default proxy pass url is `http://127.0.0.1:80/`
If you want to change some settings, like proxy pass url - open `config.json` file, edit and restart proxy.

Proxy adds additional headers:
`X-Adnl-Ip` - ip of client, and `X-Adnl-Id` - adnl id of client

If you want to change some settings, like proxy pass url - open `config.json` file, edit and restart proxy.
Or use ENV variables:
- `GLOBAL_CONFIG_URL` (default: https://ton.org/global.config.json)
- `EXTERNAL_IP` (default: detect via http://ip-api.com/json/)
- `LISTEN_IP` (default: 0.0.0.0)
- `LISTEN_PORT` (default: 9000 + rand)
- `PROXY_PASS` (default: http://127.0.0.1:80)
- `PRIVATE_KEY` (default: generate and write to `config.json`, is env not passed. It can be used on first start to generate Private Key )

ENV's, has priority over `config.json` and can be useful to run reverse-proxy in Docker container.

*Using `PRIVATE_KEY` is more safety then store key in file and recommended for production.

### FAQ

#### Can I have multiple domains on single reverse-proxy?
Expand Down
86 changes: 72 additions & 14 deletions cmd/proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"flag"
"fmt"
"github.com/mdp/qrterminal/v3"
Expand All @@ -27,6 +28,7 @@ import (
"net/http/httputil"
"net/url"
"os"
"strconv"
"time"
)

Expand Down Expand Up @@ -177,31 +179,91 @@ func getPublicIP() (string, error) {
return ip.Query, nil
}

func getEnvValue(envName string) (string, error) {
var value = os.Getenv(envName)
if value != "" {
return value, nil
} else {
return "", errors.New("environment variable " + envName + " not found")
}
}

func loadConfig() (*Config, error) {
var cfg Config
var envValue string
var saveRequire = false

file := "./config.json"
data, err := os.ReadFile(file)
if err != nil {
var srvKey ed25519.PrivateKey
_, srvKey, err = ed25519.GenerateKey(nil)
saveRequire = true
} else {
err = json.Unmarshal(data, &cfg)
if err != nil {
return nil, err
}
cfg.PrivateKey = srvKey.Seed()
}

//defaults with env priority
envValue, err = getEnvValue("GLOBAL_CONFIG_URL")
if err == nil {
cfg.NetworkConfigURL = envValue
} else if cfg.NetworkConfigURL == "" {
cfg.NetworkConfigURL = "https://ton.org/global.config.json"
}

cfg.ExternalIP, err = getPublicIP()
envValue, err = getEnvValue("EXTERNAL_IP")
if err == nil {
cfg.ExternalIP = envValue
} else if cfg.ExternalIP == "" {
var publicIP, err = getPublicIP()
if err != nil {
return nil, err
}
cfg.ExternalIP = publicIP
}

envValue, err = getEnvValue("LISTEN_IP")
if err == nil {
cfg.ListenIP = envValue
} else if cfg.ListenIP == "" {
cfg.ListenIP = "0.0.0.0"
}

envValue, err = getEnvValue("LISTEN_PORT")
if err == nil {
value, err := strconv.ParseUint(envValue, 10, 16)
if err != nil {
return nil, err
}
cfg.Port = uint16(value)
} else if cfg.Port == 0 {
// generate consistent port
cfg.Port = 9000 + (crc16.Checksum([]byte(cfg.ExternalIP), crc16.MakeTable(crc16.CRC16_XMODEM)) % 5000)
}

envValue, err = getEnvValue("PROXY_PASS")
if err == nil {
cfg.ProxyPass = envValue
} else if cfg.ProxyPass == "" {
cfg.ProxyPass = "http://127.0.0.1:80/"
}

var envPrivateKey string
envPrivateKey, err = getEnvValue("PRIVATE_KEY")
if err != nil {
log.Println("Warning: Store PrivateKey in config.json is unsafe! Use PRIVATE_KEY env instead.")
if cfg.PrivateKey == nil {
var srvKey ed25519.PrivateKey
_, srvKey, err = ed25519.GenerateKey(nil)
if err != nil {
return nil, err
}
cfg.PrivateKey = srvKey.Seed()
}
}

if saveRequire {
data, err = json.MarshalIndent(cfg, "", "\t")
if err != nil {
return nil, err
Expand All @@ -211,18 +273,14 @@ func loadConfig() (*Config, error) {
if err != nil {
return nil, err
}

return &cfg, nil
}

err = json.Unmarshal(data, &cfg)
if err != nil {
return nil, err
}

// backwards compatibility with old configs
if cfg.NetworkConfigURL == "" {
cfg.NetworkConfigURL = "https://ton.org/global.config.json"
//envPrivateKey must stay secret
if envPrivateKey != "" {
cfg.PrivateKey, err = base64.StdEncoding.DecodeString(envPrivateKey)
if err != nil {
return nil, err
}
}

return &cfg, nil
Expand Down