例如:我有两个 URL
https:// www.abc.net => maps to https://192.168.0.100:5000
https:// www.def.net => maps to https://192.168.0.100:5001
两台服务器都在同一台 Windows 10 PC 上运行。
我可以知道如何实现这个目标吗?
答案1
转发端口根据特定端口将流量转发到主机。此路由不使用任何其他信息(即任何“目标”URL)。要将特定 URL 路由到特定的本地服务,您可能需要反向代理。
简而言之,反向代理接收来自互联网的请求并将其转发到内部网络中的服务器。重要的是,它通常可以根据收到的特定 URL 执行此操作。
软件
对于设置反向代理,可能满足您需求的两种常见解决方案是阿帕奇和Nginx。两者都是开源 Web 服务器,并且都可以配置为反向代理(通过 Apache虚拟主机或 Nginx服务器块, 分别)。
带有 SSL 的 Apache 的 Windows 版本可从Apache 休息室并且 Windows 版本的 Nginx(也支持 SSL)可直接从Nginx。
注意事项
关于反向代理需要考虑的一件事是,客户端和本地服务之间的通信可能会受到反向代理本身可以传递的内容的限制。
在某些情况下,在客户端和本地服务之间建立直接链接可能是更好的选择(甚至可能是必要的)。例如,假设路由器将端口5000
和映射5001
到内部主机(例如192.168.0.100
),并且example.com
和example.net
指向该路由器,则这些端口/服务可能会以例如example.com:5000
和的形式在外部可用example.net:5001
。
这种方法的基本缺点是 DNS 不使用端口信息,因此example.net:5000
也会example.com:5001
映射到相同的服务。但是,对于某些类型的通信,这可能是唯一的选择。
反向代理示例(概述)
假设您决定使用 Apache 或 Nginx 作为反向代理,虽然各个配置步骤可能不同,但基本内容大致相同:
- 安装您喜欢的解决方案(例如 Apache 或 Nginx)。
- 执行一些基本配置(以便它可以响应HTTP请求)。
- 启用/配置任何适当的代理功能(根据需要)。
- 配置 SSL 支持(因为根据您的原始问题,您似乎希望响应 HTTPS URL)。
- 使用虚拟主机(Apache)或服务器块(Nginx)为您希望代理数据的域创建主机,然后配置这些主机以在客户端和所需的本地服务之间传递数据。
虽然下面的示例仅涵盖使用 Apache 作为反向代理,但对于 Nginx,上面概述的步骤通常可以在网上找到。
反向代理示例(Apache)
假设
以下是在 Windows 上从头开始将 Apache 设置为反向代理的简单示例。请注意,除了将请求从基本 URL A 发送到本地服务 B 之外,它并不旨在解决一般 Apache、SSL 或反向代理配置的任何细节。
它还假设:
反向代理(即 Apache)正在与当前服务(例如
192.168.0.100
)安装在同一本地服务器上,在任何虚拟机之外。该主机上的端口
80
(HTTP) 或(HTTPS)上没有运行任何服务。443
DNS 已为任何域正确设置(例如,
example.com
已example.net
指向适当的路由器/本地网络)。您希望代理的域名可以使用 SSL 证书和密钥。
您希望代理的本地服务本身不使用 HTTPS(SSL)。
端口转发已正确设置(即端口
5000
和5001
已映射到192.168.0.100
)。请注意,对于此示例,端口80
和443
也需要映射到具有反向代理的主机(再次举例192.168.0.100
)。
安装
从 Apache Lounge 下载 Apache并解压。在本例中,将标记为 的文件夹
Apache24
放在C:\
本地服务器上(即C:\Apache24
)192.168.0.100
。在这种情况下,Apache 构建为 32 位(例如
httpd-2.4.43-win32-VS16.zip
)或 64 位(例如httpd-2.4.43-win64-VS16.zip
)并不重要,因此您可以选择其中之一。从同一页面(适用
vc_redist_x86
于httpd-2.4.43-win32-VS16.zip
或)下载适用于 Visual Studio 2015-2019 的匹配 Microsoft Visual C++ Redistributable 。双击可执行文件进行安装。vc_redist_x64
httpd-2.4.43-win64-VS16.zip
如果安装程序显示“修复”现有可再发行组件安装的选项,那么您可以安全地完全取消该安装,因为您已经安装了该可再发行组件的适当版本。
可以通过
httpd -k install -n "Apache2.4"
从命令行运行(httpd.exe
位于 ex. 下C:\Apache24\bin
)将 Apache 安装为 Windows 中的服务。如果您决定这样做,请使用管理命令提示符并不要使用 以外的服务名称Apache2.4
。
配置(概述)
编辑 Apache 的任何配置文件时,应使用纯文本编辑器(如 Windows 记事本)或第三方编辑器(如记事本++。
在下述步骤中,“取消注释”表示删除
#
配置文件中一行或多行前面的任何前导符号,“注释掉”表示#
在配置文件中一行或多行前面添加前导符号:# This line is commented out This line is uncommented
在下面的各个配置示例中,
[...]
只是一个占位符,旨在指示“这里有更多不相关的东西”(即,它实际上并不进入配置文件)。下面列出的大多数配置步骤都是在
httpd.conf
(例如C:\Apache24\conf\httpd.conf
)中完成的,因为它是 Apache 的主要配置文件。对于一般的 SSL 支持和实现反向代理设置所需的虚拟主机,还需要在
httpd-ssl.conf
(例如C:\Apache24\conf\extra\httpd-ssl.conf
)和httpd-vhosts.conf
(例如)中进行一些更改。C:\Apache24\conf\extra\httpd-vhosts.conf
需要保存配置文件并重新启动 Apache(假设它正在运行)以使任何配置更改生效。
HTTP 配置
Apache 已经设置好处理基本的 HTTP 请求,特别是当放置在C:\Apache24
(Apache Lounge 版本的 Apache 假定它位于的默认目录中)时。但是,如果未取消注释ServerName
中的默认指令,则会发出警告httpd.conf
。因此,请进行以下更改:
例如 httpd.conf
[...]
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
ServerName www.example.com:80
对于此示例,此指令的值ServerName
无关紧要,只要它不是您希望代理的域之一(即保留它www.example.com:80
是可以的)。
启用代理模块
Apache 附带了许多可选模块,这些模块可启用 Apache 中的附加功能,例如将传入请求代理到本地服务的功能。这些“额外”模块已列出,httpd.conf
但通常默认被禁用(注释掉)。
您没有提到您尝试代理的服务,但您至少应该通过取消注释来启用、mod_proxy
和,mod_proxy_html
如下所示:mod_proxy_http
mod_xml2enc
httpd.conf
例如 httpd.conf
[...]
LoadModule proxy_module modules/mod_proxy.so
[...]
LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule proxy_http_module modules/mod_proxy_http.so
[...]
LoadModule xml2enc_module modules/mod_xml2enc.so
mod_proxy
是其他代理模块所依赖的“基础”模块,因此应始终取消注释。mod_proxy_html
并且mod_proxy_http
应该允许大多数网页成功代理,并mod_xml2enc
有助于确保代理页面中的非 ASCII 字符正确显示。
SSL 证书(概述)
请注意,以下说明假设您有一个现有的自签名 SSL 证书和匹配密钥
www.example.com
(如实际域中一样www.example.com
,而不仅仅是作为文档占位符)。这些不直接用于代理,但在包含默认 Apachehttpd-ssl.conf
文件时是必需的(除非对该文件进行了其他配置,此处主要跳过此配置)。如果你没有这些文件,我建议使用本网站生成它们。这只需要片刻时间,并且链接中的域名当前默认为
www.example.com
。您需要做的就是单击标记的按钮Generate
,然后使用生成的链接下载相应的.cert
和.key
文件(例如12345678-www.example.com.cert
和12345678-www.example.com.key
)。如果您想在本地生成自签名证书,SLProWeb 提供OpenSSL 的 Windows 版本可以从命令行使用,但是这里不介绍这些步骤。
如果你需要为要代理的域名获取免费的 SSL 证书(这些证书稍后将在本示例的“虚拟主机”部分中使用),我建议你查看零SSL获取证书让我们加密。它们仅持续 3 个月,但可以免费无限期续订。此外,ZeroSSL 还提供了一个简单、相当易于使用的命令行客户端,用于获取/续订 Let's Encrypt 证书。
请注意,这很重要不是在 Windows 上将加密的 SSL 密钥文件与 Apache 结合使用。Apache 不支持 Win32 上的 SSL 密码。如果您的任何 SSL 密钥文件都使用密码加密,则必须先使用 OpenSSL 删除该密码,然后才能在 Windows 上将其与 Apache 结合使用。
SSL(HTTPS)配置
要在 Apache 中启用 SSL 支持,请通过取消注释
mod_ssl
来启用模块httpd.conf
。对于此示例,您还需要启用(取消注释)mod_socache_shmcb
:例如 httpd.conf
[...] LoadModule socache_shmcb_module modules/mod_socache_shmcb.so #LoadModule speling_module modules/mod_speling.so LoadModule ssl_module modules/mod_ssl.so [...]
为了方便起见,我们还将包含默认的 Apache SSL 配置文件 (
httpd-ssl.conf
)。为此,请取消注释 末尾附近的以下行httpd.conf
:例如 httpd.conf
# Secure (SSL/TLS) connections Include conf/extra/httpd-ssl.conf
创建一个(或多个)文件夹来保存您的
www.example.com
SSL 证书和密钥文件。在本例中,这些文件夹应位于 下C:\Apache24
。将相应的文件放在您创建的文件夹中。打开
httpd-ssl.conf
(例如C:\Apache24\conf\extra\httpd-ssl.conf
)。查找该行SSLPassPhraseDialog builtin
并将其禁用(将其注释掉):例如 httpd-ssl.conf
[...] # Pass Phrase Dialog: # Configure the pass phrase gathering process. # The filtering dialog program (`builtin' is an internal # terminal dialog) has to provide the pass phrase on stdout. #SSLPassPhraseDialog builtin
在 中进一步
httpd-ssl.conf
查找SSLCertificateFile
和SSLCertificateKeyFile
指令并更改它们后面的路径以指向您的www.example.com
证书和密钥文件(无论您在上面的步骤 3 中将它们放在何处):例如 httpd-ssl.conf
[...] SSLCertificateFile "${SRVROOT}/path/to/12345678-www.example.com.cert" [...] SSLCertificateKeyFile "${SRVROOT}/path/to/12345678-www.example.com.key" [...]
测试(初步)
此时,您应该有一个可以正常工作且启用 SSL 的 Apache 服务器(但目前还不是反向代理)。要测试这一点,请执行以下操作:
httpd.conf
保存对和所做的所有更改httpd-ssl.conf
(如果还没有保存的话)。导航到您的 Apache
bin
目录(例如C:\Apache24\bin
)。在该目录中打开一个命令窗口(例如Shift+ 右键单击资源管理器中的空白区域,然后选择选项在这里打开命令提示符)。
跑步
httpd.exe
:此命令窗口应保持打开状态,没有任何其他错误或警告,也不返回命令行(例如
C:\Apache24\bin>
)。假设情况确实如此,您应该能够在浏览器中输入例如和
http://192.168.0.100
,https://192.168.0.100
并获得显示 的白页It works!
。假设您的 DNS 配置正确,并且您已将端口转发到
80
例如443
,http://192.168.0.100
使用 HTTP 和 HTTPS 版本的abc.net
和def.net
应该会产生相同的页面。对于 SSL 连接(例如
https://192.168.0.100
),您的浏览器可能会警告您证书名称不匹配和/或证书是自签名的。在这种情况下,您可以安全地忽略任何警告并继续连接。
测试(问题)
如果命令行显示任何错误或警告,请先修复它们再继续。
如果
httpd.exe
立即停止(返回到命令行)而没有任何其他输出,请检查 Apacheerror.log
(例如C:\Apache24\logs\error.log
)是否存在任何问题,例如您的 SSL 配置。如果您无法访问,
https://192.168.0.100
请确保该主机上的任何防火墙没有阻止网络流量,并且端口80
和443
正确转发到该主机。abc.net
在一些罕见的情况下,如果不考虑其他因素或采取其他步骤,可能无法使用例如def.net
。这可能是由于路由器不支持发夹形(NAT 环回)或更糟的是,ISP 有运营商级 NAT(CGNAT)或者主动阻塞端口。可以通过访问例如未连接到本地网络的设备(例如连接到运营商网络的智能手机)来绕过发夹
abc.net
问题def.net
。CGNAT 或类似技术可能需要完全在本地网络之外的服务器作为网络的附加代理,这里不作介绍。
虚拟主机(反向代理)配置
测试 Apache(以上)后,关闭命令窗口以
httpd.exe
停止 Apache。重新打开
httpd.conf
(例如)并通过取消注释以下行C:\Apache24\conf\httpd.conf
来启用默认的 Apache 虚拟主机配置文件( ):httpd-vhosts.conf
例如 httpd.conf
# Virtual hosts Include conf/extra/httpd-vhosts.conf
接下来,打开
httpd-vhosts.conf
(例如C:\Apache24\conf\extra\httpd-vhosts.conf
)并注释掉现有的虚拟主机示例条目:例如 httpd-vhosts.conf
[...] #<VirtualHost *:80> #ServerAdmin [email protected] #DocumentRoot "${SRVROOT}/docs/dummy-host.example.com" #ServerName dummy-host.example.com #ServerAlias www.dummy-host.example.com #ErrorLog "logs/dummy-host.example.com-error.log" #CustomLog "logs/dummy-host.example.com-access.log" common #</VirtualHost> #<VirtualHost *:80> #ServerAdmin [email protected] #DocumentRoot "${SRVROOT}/docs/dummy-host2.example.com" #ServerName dummy-host2.example.com #ErrorLog "logs/dummy-host2.example.com-error.log" #CustomLog "logs/dummy-host2.example.com-access.log" common #</VirtualHost>
将以下示例虚拟主机添加到末尾
httpd-vhosts.conf
:例如 httpd-vhosts.conf
# Redirect HTTP to HTTPS for http://example.com <VirtualHost *:80> ServerName example.com ServerAlias www.example.com Redirect permanent / https://example.com/ </VirtualHost> # Redirect HTTP to HTTPS for http://example.net <VirtualHost *:80> ServerName example.net ServerAlias www.example.net Redirect permanent / https://example.net/ </VirtualHost> # Redirect HTTPS requests for https://example.com to ex. 192.168.0.100:5000 <VirtualHost *:443> ServerName example.com ServerAlias www.example.com SSLEngine on SSLOptions +StrictRequire SSLCertificateFile "${SRVROOT}/path/to/www.example.com.crt" SSLCertificateKeyFile "${SRVROOT}/path/to/www.example.com.key" # Required by first virtual SSL host #SSLProtocol TLSv1 #ProxyPass / http://192.168.0.100:5000/ #ProxyPassReverse / http://192.168.0.100:5000/ # Localhost ProxyPass / http://127.0.0.1:5000/ ProxyPassReverse / http://127.0.0.1:5000/ </VirtualHost> # Redirect HTTPS requests for https://example.net to ex. 192.168.0.100:5001 <VirtualHost *:443> ServerName example.net ServerAlias www.example.net SSLEngine on SSLOptions +StrictRequire SSLCertificateFile "${SRVROOT}/path/to/www.example.net.crt" SSLCertificateKeyFile "${SRVROOT}/path/to/www.example.net.key" # Required by first virtual SSL host #SSLProtocol TLSv1 #ProxyPass / http://192.168.0.100:5001/ #ProxyPassReverse / http://192.168.0.100:5001/ # Localhost ProxyPass / http://127.0.0.1:5001/ ProxyPassReverse / http://127.0.0.1:5001/ #</VirtualHost>
根据您的需要修改此更新的示例。特别是:
与
httpd.conf
和不同httpd-ssl.conf
,用您的实际域(例如abc.net
和def.net
)替换example.com
和example.net
(例如,只需进行简单的搜索/替换)。更改
SSLCertificateFile
和SSLCertificateKeyFile
指令以指向每个域的相应 SSL 证书和密钥文件(再次,例如abc.net
和def.net
)。此示例假设您将它们放在与www.example.com
上一节“SSL”中的实际证书和密钥文件大致相同的文件夹中(上文)。虽然这些示例省略了每个主机的空间日志记录,但您可以根据需要向上述任何虚拟主机添加日志指令。
httpd-vhosts.conf
完成上述必要的更改后保存。
当 Apache 运行时,192.168.0.100:5000
和上的服务现在应该分别由和192.168.0.100:5001
的 HTTP 或 HTTPS 版本返回(带或不带前缀,假设在 DNS 中设置了非 www 版本)。 abc.net
def.net
www