Apache ProxyPass-ing múltiples ubicaciones

Apache ProxyPass-ing múltiples ubicaciones

Actualmente tengo problemas al intentar utilizar Apache para que actúe como proxy inverso para el front-end de nuestra aplicación y nuestra API de backend.

Por ejemplo, si un usuario accede a la URL, https://my.app.com/se le debe dirigir a nuestra aplicación front-end proporcionada desde S3. Si ingresa a la URL, https://my.app.com/api/hellorecibirá una respuesta JSON de nuestra API de backend.

El comportamiento ideal es que https://my.app.com/se realice un proxy inverso a http://s3app.private.

Del mismo modo, querremos https://my.app.com/api/helloque se nos realice un proxy inversohttp://myapi.private/api/hello

Nuestra configuración actual de Apache se ve así:

Listen 443                                                                                                                                                                        
<VirtualHost *:443>                                                                                                                                                               
    ServerName my.app.com                                                                                                                                               
    ErrorDocument 404 /index.html                                                                                                                                                
    ProxyErrorOverride On                                                                                                                                                        

    RequestHeader set X-Forwarded-Proto https                                                                                                                                     

    SSLEngine on                                                                                                                                                                  
    SSLCertificateFile "/usr/local/apache2/certs/certificate.crt"                                                                                                                 
    SSLCertificateKeyFile "/usr/local/apache2/certs/private.key"                                                                                                                  
    SSLProtocol TLSv1.2                                                                                                                                                           

    ProxyAddHeaders On                                                                                                                                                            

    <Location "/">                                                                                                                                                                
        ProxyPass "http://s3app.private/" retry=0                                                                                                                      
    </Location>                                                                                                                                                                   
    <Location "/api">                                                                                                                                                             
        ProxyPreserveHost On                                                                                                                                                      
        ProxyPass "http://myapi.private/api" retry=0                                                                                                                             
    </Location>                                                                                                                                                                   
</VirtualHost> 

El comportamiento actual es que cuando presionamos https://my.app.com/vemos nuestra aplicación front-end. Sin embargo, cuando presionamos, https://my.app.com/api/helloobtenemos un 503error del servidor.

Los registros de Apache muestran estas líneas:

[proxy:error] The timeout specified has expired: AH00957: HTTP: attempt to connect to <internal_ip>:80 (api.private) failed
[proxy_http:error] AH01114: HTTP: failed to make connection to backend: myapi.private, referer: https://my.app.com/
"GET /api/hello HTTP/1.1" 503 299

Hemos verificado que nuestra API realmente escucha a través de este mecanismo al señalar a Apache solo a la API de esta manera:

Listen 443                                                                                                                                                                        
<VirtualHost *:443>                                                                                                                                                               
    ServerName my.app.com                                                                                                                                               
    ErrorDocument 404 /index.html                                                                                                                                                
    ProxyErrorOverride On                                                                                                                                                        

    RequestHeader set X-Forwarded-Proto https                                                                                                                                     

    SSLEngine on                                                                                                                                                                  
    SSLCertificateFile "/usr/local/apache2/certs/certificate.crt"                                                                                                                 
    SSLCertificateKeyFile "/usr/local/apache2/certs/private.key"                                                                                                                  
    SSLProtocol TLSv1.2                                                                                                                                                           

    ProxyAddHeaders On                                                                                                                                                            

    <Location "/api">                                                                                                                                                             
        ProxyPreserveHost On                                                                                                                                                      
        ProxyPass "http://myapi.private/api" retry=0                                                                                                                             
    </Location>                                                                                                                                                                   
</VirtualHost> 

Hacerlo nos permite presionar https://my.app.com/api/helloy ver la respuesta JSON esperada. Pero esto sólo tiene éxito cuando no hay ningún otro bloque de ubicación presente.

Por si sirve de algo, nuestro DNS interno lo proporciona Route53 y nuestra API está alojada en ECS.

¡Cualquier ayuda será muy apreciada!

Respuesta1

Usar dos hosts virtuales puede resultar útil, pero puede que no sea la solución más ideal.

Listen 443
<VirtualHost *:443>
    ServerName my.app.com 
    ErrorDocument 404 /index.html
    ProxyErrorOverride On

    RequestHeader set X-Forwarded-Proto https

    SSLEngine on
    SSLCertificateFile "/usr/local/apache2/certs/certificate.crt"
    SSLCertificateKeyFile "/usr/local/apache2/certs/private.key"
    SSLProtocol TLSv1.2

    ProxyAddHeaders On

    <Location "/">
        ProxyPass "http://s3app.private/" retry=0
    </Location>
    <Location "/api">
        ProxyPreserveHost On
        ProxyPass "http://localhost:8443/api" retry=0
    </Location>
</VirtualHost>

Listen 8443
<VirtualHost *:8443>
    ServerName localhost
    <Location "/api">
        ProxyPreserveHost On
        ProxyPass "http://myapi.private/api" retry=0
    </Location>
</VirtualHost>

No tengo una razón técnica por la que esto resolvería tu problema, pero puede que valga la pena intentarlo.

información relacionada