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

ELB Https с HTTP на бэкэнде с использованием Tomcat без nginx или haproxy

Я хочу настроить ELB для отключения SSL в балансировщике нагрузки и связи с серверными экземплярами через HTTP. Я загрузил действующий сертификат на ELB. Когда я настроил следующую конфигурацию

ELB - HTTPS

Бэкэнд - HTTP

Затем, если приложение выполняет перенаправление в приложении, клиент / браузер перенаправляется на HTTP вместо HTTPS.

Хотя, если я настрою ELB для использования HTTPS и внутренних экземпляров также на HTTPS (даже с использованием самоподписанного сертификата), все будет работать нормально, поскольку обе конфигурации находятся на HTTPS!

Я использую Кот на внутренних экземплярах и не хотят использовать какой-либо другой промежуточный слой (например, nginx или haproxy)

Я нашел эту статью, которая очень похожа на вашу проблему: http://willwarren.com/2014/01/27/running-apache-tomcat-with-ssl-behind-amazon-elb/

В основном говорится об изменении server.xml на это:

<Connector
    port="8080"
    protocol="HTTP/1.1"
    proxyPort="443"
    scheme="https"
    secure="true"
    proxyName="myapp.example.com"
    connectionTimeout="20000"
    URIEncoding="UTF-8"
    redirectPort="8443" />

Мне было трудно найти это в сети, и, наконец, я нашел способ это сделать.

Проблема заключалась в том, что как только http перенаправлялся на порт https на ELB внутри, он перенаправлялся обратно на порт 80, создавая петлю. Это происходит потому, что ELB разгружает SSL, а затем снова подключается к порту 80.

Наконец, после некоторого исследования я получил правильное правило перезаписи для управления X-Forwarded-Proto таким образом, что даже если ELB выгружает SSL tomcat, теперь, когда исходный запрос использовал SSL.

Это делается с помощью Tomcat Valves на Tomcat 8. Я уверен, что это можно сделать и в более ранних версиях. Я включил правила перезаписи на Tomcat с помощью клапанов. После этого это было так же просто, как написать правила перенаправления на Apache.

Вот шаги:

Шаг 1: а. Откройте context.xml в папке tomcat conf b. Вставьте следующую строку чуть ниже

<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />

Примечание: это активирует клапан глобально. Если это необходимо включить для определенного хоста, его следует вставить в файл server.xml для этого конкретного домена.

Шаг 2:

а. Откройте conf / server.xml b. Вставьте следующую строку чуть выше </Host> тег

<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />

Шаг 3:

а. Откройте папку, в которой находится web.xml. Например, если приложение размещено в ROOT, тогда web.xml будет в webapps / ROOT / WEB-INF.

б. Точно так же, если приложение размещено в webapps / myappfolder, тогда web.xml будет в webapps / myappfolder / WEB-INF.

c. В папке WEB-INF Создайте новый файл rewrite.config. и вставьте следующее правило перезаписи:

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

Правила rewrite.config в ответе Рави у меня не работали. При использовании Tomcat 8.0.32, AWS ELB и EC2 мои правила:

# bounce all requests coming in on HTTP to HTTPS
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

Кстати: помните, что HTTP-перенаправления с 301 кешируются в браузере, и если он сработает один раз, вы не увидите, что он снова работает, пока не избавитесь от кешированного перенаправления браузера

Это может быть старый вопрос, но на него было трудно найти ответ. Здесь есть две проблемы: 1. Веб-контейнер Tomcat получает запросы по http, поэтому перенаправления, которые он будет создавать, будут такими же. Весна помогает до некоторой степени, но терпит неудачу. 2. Перенаправление пользователя на HTTPS, даже если он пытается получить доступ к HTTP.

Вторая проблема проста, поскольку ELB отправляет эту информацию в заголовке. Это можно сделать, добавив простой код в существующие фильтры или в новый.

String protocol =req.getHeader("X-Forwarded-Proto");
    if(protocol!=null && "http".equalsIgnoreCase(protocol)){
        rep.sendRedirect( req.getRequestURL().toString().replaceFirst("http", "https"));
        return;
    }

Для первой проблемы одним из решений, которые сработали для меня, было добавление дополнительного свойства (redirectHttp10Compatible) в преобразователь представлений для сервлета Spring.

<bean id="tilesviewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">

    <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
    <property name="redirectHttp10Compatible" value="false" />
 </bean>

Жизнь была хорошей, если бы к весне возникали проблемы с перенаправлениями, но, поскольку проблема была в самом контейнере, требовалась дополнительная помощь. Окончательное решение - изменить server.xml и добавить свойство RemoteIpValve для механизма tomcat. JavaDoc для RemoteIpValve

Это было последнее исправление. Надеюсь, это поможет.