2014-02-18 1 views
2

Я пытаюсь использовать https между двумя серверами tomcat. К сожалению, самоподписные сертификаты вызывают эту ошибку:Как создать самоподписанные сертификаты, которым будут довольны два кота, при использовании https между tomcats?

Caused by: javax.net.ssl.SSLHandshakeException: 
      sun.security.validator.ValidatorException: PKIX path building failed: 
      sun.security.provider.certpath.SunCertPathBuilderException: 
         unable to find valid certification path to requested target 

В частности, у меня есть мастер-кот и несколько подчиненных серверов Tomcat. Мастер связывается с сервлетом, используя простое соединение HttpURLC.

Что является самым простым способом для создания самоподписанных сертификатов с использованием моего собственного центра сертификации, так что каждый раз, когда я добавляю новый сервер, мне не нужно менять мастер-сервер tomcat.

У меня есть доступ к OpenSSL и Java 7 Keytool

Для справки моей предыдущей конфигурация:

server.xml разъем:

<Connector port="443" maxHttpHeaderSize="8192" maxThreads="150" 
    minSpareThreads="25" maxSpareThreads="75" enableLookups="false" 
    disableUploadTimeout="true" acceptCount="100" debug="0" scheme="https" 
    secure="true" clientAuth="false" sslProtocol="TLS" keystoreType="PKCS12" 
    keystoreFile="/usr/java/apache-tomee-plus/conf/keystore.ks" 
    keystorePass="XXX_SSL" truststoreType="JKS" 
    truststoreFile="/usr/java/apache-tomee-plus/conf/truststore.ks" 
    SSLEnabled="true" maxPostSize="0"/> 

Запуск сценарий /etc/init.d/tomee

$DAEMON_HOME/jsvc \ 
-user $TOMCAT_USER \ 
-home $JAVA_HOME \ 
-pidfile $JSVC_PID_FILE \ 
-Dcatalina.home=$CATALINA_HOME \ 
-Djava.security.auth.login.config=$CATALINA_HOME/conf/jaas.conf \ 
-Djavax.net.ssl.keystore=$CATALINA_HOME/conf/keystore.ks \ 
-Djavax.net.ssl.keyStorePassword=XXX_SSL \ 
-Djavax.net.ssl.trustStore=$CATALINA_HOME/conf/truststore.ks \ 
-Djavax.net.ssl.trustStorePassword=changeit \ 
-Djava.awt.headless=true \ 
-Djava.io.tmpdir=$TMP_DIR \ 
-Dopenam.agents.bootstrap.dir=/home/tomcat/tomcat_v6_agent/Agent_001/config \ 
-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses \ 
-outfile $CATALINA_HOME/logs/catalina.out \ 
-errfile $CATALINA_HOME/logs/catalina.err \ 
$CATALINA_OPTS \ 
-cp $CLASSPATH \ 
org.apache.catalina.startup.Bootstrap 

conf/jaas.conf

josso { 
    org.josso.tc55.agent.jaas.SSOGatewayLoginModule required debug=true; 
}; 

Что имеется только для устаревшей поддержки и будет прекращено. Я не уверен, что он даже загружается, поскольку он создан для tomcat 5.5 ...

Внутри кода я избегаю проблем с использованием IP-адресов в CN =, используя следующее имя узлаVerifier().

HostnameVerifier hv = new HostnameVerifier() 
{ 
    public boolean verify(String urlHostName, SSLSession session) 
    { 
     return true; 
    } 
}; 
HttpsURLConnection.setDefaultHostnameVerifier(hv); 

connection = (HttpURLConnection) servlet.openConnection(); 

------------ Обновление ---------------

Это была решена путем длительного обсуждения с @Bruno , пожалуйста, используйте его оригинальное сообщение и длинную дискуссию в чате, которая у нас была.

В конце я использовал инструменты Keytool Explorer и XCA, чтобы облегчить мне изучение и выполнение.

+0

Можете ли вы сказать нам, что именно вы уже сделали в качестве конфигурации, чтобы иметь эту ошибку? –

+0

