blacklabelops-legacy / nginx

Dockerized Ready-To-Go Nginx Reverse Proxy. Let's encrypt Support!
MIT License
95 stars 41 forks source link

Fixing "Pages with special characters in title are not accessible via reverse proxy" for Confluence #38

Open esciara opened 6 years ago

esciara commented 6 years ago

Hi,

There is a known issue for confluence with special characters in the page titles when running behind a reverse proxy. Details of pb and solution in https://confluence.atlassian.com/confkb/pages-with-special-characters-are-not-accessible-via-reverse-proxy-829664257.html

Basically, when a page contains a special character, it should be replaced by a pageid according to https://confluence.atlassian.com/confkb/confluence-page-urls-contain-pageid-instead-of-the-page-title-278692715.html

However, in some cases, it does not work, and as a result, behind a reverse proxy, it triggers a Server error with exception java.net.URISyntaxException: Illegal character in path at ...

The solution given for nginx si to change the nginx.conf file to add a proxy_pass :

location /<context-path> {

    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 

if ($request_uri ~* "/<context-path>(/.*)") { 
    proxy_pass http://<base-url>/<context-path>$1; break; 
}

proxy_pass http://<base-url>/<context-path>;
}

Would it be possible to add this to the confluence application support of the docker container ?

And if one wants to add it manually, is it possible with the currently existing variables?

Thanks !

Em

blacklabelops commented 6 years ago

Already possible you can "hook-in" your own proxy conf, see here:

https://github.com/blacklabelops/nginx/issues/30

esciara commented 6 years ago

Hi @blacklabelops,

One of my colleagues tried and failed, and now I cannot manage to make it work. Nor sure why.

I tried to follow the issue you mentioned and changed my docker-compose file to include the following: (with ATLASSIAN_NGINX_VERSION=latest)

  nginx:
    image: blacklabelops/nginx:${ATLASSIAN_NGINX_VERSION}
    ports:
      - '443:443'
      - '80:80'
    networks:
      default:
        aliases:
          - '${CONFLUENCE_DOMAIN_NAME}'
          - '${JIRA_DOMAIN_NAME}'
    volumes:
      - nginx_volume:/home/nginx
      - ssl_certificates:/etc/letsencrypt
      - ./nginx_config:/etc/nginx/conf.confluence_reverse_proxy_config
    environment:
      - 'TZ=${ATLASSIAN_TIME_ZONE}'
      - 'NGINX_REDIRECT_PORT80=${ATLASSIAN_PORT80_REDIRECT}'
      - 'SERVER1SERVER_NAME=${JIRA_DOMAIN_NAME}'
      - 'SERVER1REVERSE_PROXY_LOCATION1=/'
      - 'SERVER1REVERSE_PROXY_PASS1=http://jira:8080'
      - 'SERVER1HTTPS_ENABLED=${ATLASSIAN_HTTPS}'
      - 'SERVER1HTTP_ENABLED=${ATLASSIAN_HTTP}'
      - 'SERVER1LETSENCRYPT_CERTIFICATES=${ATLASSIAN_HTTPS}'
      - 'SERVER1CERTIFICATE_FILE=/etc/letsencrypt/live/${JIRA_DOMAIN_NAME}/fullchain.pem'
      - 'SERVER1CERTIFICATE_KEY=/etc/letsencrypt/live/${JIRA_DOMAIN_NAME}/privkey.pem'
      - 'SERVER1CERTIFICATE_TRUSTED=/etc/letsencrypt/live/${JIRA_DOMAIN_NAME}/fullchain.pem'
      - 'SERVER1PROXY_APPLICATION=jira'
      - 'SERVER2SERVER_NAME=${CONFLUENCE_DOMAIN_NAME}'
      - 'SERVER2PROXY_CONFIGURATION=/etc/nginx/conf.confluence_reverse_proxy_config/confluenceReverseProxy.conf'
      - 'SERVER2HTTPS_ENABLED=${ATLASSIAN_HTTPS}'
      - 'SERVER2HTTP_ENABLED=${ATLASSIAN_HTTP}'
      - 'SERVER2LETSENCRYPT_CERTIFICATES=${ATLASSIAN_HTTPS}'
      - 'SERVER2CERTIFICATE_FILE=/etc/letsencrypt/live/${JIRA_DOMAIN_NAME}/fullchain.pem'
      - 'SERVER2CERTIFICATE_KEY=/etc/letsencrypt/live/${JIRA_DOMAIN_NAME}/privkey.pem'
      - 'SERVER2CERTIFICATE_TRUSTED=/etc/letsencrypt/live/${JIRA_DOMAIN_NAME}/fullchain.pem'
      - 'SERVER2PROXY_APPLICATION=confluence'

With the confluenceReverseProxy.conf just copying what was generated by your code when using the REVERSE_PROXY_LOCATION with REVERSE_PROXY_PASS and other REVERSE_PROXY_* settings:

        location /synchrony {
           set $backend "http://confluence:8091";
           proxy_pass $backend$uri$is_args$args;
           proxy_set_header X-Forwarded-Host $host;
           proxy_set_header X-Forwarded-Server $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
        }
        location / {
           set $backend "http://confluence:8090";
           proxy_pass $backend$uri$is_args$args;
           proxy_set_header X-Forwarded-Host $host;
           proxy_set_header X-Forwarded-Server $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_connect_timeout 300;
           proxy_send_timeout 300;
           proxy_read_timeout 300;
        }

