Symfony 生产网站不强制 https(使用 nginx)
Symfony Production Website not forcing https (using nginx)
在我的 app/config/security.yml
文件中有:
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
- { path: ^/admin, roles: ROLE_ADMIN, requires_channel: https }
在开发中(使用 symfony 内置服务器),如果我转到 localhost/login
,它会将我重定向到 https://localhost/login
。
但是,在我的生产站点中,转到 example.com/login
,我只看到登录页面。浏览器指示连接不安全。
我的直觉认为这可能与nginx配置文件有关。
server {
listen 80;
listen 443 ssl;
server_name example.com;
root /var/www/symfony/web;
client_max_body_size 500M;
location / {
# try to serve file directly, fallback to app.php
index app.php;
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/ last;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
}
error_log /var/log/nginx/adam_error.log;
access_log /var/log/nginx/adam_access.log;
}
其中,我或多或少复制自here
其他一些需要注意的事情:如果我被 symfony 内部重定向到登录页面(即,如果我尝试访问 /admin
受限路由或在不安全的连接上登录失败,我确实得到路由到安全 https://example.com/login
url,但显然这还不够好,我不希望任何人进入 example.com/login
并且没有安全连接。
谁能发现可能出了什么问题?
要在 Nginx 上强制使用 HTTPS,您必须像这样修改您的 Nginx 配置文件:
server {
listen 80;
location /login {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
# let the browsers know that we only accept HTTPS
add_header Strict-Transport-Security max-age=2592000;
#Put the rest of your config here
}
来源:Github
好的,我明白了。在我的 nginx 配置中:
fastcgi_param HTTPS on;
导致了问题。事实证明,将其设置为 "on",如果初始端口为 80(我猜 symfony 认为此配置的端口 80 为 https),它不会强制重定向到 https,并将其设置为 "off",它会导致无限重定向(nginx 重定向 url 到端口 80,symfony 重定向 url 到端口 443)。
所以解决方案是如果是 80 端口就关闭它,如果是 443 端口(ssl 端口)就打开它。
这是我的 nginx.conf 现在的样子:
server {
listen 80;
listen 443 ssl;
server_name example.com;
root /path/to/symfony_directory/web;
#if your version of nginx is < 1.11.11, uncomment these next two lines
#as $https will not be defined.
#if ($server_port = 443) { set $https on; }
#if ($server_port = 80) { set $https off; }
location / {
# try to serve file directly, fallback to app.php
# try_files $uri /app.php$is_args$args;
index app.php;
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/ last;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#NOTE THAT "$https" is defined by nginx to be
# "on" if port 443 and off for port 80 (for version > 1.1.11)
fastcgi_param HTTPS $https;
}
}
在我的 app/config/security.yml
文件中有:
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
- { path: ^/admin, roles: ROLE_ADMIN, requires_channel: https }
在开发中(使用 symfony 内置服务器),如果我转到 localhost/login
,它会将我重定向到 https://localhost/login
。
但是,在我的生产站点中,转到 example.com/login
,我只看到登录页面。浏览器指示连接不安全。
我的直觉认为这可能与nginx配置文件有关。
server {
listen 80;
listen 443 ssl;
server_name example.com;
root /var/www/symfony/web;
client_max_body_size 500M;
location / {
# try to serve file directly, fallback to app.php
index app.php;
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/ last;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
}
error_log /var/log/nginx/adam_error.log;
access_log /var/log/nginx/adam_access.log;
}
其中,我或多或少复制自here
其他一些需要注意的事情:如果我被 symfony 内部重定向到登录页面(即,如果我尝试访问 /admin
受限路由或在不安全的连接上登录失败,我确实得到路由到安全 https://example.com/login
url,但显然这还不够好,我不希望任何人进入 example.com/login
并且没有安全连接。
谁能发现可能出了什么问题?
要在 Nginx 上强制使用 HTTPS,您必须像这样修改您的 Nginx 配置文件:
server {
listen 80;
location /login {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
# let the browsers know that we only accept HTTPS
add_header Strict-Transport-Security max-age=2592000;
#Put the rest of your config here
}
来源:Github
好的,我明白了。在我的 nginx 配置中:
fastcgi_param HTTPS on;
导致了问题。事实证明,将其设置为 "on",如果初始端口为 80(我猜 symfony 认为此配置的端口 80 为 https),它不会强制重定向到 https,并将其设置为 "off",它会导致无限重定向(nginx 重定向 url 到端口 80,symfony 重定向 url 到端口 443)。
所以解决方案是如果是 80 端口就关闭它,如果是 443 端口(ssl 端口)就打开它。
这是我的 nginx.conf 现在的样子:
server {
listen 80;
listen 443 ssl;
server_name example.com;
root /path/to/symfony_directory/web;
#if your version of nginx is < 1.11.11, uncomment these next two lines
#as $https will not be defined.
#if ($server_port = 443) { set $https on; }
#if ($server_port = 80) { set $https off; }
location / {
# try to serve file directly, fallback to app.php
# try_files $uri /app.php$is_args$args;
index app.php;
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/ last;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#NOTE THAT "$https" is defined by nginx to be
# "on" if port 443 and off for port 80 (for version > 1.1.11)
fastcgi_param HTTPS $https;
}
}