main.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package main
  2. import (
  3. "context"
  4. "flag"
  5. "fmt"
  6. "log"
  7. "net/http"
  8. "os"
  9. "os/signal"
  10. "syscall"
  11. "time"
  12. "proxmox-router/internal/api"
  13. "proxmox-router/internal/auth"
  14. "proxmox-router/internal/bridge"
  15. "proxmox-router/internal/bwtest"
  16. "proxmox-router/internal/cli"
  17. "proxmox-router/internal/dhcp"
  18. "proxmox-router/internal/dns"
  19. "proxmox-router/internal/dynamicrouting"
  20. "proxmox-router/internal/firewall"
  21. "proxmox-router/internal/logging"
  22. "proxmox-router/internal/network"
  23. "proxmox-router/internal/routing"
  24. "proxmox-router/internal/services"
  25. "proxmox-router/internal/tools"
  26. "proxmox-router/internal/vpn"
  27. "proxmox-router/internal/vrrp"
  28. "proxmox-router/internal/web"
  29. )
  30. func main() {
  31. addr := flag.String("addr", ":8080", "HTTP service address (e.g. :8080 or :80)")
  32. cliAddr := flag.String("cli-addr", ":8282", "CLI service address for Telnet and debtik-cli (e.g. :8282)")
  33. metaPath := flag.String("meta", "/etc/proxmox-router/metadata.json", "Path to interface metadata storage file")
  34. flag.Parse()
  35. // Initialize Logging Ring Buffer
  36. _ = logging.GetLogger()
  37. // Initialize components
  38. metaMgr := network.NewMetadataManager(*metaPath)
  39. netMgr := network.NewManager(metaMgr)
  40. persistMgr := network.NewPersistenceManager(netMgr)
  41. vpnMgr := vpn.NewManager()
  42. fwMgr := firewall.NewFirewallManager()
  43. routingMgr := routing.NewRoutingManager()
  44. defer routingMgr.Stop()
  45. dynRoutingMgr := dynamicrouting.NewManager("")
  46. bridgeMgr := bridge.NewBridgeManager()
  47. toolsMgr := tools.NewManager()
  48. dhcpMgr := dhcp.NewManager()
  49. dhcpServerMgr := dhcp.NewServerManager()
  50. vrrpMgr := vrrp.NewManager()
  51. bwtestMgr := bwtest.NewManager("")
  52. defer bwtestMgr.Stop()
  53. dnsMgr := dns.NewManager()
  54. authMgr := auth.NewManager("")
  55. servicesMgr := services.NewManager("")
  56. webHandler := web.Handler()
  57. // Build Unified RouterOS CLI Executor
  58. cliExecutor := cli.NewExecutor(
  59. authMgr,
  60. netMgr,
  61. routingMgr,
  62. dynRoutingMgr,
  63. fwMgr,
  64. dhcpMgr,
  65. dhcpServerMgr,
  66. dnsMgr,
  67. bridgeMgr,
  68. vpnMgr,
  69. vrrpMgr,
  70. bwtestMgr,
  71. servicesMgr,
  72. )
  73. // Determine Telnet & SSH addresses from services config or flags
  74. telnetAddr := *cliAddr
  75. if tSvc, ok := servicesMgr.GetService("telnet"); ok && tSvc.Port > 0 {
  76. telnetAddr = fmt.Sprintf(":%d", tSvc.Port)
  77. }
  78. sshAddr := ":2222"
  79. if sSvc, ok := servicesMgr.GetService("ssh"); ok && sSvc.Port > 0 {
  80. sshAddr = fmt.Sprintf(":%d", sSvc.Port)
  81. }
  82. cliTelnetServer := cli.NewServer(telnetAddr, authMgr, cliExecutor)
  83. cliSSHServer := cli.NewSSHServer(sshAddr, authMgr, cliExecutor)
  84. // Register hooks for dynamic service start/stop & port changes
  85. servicesMgr.RegisterHook("telnet", func(serviceName string, port int, disabled bool) error {
  86. cliTelnetServer.Stop()
  87. if !disabled {
  88. cliTelnetServer.SetAddr(fmt.Sprintf(":%d", port))
  89. go func() {
  90. if err := cliTelnetServer.Start(); err != nil {
  91. log.Printf("[CLI-Telnet] Listener error: %v", err)
  92. }
  93. }()
  94. }
  95. return nil
  96. })
  97. servicesMgr.RegisterHook("ssh", func(serviceName string, port int, disabled bool) error {
  98. cliSSHServer.Stop()
  99. if !disabled {
  100. cliSSHServer.SetAddr(fmt.Sprintf(":%d", port))
  101. go func() {
  102. if err := cliSSHServer.Start(); err != nil {
  103. log.Printf("[CLI-SSH] Listener error: %v", err)
  104. }
  105. }()
  106. }
  107. return nil
  108. })
  109. // Start enabled CLI servers
  110. if tSvc, ok := servicesMgr.GetService("telnet"); !ok || !tSvc.Disabled {
  111. go func() {
  112. if err := cliTelnetServer.Start(); err != nil {
  113. log.Printf("[CLI-Telnet] Server listener error: %v", err)
  114. }
  115. }()
  116. }
  117. defer cliTelnetServer.Stop()
  118. if sSvc, ok := servicesMgr.GetService("ssh"); !ok || !sSvc.Disabled {
  119. go func() {
  120. if err := cliSSHServer.Start(); err != nil {
  121. log.Printf("[CLI-SSH] Server listener error: %v", err)
  122. }
  123. }()
  124. }
  125. defer cliSSHServer.Stop()
  126. // API & Web UI Server
  127. srv := api.NewServer(
  128. netMgr,
  129. persistMgr,
  130. metaMgr,
  131. vpnMgr,
  132. fwMgr,
  133. routingMgr,
  134. dynRoutingMgr,
  135. bridgeMgr,
  136. toolsMgr,
  137. dhcpMgr,
  138. dhcpServerMgr,
  139. vrrpMgr,
  140. bwtestMgr,
  141. dnsMgr,
  142. authMgr,
  143. servicesMgr,
  144. webHandler,
  145. )
  146. httpServer := &http.Server{
  147. Addr: *addr,
  148. Handler: srv,
  149. ReadTimeout: 60 * time.Second,
  150. WriteTimeout: 60 * time.Second,
  151. IdleTimeout: 120 * time.Second,
  152. }
  153. // Print startup banner
  154. fmt.Println("========================================================")
  155. fmt.Println(" ⚡ Proxmox RouterOS Appliance Controller ⚡ ")
  156. fmt.Println("========================================================")
  157. fmt.Printf(" Web UI & API : http://0.0.0.0%s\n", *addr)
  158. fmt.Printf(" CLI Telnet Service : 0.0.0.0%s (debtik-cli / telnet)\n", telnetAddr)
  159. fmt.Printf(" CLI SSH Service : 0.0.0.0%s (ssh admin@<router-ip> -p 2222)\n", sshAddr)
  160. fmt.Printf(" Metadata Storage : %s\n", *metaPath)
  161. fmt.Printf(" Debian Config Path : %s\n", network.DebianVlansCfgPath)
  162. if ifaces, err := netMgr.ListInterfaces(); err == nil {
  163. fmt.Printf(" Discovered Links : %d interfaces\n", len(ifaces))
  164. for _, i := range ifaces {
  165. fmt.Printf(" - %-10s (%s) [%s] MTU:%d\n", i.Name, i.Type, i.State, i.MTU)
  166. }
  167. }
  168. fmt.Println("========================================================")
  169. fmt.Println(" DebTik Appliance ready. Press Ctrl+C to terminate.")
  170. // Graceful shutdown handling
  171. stopChan := make(chan os.Signal, 1)
  172. signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM)
  173. go func() {
  174. if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  175. log.Fatalf("HTTP server failed: %v", err)
  176. }
  177. }()
  178. <-stopChan
  179. fmt.Println("\nShutting down RouterOS Controller gracefully...")
  180. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  181. defer cancel()
  182. if err := httpServer.Shutdown(ctx); err != nil {
  183. log.Printf("Server shutdown error: %v", err)
  184. }
  185. fmt.Println("RouterOS Controller stopped.")
  186. }