Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1u4zkW-00AZFk-0T for pgadmin-support@arkaria.postgresql.org; Wed, 16 Apr 2025 10:12:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1u4zkS-00BUFY-Qv for pgadmin-support@arkaria.postgresql.org; Wed, 16 Apr 2025 10:12:05 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1u4zkS-00BUFQ-GJ for pgadmin-support@lists.postgresql.org; Wed, 16 Apr 2025 10:12:05 +0000 Received: from mail-yw1-x1135.google.com ([2607:f8b0:4864:20::1135]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1u4zkO-000NN1-22 for pgadmin-support@lists.postgresql.org; Wed, 16 Apr 2025 10:12:04 +0000 Received: by mail-yw1-x1135.google.com with SMTP id 00721157ae682-7023843e467so56620437b3.2 for ; Wed, 16 Apr 2025 03:12:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1744798319; x=1745403119; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=aZfziKWvDw6bkCMOSgWDkDMlxQkr1uSG+5TspeVBla8=; b=PMAbfPhoyfonHl1mYrcFdinTDBCNbIVlNhWk/sOpvoZPeGt+MsrwjR8ZsE9meZFAqu pT4/2mvDIANllBROlfid4NJ0NUbYQWF9CFOX1RmIx0IyyNemCeq+v8OIDQulrtGkSShJ KS7hzn0aD8ebJwftNATCwgZ4y1rRis0+lzr2bQQ2omeIt0dDuOwMqPDEjdlsgNQ7owy+ 7UGqdNRI3qMyhI1q2lijGHeWkoelZwSQOfgIVpO2DcVCOI6YYabJESzat8wDemjsZuur Plq1nrJGGgwRPJFdab7jPHolMbKZuyyTsyu6qZ1d1jo961/OrS2Cf8JTRjfQXsDOR0Ka WlJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744798319; x=1745403119; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=aZfziKWvDw6bkCMOSgWDkDMlxQkr1uSG+5TspeVBla8=; b=hCUvtiAUzakBUpQRYNBaem0b/1XcUdbVrEoLwLU/N9fAR6KTrRrzpThQj462U2wXUx QPI0BWvq07aOZsb7rfQK+ok0idozL7+/jdukpSg+8Yyk5Wn7vXHx2aiHDKz9QofUofdN ks7r0sbUjc4d3POLc8C1mGPb+GcQyHhivVzGl8g6Iuz7BAIr/Fwrh3oO4bbugKFaHlMv jW4Vy7yyQgFLYSmqFLORbwn4JAwN7vj6CgaooXtO6N3bGW3J9C8CPOK1NjRKLn3YXlzj KPpT4AJ/BCgDsbK/U7uDiW240qMOUQQcnrdbe2f8V2ppwkTzFdIubTrwwnAKOYKAYFhj 9V/g== X-Gm-Message-State: AOJu0Yz1UDBlwWKczRFXwiDyQg2Vm4ZHEVRn//OjbYq8FDKBYXhXQlQZ tpDdiVr8yHZFPPYwyR2ktkNqln7eJ4VbxqI6lWCmZSrOphjIR33KZl4ADnWuPmeExD/TrcNGRaZ F8ajPdNrofW6tY2sGmLmeAWtMDwLAc9FACXUM X-Gm-Gg: ASbGnct9wv/7SeS1vSaZeeZfSLoHk6Yyr04vyPIeSV/0bquPtLPDQyHQULmKP39z7Wi DGqQbvGINT1tyGhCs4EBHIUgufq6uqMm+bCG1d66NdIw8NgnRwrwPajkyabFlfcBmBR/H2osHZv mlugh1VO2tor3vdewLaFBmA5M= X-Google-Smtp-Source: AGHT+IH+cAYtfm63EUzm0J8eqd3e8nREei6KdrXcbSH4u7LPqLmYXN/gIhVPLkl89d9Q5fe4B2K5oh1uWxuNeSFoGxg= X-Received: by 2002:a05:690c:d19:b0:6ee:8363:96d3 with SMTP id 00721157ae682-706b3362794mr16761257b3.27.1744798318575; Wed, 16 Apr 2025 03:11:58 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Khushboo Vashi Date: Wed, 16 Apr 2025 15:41:46 +0530 X-Gm-Features: ATxdqUEEZSN-vh2YWasHSUezHxueVRqEY39N5XUAEI28q13L8WEhNFNiVoy7wtU Message-ID: Subject: Re: Enforcing TLS 1.3 as a a minimum version To: John Barker Cc: "pgadmin-support lists.postgresql.org" Content-Type: multipart/alternative; boundary="000000000000fbdff60632e28334" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000fbdff60632e28334 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, Apr 9, 2025 at 7:56=E2=80=AFPM John Barker = wrote: > What is the output of `curl -v ` ? > It generally gives output like the one below so we can verify the TLS version. khushboo.vashi@MAC-HLG7090G2F web % curl -v https://google.com * Trying 142.250.193.46:443... * Connected to google.com (142.250.193.46) port 443 (#0) * ALPN: offers h2,http/1.1 * (304) (OUT), TLS handshake, Client hello (1): * CAfile: /usr/local/Netskope_CA_Bundle/nscacert_combined.pem * CApath: none * (304) (IN), TLS handshake, Server hello (2): * (304) (IN), TLS handshake, Unknown (8): * (304) (IN), TLS handshake, Certificate (11): * (304) (IN), TLS handshake, CERT verify (15): * (304) (IN), TLS handshake, Finished (20): * (304) (OUT), TLS handshake, Finished (20): ** SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256* * ALPN: server accepted h2 > The curl connects successfully but gives no information: > > curl: (52) Empty reply from server. > > On Tue, Apr 8, 2025 at 11:38=E2=80=AFPM Khushboo Vashi < > khushboo.vashi@enterprisedb.com> wrote: > >> [...Looping pgAdmin-Support] >> >> On Tue, Apr 8, 2025 at 9:19=E2=80=AFPM John Barker wrote: >> >>> Hello, >>> >>> I am on a closed network so I can't copy my files and have to retype >>> them. I have verified that the file below is being parsed when the >>> container starts. My config.py is default as shipped with the >>> container. I was previously able to get this to work with pgAdmin 8.= 6 >>> and TLS 1.2 (no ssl_context required) before the requirement to upgra= de >>> to pgAdmin 9.1 and TLS 1.3 (using ssl_context). >>> >>> I include PGADMIN_ENABLE_TLS: true in my podman compose file as well as >>> my certs which are valid. There are no errors at startup in the conta= iner >>> logs. >>> >>> Here are the total contents of gunicorn_config.py >>> >>> ********* BEGIN ******************** >>> import gunicorn >>> gunicorn.SERVER_SOFTWARE =3D 'Python' >>> conf =3D '/pgadmin4/config.py' >>> >>> #ssl_version =3D 'TLSv1_2' -- working 8.6 setting >>> #ciphers =3D 'ECDHE-RSA-AES256-GCM-SHA383:!aNull' -- working 8.6 >>> setting >>> >>> def ssl_context(conf, default_ssl_context_factory): >>> import ssl >>> context =3D default_ssl_context_factory() >>> context.minimum_version =3D ssl.TLSVersion.TLSv1_3 >>> return context >>> >>> ******* EOF ************** >>> >>> This code looks fine. >> >>> I test TLS version using openssl like this: >>> >>> # openssl s_client -showcerts -tls1_2 -connect hostname:port >>> >>> What is the output of `curl -v ` ? >> >>> The above command gets a valid response with a TLS 1.2 handshake using= a cipher of ECDHE-RSA-AES256-GCM-SHA383. I would expect this not to work= . >>> >>> Thanks, John >>> >>> On Tue, Apr 8, 2025 at 7:10=E2=80=AFAM Khushboo Vashi < >>> khushboo.vashi@enterprisedb.com> wrote: >>> >>>> Hi, >>>> >>>> On Tue, Apr 8, 2025 at 12:00=E2=80=AFAM John Barker >>>> wrote: >>>> >>>>> >>>>> I am running pgAdmin 9.1 in a podman container and am trying to ensur= e >>>>> that TLS 1.3 is the minimum version. I have created an override fi= le and >>>>> I know that it is being read at startup but the enforcement of TLS 1.= 3 is >>>>> not happening. I am using this configuration as suggested by the >>>>> documentation here: https://docs.gunicorn.org/en/21.2.0/settings.htm= l >>>>> >>>>> Any idea of what to check. I know the file is being parsed because i= f >>>>> I introduce a bad config, it is noted at startup. >>>>> >>>>> Also, where or how is the instance variable for the config defined? >>>>> >>>>> "The callable needs to accept an instance variable for the Config" >>>>> >>>> >>>> Can you please share your gunicorn_config.py file? >>>> The code looks good to me, and you said that you mapped the correct >>>> Gunicorn config file from the container. >>>> Also, what testing have you done to check whether the TLS version is >>>> enforced or not? >>>> >>>>> >>>>> The below is a file mapped into the container called gunicorn_config.= py >>>>> >>>>> def ssl_context(conf, default_ssl_context_factory): >>>>> import ssl >>>>> context =3D default_ssl_context_factory() >>>>> context.minimum_version =3D ssl.TLSVersion.TLSv1_3 >>>>> return context >>>>> >>>>> --000000000000fbdff60632e28334 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Wed, Apr 9, = 2025 at 7:56=E2=80=AFPM John Barker <johnobarker@gmail.com> wrote:
What is the output of=C2=A0 `curl=C2=A0 -v <pgadmin_url>`=C2=A0 =C2=A0?=C2=A0
=C2=A0
It generally gives output like the one belo= w so we can verify the TLS version.

khushboo.vashi@MAC-HLG7090= G2F web % curl -v https://google.com

* =C2=A0 Trying 142.250.193.46:4= 43...

* Connected to google.com (142.250.193.4= 6) port 443 (#0)

* ALPN: offers h2,http/1.1

* (304) (OUT), TLS handshake, Client hell= o (1):

<= span class=3D"gmail-s1" style=3D"font-variant-ligatures:no-common-ligatures= ">*=C2=A0 CAfile: /usr/l= ocal/Netskope_CA_Bundle/nscacert_combined.pem

*=C2=A0 CApath: none

* (304) (IN), TLS handshake, Server hello= (2):

* (304) (IN), TLS handshake, Unknown (8):

* (304) (IN), TLS handshake, Certific= ate (11):

* (304) (IN), TLS handshake, CERT verify (15):

<= div class=3D"gmail_quote gmail_quote_container">

* (304) (IN), TLS handshake= , Finished (20):

* (304) (OUT), TLS handshake, Finished (20):

* SSL connection usi= ng TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256

* ALPN: server accepted h2=C2=A0



The c= url connects successfully but gives no information:

curl: (52) Empty reply from server.

On Tue, Apr 8, 2025 at 11:38=E2= =80=AFPM Khushboo Vashi <khushboo.vashi@enterprisedb.com> wrote:
[...Looping pgAdmin-Support]

On Tue, Apr 8, 2025 at 9:19=E2=80= =AFPM John Barker <johnobarker@gmail.com> wrote:
Hello,
I am on a closed network so I can't copy my files and have = to retype them.=C2=A0 =C2=A0 I have verified=C2=A0 that the file below is b= eing parsed when the container starts.=C2=A0 =C2=A0 My config.py is default= as shipped with the container.=C2=A0 =C2=A0 I was previously able to get t= his to work with pgAdmin 8.6 and TLS 1.2=C2=A0 (no ssl_context required)=C2= =A0 before the requirement to upgrade to pgAdmin 9.1 and TLS 1.3 (using ssl= _context).

I include PGADMIN_ENABLE_TLS: true in m= y podman compose file as well as my certs which are valid.=C2=A0 =C2=A0Ther= e are no errors at startup=C2=A0in the container logs.

=
Here are the total contents of gunicorn_config.py

=
*********=C2=A0 =C2=A0BEGIN ********************
=C2=A0 =C2= =A0import gunicorn
=C2=A0 =C2=A0gunicorn.SERVER_SOFTWARE =3D '= ;Python'
=C2=A0 =C2=A0conf =3D '/pgadmin4/config.py'<= /div>

=C2=A0 =C2=A0#ssl_version =3D 'TLSv1_2'=C2= =A0 =C2=A0 =C2=A0-- working 8.6 setting
=C2=A0 =C2=A0#ciphers =3D= 'ECDHE-RSA-AES256-GCM-SHA383:!aNull'=C2= =A0 -- working 8.6 setting
def ss=
l_context(conf, default_ssl_context_factory=
):
    import ssl
    context =3D default_ssl_context_factory()
    context.minimum_version =3D ssl<=
/span>.=
TLSVersion.TLSv1_3
    return context
*******  EOF  **************
This code looks fine.=C2=A0
I test TLS version using openssl like this:
# openssl s_client -showcerts -tls1_2 -connect hostname:port<= /div>
What is the output of=C2=A0 =C2=A0`curl=C2=A0 -v <pgadmin_url>`=C2=A0 =C2=A0?
The above command gets a valid response with a  TLS 1.2 handshake us=
ing a cipher of ECDHE-RSA-AES256-GCM-SHA383.   I would expect this not to w=
ork.
Thanks, John
On Tue, Apr 8, 2025 at 7:10=E2=80=AFAM Khushboo Vashi <khushboo.vashi@ente= rprisedb.com> wrote:
Hi,

On Tue, Apr 8, 2025 at 12:= 00=E2=80=AFAM John Barker <johnobarker@gmail.com> wrote:

I am running pgAdmin 9.1 in a= podman container and am trying to ensure that TLS 1.3 is the minimum versi= on.=C2=A0 =C2=A0 I have created an override=C2=A0file and I know that it is= being read at startup but the enforcement of TLS 1.3 is not happening.=C2= =A0 =C2=A0I am using this configuration as suggested by the documentation h= ere:=C2=A0=C2=A0https://docs.gunicorn.org/en/21.2.0/settings.html<= /div>

Any idea of what to check.=C2=A0 = I know the file is being parsed because if I introduce a bad config, it is = noted at startup.

Also, where or how is the instan= ce variable for the config defined?

"= ;The callable needs to accept an instance variable for the Config"

Can you please = share your=C2=A0 gunicorn_config.py file?
The code looks good to me, and= you said that you mapped the correct Gunicorn config file from the contain= er.
Also, what testing have you done to check whether the TLS ver= sion is enforced or not?

The below is a file mapped into the container called gunico= rn_config.py
def=
 ssl_context(conf, default_ssl_context_factory):
    import ssl
    context =3D default_ssl_context_factory()
    context.minimum_version =3D ssl<=
/span>.=
TLSVersion.TLSv1_3
    return context
--000000000000fbdff60632e28334--