Skip to main content

Get the Reddit app

Scan this QR code to download the app now
Or check it out in the app stores
r/programming icon
r/programming icon
Go to programming
r/programming

Computer Programming


Members Online

Get valid HTTPS certificates for dev & pre-prod using step

Share
Sort by:
Best
Open comment sort options
[deleted]
[deleted]

Week ago I'd say "where was that post when I revamped corpo's internal CA" (that was based on just few openssl scripts)

Today I'd say just use Cloud Flare's toolkit. It has basically everything you'd want for making your own CA (including OCSP, cert database and revokations), feeds off JSONs so easy to auto-generate configs for it, option for remotes (one server signs, remote server generates csrs/keys and talks with it) and has been battle-tested already. It even has ssllabs-lite like ssl scanner.

revokations

I thought that never works?

[deleted]
[deleted]

Depends what exactly you do with it. On internet, yes it is problematic

But if you want to revoke client certs for internal service that's just a question of distributing a CRL to right server.

More replies
u/d2k1 avatar

So would cfssl be something we could use to replace EJBCA?

[deleted]
[deleted]

It could be used as a part of something to replace it, but just looking at feature list it would be quite a bit of work just to create GUIs for it.

It doesn't really have any "user interface" and it seems to be heavily targeted to either be used from scripts or via API

We integrated it with our Configuration Management (we use Puppet) and it fits that use case very well. Basically we feed JSONs generated directly from CM

Note that you do not have to manage all of it using it, if you just need a scriptable tool to generate a bunch of certs from some intermediate CA you can use it in addition to CA you already have

u/d2k1 avatar

Thank you, that was very helpful. We went with EJBCA many years ago when we needed to "quickly" set up an internal CA from which we could create intermediate CAs and sign many SSL client certificates.

Back then we didn't know better and went with a full CA solution, and EJBCA was the least (but still quite) painful to set up. To this day we don't even use half the features it provides.

If I had to do it again I would probably just wrap various openssl commands in a few scripts, but it seems that cfssl could be exactly what we need.

[deleted]
[deleted]

if you have something that would generate JSONs with config for them it would probably be most straightforward way of doing it.

In our case it is basically a piece of code that loads "our" defaults (C/L/O/OU/ST/key size etc), merges it with provided CN and hosts list and pipes it directly to cfssl.

More replies
More replies
More replies
More replies
u/TicketToThePunShow avatar

This is seriously cool, I can't believe all of the hate it's getting on here. People acting like openssl commands are a piece of cake or that custom CAs aren't a thing. What world are you living in?

Tools like this and LetsEncrypt and mkcert and cfssl are trying to make security easier for everyone, I don't know how you can have a negative reaction to that. Keep it up Step team, you got at least one new fan today.

u/holgerschurig avatar

I can see both things.

I have a project where I made various hostapd.conf & wpa_supplicant.conf files to get WPA3, OME and various EAP methods to work. Obviously I needed some snake-oil-CA for this.

In this case, it was probably ok for me to mangle together a demo-CA with the help of make and openssl.

But: I'm not that deep into security, so I have no clue if I followed the various best-practices. So I wouldn't let this go out into production and would use a well-known i-hold-your-hand-with-a-CA tool instead.

More replies
u/AyrA_ch avatar

What's wrong with a self signed certificate for inter-service communication?

u/GrandOpener avatar

Nothing. That's precisely what they are suggesting you do.

Your implied question might be "why not just disable client-side CA verification with self-signed certificates?" In that case, the answer is that doing so retains the encryption elements of TLS, but discards identity verification. You become potentially vulnerable to man in the middle attacks. That detail may or may not be something you care about for inter-service communications, depending on your environment and risk model.

u/AyrA_ch avatar

Your implied question might be "why not just disable client-side CA verification with self-signed certificates?"

I didn't meant that though. You can either install self signed certificates very easily or add the thumbprint/pubkey as a trusted reference. If in doubt, just become your own CA and add the root certificate to your OS image or deployment script.

u/mjmalone avatar

If in doubt, just become your own CA and add the root certificate to your OS image or deployment script.

Yep, `step ca init` generates CA artifacts (root & intermediate signing certs) so you can become your own CA. Then `step-ca` is an online CA you can use to automate certificate issuance and renewal. Finally, `step certificate install` adds your root certificate to your OS. So this is exactly what's happening.

Root certificates are always self-signed. So we're "using self-signed certificates" in that respect. I figured you meant "why not issue one shared self-signed certificate that all services use".

u/AyrA_ch avatar

If the self signed certificate is properly used it's inaccessible from the service anyway. It should be installed on the system and not deployed with the service each time. On service start it creates the TLS handler and then drops the privileges.

