ring icon indicating copy to clipboard operation
ring copied to clipboard

Add support for serving on Unix domain socket

Open hsartoris-bard opened this issue 2 years ago • 3 comments

Summary

These changes take advantage of jetty-unixsocket to allow serving on a socket, as in the following example:

(run-jetty handler {:http? false, :socket "/run/someapp.sock"})
## hostname is still required for making requests
curl --unix-socket /run/someapp.sock http://my-expected-hostname/url-path

Rationale

Unix sockets are simpler to implement access controls to than TCP sockets, as you can simply use file permissions. They are supported by common reverse proxies such as Apache and NGINX, and are thus reasonable for exposing a service through a proxy that may be handling authentication, without making that service available to all users on the host machine.

Possible enhancements:

  1. Options for file ownership and access controls
  2. A secure-by-default approach might see :http? default false when :socket is set, unless :host or :port are explicitly configured.
  3. To avoid the additional dependency, socket support could be conditional on manually including the jetty-unixsocket library. It is not an overwhelmingly heavy dependency, though.

Note: it has proved nontrivial to get a test working, as clj-http does not support sockets, and the Clojure implementations that I've found do not seem to work as intended out of the box. I have verified that this implementation is operational manually, and I am willing to work through the process of getting a test working as long as you're interested in incorporating this functionality.

hsartoris-bard avatar Apr 07 '23 18:04 hsartoris-bard

I think this is reasonable in theory. Perhaps :unix-socket instead of :socket as an option, so it's not confused with other types of sockets. Also, have you tested to ensure that the inclusion of this library doesn't cause issues when using it under operating systems that don't have sockets (e.g. Windows)? I'd also suggest not automatically deleting the socket file on startup - that feels potentially dangerous. Instead, raise an error.

weavejester avatar Apr 09 '23 14:04 weavejester

I was under the impression that there was now unix socket support on Windows, but indeed it appears not to work.

Changes

  • [X] check for windows
  • [X] rename :socket to :unix-socket
  • [X] make :http? default false when :unix-socket is set, except when :host or :port are set
  • [X] throw error on extant file instead of deleting
  • [X] tests for basic functionality and errant attempts to use extant file

Let me know if there's anything else you'd like to see!

hsartoris-bard avatar Apr 10 '23 17:04 hsartoris-bard

Whoops, wasn't my intention to check in the *warn-on-reflection* line - I can remove that, or resolve the singular reflection warning.

hsartoris-bard avatar Apr 10 '23 17:04 hsartoris-bard

It seems that jetty-unixsocket is now deprecated/removed in favor of jetty-unixdomain-server: https://github.com/jetty/jetty.project/blob/8aa9c8b01137819415c4517d02138b52a9661218/documentation/jetty/modules/programming-guide/pages/migration/11-to-12.adoc

agorgl avatar Sep 26 '24 06:09 agorgl

Usage of the new APIs is documented here: https://jetty.org/docs/jetty/11/programming-guide/server/http.html#connector https://jetty.org/docs/jetty/11/programming-guide/client/http.html#transport-unix-domain

agorgl avatar Sep 26 '24 06:09 agorgl

Fixed by: df469736241b7ada658dc58e4b7d46e6f2003b30

weavejester avatar Oct 19 '24 05:10 weavejester