@@ -18,7 +18,9 @@ import (
1818 "net/http/httputil"
1919 "net/url"
2020 "os"
21+ "os/exec"
2122 "path/filepath"
23+ "runtime"
2224 "strings"
2325 "sync"
2426 "time"
@@ -393,10 +395,90 @@ func resolveRealIP(hostname string) (string, error) {
393395 return "" , fmt .Errorf ("no A record found for %s" , hostname )
394396}
395397
398+ // detectOS detects the OS using runtime.GOOS
399+ // Returns: "ubuntu" (assumes Canonical Ubuntu for Linux), "darwin" (macOS), "windows" (Windows)
400+ func detectOS () string {
401+ switch runtime .GOOS {
402+ case "linux" :
403+ return "ubuntu"
404+ case "darwin" :
405+ return "darwin"
406+ case "windows" :
407+ return "windows"
408+ default :
409+ panic (fmt .Sprintf ("unsupported OS: %s" , runtime .GOOS ))
410+ }
411+ }
412+
413+ // UpdateSystemCATrust adds the local CA to the system's trusted certificate store
414+ // This integrates the CA with the OS-level trust store, making it trusted system-wide
415+ // Fully implemented for Ubuntu (Canonical), shell methods only for macOS and Windows
416+ func UpdateSystemCATrust (caCertPath string ) error {
417+ switch detectOS () {
418+ case "ubuntu" :
419+ // Fully implemented for Ubuntu (Canonical) - uses update-ca-certificates
420+ return updateUbuntuCATrust (caCertPath )
421+ case "darwin" :
422+ // macOS - shell method only (not fully implemented)
423+ return updateDarwinCATrust (caCertPath )
424+ case "windows" :
425+ // Windows - shell method only (not fully implemented)
426+ return updateWindowsCATrust (caCertPath )
427+ default :
428+ log .Printf ("System CA trust update not implemented for OS: %s" , detectOS ())
429+ log .Printf ("Supported OS: ubuntu (Canonical Ubuntu), darwin (macOS), windows" )
430+ return fmt .Errorf ("unsupported OS: %s" , detectOS ())
431+ }
432+ }
433+
434+ func updateUbuntuCATrust (caCertPath string ) error {
435+ // Copy CA to system location
436+ systemCALocation := "/usr/local/share/ca-certificates/warpbuild-local-ca.crt"
437+
438+ // Read the CA certificate
439+ caData , err := os .ReadFile (caCertPath )
440+ if err != nil {
441+ return fmt .Errorf ("read CA certificate: %v" , err )
442+ }
443+
444+ // Write to system location (requires root)
445+ if err := os .WriteFile (systemCALocation , caData , 0644 ); err != nil {
446+ log .Printf ("Warning: Could not write CA to system location %s (need root): %v" , systemCALocation , err )
447+ log .Printf ("To add CA to system trust store, run as root or manually:" )
448+ log .Printf (" sudo cp %s %s" , caCertPath , systemCALocation )
449+ log .Printf (" sudo update-ca-certificates" )
450+ return fmt .Errorf ("write CA to system location: %v" , err )
451+ }
452+
453+ // Run update-ca-certificates
454+ cmd := exec .Command ("update-ca-certificates" )
455+ output , err := cmd .CombinedOutput ()
456+ if err != nil {
457+ log .Printf ("Warning: update-ca-certificates failed: %v" , err )
458+ log .Printf ("Output: %s" , string (output ))
459+ return fmt .Errorf ("update-ca-certificates failed: %v" , err )
460+ }
461+
462+ log .Printf ("Successfully added CA to Ubuntu system trust store" )
463+ log .Printf ("CA is now trusted system-wide at: %s" , systemCALocation )
464+ return nil
465+ }
466+
467+ func updateDarwinCATrust (caCertPath string ) error {
468+ return nil
469+ }
470+
471+ func updateWindowsCATrust (caCertPath string ) error {
472+ return nil
473+ }
474+
396475// Start starts the OGINY TLS reverse proxy service
397476// If port is > 0, it uses that port, otherwise defaults to 443
398477// If loggingEnabled is true, all proxy traffic will be logged to files
399- func Start (port int , loggingEnabled bool ) error {
478+ // derpPort and asurPort are used to route requests to the correct backend services
479+ // certDir specifies the directory where certificates should be stored
480+ // OS is automatically detected from the system
481+ func Start (port int , derpPort int , asurPort int , certDir string , loggingEnabled bool ) error {
400482 // Ignore cfgPath since we're inlining the config
401483 listenAddr := ":443"
402484 if port > 0 {
@@ -437,17 +519,12 @@ func Start(port int, loggingEnabled bool) error {
437519 }
438520 }
439521
440- // Set up certificate directory
441- var certDir string
522+ // Determine certDir with priority: OGINY_CERT_DIR env var -> settings file value (defaults already applied)
442523 if dir := os .Getenv ("OGINY_CERT_DIR" ); dir != "" {
443524 certDir = dir
525+ log .Printf ("Using certificate directory from OGINY_CERT_DIR: %s" , certDir )
444526 } else {
445- // Use $HOME env var with fallback to /home
446- homeBase := os .Getenv ("HOME" )
447- if homeBase == "" {
448- homeBase = "/home"
449- }
450- certDir = filepath .Join (homeBase , "runner" , "certs" )
527+ log .Printf ("Using certificate directory from settings: %s" , certDir )
451528 }
452529
453530 // Create certificate directory if it doesn't exist
@@ -471,37 +548,10 @@ func Start(port int, loggingEnabled bool) error {
471548 log .Printf ("CA certificate generated at %s" , caCertPath )
472549 }
473550
474- // Set environment variables for current process and children
475- os .Setenv ("NODE_OPTIONS" , "--use-openssl-ca" )
476- os .Setenv ("NODE_EXTRA_CA_CERTS" , caCertPath )
477- os .Setenv ("SSL_CERT_FILE" , caCertPath )
478-
479- // If running in GitHub Actions, write to GITHUB_ENV
480- if githubEnv := os .Getenv ("GITHUB_ENV" ); githubEnv != "" {
481- log .Printf ("Detected GitHub Actions environment, writing to GITHUB_ENV" )
482- if err := appendToFile (githubEnv , fmt .Sprintf ("NODE_OPTIONS=--use-openssl-ca\n NODE_EXTRA_CA_CERTS=%s\n " , caCertPath )); err != nil {
483- log .Printf ("Warning: failed to write to GITHUB_ENV: %v" , err )
484- }
485- // Write SSL_CERT_FILE in a separate call to avoid duplicate-check skipping
486- if err := appendToFile (githubEnv , fmt .Sprintf ("SSL_CERT_FILE=%s\n " , caCertPath )); err != nil {
487- log .Printf ("Warning: failed to write SSL_CERT_FILE to GITHUB_ENV: %v" , err )
488- }
489- }
490-
491- // Also write to /etc/environment if we have permissions (for system-wide)
492- if err := appendToFile ("/etc/environment" , fmt .Sprintf ("NODE_OPTIONS=\" --use-openssl-ca\" \n NODE_EXTRA_CA_CERTS=\" %s\" \n " , caCertPath )); err != nil {
493- // This is expected to fail if not running as root
494- log .Printf ("Note: Could not write to /etc/environment (need root): %v" , err )
495- log .Printf ("To set system-wide, run as root or manually add to /etc/environment:" )
496- log .Printf (" NODE_OPTIONS=\" --use-openssl-ca\" " )
497- log .Printf (" NODE_EXTRA_CA_CERTS=\" %s\" " , caCertPath )
498- log .Printf (" SSL_CERT_FILE=\" %s\" " , caCertPath )
499- } else {
500- log .Printf ("Successfully updated /etc/environment" )
501- // Write SSL_CERT_FILE in a separate call to avoid duplicate-check skipping
502- if err := appendToFile ("/etc/environment" , fmt .Sprintf ("SSL_CERT_FILE=\" %s\" \n " , caCertPath )); err != nil {
503- log .Printf ("Warning: failed to append SSL_CERT_FILE to /etc/environment: %v" , err )
504- }
551+ // Update system CA trust store (OS-specific)
552+ // This integrates the CA with the OS-level trust store, making it trusted system-wide
553+ if err := UpdateSystemCATrust (caCertPath ); err != nil {
554+ log .Printf ("Warning: Failed to update system CA trust store: %v" , err )
505555 }
506556
507557 // Generate certificates for each domain
@@ -515,13 +565,13 @@ func Start(port int, loggingEnabled bool) error {
515565 serverName : "warpbuild.blob.core.windows.net" ,
516566 certFile : filepath .Join (certDir , "warpbuild.crt" ),
517567 keyFile : filepath .Join (certDir , "warpbuild.key" ),
518- targetURL : "http://127.0.0.1:50053" ,
568+ targetURL : fmt . Sprintf ( "http://127.0.0.1:%d" , asurPort ) ,
519569 },
520570 {
521571 serverName : resultsReceiverHost ,
522572 certFile : filepath .Join (certDir , "results-receiver.crt" ),
523573 keyFile : filepath .Join (certDir , "results-receiver.key" ),
524- targetURL : "http://127.0.0.1:50052" ,
574+ targetURL : fmt . Sprintf ( "http://127.0.0.1:%d" , derpPort ) ,
525575 },
526576 }
527577
0 commit comments