Handling of TLS certitificates in OPNsense
Concerns OPNsense business edition 25.10_2.
Accessing the firewall GUI via HTTPS To access the Web GUI via HTTPS, the client establishes a TLS connection with the firewall. The Web server on the firewall replies with its public X509v3 certificate and some client data encrypted with its private key to proof that it is in possession of the private key. The client validates the public key against a trusted certificate authority (CA) or an intermediate CA.
In a new OPNsense installation the certificate pair used for HTTPS access is called 'Web GUI TLS certificate'. The public certificate contains Subject: CN = OPNsense.localdomain, C = NL, ST = Zuid-Holland, L = Middelharnis, O = OPNsense self-signed web certificate.
This is ok for accessing the firewall for the first time. You have to accept the security risk in your browser (which creates bad habits) but as long as the firewall is not connected to any network this is ok.
For production environments we don't want self-signed certificates because they are vulnerable to man in the middle (MIT) attacks. Someone could intercept the traffic, respond with a similar self-signed certificate and forward the request to the firewall. If you do not check the fingerprint of the certificate you won't recognize the interception.
Solution 1: OPNsense as CA One could use the firewall as a certificate authority and import its public key in the browser. But there are good reasons not to do this (see below). In this scenario the firewall could issue a CA signed certificate for the HTTPS access and renew it on demand.
Solution 2: Import a certificate generated from a trusted CA In business environments you normally have an offline Root CA which signs an intermediate CA. It's private key is never visible to anybody. The public key of the Root CA is deployed to every client e.g. by a group policy and used to verify all company internal certificates. The intermediate CA is responsible for signing certificate requests. It has to be online or have at least access to some transfer storage. It's private key is protected as good as one can e.g. only visible to the root user of the Intermediate CA.
Network devices normally do not support automatic renewal of certificates like Web severs do e.g. through ACME. Hence one has to do this manually:
- Import our Root CA’s public key as trusted CA into the firewall.
- Import our Intermediate CA’s public key into the firewall.
- Create a certificate signing request CSR on the firewall (which includes generating a new secret private key) and transfer the CSR to the Intermediate CA.
- Validate the CSR on the Intermediate CA.
- Sign the CSR with the Intermediate CA and transfer the generated public key certificate back to the firewall.
- Import the public key certificate into the firewall. Alternatively import the whole chain of public key certificates if the device cannot handle intermediates (bullet 2).
- Alter the HTTPS server configuration of the firewall to use the new certificate.
This is supported with some caveats on the OPNsense firewall.
So what's the problem? If you read this carefully you will have noticed, that there is no need to share any private keys at all. In fact the true magic of public key infrastructure (PKI) is the fact that no private keys ever leave the owning device at all.
Unfortunately this is not true for OPNsense. If you open the Settings>Trust you can inspect the private keys of all certificates in the Web GUI, copy paste them to wherever you want. Private keys also occasionally show up in System>Configuration>History and are part of (unencrypted) backups.
Where to go in the future? An OPNsense firewall is not a openssl playground, it is a security device. Hence the access to it's private keys has to be protected as good as possible. This excludes
- showing any private keys in the Web GUI or to non-root SSL users
- exporting private keys (PKCS12 is only for poor devices not capable of generating their own private keys)
- including private keys in unencrypted backups
The backup/restore process gets a bit more tricky. Unencrypted configuration backups are useful because you can easily compare them and track them in a version control system. If the firewall excludes private keys (and passwords) from unencrypted backups, the firewall has to create new key pairs (and set standard passwords) on restore. This is not optimal but acceptable since one can change passwords afterwards an reissue new certificates signed by the company's CA.
What do you think about certificate handling in OPNsense?
Unfortunately this is not true for OPNsense. If you open the Settings>Trust you can inspect the private keys of all certificates in the Web GUI, copy paste them to wherever you want. Private keys also occasionally show up in System>Configuration>History and are part of (unencrypted) backups.
Administrators have access to these pages for administrative purposes. If you don't need GUI users to reach these pages simply give them less than administrator privileges.
Cheers, Franco
If you don't need GUI users to reach these pages simply give them less than administrator privileges.
Hence you downgrade certificate security to Web server access control. I'd never do this!
Is this a question? You're not making much sense, sorry.
Cheers, Franco
The point is: The reason why people don't want to run Web severs as root is the possibility of bypassing Web Server security. Therefore private keys are handled by root and the rest is done with unpriviledged users. If you show private keys in the Web GUI you give away your secrets for free (or would you remember to deny access to System>Configuration>History?). If one uses PKI as designed, there is no need to see or share any private keys in a Web GUI at all.
Thank you for creating an issue. Since the ticket doesn't seem to be using one of our templates, we're marking this issue as low priority until further notice.
For more information about the policies for this repository, please read https://github.com/opnsense/core/blob/master/CONTRIBUTING.md for further details.
The easiest option to gain traction is to close this ticket and open a new one using one of our templates.
@brungu The current way of key / certificate managment is more or less in line with other security device vendors. You can extract Private Keys in Fortigates, Checkpoint, F5 etc...
I like the options provided by opensense, most devices only make the proccess more difficult, but not impossible. This only hurts the legitimate admins and not the bad actors. As the WebGUI should not be exposed to the internet there is really no security considerations in my opionion about the webgui certificate of a firewall and there certainly is no auto regeneration like ACME because that would entail you give your firewall some kind of public DNS wich can be done but I would not call this to be a recommended setup.
It is your device, it is your responsibility to secure it for your environment. If your ISMS enforces that no admin should have access to Private keys, there is nothing stopping you to save the password for root/admin User in a locked safe and have every admin work with their own restricted user account that does not have access to the Trust page.
I think Opsensene allows to restrict this as is
@Denton22 Thank you for your explanations!
You can extract Private Keys in Fortigates, Checkpoint, F5 etc...
Unencrypted? I doubt this still holds. To extend the list: Sophos does not allow you to access private keys and does not support unencrypted backups. Zyxel does not allow you to access private keys but allows export to pkcs12. Backups contain symmetrically encrypted passwords and certificates which is not really secure.
I like the options provided by opensense, most devices only make the proccess more difficult, but not impossible. This only hurts the legitimate admins and not the bad actors.
What would be a real world scenario where you effectively need to access private keys from the firewall?
As the WebGUI should not be exposed to the internet there is really no security considerations in my opionion about the webgui certificate of a firewall and there certainly is no auto regeneration like ACME because that would entail you give your firewall some kind of public DNS wich can be done but I would not call this to be a recommended setup.
ACME was just an example. I'd never use a public CA to sign firewall certificates.
It is your device, it is your responsibility to secure it for your environment. If your ISMS enforces that no admin should have access to Private keys, there is nothing stopping you to save the password for root/admin User in a locked safe and have every admin work with their own restricted user account that does not have access to the Trust page.
I think Opsensene allows to restrict this as is
The world has changed. Incidents where attackers passed a well configured firewall are quite rare. In most cases attackers built pitfalls and tricked users into entering credentials or just waited until someone made a mistake. The attack surface of a firewall is far more than its network interfaces. It includes updates, plugins, management, backups, logs, certificates...
GUI readable private keys encourage admins to copy-paste around secrets e.g. forum entry 48544. The clipboard is accessible to every process. If you work in a virtual machine the clipboard possibly bleeds out to the host and in the worst case is shared with other VMs. You could use drag and drop which is more end-to-end but still dangerous.
Everything that is allowed will extend your attack surface. Therefore we should restrict it to what is really needed and viewing private keys in the GUI is definitely not required in normal PKI workflows.
@brungu So you want the option to export "Private Keys" as a .pem file removed in the GUI? Your request is not really clear WHAT you want.
I get that the handling of private keys can be delecate....
-
Opensense doesent provide viewing the Private Key in GUI, under Trust > Certificates > Webserver Cert >show certificate Info there are no key related entries, only the public key side. So there is no copy pasting the unencrypted key...
-
Exporting the Private Key as a File is possible either as an unencrypted PEM file or as an encrypted PKCS12. If you want the unencrypted option to be removed, I think it would be possible to add some kind of option under System > Settings > Administration to allow to disable this. But you can also just simply remove the Admin Permission for the Trust Page.
-
Exporting over GUI or over CLI makes little to no difference from a security perspective.
The Current Opensense Handling is to save the Private Key and the Public Key in /conf/config.xml
In this File there is an entry like the following:
<cert uuid="ecf5c7d9-d739-4f05-8d6b-80726b1d7086"> <refid>67cdc276ca6e3</refid> <descr>Web GUI TLS certificate</descr> <caref/> <crt>PUB_KEY</crt> <csr/> <prv>PRIV_KEY</prv> </cert>
I think this is the unencrypted Private Key maybe @fichtner can shed some light here? If the Private Key is saved unencrypted into the config.xml, I think @brungu has a case here. The Private Key should not be saved unencrypted as a file or as part of a config file on the Opensense Appliance.
I would think that it should not be too hard to implement some way to save the key encrypted and load the encryption key at runtime. Maybe something for 26.X ?
So as a quick TL;DR here is an enhancement Request as I see it:
- Opensense should not save Private Keys unencrypted into the config.xml file or any other file.
- Opensense needs to save Private Keys encrypted into the config and load the encryption file at load time. This Encryption file needs to be secured with Principle of Least Privilege (PoLP) in mind.
- Opensense should remove the GUI Option to export Private Keys in unencrypted format. The Current export funtion to PKCS12 is sufficent and more safe.
- Opensense should add some kind of Disclaimer in the documentation about this topic related to Plugins / Third Party Modules like caddy that save the unencrypted private Key as a file under: /var/db/caddy/data/caddy/certificates/acme-v02.api.letsencrypt.org-directory
But this Request is strictly about opensense core
Also to give a different perspective there is a security framework established:
https://docs.opnsense.org/security.html#framework-type-of-testing-lince
When reading the testing criterias it includes "3.5 (MEC) CRYPTOGRAPHIC MECHANISMS EVALUATION" which does include the whole "where is private key stored and accessed" stuff.
I would imply if these tests pass, its okay?
@Monviech I am not familiar with the lince security framework, and I can not find any reference to your mentiond criteria in any of the reports regarding opensene in the link you supplied.
After trying to look it up I found the following: https://www.jtsec.es/files/CCN-LINCE-002_v0.1_final_EN.pdf but its quite old, it states the following:
So MEC seems to be some kind of optional extension to the lince framework? But yes its talking about the right stuff as far as i can see.
However I was unable to find any pass / fail criteria regarding this. So I dont know if passing it "fixes" the issue. After what i read you only need to describe your Key Management, but there are no recommendations regarding the Key Mangament.
So as a quick TL;DR here is an enhancement Request as I see it:
- Opensense should not save Private Keys unencrypted into the config.xml file or any other file.
- Opensense needs to save Private Keys encrypted into the config and load the encryption file at load time. This Encryption file needs to be secured with Principle of Least Privilege (PoLP) in mind.
- Opensense should remove the GUI Option to export Private Keys in unencrypted format. The Current export funtion to PKCS12 is sufficent and more safe.
- Opensense should add some kind of Disclaimer in the documentation about this topic related to Plugins / Third Party Modules like caddy that save the unencrypted private Key as a file under: /var/db/caddy/data/caddy/certificates/acme-v02.api.letsencrypt.org-directory
Just to avoid derailing this with suggestions that can impossible lead to change.
- If the key is required for some service on the firewall (it doesn't matter which one), this is theoretically impossible given the ground rules are (amongst others): "a service can use a key without needing a password in order to start", "a copy of the configuration warrants a functional firewall in equal state as before", "cryptographic keys are not bound to specific hardware"
- see above, if you store data encrypted in the config, which key was used to decrypt it then..... it's a chicken and egg problem, when storing keys in specialized hardware enclaves you can partly solve this as at the cost of convenience and platform independence (usually the software is bound to specific hardware, which doesn't work very well if everyone wants to use that same software on generic hardware)
- If you're looking for a lot of complains, sure, in reality, people need these formats as they feed these keys into their applications in many occasions. There's not much gain in removing a feature you can prevent people from accessing in the first place (do not, ever, offer regular users access to your trust store). If the concern is people exporting these keys, using PKCS12 with a password being set on export doesn't really make much of a difference.
- Always open for discussions on how to improve the documentation, in reality a lot of services have a copy of a private key needed for normal operation. The generic message when it comes to trust should more likely be "make sure to wipe your drive properly when scrapping the device"
I'm not planning to join a discussion, just offering a bit of extra context as a lot of these discussions popup over the years and a lot of conclusions have already been made.
We're always open for suggestions, but they need to have enough technical depth in order to mature and take a lot of different use-cases into account (impact on others).
@Denton22 wrote:
Opensense doesent provide viewing the Private Key in GUI, under Trust > Certificates > Webserver Cert >show certificate Info there are no key related entries, only the public key side. So there is no copy pasting the unencrypted key...
In System > Trust > Certificates you can edit certificates (pencil). If you scroll down and open Output (PEM format) you will see your private key.
As always, security and convenience must be balanced carefully. If a system is trimmed for convenience, it is most likely not secure. If it's trimmed for security, it is inconvenient and users seek for workarounds which degrades security.
As I understand, there are the following use cases to be covered:
UC1: As a firewall administrator I want to create a new secret private key and a signing request to get a signed certificate from my (intermediate) CA.
UC2: As a firewall administrator I want to import the signed certificate to use it as Web server certificate for the firewall administration GUI.
Optional UC3: As a firewall administrator I want to import an encrypted SSL/TLS key pair in PKCS12 format to use it as Web server certificate for the firewall administration GUI. (This is normally done only on very small devices which are not able to generate reasonably secure private keys and signing requests.)
Optional UC4: As a firewall administrator I wand to export any SSL/TLS key pair in encrypted PKCS12 format to do some mysterious things.
UC5: As a firewall administrator I want to see configuration changes in the GUI to check them. (This is possible in System > Configuration > History. Unfortunately it occasionally shows private keys.)
Horrible UC6: As a firewall administrator I want to back up the firewall configuration in unencrypted format to restore it on the same or changed hardware.
UC7: As a firewall administrator I want to back up the firewall configuration in encrypted format to restore it on the same or changed hardware.
UC8: As a firewall administrator I want to back up the firewall configuration without any secrets (passwords, SSH private keys, SSL/TLS private keys) in unencrypted format to track changes in a version management system. (By hand or using the os-git-backup plugin.)
UC9: As a firewall administrator I want to import an encrypted backup of the firewall configuration to restore the firewall configuration with all its secrets.
UC10: As a firewall administrator I want to import an unencrypted backup of the firewall configuration to restore a previous configuration while retaining passwords, SSH key pairs, SSL/TLS key pairs. (On virgin hardware this should retain the default password and the self signed SSL/TLS certificate for the Web GUI. Both can be replaced afterwards.)
This is a (possibly limited) user perspective. The implementation has additional boundary conditions. As @AdSchellevis pointed out, encrypting the private SSL/TLS key on the firewall itself is not feasible. Nevertheless access to private keys should be restricted as much as possible on the firewall's file system, which I assume is already the case. The generation of encrypted backups and encrypted key pair exports could be delegated to an other service such that the GUI code would not need access to the secrets itself. The Web server still needs the private key to establish the TLS connection.
If someone uses the firewall to run other Web services like a reverse proxy, they should use separate key pairs and not the ones used for the firewall administration Web GUI. I don't know the corresponding use cases but still I doubt they really need to export/import unencrypted secrets if following normal PKI workflows.
Concerning encryption of backups: Encrypting secrets with a universal symmetric key allows to import configurations on changed hardware without entering a password. This is what Zyxel does and is definitively not secure as the encryption password can easily be extracted from code. Sophos enforces a password of at least 12 characters. This is still within reach of rainbow tables but better than nothing.
Thanks for your suggestions. For the foreseeable future, however, the project can not and will not implement these requirements since they are currently considered out of scope.
Cheers, Franco