More replies
More replies
More replies
u/mjmalone avatar

It depends on what you're trying to do. Using a single self-signed certificate for lots of services basically lets you determine whether something is in or out of your cluster: it's a step above a shared password that every service knows. By contrast, if you issue certificates from a CA you can embed the actual identity of each service in the certificate. So you don't just know that a remote peer is part of your system, you know exactly which remote peer is making a request. So you can build granular access control.

There are other potential advantages of using a "real PKI". It's easier to issue and rotate short-lived certificates. You can federate with other root certificate authorities. You can embed attributes like group membership in certificates. There are mechanisms for revocation and visibility into which certificates have been issued.

Depending on what you're trying to do these things may or may not matter.

Disclosure: I work at smallstep. Our goal is to make using "real PKI" as easy as using self-signed certs.

u/AyrA_ch avatar

Using a single self-signed certificate for lots of services basically lets you determine whether something is in or out of your cluster: it's a step above a shared password that every service knows.

To be fair, if you use the exact same certificate for every service I wouldn't want to touch anything you installed ever.

u/mjmalone avatar

I might have misunderstood what you meant by "use self-signed certificates". When I hear someone say that usually I assume that's what they're doing: generating one keypair and one self-signed cert that everything trusts.

If you're issuing multiple self-signed certificates I think the management overhead would be more trouble than just running your own CA.

u/AyrA_ch avatar

Depends on how many certificates and how you handle them. If you do manually, it probably gets painful after 10 systems or so. You likely want to automatically push them using your operating systems methods. Since we work with Windows, I have them pushed via GPO to all machines as trusted certificates, which also means I don't have to explain certificate handling to whoever deploys the services and I don't have to care about keeping a CA certificate secure.

[deleted]
[deleted]

Self-signed CA certificate is what I would do for internal servers.

I thought this was the default go to option but clearly not.

More replies
More replies
More replies
More replies
More replies
[deleted]
[deleted]

https on localhost seems unnecessary to me.

u/Master_Steelblade avatar

Sometimes you want other people to test, or to put it on a server with the same environment it'll be running under. That's when https is used.

[deleted]
[deleted]

or to put it on a server with the same environment

I'm not opposed to https when it's on a dev or pre-prod environment when it's on a server, just specifically https://localhost

Even if you wanted someone to test your local instance, I still find it hard to reason with the idea of TLS over a local network. You control all the hardware... Its... *local*. If your local network is insecure, then you have bigger problems than worrying about TLS.

What if you're testing something that requires MTLS, and needs to grab the CN of the client certificate (or some other information)? In that case, MTLS over a local network is required.

More replies
More replies
More replies
u/r1ckd33zy avatar

A lot of the newer browser APIs are HTTPS only, such as geolocation and navigator.share

u/Syfaro avatar

A lot of newer APIs only work in a secure context. Pages loaded with HTTPS/TLS are secure, and so is localhost.

https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts

u/ProgramTheWorld avatar

HTTPS sites and localhost are both considered as secure. They are not for HTTPS only.

More replies
[deleted]
[deleted]

Try using multiple websockets and you may find chrome and other browsers simply will not work. You absolutely must have https even for a localhost connection.

u/nath1234 avatar

It's 2019, maybe the situation should be "http anywhere should be unnecessary".

More replies
u/UnrealQuester avatar

I'm kinda missing a "step vs. <tool>" overview. Would love to see how common use cases look like compared to other tools like cfssl without having to look up and compare the documentation of both.

Seems like a really great tool. Would have saved me a lot of work while setting this kind of infra structure up a while ago (using hacked together bash scripts/OpenSSL). Thanks for the hard work!

[deleted]
[deleted]

Comment deleted by user

u/mjmalone avatar

Disclosure: I work at smallstep.

Er, you could do this with an openssl wrapper but that's not actually what step is. step is built on the golang crypto package and our goal is to raise the level of abstraction relative to something like openssl. If you're an expert, you can do pretty much anything with openssl. But for most people common workflows like signing or validating a JWT are super hard with openssl, whereas step makes them trivially easy (and, perhaps more importantly, hard to do incorrectly).

Even if it was just a wrapper around openssl I think that'd be pretty useful :). The one-liner to generate a self-signed certificate for localhost using OpenSSL is:

openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

The number of people who know that off the top of their head is probably pretty close to zero. If you want to generate a root signing certificate, an intermediate, then a leaf (like step does), god help you.

OpenSSL also doesn't have a production-grade online CA that you can use for microservices. It's really hard to automate certificate management with OpenSSL.

u/iamapizza avatar

