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 unix domain socket support for Postgres #253

Merged
merged 6 commits into from
Apr 18, 2020

Conversation

Nilix007
Copy link
Contributor

@Nilix007 Nilix007 commented Apr 14, 2020

This PR adds unix domain socket support for Postgres. It also changes the default values of multiple connection parameters to match libpq behaviour, e.g. postgres:/// was equivalent to postgres:///postgres@localhost/postgres for sqlx, but now sqlx would connect to the DB via UDS with the current user as username and database name (assuming we're running a Unix).

Current state: Works on my Linux 😆 What kind of tests would you like to see?

Open questions:

  • This PR uses $USER to get the name of the current user. Does this work on all (supported) Unixes? What about Windows? Do we want to be smarter? (e.g. call geteuid and getpwuid)
  • What about TLS over UDS? This is currently not supported.

Fixes #144

@Nilix007 Nilix007 force-pushed the postgres_uds_support branch 2 times, most recently from 999e2ee to 7f195ac Compare April 14, 2020 19:54
@@ -14,15 +13,24 @@ pub struct MaybeTlsStream {

enum Inner {
NotTls(TcpStream),
#[cfg(all(feature = "postgres", unix))]
UnixStream(crate::runtime::UnixStream),
Copy link
Member

Choose a reason for hiding this comment

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

I don't like how this in MaybeTlsStream. I think it conflates what the type here is doing.

I'd rather something like:

  • A separate Socket (name?) type that is internally an enumeration between UnixStream and TcpStream.

  • This MaybeTlsStream is then generalized around an S type parameter.

Thoughts?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't see much reason to parameterize MaybeTlsStream if the type is always going to be Socket.

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 could call it MaybeUdsStream and reverse the relationship so that MaybeUdsStream is an enumeration between UnixStream and MaybeTlsStream.

Copy link
Member

Choose a reason for hiding this comment

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

I guess before we get ahead of ourselves here.. is TLS over UDS even a reasonable thing? If it is, we probably need to at least support that with the type sandwhich.

Copy link
Collaborator

@abonander abonander Apr 16, 2020

Choose a reason for hiding this comment

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

The wording in the documentation doesn't suggest TLS support at all over the domain socket: https://www.postgresql.org/docs/12/ssl-tcp.html

It doesn't really make sense anyways to encrypt over the UDS because if someone can sniff the traffic on that socket then they can probably also just inspect your process' memory or Postgres' memory/files for juicy secrets (since they'd have to be running on the same machine with elevated privileges already).

// and falls back to postgres@.../postgres
let username = url
.username()
.or_else(|| std::env::var("USER").map(Cow::Owned).ok())
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps https://crates.io/crates/whoami is a better idea to be more resilient?

.expect("percent-encoded hostname contained non-UTF-8 bytes")
})
.or_else(|| url.param("host"))
.unwrap_or("/var/run/postgresql".into());
Copy link
Member

Choose a reason for hiding this comment

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

By default we may want to iterate potential locations for the socket and not just hard-code this one.

  • /tmp
  • /var/run/postgresql
  • /private/tmp ( macOS )

@mehcode
Copy link
Member

mehcode commented Apr 16, 2020

First off, awesome enhancement here.

What about Windows

Postgres doesn't support UDS on Windows yet. I did see a patch get merged for that due in Postgres 13, but we have some time to think about it.

I'm not sure if Postgres supports named pipes in Windows though. I'd say that's a different improvement if it does.

@mehcode
Copy link
Member

mehcode commented Apr 18, 2020

Thanks for getting this started. I'm doing some refactoring of Postgres and want to roll this in. Thanks again. 👍

@mehcode mehcode marked this pull request as ready for review April 18, 2020 21:31
@mehcode mehcode merged commit 57f52ff into launchbadge:master Apr 18, 2020
@Nilix007
Copy link
Contributor Author

Thank you for building this awesome piece of software 🥇

PS: I've just pushed a couple of changes that piled up for this PR. You might take 'em as inspiration or something: Nilix007/sqlx@postgres_uds_support^^^...Nilix007:postgres_uds_support

@mehcode
Copy link
Member

mehcode commented May 6, 2020

@Nilix007 Thanks. I rolled that into develop: https://github.com/launchbadge/sqlx/tree/develop/sqlx-core/src/net

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

Successfully merging this pull request may close these issues.

Support Unix Domain Sockets for Postgres
3 participants