Apache,Ubuntu多个端口或子域使用SSL反向代理到不同端口同一服务器

Apache,Ubuntu多个端口或子域使用SSL反向代理到不同端口同一服务器

我在这里遇到了一些问题。我在 Azure 中安装了 Ubuntu 18.04 VM + Apache2。我有一个指向我的 VM 的 Web 服务器 /var/www/ 的域 (example.com),并且最近通过设置 SSL 保护了服务器。我使用 letsencrypt 和“certbot”获得了证书,选择了将所有 HTTP 流量重定向到 HTTPS 的选项。这是我的站点的 .conf:

root@wp-vm:/# cat /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    <Directory /var/www/example.com/>
        AllowOverride All
    </Directory>
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.example.com [OR]
RewriteCond %{SERVER_NAME} =example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

我在同一台服务器上运行其他一些 Web 服务:RStudio Shiny 服务器(端口 3838)和 Rstudio Server IDE 开源(8787)。这些是免费版本,不支持 SSL。我了解到,现在我的 Web 服务器使用 SSL,我将无法通过 iframe 将 Shiny 服务器的内容嵌入到我的网页(wordpress)中。因此,虽然我以前可以链接到 example.com:3838/app,但除非我保护端口,否则将无法再使用此功能。

我如何实现以下目标?

http(s)://example.com >> webserver (OK)
http(s)://example.com:48787 >> rstudio @ 8787
http(s)://example.com:43838 >> shiny @ 3838

或者甚至更好,我该如何使用这样的子域名进行设置(如果它不会增加太多复杂性):

http(s)://example.com >> apache webserver @ /var/www (OK)
http(s)://rstudio.example.com >> rstudio @ 8787
http(s)://shiny.example.com >> shiny @ 3838

需要明确的是,浏览器需要通过 HTTPS 进行通信,但 8787/3838 上的服务仍将保持 HTTP。

我已经尝试过但无法正常工作的一些方法:我尝试加载一堆模块并使用 ProxyPass 和 ProxyPassReverse 以各种方式定义虚拟主机,使用“Location”/subdomain 标签修改现有虚拟主机,我已告诉 apache 在 ports.conf 中监听新端口,并打开防火墙(azure 和 ufw)。我显然遗漏了一些东西,但不知道是什么。这是我当前的防火墙,请告诉我我还能提供什么可能有助于解答的问题。

root@wp-vm:/# ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] Apache Full                ALLOW IN    Anywhere
[ 2] 3838                       ALLOW IN    Anywhere
[ 3] 8787                       ALLOW IN    Anywhere
[ 4] 43838                      ALLOW IN    Anywhere
[ 5] 48787                      ALLOW IN    Anywhere
[ 6] 22/tcp                     ALLOW IN    Anywhere
[ 7] Apache Full (v6)           ALLOW IN    Anywhere (v6)
[ 8] 3838 (v6)                  ALLOW IN    Anywhere (v6)
[ 9] 8787 (v6)                  ALLOW IN    Anywhere (v6)
[10] 43838 (v6)                 ALLOW IN    Anywhere (v6)
[11] 48787 (v6)                 ALLOW IN    Anywhere (v6)
[12] 22/tcp (v6)                ALLOW IN    Anywhere (v6)

阿帕奇

root@wp-vm:/# apache2 -v
Server version: Apache/2.4.29 (Ubuntu)
Server built:   2020-08-12T21:33:25

编辑/更新:我意识到我遗漏了一个重要文件的内容,而且我可能一直在弄乱错误的文件(example.com.conf)。

root@wp-vm:/etc/apache2/sites-available# cat example.com-le-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    <Directory /var/www/example.com/>
        AllowOverride All
    </Directory>


Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

</VirtualHost>
</IfModule

因此,我现在将 example.com.conf 文件保留原样,因为我认为它只是将所有请求重写为 https 并重定向到 443。我现在尝试将其添加到 ssl conf 文件中,但没有成功。看来我将在此文件中重试所有内容。

ProxyRequests off
ProxyPass /shiny/ http://localhost:3838/
ProxyHTMLURLMap http://localhost:3838 /shiny

<Location /shiny/>
        ProxyPassReverse /
        ProxyHTMLEnable On
        ProxyHTMLURLMap  /      /shiny/
        RequestHeader    unset  Accept-Encoding
</Location>

编辑#2 如此接近,我都能感受到!我基本上已经让它与子目录(example.com/shiny 和 /rstudio)一起工作了。但是,它对于地址的输入方式很挑剔 - 它是否包含最后的尾随“/”以及“https”是否相同。

这个人似乎遇到了与 rstudio 类似的问题并通过大量重写和重定向“解决”了这个问题(向下滚动到“设置资源限制”部分之前的最终解决方案)。这适用于“根”路径,但不适用于 /shiny 下的应用程序子目录。因此 example.com/shiny/ 有效,example.com/shiny 可以通过重定向到 ../shiny/ 来工作,但 example.com/shiny/app1 无效,并解析为 /app1。我需要输入 example.com/shiny/app1/。

我现在对我的 /shiny 和 /rstudio 也做了同样的事情。这是我当前的 .conf。我认为我的问题和疑问现在已经简化为如何使其干净、正确并且对“/”省略具有鲁棒性?

root@wp-vm:/etc/apache2/sites-available# cat *-le*
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    <Directory /var/www/example.com/>
        AllowOverride All
    </Directory>


Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

SSLProxyEngine On

# extra redirect for shiny subdirectory
Redirect /shiny /shiny/
# extra redirects for the RStudio subdirectory
Redirect /rstudio /rstudio/
Redirect /auth-sign-in /rstudio/auth-sign-in
Redirect /auth-sign-out /rstudio/auth-sign-out
# Catch RStudio redirecting improperly from the auth-sign-in page
<If "%{HTTP_REFERER} =~ /auth-sign-in/">
  RedirectMatch ^/$     /rstudio/
</If>
##

ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
    AddDefaultCharset Off
    Order deny,allow
    Allow from all
</Proxy>
ProxyPass /shiny/ http://127.0.0.1:3838/
ProxyPassReverse /shiny/ http://127.0.0.1:3838/
ProxyPass /rstudio/ http://localhost:8787/
ProxyPassReverse /rstudio/ http://localhost:8787/

##
RequestHeader set X-Forwarded-Proto "https"
##
</VirtualHost>
</IfModule>

相关内容