NGINX as reverse proxy in front of Apache does not work with SSL turned on

5,064

Solution 1

Looks like I finally got implementation thanks to all the feedback I received from you. Thanx @AlexeyTen and @Tim

  • First I disabled https vhost on apache for domain foobar.net sudo a2dissite foobar.net.cong

  • I edited apache ports.conf file to only listen to port 8081 and removed listening on port 443:

NameVirtualHost *:8081

Listen 8081
  • Finally I edited nginx server block to listen to port 443 and made sure to comment out ssl on. Not doing so did not work.
> server {
>     listen 80;
>     listen 443 ssl;
>     server_name foobar.net;
> 
>   # ssl on;
>     ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem;
>     ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem;
> 
>     location / {
>         proxy_pass http://104.236.224.53:8081;
>         proxy_set_header Host $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;
>     } }

This implementation appears to work fine and handover php handling to Apache seamlessly.

Solution 2

You've told both Apache and Nginx to listen on port 443, I assume on the same machine. Only one application can listen on a port.

Perhaps you could edit your question to tell us why you want to use both Nginx and Apache - you can do most things with either of them. You might get more useful advice that way.

Share:
5,064

Related videos on Youtube

Robert
Author by

Robert

Technology lover always looking for something new to learn.

Updated on September 18, 2022

Comments

  • Robert
    Robert almost 2 years

    I have read every post, tutorial and comment on forums out there an for the life of me still cannot get Nginx proxy to work properly once SSL is turned withing Nginx server block.

    Apache is fully set up with virtual host for both regular and ssl access. Apache is listening on port 8081 with ports.conf is as follows:

    NameVirtualHost *:8081
    Listen 8081
    
    <IfModule ssl_module>
            Listen 443
    </IfModule>
    
    <IfModule mod_gnutls.c>
            Listen 443
    </IfModule>
    

    My SSL apache vhost is as follows:

    With nginx turned on and ssl settings commented out as in the following configuration (see below) everything works fine as I am able to access both SSL and non SSL versions of site correctly.

        server {
            listen 80;
      #      listen 443 ssl;
            server_name foobar.net;
    
       # ssl on;
       #     ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem;
       #     ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem;
    
            location / {
                proxy_pass http://104.236.224.53:8081;
                proxy_set_header Host $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;
            }
        }
    

    When I modify above file and turn on SSL by un-commenting options in server block there appears to be a conflict between Nginx and Apache on port 443?

    Updated and un-commented server blocks looks like so:

        server {
            listen 80;
            listen 443 ssl;
            server_name foobar.net;
    
        ssl on;
            ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem;
    
            location / {
                proxy_pass http://104.236.224.53:8081;
                proxy_set_header Host $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;
            }
        }
    

    Trying to start nginx return following error:

     nginx.service - A high performance web server and a reverse proxy server
       Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
       Active: failed (Result: exit-code) since Mon 2017-02-20 18:35:20 EST; 16s ago
      Process: 14505 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS
      Process: 14475 ExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reload (code=exited, status=0/SUCCESS)
      Process: 14671 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE)
      Process: 14652 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
     Main PID: 14328 (code=exited, status=0/SUCCESS)
    
    Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
    Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
    Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
    Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
    Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
    Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] still could not bind()
    Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Control process exited, code=exited status=1
    Feb 20 18:35:20 foo.foobar.net systemd[1]: Failed to start A high performance web server and a reverse proxy server.
    Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Unit entered failed state.
    Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Failed with result 'exit-code'.
    

    What am I missing here with my implementation to get SSL to get passed on properly to Apache from Nginx?


    Edit 1: To address @Tim's good point I'll edit my main intent in having Nginx handling all requests.

    • My original intention was to install Discourse, which itself is in a Docker container, on the same machine where Apache was already being used as my main server.
    • Because Discourse needs access to port 80 to run properly, it is recommended to setup nginx in front as a reverse proxy to handle all incoming requests so that it passes them accordingly.
    • I want to use apache on the back to handle all dynamic content and let nginx handle static bits. And so it is my understanding that in order to do so a virtual hos needs to be established on apache for each instance: both http and https requests. Maybe I'm wrong here on this point?

    I followed configurations suggested by DigitalOcean: fast forward to their optional step 9.

    Logically at this point, just as I have HTTP host on apache listening on port 8081 for requests being passed on from nginx, I assumed I could do the same and also have HTTPS host on apache listen to port 8081 and gracefully pass headers over to Apache to handle the rest. This implementation did not work fully as I was plagued with error 400: the plain http request was sent to https port

    I took it a step further and assumed that again maybe since both of Apache HTTP and HTTPS are listening to port 8081 on back that if I assigned assigned apache HTTP to port 8081 and HTTPS to port 1443 everything would work seamlessly. Again it does not work fully as when I try to access my worpress blog via HTTPS with this implementation I get error

    Your browser sent a request that this server could not understand.
    Reason: You're speaking plain HTTP to an SSL-enabled server port.
    Instead use the HTTPS scheme to access this URL, please.
    

    At this point I'm literally fresh out of ideas even though it seems many have gotten digital ocean suggested implementation to work properly. :-/

    • Alexey Ten
      Alexey Ten over 7 years
      First of all You must remove Listen 443 from apache and ssl on from nginx.
    • Robert
      Robert over 7 years
      Wow! Your suggestion led me in right direction!! I'll post solution as answer. Thank You!! @AlexeyTen
  • Robert
    Robert over 7 years
    Thanks @tim. I shared a bit of extra context in an edit as suggested.
  • Tim
    Tim over 7 years
    So basically you did what I said, you just needed a bit more detail on how to do it :-)