Db tls (#102)
* go mod tidy * complete example config * add tls support for db connection * add certpool to tlsConfig * add some lil docker scripts
This commit is contained in:
parent
bbc2494c58
commit
677490bc4e
|
@ -117,6 +117,18 @@ func main() {
|
||||||
Value: defaults.DbDatabase,
|
Value: defaults.DbDatabase,
|
||||||
EnvVars: []string{envNames.DbDatabase},
|
EnvVars: []string{envNames.DbDatabase},
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: flagNames.DbTLSMode,
|
||||||
|
Usage: "Database tls mode",
|
||||||
|
Value: defaults.DBTlsMode,
|
||||||
|
EnvVars: []string{envNames.DbTLSMode},
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: flagNames.DbTLSCACert,
|
||||||
|
Usage: "Path to CA cert for db tls connection",
|
||||||
|
Value: defaults.DBTlsCACert,
|
||||||
|
EnvVars: []string{envNames.DbTLSCACert},
|
||||||
|
},
|
||||||
|
|
||||||
// TEMPLATE FLAGS
|
// TEMPLATE FLAGS
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
docker build -t "superseriousbusiness/gotosocial:$(cat version)" .
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
docker push "superseriousbusiness/gotosocial:$(cat version)"
|
|
@ -18,7 +18,7 @@
|
||||||
##### GENERAL CONFIG ######
|
##### GENERAL CONFIG ######
|
||||||
###########################
|
###########################
|
||||||
# String. Log level to use throughout the application. Must be lower-case.
|
# String. Log level to use throughout the application. Must be lower-case.
|
||||||
# Options: ["debug","info","warn","error","fatal"]
|
# Options: ["trace","debug","info","warn","error","fatal"]
|
||||||
# Default: "info"
|
# Default: "info"
|
||||||
logLevel: "info"
|
logLevel: "info"
|
||||||
|
|
||||||
|
@ -66,14 +66,29 @@ db:
|
||||||
# REQUIRED
|
# REQUIRED
|
||||||
# String. Password to use for the database connection
|
# String. Password to use for the database connection
|
||||||
# Examples: ["password123","verysafepassword","postgres"]
|
# Examples: ["password123","verysafepassword","postgres"]
|
||||||
# Default: ""
|
# Default: "postgres"
|
||||||
password: ""
|
password: "postgres"
|
||||||
|
|
||||||
# String. Name of the database to use within the provided database type.
|
# String. Name of the database to use within the provided database type.
|
||||||
# Examples: ["mydb","postgres","gotosocial"]
|
# Examples: ["mydb","postgres","gotosocial"]
|
||||||
# Default: "postgres"
|
# Default: "postgres"
|
||||||
database: "postgres"
|
database: "postgres"
|
||||||
|
|
||||||
|
# String. Disable, enable, or require SSL/TLS connection to the database.
|
||||||
|
# If "disable" then no TLS connection will be attempted.
|
||||||
|
# If "enable" then TLS will be tried, but the database certificate won't be checked (for self-signed certs).
|
||||||
|
# If "require" then TLS will be required to make a connection, and a valid certificate must be presented.
|
||||||
|
# Options: ["disable", "enable", "require"]
|
||||||
|
# Default: "disable"
|
||||||
|
tlsMode: "disable"
|
||||||
|
|
||||||
|
# String. Path to a CA certificate on the host machine for db certificate validation.
|
||||||
|
# If this is left empty, just the host certificates will be used.
|
||||||
|
# If filled in, the certificate will be loaded and added to host certificates.
|
||||||
|
# Examples: ["/path/to/some/cert.crt"]
|
||||||
|
# Default: ""
|
||||||
|
tlsCACert: ""
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
##### WEB TEMPLATE CONFIG #####
|
##### WEB TEMPLATE CONFIG #####
|
||||||
###############################
|
###############################
|
||||||
|
@ -84,6 +99,11 @@ template:
|
||||||
# Default: "./web/template/"
|
# Default: "./web/template/"
|
||||||
baseDir: "./web/template/"
|
baseDir: "./web/template/"
|
||||||
|
|
||||||
|
# String. Directory from which gotosocial will attempt to serve static web assets (images, scripts).
|
||||||
|
# Examples: ["/some/absolute/path/", "./relative/path/", "../../some/weird/path/"]
|
||||||
|
# Default: "./web/assets/"
|
||||||
|
assetBaseDir: "./web/assets/"
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
##### ACCOUNTS CONFIG #####
|
##### ACCOUNTS CONFIG #####
|
||||||
###########################
|
###########################
|
||||||
|
@ -93,7 +113,142 @@ accounts:
|
||||||
# Options: [true, false]
|
# Options: [true, false]
|
||||||
# Default: true
|
# Default: true
|
||||||
openRegistration: true
|
openRegistration: true
|
||||||
|
|
||||||
# Bool. Do sign up requests require approval from an admin/moderator before an account can sign in/use the server?
|
# Bool. Do sign up requests require approval from an admin/moderator before an account can sign in/use the server?
|
||||||
# Options: [true, false]
|
# Options: [true, false]
|
||||||
# Default: true
|
# Default: true
|
||||||
requireApproval: true
|
requireApproval: true
|
||||||
|
|
||||||
|
# Bool. Are sign up requests required to submit a reason for the request (eg., an explanation of why they want to join the instance)?
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: true
|
||||||
|
reasonRequired: true
|
||||||
|
|
||||||
|
########################
|
||||||
|
##### MEDIA CONFIG #####
|
||||||
|
########################
|
||||||
|
# Config pertaining to user media uploads (videos, image, image descriptions).
|
||||||
|
media:
|
||||||
|
# Int. Maximum allowed image upload size in bytes.
|
||||||
|
# Examples: [2097152, 10485760]
|
||||||
|
# Default: 2097152 -- aka 2MB
|
||||||
|
maxImageSize: 2097152
|
||||||
|
|
||||||
|
# Int. Maximum allowed video upload size in bytes.
|
||||||
|
# Examples: [2097152, 10485760]
|
||||||
|
# Default: 10485760 -- aka 10MB
|
||||||
|
maxVideoSize: 10485760
|
||||||
|
|
||||||
|
# Int. Minimum amount of characters required as an image or video description.
|
||||||
|
# Examples: [500, 1000, 1500]
|
||||||
|
# Default: 0 (not required)
|
||||||
|
minDescriptionChars: 0
|
||||||
|
|
||||||
|
# Int. Maximum amount of characters permitted in an image or video description.
|
||||||
|
# Examples: [500, 1000, 1500]
|
||||||
|
# Default: 500
|
||||||
|
maxDescriptionChars: 500
|
||||||
|
|
||||||
|
##########################
|
||||||
|
##### STORAGE CONFIG #####
|
||||||
|
##########################
|
||||||
|
# Config pertaining to storage of user-created uploads (videos, images, etc).
|
||||||
|
storage:
|
||||||
|
# String. Type of storage backend to use.
|
||||||
|
# Examples: ["local", "s3"]
|
||||||
|
# Default: "local" (storage on local disk)
|
||||||
|
# NOTE: s3 storage is not yet supported!
|
||||||
|
backend: "local"
|
||||||
|
|
||||||
|
# String. Directory to use as a base path for storing files.
|
||||||
|
# Make sure whatever user/group gotosocial is running as has permission to access
|
||||||
|
# this directly, and create new subdirectories and files with in.
|
||||||
|
# Examples: ["/home/gotosocial/storage", "/opt/gotosocial/datastorage"]
|
||||||
|
# Default: "/gotosocial/storage"
|
||||||
|
basePath: "/gotosocial/storage"
|
||||||
|
|
||||||
|
# String. Protocol to use for serving stored files.
|
||||||
|
# It's very unlikely that you'll need to change this ever, but there might be edge cases.
|
||||||
|
# Examples: ["http", "https"]
|
||||||
|
serveProtocol: "https"
|
||||||
|
|
||||||
|
# String. Host for serving stored files.
|
||||||
|
# If you're using local storage, this should be THE SAME as the value you've set for Host, above.
|
||||||
|
# It should only be a different value if you're serving stored files from a host
|
||||||
|
# other than the one your instance is running on.
|
||||||
|
# Examples: ["localhost", "example.org"]
|
||||||
|
# Default: "localhost" -- you should absolutely change this.
|
||||||
|
serveHost: "localhost"
|
||||||
|
|
||||||
|
# String. Base path for serving stored files. This will be added to serveHost and serveProtocol
|
||||||
|
# to form the prefix url of your stored files. Eg., https://example.org/fileserver/.....
|
||||||
|
# It's unlikely that you will need to change this.
|
||||||
|
# Examples: ["/fileserver", "/media"]
|
||||||
|
# Default: "/fileserver"
|
||||||
|
serveBasePath: "/fileserver"
|
||||||
|
|
||||||
|
###########################
|
||||||
|
##### STATUSES CONFIG #####
|
||||||
|
###########################
|
||||||
|
# Config pertaining to the creation of statuses/posts, and permitted limits.
|
||||||
|
statuses:
|
||||||
|
# Int. Maximum amount of characters permitted for a new status.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [140, 500, 5000]
|
||||||
|
# Default: 5000
|
||||||
|
maxChars: 5000
|
||||||
|
|
||||||
|
# Int. Maximum amount of characters allowed in the CW/subject header of a status.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [100, 200]
|
||||||
|
# Default: 100
|
||||||
|
cwMaxChars: 100
|
||||||
|
|
||||||
|
# Int. Maximum amount of options to permit when creating a new poll.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [4, 6, 10]
|
||||||
|
# Default: 6
|
||||||
|
pollMaxOptions: 6
|
||||||
|
|
||||||
|
# Int. Maximum amount of characters to permit per poll option when creating a new poll.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [50, 100, 150]
|
||||||
|
# Default: 50
|
||||||
|
pollOptionMaxChars: 50
|
||||||
|
|
||||||
|
# Int. Maximum amount of media files that can be attached to a new status.
|
||||||
|
# Note that going way higher than the default might break federation.
|
||||||
|
# Examples: [4, 6, 10]
|
||||||
|
# Default: 6
|
||||||
|
maxMediaFiles: 6
|
||||||
|
|
||||||
|
##############################
|
||||||
|
##### LETSENCRYPT CONFIG #####
|
||||||
|
##############################
|
||||||
|
# Config pertaining to the automatic acquisition and use of LetsEncrypt HTTPS certificates.
|
||||||
|
letsEncrypt:
|
||||||
|
# Bool. Whether or not letsencrypt should be enabled for the server.
|
||||||
|
# If true, the server will serve on port 443 (https) and obtain letsencrypt
|
||||||
|
# certificates automatically.
|
||||||
|
# If false, the server will serve on port 8080 (http), and the rest of the settings
|
||||||
|
# here will be ignored.
|
||||||
|
# You should only change this if you want to serve GoToSocial behind a reverse proxy
|
||||||
|
# like Traefik, HAProxy, or Nginx.
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: true
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
# String. Directory in which to store LetsEncrypt certificates.
|
||||||
|
# It is a good move to make this a sub-path within your storage directory, as it makes
|
||||||
|
# backup easier, but you might wish to move them elsewhere if they're also accessed by other services.
|
||||||
|
# In any case, make sure GoToSocial has permissions to write to / read from this directory.
|
||||||
|
# Examples: ["/home/gotosocial/storage/certs", "/acmecerts"]
|
||||||
|
# Default: "/gotosocial/storage/certs"
|
||||||
|
certDir: "/gotosocial/storage/certs"
|
||||||
|
|
||||||
|
# String. Email address to use when registering LetsEncrypt certs.
|
||||||
|
# Most likely, this will be the email address of the instance administrator.
|
||||||
|
# LetsEncrypt will send notifications about expiring certificates etc to this address.
|
||||||
|
# Examples: ["admin@example.org"]
|
||||||
|
# Default: ""
|
||||||
|
emailAddress: ""
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -15,7 +15,6 @@ require (
|
||||||
github.com/dsoprea/go-utility v0.0.0-20200717064901-2fccff4aa15e // indirect
|
github.com/dsoprea/go-utility v0.0.0-20200717064901-2fccff4aa15e // indirect
|
||||||
github.com/gin-contrib/cors v1.3.1
|
github.com/gin-contrib/cors v1.3.1
|
||||||
github.com/gin-contrib/sessions v0.0.3
|
github.com/gin-contrib/sessions v0.0.3
|
||||||
github.com/gin-contrib/static v0.0.1
|
|
||||||
github.com/gin-gonic/gin v1.7.2
|
github.com/gin-gonic/gin v1.7.2
|
||||||
github.com/go-errors/errors v1.4.0 // indirect
|
github.com/go-errors/errors v1.4.0 // indirect
|
||||||
github.com/go-fed/activity v1.0.1-0.20210426194615-e0de0863dcc1
|
github.com/go-fed/activity v1.0.1-0.20210426194615-e0de0863dcc1
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -69,10 +69,7 @@ github.com/gin-contrib/sessions v0.0.3 h1:PoBXki+44XdJdlgDqDrY5nDVe3Wk7wDV/UCOuL
|
||||||
github.com/gin-contrib/sessions v0.0.3/go.mod h1:8C/J6cad3Il1mWYYgtw0w+hqasmpvy25mPkXdOgeB9I=
|
github.com/gin-contrib/sessions v0.0.3/go.mod h1:8C/J6cad3Il1mWYYgtw0w+hqasmpvy25mPkXdOgeB9I=
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-contrib/static v0.0.1 h1:JVxuvHPuUfkoul12N7dtQw7KRn/pSMq7Ue1Va9Swm1U=
|
|
||||||
github.com/gin-contrib/static v0.0.1/go.mod h1:CSxeF+wep05e0kCOsqWdAWbSszmc31zTIbD8TvWl7Hs=
|
|
||||||
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
|
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
|
||||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
|
||||||
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
||||||
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||||
|
@ -101,7 +98,6 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM
|
||||||
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
|
||||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||||
github.com/go-playground/validator/v10 v10.6.1 h1:W6TRDXt4WcWp4c4nf/G+6BkGdhiIo0k417gfr+V6u4I=
|
github.com/go-playground/validator/v10 v10.6.1 h1:W6TRDXt4WcWp4c4nf/G+6BkGdhiIo0k417gfr+V6u4I=
|
||||||
github.com/go-playground/validator/v10 v10.6.1/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk=
|
github.com/go-playground/validator/v10 v10.6.1/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk=
|
||||||
|
|
|
@ -165,6 +165,14 @@ func (c *Config) ParseCLIFlags(f KeyedFlags, version string) error {
|
||||||
c.DBConfig.Database = f.String(fn.DbDatabase)
|
c.DBConfig.Database = f.String(fn.DbDatabase)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.DBConfig.TLSMode == DBTLSModeUnset || f.IsSet(fn.DbTLSMode) {
|
||||||
|
c.DBConfig.TLSMode = DBTLSMode(f.String(fn.DbTLSMode))
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.DBConfig.TLSCACert == "" || f.IsSet(fn.DbTLSCACert) {
|
||||||
|
c.DBConfig.TLSCACert = f.String(fn.DbTLSCACert)
|
||||||
|
}
|
||||||
|
|
||||||
// template flags
|
// template flags
|
||||||
if c.TemplateConfig.BaseDir == "" || f.IsSet(fn.TemplateBaseDir) {
|
if c.TemplateConfig.BaseDir == "" || f.IsSet(fn.TemplateBaseDir) {
|
||||||
c.TemplateConfig.BaseDir = f.String(fn.TemplateBaseDir)
|
c.TemplateConfig.BaseDir = f.String(fn.TemplateBaseDir)
|
||||||
|
@ -284,12 +292,14 @@ type Flags struct {
|
||||||
Host string
|
Host string
|
||||||
Protocol string
|
Protocol string
|
||||||
|
|
||||||
DbType string
|
DbType string
|
||||||
DbAddress string
|
DbAddress string
|
||||||
DbPort string
|
DbPort string
|
||||||
DbUser string
|
DbUser string
|
||||||
DbPassword string
|
DbPassword string
|
||||||
DbDatabase string
|
DbDatabase string
|
||||||
|
DbTLSMode string
|
||||||
|
DbTLSCACert string
|
||||||
|
|
||||||
TemplateBaseDir string
|
TemplateBaseDir string
|
||||||
AssetBaseDir string
|
AssetBaseDir string
|
||||||
|
@ -329,12 +339,14 @@ type Defaults struct {
|
||||||
Protocol string
|
Protocol string
|
||||||
SoftwareVersion string
|
SoftwareVersion string
|
||||||
|
|
||||||
DbType string
|
DbType string
|
||||||
DbAddress string
|
DbAddress string
|
||||||
DbPort int
|
DbPort int
|
||||||
DbUser string
|
DbUser string
|
||||||
DbPassword string
|
DbPassword string
|
||||||
DbDatabase string
|
DbDatabase string
|
||||||
|
DBTlsMode string
|
||||||
|
DBTlsCACert string
|
||||||
|
|
||||||
TemplateBaseDir string
|
TemplateBaseDir string
|
||||||
AssetBaseDir string
|
AssetBaseDir string
|
||||||
|
@ -375,12 +387,14 @@ func GetFlagNames() Flags {
|
||||||
Host: "host",
|
Host: "host",
|
||||||
Protocol: "protocol",
|
Protocol: "protocol",
|
||||||
|
|
||||||
DbType: "db-type",
|
DbType: "db-type",
|
||||||
DbAddress: "db-address",
|
DbAddress: "db-address",
|
||||||
DbPort: "db-port",
|
DbPort: "db-port",
|
||||||
DbUser: "db-user",
|
DbUser: "db-user",
|
||||||
DbPassword: "db-password",
|
DbPassword: "db-password",
|
||||||
DbDatabase: "db-database",
|
DbDatabase: "db-database",
|
||||||
|
DbTLSMode: "db-tls-mode",
|
||||||
|
DbTLSCACert: "db-tls-ca-cert",
|
||||||
|
|
||||||
TemplateBaseDir: "template-basedir",
|
TemplateBaseDir: "template-basedir",
|
||||||
AssetBaseDir: "asset-basedir",
|
AssetBaseDir: "asset-basedir",
|
||||||
|
@ -422,12 +436,14 @@ func GetEnvNames() Flags {
|
||||||
Host: "GTS_HOST",
|
Host: "GTS_HOST",
|
||||||
Protocol: "GTS_PROTOCOL",
|
Protocol: "GTS_PROTOCOL",
|
||||||
|
|
||||||
DbType: "GTS_DB_TYPE",
|
DbType: "GTS_DB_TYPE",
|
||||||
DbAddress: "GTS_DB_ADDRESS",
|
DbAddress: "GTS_DB_ADDRESS",
|
||||||
DbPort: "GTS_DB_PORT",
|
DbPort: "GTS_DB_PORT",
|
||||||
DbUser: "GTS_DB_USER",
|
DbUser: "GTS_DB_USER",
|
||||||
DbPassword: "GTS_DB_PASSWORD",
|
DbPassword: "GTS_DB_PASSWORD",
|
||||||
DbDatabase: "GTS_DB_DATABASE",
|
DbDatabase: "GTS_DB_DATABASE",
|
||||||
|
DbTLSMode: "GTS_DB_TLS_MODE",
|
||||||
|
DbTLSCACert: "GTS_DB_CA_CERT",
|
||||||
|
|
||||||
TemplateBaseDir: "GTS_TEMPLATE_BASEDIR",
|
TemplateBaseDir: "GTS_TEMPLATE_BASEDIR",
|
||||||
AssetBaseDir: "GTS_ASSET_BASEDIR",
|
AssetBaseDir: "GTS_ASSET_BASEDIR",
|
||||||
|
|
|
@ -20,11 +20,30 @@ package config
|
||||||
|
|
||||||
// DBConfig provides configuration options for the database connection
|
// DBConfig provides configuration options for the database connection
|
||||||
type DBConfig struct {
|
type DBConfig struct {
|
||||||
Type string `yaml:"type"`
|
Type string `yaml:"type"`
|
||||||
Address string `yaml:"address"`
|
Address string `yaml:"address"`
|
||||||
Port int `yaml:"port"`
|
Port int `yaml:"port"`
|
||||||
User string `yaml:"user"`
|
User string `yaml:"user"`
|
||||||
Password string `yaml:"password"`
|
Password string `yaml:"password"`
|
||||||
Database string `yaml:"database"`
|
Database string `yaml:"database"`
|
||||||
ApplicationName string `yaml:"applicationName"`
|
ApplicationName string `yaml:"applicationName"`
|
||||||
|
TLSMode DBTLSMode `yaml:"tlsMode"`
|
||||||
|
TLSCACert string `yaml:"tlsCACert"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DBTLSMode describes a mode of connecting to a database with or without TLS.
|
||||||
|
type DBTLSMode string
|
||||||
|
|
||||||
|
// DBTLSModeDisable does not attempt to make a TLS connection to the database.
|
||||||
|
var DBTLSModeDisable DBTLSMode = "disable"
|
||||||
|
|
||||||
|
// DBTLSModeEnable attempts to make a TLS connection to the database, but doesn't fail if
|
||||||
|
// the certificate passed by the database isn't verified.
|
||||||
|
var DBTLSModeEnable DBTLSMode = "enable"
|
||||||
|
|
||||||
|
// DBTLSModeRequire attempts to make a TLS connection to the database, and requires
|
||||||
|
// that the certificate presented by the database is valid.
|
||||||
|
var DBTLSModeRequire DBTLSMode = "require"
|
||||||
|
|
||||||
|
// DBTLSModeUnset means that the TLS mode has not been set.
|
||||||
|
var DBTLSModeUnset DBTLSMode = ""
|
||||||
|
|
|
@ -120,12 +120,14 @@ func GetDefaults() Defaults {
|
||||||
Host: "",
|
Host: "",
|
||||||
Protocol: "https",
|
Protocol: "https",
|
||||||
|
|
||||||
DbType: "postgres",
|
DbType: "postgres",
|
||||||
DbAddress: "localhost",
|
DbAddress: "localhost",
|
||||||
DbPort: 5432,
|
DbPort: 5432,
|
||||||
DbUser: "postgres",
|
DbUser: "postgres",
|
||||||
DbPassword: "postgres",
|
DbPassword: "postgres",
|
||||||
DbDatabase: "postgres",
|
DbDatabase: "postgres",
|
||||||
|
DBTlsMode: "disable",
|
||||||
|
DBTlsCACert: "",
|
||||||
|
|
||||||
TemplateBaseDir: "./web/template/",
|
TemplateBaseDir: "./web/template/",
|
||||||
AssetBaseDir: "./web/assets/",
|
AssetBaseDir: "./web/assets/",
|
||||||
|
|
|
@ -22,10 +22,14 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -133,6 +137,53 @@ func derivePGOptions(c *config.Config) (*pg.Options, error) {
|
||||||
return nil, errors.New("no database set")
|
return nil, errors.New("no database set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tlsConfig *tls.Config
|
||||||
|
switch c.DBConfig.TLSMode {
|
||||||
|
case config.DBTLSModeDisable, config.DBTLSModeUnset:
|
||||||
|
break // nothing to do
|
||||||
|
case config.DBTLSModeEnable:
|
||||||
|
tlsConfig = &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
}
|
||||||
|
case config.DBTLSModeRequire:
|
||||||
|
tlsConfig = &tls.Config{
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tlsConfig != nil && c.DBConfig.TLSCACert != "" {
|
||||||
|
// load the system cert pool first -- we'll append the given CA cert to this
|
||||||
|
certPool, err := x509.SystemCertPool()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetching system CA cert pool: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// open the file itself and make sure there's something in it
|
||||||
|
caCertBytes, err := os.ReadFile(c.DBConfig.TLSCACert)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error opening CA certificate at %s: %s", c.DBConfig.TLSCACert, err)
|
||||||
|
}
|
||||||
|
if len(caCertBytes) == 0 {
|
||||||
|
return nil, fmt.Errorf("ca cert at %s was empty", c.DBConfig.TLSCACert)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure we have a PEM block
|
||||||
|
caPem, _ := pem.Decode(caCertBytes)
|
||||||
|
if caPem == nil {
|
||||||
|
return nil, fmt.Errorf("could not parse cert at %s into PEM", c.DBConfig.TLSCACert)
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse the PEM block into the certificate
|
||||||
|
caCert, err := x509.ParseCertificate(caPem.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not parse cert at %s into x509 certificate: %s", c.DBConfig.TLSCACert, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're happy, add it to the existing pool and then use this pool in our tls config
|
||||||
|
certPool.AddCert(caCert)
|
||||||
|
tlsConfig.RootCAs = certPool
|
||||||
|
}
|
||||||
|
|
||||||
// We can rely on the pg library we're using to set
|
// We can rely on the pg library we're using to set
|
||||||
// sensible defaults for everything we don't set here.
|
// sensible defaults for everything we don't set here.
|
||||||
options := &pg.Options{
|
options := &pg.Options{
|
||||||
|
@ -141,6 +192,7 @@ func derivePGOptions(c *config.Config) (*pg.Options, error) {
|
||||||
Password: c.DBConfig.Password,
|
Password: c.DBConfig.Password,
|
||||||
Database: c.DBConfig.Database,
|
Database: c.DBConfig.Database,
|
||||||
ApplicationName: c.ApplicationName,
|
ApplicationName: c.ApplicationName,
|
||||||
|
TLSConfig: tlsConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
return options, nil
|
return options, nil
|
||||||
|
|
Loading…
Reference in New Issue