routes.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package daemon
  2. import (
  3. "encoding/json"
  4. "os"
  5. "path"
  6. daemonproto "git.aetherial.dev/aeth/yosai/pkg/daemon-proto"
  7. wg "git.aetherial.dev/aeth/yosai/pkg/wireguard/centos"
  8. )
  9. type AddServerRequest struct {
  10. Name string `json:"name"`
  11. Image string `json:"image"`
  12. Region string `json:"region"`
  13. Type string `json:"type"`
  14. }
  15. type AddServerResponse struct {
  16. Id int `json:"id"`
  17. Ipv4 []string `json:"ipv4"`
  18. Label string `json:"label"`
  19. Created string `json:"created"`
  20. Region string `json:"region"`
  21. Status string `json:"status"`
  22. }
  23. type StartWireguardRequest struct {
  24. InterfaceName string `json:"interface_name"`
  25. }
  26. type AddHostRequest struct {
  27. Target string `json:"target"`
  28. }
  29. type ConfigRenderRequest struct {
  30. Client string `json:"client"`
  31. Server string `json:"server"`
  32. OutputToFile bool `json:"output_to_file"`
  33. }
  34. // Client for building internal Daemon route requests
  35. func (c *Context) CreateServer(msg daemonproto.SockMessage) daemonproto.SockMessage {
  36. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_OK, []byte("Server provisioned and indexed into Semaphore."))
  37. }
  38. /*
  39. Render the wireguard configuration seed to be used when templating into the config file
  40. :param req: the struct containing the target client/server pair for the configuration
  41. */
  42. func (c *Context) configSeed(req ConfigRenderRequest) (wg.WireguardTemplateSeed, error) {
  43. var seed wg.WireguardTemplateSeed
  44. serverKeypair, err := c.keyring.GetKey(req.Server + "_" + c.Keytags.WgKeypairKeyname())
  45. if err != nil {
  46. return seed, err
  47. }
  48. clientKeypair, err := c.keyring.GetKey(req.Client + "_" + c.Keytags.WgKeypairKeyname())
  49. if err != nil {
  50. return seed, err
  51. }
  52. server, err := c.Config.GetServer(req.Server)
  53. if err != nil {
  54. return seed, err
  55. }
  56. client, err := c.Config.GetClient(req.Client)
  57. if err != nil {
  58. return seed, err
  59. }
  60. seed = wg.WireguardTemplateSeed{
  61. VpnClientPrivateKey: clientKeypair.GetSecret(),
  62. VpnClientAddress: client.VpnIpv4.String() + "/32",
  63. Peers: []wg.WireguardTemplatePeer{
  64. {
  65. Pubkey: serverKeypair.GetPublic(),
  66. Address: server.WanIpv4,
  67. Port: c.Config.Service.VpnServerPort,
  68. },
  69. }}
  70. return seed, nil
  71. }
  72. /*
  73. wrapping the VPN show configuration function in a route friendly interface
  74. :param msg: a message to parse from the daemon socket
  75. */
  76. func (c *Context) VpnShowHandler(msg daemonproto.SockMessage) daemonproto.SockMessage {
  77. var req ConfigRenderRequest
  78. err := json.Unmarshal(msg.Body, &req)
  79. if err != nil {
  80. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_FAILED, []byte(err.Error()))
  81. }
  82. seed, err := c.configSeed(req)
  83. if err != nil {
  84. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_FAILED, []byte(err.Error()))
  85. }
  86. cfg, err := wg.RenderClientConfiguration(seed)
  87. if err != nil {
  88. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_FAILED, []byte(err.Error()))
  89. }
  90. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_OK, cfg)
  91. }
  92. /*
  93. wrapping the VPN save configuration function in a route friendly interface
  94. :param msg: a message to parse from the daemon socket
  95. */
  96. func (c *Context) VpnSaveHandler(msg daemonproto.SockMessage) daemonproto.SockMessage {
  97. var req ConfigRenderRequest
  98. err := json.Unmarshal(msg.Body, &req)
  99. if err != nil {
  100. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_FAILED, []byte(err.Error()))
  101. }
  102. seed, err := c.configSeed(req)
  103. if err != nil {
  104. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_FAILED, []byte(err.Error()))
  105. }
  106. cfg, err := wg.RenderClientConfiguration(seed)
  107. if err != nil {
  108. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_FAILED, []byte(err.Error()))
  109. }
  110. fpath := path.Join(c.Config.HostInfo.WireguardSavePath, req.Server+".conf")
  111. err = os.WriteFile(fpath, cfg, 0666)
  112. if err != nil {
  113. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_FAILED, []byte(err.Error()))
  114. }
  115. return *daemonproto.NewSockMessage(daemonproto.MsgResponse, daemonproto.REQUEST_OK, []byte("Configuration saved to: "+fpath))
  116. }
  117. type VpnRouter struct {
  118. routes map[daemonproto.Method]func(daemonproto.SockMessage) daemonproto.SockMessage
  119. }
  120. func (v *VpnRouter) Register(method daemonproto.Method, callable func(daemonproto.SockMessage) daemonproto.SockMessage) {
  121. v.routes[method] = callable
  122. }
  123. func (v *VpnRouter) Routes() map[daemonproto.Method]func(daemonproto.SockMessage) daemonproto.SockMessage {
  124. return v.routes
  125. }
  126. func NewVpnRouter() *VpnRouter {
  127. return &VpnRouter{routes: map[daemonproto.Method]func(daemonproto.SockMessage) daemonproto.SockMessage{}}
  128. }