// SecureListen obtains a listener that accepts // secure connections func SecureServe(addr string, certFile, keyFile, caFile string) { config := tls.Config{} // load the server cert / key cert, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { log.Critical("%s", err) } config.Certificates = []tls.Certificate{cert} // load the ca if necessary // FIXME(alainjobart) this doesn't quite work yet, have // to investigate if caFile != "" { config.ClientCAs = x509.NewCertPool() pemCerts, err := ioutil.ReadFile(caFile) if err != nil { log.Critical("%s", err) } if !config.ClientCAs.AppendCertsFromPEM(pemCerts) { log.Critical("%s", err) } config.ClientAuth = tls.RequireAndVerifyClientCert } l, err := tls.Listen("tcp", addr, &config) if err != nil { log.Critical("%s", err) } throttled := NewThrottledListener(l, *secureThrottle, *secureMaxBuffer) cl := proc.Published(throttled, "SecureConnections", "SecureAccepts") go http.Serve(cl, nil) }
// ListenAndServe combines Listen and Wait to also run an http // server on the specified port. If it fails to obtain a listener, // the program is fatally terminated. The return value is the signal // received for termination func ListenAndServe(port string) os.Signal { l, err := Listen(port) if err != nil { log.Critical("%s", err) } go http.Serve(l, nil) s := Wait() l.Close() return s }
func Init() { mu.Lock() defer mu.Unlock() if inited { log.Critical("servenv.Init called second time") } inited = true // Once you run as root, you pretty much destroy the chances of a // non-privileged user starting the program correctly. if uid := os.Getuid(); uid == 0 { log.Critical("servenv.Init: running this as root makes no sense") } runtime.MemProfileRate = *memProfileRate gomaxprocs := os.Getenv("GOMAXPROCS") if gomaxprocs == "" { gomaxprocs = "1" } // We used to set this limit directly, but you pretty much have to // use a root account to allow increasing a limit reliably. Dropping // privileges is also tricky. The best strategy is to make a shell // script set up the limits as root and switch users before starting // the server. fdLimit := &syscall.Rlimit{} if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, fdLimit); err != nil { log.Error("max-open-fds failed: %v", err) } fdl := stats.NewInt("MaxFds") fdl.Set(int64(fdLimit.Cur)) if err := exportBinaryVersion(); err != nil { log.Critical("servenv.Init: exportBinaryVersion: %v", err) } onInitHooks.Fire() }
func ServeRPC() { rpc.HandleHTTP() if *authConfig != "" { if err := auth.LoadCredentials(*authConfig); err != nil { log.Critical("could not load authentication credentials, not starting rpc servers: %v", err) } bsonrpc.ServeAuthRPC() jsonrpc.ServeAuthRPC() } jsonrpc.ServeHTTP() jsonrpc.ServeRPC() bsonrpc.ServeHTTP() bsonrpc.ServeRPC() }
// RunSecure is like Run, but it additionally listens for RPC and HTTP // requests using TLS on securePort, using the passed certificate, // key, and CA certificate. func RunSecure(port int, securePort int, cert, key, caCert string) { onRunHooks.Fire() ServeRPC() l, err := proc.Listen(fmt.Sprintf("%v", port)) if err != nil { log.Critical(err.Error()) } go http.Serve(l, nil) if securePort != 0 { log.Info("listening on secure port %v", securePort) SecureServe(fmt.Sprintf(":%d", securePort), cert, key, caCert) } proc.Wait() Close() }