Summary: | IPSec Renew Host Certificate causes openssl error message | ||
---|---|---|---|
Product: | IPFire | Reporter: | Adolf Belka <adolf.belka> |
Component: | --- | Assignee: | Adolf Belka <adolf.belka> |
Status: | MODIFIED --- | QA Contact: | |
Severity: | Major Usability | ||
Priority: | - Unknown - | CC: | michael.tremer |
Version: | 2 | ||
Hardware: | all | ||
OS: | Unspecified |
Description
Adolf Belka
2024-08-06 13:33:53 UTC
Looking through the log on the vm machine I found the following messages. Aug 6 15:56:32 ipfire ipsec: Regenerating host certificate... Aug 6 15:56:32 ipfire ipsec: Revoking the old host cert... Aug 6 15:56:32 ipfire ipsec: Self signing host cert... This does not show up in the IPSec System Logs as the name ipsec is used rather than charon. So the Renew Host Certficate goes through the first three parts and falls down at the Self signing host cert step. I ran the openssl commands manually and the failure occurs during the "sign the host certificate request" stage. The "Create a CSR based on the existing certificate" and "Revoke the old certificate" steps all work fine. I am not sure but it looks to me like the "Sign the host certificate request" step is also trying to revoke the old cert but it has already been revoked. The message that came up with the "Sign the host certificate request" step was openssl ca -md sha256 -days 825 -batch -notext -in /var/ipfire/certs/hostreq.pem -out /var/ipfire/certs/hostcert.pem Using configuration from /etc/ssl/openssl.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'NL' organizationName :PRINTABLE:'XXXXX' commonName :PRINTABLE:'ipfire.XXXX.XXXX.XXXX' ERROR:Serial number 01 has already been issued, check the database/serial_file for corruption The matching entry has the following details Type :Revoked Was revoked on:261109140353Z Expires on :261109140353Z Serial Number :01 File name :unknown Subject Name :/C=NL/O=Newton Sand/CN=ipfire.XXXX.XXXX.XXXX and the Error message is that the serial number 01 has already been issued. In the "Revoke the old certificate" step the following was reported:- openssl ca -revoke /var/ipfire/certs/hostcert.pem Using configuration from /etc/ssl/openssl.cnf Adding Entry with serial number 01 to DB for /C=NL/O=Newton Sand/CN=ipfire.saturn.pimb.org Revoking Certificate 01. Database updated Hence why I think the signing is trying to revoke the cert a second time but my conclusion may not be valid. Hopefully the above helps to figure out what is going wrong. Having looked through the code and thought about it for a while I am wondering if the serial number should be incremented when a new cert is being created. That doesn't happen in vpnmain.cgi. The value in the serial file always stays at 01 so when the replacement cert is being signed it finds that the serial entry in the database has already been used. I just edited the serial file to change 01 to 02 and then ran the openssl ca -md sha256 -days 825 -batch -notext -in /var/ipfire/certs/hostreq.pem -out /var/ipfire/certs/hostcert.pem command again and this time the cert was successfully signed and now the index.txt database has the revoked 01 cert and a valid 02 cert. So the serial value needs to be incremented somewhere in the vpnmain.cgi code. I will have a look and see if I can figure out where it should be done. After generating the Root/Host certificate set, if I change the value in the serial file from 01 to 02 and then press the Renew Host Certificate icon then the Host cert is renewed and the value in serial is incremented. So the incrementation is working but not at the start, only after serial has been changed to 02. I also noticed that after creating the root/host certificates that the index.txt has no Valid entry for that cert, so it looks like the initial generation is not updating the index.txt database. If the serial is changed to 02 after the root/host certs have been generated then a Renew Host Certificate step updates the index.txt to have a revoked 01 cert and a valid 02 cert. The change for renewing the vpn certificate was introduced in CU184. I installed CU184 in my vm system and tested out renewing the certificate and got exactly the same error. This suggests that this renewal was not working properly when it was first introduced. At least I have not been able to get it to renew successfully. The error messages say that the renewal cannot be done because the serial number of the cert has already been revoked. So this looks like the missing bit is that when the renewal is done, that after the revoke the number in the serial file needs to be incremented. I will have a look at adding the incremental update in and see if I can get it to work. Doing the incrementing manually worked when I tried it in my testing back in August 2024. So I have been able to get the regen working. I had to increment the serial file number from 01 to 02 after the root/host certificate generation was completed. After that the regen works and the serial number is automatically incremented. There may be a better way of doing this but I could not identify it. I also changed the "ipsec" entry for the log messages to "charon" so that the System Logs for IPSec show all the messages, including those related to generation and regeneration of the certificates. I will submit a patch set for these changes for review to identify if there is a better alternative that I should have used. patch set submitted to the dev mailing list and patchwork. https://lists.ipfire.org/hyperkitty/list/development@lists.ipfire.org/thread/ZL2WIMYA7BIM5D2M7ALRRJ2MTTDADF2A/ https://patchwork.ipfire.org/project/ipfire/list/?series=4773 patch has been merged into next. https://git.ipfire.org/?p=ipfire-2.x.git;a=commit;h=7d1d7e0bec4c7f991dbbb622ce414e0b91d14d74 More work needed on the patch. The patch submitted so far sets the serial number to 02 after the root/host certificate set is created, which works fine for a newly created certificate set. However it doesn't work for an existing root/host certificate set which already has the serial number set at 01. The simplest option would be to check in the update.sh script if the ipsec x509 certificate set has been created and then change the serial number to 02. The only way this might be a problem is if someone has manually edited the serial file to have 02 in which case after any regen this number could already be higher than 02. I think if I check in the update.sh script if serial contains 01 then it should be changed to 02 but otherwise it should be left as it is. That way the serial number will only be updated for those ipsec root/host certificate sets that have been created but still have the serial file having the contents of 01. I have moved the status back to ON_DEV until I have submitted a patch for the update.sh script and it has been merged etc. I realised that the backup should also be modified to ensure that a restore did not end up with a serial file with 01 again but then I discovered that the serial filer and the index.txt and the old versions of both of them are not backed up. The only files backed up from the /var/ipfire/certs/ directory are all .pem files. However the serial and the index.txt also need to be backed up, otherwise a restore could bring back an old certificate that has already been revoked in the existing index.txt file. The serial and index.txt files for the /var/ipfire/ovpn/certs/ directory are backed up ( all files in that directory are backed up) and the same should be happening for the ipsec certs. So my patch submission will also include a change to the include file to capture all in the vpn certs directory. No change will be needed to the backup.pl file as no existing backups will contain a serial file for ipsec. When this is started to be backed up then the serial file will already have contents of 02 once the root/host certificate set has been created for the first time and the update will ensure that existing ipsec systems will have a serial file containing at least 02. Further information has been identified. With the submitted patch when a new root/host x509 certificate set is created the serial file is set to "02". However, when a client connection is then created, the act of doing this resets the serial file contents to "01". It has become clear to me that the patch I submitted dealt with the symptoms of the problem and not the cause itself. So the patch I submitted has been reverted. Looking through the code I have identified that the subroutine &clearssldatabase is run after every openssl command for a new client connection cert and the root/host cert set. It is run both for when the command is successful and also if it gets an error. Basically every cert action will reset the serial file back to "01" which is not what is wanted. Currently the code also rests the serial entry for both client and root/host certs but there are no revocations of the client connection cert so that does not need to have any command to reset the serial file. So it looks like I need to remove the &cleanssldatabase commands from the client opensssl cert creation commands and leave them in the root/host openssl cert commands but only for when the command has a failure and the status needs to be put back to the start position. I now need to test the above out to confirm that it does what I expect and that it has not unexpected side effects. It has also been identified that the renew process, which was supposed to create a new host cert with identical contents as the expired/revoked one was missing out the SubjectAltName line contents. It has been identified how to fix that and the fix has been confirmed, so that will be submitted as a patch when the fix for the serial file contents has been identified and confirmed as working. (In reply to Adolf Belka from comment #12) > > It has also been identified that the renew process, which was supposed to > create a new host cert with identical contents as the expired/revoked one > was missing out the SubjectAltName line contents. > > It has been identified how to fix that and the fix has been confirmed, so > that will be submitted as a patch when the fix for the serial file contents > has been identified and confirmed as working. I identified that the fix I used had already been applied to openssl.cnf in CU184 but the changed file was not shipped. So the change is only found in new installs of CU184 or later. Patch has been submitted to ship the changed openssl.cnf file https://lists.ipfire.org/development/20250401122650.5358-1-adolf.belka@ipfire.org/T/#u https://patchwork.ipfire.org/project/ipfire/list/?series=4834 Patch set submitted to the dev mailing list and patchwork. I have tested this quite carefully both with creating, renewing and deleting the root/host cert set and also with adding and deleting client certs. Also tested out the backup changes. Everything I tried worked but it will be good to have it reviewed in the patch review process in case I missed anything. https://lists.ipfire.org/development/20250401180802.19784-1-adolf.belka@ipfire.org/T/#t https://patchwork.ipfire.org/project/ipfire/list/?series=4835 v2 version had to be submitted for patch 4/6 https://lists.ipfire.org/development/20250401205002.24485-1-adolf.belka@ipfire.org/T/#u https://patchwork.ipfire.org/project/ipfire/patch/20250401205002.24485-1-adolf.belka@ipfire.org/ Patch set has been merged into next for CU194. |