У нас есть веб-сервер Apache, который настроен на использование SNI с GnuTLS. Все работает, и сервер доставляет клиентам правильный сертификат.
За исключением случаев прямого подключения с Apache-хоста.
# curl -v https://example.com
* About to connect() to example.com port 443 (#0)
* Trying xxx.xxx.xxx.xxx...
* connected
* Connected to example.com (xxx.xxx.xxx.xxx) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
* Closing connection #0
curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
Та же самая командная строка работает при запуске с другого компьютера.
После некоторого тестирования я обнаружил, что проблема возникает, когда исходный IP-адрес и IP-адрес назначения совпадают.
# curl -v --interface 127.0.0.1 https://example.com
работает отлично, и рукопожатие TLS проходит успешно.
На сервере настроено два интерфейса. Пока IP-адрес интерфейса не совпадает с IP-адресом разрешенного имени хоста, все работает.
На данный момент мне удалось найти обходной путь для проблемы, но я не могу понять, что вызывает такое поведение.
~# lsb_release -si -sr
Debian
7.8
~# apache2 -v
Server version: Apache/2.2.22 (Debian)
Server built: Dec 23 2014 22:48:29
~# gnutls-cli -v
gnutls-cli (GnuTLS) 2.12.20
Packaged by Debian (2.12.20-8+deb7u3)
~# host example.com
example.com has address xxx.xxx.xxx.xxx
~# ifconfig |grep inet -B1
eth0 Link encap:Ethernet HWaddr 00:aa:bb:cc:dd:ee
inet addr:yyy.yyy.yyy.yyy Bcast:yyy.yyy.yyy.zzz Mask:255.255.255.248
--
eth1 Link encap:Ethernet HWaddr 00:aa:bb:cc:dd:ef
inet addr:xxx.xxx.xxx.xxx Bcast:xxx.xxx.zzz.zzz Mask:255.255.0.0
--
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
~# cat ports.conf
Listen xxx.xxx.xxx.xxx:443
Listen yyy.yyy.yyy.yyy:443
Listen xxx.xxx.xxx.xxx:80
Listen yyy.yyy.yyy.yyy:80
NameVirtualHost xxx.xxx.xxx.xxx:443
NameVirtualHost yyy.yyy.yyy.yyy:443
NameVirtualHost xxx.xxx.xxx.xxx:80
NameVirtualHost yyy.yyy.yyy.yyy:80
~# cat sites-enabled/example.com.conf
<VirtualHost xxx.xxx.xxx.xxx:80>
DocumentRoot "/var/www/com.example"
ServerName example.com
Redirect permanent / https://example.com/
ErrorLog ${APACHE_LOG_DIR}/example.com.error.log
CustomLog ${APACHE_LOG_DIR}/example.com.access.log combined
<Directory "/var/www/com.example">
allow from all
Options +Indexes
</Directory>
</VirtualHost>
<VirtualHost xxx.xxx.xxx.xxx:443>
GnuTLSEnable on
GnuTLSSessionTickets on
GnuTLSPriorities SECURE128:-VERS-SSL3.0:+COMP-DEFLATE
DocumentRoot "/var/www/com.example"
ServerName example.com
ErrorLog ${APACHE_LOG_DIR}/example.com.error.log
CustomLog ${APACHE_LOG_DIR}/example.com.access.log combined
GnuTLSCertificateFile /etc/ssl/certs/example.com.pem
GnuTLSKeyFile /etc/ssl/private/example.com.key
<Directory "/var/www/com.example">
allow from all
Options +Indexes
</Directory>
</VirtualHost>