// main.go package main import ( "crypto/tls" "fmt" "log" "net/http" "net/http/httputil" "net/url" "strings" "sync" "time" "Admin/src" ) type RequestInfo struct { Timestamp string `json:"timestamp"` Host string `json:"host"` IP string `json:"ip"` Path string `json:"path"` Method string `json:"method"` } // Global store for request logs var ( requests []RequestInfo mu sync.Mutex ) func isLocalIP(ipStr string) bool { if ipStr == "[::1]" { return true } return false } func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ip := r.RemoteAddr cleanIP, _, _ := strings.Cut(ip, ":") // Split at first colon, ignore port cleanIP = strings.Trim(cleanIP, "[]") // Remove IPv6 brackets cleanIP = strings.TrimPrefix(cleanIP, "::ffff:") path := r.URL.Path[1:] if path == "" { path = "/" } now := time.Now() formattedTime := fmt.Sprintf("%d.%d %d:%02d:%02d%s", now.Month(), now.Day(), now.Hour()%12, now.Minute(), now.Second(), map[bool]string{true: "am", false: "pm"}[now.Hour() < 12]) ipWithPort := r.RemoteAddr ipWithPort = ipWithPort[:strings.LastIndex(ipWithPort, ":")] // Trim port for isLocalIP if isLocalIP(ipWithPort) { log.Printf("%s %s %s", r.Host, cleanIP, path) } else { log.Printf("\033[33m%s\033[0m %s \033[94m%s %s\033[0m", formattedTime, cleanIP, r.Host, path) } // Add request info to global store mu.Lock() requests = append(requests, RequestInfo{ Timestamp: time.Now().Format(time.RFC3339), // e.g., "2025-03-26T12:34:56Z" Host: r.Host, IP: cleanIP, Path: path, Method: r.Method, }) mu.Unlock() next(w, r) } } func rootHandler(w http.ResponseWriter, r *http.Request) { ip := r.RemoteAddr ip = ip[:strings.LastIndex(ip, ":")] // Trim port if isLocalIP(ip) { src.UIServer(w, r) } else { outsideHandler(w, r) } } func serveProxy(w http.ResponseWriter, r *http.Request, port int) { target, _ := url.Parse(fmt.Sprintf("http://localhost:%d", port)) proxy := httputil.NewSingleHostReverseProxy(target) proxy.ServeHTTP(w, r) } func outsideHandler(w http.ResponseWriter, r *http.Request) { host := r.Host if strings.HasSuffix(host, ".parchment.page") { host = "parchment.page" } switch host { case "america.sun.museum": serveProxy(w, r, 8000) case "thefiveprinciples.org": serveProxy(w, r, 3001) case "americanforum.net": serveProxy(w, r, 3002) case "hyperia.so": serveProxy(w, r, 3003) case "pma.aryan.so", "aryan.so", "apply.aryan.so": serveProxy(w, r, 3004) case "parchment.page": serveProxy(w, r, 3005) case "government.forum": serveProxy(w, r, 3006) case "noahkurtis.com": serveProxy(w, r, 3007) case "comalyr.com": serveProxy(w, r, 3008) case "blockcatcher.sun.museum": serveProxy(w, r, 3009) case "git.sun.museum": serveProxy(w, r, 4000) case "admin.sun.museum": serveProxy(w, r, 8080) default: fmt.Fprintf(w, "Hello, World! You're from outside.") } } func main() { log.SetFlags(0) // Your handler with logging middleware http.HandleFunc("/", loggingMiddleware(rootHandler)) // Load multiple certificates certs := map[string]*tls.Certificate{} loadCert := func(domain string) { cert, err := tls.LoadX509KeyPair( "/etc/letsencrypt/live/"+domain+"/fullchain.pem", "/etc/letsencrypt/live/"+domain+"/privkey.pem", ) if err != nil { log.Fatalf("Failed to load certificate for %s: %v", domain, err) } certs[domain] = &cert } // Example domains loadCert("parchment.page-0001") // Separate to allow wildcards loadCert("hyperia.so-0001") // Configure TLS with SNI tlsConfig := &tls.Config{ GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) { serverName := strings.ToLower(hello.ServerName) if cert, ok := certs[serverName]; ok { return cert, nil } if strings.HasSuffix(serverName, ".parchment.page") { return certs["parchment.page-0001"], nil } // fallback: return any default cert return certs["hyperia.so-0001"], nil }, MinVersion: tls.VersionTLS12, } server := &http.Server{ Addr: ":3000", Handler: nil, // uses default http handler TLSConfig: tlsConfig, } log.Println("🔒 HTTPS server running on port 3000") log.Fatal(server.ListenAndServeTLS("", "")) // certs handled by tlsConfig }