New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Turn on NSSOCSP check in mod_nss conf #729
Conversation
ipaserver/install/httpinstance.py
Outdated
| @@ -156,6 +157,7 @@ def create_instance(self, realm, fqdn, domain_name, pkcs12_info=None, | |||
| self.set_mod_nss_protocol) | |||
| self.step("setting mod_nss password file", self.__set_mod_nss_passwordfile) | |||
| self.step("enabling mod_nss renegotiate", self.enable_mod_nss_renegotiate) | |||
| self.step("enabling mod_nss NSSOCSP", self.enable_mod_nss_ocsp) | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think OCSP is preferrable over NSSOCSP which may confuse some people.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thats true, I'll change that.
ipaserver/install/httpinstance.py
Outdated
| aug.set(os.path.join(ocsp_path, 'directive[last()+1]'), 'NSSOCSP') | ||
|
|
||
| aug.set(os.path.join(ocsp_path, 'directive[. = "NSSOCSP"]/arg'), 'on') | ||
| aug.save() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pulled this into a separate file and it didn't seem to work in F-25, could be something I did wrong...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried it during IPA installation, not alone and it worked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll chalk it up to a copy-paste problem on my end assuming others do an end-to-end test and confirm all three possible states (No starting NSSOCSP, NSSOCSP off, and NSSOCSP already on.
ipaserver/install/server/upgrade.py
Outdated
| @@ -1375,7 +1375,7 @@ def remove_ds_ra_cert(subject_base): | |||
| def fix_trust_flags(): | |||
| root_logger.info('[Fixing trust flags in %s]' % paths.HTTPD_ALIAS_DIR) | |||
|
|
|||
| if sysupgrade.get_upgrade_state('http', 'fix_trust_flags'): | |||
| if sysupgrade.get_upgrade_state('http', 'fix_trust_flags2'): | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why you are changing the name of the state rather than adding a new state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I could create new state, but is it really needed? My new code fixes trust flags in httpd/alias, thats what this state is for, so I don't see any point in copying (duplicating) it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rob is right that you should probably have a new state to do this, this one was supposed to do some changes and you're adding some more on top of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, at the beginning I wanted to add it, too, but this solution (not add new state) was recommended me by @HonzaCholasta. So if @HonzaCholasta is ok with a new state, then I will create it.
ipaserver/install/server/upgrade.py
Outdated
| @@ -1389,7 +1389,11 @@ def fix_trust_flags(): | |||
| if cert: | |||
| db.trust_root_cert(nickname, 'CT,C,C') | |||
|
|
|||
| sysupgrade.set_upgrade_state('http', 'fix_trust_flags', True) | |||
| sc_nickname = installutils.get_directive(paths.HTTPD_NSS_CONF, | |||
| "NSSNickname") | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a None check here for paranoia reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure whether there can be a situation when NSSNickname is not specified. Is it possible or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure but throughout the cert code whenever a cert is searched for in this way a sanity check follows.
ipaserver/install/server/upgrade.py
Outdated
| @@ -1404,6 +1408,11 @@ def update_mod_nss_protocol(http): | |||
| sysupgrade.set_upgrade_state('nss.conf', 'protocol_updated_tls12', True) | |||
|
|
|||
|
|
|||
| def enable_mod_nss_ocsp(http): | |||
| root_logger.info('[Updating mod_nss enabling NSSOCSP]') | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, I'd replace NSSOCSP with just OCSP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @pvomacka
thank you for the patch. please find my comments inline.
| api.finalize() | ||
|
|
||
| db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR) | ||
| server_certs = db.find_server_certs() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
db.find_server_certs() returns all the certs in the DB with the u flag, and it may return more than one nickname, maybe not the one you are expecting. You could use installutils.get_directive(paths.HTTPD_NSS_CONF,'NSSNickname') instead in order to find the nickname of HTTPd server certificate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @flo-renaud, thank you for review.
Yes, I that will be better to use the installutils method.
|
|
||
| nickname = server_certs[0][0] | ||
| db.trust_root_cert(nickname, "P,,") | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a specific reason for changing the flag in this script (during restart of httpd) rather than during upgrade? Is it to make sure that certs configured with ipa-server-certinstall have the proper flag? Then a comment would help future developers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the certmonger restart script. This is probably a belt-and-suspenders change to assure that the peer flag is retained. I agree a comment would be helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, @rcritten is right. And true is that I forgot to add it into commit message. I will add it there.
| nickname = installutils.get_directive(paths.HTTPD_NSS_CONF, "NSSNickname") | ||
|
|
||
| db.trust_root_cert(nickname, "P,,") | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a one-line comment here is needed so future devs will know what this is about without having to dig thru git history.
ipaserver/install/server/upgrade.py
Outdated
| sc_nickname = installutils.get_directive(paths.HTTPD_NSS_CONF, | ||
| "NSSNickname") | ||
| db.trust_root_cert(sc_nickname, "P,,") | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will ALWAYS fix the trust though. Is that what you want? I think it should be in a separate function, tracked separately, with a similar test for being already executed. I doubt it would cause any harm being run multiple times but it is bad form.
ipaserver/install/httpinstance.py
Outdated
| if ocsp is None: | ||
| aug.set(os.path.join(ocsp_path, 'directive[last()+1]'), 'NSSOCSP') | ||
|
|
||
| aug.set(os.path.join(ocsp_path, 'directive[. = "NSSOCSP"]/arg'), 'on') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can shorten this to:
aug.set('/files/etc/httpd/conf.d/nss.conf/VirtualHost/directive[. = "NSSOCSP"]', 'NSSOCSP')
aug.set('/files/etc/httpd/conf.d/nss.conf/VirtualHost/directive[. = "NSSOCSP"]/arg', 'on')Additionally, you can prepend the following to uncomment NSSOCSP:
aug.set('/files/etc/httpd/conf.d/nss.conf/VirtualHost/#comment[. =~ regexp("NSSOCSP .*")]', 'NSSOCSP')
aug.rename('/files/etc/httpd/conf.d/nss.conf/VirtualHost/#comment[. = "NSSOCSP"]', 'directive')|
@pvomacka, CI fails because you forgot to include python-augeas in lint BuildRequires. On a related note, the python-augeas Requires should be in python2-ipaserver and python3-ipaserver, not in freeipa-server. |
| @@ -1392,6 +1392,23 @@ def fix_trust_flags(): | |||
| sysupgrade.set_upgrade_state('http', 'fix_trust_flags', True) | |||
|
|
|||
|
|
|||
| def fix_server_cert_trust_flags(): | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick, but I would rather name this http_trust_server_cert or similar.
ipaserver/install/httpinstance.py
Outdated
| aug = augeas.Augeas() | ||
| ocsp_path = os.path.join('/files', | ||
| paths.HTTPD_NSS_CONF[1:], | ||
| 'VirtualHost') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should use format strings here as well:
path = '/files{}/VirtualHost'.format(paths.HTTPD_NSS_CONF)
ipaserver/install/httpinstance.py
Outdated
| aug.rename('{path}/#comment[. = "NSSOCSP"]'.format(path=ocsp_path), | ||
| 'directive') | ||
| aug.set('{path}/directive[. = "NSSOCSP"]/arg'.format(path=ocsp_path), | ||
| 'on') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: You can fit each of these statements on a single line by removing some unnecessary stuff:
aug.set('{}/#comment[.=~regexp("NSSOCSP .*")]'.format(path), 'NSSOCSP')
aug.rename('{}/#comment[.="NSSOCSP"]'.format(path), 'directive')
aug.set('{}/directive[.="NSSOCSP"]/arg'.format(path), 'on')
ipaserver/install/httpinstance.py
Outdated
| @@ -263,6 +265,20 @@ def enable_mod_nss_renegotiate(self): | |||
| installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSRenegotiation', 'on', False) | |||
| installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSRequireSafeNegotiation', 'on', False) | |||
|
|
|||
| def enable_mod_nss_ocsp(self): | |||
| aug = augeas.Augeas() | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default, augeas loads all lenses and all configuration files it finds in the system. I guess we don't want it to do that and load only the httpd lens and the /etc/httpd/conf.d/nss.conf file, which can be done using:
aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD)
aug.set('/augeas/load/Httpd/lens', 'Httpd.lens')
aug.set('/augeas/load/Httpd/incl', paths.HTTPD_NSS_CONF)
aug.load()There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you using augeas instead of some simple Python code? Introduction of new dependencies should be discussed first.
freeipa.spec.in
Outdated
| @@ -306,6 +306,7 @@ Requires: oddjob | |||
| Requires: gssproxy >= 0.7.0-2 | |||
| # 1.15.2: FindByNameAndCertificate (https://pagure.io/SSSD/sssd/issue/3050) | |||
| Requires: sssd-dbus >= 1.15.2 | |||
| Requires: python-augeas | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really want to depend on a new Python library, C library and complex framework just to change a line in a config file? I'm -1. The task can be accomplished with a bit of Python code and regexp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it would be possible to do it only with python regexp but it will be much nicer to do it using augeas. And python-augeas is available in RHEL and Fedora so it is not a big issue to add a dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to migrate all config file handling to augeas eventually, and don't want introduce any new yet another barely maintainable ad-hoc bits of Python code to update a config file, so now is as good time as any to add the dependency.
740da4c
to
9156542
Compare
|
Hi @pvomacka |
|
augeas should be dependency of python2-ipaserver and python3-ipaserver (python3-augeas) packages |
|
Hello @flo-renaud, thank you for testing this. |
|
And you also need python[3]-augeas as Pylint BuildDependency to pass pylint :), sorry I forgot about it. |
|
And you also need to add it in |
Turn on NSSOCSP directive during install/replica install/upgrade.
That check whether the certificate which is used for login is
revoked or not using OSCP.
Marks the server cert in httpd NSS DB as trusted peer ('P,,')
to avoid chicken and egg problem when it is needed to contact
the OCSP responder when httpd is starting.
https://pagure.io/freeipa/issue/6370
|
@MartinBasti thank you for comments, fixed. |
Turn on NSSOCSP directive during install/replica install/upgrade.
That check whether the certificate which is used for login is
revoked or not using OSCP.
https://pagure.io/freeipa/issue/6370