main.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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
  85. servicesMgr.RegisterHook("telnet", func(serviceName string, port int, disabled bool) error {
  86. if disabled {
  87. cliTelnetServer.Stop()
  88. } else {
  89. cliTelnetServer.SetAddr(fmt.Sprintf(":%d", port))
  90. go func() {
  91. if err := cliTelnetServer.Start(); err != nil {
  92. log.Printf("[CLI-Telnet] Listener error: %v", err)
  93. }
  94. }()
  95. }
  96. return nil
  97. })
  98. servicesMgr.RegisterHook("ssh", func(serviceName string, port int, disabled bool) error {
  99. if disabled {
  100. cliSSHServer.Stop()
  101. } else {
  102. cliSSHServer.SetAddr(fmt.Sprintf(":%d", port))
  103. go func() {
  104. if err := cliSSHServer.Start(); err != nil {
  105. log.Printf("[CLI-SSH] Listener error: %v", err)
  106. }
  107. }()
  108. }
  109. return nil
  110. })
  111. // Start enabled CLI servers
  112. if tSvc, ok := servicesMgr.GetService("telnet"); !ok || !tSvc.Disabled {
  113. go func() {
  114. if err := cliTelnetServer.Start(); err != nil {
  115. log.Printf("[CLI-Telnet] Server listener error: %v", err)
  116. }
  117. }()
  118. }
  119. defer cliTelnetServer.Stop()
  120. if sSvc, ok := servicesMgr.GetService("ssh"); !ok || !sSvc.Disabled {
  121. go func() {
  122. if err := cliSSHServer.Start(); err != nil {
  123. log.Printf("[CLI-SSH] Server listener error: %v", err)
  124. }
  125. }()
  126. }
  127. defer cliSSHServer.Stop()
  128. // API & Web UI Server
  129. srv := api.NewServer(
  130. netMgr,
  131. persistMgr,
  132. metaMgr,
  133. vpnMgr,
  134. fwMgr,
  135. routingMgr,
  136. dynRoutingMgr,
  137. bridgeMgr,
  138. toolsMgr,
  139. dhcpMgr,
  140. dhcpServerMgr,
  141. vrrpMgr,
  142. bwtestMgr,
  143. dnsMgr,
  144. authMgr,
  145. servicesMgr,
  146. webHandler,
  147. )
  148. httpServer := &http.Server{
  149. Addr: *addr,
  150. Handler: srv,
  151. ReadTimeout: 60 * time.Second,
  152. WriteTimeout: 60 * time.Second,
  153. IdleTimeout: 120 * time.Second,
  154. }
  155. // Print startup banner
  156. fmt.Println("========================================================")
  157. fmt.Println(" ⚡ Proxmox RouterOS Appliance Controller ⚡ ")
  158. fmt.Println("========================================================")
  159. fmt.Printf(" Web UI & API : http://0.0.0.0%s\n", *addr)
  160. fmt.Printf(" CLI Telnet Service : 0.0.0.0%s (debtik-cli / telnet)\n", telnetAddr)
  161. fmt.Printf(" CLI SSH Service : 0.0.0.0%s (ssh admin@<router-ip> -p 2222)\n", sshAddr)
  162. fmt.Printf(" Metadata Storage : %s\n", *metaPath)
  163. fmt.Printf(" Debian Config Path : %s\n", network.DebianVlansCfgPath)
  164. if ifaces, err := netMgr.ListInterfaces(); err == nil {
  165. fmt.Printf(" Discovered Links : %d interfaces\n", len(ifaces))
  166. for _, i := range ifaces {
  167. fmt.Printf(" - %-10s (%s) [%s] MTU:%d\n", i.Name, i.Type, i.State, i.MTU)
  168. }
  169. }
  170. fmt.Println("========================================================")
  171. fmt.Println(" DebTik Appliance ready. Press Ctrl+C to terminate.")
  172. // Graceful shutdown handling
  173. stopChan := make(chan os.Signal, 1)
  174. signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM)
  175. go func() {
  176. if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  177. log.Fatalf("HTTP server failed: %v", err)
  178. }
  179. }()
  180. <-stopChan
  181. fmt.Println("\nShutting down RouterOS Controller gracefully...")
  182. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  183. defer cancel()
  184. if err := httpServer.Shutdown(ctx); err != nil {
  185. log.Printf("Server shutdown error: %v", err)
  186. }
  187. fmt.Println("RouterOS Controller stopped.")
  188. }