The Apache Tomcat 5.5 Servlet/JSP Container – Realm Configuration HOW-TO

Additional notes

JNDIRealm operates according to the following rules:

Apache tomcat 9 (9.0.65) – security considerations

By default, a non-TLS, HTTP/1.1 connector is configured on port 8080.
Connectors that will not be used should be removed from server.xml.

AJP Connectors should only be used on trusted networks or be
appropriately secured with a suitable secret attribute.

AJP Connectors block forwarded requests with unknown request
attributes. Known safe and/or expected attributes may be allowed by
configuration an appropriate regular expression for the
allowedRequestAttributesPattern attribute.

The address attribute may be used to control which IP
address a connector listens on for connections. By default, a connector
listens on all configured IP addresses.

The allowTrace attribute may be used to enable TRACE
requests which can be useful for debugging. Due to the way some browsers
handle the response from a TRACE request (which exposes the browser to an
XSS attack), support for TRACE requests is disabled by default.

The discardFacades attribute set to true
will cause a new facade object to be created for each request. This
reduces the chances of a bug in an application exposing data from one
request to another.

The encodedSolidusHandling attribute allows
non-standard parsing of the request URI. Setting this attribute to a
non-default value when behind a reverse proxy may enable an attacker to
bypass any security constraints enforced by the proxy.

The maxPostSize attribute controls the maximum size
of a POST request that will be parsed for parameters. The parameters are
cached for the duration of the request so this is limited to 2MB by
default to reduce exposure to a DOS attack.

The maxSavePostSize attribute controls the saving of
the request body during FORM and CLIENT-CERT authentication and HTTP/1.1
upgrade. For FORM authentication, the request body is cached for the
duration of the authentication (which may be many minutes) so this is
limited to 4KB by default to reduce exposure to a DOS attack.

The maxParameterCount attribute controls the
maximum number of parameter and value pairs (GET plus POST) that can
be parsed and stored in the request. Excessive parameters are ignored.
If you want to reject such requests, configure a
FailedRequestFilter.

The xpoweredBy attribute controls whether or not the
X-Powered-By HTTP header is sent with each request. If sent, the value of
the header contains the Servlet and JSP specification versions, the full
Tomcat version (e.g. Apache Tomcat/9.0), the name of
the JVM vendor and
the version of the JVM. This header is disabled by default. This header
can provide useful information to both legitimate clients and attackers.

The server attribute controls the value of the Server
HTTP header. The default value of this header for Tomcat 4.1.x to
8.0.x is Apache-Coyote/1.1. From 8.5.x onwards this header is not set by
default. This header can provide limited information to both legitimate
clients and attackers.

The SSLEnabled, scheme and
secure attributes may all be independently set. These are
normally used when Tomcat is located behind a reverse proxy and the proxy
is connecting to Tomcat via HTTP or HTTPS. They allow Tomcat to see the
SSL attributes of the connections between the client and the proxy rather
than the proxy and Tomcat. For example, the client may connect to the
proxy over HTTPS but the proxy connects to Tomcat using HTTP. If it is
necessary for Tomcat to be able to distinguish between secure and
non-secure connections received by a proxy, the proxy must use separate
connectors to pass secure and non-secure requests to Tomcat. If the
proxy uses AJP then the SSL attributes of the client connection are
passed via the AJP protocol and separate connectors are not needed.

The tomcatAuthentication and
tomcatAuthorization attributes are used with the
AJP connectors to determine if Tomcat should handle all authentication and
authorisation or if authentication should be delegated to the reverse
proxy (the authenticated user name is passed to Tomcat as part of the AJP
protocol) with the option for Tomcat to still perform authorization.

The requiredSecret attribute in AJP connectors
configures shared secret between Tomcat and reverse proxy in front of
Tomcat. It is used to prevent unauthorized connections over AJP protocol.

Connecting to the directory

The realm’s connection to the directory is defined by the
connectionURL configuration attribute. This is a URL
whose format is defined by the JNDI provider. It is usually an LDAP
URL that specifies the domain name of the directory server to connect
to, and optionally the port number and distinguished name (DN) of the
required root naming context.

If you have more than one provider you can configure an
alternateURL. If a socket connection can not be
made to the provider at the connectionURL an
attempt will be made to use the alternateURL.

Quick start

To set up Tomcat to use JNDIRealm, you will need to follow these steps:

Realm element attributes

To configure a JNDIRealm, you must create a <Realm>
element and nest it in your $CATALINA_HOME/conf/server.xml file,
as described above. The attributes supported
by this Realm are listed in the Realm configuration
documentation.

Другие опции keytool

Просмотреть public-ключ:

$ keytool -printcert -file ../.ssh/setevoy-tc.cer -storetype PKCS12

Просмотреть все ключи в хранилище:

$ keytool -list -v -keystore ../.ssh/trustcacerts-teamcity.jks

Просмотреть только определённый alias:

$ keytool -list -v -keystore ../.ssh/trustcacerts-teamcity.jks -alias setevoy

