mirror of
https://github.com/decke/smtprelay.git
synced 2026-06-24 11:20:01 -06:00
Compare commits
9 Commits
v1.13.3
...
c1be36e929
| Author | SHA1 | Date | |
|---|---|---|---|
| c1be36e929 | |||
| 0c3ca70805 | |||
| c60804397f | |||
| bc021a7bff | |||
| 49c00bf7d8 | |||
| 8dcd6c8067 | |||
| d634a89b14 | |||
| 85a9c49471 | |||
| 808b662e01 |
@@ -38,7 +38,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ jobs:
|
|||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -58,7 +58,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@@ -72,4 +72,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
|
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -76,6 +76,6 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ var (
|
|||||||
listenStr = flagset.String("listen", "127.0.0.1:25 [::1]:25", "Address and port to listen for incoming SMTP")
|
listenStr = flagset.String("listen", "127.0.0.1:25 [::1]:25", "Address and port to listen for incoming SMTP")
|
||||||
localCert = flagset.String("local_cert", "", "SSL certificate for STARTTLS/TLS")
|
localCert = flagset.String("local_cert", "", "SSL certificate for STARTTLS/TLS")
|
||||||
localKey = flagset.String("local_key", "", "SSL private key for STARTTLS/TLS")
|
localKey = flagset.String("local_key", "", "SSL private key for STARTTLS/TLS")
|
||||||
|
tlsProfile = flagset.String("tls_profile", "default", "TLS profile: modern | intermediate | default | legacy")
|
||||||
localForceTLS = flagset.Bool("local_forcetls", false, "Force STARTTLS (needs local_cert and local_key)")
|
localForceTLS = flagset.Bool("local_forcetls", false, "Force STARTTLS (needs local_cert and local_key)")
|
||||||
readTimeoutStr = flagset.String("read_timeout", "60s", "Socket timeout for read operations")
|
readTimeoutStr = flagset.String("read_timeout", "60s", "Socket timeout for read operations")
|
||||||
writeTimeoutStr = flagset.String("write_timeout", "60s", "Socket timeout for write operations")
|
writeTimeoutStr = flagset.String("write_timeout", "60s", "Socket timeout for write operations")
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ module github.com/decke/smtprelay
|
|||||||
require (
|
require (
|
||||||
github.com/DeRuina/timberjack v1.4.2
|
github.com/DeRuina/timberjack v1.4.2
|
||||||
github.com/chrj/smtpd v1.0.0
|
github.com/chrj/smtpd v1.0.0
|
||||||
github.com/fsnotify/fsnotify v1.10.0
|
github.com/fsnotify/fsnotify v1.10.1
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/peterbourgon/ff/v3 v3.4.0
|
github.com/peterbourgon/ff/v3 v3.4.0
|
||||||
github.com/rs/zerolog v1.35.1
|
github.com/rs/zerolog v1.35.1
|
||||||
github.com/stretchr/testify v1.11.1
|
github.com/stretchr/testify v1.11.1
|
||||||
golang.org/x/crypto v0.50.0
|
golang.org/x/crypto v0.51.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -17,7 +17,7 @@ require (
|
|||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
golang.org/x/sys v0.43.0 // indirect
|
golang.org/x/sys v0.44.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
||||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||||
github.com/fsnotify/fsnotify v1.10.0 h1:Xx/5Ydg9CeBDX/wi4VJqStNtohYjitZhhlHt4h3St1M=
|
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
|
||||||
github.com/fsnotify/fsnotify v1.10.0/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
|
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
|
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
|
||||||
@@ -24,11 +24,11 @@ github.com/rs/zerolog v1.35.1 h1:m7xQeoiLIiV0BCEY4Hs+j2NG4Gp2o2KPKmhnnLiazKI=
|
|||||||
github.com/rs/zerolog v1.35.1/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
|
github.com/rs/zerolog v1.35.1/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
|
||||||
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
|
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
|
||||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
|||||||
@@ -281,6 +281,7 @@ func generateUUID() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getTLSConfig() *tls.Config {
|
func getTLSConfig() *tls.Config {
|
||||||
|
// Certificate loading / validation
|
||||||
if *localCert == "" || *localKey == "" {
|
if *localCert == "" || *localKey == "" {
|
||||||
log.Fatal().
|
log.Fatal().
|
||||||
Str("cert_file", *localCert).
|
Str("cert_file", *localCert).
|
||||||
@@ -295,9 +296,60 @@ func getTLSConfig() *tls.Config {
|
|||||||
Msg("cannot load X509 keypair")
|
Msg("cannot load X509 keypair")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tls.Config{
|
// TLS profile configuration
|
||||||
|
// tls.Config.CipherSuites only affects TLS 1.0–1.2.
|
||||||
|
|
||||||
|
// Base config: Go defaults unless overridden.
|
||||||
|
conf := &tls.Config{
|
||||||
Certificates: []tls.Certificate{cert},
|
Certificates: []tls.Certificate{cert},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profile := strings.ToLower(strings.TrimSpace(*tlsProfile))
|
||||||
|
if profile == "" {
|
||||||
|
profile = "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
switch profile {
|
||||||
|
case "default":
|
||||||
|
// Go defaults (leave MinVersion/MaxVersion/CipherSuites unset).
|
||||||
|
|
||||||
|
case "modern":
|
||||||
|
// TLS 1.3+.
|
||||||
|
conf.MinVersion = tls.VersionTLS13
|
||||||
|
|
||||||
|
case "intermediate":
|
||||||
|
// TLS 1.2+ with AEAD + ECDHE cipher suites only.
|
||||||
|
// Mozilla "intermediate" — AEAD + ECDHE only.
|
||||||
|
conf.MinVersion = tls.VersionTLS12
|
||||||
|
conf.CipherSuites = []uint16{
|
||||||
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||||
|
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||||
|
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||||
|
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||||
|
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||||
|
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||||
|
}
|
||||||
|
|
||||||
|
case "legacy":
|
||||||
|
// Last resort: TLS 1.0+ and everything Go exposes for TLS 1.0–1.2.
|
||||||
|
conf.MinVersion = tls.VersionTLS10
|
||||||
|
|
||||||
|
allSuites := []uint16{}
|
||||||
|
for _, cs := range tls.CipherSuites() {
|
||||||
|
allSuites = append(allSuites, cs.ID)
|
||||||
|
}
|
||||||
|
for _, cs := range tls.InsecureCipherSuites() {
|
||||||
|
allSuites = append(allSuites, cs.ID)
|
||||||
|
}
|
||||||
|
conf.CipherSuites = allSuites
|
||||||
|
|
||||||
|
default:
|
||||||
|
log.Warn().
|
||||||
|
Str("tls_profile", profile).
|
||||||
|
Msg("unknown tls_profile; using default")
|
||||||
|
}
|
||||||
|
|
||||||
|
return conf
|
||||||
}
|
}
|
||||||
|
|
||||||
func watchAliasFile() {
|
func watchAliasFile() {
|
||||||
|
|||||||
@@ -35,6 +35,33 @@
|
|||||||
;local_cert = smtpd.pem
|
;local_cert = smtpd.pem
|
||||||
;local_key = smtpd.key
|
;local_key = smtpd.key
|
||||||
|
|
||||||
|
; TLS PROFILE (STARTTLS / TLS listeners)
|
||||||
|
; Controls the minimum TLS version and allowed cipher suites for inbound
|
||||||
|
; connections when using listen protocols `starttls://` or `tls://`.
|
||||||
|
; Profiles follow the Mozilla SSL Configuration Generator guidelines.
|
||||||
|
;
|
||||||
|
; default
|
||||||
|
; Go standard library defaults. Tracks improvements as Go updates
|
||||||
|
; its TLS defaults. Recommended for most deployments.
|
||||||
|
;
|
||||||
|
; modern
|
||||||
|
; TLS 1.3+ only. Simplest and most secure, but rejects any client
|
||||||
|
; that cannot negotiate TLS 1.3.
|
||||||
|
; Matches Mozilla "modern" configuration.
|
||||||
|
;
|
||||||
|
; intermediate
|
||||||
|
; TLS 1.2+. For TLS 1.2 connections only AEAD ciphers (AES-GCM,
|
||||||
|
; ChaCha20-Poly1305) with ECDHE key exchange are allowed,
|
||||||
|
; providing forward secrecy. TLS 1.3 ciphers are always available.
|
||||||
|
; Matches Mozilla "intermediate" configuration.
|
||||||
|
;
|
||||||
|
; legacy
|
||||||
|
; TLS 1.0+ with all cipher suites the Go standard library supports,
|
||||||
|
; including insecure ones (RC4, 3DES). Use only when you must
|
||||||
|
; support very old clients that cannot negotiate TLS 1.2.
|
||||||
|
;
|
||||||
|
;tls_profile=default
|
||||||
|
|
||||||
; Enforce encrypted connection on STARTTLS ports before
|
; Enforce encrypted connection on STARTTLS ports before
|
||||||
; accepting mails from client.
|
; accepting mails from client.
|
||||||
;local_forcetls = false
|
;local_forcetls = false
|
||||||
|
|||||||
Reference in New Issue
Block a user