proxy nginx vers Tomcat avec SSL

Jan 29 2021

J'ai posté ceci sur stackoverflow par erreur (https://stackoverflow.com/questions/65942820/nginx-proxy-to-tomcat) et je le mets ici aussi dans l'espoir de trouver une solution.

J'ai parcouru des dizaines de tutoriels et je ne peux pas comprendre ce qui suit (même si cela devrait être assez basique):

J'ai mon application vue compilée dans /var/www/mydomain.com et je veux qu'elle soit partagée en tant que contenu statique.

Mon backend fonctionnant sur 8080 par tomcat avec des API publiques sur / api / quelque chose ... URL. Les URL sont codées en dur, y compris la partie "api".

Je voudrais configurer nginx pour proxy mydomain.com/api/something ... les demandes à tomcat et au repos soient servies statiquement à partir de /var/www/mydomain.com. Tout est servi via SSL.

Je n'ai littéralement besoin de rien d'autre.

Pouvez-vous m'aider à configurer le nginx et le tomcat pour y parvenir? Merci!

nginx config /etc/nginx/sites-available/mydomain.com

upstream tomcat {
    server 127.0.0.1:8080 fail_timeout=0;
}

server {
        listen 443 ssl default_server;
        #listen [::]:443 ssl default_server;

        root /var/www/mydomain.com;
        index index.html index.htm index.nginx-debian.html;

       server_name _ mydomain.com www.mydomain.com;

        location /api/ {
                include proxy_params;
                proxy_set_header Host $server_name; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://tomcat; } location / { try_files $uri $uri/ /index.html; } ssl_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/www.mydomain.com/privkey.pem; # managed by Certbot } server { if ($host = www.mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = mydomain.com) { return 301 https://$host$request_uri;
    } # managed by Certbot


       listen 80 default_server;
        listen [::]:80 default_server;

       server_name _ mydomain.com www.mydomain.com;
   return 404; # managed by Certbot
}

(1) Bloc d'emplacement alternatif que j'expérimente

        location /api/ {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-Proto https;
                proxy_pass http://localhost:8080/api/;
        }

(2) Bloc alternatif suggéré par Praveen Premaratne.

De cette façon, je reçois "GET /api/docs HTTP/1.0" 302 -et les fichiers statiques fonctionnent également. Aller à / api / docs fait rediriger vers l' domain:8443/api/docsendroit où j'obtiens ERR_CONNECTION_REFUSED.

        location /api/ {
                include proxy_params;
                proxy_pass http://tomcat;
        }

        location / {
                try_files $uri $uri/ /index.html;
        }

(3) Alternative utilisant un sous-domaine.

J'ai pu créer un sous-domaine api.mydomain.com et configurer nginx pour accéder à la page d'index à partir de là (en ajoutant le bloc suivant). Aucune idée de comment faire le proxy par la suite.

server {
        listen 443 ssl;

        root /var/www/www.mydomain.com; <- redundand I guess?
        index index.html index.htm index.nginx-debian.html; <- redundand I guess?

        server_name api.mydomain.com

        ssl_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/www.mydomain.com/privkey.pem; # managed by Certbot
}

Serveur de configuration Tomcat.xml

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               address="127.0.0.1"
               redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
   ...
   <Host name="localhost"  appBase="webapps"
         unpackWARs="true" autoDeploy="true">
      
      <Valve className="org.apache.catalina.valves.AccessLogValve" 
         directory="logs"
         prefix="localhost_access_log" suffix=".txt"
         requestAttributesEnabled="true"
         pattern="%h %l %u %t &quot;%r&quot; %s %b" />
        
      <Valve className="org.apache.catalina.valves.RemoteIpValve"
         protocolHeader="X-Forwarded-Proto" /> 
   ...    

La situation actuelle est que lorsque je vais sur mydomain.com/api/docs où swagger devrait être en cours d'exécution, je suis redirigé vers mydomain.com ou j'obtiens une erreur 500 ou 502.

Réponses

1 TomášLeitl Feb 01 2021 at 01:45

Ok, donc avec l'aide de @Praveen Premaratne et @Piotr P. Karwasz et de cet article, j'ai trouvé la configuration suivante:

ne mettez pas les lignes avec "# managed by Certbot", celles-ci sont créées par certbot, vérifiez https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04

etc / nginx / sites-available / mydomain.com

server {
    server_name    mydomain.com www.mydomain.com;

    root /var/www/mydomain.com;
    index index.html;

    access_log /var/log/nginx/mydomain-access.log;
    error_log /var/log/nginx/mydomain-error.log;

    location / {
        try_files $uri $uri/ /index.html;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.mydomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = www.mydomain.com) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    server_name    mydomain.com www.mydomain.com;
    listen 80;
    return 404; # managed by Certbot
}

/etc/nginx/sites-available/api.mydomain.com

server {
    server_name    api.mydomain.com;

    access_log /var/log/nginx/api-mydomain-access.log;
    error_log /var/log/nginx/api-mydomain-error.log;

    location / {
        proxy_set_header Host $http_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-Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:8080; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/www.mydomain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = api.mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name    api.mydomain.com;
    listen 80;
    return 404; # managed by Certbot
}

Serveur Tomcat.xml

<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
    connectionTimeout="20000"
    address="127.0.0.1"
    proxyName="api.mydomain.com"
    proxyPort="80"/>

<Engine name="Catalina" defaultHost="localhost">

    <Realm className="org.apache.catalina.realm.LockOutRealm">
    ...
    </Realm>

    <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

        <Valve className="org.apache.catalina.valves.RemoteIpValve"
            remoteIpHeader="x-forwarded-for"
            proxiesHeader="x-forwarded-by"
            protocolHeader="x-forwarded-proto" />

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
            prefix="localhost_access_log" suffix=".txt"
            pattern="%h %l %u %t %r %s %b" />

  </Host>
</Engine>
fuero Jan 29 2021 at 20:01

Essaye ça:

location / {
        try_files $uri @backend;
}
location @backend {
        include proxy_params;
        proxy_pass http://tomcat;
}
PraveenPremaratne Jan 29 2021 at 23:22

Si je devais faire cela en utilisant l'approche des sous-domaines, voici comment je le ferais.

  • Créer un fichier de configuration Nginx pour l'API backend
  • Créer un fichier de configuration Nginx pour le contenu Web statique

Fichier HTML Nginx statique mydomain.com.nginx

server {
    server_name    mydomain.com;

    root /var/www/mydomain.com;
    index index.html;

    access_log /var/log/nginx/mydomain-access.log;
    error_log /var/log/nginx/mydomain-error.log;

    location / {
        try_files $uri $uri/ /index.html;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.mydomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = mydomain.com) { return 301 https://$host$request_uri;
    } # managed by Certbot


    listen         80;
    server_name    mydomain.com;
    return 404; # managed by Certbot


}

Fichier de configuration API Nginx api.mydomain.com.nginx

server {
    server_name    api.mydomain.com;

    access_log /var/log/nginx/api-mydomain-access.log;
    error_log /var/log/nginx/api-mydomain-error.log;

    location / {
        proxy_set_header X-Forwarded-Host $host:$server_port; proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080; proxy_redirect off; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/api.mydomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/api.mydomain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = api.mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen         80;
    server_name    app.mydomain.com;
    return 404; # managed by Certbot


}

Vous pouvez les ajouter au /etc/nginx/site-available/répertoire et les activer.

Ps: Je supprimerais les éléments SSL et exécuterais Certbot pour les mettre à jour puisque vous devez émettre un nouveau certificat pour app.mydomain.com , donc il mettrait simplement à jour les fichiers lui-même