本文目录
-
- 准备
- 登陆云服务器
- [安装 Java](#安装 Java)
- [下载 tomcat 包](#下载 tomcat 包)
- 配置防火墙
- [浏览器访问 Tomcat 默认页面](#浏览器访问 Tomcat 默认页面)
- [以服务的形式运行 Tomcat](#以服务的形式运行 Tomcat)
-
- [创建 Tomcat 用户和组](#创建 Tomcat 用户和组)
- [创建 systemd 服务文件](#创建 systemd 服务文件)
- [启动 tomcat 服务](#启动 tomcat 服务)
- [Tomcat webapps 文件目录](#Tomcat webapps 文件目录)
-
- 部署一个静态网站
- [tomcat 的配置文件](#tomcat 的配置文件)
- 将域名解析到服务器
- [Tomcat 配置 SSL/TLS 证书](#Tomcat 配置 SSL/TLS 证书)
-
- [获取 SSL/TLS 证书](#获取 SSL/TLS 证书)
- [Tomcat 配置 SSL/TLS 证书,实现 HTTPS,并启用 HTTP/2.0](#Tomcat 配置 SSL/TLS 证书,实现 HTTPS,并启用 HTTP/2.0)
-
- [配置 server.xml 文件,使用 keystore.jks 文件](#配置 server.xml 文件,使用 keystore.jks 文件)
- [解决无法监听 443 端口的问题](#解决无法监听 443 端口的问题)
- [配置 server.xml 文件,使用证书文件](#配置 server.xml 文件,使用证书文件)
- [apache2 反向代理到 tomcat](#apache2 反向代理到 tomcat)
-
- [安装 apache2](#安装 apache2)
- [编辑 apache2 配置文件](#编辑 apache2 配置文件)
- 证书过期更新
准备
- 有一台云服务器。
- 云服务器安装 Ubuntu 操作系统(或者是其他 Linux 操作系统的发行版,本文的演示使用 Ubuntu 系统)。
- 熟悉 Linux 命令行操作。
- 能够远程云服务器。推荐使用 SSH 进行远程,参见 SSH 远程连接。
登陆云服务器
ssh 使用私钥登陆到服务器。
bash
ssh -i /path/to/id_rsa ubuntu@server_IP_address
安装 Java
运行 tomcat 需要 Java 的环境。首先检查 Java 是否安装。java --version
bash
ubuntu@VM-0-17-ubuntu:~$ java --version
Command 'java' not found, but can be installed with:
sudo apt install openjdk-17-jre-headless # version 17.0.12+7-1ubuntu2~24.04, or
sudo apt install openjdk-21-jre-headless # version 21.0.4+7-1ubuntu2~24.04
sudo apt install default-jre # version 2:1.17-75
sudo apt install openjdk-11-jre-headless # version 11.0.24+8-1ubuntu3~24.04.1
sudo apt install openjdk-8-jre-headless # version 8u422-b05-1~24.04
sudo apt install openjdk-19-jre-headless # version 19.0.2+7-4
sudo apt install openjdk-20-jre-headless # version 20.0.2+9-1
sudo apt install openjdk-22-jre-headless # version 22~22ea-1
JDK (Java Development Kit) 包含了Java编译器和其他开发工具,而JRE (Java Runtime Environment) 则包含了运行Java程序所需的运行时环境。对于大多数Tomcat部署,只需安装JRE即可,因为Tomcat主要用于运行Java Web应用程序,而不是编译Java源代码。
安装 JRE 可以选择使用上面的命令 sudo apt install default-jre
,或者根据需要自行选择版本。
安装完成后,输入 java --version
验证安装:
bash
ubuntu@VM-0-17-ubuntu:~$ java --version
openjdk 21.0.5 2024-10-15
OpenJDK Runtime Environment (build 21.0.5+11-Ubuntu-1ubuntu124.04)
OpenJDK 64-Bit Server VM (build 21.0.5+11-Ubuntu-1ubuntu124.04, mixed mode, sharing)
如果想要查看 Java 的安装路径可以使用以下命令:
bash
ubuntu@VM-0-17-ubuntu:~$ which java
/usr/bin/java
ubuntu@VM-0-17-ubuntu:~$ readlink -f /usr/bin/java
/usr/lib/jvm/java-21-openjdk-amd64/bin/java
想要手动配置环境变量的话,可以根据安装路径来手动配置环境变量。一般情况下,安装后会自动配置环境变量。如果验证安装时,发现没有打印 java 版本号相关信息,可能就是环境变量没有配置的问题。
配置环境变量(不需要的跳过此步) :
Linux 系统级环境变量的配置文件在 /etc/environment
,使用 vim 进行编辑(vim 的教程网上有很多)。
sudo vim /etc/environment
在 /etc/environment
文件中添加以下内容:注意修改真实的安装路径。注意文件原来的系统环境变量要放在最后一行,并把 :$JAVA_HOME/bin
放在 PATH 末尾。
JAVA_HOME="/usr/lib/jvm/java-21-openjdk-amd64"
CLASSPATH="$JAVA_HOME/lib"
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:$JAVA_HOME/bin"
保存退出 vim 使用 :wq
source /etc/environment
重新加载环境变量。
验证环境变量的配置:
echo $JAVA_HOME
echo $CLASSPATH
echo $PATH
root@VM-0-17-ubuntu:/opt/tomcat/bin# echo $JAVA_HOME
/usr/lib/jvm/java-21-openjdk-amd64
root@VM-0-17-ubuntu:/opt/tomcat/bin# echo $CLASSPATH
/usr/lib/jvm/java-21-openjdk-amd64/lib
root@VM-0-17-ubuntu:/opt/tomcat/bin# echo $PATH
/usr/lib/jvm/java-21-openjdk-amd64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
下载 tomcat 包
下载 Tomcat.tar.gz 包。到 Tomcat 官网 找到对应 Tomcat 版本的下载链接。截至写这篇文章(2024年11月27日)为止,Tomcat 的最新版本是 11 (alpha) 测试版,稳定版是 Tomcat 10 。
我这里下载的版本是 Tomcat 10.1.33,根据需要自行选择版本。
为了后续方便操作,先提升为 root 用户。
sudo -i
下载 tomcat 包:wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.33/bin/apache-tomcat-10.1.33.tar.gz
注意下载链接以后可能会失效,不要直接复制这里,下载链接自行去官网找想要的版本。
root@VM-0-17-ubuntu:/home/ubuntu# wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.33/bin/apache-tomcat-10.1.33.tar.gz
--2024-11-27 16:13:11-- https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.33/bin/apache-tomcat-10.1.33.tar.gz
Resolving dlcdn.apache.org (dlcdn.apache.org)... 151.101.2.132, 2a04:4e42::644
Connecting to dlcdn.apache.org (dlcdn.apache.org)|151.101.2.132|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 13678161 (13M) [application/x-gzip]
Saving to: 'apache-tomcat-10.1.33.tar.gz'
apache-tomcat-10.1.33.tar.gz 100%[===============================================>] 13.04M 45.3MB/s in 0.3s
2024-11-27 16:13:12 (45.3 MB/s) - 'apache-tomcat-10.1.33.tar.gz' saved [13678161/13678161]
root@VM-0-17-ubuntu:/home/ubuntu# ls
apache-tomcat-10.1.33.tar.gz
解压缩 :tar -xzvf apache-tomcat-10.1.33.tar.gz
root@VM-0-17-ubuntu:/home/ubuntu# tar -xzvf apache-tomcat-10.1.33.tar.gz
apache-tomcat-10.1.33/conf/
apache-tomcat-10.1.33/conf/catalina.policy
apache-tomcat-10.1.33/conf/catalina.properties
apache-tomcat-10.1.33/conf/context.xml
... ...
... ...
root@VM-0-17-ubuntu:/home/ubuntu# ls
apache-tomcat-10.1.33 apache-tomcat-10.1.33.tar.gz
复制到 /opt/tomcat 下 :cd /opt
+ mkdir tomcat
+ cp -r /home/ubuntu/apache-tomcat-10.1.33/* ./tomcat
cd /opt
root@VM-0-17-ubuntu:/opt# mkdir tomcat
root@VM-0-17-ubuntu:/opt# cp -r /home/ubuntu/apache-tomcat-10.1.33/* ./tomcat
root@VM-0-17-ubuntu:/opt# ls -l tomcat
total 152
drwxr-x--- 2 root root 4096 Nov 27 16:29 bin
-rw-r----- 1 root root 21039 Nov 27 16:29 BUILDING.txt
drwx------ 2 root root 4096 Nov 27 16:29 conf
-rw-r----- 1 root root 6166 Nov 27 16:29 CONTRIBUTING.md
drwxr-x--- 2 root root 4096 Nov 27 16:29 lib
-rw-r----- 1 root root 60393 Nov 27 16:29 LICENSE
drwxr-x--- 2 root root 4096 Nov 27 16:29 logs
-rw-r----- 1 root root 2333 Nov 27 16:29 NOTICE
-rw-r----- 1 root root 3298 Nov 27 16:29 README.md
-rw-r----- 1 root root 6776 Nov 27 16:29 RELEASE-NOTES
-rw-r----- 1 root root 16109 Nov 27 16:29 RUNNING.txt
drwxr-x--- 2 root root 4096 Nov 27 16:29 temp
drwxr-x--- 7 root root 4096 Nov 27 16:29 webapps
drwxr-x--- 2 root root 4096 Nov 27 16:29 work
启动 tomcat:
root@VM-0-17-ubuntu:/opt# cd tomcat/bin
root@VM-0-17-ubuntu:/opt/tomcat/bin# ls
bootstrap.jar commons-daemon.jar digest.sh setclasspath.sh tomcat-native.tar.gz
catalina.bat commons-daemon-native.tar.gz makebase.bat shutdown.bat tool-wrapper.bat
catalina.sh configtest.bat makebase.sh shutdown.sh tool-wrapper.sh
catalina-tasks.xml configtest.sh migrate.bat startup.bat version.bat
ciphers.bat daemon.sh migrate.sh startup.sh version.sh
ciphers.sh digest.bat setclasspath.bat tomcat-juli.jar
tomcat/bin
目录下有个 startup.sh
是一个启动脚本文件。这个脚本会设置必要的环境变量,并调用Tomcat的启动类来启动服务。
执行启动脚本:./startup.sh
root@VM-0-17-ubuntu:/opt/tomcat/bin# ./startup.sh
Using CATALINA_BASE: /opt/tomcat
Using CATALINA_HOME: /opt/tomcat
Using CATALINA_TMPDIR: /opt/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
运行 startup.sh
脚本时,它会首先设置一些环境变量,如 CATALINA_HOME
和 CATALINA_BASE
等,这些变量用于指定 Tomcat 的安装目录和工作目录。接着,脚本会调用 catalina.sh
脚本,该脚本是 Tomcat 启动的核心。
在 catalina.sh
脚本中,会调用 org.apache.catalina.startup.Bootstrap
类的 main
方法。这是 Tomcat 启动的入口点。
在 main
方法中,会进行初始化操作,包括创建类加载器、加载 Tomcat 的配置文件等。
Bootstrap
类的 main
方法会调用 init
方法来初始化 Tomcat 所需的类加载器,并设置当前线程的上下文类加载器。
接着,会调用 load
方法来加载 Tomcat 的配置文件,并初始化容器组件。
在完成初始化操作后,Bootstrap
类的 main
方法会调用 start
方法来启动 Tomcat 服务。
Tomcat 服务启动后,会监听指定的端口号(如8080),准备接受客户端的请求。
配置防火墙
Tomcat 在服务器启动后,想要在本地访问 tomcat 的默认页面,要配置防火墙。参见 Linux: iptables && ufw 配置防火墙规则 。Ubuntu 系统内的防火墙要放行 8080 端口的 TCP 流量,服务器提供商的控制台界面的防火墙也要放行 8080 TCP 的流量。最好也把 443 端口的 TCP 流量也放行了,后面配置好 HTTPS 后就不用再配置防火墙了。
浏览器访问 Tomcat 默认页面
配置好防火墙以后,在本地的浏览器输入 http://IP_address:8080
就可以访问到 Tomcat 的默认页面了,IP_address
对应你服务器的公网 IP 地址:
看到以上页面说明你的 Tomcat 部署已经初步成功了。
以服务的形式运行 Tomcat
首先关闭 tomcat 服务:cd /opt/tomcat/bin
+ ./shutdown.sh
进入到 /opt/tomcat/bin
目录,执行关闭脚本。
以上 启动 / 关闭 Tomcat 使用的是 tomcat/bin/startup.sh | shutdown.sh
启动 / 关闭 脚本,我们总不能每次启动 Tomcat 都要运行这个脚本,所以要以一个服务的形式运行 Tomcat 。这里的服务指的就是一种运行在操作系统(Linux)后台的守护进程(daemon),这些所谓的服务由systemd管理,它们负责执行系统所需的各种任务。
Windows 系统上也有这种类似的服务:
创建 Tomcat 用户和组
为了安全起见,我们要创建专门的 tomcat 用户和组来运行 tomcat。
以 root 的身份运行 tomcat 也是可以的,但是会存在安全风险。
因为 root 用户是系统的管理员用户,有着对各种系统文件的访问权限。
以 root 用户身份运行应用程序(包括 Tomcat)意味着该应用程序拥有对整个系统的完全访问权限。
如果 Tomcat 或其中的某个 Web 应用出现安全漏洞,攻击者可以利用该漏洞获得对系统的完全控制权限。
这可能导致:
-
系统篡改:攻击者可以访问和修改系统的核心文件,甚至安装恶意软件或后门。
-
数据泄露:敏感信息(如数据库凭证、用户数据等)可能被泄露或窃取。
-
拒绝服务攻击:攻击者可以消耗系统资源,导致服务无法正常运行。
防止 root 用户滥用的最佳做法是遵循 最小权限原则(Principle of Least Privilege)。即让每个进程或服务仅获得它执行任务所需的最小权限,避免为应用程序提供多余的特权。
命令:
sudo -i
groupadd tomcat
useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat
chown -R tomcat:tomcat /opt/tomcat
命令解释:
-
groupadd tomcat
添加一个名为 tomcat 的组。 -
useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat
-s
参数用于指定该用户的默认 shell。/bin/false
是一种常用的做法,它表示该用户无法登录系统,因为/bin/false
会立即退出并返回一个失败的状态。这是为了防止 Tomcat 用户通过 SSH 或其他方式直接登录到服务器。设置为/bin/false
后,Tomcat 用户只能作为服务运行,而不能以交互式的方式登录到系统。-g
参数指定新用户的主用户组。tomcat
表示新用户将加入名为tomcat
的组。在创建 Tomcat 服务时,通常会为其创建一个专用的用户和组,用来确保 Tomcat 服务运行时的权限是受限的。通过将 Tomcat 用户加入到同名的tomcat
组,确保它对 Tomcat 文件夹(通常位于/opt/tomcat
)有适当的权限。-d
参数指定用户的主目录。/opt/tomcat
表示 Tomcat 用户的主目录将被设置为/opt/tomcat
。通常情况下,Tomcat 的安装路径是/opt/tomcat
或其他类似的路径,目的是将 Tomcat 文件存放在该目录下。为 Tomcat 用户设置主目录为此路径,并且将该目录的权限授予该用户,使得 Tomcat 可以访问和管理其文件。- 最后,
tomcat
是要创建的用户的用户名。也就是说,命令会创建一个名为tomcat
的用户。
-
chown -R tomcat:tomcat /opt/tomcat
-
chown
change owner 改变文件或目录的拥有者(user)和所属组(group)的命令。 -
-R
是chown
命令的一个选项,表示 "递归"(recursive)。它的作用是让chown
命令不仅改变指定目录本身的所有者和组,还会递归地改变该目录下所有子目录和文件的拥有者和组。 -
tomcat:tomcat
- 前面的是目标用户(user),即指定的文件或目录的新拥有者(owner)。
- 后面的是目标组(group),即指定的文件或目录的新所属组(group)。
-
在此命令中,
tomcat:tomcat
意味着将/opt/tomcat
目录及其所有子目录和文件的拥有者和所属组都更改为tomcat
用户和tomcat
组。root@VM-0-17-ubuntu:/opt/tomcat/bin# groupadd tomcat
root@VM-0-17-ubuntu:/opt/tomcat/bin# useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat
root@VM-0-17-ubuntu:/opt/tomcat/bin# chown -R tomcat:tomcat /opt/tomcat
-
创建 systemd 服务文件
vim /etc/systemd/system/tomcat.service
使用 vim 创建 tomcat.service
文件。
编辑内容如下:
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always
[Install]
WantedBy=multi-user.target
service 文件配置解释:
After=network.target
指定服务的启动顺序。表示 Tomcat 服务将在网络服务启动后再启动。network.target 是指系统的网络服务,通常意味着网络接口已经准备好,能够提供网络功能。因此,Tomcat 会在网络正常运行后才开始启动,以确保 Tomcat 可以正常访问网络。Type=forking
指定服务的启动类型。表示 Tomcat 启动时会创建一个子进程,并且在主进程退出时认为服务已经成功启动。这通常适用于像 Tomcat 这样的服务,它会在启动时创建一个子进程并返回控制。forking 类型的服务通常会启动一个后台进程,而系统认为主进程启动成功后就可以继续执行其他操作。如果 Tomcat 使用的是前台模式,则应使用 Type=simple,但 forking 是 Tomcat 的标准启动方式。Environment
是环境变量。其中JAVA_HOME
根据 Java 的实际安装路径进行更改。Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
设置 Tomcat 的 PID 文件路径。CATALINA_PID
环境变量指定 Tomcat 进程的 PID(进程 ID)文件路径。Tomcat 会将它的进程 ID 写入这个文件,用于后续的进程管理(如停止 Tomcat 时查找该 PID)。CATALINA_HOME
设置 Tomcat 的安装目录。CATALINA_BASE
设置 Tomcat 的基础目录。UMask=0007
设置文件权限掩码。用来设置新创建文件或目录的默认权限。0007
表示文件的权限是rwxr-----
,即文件的所有者可以读、写、执行,组成员可以读取和执行,但其他用户没有任何权限。这是为了确保只有tomcat
用户和tomcat
组能够访问 Tomcat 相关文件。RestartSec=10
设置服务崩溃后重新启动的延迟时间。指定了服务崩溃后等待 10 秒钟再重启。这是为了避免系统在服务崩溃时立即重启,给系统一些时间来恢复,避免频繁重启带来的资源消耗。Restart=always
设置服务崩溃后的重启策略。表示如果 Tomcat 服务停止(无论是正常停止还是崩溃),systemd
都会自动重启服务。这适用于需要持续运行的服务,确保 Tomcat 进程始终在线。WantedBy=multi-user.target
指定服务在启动时应该与哪个目标(target)关联。multi-user.target
是一个systemd
目标,表示系统处于多用户模式下,通常是在没有图形界面的服务器上。当你运行systemctl enable tomcat
时,Tomcat 会被配置为在系统进入multi-user.target
时自动启动,即在系统启动并进入多用户模式时,Tomcat 会自动启动。
编辑完成 service 文件以后,退出 vim 并保存。
启动 tomcat 服务
命令 systemctl daemon-reload
重新加载 systemd 配置,以便它能识别新创建的 tomcat.service
文件。
启动 tomcat 服务:systemctl start tomcat
。
如果需要重启:systemctl restart tomcat
。
检查 Tomcat 服务的状态:systemctl status tomcat
。
root@VM-0-17-ubuntu:/etc/systemd/system# systemctl status tomcat
● tomcat.service - Apache Tomcat Web Application Container
Loaded: loaded (/etc/systemd/system/tomcat.service; disabled; preset: enabled)
Active: active (running) since Wed 2024-11-27 19:40:03 CST; 9s ago
Process: 642898 ExecStart=/opt/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
Main PID: 642905 (java)
Tasks: 35 (limit: 4307)
Memory: 104.2M (peak: 104.7M)
CPU: 3.768s
CGroup: /system.slice/tomcat.service
└─642905 /usr/lib/jvm/java-21-openjdk-amd64/bin/java -Djava.util.logging.config.file=/opt/tomcat/conf/lo>
Nov 27 19:40:03 VM-0-17-ubuntu systemd[1]: Starting tomcat.service - Apache Tomcat Web Application Container...
Nov 27 19:40:03 VM-0-17-ubuntu startup.sh[642898]: Tomcat started.
Nov 27 19:40:03 VM-0-17-ubuntu systemd[1]: Started tomcat.service - Apache Tomcat Web Application Container.
lines 1-14/14 (END)
这时在本地浏览器中检查一下能否访问,http://IP_address:8080
,能够看到 tomcat 默认页面说明服务启动成功。
执行命令 systemctl enable tomcat
希望 Tomcat 在系统启动时自动启动。
systemctl stop tomcat
停止 tomcat 服务。
journalctl -u tomcat
查看 tomcat 的日志。
journalctl -u tomcat -f
查看 tomcat 的实时日志。
journalctl -u tomcat -n 100
查看近 100 条日志。
journalctl -u tomcat --since today
查看今天的日志。
journalctl -u tomcat --since "2024-11-01" --until "2024-11-10"
查看指定时间段的日志。
journalctl -u tomcat | grep "ERROR"
查看错误的日志。 |
管道将前面一条命令的输出作为参数传给后面一条命令,grep
筛选出带有 "ERROR" 的记录。
root@VM-0-17-ubuntu:/etc/systemd/system# systemctl enable tomcat
Created symlink /etc/systemd/system/multi-user.target.wants/tomcat.service → /etc/systemd/system/tomcat.service.
root@VM-0-17-ubuntu:/etc/systemd/system# systemctl status tomcat
● tomcat.service - Apache Tomcat Web Application Container
Loaded: loaded (/etc/systemd/system/tomcat.service; enabled; preset: enabled)
Active: active (running) since Wed 2024-11-27 19:40:03 CST; 5min ago
Main PID: 642905 (java)
Tasks: 35 (limit: 4307)
Memory: 111.1M (peak: 121.3M)
CPU: 5.504s
CGroup: /system.slice/tomcat.service
└─642905 /usr/lib/jvm/java-21-openjdk-amd64/bin/java -Djava.util.logging.config.file=/opt/tomcat/conf/lo>
Nov 27 19:40:03 VM-0-17-ubuntu systemd[1]: Starting tomcat.service - Apache Tomcat Web Application Container...
Nov 27 19:40:03 VM-0-17-ubuntu startup.sh[642898]: Tomcat started.
Nov 27 19:40:03 VM-0-17-ubuntu systemd[1]: Started tomcat.service - Apache Tomcat Web Application Container.
lines 1-13/13 (END)
至此,tomcat 的基本部署已经完成。
Tomcat webapps 文件目录
root@VM-0-17-ubuntu:/opt/tomcat/webapps# ls
docs examples host-manager manager ROOT
/opt/tomcat/webapps
是 Apache Tomcat 服务器的一个关键目录,用于存放和管理 Web 应用程序。
/opt/tomcat/webapps/
├── app1/
│ ├── WEB-INF/
│ │ ├── classes/ # Java 编译后的类文件
│ │ └── lib/ # 应用所依赖的 jar 包
│ ├── index.html # 主页 HTML 文件
│ └── ... # 其他资源
├── app2/
│ ├── WEB-INF/
│ │ ├── classes/ # Java 编译后的类文件
│ │ └── lib/ # 应用所依赖的 jar 包
│ ├── index.jsp # 主页 JSP 文件
│ └── ... # 其他资源
├── ROOT/ # 默认 Web 应用
│ ├── index.jsp
│ ├── ... # 默认的 Web 应用
└── ...
如果你希望将一个静态的网站部署到 tomcat,那么你只需要将所有的静态网站资源文件复制到 tomcat webapps 下的一个文件夹中。
部署一个静态网站
首先你的本地电脑上已经做好了一个静态网站。然后使用 scp 命令将静态网站所有的资源复制到服务器 /opt/tomcat/webapps/example
下:
创建一个 example 文件夹:
root@VM-0-17-ubuntu:/opt/tomcat/webapps# mkdir example
root@VM-0-17-ubuntu:/opt/tomcat/webapps# ls
docs example examples host-manager manager ROOT
root@VM-0-17-ubuntu:/opt/tomcat/webapps#
scp -i "/path/to/your/private_key/id_rsa" -r /path/to/your/web_resources/* ubuntu@IP_address_of_server:/opt/tomcat/webapps/example/
-
scp
使用 ssh 协议来进行文件传输。 -
-i
指定私钥文件的路径。 -
-r
递归复制:所有文件及子文件。 -
ubuntu@IP_address_of_server
用户名 ubuntu,@ 服务器 IP 地址。 -
:
冒号加目标路径。/d/public$ scp -i "/d/.ssh/my_rsa" -r ./* ubuntu@xxx.xxx.xxx.xxx:/opt/tomcat/webapps/example/
Enter passphrase for key '/d/.ssh/my_rsa':
scp: remote mkdir "/opt/tomcat/webapps/example/": Permission denied
上面的运行结果来看复制失败了,因为 /opt/tomcat/webapps/example/
是以 root 权限创建的文件夹,而 ubuntu 用户并没有权限来访问这个文件夹。可以先复制到 ubuntu 用户的某个地方,然后再复制到 example
目录下:
exit
命令退出之前 sudo -i
进入的 root 管理模式。
cd /home/ubuntu/
进入到 ubuntu 用户的目录下,mkdir example
创建文件夹。
再次使用 scp 命令进行复制:
/d/public$ scp -i "/d/.ssh/my_rsa" -r ./* ubuntu@xxx.xxx.xxx.xxx:/home/ubuntu/example/
Enter passphrase for key '/d/.ssh/my_rsa':
1.json 100% 736 2.8KB/s 00:00
hello-world.json 100% 3835 15.1KB/s 00:00
blog-author.json 100% 974 4.0KB/s 00:00
categories.json 100% 2 0.0KB/s 00:00
... ...
... ...
然后在服务器使用 cp 命令复制到 /opt/tomcat/webapps/example/
下:
ubuntu@VM-0-17-ubuntu:~/example$ sudo -i
root@VM-0-17-ubuntu:~# cp -r /home/ubuntu/example/* /opt/tomcat/webapps/example/
root@VM-0-17-ubuntu:~#
这里,我将我的博客网站所有的静态资源放在了 tomcat 下,那么,在浏览器输入 http://IP_address_of_server:8080/example/
就可以访问我的博客网站了。
tomcat 的配置文件
tomcat 的配置文件在 /opt/tomcat/conf/server.xml
。使用 vim 进行编辑。
找到:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
这里可以指定默认 web 应用。添加:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Context path="/" docBase="example" />
docBase="example"
用来指定默认的web应用。这样输入 http://xxx.xxx.xxx.xxx:8080
进行访问时就可以直接访问到 example 下的网站了,而不是 tomcat 的默认应用。
每次修改完配置文件,要重启 tomcat 服务才能生效。systemctl restart tomcat
。
将域名解析到服务器
首先你要有一个域名。
在你的域名供应商界面配置 DNS 解析,添加一条 A 记录(域名到 IPv4 地址),Name 栏填写你的域名,Value 栏填写你的服务器的公网 IP 地址。保存后,要等一段时间解析的记录才能生效,因为这条 A 记录要在 Internet 上传播一段时间,让所有的 DNS 服务器都能接收到这条 A 记录。
当这条 DNS A 记录在 Internet 上广泛传播以后,你在浏览器就可以通过域名来访问你的博客网站了。
在你的域名供应商的 DNS 界面,你也可以指定第三方 DNS 服务器来解析你的域名,这样,你的 DNS A 记录要配置在第三方 DNS 服务器上,而你的域名供应商 DNS 界面,要配置这个第三方 DNS 服务器提供的域名,具体情况下,这个第三方 DNS 服务器会告诉你怎么做。使用第三方 DNS 服务器来进行 DNS 解析,速度会更快一些。
有关 DNS 解析的原理,参见往期的文章 Linux: C语言发起 DNS 查询报文 和 Linux: C语言解析域名 两篇文章。
Tomcat 配置 SSL/TLS 证书
SSL/TLS 就是在 HTTP 协议上实现了加密,让你和服务器之间的通信变得更加安全。
Tomcat 是支持 http/2.0 协议的,但是 http/2.0 协议要求必须使用 SSL/TLS 加密,所以要想使用 h2 协议,首先配置 SSL/TLS 加密。
获取 SSL/TLS 证书
这里使用 certbot 来获取 SSL/TLS 证书。
由于我的博客网站 jackey-song.com 已经配置了一条 A 记录,所以本文演示的这台云服务器配置一个子域名 example,以获取 SSL/TLS 证书。配置子域名使用 A 记录,Name 栏填写 example,Value 栏填写云服务器的公网 IP 地址。
Ubuntu 上安装 certbot:
sudo apt update
sudo apt install certbot
安装成功后,执行 certbot -h
会打印帮助信息,以验证安装是否成功。
临时关闭 tomcat 服务,tomcat 会占用 8080 端口。systemctl stop tomcat
,然后使用命令检查 80 端口是否被占用 netstat -tuln | grep :80
。
进行下一步之前请确保你的域名已经指向了你的服务器,因为 certbot 的操作会验证域名的所有权,检验域名是否指向了云服务器。
执行命令:certbot certonly --standalone -d example.jackey-song.com
这是我服务器的域名,你要替换其中的 example.jackey-song.com
为你的域名。
执行命令后,按照提示输入你的 email 等操作,下面是完整过程:
root@VM-0-17-ubuntu:/opt/tomcat/conf# certbot certonly --standalone -d example.jackey-song.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): my_email_address@xxx.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf. You must agree in
order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Account registered.
Requesting a certificate for example.jackey-song.com
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.jackey-song.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.jackey-song.com/privkey.pem
This certificate expires on 2025-02-25.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
可以看到证书保存的文件路径:Certificate is saved at: /etc/letsencrypt/live/example.jackey-song.com/fullchain.pem
和 Key is saved at: /etc/letsencrypt/live/example.jackey-song.com/privkey.pem
。
certbot certonly --standalone -d example.jackey-song.com
命令解释:
certonly
参数告诉 Certbot 只执行证书的申请过程,而 不配置 Web 服务器。即,certonly 只会获取证书并将其保存在服务器上,而不会修改任何 Web 服务器配置或自动启用 HTTPS。--standalone
是 Certbot 的一种 验证方法,它允许 Certbot 在没有现有 Web 服务器的情况下验证域名的所有权。此选项启动一个临时的 Web 服务器,并在 80 端口上进行 HTTP 验证。- Certbot 会启动一个临时的 HTTP 服务器监听在 80 端口(或者 443 端口,如果你选择了 HTTPS 验证)。然后,它会向 Let's Encrypt 提交验证请求,Let's Encrypt 会尝试通过 HTTP 请求访问你服务器上生成的临时文件来验证你对域名的所有权。所以前面要关闭 tomcat 服务,并确定 80 端口没有被其他进程占用。如果不关闭 tomcat 服务,也可以使用其他命令:
certbot certonly --webroot -w /opt/tomcat/webapps/example -d yourdomain.com
,其中使用--webroot
参数时,Certbot 会将一个临时文件写入指定的 Web 根目录,然后通过 HTTP 请求验证域名。需要指定 -w 参数来告诉 Certbot 的 Web 根目录。根目录在之前 server.xml 配置中,已经指向了 example。如果你配置的是不同的根目录,这里要修改一下。
- Certbot 会启动一个临时的 HTTP 服务器监听在 80 端口(或者 443 端口,如果你选择了 HTTPS 验证)。然后,它会向 Let's Encrypt 提交验证请求,Let's Encrypt 会尝试通过 HTTP 请求访问你服务器上生成的临时文件来验证你对域名的所有权。所以前面要关闭 tomcat 服务,并确定 80 端口没有被其他进程占用。如果不关闭 tomcat 服务,也可以使用其他命令:
-d
是指定你要为其申请证书的域名。
Tomcat 配置 SSL/TLS 证书,实现 HTTPS,并启用 HTTP/2.0
首先转换证书为 Java Keystore (JKS) 格式。Tomcat 使用 Java Keystore 来存储 SSL/TLS 证书,所以我们需要将从 Let's Encrypt 获得的证书(PEM 格式)转换为 JKS 格式。
openssl pkcs12 -export -in /etc/letsencrypt/live/example.jackey-song.com/fullchain.pem -inkey /etc/letsencrypt/live/example.jackey-song.com/privkey.pem -out /etc/letsencrypt/live/example.jackey-song.com/keystore.p12 -name tomcat
该命令用于将 SSL 证书 和 私钥 合并为 PKCS#12 格式的文件,该文件可以包含证书(cert.pem)、私钥(privkey.pem)以及证书链(fullchain.pem)。命令中注意修改你的域名,和实际的证书路径。
-export
参数指定将证书和私钥导出到 PKCS#12 格式文件中。-in
指定包含 证书链(fullchain.pem)的输入文件。-inkey
指定包含 私钥(privkey.pem)的输入文件。私钥是和公钥匹配的密钥,用于加密和解密数据,是 SSL/TLS 通信中的关键部分。-out
指定输出的 PKCS#12 文件 (.p12
) 的路径。-name tomcat
指定在 PKCS#12 文件中的证书别名(Alias)。这个别名用于区分同一 keystore 文件中可能包含的多个证书。-name 参数是给证书设置一个标识符,以便在导入 keystore 时,能够根据该别名引用证书。
执行命令后,提示设置密码,该密码用于保证 keystore.p12 文件的安全,不设置密码直接按回车键:
root@VM-0-17-ubuntu:/opt/tomcat/conf# openssl pkcs12 -export -in /etc/letsencrypt/live/example.jackey-song.com/fullchain.pem -inkey /etc/letsencrypt/live/example.jackey-song.com/privkey.pem -out /etc/letsencrypt/live/example.jackey-song.com/keystore.p12 -name tomcat
Enter Export Password:
Verifying - Enter Export Password:
root@VM-0-17-ubuntu:/opt/tomcat/conf# ls /etc/letsencrypt/live/example.jackey-song.com
cert.pem chain.pem fullchain.pem keystore.p12 privkey.pem README
root@VM-0-17-ubuntu:/opt/tomcat/conf#
然后,将 PKCS12
格式的证书导入到 Java Keystore 中:
命令:keytool -importkeystore -destkeystore /opt/tomcat/conf/keystore.jks -srckeystore /etc/letsencrypt/live/example.jackey-song.com/keystore.p12 -srcstoretype PKCS12 -alias tomcat
参数说明:
-destkeystore /opt/tomcat/conf/keystore.jks
:指定目标 Java Keystore 文件的路径,通常是Tomcat/conf
目录下。-srckeystore /etc/letsencrypt/live/example.jackey-song.com/keystore.p12
:指定刚才生成的 PKCS12 文件。-srcstoretype PKCS12
:指定源文件类型是 PKCS12 格式。
执行该命令,提示输入密码,该密码用来保护 keystore.jks
文件的安全。Enter source keystore password:
后面输入的是 keystore.p12 文件的密码。
root@VM-0-17-ubuntu:/opt/tomcat/conf# keytool -importkeystore -destkeystore /opt/tomcat/conf/keystore.jks -srckeystore /etc/letsencrypt/live/example.jackey-song.com/keystore.p12 -srcstoretype PKCS12 -alias tomcat
Importing keystore /etc/letsencrypt/live/example.jackey-song.com/keystore.p12 to /opt/tomcat/conf/keystore.jks...
Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
root@VM-0-17-ubuntu:/opt/tomcat/conf# ls | grep .jks
keystore.jks
配置 server.xml 文件,使用 keystore.jks 文件
vim server.xml
找到 <Connector port="8080">
这一部分,将其重定向到 443
端口,后面添加支持 SSL/TLS 的内容:
xml
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443"
maxParameterCount="1000" />
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
port="443"
maxThreads="150"
SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="/opt/tomcat/conf/keystore.jks"
certificateKeystorePassword="changeit"
certificateKeyAlias="tomcat"
type="RSA" />
</SSLHostConfig>
</Connector>
certificateKeystorePassword="changeit"
这里密码要修改为keystore.jks
的保护密码。certificateKeyAlias="tomcat"
这里是指 PKCS#12 文件中的证书别名(Alias)。
检查确定 server.xml 的权限是 tomcat,ls -l /opt/tomcat/conf/server.xml
。如果不是,修改 server.xml 文件的权限:chown tomcat:tomcat /opt/tomcat/conf/server.xml
+ chmod 600 /opt/tomcat/conf/server.xml
。
这里注意,1024 以下的端口号(including 1024),非 root 权限是无法监听的,这里测试的话,先使用 root 用户运行 tomcat 。
在运行 tomcat 之前需要确认之前运行的 tomcat 进程已经关闭,否则可能因曾经运行的 tomcat 正在占用端口而无法监听。
ps aux | grep tomcat
命令查找 tomcat 进程:(ps aux | grep '[t]omcat'
该命令不会显示 grep 行,这里,[t]omcat
是一个正则表达式,它匹配包含 "tomcat" 的行,但因为 grep
命令行中的 "tomcat" 前面没有 t
(实际上是 grep --color=auto tomcat
),所以 grep
自身的行不会被匹配到。注意,这里的 t
是任意的,只是为了确保正则表达式不匹配到 grep
命令本身。你也可以使用其他字符,只要它不出现在你实际要搜索的字符串前面即可。)
root@VM-0-17-ubuntu:/opt/tomcat/conf# ps aux | grep tomcat
root 802473 0.0 0.0 6544 2304 pts/1 S+ 03:54 0:00 grep --color=auto tomcat
上面最后一条是 grep 命令本身自带了 tomcat。如果有其他信息如:
root@VM-0-17-ubuntu:/opt/tomcat/conf# ps aux | grep tomcat
root 782976 0.6 3.4 3560580 127812 pts/1 Sl 02:54 0:05 /usr/lib/jvm/java-21-openjdk-amd64/bin/java -Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -classpath /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/opt/tomcat -Dcatalina.home=/opt/tomcat -Djava.io.tmpdir=/opt/tomcat/temp org.apache.catalina.startup.Bootstrap start
root 787013 0.0 0.0 6544 2304 pts/1 S+ 03:07 0:00 grep --color=auto tomcat
则表明有正在运行的 tomcat 进程,这时候可以使用 systemctl stop tomcat
或者 /opt/tomcat/bin/shutdown.sh
来结束 tomcat 进程。亦或者直接使用 kill -9 782976
来杀死指定进程 782976
为指定进程的进程号(PID)。
每次重新启动 tomcat 前,检查端口占用情况使用 netstat -tuln
命令:确定 80 端口或者 443 没有被其他进程占用。netstat -tuln | grep 80
/ netstat -tuln | grep 443
。
root@VM-0-17-ubuntu:/opt/tomcat/conf# netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.54:53 0.0.0.0:* LISTEN
tcp6 0 0 :::22 :::* LISTEN
udp 0 0 127.0.0.54:53 0.0.0.0:*
udp 0 0 127.0.0.53:53 0.0.0.0:*
udp 0 0 10.0.0.17:68 0.0.0.0:*
udp 0 0 127.0.0.1:323 0.0.0.0:*
udp6 0 0 ::1:323 :::*
确定没有其他进程占用端口,或者曾经运行的 tomcat 进程全部关闭后,以 root 的权限手动启动 tomcat :/opt/tomcat/bin/startup.sh
,这时候查看端口 80 和 443 是否被监听,使用上面提到的命令。如果端口被监听,那么就可以在浏览器中通过域名访问你的网站了。
注意看,本文演示的 tomcat 10.1.33 版本,在配置中并没有指定使用 http/2.0 协议,但是从调试界面来看已经默认支持了 h2 协议了:
如果你做到这里,一切顺利,那么恭喜你,你已经取得了阶段性成果。
如果你无法访问你的网站,尝试配置防火墙放行 TCP:443 端口。iptables -A INPUT -p tcp --dport 443 -j ACCEPT
,之前的文章中也写了如何配置 Linux 防火墙。还要注意服务器供应商的控制台界面,也有个防火墙,也要放行 TCP:443 的流量。
如果运行 tomcat 出现错误,请执行 tail -f /opt/tomcat/logs/catalina.out
查看 tomcat 的日志文件,并查找相关错误信息以及解决方法。
解决无法监听 443 端口的问题
上面启动 tomcat 并不是以一个服务的形式启动,而是使用 root 权限,手动启动。因为 非 root 权限无法监听小于等于 1024 以下的端口,而配置 tomcat.service 文件时,使用 User=tomcat Group=tomcat
的权限来启动 tomcat,这导致 tomcat 没有足够的权限监听 443 端口。
为了解决这个问题,有以下方法:
-
可以修改 tomcat.service 文件,
User=root
以 root 权限来启动 tomcat,但是这样会带来风险,root 权限过大,如果 tomcat 的 web 应用有潜在的 bug ,会导致服务器遭受攻击。所以不推荐这么做。 -
还有一种方法,那就是赋予 Tomcat 绑定绑定到特权端口(<=1024)的权力,使用
setcap
命令:sudo setcap 'cap_net_bind_service=+ep' /usr/lib/jvm/java-21-openjdk-amd64/bin/java
因为 tomcat 使用的是 java 的运行环境,所以要赋予 java 绑定特权端口的权力。这样在以服务的形式启动 tomcat 的时候,就可以绑定 443 端口了。- 移除
java
绑定特权端口的权力,使用命令setcap -r /path/to/java
。 - 查看是否移除:
getcap /path/to/java
。
-
还有一种方法,tomcat 监听 8433 端口,然后使用反向代理。前提是代理具有监听 443 端口的权限,然后反向代理到 tomcat 的 8443 端口。比如 apache2,可以将 SSL/TLS 证书配置到 apache2,tomcat 不处理 https,只运行 http/1.1 ,然后将 apache2 反向代理到 tomcat 。
-
还还还还还还有一种方法,那就是 iptables 将来自443端口的流量转发到Tomcat实际监听的较高端口(例如8443)。这样,Tomcat可以在非特权端口上运行,而外部请求则通过iptables转发到该端口。
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443
该命令在NAT(网络地址转换)表的PREROUTING链上添加一条规则。-
-t nat
:指定要操作的表是NAT表。NAT表主要用于地址转换,包括源地址转换(SNAT)和目的地址转换(DNAT),以及端口重定向等。 -
-A PREROUTING
:表示向PREROUTING链添加(Append)一条规则。PREROUTING链用于处理进入本机之前、且尚未进行路由选择的数据包。 -
-p tcp
:指定要匹配的协议是TCP。这意味着该规则仅适用于TCP协议的数据包。 -
--dport 443
:指定目的端口为443。 -
-j REDIRECT
:指定匹配的数据包应该执行的动作是REDIRECT(重定向)。REDIRECT动作会将数据包重定向到本机的另一个端口上,而不是进行地址转换。 -
--to-port 8443
:指定重定向的目标端口是8443。这意味着所有目的端口为443的TCP数据包都会被重定向到本机的8443端口上。 -
iptables -t nat -L -n
查看 nat 表:root@VM-0-17-ubuntu:/opt/tomcat# iptables -t nat -L -n Chain PREROUTING (policy ACCEPT) target prot opt source destination REDIRECT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 redir ports 8443
-
systemctl restart tomcat
重启tomcat。root@VM-0-17-ubuntu:/opt/tomcat# netstat -tuln | grep 443 tcp6 0 0 :::8443 :::* LISTEN
可以看到只有 8443 端口在被监听,但是此时在浏览器仍然能使用 https 协议访问网站。
-
配置 server.xml 文件,使用证书文件
关于 server.xml 文件的配置:除了使用 keystore.jks 文件,也可以直接使用证书文件进行配置。至于你的 tomcat 是否支持这样做,请到 tomcat 查阅官方文档。
xml
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="443"
maxThreads="150"
SSLEnabled="true">
<SSLHostConfig>
<Certificate
certificateKeyFile="/path/to/privkey.pem"
certificateFile="/path/to/cert.pem"
certificateChainFile="/path/to/chain.pem"
type="RSA"
/>
</SSLHostConfig>
</Connector>
注意修改真实的证书文件的路径。同时确保 tomcat 用户有足够的权限访问这些文件,因为这些文件在创建的时候都是以 root 身份创建的。
文章到这里基本上算是结束了,下面的内容是使用 apache2 进行反向代理(一开始使用 apache2 会非常简单,所以 apache2 的反向代理放在最后)。
apache2 反向代理到 tomcat
使用 apache2 进行反向代理的话,就不需要 tomcat 配置证书了。cp server.xml server.xml.backup
将已经配置好证书的 server.xml
备份一下为 server.xml.backup
,server.xml 中删掉证书配置的 <Connector ... />
。
安装 apache2
sudo apt update
sudo apt install apache2
启动 apache2 服务
sudo systemctl start apache2
设置 apache2 开机自动启动
sudo systemctl enable apache2
编辑 apache2 配置文件
/etc/apache2/sites-available/my_conf.conf
,这里的配置文件名随意起,配置文件中写入如下内容:
xml
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerName example.jackey-song.com
# SSL配置开始
SSLCertificateFile /etc/letsencrypt/live/example.jackey-song.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.jackey-song.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.jackey-song.com/chain.pem
# 反向代理到 Tomcat
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>
</IfModule>
保存后退出 vim 。
然后执行 sudo a2ensite /etc/apache2/sites-available/my_conf.conf
启用配置文件。
systemctl reload apache2
systemctl restart apache2
systemctl enable apache2
sudo a2enmod proxy
启用代理模块。
sudo a2enmod proxy_http
sudo a2enmod ssl
启用 SSL。
sudo systemctl restart apache2
重启 apache2 。
由于配置了 apache2 反向代理,所以要移除 iptables
443 到 8443 的重定向。
root@VM-0-17-ubuntu:/etc/apache2/sites-available# iptables -t nat -L PREROUTING -v -n --line-numbers
Chain PREROUTING (policy ACCEPT 3686 packets, 117K bytes)
num pkts bytes target prot opt in out source destination
1 54 3104 REDIRECT 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 redir ports 8443
root@VM-0-17-ubuntu:/etc/apache2/sites-available# iptables -t nat -D PREROUTING 1
这时候,在浏览器通过域名访问网站,访问成功!apache2 反向代理配置成功!
证书过期更新
使用 certbot 会从 Let's Encrypt 获得免费的证书。在SSL/TLS证书过期前,Certbot能够自动化处理续订和更新过期的证书。Let's Encrypt颁发的证书通常有效期为90天。经常更换证书就像我们经常更新我们的账号密码一样,是为了安全起见。运行命令 sudo certbot renew --dry-run
,这个命令将模拟续订和更新证书的过程,但不会实际更新证书。它将显示哪些证书将被续订,以及续订过程中可能出现的任何错误。
openssl x509 -in /etc/letsencrypt/live/yourdomain.com/cert.pem -noout -text | grep -A2 "Not After"
该命令用于检查证书的过期日期。
如果想要让证书更新时,自动转换成 keystore.jks 格式,可以写一个 Bash 脚本来检查证书的过期日期,并在必要时执行转换步骤。
本文结束。离开前记得给本文一键三连,这篇文章写了很久,字数为 27000 多字。觉得本文有用的朋友,可以到我博客网站打赏一下博客文章,请我喝杯咖啡吧。
END