Удалить ключ из хранилища:

$ keytool -delete -alias setevoy -keystore ../.ssh/trustcacerts-teamcity.jks

Изменить пароль хранилища:

$ keytool -storepasswd -new newpassword -keystore ../.ssh/trustcacerts-teamcity.jks

Добавить клиентский сертификат в хранилище:

$ keytool -importcert -file setevoy-tc.cer -alias setevoy -keystore ../.ssh/trustcacerts-teamcity.jks

Ссылки по теме

Импорт ssl-сертификата в браузер

Передаём файл setevoy-tc.p12, и импортируем его в браузер.

Открываем Настройки Advanced > Certificates > View Certificates> Your Certificates:

Жмём кнопку Import и выбираем клиентский сертификат:

Указываем пароль ключа:

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

Готово.

Настройка ssl для tomcat

Пару недель назад столкнулся с проблемой — стоит TomCat на сервере(windows 2008), ставлен не мной, мало того, я даже не видел как его ставили. Нужно сделать авторизацию по SSL протоколу. Раньше никогда не настраивал веб-сервера ни на винде ни на никсах, а решать нужно в кратчайшие сроки — 3 дня. Решил спросить у гугла с яндексом и нашел куче статей как сделать SSL шифрование канала и одну малопонятную о «двухфазной авторизации». Мучался все 3 дня и на исходе срока получил решение (как всегда светлая идея пришла с великого бодуна). Теперь подробнее:

как устанавливать TomCat описывать не буду, т.к. таких статей валом.

Для начала создаём хранилище (keystore) с ключом:

Наберем в коммандной строке следующий код:


>keytool -genkey -alias tomcat -keyalg RSA -keystore mystore -validity 999 -keysize 512

Здесь:

— tomcat — имя псевдонима

— keyalg — алгоритм формирования ключа

— keystore — имя хранилища

— validity – Срок действия сертификата

— keysize – Размер ключа

В результате на консоле увидите следующее:

Enter keystore password:

mystorepassword

What is your first and last name?

[Unknown]:

firstname lastname

What is the name of your organizational unit?

[Unknown]:

organizationalunit

What is the name of your organization?

[Unknown]:

organization

What is the name of your City or Locality?

[Unknown]:

city

What is the name of your State or Province?

[Unknown]:

state

What is the two-letter country code for this unit?

[Unknown]:

ru

Is CN=firstname lastname, OU=organizationalunit, O=organization, L=city, ST=state, C=ru correct?

[no]:

yes

Enter key password for (RETURN if same as keystore password):

То что выделено жирным — вводиться вручную, запросы появляются построчно.

Обратите внимание на то, что для ключа пароль не был введён (в этом случае используется пароль хранилища).

Конфигурируем SSL-коннектор (фрагмент server.xml):
Находим запись


<!-- Define a SSL HTTP/1.1 Connector on port 443
         This connector uses the JSSE configuration, when using APR, the 
         connector should be using the OpenSSL style configuration
         described in the APR documentation -->

и ниже нее добавляем


<Connector port="8443" SSLEnabled="true" maxHttpHeaderSize="8192" 
        maxThreads="150" minSpareThreads="25" maxSpareThreads="200"
        enableLookups="false" disableUploadTimeout="true"         
        acceptCount="100" scheme="https" secure="true"
         clientAuth="false" sslProtocol="TLS"
         keystoreFile="mystore" keystorePass="mystorepassword" keystoreType="JKS"
         keyAlias="tomcat"/>

Находим строку:


<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />

— по умолчанию 27 строка, закомментируем её.

Так же, если у вас есть вот такая строка:


<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />

тоже её комментируем.

Теперь кидаем файл

mystore

из папки с явой в корень томката, если кинуть не в корень то нужно изменить строку

 keystoreFile="mystore"

на

 keystoreFile="/ваш путь/mystore"

Строка

keystorePass="mystorepassword"

— «mystorepassword», это ваш пароль указанный при создании хранилища с ключем.

Запускаем Tomcat, SSL- шифрование уже работает.

«Двухфазный» SSL — авторизация на сайте по сертификату

Механизм проверки очень прост: необходимо, чтобы у сервера нашелся ключ, subject distinguished name которого будет совпадать с issuer distinguished name проверяемого ключа (при этом клиент не обязательно должен обладать таким ключом, т. к. можно в диалоговом режиме подтвердить доверие). Когда используются ключи, выданные центром сертификации, у нас уже есть публичный ключ центра и свой, подписанный этим центром. В случае с самоподписанным ключом (именно такие ключи по создаёт keytool) необходимо, чтобы публичный ключ используемый клиентом, был в truststore сервера.

Ключ сервера мы генерировали выше, теперь сделаем ключ клиента
Наберем в консоли следующую команду


keytool -genkey -alias client -keyalg RSA -keystore myclientstore -storetype PKCS12 -validity 999 -keysize 512

на консоли появится следующее:

Enter keystore password:

myclientstorepassword

What is your first and last name?

[Unknown]:

