Add gen-nginx for the read path

This commit is contained in:
Pim van Pelt
2025-08-24 14:05:26 +02:00
parent ca6797c1f6
commit efa92a73bd
2 changed files with 139 additions and 0 deletions

View File

@@ -56,6 +56,8 @@ func main() {
generateEnv(*configFile) generateEnv(*configFile)
case "gen-key": case "gen-key":
generateKeys(*configFile) generateKeys(*configFile)
case "gen-nginx":
generateNginx(*configFile)
case "gen-roots": case "gen-roots":
generateRoots(args[1:]) generateRoots(args[1:])
default: default:
@@ -103,6 +105,8 @@ func showHelp() {
fmt.Printf(" Combines global roots and log-specific extraroots into roots.pem.\n\n") fmt.Printf(" Combines global roots and log-specific extraroots into roots.pem.\n\n")
fmt.Printf(" gen-key Generate prime256v1 private keys for each log (only if they don't exist).\n") fmt.Printf(" gen-key Generate prime256v1 private keys for each log (only if they don't exist).\n")
fmt.Printf(" Creates EC private key files at the path specified in log.secret.\n\n") fmt.Printf(" Creates EC private key files at the path specified in log.secret.\n\n")
fmt.Printf(" gen-nginx Generate nginx configuration files for each log's monitoring endpoint.\n")
fmt.Printf(" Creates nginx-<hostname>.conf files in each log's localdirectory.\n\n")
fmt.Printf(" gen-roots Download root certificates from a Certificate Transparency log.\n") fmt.Printf(" gen-roots Download root certificates from a Certificate Transparency log.\n")
fmt.Printf(" Options: --source <url> (default: https://rennet2027h2.log.ct.ipng.ch/)\n") fmt.Printf(" Options: --source <url> (default: https://rennet2027h2.log.ct.ipng.ch/)\n")
fmt.Printf(" --output <file> (default: roots.pem)\n\n") fmt.Printf(" --output <file> (default: roots.pem)\n\n")

135
tesseract/genconf/nginx.go Normal file
View File

@@ -0,0 +1,135 @@
package main
import (
"fmt"
"net/url"
"os"
"path/filepath"
"strings"
"text/template"
)
const nginxTemplate = `server {
listen 8080;
listen [::]:8080;
# Replace with your actual domain(s)
server_name {{.MonitoringHost}};
# Document root for static files
root {{.LocalDirectory}};
location = / {
try_files /index.html =404;
add_header Content-Type "text/html; charset=utf-8" always;
add_header Access-Control-Allow-Origin "*" always;
}
# Checkpoint endpoint - no caching
location = /checkpoint {
try_files /checkpoint =404;
add_header Content-Type "text/plain; charset=utf-8" always;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "no-store" always;
}
# Log info endpoint
location = /log.v3.json {
try_files /log.v3.json =404;
add_header Content-Type "application/json" always;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "public, max-age=3600, immutable" always;
}
# Issuer certificate endpoint - long cache
location ~ ^/issuer/(.+)$ {
try_files /issuer/$1 =404;
add_header Content-Type "application/pkix-cert" always;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "public, max-age=604800, immutable" always;
}
# Tile data endpoint - long cache, may have gzip
location ~ ^/tile/(.+)$ {
try_files /tile/$1 =404;
add_header Content-Type "application/octet-stream" always;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "public, max-age=604800, immutable" always;
# Gzip encoding for .gz files
location ~ \.gz$ {
add_header Content-Encoding "gzip" always;
}
}
}
`
type NginxTemplateData struct {
MonitoringHost string
LocalDirectory string
}
func generateNginx(yamlFile string) {
config := loadConfig(yamlFile)
for _, log := range config.Logs {
// Extract hostname from monitoring prefix
hostname, err := extractHostname(log.MonitoringPrefix)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to extract hostname from %s: %v\n", log.MonitoringPrefix, err)
continue
}
// Create template data
data := NginxTemplateData{
MonitoringHost: hostname,
LocalDirectory: log.LocalDirectory,
}
// Parse and execute template
tmpl, err := template.New("nginx").Parse(nginxTemplate)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to parse nginx template: %v\n", err)
continue
}
// Generate output filename using only hostname part
outputFilename := fmt.Sprintf("%s.conf", hostname)
outputPath := filepath.Join(log.LocalDirectory, outputFilename)
// Create output file
file, err := os.Create(outputPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create nginx config file %s: %v\n", outputPath, err)
continue
}
defer file.Close()
// Execute template
err = tmpl.Execute(file, data)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to execute nginx template for %s: %v\n", outputPath, err)
continue
}
fmt.Printf("Generated nginx config: %s\n", outputPath)
}
}
func extractHostname(urlStr string) (string, error) {
if !strings.HasPrefix(urlStr, "http://") && !strings.HasPrefix(urlStr, "https://") {
urlStr = "https://" + urlStr
}
parsedURL, err := url.Parse(urlStr)
if err != nil {
return "", err
}
return parsedURL.Hostname(), nil
}