当 Hunchentoot 在反向代理后面时如何重定向到 HTTPS
How to redirect to HTTPS when Hunchentoot is behind a reverse proxy
我在 http://localhost:4242
上有一个 Hunchentoot 应用程序 运行。此应用程序使用 non-SSL 接受器(即 hunchentoot:easy-acceptor
而不是 hunchentoot:easy-ssl-acceptor
)。我将 Nginx 设置为反向代理以使用 SSL 为该应用程序提供服务。这是 Nginx 配置:
server {
listen 443 ssl;
server_name example.test;
ssl_certificate /etc/my-ssl/certs/example.pem;
ssl_certificate_key /etc/my-ssl/private/example.key;
location / {
include /etc/nginx/proxy_params;
proxy_pass http://localhost:4242;
}
}
其中 /etc/nginx/proxy_params
是
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
问题是 Hunchentoot 不知道反向代理(即 Nginx)实际上是使用 HTTPS 服务客户端。因此,(hunchentoot:redirect "/some-page/")
将重定向到 http://example.test/some-page/
而不是 https://example.test/some-page/
。 Hunchentoot 没有考虑 X-Forwarded-Proto
header.
为了解决这个问题,我写了一个替代的重定向函数,我用它来代替 #'hunchentoot:redirect
:
(defun my-redirect (target
&rest args
&key (protocol
(if (string= (hunchentoot:header-in* :x-forwarded-proto)
"https")
:https
:http))
&allow-other-keys)
(apply #'hunchentoot:redirect target :protocol protocol args))
这是解决问题的正确方法吗?有没有更好的方法?
(Hunchentoot 1.3.0;SBCL 2.2.2;Nginx 1.18.0;Ubuntu 20.04)
编辑:
在 Hunchentoot 的问题跟踪器中:Incorrect redirection to HTTP when application is served using HTTPS reverse proxy
一个选项是继承 hunchentoot:easy-acceptor
并为您的接受器专门化 acceptor-ssl-p
方法。这将使您能够调用 hunchentoot:redirect
并在幕后进行协议决策。
(defclass my-easy-acceptor (hunchentoot:easy-acceptor)
())
(defmethod hunchentoot:acceptor-ssl-p ((acceptor my-easy-acceptor))
(string= (hunchentoot:header-in* :x-forwarded-proto) "https"))
但是,在我看来(从 nginx 配置来看)您始终提供 HTTPS - 因此您可以省略逻辑并始终 return t
.
我在 http://localhost:4242
上有一个 Hunchentoot 应用程序 运行。此应用程序使用 non-SSL 接受器(即 hunchentoot:easy-acceptor
而不是 hunchentoot:easy-ssl-acceptor
)。我将 Nginx 设置为反向代理以使用 SSL 为该应用程序提供服务。这是 Nginx 配置:
server {
listen 443 ssl;
server_name example.test;
ssl_certificate /etc/my-ssl/certs/example.pem;
ssl_certificate_key /etc/my-ssl/private/example.key;
location / {
include /etc/nginx/proxy_params;
proxy_pass http://localhost:4242;
}
}
其中 /etc/nginx/proxy_params
是
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
问题是 Hunchentoot 不知道反向代理(即 Nginx)实际上是使用 HTTPS 服务客户端。因此,(hunchentoot:redirect "/some-page/")
将重定向到 http://example.test/some-page/
而不是 https://example.test/some-page/
。 Hunchentoot 没有考虑 X-Forwarded-Proto
header.
为了解决这个问题,我写了一个替代的重定向函数,我用它来代替 #'hunchentoot:redirect
:
(defun my-redirect (target
&rest args
&key (protocol
(if (string= (hunchentoot:header-in* :x-forwarded-proto)
"https")
:https
:http))
&allow-other-keys)
(apply #'hunchentoot:redirect target :protocol protocol args))
这是解决问题的正确方法吗?有没有更好的方法?
(Hunchentoot 1.3.0;SBCL 2.2.2;Nginx 1.18.0;Ubuntu 20.04)
编辑: 在 Hunchentoot 的问题跟踪器中:Incorrect redirection to HTTP when application is served using HTTPS reverse proxy
一个选项是继承 hunchentoot:easy-acceptor
并为您的接受器专门化 acceptor-ssl-p
方法。这将使您能够调用 hunchentoot:redirect
并在幕后进行协议决策。
(defclass my-easy-acceptor (hunchentoot:easy-acceptor)
())
(defmethod hunchentoot:acceptor-ssl-p ((acceptor my-easy-acceptor))
(string= (hunchentoot:header-in* :x-forwarded-proto) "https"))
但是,在我看来(从 nginx 配置来看)您始终提供 HTTPS - 因此您可以省略逻辑并始终 return t
.