security: hardening по результатам аудита безопасности

This commit is contained in:
2026-08-08 22:48:16 +03:00
parent 8c8631ac9c
commit bf2bceb520
18 changed files with 400 additions and 20 deletions
+2 -1
View File
@@ -23,6 +23,7 @@ import (
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/retention"
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/storage/local"
"git.tswf.io/infra/go-synapse-backupper/pkg/domain"
"git.tswf.io/infra/go-synapse-backupper/pkg/domain/backup"
"git.tswf.io/infra/go-synapse-backupper/pkg/domain/crypto"
"git.tswf.io/infra/go-synapse-backupper/pkg/domain/pgdump"
)
@@ -98,7 +99,7 @@ var backupCmd = &cobra.Command{
Database: cfg.PG.Database,
User: cfg.PG.User,
Password: cfg.PG.Password,
Key: fmt.Sprintf("synapse-%s.dump.pqenc", startTime.Format("20060102-150405")),
Key: backup.ArtifactKey(startTime),
ExcludeTables: cfg.PG.ExcludeTables,
}
+3 -2
View File
@@ -134,7 +134,6 @@ func setBackupFlags(
_ = cmd.Flags().Set("pg-host", "localhost")
_ = cmd.Flags().Set("pg-port", "5432")
_ = cmd.Flags().Set("pg-user", "testuser")
_ = cmd.Flags().Set("pg-password", "testpass")
_ = cmd.Flags().Set("pg-database", "testdb")
}
@@ -162,6 +161,7 @@ func TestBackupCmd_Structure(t *testing.T) {
func TestBackupCmd_Success(t *testing.T) {
restoreGlobals(t)
t.Setenv("APP_PG_PASSWORD", "testpass")
backupDir := t.TempDir()
pqPath := filepath.Join(backupDir, "pq.pub")
@@ -240,7 +240,7 @@ func TestBackupCmd_Success(t *testing.T) {
key := dumper.receivedOpts.Key
matched, _ := regexp.MatchString(
`^synapse-\d{8}-\d{6}\.dump\.pqenc$`,
`^synapse-\d{8}-\d{6}-[a-f0-9]{6}\.dump\.pqenc$`,
key,
)
if !matched {
@@ -300,6 +300,7 @@ func TestBackupCmd_Success(t *testing.T) {
func TestBackupCmd_PgDumpFailure(t *testing.T) {
restoreGlobals(t)
t.Setenv("APP_PG_PASSWORD", "testpass")
backupDir := t.TempDir()
pqPath := filepath.Join(backupDir, "pq.pub")
+45
View File
@@ -0,0 +1,45 @@
package main
import (
"context"
"fmt"
"net/http"
"time"
"github.com/spf13/cobra"
)
func newHealthcheckCmd() *cobra.Command {
var port int
cmd := &cobra.Command{
Use: "healthcheck",
Short: "Check the scheduler health endpoint",
Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(cmd.Context(), 3*time.Second)
defer cancel()
url := fmt.Sprintf("http://127.0.0.1:%d/healthz", port)
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return fmt.Errorf("build health request: %w", err)
}
response, err := http.DefaultClient.Do(request)
if err != nil {
return fmt.Errorf("health request failed: %w", err)
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return fmt.Errorf("health check returned status %d", response.StatusCode)
}
return nil
},
}
cmd.Flags().IntVar(&port, "port", 8080, "Health check server port")
return cmd
}
+42
View File
@@ -0,0 +1,42 @@
package main
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestHealthcheckCmd_Success(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/healthz" {
t.Errorf("unexpected path: %q", r.URL.Path)
}
w.WriteHeader(http.StatusOK)
}))
defer server.Close()
cmd := newHealthcheckCmd()
cmd.SetArgs([]string{"--port", serverPort(server)})
if err := cmd.Execute(); err != nil {
t.Fatalf("healthcheck failed: %v", err)
}
}
func TestHealthcheckCmd_Failure(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusServiceUnavailable)
}))
defer server.Close()
cmd := newHealthcheckCmd()
cmd.SetArgs([]string{"--port", serverPort(server)})
err := cmd.Execute()
if err == nil {
t.Fatal("expected error for non-OK health status")
}
}
func serverPort(server *httptest.Server) string {
return server.Listener.Addr().String()[strings.LastIndex(server.Listener.Addr().String(), ":")+1:]
}
+6
View File
@@ -108,6 +108,12 @@ func newKeygenCmdWithDeps(reg crypto.Registry) *cobra.Command {
if err := privFile.Close(); err != nil {
return fmt.Errorf("close private key file %s: %w", privPath, err)
}
if err := os.Chmod(pubPath, 0o644); err != nil {
return fmt.Errorf("chmod public key file %s: %w", pubPath, err)
}
if err := os.Chmod(privPath, 0o600); err != nil {
return fmt.Errorf("chmod private key file %s: %w", privPath, err)
}
}
return nil
+1
View File
@@ -23,6 +23,7 @@ func main() {
rootCmd.AddCommand(restoreCmd)
rootCmd.AddCommand(runCmd)
rootCmd.AddCommand(newKeygenCmd())
rootCmd.AddCommand(newHealthcheckCmd())
rootCmd.AddCommand(generateConfigCmd())
if err := rootCmd.ExecuteContext(ctx); err != nil {