-
Notifications
You must be signed in to change notification settings - Fork 24
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
Configuration file for HTTP Unix daemon #77
Comments
Thanks for writing this down. Would be nice if one could place margin notes in issues ... So, I'll give a few quoted replies.
This remark is in because ideally there should be a Windows counterpart of this file. That would have to deal with all these certificate and server start issues as well, but not with forking, syslog interactions, etc. But, let us not complicate things further than needed and keep focussing on the http_unix_daemon.pl. If we ever write a http_windows_service.pl or something like that we can still refactor the code and move the shared part into a new file. |
Note that most of the options are for classical init daemons. There is no need for Somehow, I guess we need a sensible default for the |
We have that by means of That is why I'd like to stick with the idea of using hooks in For example: define
This way we keep things modular and we keep everybody happy. This style is used throughout the HTTP infrastructure and seems to work well. |
Perfect, I fully support extending this with hooks. Please note that we should have a solution for #71 first, so that the I see no need for There is one thing though I still would like to discuss. We must distinguish between 3 kinds of options:
In the HTTP framework, (3) appear as part of (2), in the form of The remaining task is to make the current option processing so general that most practically arising situations are well covered, or at least can be covered with acceptable work. The HTTP Unix daemon currently (or at least with the proposed patch) uses the following for (3): SSL = ssl([ certificate_key_pairs(Pairs), cipher_list(CipherList), password(Passwd), sni_hook(http_unix_daemon:sni) ]). It is completely OK that
What's definitely not OK if this is to be extended by hooks is the fixed appearance of Here is a list of use cases (which I expect to occur quite frequently in the near future) that are currently not covered by the Unix daemon, and which should become possible with new hooks: a) HTTPS servers without default certificate (relying fully on SNI) The most important are (a) and (b), which are the subject of #76. (c) is lower priority, but there is one important point about it: Currently, findall(HostName-HostOptions, http:sni_options(HostName, HostOptions), SNIs), maplist(sni_contexts, SNIs), etc. sni_contexts(Host-Options) :- ssl_context(server, SSL, Options), assertz(sni(_, Host, SSL)). I think this would be doable for users who are interested in SNI, and I will document this in LetSWICrypt, so we could remove I mention (d) only for completeness: Of course, the current options that affect the daemon itself should all continue to work. This may sound a bit complex now, so I would like to point out that we are extremely close to this already now: Almost everything works already, and a single new hook may be sufficient to also cover the remaining use cases in an elegant and flexible way. |
I think I have found a good way to solve these issues: I will add a new predicate called Update: It turns out that In addition, there will be a new hook hat is invoked by the HTTPS plugin after creating the SSL context of the server. By defining a clause for that hook and using the new With some luck, I may be able to use the new predicate to also solve #70, and I will work on this in 7.5. Note that OpenSSL has no API to remove certificates from a context, so this may require much more work, but updating a certificate may turn out to be easy. I would greatly appreciate a good naming suggestion for the HTTPS hook that is in line with the existing hooks. I note that some of the hooks currently use the |
(c) above can likewise be solved with a new predicate like I think such predicates to modify an SSL context after its creation are best to obtain the flexibility we need in this case. In many situations, I would like to use the HTTP Unix daemon and make only such small adjustments without having to roll my own server. A single suitable hook to configure an HTTPS server by giving access to the SSL context after its creation is enough to handle all this. |
I'm closing this because the new hooks The way to extend this in the future is to add further predicates that allow us to adjust an SSL context, in a pure and — therefore — thread-safe way, of course. |
In this issue, I would like to:
library(ssl)
The (perceived) need for a configuration file was first raised and supported in #54, with Wouter and me in favour of the idea. It was dismissed again because for that concrete issue, a more trivial fix was applied. Now, a few months later and with the availability of new features for HTTPS servers, this is coming up again in #76.
First, I would like to give a short summary of what a typical HTTPS server needs as its configuration. It is evident that in the very near future, HTTPS servers will become the "normal" web servers, since plain HTTP servers will be marked as insecure by all major browsers. Therefore, it is wise to consider how to best accommodate their configuration.
Currently, a typical SWI-Prolog HTTPS server is started by supplying the following command line options to the Unix daemon:
--https
(mandatory)--keyfile=File
(almost all servers will use this, even though it could theoretically be omitted)--certfile=File
(again, used by almost all servers).A significant portions of these servers will also use:
--redirect
to redirect HTTP to HTTPS.--cipherlist=Atom
to set ciphers with (currently) acceptable security.Now, with recent changes to
library(ssl)
, the following configurations must also be considered:SNI is already supported in the Unix daemon by the hook
http:sni_options/2
. Multiple certificates are not yet possible. However, it is clear that this use case will become increasingly relevant in the future, and so it should also be possible to supply multiple certificates somehow.Currently, a typical invocation of an HTTPS server could like like this:
I have highlighted options that are specific to HTTPS.
It is evident that such an invocation is extremely inconvenient. Moreover, the following problem arises: If you put all this for example in a
.service
file forsystemd
, then you need to dosudo systemctl daemon-reload
every time you change the configuration parameters. This is also inconvenient, and there is no way around this.The point has been raised that the Unix daemon is becoming too complex altogether, providing features that go far beyond its initial conception of a "Unix daemon". To be honest, my impression is almost the opposite: In less than 1000 lines of code (including extensive documentation), the daemon manages to expose an impressive amount of very flexible functionality, far more than I initially thought would be possible by so little glue code. If this is now deemed too complex, I wonder what to think about certain other areas of the code that ships with SWI-Prolog. To me, it is a testament to the elegant architecture of the web framework that the Unix daemon takes comparatively little and quite straight-forward code.
We are almost at the point that all of the above is supported. However, multiple certificates remain pending in #76, and this has now provided the impetus to look more closely at the best approach to include this feature too.
In general, we actually need triples of the form:
Using passwords to protect private keys is certainly advisable, but frequently simply not done in practice, also not by Let's Encrypt: In this case and many others, suitable file permissions are used to severely restrict access to private keys and even certificates. Still, we support also encrypted private keys by means of the
--pwfile
option (which is to be preferred over--password
, since command line arguments can be easily inspected by other processes).So, we could support multiple certificates by using for example multiple occurrences of
--certfile
etc. However, this gets increasingly complex and unwieldy to use (the implementation remains rather straight-forward, and does not significantly increase the complexity of the Unix daemon).Now the main point: I still think that a configuration file would be a great idea to solve all this. The main reason for this is the following:
The Prolog community missed the boat when it came to choosing a syntax for RDF and many other web standards, where Prolog syntax could have played a very important role. Why miss the next boat too? Wouldn't it be nice to have Prolog based configuration files as follows, say
config.pl
:And then start the daemon with:
Further, SNI could be accommodated by providing
http:sni_options/2
in the same file.Moreover, multiple
certfile/1
andkeyfile/1
options could appear.Of course, the following syntax would make even more sense:
I think adding this feature to the HTTP Unix daemon would allow a very flexible and convenient configuration of (multiple) HTTPS servers and at the same time advertise Prolog as a nice language for configuration files too.
The text was updated successfully, but these errors were encountered: