如何将 NGINX 正确配置为 tine20 docker 容器(与 Apache2 一起运行)的反向代理?
How to configure NGINX correctly as reverse proxy for tine20 docker container (which runs with Apache2)?
我正在尝试将 nginx 配置为 tine20 docker 容器(使用 apache2作为网络服务器)。
我正在使用以下反向代理配置:
server {
listen 443 ssl http2;
server_name ${DOMAIN};
ssl_certificate /etc/letsencrypt/live/${PATH}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${PATH}/privkey.pem;
ssl_dhparam /etc/ssl/dhparams.pem;
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
root /etc/letsencrypt/webrootauth;
location / {
proxy_pass http://${UPSTREAM};
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache anonymous;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
location /.well-known/acme-challenge {
alias /etc/letsencrypt/webrootauth/.well-known/acme-challenge;
location ~ /.well-known/acme-challenge/(.*) {
add_header Content-Type application/jose+json;
}
}
}
server {
listen 80;
server_name ${DOMAIN};
return 301 https://$server_name$request_uri;
}
tine20 容器内的 Apache 使用以下配置:
# Apache and PHP configuration for Tine 2.0
#
# Alias /tine20 /usr/share/tine20
# Alias /Microsoft-Server-ActiveSync /usr/share/tine20/Microsoft-Server-ActiveSync
# some people prefer a simple URL like http://tine20.example.org
# in this case you also have to disable to Alias lines above
<VirtualHost *:80>
DocumentRoot /usr/share/tine20
ServerName ${SERVER_NAME}
</VirtualHost>
<Directory /usr/share/tine20>
Order Allow,Deny
Allow from all
DirectoryIndex index.php
Options +ExecCGI
<IfModule mod_php5.c>
Define PHP_MODULE_INSTALLED
</IfModule>
<IfModule mod_php7.c>
Define PHP_MODULE_INSTALLED
</IfModule>
<IfDefine PHP_MODULE_INSTALLED>
php_admin_value max_input_time 120
php_admin_value include_path .:/usr/share/tine20:/usr/share/tine20/library:/usr/share/tine20/vendor/zendframework/zendframework1/library:/etc/tine20
php_admin_value open_basedir /usr/share/tine20:/var/lib/tine20:/tmp:/usr/share/php:/etc/tine20:/var/log/tine20
php_admin_value session.gc_maxlifetime 86400
php_admin_value memory_limit 128M
php_admin_value upload_max_filesize 20M
php_admin_value post_max_size 20M
php_admin_value safe_mode off
php_admin_flag display_errors off
php_admin_flag log_errors on
php_admin_flag magic_quotes_gpc off
php_admin_flag magic_quotes_runtime off
php_admin_flag register_globals off
<IfModule mod_headers.c>
# activate zlib compression and remove content-length header
# this is necessary because of this php bug: https://bugs.php.net/bug.php?id=44164
php_admin_flag zlib.output_compression on
<FilesMatch "\.php$">
Header unset Content-Length
</FilesMatch>
</IfModule>
php_value max_execution_time 90
</IfDefine>
<IfModule mod_rewrite.c>
RewriteEngine on
# needs to be adopted if tine20 is not in subdir /tine20
RewriteBase /tine20
# ActiveSync
RewriteRule ^Microsoft-Server-ActiveSync index.php?frontend=activesync [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
# OpenID
RewriteRule ^users/(.*) index.php?frontend=openid&username= [L,QSA]
# WebDAV / CalDAV / CardDAV
RewriteCond %{REQUEST_METHOD} !^(GET|POST)$
RewriteRule ^$ index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^addressbooks index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^calendars index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^webdav index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^principals index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^remote.php index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
# Anonymous downloads
RewriteRule ^download/get/(.*) index.php?method=Download.downloadNode&path= [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^download/show/(.*) index.php?method=Download.displayNode&path= [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
# Routing
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php?doRouting=1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
</IfModule>
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/json
<IfModule mod_headers.c>
# properly handle requests coming from behind proxies
Header append Vary User-Agent env=!dont-vary
</IfModule>
</IfModule>
</Directory>
使用此配置,我 运行 在 Firefox Developer Console 日志中显示以下错误:
Mixed Content: The page at 'https://localhost/' was loaded over HTTPS, but requested an insecure script 'http://localhost/Tinebase/js/fatClient.js-c79fcf9f7cddb7b5e69e-FAT.js'. This request has been blocked; the content must be served over HTTPS.
(index):1 Mixed Content: The page at 'https://localhost/' was loaded over HTTPS, but requested an insecure script 'http://localhost/index.php?method=Tinebase.getJsTranslations&locale=en&app=all&version=ce92dfccacd6bf202116c419e856ffea17b37604'. This request has been blocked; the content must be served over HTTPS.
要重现此错误并可以按照此 repository 中的说明对配置进行试验。
此错误的问题在于,从 docker 容器托管的 tine20 应用程序在访问登录页面 (https://localhost/) 时永远无法加载,因为脚本文件被阻止浏览器。
如果您从开发者控制台复制请求的 http urls 并将 m 粘贴到 url 栏中,脚本将被加载并正确重定向到 https 地址(通过301).
现在我不太明白为什么会出现错误以及如何正确加载内容。
Mixed Content: The page at 'https://localhost/' was loaded over HTTPS, but requested an insecure script 'http://localhost/Tinebase/js/fatClient.js-c79fcf9f7cddb7b5e69e-FAT.js'. This request has been blocked; the content must be served over HTTPS.
您的问题的解决方案在上述错误消息的最后一位This request has been blocked; the content must be served over HTTPS.
因此,当通过 https
加载页面时,您正在通过 http
提供一些资产,而浏览器现在很长一段时间都不允许这样做。
页面卡住的原因是因为被服务器阻止的资产*FAT.js
必须是渲染页面所必需的。
修复源代码以通过使用相对模式(也就是没有 http(s)
位,仅以 //example.com/path/to/something
开头)在页面所服务的模式上加载它。
在您的具体情况下更改为:
//localhost/Tinebase/js/fatClient.js-c79fcf9f7cddb7b5e69e-FAT.js
这样它将使用加载它的页面所使用的相同 http 模式来加载资源。
对抛出此消息的每个资源重复此操作:
This request has been blocked; the content must be served over HTTPS.
我正在尝试将 nginx 配置为 tine20 docker 容器(使用 apache2作为网络服务器)。
我正在使用以下反向代理配置:
server {
listen 443 ssl http2;
server_name ${DOMAIN};
ssl_certificate /etc/letsencrypt/live/${PATH}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${PATH}/privkey.pem;
ssl_dhparam /etc/ssl/dhparams.pem;
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
root /etc/letsencrypt/webrootauth;
location / {
proxy_pass http://${UPSTREAM};
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache anonymous;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
location /.well-known/acme-challenge {
alias /etc/letsencrypt/webrootauth/.well-known/acme-challenge;
location ~ /.well-known/acme-challenge/(.*) {
add_header Content-Type application/jose+json;
}
}
}
server {
listen 80;
server_name ${DOMAIN};
return 301 https://$server_name$request_uri;
}
tine20 容器内的 Apache 使用以下配置:
# Apache and PHP configuration for Tine 2.0
#
# Alias /tine20 /usr/share/tine20
# Alias /Microsoft-Server-ActiveSync /usr/share/tine20/Microsoft-Server-ActiveSync
# some people prefer a simple URL like http://tine20.example.org
# in this case you also have to disable to Alias lines above
<VirtualHost *:80>
DocumentRoot /usr/share/tine20
ServerName ${SERVER_NAME}
</VirtualHost>
<Directory /usr/share/tine20>
Order Allow,Deny
Allow from all
DirectoryIndex index.php
Options +ExecCGI
<IfModule mod_php5.c>
Define PHP_MODULE_INSTALLED
</IfModule>
<IfModule mod_php7.c>
Define PHP_MODULE_INSTALLED
</IfModule>
<IfDefine PHP_MODULE_INSTALLED>
php_admin_value max_input_time 120
php_admin_value include_path .:/usr/share/tine20:/usr/share/tine20/library:/usr/share/tine20/vendor/zendframework/zendframework1/library:/etc/tine20
php_admin_value open_basedir /usr/share/tine20:/var/lib/tine20:/tmp:/usr/share/php:/etc/tine20:/var/log/tine20
php_admin_value session.gc_maxlifetime 86400
php_admin_value memory_limit 128M
php_admin_value upload_max_filesize 20M
php_admin_value post_max_size 20M
php_admin_value safe_mode off
php_admin_flag display_errors off
php_admin_flag log_errors on
php_admin_flag magic_quotes_gpc off
php_admin_flag magic_quotes_runtime off
php_admin_flag register_globals off
<IfModule mod_headers.c>
# activate zlib compression and remove content-length header
# this is necessary because of this php bug: https://bugs.php.net/bug.php?id=44164
php_admin_flag zlib.output_compression on
<FilesMatch "\.php$">
Header unset Content-Length
</FilesMatch>
</IfModule>
php_value max_execution_time 90
</IfDefine>
<IfModule mod_rewrite.c>
RewriteEngine on
# needs to be adopted if tine20 is not in subdir /tine20
RewriteBase /tine20
# ActiveSync
RewriteRule ^Microsoft-Server-ActiveSync index.php?frontend=activesync [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
# OpenID
RewriteRule ^users/(.*) index.php?frontend=openid&username= [L,QSA]
# WebDAV / CalDAV / CardDAV
RewriteCond %{REQUEST_METHOD} !^(GET|POST)$
RewriteRule ^$ index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^addressbooks index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^calendars index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^webdav index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^principals index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^remote.php index.php?frontend=webdav [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
# Anonymous downloads
RewriteRule ^download/get/(.*) index.php?method=Download.downloadNode&path= [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteRule ^download/show/(.*) index.php?method=Download.displayNode&path= [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
# Routing
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php?doRouting=1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
</IfModule>
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/json
<IfModule mod_headers.c>
# properly handle requests coming from behind proxies
Header append Vary User-Agent env=!dont-vary
</IfModule>
</IfModule>
</Directory>
使用此配置,我 运行 在 Firefox Developer Console 日志中显示以下错误:
Mixed Content: The page at 'https://localhost/' was loaded over HTTPS, but requested an insecure script 'http://localhost/Tinebase/js/fatClient.js-c79fcf9f7cddb7b5e69e-FAT.js'. This request has been blocked; the content must be served over HTTPS.
(index):1 Mixed Content: The page at 'https://localhost/' was loaded over HTTPS, but requested an insecure script 'http://localhost/index.php?method=Tinebase.getJsTranslations&locale=en&app=all&version=ce92dfccacd6bf202116c419e856ffea17b37604'. This request has been blocked; the content must be served over HTTPS.
要重现此错误并可以按照此 repository 中的说明对配置进行试验。
此错误的问题在于,从 docker 容器托管的 tine20 应用程序在访问登录页面 (https://localhost/) 时永远无法加载,因为脚本文件被阻止浏览器。
如果您从开发者控制台复制请求的 http urls 并将 m 粘贴到 url 栏中,脚本将被加载并正确重定向到 https 地址(通过301).
现在我不太明白为什么会出现错误以及如何正确加载内容。
Mixed Content: The page at 'https://localhost/' was loaded over HTTPS, but requested an insecure script 'http://localhost/Tinebase/js/fatClient.js-c79fcf9f7cddb7b5e69e-FAT.js'. This request has been blocked; the content must be served over HTTPS.
您的问题的解决方案在上述错误消息的最后一位This request has been blocked; the content must be served over HTTPS.
因此,当通过 https
加载页面时,您正在通过 http
提供一些资产,而浏览器现在很长一段时间都不允许这样做。
页面卡住的原因是因为被服务器阻止的资产*FAT.js
必须是渲染页面所必需的。
修复源代码以通过使用相对模式(也就是没有 http(s)
位,仅以 //example.com/path/to/something
开头)在页面所服务的模式上加载它。
在您的具体情况下更改为:
//localhost/Tinebase/js/fatClient.js-c79fcf9f7cddb7b5e69e-FAT.js
这样它将使用加载它的页面所使用的相同 http 模式来加载资源。
对抛出此消息的每个资源重复此操作:
This request has been blocked; the content must be served over HTTPS.