Mailing List Archive

Gunicorn - HTTP and HTTPS in the same instance?
Hopefully some Pythonistas are also Gunicornistas. I've had little success
finding help with a small dilemma in the docs or in other more specific
sources.

I'm testing out a new, small website. It is just Gunicorn+Flask. I'd like
to both listen for HTTP and HTTPS connections. Accordingly, in my config, I
have the Gunicorn process bind to both ports 80 and 443 if running as root:

if IAM_ROOT:
bind = [
'0.0.0.0:443',
'0.0.0.0:80',
]
else:
bind = [
'0.0.0.0:8080',
]

Gunicorn listens on both ports, but insists on SSL/TLS chit chat over port
80, not just port 443 (which seems to work okay). Is there some magic
incantation to get it to just talk HTTP on port 80, or will I need to spin
up two instances? (The non-root config works fine - plain old HTTP over
port 8080.)

Thx,

Skip
--
https://mail.python.org/mailman/listinfo/python-list
Re: Gunicorn - HTTP and HTTPS in the same instance? [ In reply to ]
On Fri, Jan 07 2022 at 12:51:48 PM, Skip Montanaro <skip.montanaro@gmail.com> wrote:
> Hopefully some Pythonistas are also Gunicornistas. I've had little success
> finding help with a small dilemma in the docs or in other more specific
> sources.
>
> I'm testing out a new, small website. It is just Gunicorn+Flask. I'd like
> to both listen for HTTP and HTTPS connections. Accordingly, in my config, I
> have the Gunicorn process bind to both ports 80 and 443 if running as root:
>
> if IAM_ROOT:
> bind = [
> '0.0.0.0:443',
> '0.0.0.0:80',
> ]
> else:
> bind = [
> '0.0.0.0:8080',
> ]
>
> Gunicorn listens on both ports, but insists on SSL/TLS chit chat over port
> 80, not just port 443 (which seems to work okay). Is there some magic
> incantation to get it to just talk HTTP on port 80, or will I need to spin
> up two instances? (The non-root config works fine - plain old HTTP over
> port 8080.)
>

It is not possible to do this. The ssl-ness is a global configuration,
and will apply to all of the listening sockets gunicorn creates. To get
what you want, you need to run multiple instances, as you say, if you
can run those safely.

The recommended way to deploy gunicorn, though, is to front it with a
reverse proxy such as nginx. You'd configure nginx (or whatever proxy
you choose) to listen on the interfaces/ports you want, and
enable/disable TLS as required. Example for configuring nginx is at
https://docs.gunicorn.org/en/latest/deploy.html, although that
particular example does not talk about TLS.

--
regards,
kushal
--
https://mail.python.org/mailman/listinfo/python-list
Re: Gunicorn - HTTP and HTTPS in the same instance? [ In reply to ]
I always use NGINX for this. Run Flask/Gunicorn on localhost:5000 and have
NGINX rewrite https requests to localhost requests. In nginx.conf I
automatically redirect every http request to https. Static files are
served by NGINX, not by Gunicorn, which is faster. NGINX also allows you
to easily set the transfer encoding to gzip
Albert-Jan
--
https://mail.python.org/mailman/listinfo/python-list
RE: Gunicorn - HTTP and HTTPS in the same instance? [ In reply to ]
Hi.
You probably can solve issue on Gunicorn side. But afaik better solution is to use http proxy before Gunicorn. This proxy accepts https connection and proxy requests to Gunicorn instances as plain http.

This approach gives you:
a) Monitoring on network layer (tcpdump/wireshark shows you req/res on Gunicorn instance)
b) Scalability (proxy can spread traffic on several Gunicorn instances)
c) Maintenance (you can gracefully shutdown/restart Gunicorn instances one by one)
d) Security (For example SSL certificate is configured in proxy only. There are another useful features which such proxy can do: simple authentication, ddos/fail2ban and so on)

Quite often NGINX is better choice for such proxy. But apache is good as well.

Best regards.
Kirill

??: Skip Montanaro
??????????: 7 ?????? 2022 ?. ? 21:54
????: Python
????: Gunicorn - HTTP and HTTPS in the same instance?

Hopefully some Pythonistas are also Gunicornistas. I've had little success
finding help with a small dilemma in the docs or in other more specific
sources.

