Nginx多域名解析、https证书

September 13, 2024

前言

当一个开发者有了一台云服务器,可能会想着部署一个博客网页,一个工具网站;

也可能是想部署一个网站所以入手了一台云服务器。

Anyway,当需要部署并暴露某个网站时,那它一定需要一个容易被人记住的名字:域名

没人会愿意通过ip加端口号的方式去访问一个网站,包括开发者自己。

仅仅有个域名还不够,还需要https的安全证书🔐。那到底该如何去优雅地暴露服务呢?

我的选择是 「Nginx」 + 「Let's Encrypt

前者提供域名映射,后者提供安全证书

多域名

当拥有了一个根域名后,就可以扩展出多个子域名了;当然,如果有多个域名更好。

我有一个根域名 tunan.fun,我就可以拥有多个子域名。i.e. tools.tunan.fun

这些都可以在你的域名购买的厂商那里去设置,然后将域名解析到自己的服务器IP上。

如果服务器是中国国内的,那么还需要进行备案,需要几个工作日等待审核处理。

映射到多服务

现在假设我有这样一个需求,我的服务器中部署了两个网站,我想通过不同的域名来访问:

  • tunan.fun访问我的博客应用tunan-blog-app
  • tools.tunan.fun访问我的工具箱应用tunan-tools-app

该如何使用「Nginx」做映射?

Nginx」的下载和安装就不在此展开了,主要讲讲如何通过它实现我们的目的。

比如我现在要映射到我的两个服务的前端(两个网站均采用前后端分离的架构)。

  • tunan-blog-app基于reac+node.js框架,通过暴露某个端口(i.e.8080)作为服务入口。
  • tunan-tools-app基于vue框架,利用生成的静态文件dist做服务入口。

也就是说我需要nginx来帮我做到:

  • 当解析到该服务器ip的域名是tunan.fun时,nginx帮我把请求映射到localhost:8080端口的服务上;
  • 当解析到该服务器ip的域名是tools.tunan.fun时,nginx帮我把请求映射到相应的静态文件的index.html上。

image-20240913201632228

接下来就看看如何编写该配置文件。

配置文件 nginx.conf

找到「Nginx」所在的安装位置中的配置文件nginx.conf

可以通过以下两种方式寻找配置文件:

  • ps -ef | grep nginx
  • nginx-t

一般情况下,安装目录为/etc/nginx

找到后修改该配置文件,修改或者新增http{}server{}的配置。

http {
	server {
		server_name tools.tunan.fun;
		root /home/yaodao/my-app/my-tools/front/dist;
    index index.html;
    location / {
            try_files $uri $uri/ /index.html;
    }

	}	
	server {
		server_name tunan.fun www.tunan.fun;
		location / {
			 		proxy_pass  http://127.0.0.1:8080;
   			 	proxy_set_header Host $host;
   			 	proxy_set_header X-Real-IP $remote_addr;
   			 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		 }
	}
}

通过service nginx reload命令使新的配置文件生效。

注意这里有 tunan.fun, 和 www.tunan.fun,这是希望其他人通过这两个域名都能访问到我的博客,它们俩在服务商的域名解析的配置中是不同的两个,分别是:http://www.tunan.fun,这是希望其他人通过这两个域名都能访问到该博客,它们俩在服务商的域名解析的配置中是不同的两个,分别是:

  • @.tunan.fun
  • www.tunan.fun

不安全的Http访问

做完上面的事情,就可以通过http://tunan.fun进行访问了,但此时谷歌浏览器就会告知这是不安全的网站。

Https才是安全的访问方式,没有人愿意自己的博客网页被标记是不安全的。

接下来我们就通过「Let's Encrypt」来实现https安全证书的安装。

Let's Encrypt

We recommend that most people with shell access use the Certbot ACME client.

这是其Getting Started中的描述,接下来我们就会使用 Certbot 来安装证书。

image-20240913203319189

选择Nginx+Linux,随后就会给出相关的安装步骤,比较简单,其中最关键的一步是Choose how you'd like to run Certbot

我建议直接使用第一种方式:certbot --nginx。它会做几件事情:

  • 基于现在的nginx配置中的server_name来生成相应的证书(存到某个位置)
  • 把证书的配置写到nginx.conf
  • 使配置文件生效

此时再看配置文件就会额外多出一些不同的内容,我建议你,保存之前的配置文件,前后对比一下。

http {
	server {
		server_name tools.tunan.fun;
		root /home/yaodao/my-app/my-tools/front/dist;
    index index.html;
    location / {
            try_files $uri $uri/ /index.html;
    }
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/www.tunan.fun/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.tunan.fun/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  }	
	server {
		server_name tunan.fun www.tunan.fun;

		location / {
			 	proxy_pass  http://127.0.0.1:8080;
       	proxy_set_header Host $host;
      	proxy_set_header X-Real-IP $remote_addr;
   			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		}
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/www.tunan.fun/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.tunan.fun/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  }
}

  1. 这里需要注意证书是会过期的,但没关系,写个脚本就可以了,不会写也没关系,Certbot贴心的给出了,只要耐心读完它的所有步骤。
  2. 如果server_name中有些域名是无效的(忘记在域名解析中设置了),那就不要为其生成证书或者先去设置一下,命令执行时会询问为哪些server_name生成证书。
  3. 实际上子域名和根域名的证书是一样,当多个完全无关的域名时就会生成多个证书了。
  4. 如果我想再加一个server_name并安装证书,只要加上server{},然后重新执行certbot --nginx一遍就可以了。

🎉 Https 访问!

现在就可以通过https访问你的网站了: https://www.tunan.fun.

然而万事大吉了吗?NO!!!

🫨 突然的报错

如果你的服务是前后端分离的,比如:

  • tunan-blog-app
    • 前端基于reac+node.js框架,通过暴露某个端口(i.e.8080)作为服务入口
    • 后端通过go语言的Go Fiber提供http服务。
  • tunan-tools-app
    • 前端基于vue框架,利用生成的静态文件dist做服务入口。
    • 后端通过java语言的Spring Web提供http服务。

原本,前端进行http调用的时候直接通过ip:port或者http+域名的方式进行后台服务调用,现在网站升级成https的了。

此时浏览器再发起http的方式进行网络接口调用,就会被拦截,认为这是不安全的操作。

所以还需要将后台的服务也变成https的访问。以设置tunan-tools-app的后台服务的域名访问为例。

该服务运行在9091端口上,想通过https://tools.tunan.fun/api/xxx来访问。那么nginx的配置文件增加新的location / * {} 模块

http {
	server {
		server_name tools.tunan.fun;
		root /home/yaodao/my-app/my-tools/front/dist;
    index index.html;
    location / {
          try_files $uri $uri/ /index.html;
    }
   	location /api  {
      		proxy_pass  http://127.0.0.1:9091;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/www.tunan.fun/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.tunan.fun/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  }
  ……
}

映射关系如下:

image-20240913210740656

完结

通过这种方式,就能物尽其用,子域名映射到不同的服务上!希望这篇文章能够帮助到正在读的你。

Comments