11

I've generated a single self-signed SSL certificate (that expires in 5000 years). The purpose of the cert is to simply encrypt the https traffic of a trusted deno application that is accessed by a variety of web browsers on multiple corporate intranet sites.

In a comment, of my prior question, someone advised me that it is possible to distribute my self-signed public SSL key to all computers within an Active Directory environment using Group Policy on the domain controller.

My goal, is to prevent users from having to manually accept this self-sign certificate.

This application's security is not the top priority. The top priority is the automatic acceptance of the self-signed certificate. So that even if a new user is using Chrome or Firefox to access this application for the first time, they will not have to manually accept the certificate to see a page within the App.

If you're wondering why I'm not just using http (instead of https), it is only because there are features in the web standards that are not available unless your protocol is https. The Notification API is one example.

Does there exist a full tutorial for my use case?

I right-clicked here: enter image description here

That brought me to the Group Policy editor, and I actually succeeded in importing my self-signed public key here: enter image description here

However, this had no effect. For example, I logged into a few workstation on the LAN, and from both Firefox and Chrome I was still prompted to manually permit the certificate.

Where can I find thorough instructions for my exact use-case and goals. How can I do this in a way that both Chrome and Firefox will auto-receive the pre-authorization of the certificate I'm trying to distribute?

This is something I need to accomplish for multiple installations at multiple company intranet sites. At each install-location, I need to get active directory to distribute this cert, so that all browsers on each workstation will accept it.