I'm testing out a new, small website. It is just Gunicorn+Flask. I'd like
to both listen for HTTP and HTTPS connections. Accordingly, in my config, I
have the Gunicorn process bind to both ports 80 and 443 if running as root:

if IAM_ROOT:
bind = [
'0.0.0.0:443',
'0.0.0.0:80',
]
else:
bind = [
'0.0.0.0:8080',
]

Gunicorn listens on both ports, but insists on SSL/TLS chit chat over port
80, not just port 443 (which seems to work okay). Is there some magic
incantation to get it to just talk HTTP on port 80, or will I need to spin
up two instances? (The non-root config works fine - plain old HTTP over
port 8080.)

Thx,

Skip
--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: Gunicorn - HTTP and HTTPS in the same instance? [ In reply to ]
Thanks all. I was hoping to get away without something more
sophisticated like NGINX. This is just a piddly little archive of an
old mailing list running on a single-core Ubuntu VM somewhere on the
East Coast. Speed is not a real requirement. Load balancing seemed
like overkill to me. Still, I guess if it has to be, then it has to
be.

Skip
--
https://mail.python.org/mailman/listinfo/python-list
Re: Gunicorn - HTTP and HTTPS in the same instance? [ In reply to ]
I think this is more a thing of apporach. Nginx is quite simple to
install and a config doing nothing else than redirecting https to https
and proxying requests to a service (whichever tat is, in your case
gunicorn) can become a nobrainer. That is what it became for me.
Additionally the config for only this functionality are less than 10. So
it's may seem complicated at first, but is way less oncxe you got used
to it.

Cheers

Lars

Am 08.01.22 um 17:25 schrieb Skip Montanaro:
> Thanks all. I was hoping to get away without something more
> sophisticated like NGINX. This is just a piddly little archive of an
> old mailing list running on a single-core Ubuntu VM somewhere on the
> East Coast. Speed is not a real requirement. Load balancing seemed
> like overkill to me. Still, I guess if it has to be, then it has to
> be.
>
> Skip

--
punkt.de GmbH
Lars Liedtke
.infrastructure

Kaiserallee 13a
76133 Karlsruhe

Tel. +49 721 9109 500
https://infrastructure.punkt.de
info@punkt.de

AG Mannheim 108285
Geschäftsführer: Jürgen Egeling, Daniel Lienert, Fabian Stein

--
https://mail.python.org/mailman/listinfo/python-list
Re: Gunicorn - HTTP and HTTPS in the same instance? [ In reply to ]
server {
   listen [::]:80;
   listen 80;


   server_name api.familie-liedtke.net;

   location / {
       return 301 https://$host$request_uri;
   }

   include /usr/local/etc/nginx/include/letsencrypt.conf;
}

server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;

   server_name api.familie-liedtke.net;

   ssl_certificate
/usr/local/etc/ssl/certs/api.familie-liedtke.net/fullchain.pem;
   ssl_certificate_key
/usr/local/etc/ssl/certs/api.familie-liedtke.net/privkey.pem;

   root /var/www/api;

   location /weather/{
       access_log /var/log/nginx/weather-access.log;
       include uwsgi_params;
       rewrite ^/weather(/.*)$ $1 break;
       uwsgi_pass unix:///tmp/uwsgi.sock;
   }

   include /usr/local/etc/nginx/include/ssl.conf;
}

This is my config for a flask app on uwsgi. granted it is a bit more
than the 10 lines I said. But there is not much sophistication to it.

Am 08.01.22 um 17:25 schrieb Skip Montanaro:
> Thanks all. I was hoping to get away without something more
> sophisticated like NGINX. This is just a piddly little archive of an
> old mailing list running on a single-core Ubuntu VM somewhere on the
> East Coast. Speed is not a real requirement. Load balancing seemed
> like overkill to me. Still, I guess if it has to be, then it has to
> be.
>
> Skip

--
punkt.de GmbH
Lars Liedtke
.infrastructure

Kaiserallee 13a
76133 Karlsruhe

Tel. +49 721 9109 500
https://infrastructure.punkt.de
info@punkt.de

AG Mannheim 108285
Geschäftsführer: Jürgen Egeling, Daniel Lienert, Fabian Stein
--
https://mail.python.org/mailman/listinfo/python-list