如何通过http-header区分http和https

时间:2013-12-24 16:56:14

标签: c# ssl proxy http-headers tcplistener

我在C#中用TcpListener编写代理。

此代理侦听用户发送请求的端口。当接受用户请求时,它将解析请求标头并找到主机名。然后它为主机服务器创建TcpClient

这就是问题所在。当http请求到来时,它应该连接服务器的端口80;当https请求到来时,它应该连接服务器的端口443。但我不知道如何区分http请求和https请求。

一句话的问题:如何知道这是TcpListener接受的http请求或https请求?

非常感谢!

2 个答案:

答案 0 :(得分:0)

标题完全加密。通过网络“清除”的唯一信息与SSL设置和D / H密钥交换有关。此交换经过精心设计,不会向窃听者提供任何有用的信息,一旦发生,所有数据都会被加密。

更新顺便说一下SSL协商之后,普通的HTTP标头会在加密流中传播,所以两者之间确实没有区别。

答案 1 :(得分:0)

你已经介入了一个长期困扰网络服务器管理员的问题。

这是过程:

  1. Web浏览器与Web服务器上的特定IP建立TCP连接。
  2. Web服务器知道从哪个IP获取连接,知道该IP仅用于secure.example.com,因此加载了secure.example.com的SSL证书。
  3. 网络服务器和网络浏览器协商SSL连接。
  4. Web浏览器向SSL管道发送vanilla HTTP标头,其中包含指示要使用的虚拟主机的“HOST:secure.example.com”行。
  5. Web服务器处理请求,并使用通过SSL管道发送的vanilla HTTP标头发送响应。
  6. Web服务器必须决定在具有任何HTTP标头之前使用哪个虚拟主机。这是因为它必须首先协商SSL连接,并且必须首先知道要使用哪个证书。 vanilla解决方案是使用基于IP的虚拟主机 - 在IP地址X上运行Web服务器;每当服务器收到发送到地址X的请求时,它就知道该请求属于该地址的已配置vhost。

    该方案的问题在于服务器必须为其运行的每个安全网站分别拥有IP地址。这可能是许多很多IP地址,并且成本高昂或不切实际。

    单步执行Server Name Indication。当Web浏览器正在协商与Web服务器的SSL连接时,Web浏览器在SSL协商信息中包含它要连接的主机名。现在,Web服务器可以使用该信息来执行基于名称的普通虚拟主机,因此Web服务器可以在一个IP地址上运行一千个不同的安全网站,每个网站都有自己的SSL证书。一切都在世界上是正确的。

    您希望了解这一点,这意味着您必须了解SSL / TLS协商阶段,解析服务器名称信息,并将请求转发到正确的Web服务器。

    您的新流程看起来像这样:

    1. Web浏览器与代理建立TCP连接。
    2. 代理开始记录SSL交换。
    3. Web浏览器开始进行SSL协商,并作为其中一部分,向下发送服务器名称信息。
    4. 代理解析服务器名称信息,决定哪个Web服务器应该处理请求,并将SSL协商信息转发给Web服务器。
    5. 代理人不参与谈判;它读取SNI,但完全是“传递”。
    6. 网络浏览器和服务器完成SSL协商,服务器选择正确的虚拟主机,浏览器为请求发送vanilla http标头。
    7. Web服务器通过SSL连接读取vanilla标头,并处理请求。
    8. 既然已经说过了,你可能会发现在SSL连接协商中坚持下去可能比它的价值更麻烦。事实证明,其他一些人已经有了和你一样的想法,并且已经实现了一些似乎完全正在尝试做的程序 - 搜索“http sni proxy” - 我想出了这个:{ {3}}