LonnieBest
  • 1,450
  • 4
  • 21
  • 36
  • What does a gpresult report ( run `gpresult /h C:\path\to\file\filename.html` ) say about that section of the policy? – Davidw May 21 '20 at 06:04
  • Did you refresh group policies on clients after editing the GPO? – Crypt32 May 21 '20 at 06:58
  • @Davidw Forgive me, I'm not sure what path to put into the command you're wanting me to run. – LonnieBest May 21 '20 at 14:04
  • @Crypt32 I'm not sure how to do that. I can't recall the last time I used Group Policy. Anything I use to know about it has been forgotten by now. – LonnieBest May 21 '20 at 14:06
  • 1
    @LonnieBest I would just use the desktop, it's the easiest way to find the file. Otherwise, it's up to you. And to refresh group policy, it's `gpupdate` – Davidw May 21 '20 at 16:15
  • 2
    It's worth noting that "This application's security is not the top priority." is not really relevant - the problem with having the workstations accept a (potentially compromised in future) self-signed certificate authority with a 5000 year expiry is not in the security risks to that particular application, but to the risks created for the users/workstations when using everything else. If the workstation trusts that CA for this app, then it will also trust that CA if it's used for MITM'ing, for example, automatically downloading updates for some application or going to `https://www.mybank.com`. – Peteris May 21 '20 at 23:38
  • @Peteris That's good point. At least when the user manually permits the use of the certificate, hopefully that use is limited to only the ip address of the App's intranet location, and not also permitted outside of that scope. – LonnieBest May 22 '20 at 01:39
  • This leads me to the idea, that when a cert is distributed via Active Directory, you should also have to specify the scope to which it applies. It would be very nice if I could tell Active Directory to distribute the certificate and only consider if valid for communication with a particular internal private IP address. I bet that's not offered though. – LonnieBest May 22 '20 at 01:49
  • The big burden is having to have a separate certificate, at each company you install the application. If the application was not using the web browser, you would not have this silly burden. Perhaps I should migrate the app to use something like [Electron](https://www.electronjs.org/), where I might be able to auto-accept the cert in code for all users at all locations. – LonnieBest May 22 '20 at 01:54
  • Can [Electron](https://stackoverflow.com/questions/61961738/) override of self-sign certificate warnings? – LonnieBest May 22 '20 at 18:51
  • I just came across [devcert](https://www.npmjs.com/package/devcert). Sounds interesting at least. – LonnieBest Jul 22 '21 at 16:47

3 Answers3

13

Writing a comprehensive tutorial on this might not be suitable for a Q/A site, but here's some advices. Also, this is from the perspective of managing the installation for a single client within their own intranet. For e.g. SaaS installations it's better to use global FQDNs & PKI.

As a software vendor, you SHOULD NOT:

  • implement own PKI and push it across your clients, as it enables you to issue certificates for arbitrary hosnames, giving you a God mode over their entire infrastucture.
  • use the same self-signed certificates for multiple clients with hard-coded private keys, as they can easily be extracted and used against other clients.
  • combine these mistakes, as it would give every client a God mode over all other clients.

Create your own PKI instead of trusting individual certificates

This is mainly a security consideration, but it's also easier to maintain, as you mention having multiple installations at multiple intranet sites.

  • From the security perspective, you don't want every application to be able to sign certificates for arbitrary hostnames. Therefore, the individual self-signed certificates should not all be trusted certificate authorities.

  • From the maintenance perspective, you don't want to update your policies and wait for them to propagate every time you need to add a new web application.

  • Although preferable, sometimes it's not possible (or wanted) to get certificates from external CAs. The intranet sites may not have globally valid FQDNs, making domain verification impossible, or their connectivity to the Internet is restricted, making it harder to maintain certificate renewals.

In this case, the recommended alternative is to create an own certificate authority for the client (do not push your PKI to multiple clients as a software vendor) and sign all the application certificates with it. This way you only need to add a single certificate to the trusted certificate authorities using GP, and every application certificate signed with it will be trusted.

If you only need a tiny certificate authority for this purpose alone, you might go with OpenSSL:

  1. Generate the root key (rootCA.key) and the root certificate (rootCA.crt).

    openssl genrsa -aes256 -out rootCA.key 4096
    openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 7300 -out rootCA.crt
    

    Keep the key safe, recommendably offline, and distribute the certificate using Group Policy.

  2. Create a certificate for your application starting with a key and a certificate signing request (.csr).

    openssl genrsa -out app.example.com.key 2048
    
    openssl req -new -sha256 \
        -key app.example.com.key \
        -subj "/C=US/ST=CA/O=My Application/CN=app.example.com" \
        -out app.example.com.csr
    
  3. Create an application certificate signed with your CA:

    openssl x509 -req -in app.example.com.csr \
        -CA rootCA.crt -CAkey rootCA.key -CAcreateserial \
        -days 730 -sha256 \
        -out app.example.com.crt
    
  4. Use the app.example.com.key and app.example.com.crt in your application.

For heavier solutions there's Active Directory Certificate Services (AD CS), but that really needs some planning, and your skillset might not be adequate for that, yet.

Use a GPO instead of editing the Default Domain Policy

As a side note, I wouldn't edit the Default Domain Policy for this, but create a new Group Policy Object (GPO), instead. It makes a lot easier to limit the scope of the changes, e.g. making it possible to apply them to a group of test computers, first. It also makes it easier to revert changes, if something goes wrong.


Firefox has own cert store – possible to use certificates from Windows

Mozillaʼs CA Certificate Program governs inclusion of root certificates in Network Security Services (NSS), a set of open source libraries designed to support cross-platform development of security-enabled client and server applications. The NSS root certificate store is used in Mozilla products such as the Firefox browser, and is also used by other companies in a variety of products.

This means certificates added to Windows certificate store doesn't apply to Firefox, by default. For easier maintenance it might be a good idea to make Firefox use the certificate authories installed on Windows. Using own certificate store is a good idea for protecting privacy of individuals using Firefox, but not that suitable for Windows AD environments. Luckily, there's a way to disable it.

Assuming the installation directory of Firefox is C:\Program Files\Mozilla Firefox\, you need to add two ANSI encoded configuration files:

  1. C:\Program Files\Mozilla Firefox\defaults\pref\local-settings.js having

    pref("general.config.obscure_value", 0); 
    pref("general.config.filename", "ownsettings.cfg");
    

    This simply refers to the next file, having the actual configuration parameters.

  2. C:\Program Files\Mozilla Firefox\ownsettings.cfg having

    //
    lockPref("security.enterprise_roots.enabled", true);
    

    It's important the actual settings starts from the second line after //!

These files can be distributed on the same GPO using:

Computer Configuration \ Preferences \ Windows Settings \ Files

enter image description here

Esa Jokinen
  • 43,252
  • 2
  • 75
  • 122
  • Installing his CA at his clients effectively gives him a master key for all HTTPS traffic at his clients. That is a pretty big concern for his clients, and something readers of this answer should be aware of. – marcelm May 22 '20 at 10:47
  • That's not something a software vendor should do! **The own PKI must be internal to the client.** I believe the software is installed on-premises (on local intranets) and clients can freely install the certificate on the server (a single implementation of the application) from their own PKI. If this was a SaaS application, it would definitely need a certificate issued by a root CA (or intermediate) already installed on the browsers. Frankly, I couldn't even imagine the software vendor pushing own self-signed certificates to the trusted certificate store – that simply doesn't make any sense. – Esa Jokinen May 22 '20 at 12:22
  • 2
    From the comments on your answer I can now see that this really was the case. I've added some clarifications to make it clear in what perspective this would be within acceptable solutions. – Esa Jokinen May 22 '20 at 13:37
10

Don't introduce root CAs into other organisations

Using self-signed certificates and distributing them through Active Directory is possible, but fairly involved. Esa Jokinen goes into more detail in his answer.

More important are the security implications; root certificates are like a master key, all certificates signed by a root certificate in AD will be trusted by all company computers. If you control a root cert at an application then you can not just create a certificate for yourapp.intranet that will be trusted, you can do that for any domain. Also for bigbank.com, or for google.com.

Essentially, getting someone to install your root certificate puts you in a position to attack all their HTTPS connections. This means you need to have proper procedures for dealing with those keys, for dealing with revocations, and for dealing with security breaches. It also means that those companies need to put an awful lot of trust in you. And I don't think they should, sorry.

Honestly, if a supplier tried to introduce their own root CA into my organization without thoroughly understanding the concerns involved and having proper plans for everything, I would veto them. I'd probably even veto them with those plans.

Depending on the organization, perhaps they already have their own internal CA; in that case you could request a certificate from them; this absolves you from most of these issues, since CA management is their responsibility, not yours. They also will only give you certificates for just your application.

Is there an alternative?

Consider this alternative approach; Obtain a proper domain name for your application, and obtain a regular SSL certificate from any CA. If cost is a concern, there are several parties offering certificates for free. I like Let's Encrypt.

For the domain name, the most obvious options are company.yourapp.com and yourapp.company.com. The first is easier for you to manage, since obtaining the hostname and the certificate are standardized across all deployments. The latter requires you to deal with the client's IT, but offers better integration for them.

By the way, neither of these options requires your application to be publicly accessible (although that is certainly an option). The domain could simply point to an IP address internal to the company where the application is deployed; You'd need to use email verification or DNS verification to obtain the certificates.

Another option is to have split-DNS; the domain points to a server under your control, which hosts the necessary CA verification stuff so you can obtain certificates. At the company where you application is deployed, their internal DNS points your domain to your private application server.

Replying to some comments

In my opinion, the security zealots blow this topic out of proportion. They treat every situation like online banking, when sometimes all a developer wants is encrypted data transfer.

What you want doesn't exist. You can set up "just encryption", but when you exchange the encryption keys, an attacker can simply intercept those keys and substitute their own, enabling them to read all your encrypted traffic. Certificates ensure that the browser is actually exchanging keys with the intended server, instead of with an attacker. This part is necessary for safe encryption.

In the end, the identity verification is integral to getting the encrypted communication; it is not optional.

The truth is, that a self-signed certificate can provide the same level of encryption (during data transfer) as one used by Bank of America.

Only if you can manage to correctly distribute those certificates. That's easy if it's just one local computer that needs the certificate, but it scales very poorly, and becomes very hard to do right for an arbitrary number of computers.

That's why we use Certificate Authorities; they provide a way to distribute certificates in a scalable and reasonably secure manner.

Apps served from private IP addresses shouldn't have to play by the same rules as international banks, in my opinion.

Thing is, computers don't have common sense. They don't understand that good security is necessary for visiting a bank website, but ehhh security is alright for visiting your app. They can't understand that. And they shouldn't try. What if your app starts dealing with medical records? Suddenly the "common sense" of accepting ehhh security for your app is unacceptable. The computer cannot know that distinction.

If computers have to accept sloppy security on your site, they have to accept it for other sites as well. And luckily we've gotten to the point where that is unacceptable. Accept it, and proudly give your application the same encryption banks use!

It puts a terrible unnecessary burden on the developer

No it doesn't.

Yes, securing a website with HTTPS puts some burden on the developer, such is life. Calling it either terrible or unnecessary is blowing things way out of proportion.

Honestly, just slap some Let's Encrypt certificates on your sites. It gets you the security you want (plus a bit extra), and it's way less effort than complaining about all of this. It's also less effort and safer than trying to be a CA for your clients.

marcelm
  • 994
  • 7
  • 9
  • In my opinion, the security zealots blow this topic out of proportion. They treat every situation like online banking, when sometimes all a developer wants is encrypted data transfer. The truth is, that a self-signed certificate can provide the same level of encryption (during data transfer) as one used by Bank of America. Apps served from private IP addresses shouldn't have to play by the same rules as international banks, in my opinion. It puts a terrible unnecessary burden on the developer, who could otherwise have one key accomplishing data encryption at every installation. – LonnieBest May 22 '20 at 01:34
  • I read Peteris comment, under the question (above). That's a good argument against what I've said above. – LonnieBest May 22 '20 at 01:40
  • It seems it is hard to avoid the granularity at which these SSL certs must be managed. I'm taking your suggestions into consideration. It is a shame you have to put up with this level of micromanagement just to serve an intranet App over https! – LonnieBest May 22 '20 at 02:00
  • 2
    @LonnieBest I was trying to explain the broad security implications in my answer, but it seems I failed to make them sufficiently clear. I have rewritten that part of my answer to be a lot more explicit about that. – marcelm May 22 '20 at 10:44
  • My goal is to distribute my application in a manner that minimizes maintenance. Formal, yearly expiring, certificates are a management nightmare in my opinion. You have to be proactive to ensure that each installation gets a new certificate before the old one expires, else receive support calls when they do expire. Compare this with http, which requires no such maintenance. There needs to be some allowance for intranet apps served from a private IP address with no domain name. The browser-level warnings, for this circumstance, almost make me regret developing my app based on web technologies. – LonnieBest May 26 '20 at 07:50
  • Because, compare web technology based development with desktop applications. In desktop applications you have complete control over the client; if you want to not burden your users with confusing security warnings, you can omit them. With a modern web browser as the client, you have to treat a local application like an international bank to avoid warnings about picky certificate authentication deficiencies. – LonnieBest May 26 '20 at 07:55
2

As the security preaching is already done, so you can go on and make an educated decision, let me give you a simple answer to your question:

  1. The way you already found does work, but only for browsers that actually use the Windows cert store, e.g. IE, Edge as well as Chrome (and others - haven't found a conclusive list)
  2. Firefox can be made to adhere to, but it requires adding and using the ADMX templates, ref. Friefox support

Side note: Google does plan to bring their own CA store to Chrome (not ETA yet AFAIK) but states that the OS enterprise root ca store will still be usable, ref. Chrome Root Program

If you’re an enterprise managing trusted CAs for your organization, including locally installed enterprise CAs, the policies described in this document do not apply to your CA. No changes are currently planned for how enterprise administrators manage those CAs within Chrome. CAs that have been installed by the device owner or administrator into the operating system trust store are expected to continue to work as they do today.