diff --git a/Makefile b/Makefile index 5c0d72030..e01c1b92b 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,14 @@ GIT_COMMIT=$(shell git rev-parse --short HEAD) .PHONY: all all: fmt lint test build go.mod +# Build static assets +# This will create dist directory containing client's static files +.PHONY: static +static: + cd web/client + yarn + yarn build + .PHONY: build build: go generate ./... diff --git a/cmd/serve.go b/cmd/serve.go index f3679cc7e..0449e2e0b 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -2,6 +2,10 @@ package cmd import ( "fmt" + "log" + "net/http" + "os" + "github.com/gin-gonic/gin" "github.com/joho/godotenv" "github.com/sirupsen/logrus" @@ -11,14 +15,14 @@ import ( "github.com/sundowndev/phoneinfoga/v2/lib/remote" "github.com/sundowndev/phoneinfoga/v2/web" "github.com/sundowndev/phoneinfoga/v2/web/v2/api/handlers" - "log" - "net/http" - "os" ) type ServeCmdOptions struct { HttpPort int DisableClient bool + Domain string + KeyfilePath string + CertfilePath string DisabledScanners []string PluginPaths []string EnvFiles []string @@ -33,11 +37,19 @@ func init() { // Register flags cmd.PersistentFlags().IntVarP(&opts.HttpPort, "port", "p", 5000, "HTTP port") cmd.PersistentFlags().BoolVar(&opts.DisableClient, "no-client", false, "Disable web client (REST API only)") + cmd.PersistentFlags().StringVar(&opts.Domain, "domain", "", "Use a specific domain to host (with tls).") + cmd.PersistentFlags().StringVar(&opts.CertfilePath, "cert", "", "Path to certfile (will use default letsencrypt path for domain if none provided).") + cmd.PersistentFlags().StringVar(&opts.KeyfilePath, "key", "", "Path to keyfile (will use default letsencrypt path for domain if none provided).") cmd.PersistentFlags().StringArrayVarP(&opts.DisabledScanners, "disable", "D", []string{}, "Scanner to skip for the scans") cmd.PersistentFlags().StringArrayVar(&opts.PluginPaths, "plugin", []string{}, "Extra scanner plugin to use for the scans") cmd.PersistentFlags().StringSliceVar(&opts.EnvFiles, "env-file", []string{}, "Env files to parse environment variables from (looks for .env by default)") } +func fmtLetsEncrypt(sitename string) (string, string) { + return fmt.Sprintf("/etc/letsencrypt/live/%s/fullchain.pem", sitename), + fmt.Sprintf("/etc/letsencrypt/live/%s/privkey.pem", sitename) +} + func NewServeCmd(opts *ServeCmdOptions) *cobra.Command { return &cobra.Command{ Use: "serve", @@ -70,6 +82,15 @@ func NewServeCmd(opts *ServeCmdOptions) *cobra.Command { log.Fatal(err) } + if len(opts.Domain) != 0 { + if len(opts.CertfilePath) == 0 || len(opts.KeyfilePath) == 0 { + opts.CertfilePath, opts.KeyfilePath = fmtLetsEncrypt(opts.Domain) + } + if err := srv.ListenAndServeTLS(opts.Domain+":443", opts.CertfilePath, opts.KeyfilePath); err != nil && err != http.ErrServerClosed { + log.Fatalf("listen: %s\n", err) + } + } + addr := fmt.Sprintf(":%d", opts.HttpPort) fmt.Printf("Listening on %s\n", addr) if err := srv.ListenAndServe(addr); err != nil && err != http.ErrServerClosed { diff --git a/web/server.go b/web/server.go index 7bd4bb05f..f3a9d254a 100644 --- a/web/server.go +++ b/web/server.go @@ -1,11 +1,13 @@ // Package web includes code for the web server of PhoneInfoga +// //go:generate swag init -g ./server.go --parseDependency package web import ( + "net/http" + "github.com/gin-gonic/gin" v2 "github.com/sundowndev/phoneinfoga/v2/web/v2/api/server" - "net/http" ) // @title PhoneInfoga REST API @@ -69,6 +71,10 @@ func (s *Server) ListenAndServe(addr string) error { return s.router.Run(addr) } +func (s *Server) ListenAndServeTLS(addr string, certfile, keyfile string) error { + return s.router.RunTLS(addr, certfile, keyfile) +} + func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.router.ServeHTTP(w, r) }