firefly-iii / firefly-iii

Firefly III: a personal finances manager
https://firefly-iii.org/
GNU Affero General Public License v3.0
16.26k stars 1.47k forks source link

Forced https with nginx: problems with CSP and forms #1773

Closed chrisb86 closed 6 years ago

chrisb86 commented 6 years ago

I am running Firefly III version 4.7.7

Description I can't get Firefly III working with nginx and php-fpm on FreeBSD. My server redirects all http traffic to https but Firefly III just refers http for everything. I can't send forms and get mixed content warning all the way.

I set APP_URL to https://firefly.example.com and TRUSTED_PROXIES to **.

I tried to disable al headers that nginx will send but noting changed.

Extra info Debug information generated at 2018-10-07 00:25:45 Europe/Berlin for Firefly III version 4.7.7.

Variable Content
FF version 4.7.7
FF API version 0.8
App environment local
App debug mode true
App cache driver file
App logging notice, daily
PHP version 7.2.10
Display errors Off
Session start 2018-10-01 00:00:00
Session end 2018-10-31 23:59:59
Session first 2018-01-01 00:00:00
Error reporting ALL errors
Host FreeBSD
Interface fpm-fcgi
UserID 1
Attempt at "en" false
Attempt at "English" false
Attempt at "en_US.utf8" false
Attempt at "en_US.UTF-8" 'en_US.UTF-8'
DB drivers mysql
Current driver mysql
Using Sandstorm? no
Is Sandstorm (.env) false
Is Docker (.env) false
bunq uses sandbox false
Trusted proxies (.env) **
User agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:62.0) Gecko/20100101 Firefox/62.0
Loaded extensions Core, date, libxml, pcre, Reflection, SPL, hash, session, cgi-fcgi, standard, apcu, bcmath, bz2, ctype, curl, dom, mbstring, fileinfo, filter, gd, geoip, mysqlnd, iconv, imap, intl, json, exif, mysqli, openssl, pcntl, PDO, posix, SimpleXML, tokenizer, xml, xmlwriter, zip, zlib, memcached, pdo_mysql, Phar, redis, xmlreader, Zend OPcache
Installed packages bacon/bacon-qr-code@1.0.3, bunq/sdk_php@dev-master, davejamesmiller/laravel-breadcrumbs@5.1.2, defuse/php-encryption@v2.2.1, doctrine/cache@v1.8.0, doctrine/dbal@v2.8.0, doctrine/event-manager@v1.0.0, doctrine/inflector@v1.3.0, doctrine/lexer@v1.0.1, dragonmantank/cron-expression@v2.2.0, egulias/email-validator@2.1.6, erusev/parsedown@1.7.1, fideloper/proxy@4.0.0, firebase/php-jwt@v5.0.0, guzzlehttp/guzzle@6.3.3, guzzlehttp/promises@v1.3.1, guzzlehttp/psr7@1.4.2, laravel/framework@v5.7.6, laravel/passport@v7.0.2, laravelcollective/html@v5.7.1, lcobucci/jwt@3.2.4, league/commonmark@0.18.0, league/csv@9.1.4, league/event@2.1.2, league/flysystem@1.0.47, league/fractal@0.17.0, league/oauth2-server@7.2.0, monolog/monolog@1.23.0, nesbot/carbon@1.34.0, paragonie/constant_time_encoding@v2.2.2, paragonie/random_compat@v9.99.99, phpseclib/phpseclib@2.0.11, pragmarx/google2fa@v3.0.3, pragmarx/google2fa-laravel@v0.2.0, psr/container@1.0.0, psr/http-message@1.0.1, psr/log@1.0.2, psr/simple-cache@1.0.1, ramsey/uuid@3.8.0, rcrowe/twigbridge@v0.9.8, swiftmailer/swiftmailer@v6.1.3, symfony/console@v4.1.4, symfony/css-selector@v4.1.4, symfony/debug@v4.1.4, symfony/event-dispatcher@v4.1.4, symfony/finder@v4.1.4, symfony/http-foundation@v4.1.4, symfony/http-kernel@v4.1.4, symfony/polyfill-ctype@v1.9.0, symfony/polyfill-mbstring@v1.9.0, symfony/polyfill-php56@v1.9.0, symfony/polyfill-php72@v1.9.0, symfony/polyfill-util@v1.9.0, symfony/process@v4.1.4, symfony/psr-http-message-bridge@v1.1.0, symfony/routing@v4.1.4, symfony/translation@v4.1.4, symfony/var-dumper@v4.1.4, tijsverkoyen/css-to-inline-styles@2.2.1, twig/twig@v1.35.4, vlucas/phpdotenv@v2.5.1, zendframework/zend-diactoros@1.8.6,

nginx config

# config file for firefly.example.com
# php-fpm port 9119

server {
    include includes/listen_http.conf;

    server_name firefly.example.com;

    #include includes/headers.conf;
    include includes/letsencrypt_auth.conf;
    include includes/force_https.conf;
}

## Main server config
server {
    include includes/listen_https.conf;

    # Domain names
    server_name firefly.example.com;

    root /usr/local/www/firefly.example.com/www/firefly-iii/public;

    # SSL settings
    ssl_certificate /usr/local/www/firefly.example.com/certs/fullchain.pem;
    ssl_certificate_key /usr/local/www/firefly.example.com/certs/privkey.pem;
    ssl_trusted_certificate /usr/local/www/firefly.example.com/certs/fullchain.pem;

    #include includes/headers_firefly-iii.conf;

    # log files
    access_log /usr/local/www/firefly.example.com/log/nginx.access.log main;
    error_log /usr/local/www/firefly.example.com/log/nginx.error.log crit;

    include includes/strip_www.conf;
    include includes/nolog_robots_favicon.conf;

    # Document root
    location / {
        autoindex off;
        try_files $uri $uri/ /index.php;
    }

    # PHP handler (is configured in /usr/local/etc/php-fpm.d/firefly.example.com.conf)
    location ~ \.php$ {
        fastcgi_pass 10.0.0.14:9119;
        include includes/php_handler.conf;
    }

    include includes/expires.conf;
    include includes/protect_system_files.conf;
}
JC5 commented 6 years ago

Mmmm. What's the content of php_handler.conf? For reference, here's my reverse proxy config:

    # Firefly III
        location / {
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Server $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
                client_max_body_size 64M;
                proxy_pass http://127.0.0.1:8090$uri$is_args$args;
        }

It is a slightly different setup but as you can see, I am also setting some headers to make Firefly III (it's a Docker image) know what the URL + protocol should be.

chrisb86 commented 6 years ago

php_handler.conf

fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include includes/fastcgi_params.conf;

fastcgi_params.conf

fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
fastcgi_max_temp_file_size 0;
chrisb86 commented 6 years ago

I found a solution now.

nginx doesn't pass the HTTPS server variable to PHP.

I put fastcgi_param HTTPS 'on'; in my fastcgi params and it works now. I found the solution here: https://ma.ttias.be/setting-https-server-variables-in-php-fpm-with-nginx/

JC5 commented 6 years ago

Nice, thanks for reporting back with the solution. I must admit I am a bit out of my league. When nginx is a reversed proxy you can do the $scheme thing.