在Ubuntu中利用Nginx进行多站点的配置

1,751 阅读7分钟

前言

这一篇文章写得非常惨不忍睹,因为遇到了太多坑了,这里我重新梳理一下本篇文章在讲什么,遇到了什么问题,目标是什么。

  • 目标也就是需求是什么?在云服务器上,运行着多个容器,每个容器都是一个web服务,通过端口映射使得能通过IP:端口号访问不同的服务,但是这么多的服务,分配的端口号也多,如何记住这些不同的端口号对应的不同服务就成了一个难题,这个难题类似记住很多个IP及其对应的主机一样难,为此我们也通过域名系统DNS解决这个难题,怎么办呢?子域名来帮忙!通过设置人脑容易记住的名字对应上不同的服务,这样不就解决了?
  • 解决思路是什么?通过不同的子域名对应不同的服务,具体的实现是采用Nginx进行反向代理,根据域名实现虚拟主机,在每个虚拟主机(server块)中设置server_name,并利用location进行普通匹配,然后设置proxy_pass并且利用proxy_set_header设置Host和真实的IP,详细的过程在后面讲解。
  • 没有备案被劫持怎么办?比较现实的问题是我的域名和主机都没有备案,所以默认的80端口肯定用不了(会被劫持,具体结果后面有贴图),故而我采取让所有的虚拟主机都统一监听888端口的方式以避免备案问题。
  • 开启HTTPS?如果要采用HTTPS,则必须使用受到浏览器信任的机构发放的证书,这个是需要购买的(此需求肯定要买通配符证书,但很贵)!免费的有Let's Encrypt组织提供,需要使用certbot,但该工具的使用的前提就是必须保证80端口可以访问到你的网站,由于没有备案所以也用不了(但是意外的是我又发现了一个短期可用的免费证书申请站点:freessl.cn/,关于因此关于HTTPS的配置将在这篇文章:Nginx中HTTPS的配置中着重叙述)。你可能会说使用openssl自己生成不行吗?还真的不行,因为不被浏览器信任就会显示不安全而不是锁🔐,相当于你的云主机成了CA,但不被浏览器信任。

准备条件

  • 使用前,请注意:云备案,国内主机必须备案,否则会被劫持而无法访问,在我看来它就是劫持80和443端口,如果不想备案就保持原来的,使用不同的端口访问服务。

表面上经过代理后的情况

跳过cloudflare的代理,得到真实情况

  • 思考有没有不备案的解决方案?有的,把子域名和非80或443端口结合起来,例如每个web服务都使用不同的子域名,但都带同样的端口号888。使用子域名是为了更方便确定要使用的某项web服务(如果通过端口访问不同服务,那记起来就太难了),统一使用888端口(这个端口号应指定非80或443或预留的)是为了避免国内主机没有进行备案而被封,因此在后面给出的示例的配置中我们多加了一个监听:listen 888注意由于证书啥的使用certbot,必须要80端口可访问,故不配置HTTPS!
  • 注意使用docker运行的这些服务,都有一个network,名字叫做bridge,因此现在有了Nginx就不需要再做端口映射暴露出来用localhost访问,而是直接访问容器的IP:80(也就是说容器与云主机是在一个网络中的,可以相互访问,而每个容器都有一个IP,所以可以直接使用Nginx的代理访问容器IP),使用docker network inspect bridge可以查看。
  • 在用Nginx进行代理的时候,我们用到了**proxy_set_header Host $host:888**,原因在于$host没有带上端口,所以当服务跳转的时候就可能出错(因为比如nextcloud的服务就开启了域名信任白名单,会检测Host字段,也就是跨域的安全性问题)。
  • 查看系统版本 cat /proc/version
    cat /proc/version
  • 查看端口占用:netstat -tlnp,因为Nginx要监听80和443。
  • 作者的服务器上已经运行有多个之前使用docker部署的服务,通过不同的端口号可以访问不同的服务。
    docker ps
  • 现在的目的是使用子域名访问不同的服务,而不是通过不同的端口,例如a.dfface.comb.dfface.com
  • 仅供参考,反正自己无聊就喜欢做实验,还喜欢顺便记录下。

安装 Nginx

之前一篇文章介绍过编译安装:在CentOS中通过源码编译安装Nginx ,这里偷懒直接使用apt install nginx

需要注意的是: /usr/sbin/nginx:主程序 /etc/nginx:存放配置文件 /usr/share/nginx:存放静态文件 /var/log/nginx:存放日志

cloudflare 上的配置

先设置一条A,填上服务器的IP,例如A a 192.168.1.1。 然后设置众多子域名,利用的是CNAME,相当于起别名,填上CNAME b a.dfface.com

HTTPS 的准备

这里的证书是不可信的:管理 Cloudflare Origin CA 证书

CloudFlare Origin Certificate不受信任,跟自己用OpenSSL生成的效果一样……)

需要注意的是cloudflare出于安全原因,在创建 Origin 证书后,不会再次显示私钥

配置完成之后,注意:

在源 Web 服务器上安装 Cloudflare Origin CA 证书后,指示 Cloudflare 加密到源 Web 服务器的流量。在 Cloudflare SSL/TLS 应用中将 SSL 模式设置为完全Full或完全(严格)Full (strict),以在 Cloudflare 和您的源 Web 服务器之间启用加密。

Origin CA 证书仅加密 Cloudflare 与您的源 Web 服务器之间的流量,并且在 Cloudflare 之外直接访问您的原始网站时不受客户端浏览器的信任。

建议使用 免费的certbot,但前提是开了80端口可访问网站(即国内备案)。

配置 nginx.conf

直接在/etc/nginx/sites-available下新建自己的一些站点配置文件,进行简单的配置:

cp default acp default b,在默认的配置上进行修改即可。

关于Nginx如何配置,可以看这篇文章:www.jianshu.com/p/fd25a9c00…,或者其他书籍,例如《Nginx高性能Web服务器实战教程》(两三天就看完了,适合入门),这里不说啦。

那么贴上一个站点的设置做参考,由于在/etc/nginx.conf中已经经过了大量的设置,因此我们需要写的比较少其实:

server {
        listen 888;
        listen [::]:888;
        server_name b.dfface.com;

        location / {
            proxy_pass http://172.18.0.7;
            proxy_set_header Host $host:888;
            proxy_set_header X-Client-IP $remote_addr;
        }
}

**注意,这里的proxy_pass后面跟的URL,其中的IP是bridge网络中的容器的IP!**不再使用端口映射,因为Nginx帮我们做了代理,而Nginx本身也可以运行在容器里的,因此可以使用Nginx的容器而不是在主机中直接安装,但我想的是在主机中直接安装可能性能更高。

修改完成之后,需要注意在/etc/nginx/sites-enabled中建立软链接,例如:

ln -s /etc/ngix/sites-available/web1.com /etc/nginx/sites-enabled/web1.com

查看Nginx状态:systemctl status nginx

使配置生效,请使用命令:systemctl reload nginx

还有就是Ubuntu本身有个防火墙:ufw allow 888,云服务器也有个防火墙得在设置中开启888端口。

结语

请继续阅读Nginx中HTTPS的配置,里面有最终效果贴图!


dfface 的版权声明:所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处,严禁商业用途!