09.08.2011

Форвард с HTTP на HTTPS в Nexus (Jetty) и Tomcat

Чтобы все было по фэн-шую, корпоративные ресурсы нужно делать только по HTTPS, так как там везде аутентификацию и, соответственно, передаются данные, которые можно легко перехватить.
В случае, если Вы используете Apache или Nginx, то все тривиально, но если ресурс на Jetty/Tomcat, как например TeamCity или Nexus, то придется немножко помучаться.

Jetty.
Итак начнем с Jetty (рассматривается на примере Nexus):
Первое, что требуется - научить его работать одновременно и с HTTP и с HTTPS. Для этого в файл свойств jetty добавим еще один порт:
vim /opt/nexus/conf/plexus.properties


application-port=80
application-port-ssl=443
...

Далее в конфигурационном файле Jetty, создадим еще один коннектор.

Был только один коннектор:
    <Call name="addConnector">
        <Arg>
            <New class="org.mortbay.jetty.nio.SelectChannelConnector">
              <Set name="host">${application-host}</Set>
              <Set name="port">${application-port}</Set>
            </New>
        </Arg>
    </Call>

А мы сделаем два одновременно (второй пообширнее, так как там сертификат описывается):

        <Call name="addConnector">
        <Arg>
            <New class="org.mortbay.jetty.nio.SelectChannelConnector">
              <Set name="host">${application-host}</Set>
              <Set name="port">${application-port}</Set>
            </New>
        </Arg>
    </Call>

    <Call name="addConnector">
        <Arg>
            <New class="org.mortbay.jetty.security.SslSelectChannelConnector">
              <Set name="host">${application-host}</Set>
              <Set name="port">${application-port-ssl}</Set>
              <Set name="keystore">/etc/ssl/keystore</Set>
              <Set name="keyPassword">Meik8hahTi5ooXoong3aiv1maiteed</Set>
              <Set name="truststore">/etc/ssl/keystore</Set>
              <Set name="password">Meik8hahTi5ooXoong3aiv1maiteed</Set>
              <Set name="trustPassword">Meik8hahTi5ooXoong3aiv1maiteed</Set>
            </New>
        </Arg>
    </Call>
Теперь заменяем объявление существующего handler/context-collection на отдельный context-collection. А именно просто убираем обрамляющий тег .



Было так:
<Set name="handler">
    <New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection">
        <!-- The following configuration is REQUIRED, and MUST BE FIRST.
             It makes the Plexus container available for use in the Nexus webapp. -->
        <Call name="addLifeCycleListener">
            <Arg>
                <New class="org.sonatype.plexus.jetty.custom.InjectExistingPlexusListener" />
            </Arg>
        </Call>

        <!-- The following configuration disables JSP taglib support, the validation of which
             slows down Jetty's startup significantly. -->
        <Call name="addLifeCycleListener">
            <Arg>
                <New class="org.sonatype.plexus.jetty.custom.DisableTagLibsListener" />
            </Arg>
        </Call>
    </New>
</Set>

А стало так:

      <New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection">
        <!-- The following configuration is REQUIRED, and MUST BE FIRST.
             It makes the Plexus container available for use in the Nexus webapp. -->
        <Call name="addLifeCycleListener">
            <Arg>
                <New class="org.sonatype.plexus.jetty.custom.InjectExistingPlexusListener" />
            </Arg>
        </Call>

        <!-- The following configuration disables JSP taglib support, the validation of which
             slows down Jetty's startup significantly. -->
        <Call name="addLifeCycleListener">
            <Arg>
                <New class="org.sonatype.plexus.jetty.custom.DisableTagLibsListener" />
            </Arg>
        </Call>
    </New>
 
 
И добавляем прямо перед линией stopAtShutdown хэндлер рерайта:

      <Set name="handler">
        <New id="Handlers" class="org.mortbay.jetty.handler.rewrite.RewriteHandler">

            <Set name="rules">
                <Array type="org.mortbay.jetty.handler.rewrite.Rule">
                    <Item>
                        <New id="redirectedHttps" class="org.sonatype.plexus.jetty.custom.RedirectToHttpsRule">
                            <Set name="httpsPort">${application-port-ssl}</Set>
                        </New>
                    </Item>
                </Array>
            </Set>

            <Set name="handler">
                <New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
                    <Set name="handlers">
                        <Array type="org.mortbay.jetty.Handler">
                            <Item><Ref id="Contexts"/></Item>
                            <Item>
                                <New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
                            </Item>
                            <Item>
                                <New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/>
                            </Item>
                         </Array>
                    </Set>
                </New>
            </Set>
        </New>
    </Set>
 
Готово. Теперь перегружаем (с поправкой на то, где у Вас nexus живет):
/opt/nexus/bin/jsw/linux-x86-64/nexus stop
/opt/nexus/bin/jsw/linux-x86-64/nexus start
После данного действия, если Вы заходите на сервер на 80-й порт как HTTP, то Вам перебрасывает на 443-й на HTTPS

Tomcat.
И тоже самое можно делать в Tomcat, причем намного проще.
Сначала настроим правильно форвард с 80-го порта:
vim server.xml

    <Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="443"
               enableLookup="false"
               useBodyEncodingForURI="true"
        /
>
А также проверим в том же файле коннектор самого 443-го порта (по умолчанию он закомментированный значками <--! и --> ) и уберем оттуда восьмеру, чтобы был не 8443/8543, а нормальный 443-й как у людей, чтобы браузеру не задавать порт:
    <Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" keystorePass="
Meik8hahTi5ooXoong3aiv1maiteed" />

Теперь откроем файл web.xml и там укажем дополнительно сразу под этим блоком:
    <!-- The mapping for the default servlet -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
вот этот:
<!-- Forward from HTTP to HTTPS -->

   
<security-constraint>
        <web-resource-collection>
            <web-resource-name>Entire Application</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
Теперь перегружаем Tomcat и пробуем зайти на него по HTTP - должен перекинуть на HTTPS.

Комментариев нет:

Отправить комментарий