When starting up with a docker-compose -f compose-atlassian.yml -p atlassian up nginx &, I get the following output.

Creating atlassian_nginx_1 ... done
Attaching to atlassian_nginx_1
nginx_1                  |         location / {
nginx_1                  |           set $backend "http://jira:8080";
nginx_1                  |           proxy_pass $backend$uri$is_args$args;
nginx_1                  |           proxy_set_header X-Forwarded-Host $host;
nginx_1                  |           proxy_set_header X-Forwarded-Server $host;
nginx_1                  |           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
nginx_1                  |         }
nginx_1                  | server {
nginx_1                  |   listen       80;
nginx_1                  |   server_name         jira.example.com;
nginx_1                  |
nginx_1                  |   ssl_trusted_certificate /etc/letsencrypt/live/jira.example.com/fullchain.pem;
nginx_1                  |   # Load configuration files for the default server block.
nginx_1                  |   include /etc/nginx/conf.d/server1/*.conf;
nginx_1                  | }
nginx_1                  | worker_processes auto;
nginx_1                  | error_log /dev/stdout info;
nginx_1                  |
nginx_1                  | events {
nginx_1                  |   worker_connections 1024;
nginx_1                  | }
nginx_1                  |
nginx_1                  | http {
nginx_1                  |   log_format  main  '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
nginx_1                  |
nginx_1                  |   access_log /dev/stdout;
nginx_1                  |
nginx_1                  |   sendfile              on;
nginx_1                  |   tcp_nopush            on;
nginx_1                  |   tcp_nodelay           on;
nginx_1                  |
nginx_1                  |   resolver 127.0.0.11  ipv6=off valid=30s;
nginx_1                  |
nginx_1                  |   include mime.types;
nginx_1                  |   client_max_body_size  100m;
nginx_1                  |   keepalive_timeout     65;
nginx_1                  |   types_hash_max_size   2048;
nginx_1                  |
nginx_1                  |   # Load modular configuration files from the /etc/nginx/conf.d directory.
nginx_1                  |   # See http://nginx.org/en/docs/ngx_core_module.html#include
nginx_1                  |   # for more information.
nginx_1                  |   include /etc/nginx/conf.d/*.conf;
nginx_1                  | }
nginx_1                  | 2018/03/21 19:34:21 [notice] 7#7: using the "epoll" event method
nginx_1                  | 2018/03/21 19:34:21 [notice] 7#7: nginx/1.10.3
nginx_1                  | 2018/03/21 19:34:21 [notice] 7#7: OS: Linux 4.9.60-linuxkit-aufs
nginx_1                  | 2018/03/21 19:34:21 [notice] 7#7: getrlimit(RLIMIT_NOFILE): 1048576:1048576
nginx_1                  | 2018/03/21 19:34:21 [notice] 7#7: start worker processes
nginx_1                  | 2018/03/21 19:34:21 [notice] 7#7: start worker process 35
nginx_1                  | 2018/03/21 19:34:21 [notice] 7#7: start worker process 36
nginx_1                  | 2018/03/21 19:34:21 [notice] 7#7: start worker process 37
nginx_1                  | 2018/03/21 19:34:21 [notice] 7#7: start worker process 38

As you can see, the SERVER1 features (for the Jira server) are generated, but not for the SERVER2 (for Confluence).

What am I missing?

blacklabelops commented 6 years ago

You generated config looks outdated. Have you tried updating the image with docker pull?

esciara commented 6 years ago

@blacklabelops : never mind.... my docker did not pull automatically the latest image even though it was at latest... Doh. Sorry. I am continuing with the work and will put the working example on this thread.

esciara commented 6 years ago

Ok. I solved the special character issue with:

        location ~* ^/(.*) {
          set $backend "http://confluence:8090";
          if ($request_uri ~* "/(.*)") {
              proxy_pass $backend/$1; break;
          }
          proxy_pass $backend/;
          proxy_set_header X-Forwarded-Host $host;
          proxy_set_header X-Forwarded-Server $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

It also means that it rolls back changes added in 07667578b30ae01ee8ab85c94be0f54cccfb62d0 to solve #39 . Don't know how to make both work together.

blacklabelops commented 6 years ago

I would still include the custom config.

esciara commented 6 years ago

And I did :).

So, final result:

One question @blacklabelops : should this correction of the special character issue not be built in the image ? With something like SERVER2REVERSE_PROXY_HANDLE_SPECIAL_CHARACTERS=true?

Thanks for your help.

blacklabelops commented 6 years ago

Maybe I will take a look.

Btw. I am running Confluence fine without synchrony proxy. Latest Confluence version runs synchrony fine over path.

esciara commented 6 years ago

Thanks. Cool you could take a look. It is a bit too complex for me level of knowledge of Nginx, especially with the changes related to #39. I leave you to decide to close this issue or not, whether you choose to add this change or not.

I tried with removing the proxy for synchrony... And it works ! Thanks!

So the changed ./nginx_config/nginxConfluenceReverseProxy.conf file is:

        location ~* ^/(.*) {
          set $backend "http://confluence:8090";

          if ($request_uri ~* "/(.*)") {
              proxy_pass $backend/$1; break;
          }
          proxy_pass $backend/;

          proxy_set_header X-Forwarded-Host $host;
          proxy_set_header X-Forwarded-Server $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_connect_timeout 300;
          proxy_send_timeout 300;
          proxy_read_timeout 300;
        }