client

What is the name of your organizational unit?

[Unknown]:

orgunit

What is the name of your organization?

[Unknown]:

org

What is the name of your City or Locality?

[Unknown]:

locality

What is the name of your State or Province?

[Unknown]:

state

What is the two-letter country code for this unit?

[Unknown]:

RU

Is CN=client, OU=orgunit, O=org, L=locality, ST=state, C=RU correct?

[no]:

yes

Enter key password for (RETURN if same as keystore password):

все по аналогии с генерацией ключа сервера, появился только параметр

 -storetype

. Этот параметр указывает тип хранилища поддерживаемое нашим браузером, если не знаете точно какой тип у вас — не меняйте, этот подходит для всех (проверено электроникой!!!)

 -keystore

— здесь это уже хранилище сертификатов клиентов.

Следующий этап — помещаем публичный ключ в доверенное хранилище( truststore) сервера. Для этого экспортируем его из полученного хранилища(myclientstore) в файл clientcert:

Введем в консоли следующую комманду:

keytool -export -alias client -keyalg RSA -keystore myclientstore -storetype PKCS12 -file clientcert 

в ответ увидим:

Enter keystore password: myclientstorepassword
Certificate stored in file ” clientcert “

Здесь вопрос «Enter keystore password: » просит не новый пароль, а тот, который мы ввели при формировании «myclientstore»
Тут думаю все уже понятно, т.к. всепараметры рассмотрены выше. А результат — файл clientcert.
Полученный файл импортируем в новое хранилище для сервера (это и будет truststore):
Введем в консоли комманду


keytool -import -alias client -keyalg RSA -keystore mytruststore -storetype JKS -file clientcert 

Нас спросят

Enter keystore password: mytruststorepassword

если ответили правильно то увидим

Owner: CN=client, OU=orgunit, O=org, L=locality, ST=state, C=RU
Issuer: CN=client, OU=orgunit, O=org, L=locality, ST=state, C=RU
Serial number: 462a2361
Valid from: Sat Apr 21 18:44:49 MSD 2007 until: Fri Jul 20 18:44:49 MSD 2007
Certificate fingerprints:
MD5: 78:55:83:13:3A:4F:DB:CA:1A:60:5E:A4:87:1D:EC:93
SHA1: 7A:A7:7C:C6:71:2B:82:74:9C:4F:C7:3D:FA:14:AD:2A:E5:BF:39:2F

последний вопрос

Trust this certificate? [no]: yes

а в ответ

Certificate was added to keystore

Здесь вопрос «Enter keystore password: » просит не новый пароль, а тот, который мы ввели при формировании «mytruststore»
Ну вот, все сертификаты сформированы и помещены в доверенные хранилища.
Теперь надо сказать серверу что их нужно использовать, дополняем конфигурацию сервера. Теперь конфигурация SSL-коннектора выглядит так:


<Connector port="8443" SSLEnabled="true" maxHttpHeaderSize="8192" 
maxThreads="150" minSpareThreads="25" maxSpareThreads="200"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="mystore" keystorePass="123456" keystoreType="JKS"
keyAlias="tomcat"
truststoreFile="mytruststore" truststorePass="123456" truststoreType="JKS"/>

Пути до mytruststore,mystore как и было уже сказано можно менять, не забудьте заодно поменять и значения паролей 🙂

Если в trustedstore нужно добавить сторонний сертификат используйте следующий код:

keytool -import -mytruststore -keystore mystore -alias tomcat -file clientcert

Если в trustedstore нужно удалить сертификат используйте следующий код:

keytool -delete -mytruststore -keystore mystore -alias tomcat -file clientcert

Копируем файлы mytruststore и mystore в корень томката или в папки указаные в параметрах коннектора (keystoreFile и truststoreFile) ели вы их изменили.
Импортируем myclientstore в используемый браузер в сертификаты. Т.е. на примере IE:
Сервис-> Свойства обозревателя->Содержание->Сертификаты->Импорт->Далее->Обзор->Все файлы->Находим папку с явой (по умолчанию там сохраняются новые генерированные файлы), выбираем наш myclientstore, -> Далее-> вводим пароль который мы задавали при генерации myclientstore и все!
Перезапускаем сервер.
Сейчас если набрать https :// localhost:8443 — сервер потребует сертификат, но если набрать
http ://localhost:8080 откроется та же страница, что и в первом случае, но без всякой защиты. Для того чтобы все запросы перенаправлялись с http на https в web.xml добавляем
до закрытия web-app:


<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Context</web-resource-name>
 <url-pattern>/*</url-pattern>
</web-resource-collection>
<!—если ваш сервер требует аутерификации -->
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

Перезапускаем сервер, вуаля – все работает!
Надеюсь эта статья будет более понятна чем остальные, т.к. тут я собрал все крупицы знаний найденных в интернете и опыт полученный мною в момент жесткого занятия любовью с SSL и TomCat.

Похожее:  Token, refresh token и создание асинхронной обертки для REST-запроса / Хабр

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *