-
Notifications
You must be signed in to change notification settings - Fork 274
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
Streamline SSL experience #677
Conversation
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.
Just one comment about charlist and this is good to go. I tested it on DigitalOcean and it worked!
Mix.install([
{:postgrex, github: "elixir-ecto/postgrex", branch: "jv-add-ssl-verify-full"}
])
{:ok, pid} =
Postgrex.start_link(
hostname: System.fetch_env!("DO_HOST"),
port: 25060,
username: "doadmin",
password: System.fetch_env!("DO_PASSWORD"),
database: "defaultdb",
ssl: :verify_full,
ssl_opts: [
cacertfile: "/Users/wojtek/Downloads/ca-certificate.crt"
]
)
IO.inspect(Postgrex.query!(pid, "SELECT NOW()", []))
Co-authored-by: Wojtek Mach <[email protected]>
@voltone, please let me know if you have thoughts here, the goal is to mirror this in myxql as well. |
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.
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.
There are a few more places in the docs where ssl options are described, including for example the endpoints
list under "Failover with SSL support". I don't have time right now to trace the behavior of endpoints
and understand the implications to propose updates, sorry. Thought I'd give my feedback now before this gets merged. I might have time tonight...
Co-authored-by: Bram Verburg <[email protected]>
Co-authored-by: Bram Verburg <[email protected]>
Thank you @voltone, I believe I have addressed all of your concerns. However, there is one problem, we are always setting |
From some tests this does not seem to be an issue and, if it happens, folks can always set it to |
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 tested this on Supabase, CockroachDB, Neon, DigitalOcean PostgreSQL, and PlanetScale (which is MySQL, but same idea) and it works well! I'll work on similar change for MyXQL soon.
💚 💙 💜 💛 ❤️ |
👋 It seems like setting config :app, Repo,
url: "ecto://postgresql://your_username:[email protected]:25060/defaultdb?ssl=true",
ssl: [cacertfile: "/path/to/cacert.pem"] results in Postgrex.child_spec([repo: Repo, ssl: true, ...]) and a warning
I wonder if URL parsing logic should be updated to avoid overwriting |
Yes, we should probably fix it in Ecto. Maybe we ignore |
) | ||
|
||
# Read ssl_opts for backwards compatibility | ||
Keyword.pop(opts, :ssl_opts, []) |
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.
👋
Sorry for posting on an old PR, but shouldn't the default here be verify: :verify_none
(according to the warning)?
Keyword.pop(opts, :ssl_opts, verify: :verify_none)
It seems like -- by default -- :ssl
still tries to verify the peer.
iex> :ssl.start()
#==> :ok
iex> :ssl.connect(~c"google.com", 443, [])
#==> {:error, {:options, :incompatible, [verify: :verify_peer, cacerts: :undefined]}}
iex> :ssl.connect(~c"google.com", 443, verify: :verify_none)
#==> {:ok,
#==> {:sslsocket, {:gen_tcp, #Port<0.5>, :tls_connection, :undefined},
#==> [#PID<0.139.0>, #PID<0.138.0>]}}
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 previous OTP defaulted to :verify_none and more recent to :verify_peer and so I believe the idea was for this legacy ssl: true
to keep whatever that particular OTP defaulted to, however ssl: list
would force secure defaults.
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.
Right, but the warning kind of implies that no verification happens anyway when ssl: true
:
Logger.warning(
"setting ssl: true on your database connection offers only limited protection, " <>
"as the server's certificate is not verified. Set \"ssl: [cacertfile: path/to/file]\" instead"
)
So, for the warning message to be true, setting verify: :verify_none
seems safe (i.e. no surprises to the users).
Right now, with the current :ssl
and :ssl_opts
defaults it just doesn't work.
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 you know if this change broke any apps? Cause if the warning implies less security we should change the warning not intentionally make things less secure. Sorry I don't have an easy way to check how it all works right now.
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.
No, I don't think it broke any apps. My suggestion was purely a (questionable) QoL improvement :)
Also it seems like right now the warning might be a false positive in this scenario:
config :app, Repo,
ssl: true,
ssl_opts: [cacertfile: "..."]
Maybe some other wording could be used to highlight that:
ssl_opts
is deprecated and should be replaced withssl: list
- just setting
ssl: true
doesn't work out-of-the-box andssl: [verify: :verify_none]
can be used to replicate?sslmode=require
ssl: [cacertfile: ...]
is the actual suggested approach
@chrismccord, let me know if this works. For now, this means you need to explicitly set
ssl: :verify_full
in your config file but we can support "ssl=verify_full" via query string too.