В stackoverflow уже есть много вопросов с тегом [tomcat]. Ваш вопрос не похож на тему. Однако, если у людей нет немедленного ответа, требуется время, чтобы настроить/воспроизвести всю вашу среду, чтобы выяснить, что происходит. Вы можете установить щедрость (http://meta.stackexchange.com/questions/16065/how-does-the-bounty-system-work), чтобы мотивировать poeple или увидеть проблему непосредственно с сообществом tomcat (http: // tomcat. apache.org/findhelp.html). –

+0

«Если этот вопрос здесь не принадлежит, есть ли более подходящий сайт-помощник» - проблемы с конфигурацией обычно принадлежат [Super User] (http://www.superuser.com) или [Server Fault] (http: // www .serverfault.com). – jww

ответ

2

Во-первых, вы фактически не делаете соединения между серверами: это все еще соединения «клиент-сервер». Просто случается, что ваш клиент - webapp, работающий в контейнере сервлетов.

Это важно, потому что это настройки доверия клиентов, которые будут использоваться для установления соединений. Они отличаются от настроек доверия на соединителе Tomcat.

Как ваш клиент webapp использует свои настройки доверия, зависит от того, как он реализован и в какой библиотеке он использует. Справедливости ради следует сказать, что большинство клиентов будут использовать настройки JRE по умолчанию, если только для этого не существует конкретного кода. Без каких-либо настроек обычно используется файл cacerts JRE (см. Подробности в JSSE Reference guide, customisation section). Вы также можете указать обычные свойства javax.net.ssl.* (используя -Djavax.net.ssl....=....); это должно быть сделано в файле сценария запуска каталинии (.bat или .sh в зависимости от платформы) в JAVA_OPTS. Это повлияет на значения по умолчанию, запущенные в этом экземпляре JRE, так что это может быть не ваш предпочтительный выбор (вы можете захотеть что-то более конкретное, которое влияет только на данный веб-приложение, но вам нужно знать, как реализован этот webapp или какие возможные варианты он может использовать). Настройки в вашем <Connector .../> переопределяют это, хотя (и настройки доверия не имеют значения, если вы также не хотите использовать проверку подлинности клиентского сертификата).

Если у вас есть несколько систем, вероятно, не стоит использовать самоподписанные сертификаты: каждый клиент должен будет импортировать все эти самозаверяющие сертификаты в свой магазин доверия. Вместо этого вы можете создать свой собственный ЦС и импортировать только этот сертификат ЦС. (В локальном развертывании достаточно одного верхнего уровня/корневого ЦС, без необходимости в промежуточных ЦС). OpenSSL's CA.pl - хороший скрипт для создания небольшого ЦС, но вы можете найти другие инструменты, такие как XCA или TinyCA more удобный. (Обратите внимание, что обычно можно использовать .p12 файлы непосредственно в Java, используя тип PKCS12 хранилищу, а не по умолчанию JKS. Для PKCS # 12 магазинов, пароль хранилища ключей и ключ/KeyManager пароль являются одинаковыми.)

С вы используете IP-адреса вместо имен, вы также должны знать, что Java follows RFC 2818 on IP address quite stricly (в отличие от многих браузеров). В частности, IP-адрес в CN вашего объекта Subject не будет работать: он должен быть включен в расширение альтернативного имени объекта (типа IPAddress, а не DNS-имя).


EDIT:

Во-первых, избавиться от этого имени хоста проверяющего: он вводит уязвимость к MITM атак для всех в HttpsURLConnection, который будет использовать этот верификатор по умолчанию, включая возможные подключения к внешним серверам. Вы можете исправить это, используя IP-адрес SAN.

Вот шаги, которые необходимо выполнить:

  • Создать свой CA (например, с XCA). Экспортируйте свой сертификат (не его закрытый ключ) в mycacert.pem.

  • Если ваше приложение может сделать HTTPS соединения с другими службами, скопируйте файл по умолчанию cacerts в новый файл mytruststore.jks (если приложение не делает любое другое соединение, не копировать файл, keytool создаст Это).

  • Импорт mycacert.pem в mytruststore.jks с keytool:

    keytool -import -keystore mytruststore.jks -alias my_alias_name -cert mycacert.pem 
    
  • Теперь у вас есть доверенные сертификаты, которые можно установить во всех ваших клиентах, которые должны будут говорить с этими серверами. (Возможно, вам придется выполнить эти шаги еще раз, если файл cacerts будет обновлен с помощью JRE.)

    • Настройте это доверительное хранилище у ваших клиентов. Здесь это делается в ваших сценариях Catalina в JAVA_OPTS: -Djavax.net.ssl.trustStore=... (и пароль). Помимо того факта, что эти параметры JVM находятся в запуске Catalina, они такие же, как и для других типов клиентов.
    • Избавьтесь от -Djavax.net.ssl.keyStore=... там, это будет использоваться только для аутентификации клиентского сертификата, и не всегда рекомендуется, чтобы веб-приложения использовали сертификат сервера, на котором они работают для аутентификации клиента.
  • Создайте сертификат с этим ЦС для каждого сервера, который вы хотите использовать. Убедитесь, что вы используете IP-адрес SAN, если хотите использовать IP-адреса. (Поскольку вы контролируете все, XCA должно позволить вам генерировать закрытый ключ и сертификат за один шаг, здесь нет необходимости в CSR, но вы могли бы, если хотите, а также подготовили профили для расширений веб-серверов, поскольку а также возможность добавления альтернативных имен объекта IP-адреса типа или другого.)

  • Экспортировать комбинацию сертификата и закрытого ключа в PKCS # 12 (например, server1.p12) для каждого сервера. Каждый сервер должен иметь свой собственный, не делить их. Вы сможете использовать это как "keystore keystore" в каждой конфигурации сервера.

    • Настройка это Хранилище ключи в каждом сервере в конфигурации соединителя (keystoreType="PKCS12", и keyPass и keystorePass должны быть идентичны при использовании PKCS # 12 магазинов).
    • Вам не нужны никакие настройки доверия в конфигурации вашего соединителя, если вы не используете аутентификацию сертификата клиента.

(Это может быть стоит использовать аутентификацию клиента сертификат, чтобы убедиться, что подключение к вашему серверу, по крайней мере исходить только от одного другого юридического лица исходя из того же центра сертификации, не хватает чего-то более точным, но доверенное хранилище настроить на разъеме должны содержать только сертификат ЦС, а не других, таким образом, создать совершенно новую для доверенных сертификатов, что.)

+0

Я обновил дополнительную информацию. Ваше заявление о IP-адресе и RFC 2818 вызвало мою память. Я нашел в нашем классе низкого уровня, который делает соединение, что мы перегружаем класс верификации имени хоста, чтобы всегда возвращать true. Так что, возможно, так мы всегда обошли это требование. Не очень хорошая практика, я уверен ... –

+0

Причиной выбора связи «сервер-сервер» является то, что люди перестанут думать с точки зрения клиента веб-браузера. Я согласен с вами в том, что клиент здесь - это запрос HttpURLConnection, сделанный из сервлета master tomcat. –

+0

Кстати, пытаетесь ли вы использовать аутентификацию сертификата клиента для этих подключений или выполняете ли клиентские веб-приложения другой тип аутентификации (если требуется) независимо от SSL/TLS? – Bruno

0

Чтобы ответить на ваш вопрос, я не думаю, что вам нужна цепочка сертификатов. Я уже использовал tomcat с самоподписанным сертификатом сервера и подключился к нему с другим самозаверяющим сертификатом клиента. Я не знаю о tomEE, но я думаю, что все будет так.

Чтобы помочь вам понять, что goining, я думаю об этих возможных отладочных действий:

  • перед входом в автоматизации, пытаются заставить все работать без сценариев. Создание правильной конфигурации будет проще.

  • убедитесь, что скрипт работает правильно: проверьте, соответствуют ли содержимое магазинов магазинам, и убедитесь, что файлы server.xml указывают на правильные.

  • Попробуйте протестировать серверы отдельно, используя аутентификацию клиента браузера, если сможете.

Прежде всего, убедитесь, что вам действительно нужно https между серверами. Если вы находитесь в защищенной области, вы, вероятно, используете безопасность и просто замедляете свое приложение.

+0

Когда вы подключились к другому собственному сертификату, было ли это с другого сервера? В браузере вы можете просто сказать: «да, пожалуйста, доверяй/импортируй этот сертификат». Когда два сервера пытаются связаться, если они еще не доверяют сертификату, вы получаете ошибку, которую я вижу. Разве это не так? –

+0

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

+0

@GuyBouallet Накладные расходы на использование SSL обычно довольно низки, если вы не используете большой объем запросов. Почему это необходимо для безопасности, потому что и приложение является «внутренним»? Глубокая защита, которая позволяет использовать низкие висячие фрукты, такие как включение SSL, всегда положительна, если нет бизнес-кейса, НЕ этого делать. – Matthew

0

How do I create self signed certificates that two tomcats will be happy with when using https between the tomcats?

Tomcat должен позволить вам сделать один из двух вещей. Сначала запускается частный PKI, или второй используется пинсет.


Чем проще ответ первый: а pinset представляет собой набор доверенных сертификатов или открытых ключей для идентификации хоста или набор хостов. Это сертификат или открытый ключ с мультипликатором.В этом случае вы хотите взять 3 или 4 сертификата и применить их к каждому серверу. Затем, когда пользователи сообщают друг другу, они неявно доверяют сертификату партнера.

Он не отображается. Tomcat (или IIS или Apache) позволяет указать пинсет. То есть вы не можете указать коллекцию самозаверяющих сертификатов для доверия. Таким образом, вам придется использовать частный PKI.


Более сложный ответ - запустить частный PKI. Нет ничего сложного в управлении частной PKI. Трудность заключается в ее реализации, потому что для этого есть много. Нет никакой серебряной пули, чтобы заставить ее работать, потому что вам нужна частная PKI, и вам нужно настроить серверы для ее использования.


На вопрос, «Как я могу использовать свой собственный CA подписать каждый сертификат», смотри, например, How To Setup a CA или даже Signing a certificate with my CA и Create my CA how to make a trusted self certified....


Я не могу помочь вам с конфигурацией Tomcat. Но вот шаги, которые нужно сделать программно в OpenSSL, если вы строили клиент и сервер. Здесь, "клиент" и "сервер" означает роль сервера Tomcat берет (каждый берет обе роли):

  • Client

    • вызов SSL_CTX_load_verify_locations с вашим CA
    • вызова SSL_CTX_set_default_verify_paths на контекст
    • вызов SSL_CTX_set_verify с SSL_VERIFY_PEER
  • Сервер

    • вызов SSL_CTX_use_certificate_chain_file
    • вызов SSL_CTX_use_PrivateKey_file
    • вызов SSL_CTX_set_verify с SSL_VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT

Действуя как клиент, сервер Tomcat должен знать доверенный корневой организации. Вот что SSL_CTX_load_verify_locations и SSL_CTX_set_default_verify_paths выполнить.

При работе в качестве клиента SSL_CTX_set_verify гарантирует, что сервер Tomcat проверяет идентификацию партнера (по модулю отсутствия проверки имени хоста в OpenSSL).

При работе в качестве сервера сервер Tomcat должен знать сертификат для отправки и закрытый ключ для подписки. Вот что SSL_CTX_use_certificate_chain_file и SSL_CTX_use_PrivateKey_file сделать.

При работе в качестве сервера сервер Tomcat требует взаимной аутентификации. Это то, что SSL_CTX_set_verify с SSL_VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT делает.

Я не знаю, как это сделать в конфигурации Tomcat.

+0

ах вы описываете, что моя неделя чувствовала с этим простым Фраза «... поднимите их в Tomcat ...». Спасибо за ответ. Частная дискуссия PKI - это не то, что я последую, но я не думаю, что мне нужно. Интересно обсуждение использования openssl api. Поток, безусловно, помогает укрепить мое понимание событий. Благодарю. –

+0

Приложения Java, использующие JSSE (включая Tomcat и webapps, запущенные внутри него), используют хранилище доверия для хранения доверенных сертификатов. Это могут быть конкретные сертификаты конечного объекта или сертификаты CA, поэтому вы можете использовать определенную коллекцию сертификатов, если хотите. Я также считаю, что поддерживать собственный PKI/CA не намного сложнее, чем напрямую обращаться к 3+ самозаверяющим сертификатам. (Также указывая, что Tomcat - это всего лишь контейнер клиента, который использует JSSE API Java, поэтому функции OpenSSL не помогут.) – Bruno

Смежные вопросы