openssl s_client -connect默认为子域名?

时间:2013-12-29 08:01:31

标签: android linux apache ssl openssl

我花了最近两天试图找出为什么我的Android应用程序在使用以下代码连接到我的网站时出现“无对等证书”异常错误:

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("https://mysite.co.uk/android/login.php");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response = httpclient.execute(httppost, responseHandler);

我使用了SSL Labs检查程序,我的证书通过了A级,没有SSL链问题(我在这里读了很多帖子声称这是问题)。无论如何,认为它是android的错误我尝试了许多不同的建议。

我发现了在我的服务器中输入以下命令的建议:

openssl s_client -connect mysite.co.uk:443

查看结果时,它打印出我设计网站的自签名证书!显然这不是预期的!

以下是我的主站点(域和www)的三个虚拟主机配置文件,然后是设计站点

mysite.co.uk.conf

# domain: mysite.co.uk
# public: /home/user/public/mysite.co.uk/public

<VirtualHost *:80>
  ServerName mysite.co.uk
  ServerAlias *.mysite.co.uk
  RedirectMatch permanent /(.*) https://mysite.co.uk/$1
</VirtualHost>

<VirtualHost *:443>

  Header always set Strict-Transport-Security "max-age=63072000;"

  SSLEngine On
  SSLCertificateFile /etc/apache2/ssl/mysite.co.uk/mysite.co.uk.crt
  SSLCACertificateFile /etc/apache2/ssl/mysite.co.uk/gs_intermediate_ca.crt

  <Directory />
    Options FollowSymLinks
    AllowOverride None
  </Directory>

  <Directory "/home/user/public/mysite.co.uk/public">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  # Admin email, Server Name (domain name), and any aliases
  ServerAdmin admin@mysite.co.uk
  ServerName mysite.co.uk

  # Index file and Document Root (where the public files are located)
  DirectoryIndex index.html index.php
  DocumentRoot /home/user/public/mysite.co.uk/public

  # Log file locations
  LogLevel warn
  ErrorLog  /home/user/public/mysite.co.uk/log/error.log
  CustomLog /home/user/public/mysite.co.uk/log/access.log combined
</VirtualHost>

www.mysite.co.uk.conf

# domain: www.mysite.co.uk
# public: /home/user/public/mysite.co.uk/public

<VirtualHost *:80>
  ServerName www.mysite.co.uk
  ServerAlias *.www.mysite.co.uk
  RedirectMatch permanent /(.*) https://www.mysite.co.uk/$1
</VirtualHost>

<VirtualHost *:443>

  Header always set Strict-Transport-Security "max-age=63072000;"

  SSLEngine On
  SSLCertificateFile /etc/apache2/ssl/mysite.co.uk/www.mysite.co.uk.crt
  SSLCACertificateFile /etc/apache2/ssl/mysite.co.uk/gs_intermediate_ca.crt

  <Directory />
    Options FollowSymLinks
    AllowOverride None
  </Directory>

  <Directory "/home/user/public/mysite.co.uk/public">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  # Admin email, Server Name (domain name), and any aliases
  ServerAdmin admin@mysite.co.uk
  ServerName www.mysite.co.uk

  # Index file and Document Root (where the public files are located)
  DirectoryIndex index.html index.php
  DocumentRoot /home/user/public/mysite.co.uk/public

  # Log file locations
  LogLevel warn
  ErrorLog  /home/user/public/mysite.co.uk/log/error.log
  CustomLog /home/user/public/mysite.co.uk/log/access.log combined
</VirtualHost>

design.mysite.co.uk.conf

# domain: design.mysite.co.uk
# public: /home/user/public/mysite.co.uk/design/public

<VirtualHost *:80>
  ServerName design.mysite.co.uk
  ServerAlias *.design.mysite.co.uk
  RedirectMatch permanent /(.*) https://design.mysite.co.uk/$1
</VirtualHost>

<VirtualHost *:443>

  SSLEngine On
  SSLCertificateFile /etc/apache2/ssl/design.mysite.co.uk/apache.crt
  SSLCertificateKeyFile /etc/apache2/ssl/design.mysite.co.uk/apache.key

  <Directory />
    Options FollowSymLinks
    AllowOverride None
  </Directory>

  <Directory "/home/user/public/mysite.co.uk/design/public">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  # Admin email, Server Name (domain name), and any aliases
  ServerAdmin contact@mysite.co.uk
  ServerName  design.mysite.co.uk

  # Index file and Document Root (where the public files are located)
  DirectoryIndex index.html index.php
  DocumentRoot /home/user/public/mysite.co.uk/design/public

  # Log file locations
  LogLevel warn
  ErrorLog  /home/user/public/mysite.co.uk/log/error.log
  CustomLog /home/user/public/mysite.co.uk/log/access.log combined
</VirtualHost>

这也位于我的apache配置文件

SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLCACertificateFile /etc/apache2/ssl/mysite.co.uk/gs_intermediate_ca.crt
SSLStaplingCache shmcb:/var/run/ocsp(128000)

SSLProtocol -ALL +TLSv1 +TLSv1.1 +TLSv1.2
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH
SSLInsecureRenegotiation off

当我跑步时:

sudo a2dissite design.mysite.co.uk
sudo service apache2 restart

然后运行:

openssl s_client -connect mysite.co.uk:443

然后我获得了mysite.co.uk的证书详细信息,我的Android应用程序再次运行。我在这里错过了什么吗?为什么我的服务器默认为设计网站?

2 个答案:

答案 0 :(得分:5)

因为您在同一IP地址后面有多个主机名,并且每个主机名都有自己的证书,您需要使用SNI(服务器名称指示)。这将在SSL握手中发送所需的主机名。要使用openssl对此进行测试,您必须使用-servername参数,例如

  

openssl s_client -servername mysite.co.uk -connect mysite.co.uk:443

虽然所有当前浏览器默认使用SNI,但默认情况下android似乎不使用SNI,因此可能只从默认服务器获取证书。我自己不是一个Android程序员,但有几个关于SNI与stackoverflow和其他地方的android的讨论表明,它可能是可能的,但可能不是DefaultHTTPClient类。

答案 1 :(得分:0)

我认为您的问题是您在两个不同的域上使用SSL,这两个域共享相同的IP地址。

由于SSL是在Web服务(HTTP)之前完成的,因此SSL无法知道用户是否正在访问design.mysite.co.ukmysite.co.uk,它只知道它正在访问IP A上的网站,所以它正在处理它所拥有的证书,如果我正确读取的是mysite.co.uk

然后HTTP会话启动,浏览器确认提供的证书是否与URL匹配,当您访问design.mysite.co.uk时,浏览器确认它是否匹配。

解决方案:

获取另一个IP地址并将其提供给其中一个站点,从而将您的网站的SSL访问权限分成两个单独的IP地址,每个IP地址将提供差异证书。