예제 #1
0
func main() {
	app := cmd.NewAppShell("boulder-ca", "Handles issuance operations")
	app.Action = func(c cmd.Config, stats metrics.Statter, logger blog.Logger) {
		// Validate PA config and set defaults if needed
		cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration")

		go cmd.DebugServer(c.CA.DebugAddr)

		pa, err := policy.New(c.PA.Challenges)
		cmd.FailOnError(err, "Couldn't create PA")

		if c.CA.HostnamePolicyFile == "" {
			cmd.FailOnError(fmt.Errorf("HostnamePolicyFile was empty."), "")
		}
		err = pa.SetHostnamePolicyFile(c.CA.HostnamePolicyFile)
		cmd.FailOnError(err, "Couldn't load hostname policy file")

		issuers, err := loadIssuers(c)
		cmd.FailOnError(err, "Couldn't load issuers")

		cai, err := ca.NewCertificateAuthorityImpl(
			c.CA,
			clock.Default(),
			stats,
			issuers,
			c.KeyPolicy(),
			logger)
		cmd.FailOnError(err, "Failed to create CA impl")
		cai.PA = pa

		go cmd.ProfileCmd("CA", stats)

		amqpConf := c.CA.AMQP
		cai.SA, err = rpc.NewStorageAuthorityClient(clientName, amqpConf, stats)
		cmd.FailOnError(err, "Failed to create SA client")

		if c.CA.PublisherService != nil {
			conn, err := bgrpc.ClientSetup(c.CA.PublisherService)
			cmd.FailOnError(err, "Failed to load credentials and create connection to service")
			cai.Publisher = bgrpc.NewPublisherClientWrapper(pubPB.NewPublisherClient(conn), c.CA.PublisherService.Timeout.Duration)
		} else {
			cai.Publisher, err = rpc.NewPublisherClient(clientName, amqpConf, stats)
			cmd.FailOnError(err, "Failed to create Publisher client")
		}

		cas, err := rpc.NewAmqpRPCServer(amqpConf, c.CA.MaxConcurrentRPCServerRequests, stats, logger)
		cmd.FailOnError(err, "Unable to create CA RPC server")
		err = rpc.NewCertificateAuthorityServer(cas, cai)
		cmd.FailOnError(err, "Failed to create Certificate Authority RPC server")

		err = cas.Start(amqpConf)
		cmd.FailOnError(err, "Unable to run CA RPC server")
	}

	app.Run()
}
예제 #2
0
func init() {
	var err error
	pa, err = policy.New(map[string]bool{})
	if err != nil {
		log.Fatal(err)
	}
	err = pa.SetHostnamePolicyFile("../../test/hostname-policy.json")
	if err != nil {
		log.Fatal(err)
	}
}
예제 #3
0
func main() {
	configFile := flag.String("config", "", "File path to the configuration file for this service")
	flag.Parse()
	if *configFile == "" {
		flag.Usage()
		os.Exit(1)
	}

	var c config
	err := cmd.ReadJSONFile(*configFile, &c)
	cmd.FailOnError(err, "Reading JSON config file into config structure")

	go cmd.DebugServer(c.RA.DebugAddr)

	stats, logger := cmd.StatsAndLogging(c.StatsdConfig, c.SyslogConfig)
	defer logger.AuditPanic()
	logger.Info(cmd.VersionString(clientName))

	// Validate PA config and set defaults if needed
	cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration")

	pa, err := policy.New(c.PA.Challenges)
	cmd.FailOnError(err, "Couldn't create PA")

	if c.RA.HostnamePolicyFile == "" {
		cmd.FailOnError(fmt.Errorf("HostnamePolicyFile must be provided."), "")
	}
	err = pa.SetHostnamePolicyFile(c.RA.HostnamePolicyFile)
	cmd.FailOnError(err, "Couldn't load hostname policy file")

	go cmd.ProfileCmd("RA", stats)

	amqpConf := c.RA.AMQP
	var vac core.ValidationAuthority
	if c.RA.VAService != nil {
		conn, err := bgrpc.ClientSetup(c.RA.VAService)
		cmd.FailOnError(err, "Unable to create VA client")
		vac = bgrpc.NewValidationAuthorityGRPCClient(conn)
	} else {
		vac, err = rpc.NewValidationAuthorityClient(clientName, amqpConf, stats)
		cmd.FailOnError(err, "Unable to create VA client")
	}

	cac, err := rpc.NewCertificateAuthorityClient(clientName, amqpConf, stats)
	cmd.FailOnError(err, "Unable to create CA client")

	sac, err := rpc.NewStorageAuthorityClient(clientName, amqpConf, stats)
	cmd.FailOnError(err, "Unable to create SA client")

	rai := ra.NewRegistrationAuthorityImpl(
		clock.Default(),
		logger,
		stats,
		c.RA.MaxContactsPerRegistration,
		c.AllowedSigningAlgos.KeyPolicy(),
		c.RA.MaxNames,
		c.RA.DoNotForceCN,
		c.RA.ReuseValidAuthz)

	policyErr := rai.SetRateLimitPoliciesFile(c.RA.RateLimitPoliciesFilename)
	cmd.FailOnError(policyErr, "Couldn't load rate limit policies file")
	rai.PA = pa

	raDNSTimeout, err := time.ParseDuration(c.Common.DNSTimeout)
	cmd.FailOnError(err, "Couldn't parse RA DNS timeout")
	scoped := metrics.NewStatsdScope(stats, "RA", "DNS")
	dnsTries := c.RA.DNSTries
	if dnsTries < 1 {
		dnsTries = 1
	}
	if !c.Common.DNSAllowLoopbackAddresses {
		rai.DNSResolver = bdns.NewDNSResolverImpl(
			raDNSTimeout,
			[]string{c.Common.DNSResolver},
			nil,
			scoped,
			clock.Default(),
			dnsTries)
	} else {
		rai.DNSResolver = bdns.NewTestDNSResolverImpl(
			raDNSTimeout,
			[]string{c.Common.DNSResolver},
			scoped,
			clock.Default(),
			dnsTries)
	}

	rai.VA = vac
	rai.CA = cac
	rai.SA = sac

	ras, err := rpc.NewAmqpRPCServer(amqpConf, c.RA.MaxConcurrentRPCServerRequests, stats, logger)
	cmd.FailOnError(err, "Unable to create RA RPC server")
	err = rpc.NewRegistrationAuthorityServer(ras, rai, logger)
	cmd.FailOnError(err, "Unable to setup RA RPC server")

	err = ras.Start(amqpConf)
	cmd.FailOnError(err, "Unable to run RA RPC server")
}
예제 #4
0
func main() {
	app := cli.NewApp()
	app.Name = "cert-checker"
	app.Usage = "Checks validity of issued certificates stored in the database"
	app.Version = cmd.Version()
	app.Author = "Boulder contributors"
	app.Email = "*****@*****.**"

	app.Flags = []cli.Flag{
		cli.IntFlag{
			Name:  "workers",
			Value: runtime.NumCPU(),
			Usage: "The number of concurrent workers used to process certificates",
		},
		cli.BoolFlag{
			Name:  "unexpired-only",
			Usage: "Only check currently unexpired certificates",
		},
		cli.BoolFlag{
			Name:  "bad-results-only",
			Usage: "Only collect and display bad results",
		},
		cli.StringFlag{
			Name:  "db-connect",
			Usage: "SQL URI if not provided in the configuration file",
		},
		cli.StringFlag{
			Name:  "check-period",
			Value: "2160h",
			Usage: "How far back to check",
		},
		cli.StringFlag{
			Name:  "config",
			Value: "config.json",
			Usage: "Path to configuration file",
		},
	}

	app.Action = func(c *cli.Context) {
		configPath := c.GlobalString("config")
		if configPath == "" {
			fmt.Fprintln(os.Stderr, "--config is required")
			os.Exit(1)
		}
		configBytes, err := ioutil.ReadFile(configPath)
		cmd.FailOnError(err, "Failed to read config file")
		var config cmd.Config
		err = json.Unmarshal(configBytes, &config)
		cmd.FailOnError(err, "Failed to parse config file")

		stats, err := metrics.NewStatter(config.Statsd.Server, config.Statsd.Prefix)
		cmd.FailOnError(err, "Failed to create StatsD client")
		syslogger, err := syslog.Dial("", "", syslog.LOG_INFO|syslog.LOG_LOCAL0, "")
		cmd.FailOnError(err, "Failed to dial syslog")
		logger, err := blog.New(syslogger, 0, 0)
		cmd.FailOnError(err, "Failed to construct logger")
		err = blog.Set(logger)
		cmd.FailOnError(err, "Failed to set audit logger")

		if connect := c.GlobalString("db-connect"); connect != "" {
			config.CertChecker.DBConnect = connect
		}
		if workers := c.GlobalInt("workers"); workers != 0 {
			config.CertChecker.Workers = workers
		}
		config.CertChecker.UnexpiredOnly = c.GlobalBool("valid-only")
		config.CertChecker.BadResultsOnly = c.GlobalBool("bad-results-only")
		if cp := c.GlobalString("check-period"); cp != "" {
			config.CertChecker.CheckPeriod.Duration, err = time.ParseDuration(cp)
			cmd.FailOnError(err, "Failed to parse check period")
		}

		// Validate PA config and set defaults if needed
		cmd.FailOnError(config.PA.CheckChallenges(), "Invalid PA configuration")

		saDbURL, err := config.CertChecker.DBConfig.URL()
		cmd.FailOnError(err, "Couldn't load DB URL")
		saDbMap, err := sa.NewDbMap(saDbURL, config.CertChecker.DBConfig.MaxDBConns)
		cmd.FailOnError(err, "Could not connect to database")
		go sa.ReportDbConnCount(saDbMap, metrics.NewStatsdScope(stats, "CertChecker"))

		pa, err := policy.New(config.PA.Challenges)
		cmd.FailOnError(err, "Failed to create PA")
		err = pa.SetHostnamePolicyFile(config.CertChecker.HostnamePolicyFile)
		cmd.FailOnError(err, "Failed to load HostnamePolicyFile")

		checker := newChecker(
			saDbMap,
			clock.Default(),
			pa,
			config.CertChecker.CheckPeriod.Duration,
		)
		fmt.Fprintf(os.Stderr, "# Getting certificates issued in the last %s\n", config.CertChecker.CheckPeriod)

		// Since we grab certificates in batches we don't want this to block, when it
		// is finished it will close the certificate channel which allows the range
		// loops in checker.processCerts to break
		go func() {
			err = checker.getCerts(config.CertChecker.UnexpiredOnly)
			cmd.FailOnError(err, "Batch retrieval of certificates failed")
		}()

		fmt.Fprintf(os.Stderr, "# Processing certificates using %d workers\n", config.CertChecker.Workers)
		wg := new(sync.WaitGroup)
		for i := 0; i < config.CertChecker.Workers; i++ {
			wg.Add(1)
			go func() {
				s := checker.clock.Now()
				checker.processCerts(wg, config.CertChecker.BadResultsOnly)
				stats.TimingDuration("certChecker.processingLatency", time.Since(s), 1.0)
			}()
		}
		wg.Wait()
		fmt.Fprintf(
			os.Stderr,
			"# Finished processing certificates, sample: %d, good: %d, bad: %d\n",
			len(checker.issuedReport.Entries),
			checker.issuedReport.GoodCerts,
			checker.issuedReport.BadCerts,
		)
		err = checker.issuedReport.dump()
		cmd.FailOnError(err, "Failed to dump results: %s\n")
	}

	err := app.Run(os.Args)
	cmd.FailOnError(err, "Failed to run application")
}
예제 #5
0
func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAuthority, *RegistrationAuthorityImpl, clock.FakeClock, func()) {
	err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	err = json.Unmarshal(AccountKeyJSONB, &AccountKeyB)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	err = json.Unmarshal(AccountKeyJSONC, &AccountKeyC)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")

	err = json.Unmarshal(AccountPrivateKeyJSON, &AccountPrivateKey)
	test.AssertNotError(t, err, "Failed to unmarshal private JWK")

	err = json.Unmarshal(ShortKeyJSON, &ShortKey)
	test.AssertNotError(t, err, "Failed to unmarshal JWK")

	fc := clock.NewFake()

	dbMap, err := sa.NewDbMap(vars.DBConnSA, 0)
	if err != nil {
		t.Fatalf("Failed to create dbMap: %s", err)
	}
	ssa, err := sa.NewSQLStorageAuthority(dbMap, fc, log)
	if err != nil {
		t.Fatalf("Failed to create SA: %s", err)
	}

	saDBCleanUp := test.ResetSATestDatabase(t)

	va := &DummyValidationAuthority{}

	pa, err := policy.New(SupportedChallenges)
	test.AssertNotError(t, err, "Couldn't create PA")
	err = pa.SetHostnamePolicyFile("../test/hostname-policy.json")
	test.AssertNotError(t, err, "Couldn't set hostname policy")

	stats, _ := statsd.NewNoopClient()

	ca := &mocks.MockCA{
		PEM: eeCertPEM,
	}
	cleanUp := func() {
		saDBCleanUp()
	}

	block, _ := pem.Decode(CSRPEM)
	ExampleCSR, _ = x509.ParseCertificateRequest(block.Bytes)

	Registration, _ = ssa.NewRegistration(ctx, core.Registration{
		Key:       AccountKeyA,
		InitialIP: net.ParseIP("3.2.3.3"),
	})

	ra := NewRegistrationAuthorityImpl(fc,
		log,
		stats,
		1, testKeyPolicy, 0, true, false)
	ra.SA = ssa
	ra.VA = va
	ra.CA = ca
	ra.PA = pa
	ra.DNSResolver = &bdns.MockDNSResolver{}

	AuthzInitial.RegistrationID = Registration.ID

	challenges, combinations := pa.ChallengesFor(AuthzInitial.Identifier, &Registration.Key)
	AuthzInitial.Challenges = challenges
	AuthzInitial.Combinations = combinations

	AuthzFinal = AuthzInitial
	AuthzFinal.Status = "valid"
	exp := time.Now().Add(365 * 24 * time.Hour)
	AuthzFinal.Expires = &exp
	AuthzFinal.Challenges[0].Status = "valid"

	return va, ssa, ra, fc, cleanUp
}
예제 #6
0
파일: main.go 프로젝트: jfrazelle/boulder
func main() {
	configFile := flag.String("config", "", "File path to the configuration file for this service")
	workers := flag.Int("workers", runtime.NumCPU(), "The number of concurrent workers used to process certificates")
	badResultsOnly := flag.Bool("bad-results-only", false, "Only collect and display bad results")
	connect := flag.String("db-connect", "", "SQL URI if not provided in the configuration file")
	cp := flag.Duration("check-period", time.Hour*2160, "How far back to check")
	unexpiredOnly := flag.Bool("unexpired-only", false, "Only check currently unexpired certificates")

	flag.Parse()
	if *configFile == "" {
		flag.Usage()
		os.Exit(1)
	}

	var config config
	err := cmd.ReadConfigFile(*configFile, &config)
	cmd.FailOnError(err, "Reading JSON config file into config structure")

	err = features.Set(config.CertChecker.Features)
	cmd.FailOnError(err, "Failed to set feature flags")

	stats, err := metrics.NewStatter(config.Statsd.Server, config.Statsd.Prefix)
	cmd.FailOnError(err, "Failed to create StatsD client")
	syslogger, err := syslog.Dial("", "", syslog.LOG_INFO|syslog.LOG_LOCAL0, "")
	cmd.FailOnError(err, "Failed to dial syslog")
	logger, err := blog.New(syslogger, 0, 0)
	cmd.FailOnError(err, "Failed to construct logger")
	err = blog.Set(logger)
	cmd.FailOnError(err, "Failed to set audit logger")

	if *connect != "" {
		config.CertChecker.DBConnect = *connect
	}
	if *workers != 0 {
		config.CertChecker.Workers = *workers
	}
	config.CertChecker.UnexpiredOnly = *unexpiredOnly
	config.CertChecker.BadResultsOnly = *badResultsOnly
	config.CertChecker.CheckPeriod.Duration = *cp

	// Validate PA config and set defaults if needed
	cmd.FailOnError(config.PA.CheckChallenges(), "Invalid PA configuration")

	saDbURL, err := config.CertChecker.DBConfig.URL()
	cmd.FailOnError(err, "Couldn't load DB URL")
	saDbMap, err := sa.NewDbMap(saDbURL, config.CertChecker.DBConfig.MaxDBConns)
	cmd.FailOnError(err, "Could not connect to database")
	go sa.ReportDbConnCount(saDbMap, metrics.NewStatsdScope(stats, "CertChecker"))

	pa, err := policy.New(config.PA.Challenges)
	cmd.FailOnError(err, "Failed to create PA")
	err = pa.SetHostnamePolicyFile(config.CertChecker.HostnamePolicyFile)
	cmd.FailOnError(err, "Failed to load HostnamePolicyFile")

	checker := newChecker(
		saDbMap,
		clock.Default(),
		pa,
		config.CertChecker.CheckPeriod.Duration,
	)
	fmt.Fprintf(os.Stderr, "# Getting certificates issued in the last %s\n", config.CertChecker.CheckPeriod)

	// Since we grab certificates in batches we don't want this to block, when it
	// is finished it will close the certificate channel which allows the range
	// loops in checker.processCerts to break
	go func() {
		err = checker.getCerts(config.CertChecker.UnexpiredOnly)
		cmd.FailOnError(err, "Batch retrieval of certificates failed")
	}()

	fmt.Fprintf(os.Stderr, "# Processing certificates using %d workers\n", config.CertChecker.Workers)
	wg := new(sync.WaitGroup)
	for i := 0; i < config.CertChecker.Workers; i++ {
		wg.Add(1)
		go func() {
			s := checker.clock.Now()
			checker.processCerts(wg, config.CertChecker.BadResultsOnly)
			stats.TimingDuration("certChecker.processingLatency", time.Since(s), 1.0)
		}()
	}
	wg.Wait()
	fmt.Fprintf(
		os.Stderr,
		"# Finished processing certificates, sample: %d, good: %d, bad: %d\n",
		len(checker.issuedReport.Entries),
		checker.issuedReport.GoodCerts,
		checker.issuedReport.BadCerts,
	)
	err = checker.issuedReport.dump()
	cmd.FailOnError(err, "Failed to dump results: %s\n")

}
예제 #7
0
func setup(t *testing.T) *testCtx {
	fc := clock.NewFake()
	fc.Add(1 * time.Hour)

	pa, err := policy.New(nil)
	test.AssertNotError(t, err, "Couldn't create PA")
	err = pa.SetHostnamePolicyFile("../test/hostname-policy.json")
	test.AssertNotError(t, err, "Couldn't set hostname policy")

	// Create a CA
	caConfig := cmd.CAConfig{
		RSAProfile:   rsaProfileName,
		ECDSAProfile: ecdsaProfileName,
		SerialPrefix: 17,
		Expiry:       "8760h",
		LifespanOCSP: cmd.ConfigDuration{Duration: 45 * time.Minute},
		MaxNames:     2,
		DoNotForceCN: true,
		CFSSL: cfsslConfig.Config{
			Signing: &cfsslConfig.Signing{
				Profiles: map[string]*cfsslConfig.SigningProfile{
					rsaProfileName: {
						Usage:     []string{"digital signature", "key encipherment", "server auth"},
						CA:        false,
						IssuerURL: []string{"http://not-example.com/issuer-url"},
						OCSP:      "http://not-example.com/ocsp",
						CRL:       "http://not-example.com/crl",

						Policies: []cfsslConfig.CertificatePolicy{
							{
								ID: cfsslConfig.OID(asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}),
							},
						},
						ExpiryString: "8760h",
						Backdate:     time.Hour,
						CSRWhitelist: &cfsslConfig.CSRWhitelist{
							PublicKeyAlgorithm: true,
							PublicKey:          true,
							SignatureAlgorithm: true,
						},
						ClientProvidesSerialNumbers: true,
						AllowedExtensions: []cfsslConfig.OID{
							cfsslConfig.OID(oidTLSFeature),
						},
					},
					ecdsaProfileName: {
						Usage:     []string{"digital signature", "server auth"},
						CA:        false,
						IssuerURL: []string{"http://not-example.com/issuer-url"},
						OCSP:      "http://not-example.com/ocsp",
						CRL:       "http://not-example.com/crl",

						Policies: []cfsslConfig.CertificatePolicy{
							{
								ID: cfsslConfig.OID(asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}),
							},
						},
						ExpiryString: "8760h",
						Backdate:     time.Hour,
						CSRWhitelist: &cfsslConfig.CSRWhitelist{
							PublicKeyAlgorithm: true,
							PublicKey:          true,
							SignatureAlgorithm: true,
						},
						ClientProvidesSerialNumbers: true,
					},
				},
				Default: &cfsslConfig.SigningProfile{
					ExpiryString: "8760h",
				},
			},
		},
	}

	stats := mocks.NewStatter()

	issuers := []Issuer{{caKey, caCert}}

	keyPolicy := core.KeyPolicy{
		AllowRSA:           true,
		AllowECDSANISTP256: true,
		AllowECDSANISTP384: true,
	}

	return &testCtx{
		caConfig,
		pa,
		issuers,
		keyPolicy,
		fc,
		stats,
	}
}
예제 #8
0
파일: main.go 프로젝트: patf/boulder
func main() {
	app := cmd.NewAppShell("boulder-ra", "Handles service orchestration")
	app.Action = func(c cmd.Config, stats metrics.Statter, logger blog.Logger) {
		// Validate PA config and set defaults if needed
		cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration")

		go cmd.DebugServer(c.RA.DebugAddr)

		pa, err := policy.New(c.PA.Challenges)
		cmd.FailOnError(err, "Couldn't create PA")

		if c.RA.HostnamePolicyFile == "" {
			cmd.FailOnError(fmt.Errorf("HostnamePolicyFile must be provided."), "")
		}
		err = pa.SetHostnamePolicyFile(c.RA.HostnamePolicyFile)
		cmd.FailOnError(err, "Couldn't load hostname policy file")

		rateLimitPolicies, err := cmd.LoadRateLimitPolicies(c.RA.RateLimitPoliciesFilename)
		cmd.FailOnError(err, "Couldn't load rate limit policies file")

		go cmd.ProfileCmd("RA", stats)

		amqpConf := c.RA.AMQP
		vac, err := rpc.NewValidationAuthorityClient(clientName, amqpConf, stats)
		cmd.FailOnError(err, "Unable to create VA client")

		cac, err := rpc.NewCertificateAuthorityClient(clientName, amqpConf, stats)
		cmd.FailOnError(err, "Unable to create CA client")

		sac, err := rpc.NewStorageAuthorityClient(clientName, amqpConf, stats)
		cmd.FailOnError(err, "Unable to create SA client")

		var dc *ra.DomainCheck
		if c.RA.UseIsSafeDomain {
			dc = &ra.DomainCheck{VA: vac}
		}

		rai := ra.NewRegistrationAuthorityImpl(clock.Default(), logger, stats,
			dc, rateLimitPolicies, c.RA.MaxContactsPerRegistration, c.KeyPolicy(),
			c.RA.UseNewVARPC)
		rai.PA = pa
		raDNSTimeout, err := time.ParseDuration(c.Common.DNSTimeout)
		cmd.FailOnError(err, "Couldn't parse RA DNS timeout")
		scoped := metrics.NewStatsdScope(stats, "RA", "DNS")
		dnsTries := c.RA.DNSTries
		if dnsTries < 1 {
			dnsTries = 1
		}
		if !c.Common.DNSAllowLoopbackAddresses {
			rai.DNSResolver = bdns.NewDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}, scoped, clock.Default(), dnsTries)
		} else {
			rai.DNSResolver = bdns.NewTestDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}, scoped, clock.Default(), dnsTries)
		}

		rai.VA = vac
		rai.CA = cac
		rai.SA = sac

		ras, err := rpc.NewAmqpRPCServer(amqpConf, c.RA.MaxConcurrentRPCServerRequests, stats)
		cmd.FailOnError(err, "Unable to create RA RPC server")
		err = rpc.NewRegistrationAuthorityServer(ras, rai)
		cmd.FailOnError(err, "Unable to setup RA RPC server")

		err = ras.Start(amqpConf)
		cmd.FailOnError(err, "Unable to run RA RPC server")
	}

	app.Run()
}
예제 #9
0
func main() {
	configFile := flag.String("config", "", "File path to the configuration file for this service")
	flag.Parse()
	if *configFile == "" {
		flag.Usage()
		os.Exit(1)
	}

	var c config
	err := cmd.ReadJSONFile(*configFile, &c)
	cmd.FailOnError(err, "Reading JSON config file into config structure")

	go cmd.DebugServer(c.CA.DebugAddr)

	stats, logger := cmd.StatsAndLogging(c.StatsdConfig, c.SyslogConfig)
	defer logger.AuditPanic()
	logger.Info(cmd.VersionString(clientName))

	cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration")

	pa, err := policy.New(c.PA.Challenges)
	cmd.FailOnError(err, "Couldn't create PA")

	if c.CA.HostnamePolicyFile == "" {
		cmd.FailOnError(fmt.Errorf("HostnamePolicyFile was empty."), "")
	}
	err = pa.SetHostnamePolicyFile(c.CA.HostnamePolicyFile)
	cmd.FailOnError(err, "Couldn't load hostname policy file")

	issuers, err := loadIssuers(c)
	cmd.FailOnError(err, "Couldn't load issuers")

	cai, err := ca.NewCertificateAuthorityImpl(
		c.CA,
		clock.Default(),
		stats,
		issuers,
		c.KeyPolicy(),
		logger)
	cmd.FailOnError(err, "Failed to create CA impl")
	cai.PA = pa

	go cmd.ProfileCmd("CA", stats)

	amqpConf := c.CA.AMQP
	cai.SA, err = rpc.NewStorageAuthorityClient(clientName, amqpConf, stats)
	cmd.FailOnError(err, "Failed to create SA client")

	if c.CA.PublisherService != nil {
		conn, err := bgrpc.ClientSetup(c.CA.PublisherService)
		cmd.FailOnError(err, "Failed to load credentials and create connection to service")
		cai.Publisher = bgrpc.NewPublisherClientWrapper(pubPB.NewPublisherClient(conn), c.CA.PublisherService.Timeout.Duration)
	} else {
		cai.Publisher, err = rpc.NewPublisherClient(clientName, amqpConf, stats)
		cmd.FailOnError(err, "Failed to create Publisher client")
	}

	cas, err := rpc.NewAmqpRPCServer(amqpConf, c.CA.MaxConcurrentRPCServerRequests, stats, logger)
	cmd.FailOnError(err, "Unable to create CA RPC server")
	err = rpc.NewCertificateAuthorityServer(cas, cai)
	cmd.FailOnError(err, "Failed to create Certificate Authority RPC server")

	err = cas.Start(amqpConf)
	cmd.FailOnError(err, "Unable to run CA RPC server")
}
예제 #10
0
파일: main.go 프로젝트: jfrazelle/boulder
func main() {
	configFile := flag.String("config", "", "File path to the configuration file for this service")
	flag.Parse()
	if *configFile == "" {
		flag.Usage()
		os.Exit(1)
	}

	var c config
	err := cmd.ReadConfigFile(*configFile, &c)
	cmd.FailOnError(err, "Reading JSON config file into config structure")

	err = features.Set(c.CA.Features)
	cmd.FailOnError(err, "Failed to set feature flags")

	stats, logger := cmd.StatsAndLogging(c.Statsd, c.Syslog)
	scope := metrics.NewStatsdScope(stats, "CA")
	defer logger.AuditPanic()
	logger.Info(cmd.VersionString(clientName))

	cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration")

	pa, err := policy.New(c.PA.Challenges)
	cmd.FailOnError(err, "Couldn't create PA")

	if c.CA.HostnamePolicyFile == "" {
		cmd.FailOnError(fmt.Errorf("HostnamePolicyFile was empty."), "")
	}
	err = pa.SetHostnamePolicyFile(c.CA.HostnamePolicyFile)
	cmd.FailOnError(err, "Couldn't load hostname policy file")

	issuers, err := loadIssuers(c)
	cmd.FailOnError(err, "Couldn't load issuers")

	cai, err := ca.NewCertificateAuthorityImpl(
		c.CA,
		clock.Default(),
		scope,
		issuers,
		goodkey.NewKeyPolicy(),
		logger)
	cmd.FailOnError(err, "Failed to create CA impl")
	cai.PA = pa

	amqpConf := c.CA.AMQP
	if c.CA.SAService != nil {
		conn, err := bgrpc.ClientSetup(c.CA.SAService, scope)
		cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
		cai.SA = bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(conn))
	} else {
		cai.SA, err = rpc.NewStorageAuthorityClient(clientName, amqpConf, scope)
		cmd.FailOnError(err, "Failed to create SA client")
	}

	if amqpConf.Publisher != nil {
		cai.Publisher, err = rpc.NewPublisherClient(clientName, amqpConf, scope)
		cmd.FailOnError(err, "Failed to create Publisher client")
	}

	var grpcSrv *grpc.Server
	if c.CA.GRPC != nil {
		s, l, err := bgrpc.NewServer(c.CA.GRPC, scope)
		cmd.FailOnError(err, "Unable to setup CA gRPC server")
		caWrapper := bgrpc.NewCertificateAuthorityServer(cai)
		caPB.RegisterCertificateAuthorityServer(s, caWrapper)
		go func() {
			err = s.Serve(l)
			cmd.FailOnError(err, "CA gRPC service failed")
		}()
		grpcSrv = s
	}

	cas, err := rpc.NewAmqpRPCServer(amqpConf, c.CA.MaxConcurrentRPCServerRequests, scope, logger)
	cmd.FailOnError(err, "Unable to create CA RPC server")

	go cmd.CatchSignals(logger, func() {
		cas.Stop()
		if grpcSrv != nil {
			grpcSrv.GracefulStop()
		}
	})

	err = rpc.NewCertificateAuthorityServer(cas, cai)
	cmd.FailOnError(err, "Failed to create Certificate Authority RPC server")

	go cmd.DebugServer(c.CA.DebugAddr)
	go cmd.ProfileCmd(scope)

	err = cas.Start(amqpConf)
	cmd.FailOnError(err, "Unable to run CA RPC server")
}
예제 #11
0
파일: main.go 프로젝트: jfrazelle/boulder
func main() {
	configFile := flag.String("config", "", "File path to the configuration file for this service")
	flag.Parse()
	if *configFile == "" {
		flag.Usage()
		os.Exit(1)
	}

	var c config
	err := cmd.ReadConfigFile(*configFile, &c)
	cmd.FailOnError(err, "Reading JSON config file into config structure")

	err = features.Set(c.RA.Features)
	cmd.FailOnError(err, "Failed to set feature flags")

	stats, logger := cmd.StatsAndLogging(c.Statsd, c.Syslog)
	scope := metrics.NewStatsdScope(stats, "RA")
	defer logger.AuditPanic()
	logger.Info(cmd.VersionString(clientName))

	// Validate PA config and set defaults if needed
	cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration")

	pa, err := policy.New(c.PA.Challenges)
	cmd.FailOnError(err, "Couldn't create PA")

	if c.RA.HostnamePolicyFile == "" {
		cmd.FailOnError(fmt.Errorf("HostnamePolicyFile must be provided."), "")
	}
	err = pa.SetHostnamePolicyFile(c.RA.HostnamePolicyFile)
	cmd.FailOnError(err, "Couldn't load hostname policy file")

	amqpConf := c.RA.AMQP
	var vac core.ValidationAuthority
	if c.RA.VAService != nil {
		conn, err := bgrpc.ClientSetup(c.RA.VAService, scope)
		cmd.FailOnError(err, "Unable to create VA client")
		vac = bgrpc.NewValidationAuthorityGRPCClient(conn)
	} else {
		vac, err = rpc.NewValidationAuthorityClient(clientName, amqpConf, scope)
		cmd.FailOnError(err, "Unable to create VA client")
	}

	var cac core.CertificateAuthority
	if c.RA.CAService != nil {
		conn, err := bgrpc.ClientSetup(c.RA.CAService, scope)
		cmd.FailOnError(err, "Unable to create CA client")
		cac = bgrpc.NewCertificateAuthorityClient(caPB.NewCertificateAuthorityClient(conn))
	} else {
		cac, err = rpc.NewCertificateAuthorityClient(clientName, amqpConf, scope)
		cmd.FailOnError(err, "Unable to create CA client")
	}

	var pubc core.Publisher
	if c.RA.PublisherService != nil {
		conn, err := bgrpc.ClientSetup(c.RA.PublisherService, scope)
		cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to Publisher")
		pubc = bgrpc.NewPublisherClientWrapper(pubPB.NewPublisherClient(conn))
	}

	var sac core.StorageAuthority
	if c.RA.SAService != nil {
		conn, err := bgrpc.ClientSetup(c.RA.SAService, scope)
		cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
		sac = bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(conn))
	} else {
		sac, err = rpc.NewStorageAuthorityClient(clientName, amqpConf, scope)
		cmd.FailOnError(err, "Unable to create SA client")
	}

	// TODO(patf): remove once RA.authorizationLifetimeDays is deployed
	authorizationLifetime := 300 * 24 * time.Hour
	if c.RA.AuthorizationLifetimeDays != 0 {
		authorizationLifetime = time.Duration(c.RA.AuthorizationLifetimeDays) * 24 * time.Hour
	}

	// TODO(patf): remove once RA.pendingAuthorizationLifetimeDays is deployed
	pendingAuthorizationLifetime := 7 * 24 * time.Hour
	if c.RA.PendingAuthorizationLifetimeDays != 0 {
		pendingAuthorizationLifetime = time.Duration(c.RA.PendingAuthorizationLifetimeDays) * 24 * time.Hour
	}

	rai := ra.NewRegistrationAuthorityImpl(
		clock.Default(),
		logger,
		scope,
		c.RA.MaxContactsPerRegistration,
		goodkey.NewKeyPolicy(),
		c.RA.MaxNames,
		c.RA.DoNotForceCN,
		c.RA.ReuseValidAuthz,
		authorizationLifetime,
		pendingAuthorizationLifetime,
		pubc)

	policyErr := rai.SetRateLimitPoliciesFile(c.RA.RateLimitPoliciesFilename)
	cmd.FailOnError(policyErr, "Couldn't load rate limit policies file")
	rai.PA = pa

	raDNSTimeout, err := time.ParseDuration(c.Common.DNSTimeout)
	cmd.FailOnError(err, "Couldn't parse RA DNS timeout")
	dnsTries := c.RA.DNSTries
	if dnsTries < 1 {
		dnsTries = 1
	}
	if !c.Common.DNSAllowLoopbackAddresses {
		rai.DNSResolver = bdns.NewDNSResolverImpl(
			raDNSTimeout,
			[]string{c.Common.DNSResolver},
			nil,
			scope,
			clock.Default(),
			dnsTries)
	} else {
		rai.DNSResolver = bdns.NewTestDNSResolverImpl(
			raDNSTimeout,
			[]string{c.Common.DNSResolver},
			scope,
			clock.Default(),
			dnsTries)
	}

	rai.VA = vac
	rai.CA = cac
	rai.SA = sac

	err = rai.UpdateIssuedCountForever()
	cmd.FailOnError(err, "Updating total issuance count")

	var grpcSrv *grpc.Server
	if c.RA.GRPC != nil {
		var listener net.Listener
		grpcSrv, listener, err = bgrpc.NewServer(c.RA.GRPC, scope)
		cmd.FailOnError(err, "Unable to setup RA gRPC server")
		gw := bgrpc.NewRegistrationAuthorityServer(rai)
		rapb.RegisterRegistrationAuthorityServer(grpcSrv, gw)
		go func() {
			err = grpcSrv.Serve(listener)
			cmd.FailOnError(err, "RA gRPC service failed")
		}()
	}

	ras, err := rpc.NewAmqpRPCServer(amqpConf, c.RA.MaxConcurrentRPCServerRequests, scope, logger)
	cmd.FailOnError(err, "Unable to create RA RPC server")

	go cmd.CatchSignals(logger, func() {
		ras.Stop()
		if grpcSrv != nil {
			grpcSrv.GracefulStop()
		}
	})

	err = rpc.NewRegistrationAuthorityServer(ras, rai, logger)
	cmd.FailOnError(err, "Unable to setup RA RPC server")

	go cmd.DebugServer(c.RA.DebugAddr)
	go cmd.ProfileCmd(scope)

	err = ras.Start(amqpConf)
	cmd.FailOnError(err, "Unable to run RA RPC server")
}