Bundle certbot's DH parameters as a resource instead of downloading them
certbot removed ssl-dhparams.pem from its repository, so the managed-nginx startup failed with HTTP 404 on fresh installations (the legacy script only kept working through its year-old state-dir cache). The RFC 7919 ffdhe2048 parameters are now a classpath resource; the download seam and NginxConfigFiles.DH_PARAMS_URL are gone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
66183f9765
commit
800fcae2f7
@@ -77,7 +77,4 @@ object NginxConfigFiles {
|
|||||||
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:" +
|
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:" +
|
||||||
"DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384\";\n" +
|
"DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384\";\n" +
|
||||||
"ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;\n"
|
"ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;\n"
|
||||||
|
|
||||||
/** Certbot's pinned DH parameters, downloaded once into the state dir (like legacy). */
|
|
||||||
const val DH_PARAMS_URL: String = "https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,9 @@ import de.hoennig.gittally.config.ConfigLoader
|
|||||||
import de.hoennig.gittally.git.GitCommandRunner
|
import de.hoennig.gittally.git.GitCommandRunner
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
import java.net.URI
|
|
||||||
import java.net.http.HttpClient
|
|
||||||
import java.net.http.HttpRequest
|
|
||||||
import java.net.http.HttpResponse
|
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.time.Duration
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the opt-in nginx+certbot Docker container that serves GitTally over
|
* Manages the opt-in nginx+certbot Docker container that serves GitTally over
|
||||||
@@ -36,9 +31,6 @@ class NginxProxyManager(
|
|||||||
|
|
||||||
var workingDir: Path = Paths.get(".")
|
var workingDir: Path = Paths.get(".")
|
||||||
|
|
||||||
/** Replaceable for tests: fetches certbot's pinned DH parameters into [target]; throws on failure. */
|
|
||||||
internal var dhParamsDownloader: (target: Path) -> Unit = ::downloadDhParams
|
|
||||||
|
|
||||||
/** Replaceable for tests: the wait between port-conflict re-checks. */
|
/** Replaceable for tests: the wait between port-conflict re-checks. */
|
||||||
internal var sleeper: (millis: Long) -> Unit = Thread::sleep
|
internal var sleeper: (millis: Long) -> Unit = Thread::sleep
|
||||||
|
|
||||||
@@ -188,7 +180,7 @@ class NginxProxyManager(
|
|||||||
Files.writeString(settings.certbotConf.resolve("options-ssl-nginx.conf"), NginxConfigFiles.SSL_OPTIONS)
|
Files.writeString(settings.certbotConf.resolve("options-ssl-nginx.conf"), NginxConfigFiles.SSL_OPTIONS)
|
||||||
val dhParams = settings.certbotConf.resolve("ssl-dhparams.pem")
|
val dhParams = settings.certbotConf.resolve("ssl-dhparams.pem")
|
||||||
if (!Files.exists(dhParams)) {
|
if (!Files.exists(dhParams)) {
|
||||||
dhParamsDownloader(dhParams)
|
writeBundledDhParams(dhParams)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,19 +416,16 @@ class NginxProxyManager(
|
|||||||
fun defaultContainerName(repoDir: Path): String =
|
fun defaultContainerName(repoDir: Path): String =
|
||||||
"gittally-nginx-" + repoDir.fileName.toString().replace(Regex("[^A-Za-z0-9_.-]"), "-")
|
"gittally-nginx-" + repoDir.fileName.toString().replace(Regex("[^A-Za-z0-9_.-]"), "-")
|
||||||
|
|
||||||
private fun downloadDhParams(target: Path) {
|
/**
|
||||||
val response =
|
* Certbot's pinned DH parameters (RFC 7919 ffdhe2048), bundled as a resource:
|
||||||
HttpClient
|
* certbot removed the file from its repository, so it can no longer be downloaded.
|
||||||
.newBuilder()
|
*/
|
||||||
.connectTimeout(Duration.ofSeconds(10))
|
private fun writeBundledDhParams(target: Path) {
|
||||||
.followRedirects(HttpClient.Redirect.NORMAL)
|
val resource =
|
||||||
.build()
|
checkNotNull(NginxProxyManager::class.java.getResourceAsStream("/nginx/ssl-dhparams.pem")) {
|
||||||
.send(
|
"bundled nginx/ssl-dhparams.pem resource is missing"
|
||||||
HttpRequest.newBuilder(URI.create(NginxConfigFiles.DH_PARAMS_URL)).GET().build(),
|
}
|
||||||
HttpResponse.BodyHandlers.ofString(),
|
resource.use { Files.copy(it, target) }
|
||||||
)
|
|
||||||
check(response.statusCode() == 200) { "downloading ssl-dhparams.pem failed with HTTP ${response.statusCode()}" }
|
|
||||||
Files.writeString(target, response.body())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN DH PARAMETERS-----
|
||||||
|
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||||
|
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||||
|
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||||
|
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||||
|
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||||
|
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
||||||
|
-----END DH PARAMETERS-----
|
||||||
@@ -126,7 +126,6 @@ class NginxProxyManagerTest : FunSpec() {
|
|||||||
}
|
}
|
||||||
manager = NginxProxyManager(commandRunner, configLoader)
|
manager = NginxProxyManager(commandRunner, configLoader)
|
||||||
manager.workingDir = repoDir
|
manager.workingDir = repoDir
|
||||||
manager.dhParamsDownloader = { Files.writeString(it, "dh-params") }
|
|
||||||
manager.sleeper = { sleepCount++ }
|
manager.sleeper = { sleepCount++ }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +197,8 @@ class NginxProxyManagerTest : FunSpec() {
|
|||||||
"--register-unsafely-without-email",
|
"--register-unsafely-without-email",
|
||||||
)
|
)
|
||||||
Files.readString(stateDir.resolve("certbot/conf/options-ssl-nginx.conf")) shouldBe NginxConfigFiles.SSL_OPTIONS
|
Files.readString(stateDir.resolve("certbot/conf/options-ssl-nginx.conf")) shouldBe NginxConfigFiles.SSL_OPTIONS
|
||||||
Files.readString(stateDir.resolve("certbot/conf/ssl-dhparams.pem")) shouldBe "dh-params"
|
// the bundled RFC 7919 ffdhe2048 parameters, vendored because certbot removed the download
|
||||||
|
Files.readString(stateDir.resolve("certbot/conf/ssl-dhparams.pem")) shouldContain "BEGIN DH PARAMETERS"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("start with an existing certificate uses the full config immediately and renews") {
|
test("start with an existing certificate uses the full config immediately and renews") {
|
||||||
|
|||||||
Reference in New Issue
Block a user