aboutsummaryrefslogtreecommitdiffstats
path: root/api/handlers
diff options
context:
space:
mode:
authorLeonardo Bishop <me@leonardobishop.com>2025-02-06 15:22:34 +0000
committerLeonardo Bishop <me@leonardobishop.com>2025-02-06 15:22:34 +0000
commit2475f5a8b92ef0dd28e7af5f36d01b25243ed778 (patch)
tree12f8931d241db4159f8d30f7bf2b648709a94166 /api/handlers
Initial commit
Diffstat (limited to 'api/handlers')
-rw-r--r--api/handlers/index.go22
-rw-r--r--api/handlers/peer.go75
-rw-r--r--api/handlers/reverseProxy.go35
3 files changed, 132 insertions, 0 deletions
diff --git a/api/handlers/index.go b/api/handlers/index.go
new file mode 100644
index 0000000..c165f3b
--- /dev/null
+++ b/api/handlers/index.go
@@ -0,0 +1,22 @@
+package handlers
+
+import (
+ "net/http"
+
+ "github.com/LMBishop/gunnel/pkg/config"
+ "github.com/LMBishop/gunnel/web"
+)
+
+func Index(configService config.Service) func(http.ResponseWriter, *http.Request) {
+ return func(w http.ResponseWriter, r *http.Request) {
+ web.Index().Execute(w, struct {
+ Host string
+ ExpireAfter int
+ Iface string
+ }{
+ Host: configService.Config().Hostname,
+ ExpireAfter: configService.Config().ExpireAfter,
+ Iface: configService.Config().WireGuard.InterfaceName,
+ })
+ }
+}
diff --git a/api/handlers/peer.go b/api/handlers/peer.go
new file mode 100644
index 0000000..51fa047
--- /dev/null
+++ b/api/handlers/peer.go
@@ -0,0 +1,75 @@
+package handlers
+
+import (
+ "fmt"
+ "log/slog"
+ "net/http"
+
+ "github.com/LMBishop/gunnel/pkg/config"
+ "github.com/LMBishop/gunnel/pkg/store"
+ "github.com/LMBishop/gunnel/pkg/wireguard"
+ "github.com/gorilla/mux"
+)
+
+const script = `#!/bin/bash
+
+# Your IP address: %s
+# Private key: %s
+# Unique slug: %s
+
+# Run this script as root to set up your client
+
+set -euo pipefail
+
+sudo ip link delete dev %s 2>/dev/null || true
+sudo ip link add %s type wireguard
+sudo ip addr add %s dev %s
+echo "%s" | sudo tee /tmp/tunnel-private > /dev/null
+sudo wg set %s private-key /tmp/tunnel-private
+sudo wg set %s peer %s allowed-ips %s endpoint %s:%s persistent-keepalive 21
+sudo ip link set up dev %s
+sudo ip route add %s dev %s
+
+echo "http://0.0.0.0:%s is now reachable at http://%s.%s"`
+
+func NewPeer(storeService store.Service, wireguardService wireguard.Service, configService config.Service) func(http.ResponseWriter, *http.Request) {
+ return func(w http.ResponseWriter, r *http.Request) {
+ params := mux.Vars(r)
+ port := params["port"]
+
+ peer, err := wireguardService.NewPeer()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ slug := storeService.GetUnusedSlug()
+
+ ipAddr := peer.IPAddr.String()
+
+ storeService.NewForwardingRule(slug, peer, port)
+
+ iface := configService.Config().WireGuard.InterfaceName
+ wireguardPort := configService.Config().WireGuard.Port
+ hostname := configService.Config().Hostname
+ network := configService.Config().WireGuard.Network
+ publicKey := wireguardService.PublicKey()
+
+ slog.Info("new peer", "peer", peer.PrivateKey)
+
+ fmt.Fprintf(w, script,
+ ipAddr,
+ peer.PrivateKey,
+ slug,
+ iface,
+ iface,
+ ipAddr, iface,
+ peer.PrivateKey,
+ iface,
+ iface, publicKey, network, hostname, wireguardPort,
+ iface,
+ network, iface,
+ port, slug, hostname,
+ )
+ }
+}
diff --git a/api/handlers/reverseProxy.go b/api/handlers/reverseProxy.go
new file mode 100644
index 0000000..4ac4c87
--- /dev/null
+++ b/api/handlers/reverseProxy.go
@@ -0,0 +1,35 @@
+package handlers
+
+import (
+ "fmt"
+ "net/http"
+ "net/http/httputil"
+ "net/url"
+ "strings"
+ "time"
+
+ "github.com/LMBishop/gunnel/pkg/store"
+)
+
+func ReverseProxy(storeService store.Service) func(http.ResponseWriter, *http.Request) {
+ return func(w http.ResponseWriter, r *http.Request) {
+ hostParts := strings.Split(r.Host, ".")
+
+ slug := hostParts[0]
+ rule := storeService.GetRuleBySlug(slug)
+ if rule == nil {
+ http.Error(w, fmt.Sprintf("Unknown peer '%s'", slug), http.StatusNotFound)
+ return
+ }
+
+ targetURL, err := url.Parse("http://" + rule.Peer.IPAddr.String() + ":" + rule.Port)
+ rule.LastUsed = time.Now()
+ if err != nil {
+ http.Error(w, "Invalid target URL", http.StatusInternalServerError)
+ return
+ }
+
+ proxy := httputil.NewSingleHostReverseProxy(targetURL)
+ proxy.ServeHTTP(w, r)
+ }
+}