Назад | Перейти на главную страницу

Apache ProxyPass-ing в нескольких местах

В настоящее время у меня возникают проблемы с попыткой использовать Apache в качестве обратного прокси для внешнего интерфейса нашего приложения и нашего внутреннего API.

Например, если пользователь попадает по URL-адресу https://my.app.com/ их следует направить в наше внешнее приложение, обслуживаемое из S3. Если вы нажмете URL https://my.app.com/api/hello вы получите ответ в формате JSON от нашего внутреннего API.

Идеальное поведение - это https://my.app.com/ быть обратным проксированием к http://s3app.private.

Так же мы захотим https://my.app.com/api/hello для обратного проксирования http://myapi.private/api/hello

Наша текущая конфигурация apache выглядит так:

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> 

Текущее поведение таково, что когда мы нажимаем https://my.app.com/ мы видим наше интерфейсное приложение. Однако когда мы попали https://my.app.com/api/hello мы получаем 503 ошибка с сервера.

Журналы Apache показывают эти строки:

[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

Мы проверили, что наш API действительно прослушивает этот механизм, указав Apache только на API следующим образом:

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> 

Это позволяет нам ударить https://my.app.com/api/hello и увидеть ожидаемый ответ JSON. Но это успешно только тогда, когда нет другого блока местоположения.

Как бы то ни было, наш внутренний DNS предоставляется Route53, а наш API размещен в ECS.

Любая помощь будет принята с благодарностью!

Использование двух виртуальных хостов может помочь, но, возможно, это не самое идеальное решение.

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>

У меня нет технической причины, почему это решило бы вашу проблему, но, возможно, стоит попробовать.