Compare commits

...
9 Commits
Author SHA1 Message Date
Cody Thomas 96b24b48a7 Merge pull request #594 from je4yfc/integration
Generalized Support for external services across compose generation and port checks
2026-10-11 10:24:27 -05:00
Cody Thomas bdc722f6ce Merge pull request #589 from mjmaley/fix/cli-pasted-whitespace
Handle pasted whitespace in task arguments
2026-10-08 10:39:11 -05:00
Joseph Erdosy f9e71d0859 feat(cli): generalize external service handling in compose configuration and port checks
Signed-off-by: Joseph Erdosy <[email protected]>
2026-09-10 10:46:37 -04:00
Joseph Erdosy 742d878928 fix(cli): support external Nginx and create config dir for block lists
Signed-off-by: Joseph Erdosy <[email protected]>
2026-09-10 10:46:34 -04:00
Joseph Erdosy 01ea8bc896 feat(database): add external PostgreSQL support and configurable SSL mode (#587, #590)
Signed-off-by: Joseph Erdosy <[email protected]>
2026-09-10 10:46:31 -04:00
pwn 94418bcd52 fix(cli): fail fast on docker-compose failures instead of misleading health loop
The pty path in runDockerCompose returned the (nil) error variable on
nonzero exit, and start() discarded ServiceStart's error. Both together
let 'mythic-cli start' proceed into the UI probe loop after a failed
compose up, ending in os.Exit(1) with unrelated diagnostics (run-1.log).

- dockerComposeManager.runDockerCompose: return a descriptive error on
  nonzero exit in the pty path
- start: log.Fatalf on ServiceStart error so compose failures surface
  immediately

Signed-off-by: Joseph Erdosy <[email protected]>
2026-09-10 10:46:28 -04:00
Cody Thomas 3ae9c5fe18 Merge pull request #593 from je4yfc/cli-error-handling-fixes
fix(cli): fail fast on docker-compose failures in mythic-cli start
2026-09-07 10:57:19 -05:00
pwn 5e85a20d14 fix(cli): fail fast on docker-compose failures instead of misleading health loop
The pty path in runDockerCompose returned the (nil) error variable on
nonzero exit, and start() discarded ServiceStart's error. Both together
let 'mythic-cli start' proceed into the UI probe loop after a failed
compose up, ending in os.Exit(1) with unrelated diagnostics (run-1.log).

- dockerComposeManager.runDockerCompose: return a descriptive error on
  nonzero exit in the pty path
- start: log.Fatalf on ServiceStart error so compose failures surface
  immediately
2026-09-06 14:29:33 -04:00
mjmaley 5f46db6ede Handle pasted whitespace in task arguments 2026-09-02 16:56:36 -04:00
11 changed files with 184 additions and 164 deletions

No files matched your search

@@ -827,7 +827,7 @@ export function CallbacksTabsTaskingInputPreMemo(props){
buffer += value;
return;
}
else if(value === " "){
else if([" ", "\t", "\r", "\n"].includes(value)){
if(backslash){
backslash = false;
//buffer += " ";
+3
View File
@@ -271,6 +271,9 @@ If it's anything else, mythic-cli will not spin up this container as it assumes
mythicEnv.SetDefault("postgres_password", utils.GenerateRandomPassword(30))
mythicEnvInfo["postgres_password"] = `This is the randomly generated password that mythic_server and mythic_graphql use to connect to the mythic_postgres container`
mythicEnv.SetDefault("postgres_sslmode", "disable")
mythicEnvInfo["postgres_sslmode"] = `This specifies the SSL mode used when connecting to the PostgreSQL database (e.g. disable, require, verify-ca, verify-full)`
mythicEnv.SetDefault("postgres_cpus", defaultNumberOfCPUs)
mythicEnvInfo["postgres_cpus"] = `Set this to limit the maximum number of CPUs this service is able to consume`
@@ -87,8 +87,14 @@ func ServiceStart(containers []string, keepVolume bool) error {
log.Printf("[-] Failed to remove images\n%v\n", err)
return err
}
updateNginxBlockLists()
generateCerts()
// nginx-specific housekeeping only applies when mythic_nginx runs locally
if isServiceInternal("mythic_nginx") {
updateNginxBlockLists()
if err := generateCerts(); err != nil {
log.Printf("[-] Failed to generate certs: %v\n", err)
return err
}
}
TestMythicRabbitmqConnection()
TestMythicConnection()
Status(false)
+135 -153
View File
@@ -67,16 +67,7 @@ func AddMythicService(service string, removeVolume bool) {
} else {
delete(pStruct, "ports")
pStruct["network_mode"] = "host"
pStruct["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
}
pStruct["extra_hosts"] = getExtraHosts()
if mythicEnv.GetBool("postgres_bind_localhost_only") {
pStruct["command"] = "postgres -c \"max_connections=100\" -p ${POSTGRES_PORT} -c config_file=/etc/postgresql.conf -c \"listen_addresses=localhost\""
} else {
@@ -146,16 +137,7 @@ func AddMythicService(service string, removeVolume bool) {
} else {
delete(pStruct, "ports")
pStruct["network_mode"] = "host"
pStruct["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
}
pStruct["extra_hosts"] = getExtraHosts()
if mythicEnv.GetBool("documentation_bind_localhost_only") {
pStruct["environment"] = []string{
"DOCUMENTATION_PORT=${DOCUMENTATION_PORT}",
@@ -185,13 +167,21 @@ func AddMythicService(service string, removeVolume bool) {
}
}
case "mythic_graphql":
pStruct["depends_on"] = map[string]map[string]string{
"mythic_postgres": {
dependsOn := map[string]map[string]string{}
if isServiceInternal("mythic_server") {
dependsOn["mythic_server"] = map[string]string{
"condition": "service_healthy",
},
"mythic_server": {
}
}
if isServiceInternal("mythic_postgres") {
dependsOn["mythic_postgres"] = map[string]string{
"condition": "service_healthy",
},
}
}
if len(dependsOn) > 0 {
pStruct["depends_on"] = dependsOn
} else {
delete(pStruct, "depends_on")
}
if mythicEnv.GetBool("hasura_use_build_context") {
pStruct["build"] = map[string]interface{}{
@@ -208,8 +198,8 @@ func AddMythicService(service string, removeVolume bool) {
pStruct["mem_limit"] = mythicEnv.GetString("hasura_mem_limit")
}
environment := []string{
"HASURA_GRAPHQL_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}",
"HASURA_GRAPHQL_METADATA_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}",
"HASURA_GRAPHQL_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=${POSTGRES_SSLMODE:-disable}",
"HASURA_GRAPHQL_METADATA_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=${POSTGRES_SSLMODE:-disable}",
"HASURA_GRAPHQL_ENABLE_CONSOLE=true",
"HASURA_GRAPHQL_DEV_MODE=false",
"HASURA_GRAPHQL_ADMIN_SECRET=${HASURA_SECRET}",
@@ -239,16 +229,7 @@ func AddMythicService(service string, removeVolume bool) {
} else {
delete(pStruct, "ports")
pStruct["network_mode"] = "host"
pStruct["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
}
pStruct["extra_hosts"] = getExtraHosts()
if mythicEnv.GetBool("hasura_bind_localhost_only") {
environment = append(environment, "HASURA_GRAPHQL_SERVER_HOST=127.0.0.1")
} else {
@@ -264,22 +245,36 @@ func AddMythicService(service string, removeVolume bool) {
delete(pStruct, "volumes")
}
case "mythic_nginx":
pStruct["depends_on"] = map[string]map[string]string{
"mythic_server": {
dependsOn := map[string]map[string]string{}
if isServiceInternal("mythic_server") {
dependsOn["mythic_server"] = map[string]string{
"condition": "service_healthy",
},
"mythic_react": {
}
}
if isServiceInternal("mythic_react") {
dependsOn["mythic_react"] = map[string]string{
"condition": "service_started",
},
"mythic_jupyter": {
}
}
if isServiceInternal("mythic_jupyter") {
dependsOn["mythic_jupyter"] = map[string]string{
"condition": "service_healthy",
},
"mythic_documentation": {
}
}
if isServiceInternal("mythic_documentation") {
dependsOn["mythic_documentation"] = map[string]string{
"condition": "service_started",
},
"mythic_graphql": {
}
}
if isServiceInternal("mythic_graphql") {
dependsOn["mythic_graphql"] = map[string]string{
"condition": "service_healthy",
},
}
}
if len(dependsOn) > 0 {
pStruct["depends_on"] = dependsOn
} else {
delete(pStruct, "depends_on")
}
if mythicEnv.GetBool("nginx_use_build_context") {
pStruct["build"] = map[string]interface{}{
@@ -348,16 +343,7 @@ func AddMythicService(service string, removeVolume bool) {
} else {
delete(pStruct, "ports")
pStruct["network_mode"] = "host"
pStruct["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
}
pStruct["extra_hosts"] = getExtraHosts()
if mythicEnv.GetBool("nginx_bind_localhost_only") {
finalNginxEnv = append(finalNginxEnv, "NGINX_BIND_IPV4=127.0.0.1", "NGINX_BIND_IPV6=[::1]")
} else {
@@ -434,16 +420,7 @@ func AddMythicService(service string, removeVolume bool) {
} else {
delete(pStruct, "ports")
pStruct["network_mode"] = "host"
pStruct["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
}
pStruct["extra_hosts"] = getExtraHosts()
if mythicEnv.GetBool("rabbitmq_bind_localhost_only") {
environment = append(environment, "RABBITMQ_NODE_IP_ADDRESS=127.0.0.1", "RABBITMQ_NODE_PORT=${RABBITMQ_PORT}")
} else {
@@ -469,16 +446,26 @@ func AddMythicService(service string, removeVolume bool) {
}
}
case "mythic_react":
pStruct["depends_on"] = map[string]map[string]string{
"mythic_server": {
dependsOn := map[string]map[string]string{}
if isServiceInternal("mythic_server") {
dependsOn["mythic_server"] = map[string]string{
"condition": "service_healthy",
},
"mythic_graphql": {
}
}
if isServiceInternal("mythic_graphql") {
dependsOn["mythic_graphql"] = map[string]string{
"condition": "service_healthy",
},
"mythic_postgres": {
}
}
if isServiceInternal("mythic_postgres") {
dependsOn["mythic_postgres"] = map[string]string{
"condition": "service_healthy",
},
}
}
if len(dependsOn) > 0 {
pStruct["depends_on"] = dependsOn
} else {
delete(pStruct, "depends_on")
}
if mythicEnv.GetBool("mythic_react_debug") {
pStruct["build"] = map[string]interface{}{
@@ -550,16 +537,7 @@ func AddMythicService(service string, removeVolume bool) {
} else {
delete(pStruct, "ports")
pStruct["network_mode"] = "host"
pStruct["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
}
pStruct["extra_hosts"] = getExtraHosts()
if mythicEnv.GetBool("mythic_react_bind_localhost_only") {
pStruct["environment"] = []string{
"MYTHIC_REACT_PORT=${MYTHIC_REACT_PORT}",
@@ -574,16 +552,26 @@ func AddMythicService(service string, removeVolume bool) {
}
case "mythic_jupyter":
pStruct["depends_on"] = map[string]map[string]string{
"mythic_server": {
dependsOn := map[string]map[string]string{}
if isServiceInternal("mythic_server") {
dependsOn["mythic_server"] = map[string]string{
"condition": "service_healthy",
},
"mythic_postgres": {
}
}
if isServiceInternal("mythic_graphql") {
dependsOn["mythic_graphql"] = map[string]string{
"condition": "service_healthy",
},
"mythic_graphql": {
}
}
if isServiceInternal("mythic_postgres") {
dependsOn["mythic_postgres"] = map[string]string{
"condition": "service_healthy",
},
}
}
if len(dependsOn) > 0 {
pStruct["depends_on"] = dependsOn
} else {
delete(pStruct, "depends_on")
}
if mythicEnv.GetBool("jupyter_use_build_context") {
pStruct["build"] = map[string]interface{}{
@@ -620,16 +608,7 @@ func AddMythicService(service string, removeVolume bool) {
} else {
delete(pStruct, "ports")
pStruct["network_mode"] = "host"
pStruct["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
}
pStruct["extra_hosts"] = getExtraHosts()
environment := []string{
"JUPYTER_TOKEN=${JUPYTER_TOKEN}",
"CHOWN_EXTRA=/projects",
@@ -665,13 +644,21 @@ func AddMythicService(service string, removeVolume bool) {
}
}
case "mythic_server":
pStruct["depends_on"] = map[string]map[string]string{
"mythic_postgres": {
dependsOn := map[string]map[string]string{}
if isServiceInternal("mythic_rabbitmq") {
dependsOn["mythic_rabbitmq"] = map[string]string{
"condition": "service_healthy",
},
"mythic_rabbitmq": {
}
}
if isServiceInternal("mythic_postgres") {
dependsOn["mythic_postgres"] = map[string]string{
"condition": "service_healthy",
},
}
}
if len(dependsOn) > 0 {
pStruct["depends_on"] = dependsOn
} else {
delete(pStruct, "depends_on")
}
if mythicEnv.GetBool("mythic_server_use_build_context") {
pStruct["build"] = map[string]interface{}{
@@ -710,6 +697,7 @@ func AddMythicService(service string, removeVolume bool) {
"POSTGRES_HOST=${POSTGRES_HOST}",
"POSTGRES_PORT=${POSTGRES_PORT}",
"POSTGRES_PASSWORD=${POSTGRES_PASSWORD}",
"POSTGRES_SSLMODE=${POSTGRES_SSLMODE}",
"RABBITMQ_HOST=${RABBITMQ_HOST}",
"RABBITMQ_PORT=${RABBITMQ_PORT}",
"RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}",
@@ -740,16 +728,7 @@ func AddMythicService(service string, removeVolume bool) {
} else {
delete(pStruct, "ports")
pStruct["network_mode"] = "host"
pStruct["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
}
pStruct["extra_hosts"] = getExtraHosts()
}
if _, ok := pStruct["environment"]; ok {
@@ -774,10 +753,12 @@ func AddMythicService(service string, removeVolume bool) {
}
}
case "mythic_sync":
pStruct["depends_on"] = map[string]map[string]string{
"mythic_nginx": {
"condition": "service_healthy",
},
if isServiceInternal("mythic_nginx") {
pStruct["depends_on"] = map[string]map[string]string{
"mythic_nginx": {"condition": "service_healthy"},
}
} else {
delete(pStruct, "depends_on")
}
absPath, err := filepath.Abs(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service))
if err != nil {
@@ -822,16 +803,7 @@ func AddMythicService(service string, removeVolume bool) {
delete(pStruct, "extra_hosts")
} else {
pStruct["network_mode"] = "host"
pStruct["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
}
pStruct["extra_hosts"] = getExtraHosts()
}
}
@@ -863,29 +835,25 @@ func Add3rdPartyService(service string, additionalConfigs map[string]interface{}
"args": config.GetBuildArguments(),
}
existingConfig["network_mode"] = "host"
existingConfig["extra_hosts"] = []string{
"mythic_server:127.0.0.1",
"mythic_rabbitmq:127.0.0.1",
"mythic_nginx:127.0.0.1",
"mythic_react:127.0.0.1",
"mythic_documentation:127.0.0.1",
"mythic_graphql:127.0.0.1",
"mythic_jupyter:127.0.0.1",
"mythic_postgres:127.0.0.1",
existingConfig["extra_hosts"] = getExtraHosts()
dependsOn := map[string]map[string]string{}
if isServiceInternal("mythic_server") {
dependsOn["mythic_server"] = map[string]string{"condition": "service_healthy"}
}
existingConfig["depends_on"] = map[string]map[string]string{
"mythic_server": {
"condition": "service_healthy",
},
"mythic_rabbitmq": {
"condition": "service_healthy",
},
"mythic_nginx": {
"condition": "service_healthy",
},
"mythic_graphql": {
"condition": "service_healthy",
},
if isServiceInternal("mythic_rabbitmq") {
dependsOn["mythic_rabbitmq"] = map[string]string{"condition": "service_healthy"}
}
if isServiceInternal("mythic_graphql") {
dependsOn["mythic_graphql"] = map[string]string{"condition": "service_healthy"}
}
if isServiceInternal("mythic_nginx") {
dependsOn["mythic_nginx"] = map[string]string{"condition": "service_healthy"}
}
if len(dependsOn) > 0 {
existingConfig["depends_on"] = dependsOn
} else {
delete(existingConfig, "depends_on")
}
agentConfigs := config.GetConfigStrings([]string{fmt.Sprintf("%s_.*", service)})
agentUseBuildContextKey := fmt.Sprintf("%s_use_build_context", service)
@@ -1003,3 +971,17 @@ func applyImageMirror(imageURL, mirror string) string {
}
return mirror + "/" + imageURL
}
func isServiceInternal(service string) bool {
return manager.GetManager().IsServiceInternal(service)
}
func getExtraHosts() []string {
extraHosts := []string{}
for _, service := range config.MythicPossibleServices {
if isServiceInternal(service) {
extraHosts = append(extraHosts, fmt.Sprintf("%s:127.0.0.1", service))
}
}
return extraHosts
}
+3
View File
@@ -112,6 +112,9 @@ func updateNginxBlockLists() {
outputString += "deny all;"
if !config.GetMythicEnv().GetBool("nginx_use_volume") {
ipFilePath := filepath.Join(utils.GetCwdFromExe(), "nginx-docker", "config", "blockips.conf")
if err := os.MkdirAll(filepath.Dir(ipFilePath), 0755); err != nil {
log.Fatalf("[-] Failed to create nginx-docker/config directory for block list file: %v\n", err)
}
if err := os.WriteFile(ipFilePath, []byte(outputString), 0600); err != nil {
log.Fatalf("[-] Failed to write out block list file: %v\n", err)
}
@@ -92,6 +92,18 @@ func (d *DockerComposeManager) IsServiceRunning(service string) bool {
return false
}
// IsServiceInternal checks if a service is configured to run locally in docker vs externally
func (d *DockerComposeManager) IsServiceInternal(service string) bool {
if !utils.StringInSlice(service, config.MythicPossibleServices) {
return true
}
intendedServices, err := config.GetIntendedMythicServiceNames()
if err != nil {
return true
}
return utils.StringInSlice(service, intendedServices)
}
// DoesImageExist use Docker API to check existing images for the specified name
func (d *DockerComposeManager) DoesImageExist(service string) bool {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
@@ -624,9 +636,9 @@ func (d *DockerComposeManager) TestPorts(services []string) {
var removeServices []string
mythicEnv := config.GetMythicEnv()
for key, val := range portChecks {
// only check ports for services we're about to start
// only check ports for services we're about to start that are running locally
if utils.StringInSlice(val[1], services) {
if mythicEnv.GetString(key) == val[1] || mythicEnv.GetString(key) == "127.0.0.1" {
if d.IsServiceInternal(val[1]) {
addServices = append(addServices, val[1])
p, err := net.Listen("tcp", ":"+strconv.Itoa(mythicEnv.GetInt(val[0])))
if err != nil {
@@ -1413,7 +1425,7 @@ func (d *DockerComposeManager) runDockerCompose(args []string) error {
return err
}
if processState.ExitCode() != 0 {
return err
return fmt.Errorf("docker-compose %v exited with code %d", args, processState.ExitCode())
}
}
return nil
@@ -12,6 +12,8 @@ type CLIManager interface {
GetManagerName() string
// IsServiceRunning checks if a service by the specified name is currently running or not
IsServiceRunning(service string) bool
// IsServiceInternal checks if a service is configured to run locally in docker vs externally
IsServiceInternal(service string) bool
// CheckRequiredManagerVersion checks if the version of the management software installed is a valid version or not
CheckRequiredManagerVersion() bool
// GenerateRequiredConfig creates any necessary base configuration files needed by the manager, like a docker-compose.yml file
+3 -1
View File
@@ -1,6 +1,8 @@
package cmd
import (
"log"
"github.com/MythicMeta/Mythic_CLI/cmd/config"
"github.com/MythicMeta/Mythic_CLI/cmd/internal"
"github.com/spf13/cobra"
@@ -31,6 +33,6 @@ func start(cmd *cobra.Command, args []string) {
keepVolume = !config.GetMythicEnv().GetBool("REBUILD_ON_START")
}
if err := internal.ServiceStart(args, localKeepVolume); err != nil {
log.Fatalf("[-] Failed to start Mythic: %v\n", err)
}
}
+8 -2
View File
@@ -36,6 +36,11 @@ func Initialize() {
logging.LogInfo("Disconnecting from database and reconnecting to load new schema")
DB.Close()
DB = getNewDbConnection()
if utils.MythicConfig.PostgresDebug {
if _, err := DB.Exec("CREATE EXTENSION IF NOT EXISTS pg_stat_statements SCHEMA public;"); err != nil {
logging.LogWarning("Failed to create pg_stat_statements extension (requires superuser)", "error", err.Error())
}
}
// we need to initialize the admin user and operation
salt := uuid.NewString()
newUser := databaseStructs.Operator{
@@ -161,12 +166,13 @@ func checkDBConnection() {
func getNewDbConnection() *sqlx.DB {
for {
logging.LogInfo("Attempting to connect to database...", "host", utils.MythicConfig.PostgresHost, "port", utils.MythicConfig.PostgresPort)
conn, err := sqlx.Connect("postgres", fmt.Sprintf("user='%s' password='%s' host='%s' port='%d' dbname='%s' sslmode=disable connect_timeout=10",
conn, err := sqlx.Connect("postgres", fmt.Sprintf("user='%s' password='%s' host='%s' port='%d' dbname='%s' sslmode=%s connect_timeout=10",
utils.MythicConfig.PostgresUser,
utils.MythicConfig.PostgresPassword,
utils.MythicConfig.PostgresHost,
utils.MythicConfig.PostgresPort,
utils.MythicConfig.PostgresDB),
utils.MythicConfig.PostgresDB,
utils.MythicConfig.PostgresSSLMode),
)
if err != nil {
logging.LogError(err, "Failed to connect to database", "host", utils.MythicConfig.PostgresHost, "port", utils.MythicConfig.PostgresPort)
-2
View File
@@ -4847,8 +4847,6 @@ ALTER TABLE ONLY public.wrappedpayloadtypes
ALTER TABLE ONLY public.wrappedpayloadtypes
ADD CONSTRAINT wrappedpayloadtypes_wrapper_id_fkey FOREIGN KEY (wrapper_id) REFERENCES public.payloadtype(id) ON DELETE CASCADE;
CREATE EXTENSION pg_stat_statements SCHEMA public;
--
-- PostgreSQL database dump complete
--
+6
View File
@@ -47,6 +47,8 @@ type Config struct {
PostgresDB string
PostgresUser string
PostgresPassword string
PostgresSSLMode string
PostgresDebug bool
// jwt configuration
JWTSecret []byte
@@ -78,6 +80,8 @@ func Initialize() {
mythicEnv.SetDefault("postgres_db", "mythic_db")
mythicEnv.SetDefault("postgres_user", "mythic_user")
mythicEnv.SetDefault("postgres_password", "")
mythicEnv.SetDefault("postgres_sslmode", "disable")
mythicEnv.SetDefault("postgres_debug", false)
// rabbitmq configuration
mythicEnv.SetDefault("rabbitmq_host", "mythic_rabbitmq")
mythicEnv.SetDefault("rabbitmq_port", 5672)
@@ -180,6 +184,8 @@ func setConfigFromEnv(mythicEnv *viper.Viper) {
MythicConfig.PostgresDB = mythicEnv.GetString("postgres_db")
MythicConfig.PostgresUser = mythicEnv.GetString("postgres_user")
MythicConfig.PostgresPassword = mythicEnv.GetString("postgres_password")
MythicConfig.PostgresSSLMode = mythicEnv.GetString("postgres_sslmode")
MythicConfig.PostgresDebug = mythicEnv.GetBool("postgres_debug")
// rabbitmq configuration
MythicConfig.RabbitmqHost = mythicEnv.GetString("rabbitmq_host")
MythicConfig.RabbitmqPort = mythicEnv.GetUint("rabbitmq_port")