OpenSSL also doesn't have a production-grade online CA that you can use for microservices.

Can you elaborate on this 'online CA'. This seems to be the key differentiator from reading your docs and comments - otherwise it isn't actually a lot of trouble to use openssl to generate a Root CA, sign some certs and distribute them with Puppet/Chef, or include the PEMs when making http requests for validation, regardless of dev/production environment. There is no need for someone to remember the openssl commands involved, just to use it or construct it and put it in a document (to run manually) or in an automation pipeline.

So does online CA indicate that the calling clients don't actually need the PEMs included when making their http requests? How is that?

u/mjmalone avatar

It's not that they don't need them when they make a request. It's more about how they get them.

We have a blog post that goes into lots of detail and there's more info in the step certificates GitHub repo. Roughly, though, we want to make it easy for everyone to implement PKI best practices like short-lived certificates, generating keys where they'll be used, automated enrollment & renewal, cert transparency, etc. You can totally build all this stuff using OpenSSL. But it's hard.

The way our bootstrap protocol works is that your provisioning system (e.g., Chef or Puppet or Kubernetes or whatever) can generate a one-time token that includes your root cert's fingerprint and can be submitted by a client, along with a CSR, to get a certificate.

To generate one of these tokens you just run:

step ca token svc.example.com

Then you pass it to whatever service is being started and that service runs:

step ca certificate --token <token> svc.example.com svc.crt svc.key

This command will generate a key pair, a certificate signing request, fetch the root certificate & verify its fingerprint, then exchange the CSR & token with the online CA to get a certificate.

Then you can run

step ca renew --daemon svc.crt svc.key

to start a deamon that'll automatically renew that cert before it expires (your code will have to notice that this cert has been renewed... or you can write a little supervisor).

We're also working on SDKs that do all of this in your code for you so your code just consumes a bootstrap token and proper cert management just magically happens for you.

More replies
[deleted]
[deleted]

Comment deleted by user

[deleted]
[deleted]

It makes sense if there is a trusted party (say company's IT department) that have some control and auditing over generating certs for domains. As company's machines are controlled by company anyway,

IN THEORY it is possible to create CA that is only trusted to certain set of names (say ending with "test.companyname.com"), but in practice you can't be sure target SSL implementation supports that extension. X.509 is fucking mess

And like heck would I install a root CA cert someone else has given me.

Yet you trust other ~150 certs installed by default. Even tho whole CA system has proven over and over again that even if CA basically fucked up(Symantec case), their root and all of their certs will still be active for months.

And CA is still useful for tools that use it that are not "your browser accessing your bank" and

[deleted]
[deleted]

...sooo basically you just wrote https://github.com/cloudflare/cfssl again ?

u/mjmalone avatar

Sure, you could say that... you could also say CFSSL just wrote dogtag again :).

Anyways, step has a bootstrap protocol and command-line tooling to do automated enrollment and certificate renewal, which CFSSL lacks (or at least did when we started building step). We have lots more existing and planned features that CFSSL doesn't seem to have or even aspire towards. As far as I can tell, CFSSL's agenda is to support cloudflare's internal PKI and they don't seem to have a ton of interest in use cases they don't have internally (which is totally find / their prerogative).

The step command line tool does more than just certs, too. Broadly, we're helping people manage identity in distributed systems. There's some overlap with CFSSL there, but PKI is just one (big) part of that story.

Still, CFSSL is great. If it works for you, use it! If it confused you or didn't do everything you want, check out our stuff. What's wrong with a little competition?

[deleted]
[deleted]

Well option to fall back onto (that's not "ugly bash scripting around openssl") is always welcome :). Our developers would probably enjoy having mostly-automated defaults too (altho lazy bastards usually ask us to give them SSL..).

Anyways, step has a bootstrap protocol and command-line tooling to do automated enrollment and certificate renewal, which CFSSL lacks (or at least did when we started building step)

Cfssl seems to built for different case, where you already have "the logic" and just need something to do the heavy lifting. It is clearly not written for "human" use but by automation.

We already had a bunch of automation in-place so it was no-brainer for us. Stuff that would be annoying for user like only dumping generated certs to stdout as JSON (cfssl does have command to save it to file, but it is separate binary) is MASSIVE advantage for scripting, because instead of fucking around with temporary dirs we just dump it directly to our credentials store. Same with builtin cert server, easy way to keep the signing key separate from place that requests the cert without having to copy CSR around.

More replies
More replies
More replies
u/ram-foss avatar

Let's Encrypt offers free SSL certificate. May be you can give a try.

u/doublehyphen avatar

Given that their company website uses Let's Encrypt I suspect that they know.

More replies