mirror of
https://github.com/boringproxy/boringproxy.git
synced 2025-02-25 18:55:29 -06:00
Store full tunnel information in db
Now have a single Tunnel type which is returned on creation and when querying the current tunnels.
This commit is contained in:
35
api.go
35
api.go
@@ -1,12 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
//"strings"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"os/user"
|
||||
)
|
||||
|
||||
type Api struct {
|
||||
@@ -16,14 +13,6 @@ type Api struct {
|
||||
mux *http.ServeMux
|
||||
}
|
||||
|
||||
type CreateTunnelResponse struct {
|
||||
ServerAddress string `json:"server_address"`
|
||||
ServerPort int `json:"server_port"`
|
||||
ServerPublicKey string `json:"server_public_key"`
|
||||
Username string `json:"username"`
|
||||
TunnelPort int `json:"tunnel_port"`
|
||||
TunnelPrivateKey string `json:"tunnel_private_key"`
|
||||
}
|
||||
|
||||
func NewApi(config *BoringProxyConfig, auth *Auth, tunMan *TunnelManager) *Api {
|
||||
|
||||
@@ -72,37 +61,21 @@ func (a *Api) handleCreateTunnel(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
domain := query["domain"][0]
|
||||
|
||||
port, privKey, err := a.tunMan.CreateTunnel(domain)
|
||||
tunnel, err := a.tunMan.CreateTunnel(domain)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
io.WriteString(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
user, err := user.Current()
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
io.WriteString(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response := &CreateTunnelResponse{
|
||||
ServerAddress: a.config.AdminDomain,
|
||||
ServerPort: 22,
|
||||
ServerPublicKey: "",
|
||||
TunnelPort: port,
|
||||
TunnelPrivateKey: privKey,
|
||||
Username: user.Username,
|
||||
}
|
||||
|
||||
responseJson, err := json.MarshalIndent(response, "", " ")
|
||||
tunnelJson, err := json.MarshalIndent(tunnel, "", " ")
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
io.WriteString(w, "Error encoding response")
|
||||
io.WriteString(w, "Error encoding tunnel")
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(responseJson)
|
||||
w.Write(tunnelJson)
|
||||
}
|
||||
|
||||
func (a *Api) handleDeleteTunnel(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -56,7 +56,7 @@ func Listen() {
|
||||
//certmagic.DefaultACME.CA = certmagic.LetsEncryptStagingCA
|
||||
certConfig := certmagic.NewDefault()
|
||||
|
||||
tunMan := NewTunnelManager(db, certConfig)
|
||||
tunMan := NewTunnelManager(config, db, certConfig)
|
||||
|
||||
err = certConfig.ManageSync([]string{config.AdminDomain})
|
||||
if err != nil {
|
||||
|
||||
12
client.go
12
client.go
@@ -55,14 +55,14 @@ func (c *BoringProxyClient) Run() {
|
||||
log.Fatal("Failed to create tunnel: " + string(body))
|
||||
}
|
||||
|
||||
createTunnelResponse := &CreateTunnelResponse{}
|
||||
tunnel := &Tunnel{}
|
||||
|
||||
err = json.Unmarshal(body, &createTunnelResponse)
|
||||
err = json.Unmarshal(body, &tunnel)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to parse response", err)
|
||||
}
|
||||
|
||||
signer, err := ssh.ParsePrivateKey([]byte(createTunnelResponse.TunnelPrivateKey))
|
||||
signer, err := ssh.ParsePrivateKey([]byte(tunnel.TunnelPrivateKey))
|
||||
if err != nil {
|
||||
log.Fatalf("unable to parse private key: %v", err)
|
||||
}
|
||||
@@ -70,7 +70,7 @@ func (c *BoringProxyClient) Run() {
|
||||
//var hostKey ssh.PublicKey
|
||||
|
||||
config := &ssh.ClientConfig{
|
||||
User: createTunnelResponse.Username,
|
||||
User: tunnel.Username,
|
||||
Auth: []ssh.AuthMethod{
|
||||
ssh.PublicKeys(signer),
|
||||
},
|
||||
@@ -78,14 +78,14 @@ func (c *BoringProxyClient) Run() {
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||
}
|
||||
|
||||
sshHost := fmt.Sprintf("%s:%d", createTunnelResponse.ServerAddress, createTunnelResponse.ServerPort)
|
||||
sshHost := fmt.Sprintf("%s:%d", tunnel.ServerAddress, tunnel.ServerPort)
|
||||
client, err := ssh.Dial("tcp", sshHost, config)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to dial: ", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
tunnelAddr := fmt.Sprintf("127.0.0.1:%d", createTunnelResponse.TunnelPort)
|
||||
tunnelAddr := fmt.Sprintf("127.0.0.1:%d", tunnel.TunnelPort)
|
||||
l, err := client.Listen("tcp", tunnelAddr)
|
||||
if err != nil {
|
||||
log.Fatal("unable to register tcp forward: ", err)
|
||||
|
||||
@@ -18,9 +18,14 @@ type Session struct {
|
||||
}
|
||||
|
||||
type Tunnel struct {
|
||||
Port int `json:"port"`
|
||||
ServerAddress string `json:"server_address"`
|
||||
ServerPort int `json:"server_port"`
|
||||
ServerPublicKey string `json:"server_public_key"`
|
||||
Username string `json:"username"`
|
||||
TunnelPort int `json:"tunnel_port"`
|
||||
TunnelPrivateKey string `json:"tunnel_private_key"`
|
||||
}
|
||||
type Tunnels map[string]*Tunnel
|
||||
|
||||
|
||||
func NewDatabase() (*Database, error) {
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
)
|
||||
|
||||
type TunnelManager struct {
|
||||
config *BoringProxyConfig
|
||||
db *Database
|
||||
nextPort int
|
||||
mutex *sync.Mutex
|
||||
@@ -24,7 +25,7 @@ type TunnelManager struct {
|
||||
user *user.User
|
||||
}
|
||||
|
||||
func NewTunnelManager(db *Database, certConfig *certmagic.Config) *TunnelManager {
|
||||
func NewTunnelManager(config *BoringProxyConfig, db *Database, certConfig *certmagic.Config) *TunnelManager {
|
||||
|
||||
user, err := user.Current()
|
||||
if err != nil {
|
||||
@@ -42,13 +43,14 @@ func NewTunnelManager(db *Database, certConfig *certmagic.Config) *TunnelManager
|
||||
nextPort := 9001
|
||||
|
||||
mutex := &sync.Mutex{}
|
||||
return &TunnelManager{db, nextPort, mutex, certConfig, user}
|
||||
return &TunnelManager{config, db, nextPort, mutex, certConfig, user}
|
||||
}
|
||||
|
||||
func (m *TunnelManager) GetTunnels() map[string]Tunnel {
|
||||
return m.db.GetTunnels()
|
||||
}
|
||||
|
||||
// TODO: Update this
|
||||
func (m *TunnelManager) SetTunnel(host string, port int) error {
|
||||
err := m.certConfig.ManageSync([]string{host})
|
||||
if err != nil {
|
||||
@@ -56,17 +58,17 @@ func (m *TunnelManager) SetTunnel(host string, port int) error {
|
||||
return errors.New("Failed to get cert")
|
||||
}
|
||||
|
||||
tunnel := Tunnel{port}
|
||||
tunnel := Tunnel{TunnelPort: port}
|
||||
m.db.SetTunnel(host, tunnel)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TunnelManager) CreateTunnel(domain string) (int, string, error) {
|
||||
func (m *TunnelManager) CreateTunnel(domain string) (Tunnel, error) {
|
||||
err := m.certConfig.ManageSync([]string{domain})
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return 0, "", errors.New("Failed to get cert")
|
||||
return Tunnel{}, errors.New("Failed to get cert")
|
||||
}
|
||||
|
||||
m.mutex.Lock()
|
||||
@@ -74,20 +76,29 @@ func (m *TunnelManager) CreateTunnel(domain string) (int, string, error) {
|
||||
|
||||
_, exists := m.db.GetTunnel(domain)
|
||||
if exists {
|
||||
return 0, "", errors.New("Tunnel exists for domain " + domain)
|
||||
return Tunnel{}, errors.New("Tunnel exists for domain " + domain)
|
||||
}
|
||||
|
||||
port := m.nextPort
|
||||
m.nextPort += 1
|
||||
tunnel := Tunnel{port}
|
||||
m.db.SetTunnel(domain, tunnel)
|
||||
|
||||
privKey, err := m.addToAuthorizedKeys(domain, port)
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
return Tunnel{}, err
|
||||
}
|
||||
|
||||
return port, privKey, nil
|
||||
tunnel := Tunnel{
|
||||
ServerAddress: m.config.AdminDomain,
|
||||
ServerPort: 22,
|
||||
ServerPublicKey: "",
|
||||
TunnelPort: port,
|
||||
TunnelPrivateKey: privKey,
|
||||
Username: m.user.Username,
|
||||
}
|
||||
|
||||
m.db.SetTunnel(domain, tunnel)
|
||||
|
||||
return tunnel, nil
|
||||
}
|
||||
|
||||
func (m *TunnelManager) DeleteTunnel(domain string) error {
|
||||
@@ -112,7 +123,7 @@ func (m *TunnelManager) DeleteTunnel(domain string) error {
|
||||
|
||||
lines := strings.Split(akStr, "\n")
|
||||
|
||||
tunnelId := fmt.Sprintf("boringproxy-%s-%d", domain, tunnel.Port)
|
||||
tunnelId := fmt.Sprintf("boringproxy-%s-%d", domain, tunnel.TunnelPort)
|
||||
|
||||
outLines := []string{}
|
||||
|
||||
@@ -141,7 +152,7 @@ func (m *TunnelManager) GetPort(domain string) (int, error) {
|
||||
return 0, errors.New("Doesn't exist")
|
||||
}
|
||||
|
||||
return tunnel.Port, nil
|
||||
return tunnel.TunnelPort, nil
|
||||
}
|
||||
|
||||
func (m *TunnelManager) addToAuthorizedKeys(domain string, port int) (string, error) {
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
{{range $domain, $tunnel:= .}}
|
||||
<div class='tunnel'>
|
||||
<div>
|
||||
<a href="https://{{$domain}}">{{$domain}}</a> -> {{$tunnel.Port}}
|
||||
<a href="https://{{$domain}}">{{$domain}}</a> -> {{$tunnel.TunnelPort}}
|
||||
</div>
|
||||
<a href="/delete-tunnel?host={{$domain}}">Delete</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user