Skip to content
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

Add TLS support for Pgx_async #108

Merged
merged 12 commits into from
May 11, 2021
Merged

Add TLS support for Pgx_async #108

merged 12 commits into from
May 11, 2021

Conversation

brendanlong
Copy link
Contributor

@brendanlong brendanlong commented Apr 29, 2021

This adds TLS support for Pgx_async using Conduit.

There are a few things that aren't ideal about this:

  • We're using the Conduit.V1 interface, which we may not want to rely on
    (the latest is V3)
  • I can't find any way to do this for Lwt

Resolves #107

This adds TLS support for Pgx_async using Conduit.

This is only a proof of concept because:

- We're using the Conduit.V1 interface, which we may not want to rely on
  (the latest is V3)
- We need to add support for Pgx_async
- We probably need better error handling than asserts

Resolves #107
@brendanlong
Copy link
Contributor Author

See mirage/ocaml-conduit#391 for a question about how Conduit's maintainers want us to do this with V3

@brendanlong
Copy link
Contributor Author

@anuragsoni Not sure if you're still interested in Pgx stuff, but if you are, do you have any opinions on how I'm implementing this?

@coveralls
Copy link

coveralls commented Apr 29, 2021

Coverage Status

Coverage decreased (-0.1%) to 66.737% when pulling 31291c1 on tls-support into d8eb9a2 on master.

@anuragsoni
Copy link
Contributor

Not sure if you're still interested in Pgx stuff, but if you are, do you have any opinions on how I'm implementing this?

@brendanlong This looks nice! I implemented ssl support in a similar way in my proof of concept at https://github.com/anuragsoni/postgres-protocol/
I hadn't looked at conduit at that moment, but i vaguely remember the public api for conduit > v1 not having a way to upgrade a current set of reader/writer pairs that "upgrade" the connection and return a reader/writer pair.

How would you feel about not pulling in conduit and just using async_ssl directly for the async backend, and ocaml-tls for the lwt backend? It might also be nice to avoid having to deal with optional ssl dependencies and just compile with async_ssl and ocaml-tls always, and then let the user configure it somehow whether they want to make an encrypted connection or not.

@brendanlong
Copy link
Contributor Author

Yeah I asked the Conduit people about upgrading in >V1 in mirage/ocaml-conduit#391

I could pull in Async_ssl and ocaml-tls directly, but I'm worried that I'd have to re-implement a bunch of stuff, and Conduit seems to be the "standard" way of doing this. If Conduit had a way to do this upgrade in V3, would there still be reason you think we should avoid it?

@anuragsoni
Copy link
Contributor

If Conduit had a way to do this upgrade in V3, would there still be reason you think we should avoid it?

I don't think so. If Conduit works for how we need to communicate with Postgres, it'd be nice to just use it for setting up all the connections.

@brendanlong
Copy link
Contributor Author

That makes sense, I'll wait to see what they say then.

@brendanlong
Copy link
Contributor Author

I haven't heard back from the Conduit people, so for now I think I'm going to implement this using the V1 interface and then I'll update it if/when other options become available.

@pull-request-size pull-request-size bot added size/L and removed size/M labels May 6, 2021
@brendanlong brendanlong changed the title PoC: Add TLS support Add TLS support for Pgx_async May 6, 2021
| `Always _ ->
failwith
"TLS support is not compiled into this Pgx library but ~ssl was set to \
`Always"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to make this impossible but I'm not sure how.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#suggestion: We can also enforce that the io wrappers for pgx should always pick an ssl option (async_ssl, tls or lwt_ssl), and get rid of this branch. I'd expect that eventually all io wrappers in the pgx repo will support encrypted connections, but if we don't want to support them in a particular backend, we can probably tweak the wrapper itself to not expose any ssl related options in its mli file

Comment on lines +572 to +573
| `Auto -> None
| `Always ssl_config -> Some ssl_config
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not completely sure on this interace. My idea was that if people actually care about SSL, they probably want to send a config.

@brendanlong
Copy link
Contributor Author

@anuragsoni What do you think of this interface?

I think I want to keep the conduit implementation for Pgx_async for now since it's much simpler, but I'd be open to replacing it with a different one. I think my Pgx interface would allow us to implement Pgx_lwt_unix in whatever way is more convenient (doesn't need to be conduit).

I'm mostly trying to finish this up since I don't actually have a lot of time to work on it right now :( But I'm hoping to come up with an interface that's at least stable enough that there won't be major sure in the main Pgx functor.

-> ?verbose:int
-> ?max_message_length:int
-> (t -> 'a Deferred.t)
-> 'a Deferred.t
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unnecessary since it's exactly the same interface that we import above in include Pgx.S

@brendanlong brendanlong assigned anuragsoni and unassigned anuragsoni May 6, 2021
@brendanlong brendanlong requested a review from a team May 6, 2021 19:52
Comment on lines +20 to +28
val upgrade_ssl
: [ `Not_supported
| `Supported of
?ssl_config:ssl_config
-> in_channel
-> out_channel
-> (in_channel * out_channel) t
]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that the async_ssl dependency is mandatory, will there still be a scenario where attempting to setup a tls connection via conduit will fail because of missing support? I'm guessing with the current setup we might not need the Not_supported branch at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need the Not_supported branch because Pgx_lwt and Pgx_unix don't support TLS right now. Hopefully at some point we can get this supported for Pgx_lwt, but I doubt we'll ever support it for Pgx_unix.

I'm open to alternative ways of doing this though if there is one?

@brendanlong brendanlong merged commit cdef3ff into master May 11, 2021
@brendanlong brendanlong deleted the tls-support branch May 11, 2021 19:23
brendanlong added a commit to brendanlong/opam-repository that referenced this pull request May 12, 2021
…x_lwt_unix, pgx_lwt and pgx (2.0)

CHANGES:

### Breaking changes

* The Pgx module is now wrapped, which means `Pgx_aux`, `Types`, `Access`, etc. aren't added to the global scope.
  The main result of this is that `Pgx_value` now needs to be accessed as `Pgx.Value`.
  (arenadotio/pgx#103)
* `Pgx_async.connect` and `with_conn` now have an additional optional `?ssl` argument (see below).

### Added

* Pgx_async now supports TLS connections using Conduit_async. This is enabled by default and can be controlled with the
  new `?ssl` argument to `connect` and `with_conn`.
  (arenadotio/pgx#108)

### Fixed

* Improved message for authentication errors. Previously these raised `Pgx_eof`, and now they raise
  `PostgreSQL_Error("Failed to authenticate with postgres server", additional details ...)`.
  (arenadotio/pgx#105)

### Changed

* Support new Mirage-conduit timeout argument (arenadotio/pgx#95).
yomimono pushed a commit to yomimono/pgx that referenced this pull request Mar 8, 2022
This adds TLS support for Pgx_async using Conduit.

There are a few things that aren't ideal about this:

- We're using the Conduit.V1 interface, which we may not want to rely on (the latest is V3)
- We haven't implemented this for Lwt yet since they don't expose the same SSL upgrade interface in Conduit

Resolves arenadotio#107
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support TLS encryption
4 participants