0
点赞
收藏
分享

微信扫一扫

2. Apache - 高级配置

爱写作的小土豆 2021-09-27 阅读 56

21. 多虚拟主机

多虚拟主机应用场景:

httpd支持在一台物理主机实现多个网站, 即多虚拟主机
对于访问量不是很大的网站, 可以在同一个主机配置不同的网站

网站的唯一标识:

ip相同, 但端口不同
ip不同, 但端口相同
FQDN不同, ip端口和端口都相同

多虚拟主机有三种实现方案:

1. 基于ip: 为每个虚拟主机准备至少一个ip地址, 在一台服务器上, 准备多个ip地址, 搭建多个独立的网站
2. 基于port: 为每个虚拟主机使用至少一个独立的port, 但是ip地址相同
3. 基于FQDN: 为每个虚拟主机使用至少一个FQDN, 利用请求报文首部的Host字段:www.apache.com

准备环境:

CentOS8, yum安装httpd, ip:10.0.0.84

1. 基于IP的虚拟主机

每个网站域名绑定一个公网IP, 都使用默认的80端口
主机网卡配置多个IP地址, 客户可以直接通过域名访问

缺点: 一个网站就需要一个公网IP

案例:

  1. 安装httpd服务, 设置默认页面
yum -y install httpd; systemctl enable --now httpd; echo default /var/www/html/index.html > /var/www/html/index.html
  1. 修改客户端hosts文件, 实现dns解析
10.0.0.85作为客户端, 修改其hosts文件

vim /etc/hosts
10.0.0.84   www.httpd.org
  1. 测试访问
[12:32:06 root@client ~]#curl www.httpd.org
default /var/www/html/index.html
  1. 实现基于ip地址的多虚拟主机

格式: 虚拟主机的配置文件, 建议放在独立的配置文件中

<VirtualHost IP:PORT>  # 虚拟主机语句块
ServerName FQDN # 主机头, 只在利用FQDN搭建虚拟主机时才起作用
DocumentRoot "/path" #网站文件目录
</VirtualHost>  # 虚拟主机语句块

案例: 实现基于ip地址的多虚拟主机, 搭建额外三个网站

添加网卡ip

10.0.0.81 第一个虚拟主机
10.0.0.82 第二个虚拟主机
10.0.0.83 第三个虚拟主机
10.0.0.84 默认站点
[12:32:54 root@apache ~]#ip a a 10.0.0.81/24 dev eth0 label eth0:1
[12:37:09 root@apache ~]#ip a a 10.0.0.82/24 dev eth0 label eth0:2
[12:37:13 root@apache ~]#ip a a 10.0.0.83/24 dev eth0 label eth0:3
[12:37:17 root@apache ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:1f:4a:0c brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.84/24 brd 10.0.0.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 10.0.0.81/24 scope global secondary eth0:1
       valid_lft forever preferred_lft forever
    inet 10.0.0.82/24 scope global secondary eth0:2
       valid_lft forever preferred_lft forever
    inet 10.0.0.83/24 scope global secondary eth0:3
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe1f:4a0c/64 scope link 
       valid_lft forever preferred_lft forever

没有做配置前, 通过这三个ip访问得到的都是上一步定义的默认页面

[12:38:10 root@apache ~]#curl 10.0.0.81
default /var/www/html/index.html
[12:38:14 root@apache ~]#curl 10.0.0.82
default /var/www/html/index.html
[12:38:15 root@apache ~]#curl 10.0.0.83
default /var/www/html/index.html
[12:38:16 root@apache ~]#curl 10.0.0.84
default /var/www/html/index.html
[12:38:18 root@apache ~]#curl www.httpd.org
default /var/www/html/index.html

给三个网站创建DocumentRoot, 制作默认页面

[12:38:22 root@apache ~]#mkdir /data/html/web_81 -pv
mkdir: created directory '/data/html'
mkdir: created directory '/data/html/web_81'
[12:39:09 root@apache ~]#mkdir /data/html/web_82 -pv
mkdir: created directory '/data/html/web_82'
[12:39:11 root@apache ~]#mkdir /data/html/web_83 -pv
mkdir: created directory '/data/html/web_83'

[12:39:13 root@apache ~]#echo /data/html/web_81/index.html  > /data/html/web_81/index.html
[12:39:44 root@apache ~]#echo /data/html/web_82/index.html  > /data/html/web_82/index.html
[12:39:49 root@apache ~]#echo /data/html/web_83/index.html  > /data/html/web_83/index.html

编辑虚拟主机配置文件

[12:39:53 root@apache ~]#vim /etc/httpd/conf.d/test.conf

<VirtualHost 10.0.0.81:80>
ServerName www.web_81.org   #基于ip地址的虚拟主机, 无需servername
DocumentRoot "/data/html/web_81"
<directory /data/html/web_81>
Require all granted
</directory>                                                                                                                                                                        
</VirtualHost>`
[12:44:15 root@apache ~]#systemctl restart httpd

客户端配置本地域名解析, 为了测试

10.0.0.81   www.web_81.org www.web_82.org www.web_83.org

测试访问:

可以看到, 无论访问哪个域名, 最终访问的都是10.0.0.81对应的页面, 因此, 证明了基于ip地址的虚拟主机, servername指令是不起作用的. 真正起作用的是域名解析到的ip地址

虽然81的servername是web_81, 但是访问web_82和web_83.org都能访问到10.0.0.81虚拟主机

[12:44:28 root@client ~]#curl www.web_81.org
/data/html/web_81/index.html
[12:44:30 root@client ~]#curl www.web_82.org
/data/html/web_81/index.html
[12:44:33 root@client ~]#curl www.web_83.org
/data/html/web_81/index.html

剩余两个虚拟主机配置

[12:45:52 root@apache ~]#vim /etc/httpd/conf.d/test.conf 

<VirtualHost 10.0.0.81:80>                                                                                                                                                          
ServerName www.web_81.org
DocumentRoot "/data/html/web_81"
<directory /data/html/web_81>
Require all granted
</directory>
</VirtualHost>

<VirtualHost 10.0.0.82:80>
#ServerName FQDN
DocumentRoot "/data/html/web_82"
<directory /data/html/web_82>
Require all granted
</directory>
</VirtualHost>


<VirtualHost 10.0.0.83:80>
#ServerName FQDN
DocumentRoot "/data/html/web_83"
<directory /data/html/web_83>
Require all granted
</directory>
</VirtualHost>

[12:45:49 root@apache ~]#systemctl restart httpd

修改客户端/etc/hosts文件, 实现域名和ip对应

10.0.0.84   www.httpd.org
10.0.0.81   www.web_81.org 
10.0.0.82   www.web_82.org 
10.0.0.83   www.web_83.org  

测试访问:

[12:47:16 root@client ~]#curl www.httpd.org
default /var/www/html/index.html
[12:47:38 root@client ~]#curl 10.0.0.81
/data/html/web_81/index.html
[12:47:43 root@client ~]#curl 10.0.0.82
/data/html/web_82/index.html
[12:47:44 root@client ~]#curl 10.0.0.83
/data/html/web_83/index.html
[12:47:45 root@client ~]#curl 10.0.0.84
default /var/www/html/index.html
[12:47:47 root@client ~]#curl www.web_81.org
/data/html/web_81/index.html
[12:47:55 root@client ~]#curl www.web_82.org
/data/html/web_82/index.html
[12:47:57 root@client ~]#curl www.web_83.org
/data/html/web_83/index.html

2. 基于端口号的虚拟主机

所有网站共用一个IP, 但是端口号不同, 用户访问时, 根据指定的端口号来访问对应的网站页面

缺点: 客户访问时, 需要在域名后面+端口号

案例:

准备环境, 把上一步添加的网卡ip清除

#重新加载在网卡即可
nmcli conn up eth0

配置基于端口号的虚拟主机, *:81, *:82, *;83, 服务器上所有ip的81,82,83端口, 实现三个虚拟主机
10.0.0.84:80 还是作为默认的站点

配置文件:

[12:46:22 root@apache ~]#vim /etc/httpd/conf.d/test.conf 
                                                                                                                                                      
listen 81             # 需要打开监听端口                                                                                                                                                              
listen 82
listen 83

<VirtualHost *:81>
ServerName www.web_81.org
DocumentRoot "/data/html/web_81"
<directory /data/html/web_81>
Require all granted
</directory>
</VirtualHost>

<VirtualHost *:82>
ServerName www.web_82.org
DocumentRoot "/data/html/web_82"
<directory /data/html/web_82>
Require all granted
</directory>
</VirtualHost>


<VirtualHost *:83>
ServerName www.web_83.org
DocumentRoot "/data/html/web_83"
<directory /data/html/web_83>
Require all granted
</directory>
</VirtualHost>

重启服务, 修改客户端hosts文件, 测试访问

[12:58:49 root@apache ~]#systemctl restart httpd

[12:55:46 root@apache ~]#ss -ntl
State                   Recv-Q                  Send-Q                                    Local Address:Port                                     Peer Address:Port                  
LISTEN                  0                       128                                             0.0.0.0:22                                            0.0.0.0:*                     
LISTEN                  0                       128                                                   *:80                                                  *:*                     
LISTEN                  0                       128                                                   *:81                                                  *:*                     
LISTEN                  0                       128                                                   *:82                                                  *:*                     
LISTEN                  0                       128                                                   *:83                                                  *:*                     
LISTEN                  0                       128                                                [::]:22                                               [::]:* 
10.0.0.84   www.httpd.org
10.0.0.84   www.web_81.org www.web_82.org www.web_83.org  
[12:59:41 root@client ~]#curl www.httpd.org
default /var/www/html/index.html
[13:00:46 root@client ~]#curl 10.0.0.84
default /var/www/html/index.html
[13:00:50 root@client ~]#curl www.web_81.org:81
/data/html/web_81/index.html
[13:01:02 root@client ~]#curl www.web_82.org:82
/data/html/web_82/index.html
[13:01:09 root@client ~]#curl www.web_83.org:83
/data/html/web_83/index.html
[13:01:11 root@client ~]#curl www.web_83.org:82
/data/html/web_82/index.html
[13:02:59 root@client ~]#curl www.web_83.org:80
default /var/www/html/index.html
[13:03:05 root@client ~]#curl www.web_83.org:81
/data/html/web_81/index.html
[13:03:11 root@client ~]#curl www.web_83.org
default /var/www/html/index.html

根据以上结果可以得出, 基于端口号的多虚拟主机, 和servername无关, 起作用的是端口号
无论客户端输入那个域名, 最终都会解析成10.0.0.84的ip地址, 最终能访问到哪个虚拟主机, 就看域名后面加的端口号. 不加端口, 就是访问默认的80主站点, 81就是web_81... 和servername无关

3. 基于FQDN

http请求报文头部会封装用户访问的网站名: host(http报文字段):网站名, 因此基于FQDN的虚拟主机可以根据网站名去分辨用户访问的是哪个网站, 而不是基于IP地址或端口. 这样达到在一个物理机, 一个IP上搭建多个网站.

[13:07:16 root@client ~]#telnet 10.0.0.84 80
Trying 10.0.0.84...
Connected to 10.0.0.84.
Escape character is '^]'.
GET /index.html HTTP/1.1
host: www.web_82.org      # 指定头部信息, 也就是要访问的网站域名

HTTP/1.1 200 OK
Date: Wed, 10 Mar 2021 05:08:51 GMT
Server: Apache/2.4.37 (centos)
Last-Modified: Wed, 10 Mar 2021 04:30:04 GMT
ETag: "21-5bd271ef0bd56"
Accept-Ranges: bytes
Content-Length: 33
Content-Type: text/html; charset=UTF-8

default /var/www/html/index.html
Connection closed by foreign host.

curl -v 查看详细报文.

[13:10:10 root@client ~]#curl -v www.web_82.org
* Rebuilt URL to: www.web_82.org/
*   Trying 10.0.0.84...
* TCP_NODELAY set
* Connected to www.web_82.org (10.0.0.84) port 80 (#0)
> GET / HTTP/1.1
> Host: www.web_82.org
> User-Agent: curl/7.61.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Wed, 10 Mar 2021 05:10:41 GMT
< Server: Apache/2.4.37 (centos)
< Last-Modified: Wed, 10 Mar 2021 04:30:04 GMT
< ETag: "21-5bd271ef0bd56"
< Accept-Ranges: bytes
< Content-Length: 33
< Content-Type: text/html; charset=UTF-8
< 
default /var/www/html/index.html
* Connection #0 to host www.web_82.org left intact
报文封装结构:

datalink-IP(10.0.0.84)-TCP-http(host:servername)-data

基于FQDN的虚拟主机注意事项:

设置了基于FQDN虚拟主机后, 如果还是用ip地址访问, 那么会显示排在虚拟主机第一位的网站, 而非默认页面.
用了FQDN虚拟主机后, 默认页面就失效了, 即使在服务器上访问自己的127地址, 也是显示配置文件中, 排在第一位的虚拟主机的页面. 而基于IP和端口号的, 默认页面还有效.

配置注意事项:

  • 任意目录下的页面只有显示授权才能被访问
  • 基于FQDN的虚拟主机, 需要做日志分离
  • 三种方式的虚拟主机可以混合使用
  • FQDN,公网访问只需要有多个域名即可, 在局域网内, 可以用基于IP或者端口的.

实现过程:

修改配置文件

<VirtualHost *:80>
ServerName www.web_81.org
DocumentRoot "/data/html/web_81"
<directory /data/html/web_81>
Require all granted
</directory>
</VirtualHost>

<VirtualHost *:80>
ServerName www.web_82.org
DocumentRoot "/data/html/web_82"
<directory /data/html/web_82>
Require all granted
</directory>
</VirtualHost>


<VirtualHost *:80>
ServerName www.web_83.org
DocumentRoot "/data/html/web_83"
<directory /data/html/web_83>
Require all granted
</directory>
</VirtualHost> 

systemctl restart httpd

客户端dns配置

10.0.0.84   www.httpd.org www.web_81.org www.web_82.org www.web_83.org

访问测试:

[13:17:26 root@client ~]#curl www.web_81.org
/data/html/web_81/index.html
[13:17:49 root@client ~]#curl www.web_82.org
/data/html/web_82/index.html
[13:17:52 root@client ~]#curl www.web_83.org
/data/html/web_83/index.html
[13:17:54 root@client ~]#curl www.httpd.org # 基于FQDN的虚拟主机, 默认页面会失效, 访问主站点域名, 实际会访问到在配置文件中定义的第一个虚拟主机网站
/data/html/web_81/index.html
[13:18:00 root@client ~]#curl 10.0.0.84
/data/html/web_81/index.html
[13:16:12 root@apache ~]#curl localhost
/data/html/web_81/index.html
# 无论是访问ip地址, 还是在服务器本地访问localhost, 都是访问的排在第一个的虚拟主机

实现日志分离, 每个网站都有单独的日志

只需在每个VirtualHost添加日志保存路径和定义格式即可, 这里使用默认格式, 实现,每个网站的日志, 放在自己的家目录下

日志存放路径需要指定绝对路径, 否则就是相对ServerRoot安装目录下的logs. 而安装目录下的logs实际是/var/log/httpd的软连接

先创建存放日志目录

[13:32:20 root@apache ~]#mkdir /data/html/web_81/logs
[13:32:30 root@apache ~]#mkdir /data/html/web_82/logs
[13:32:32 root@apache ~]#mkdir /data/html/web_83/logs

修改配置文件, 指定日志存放路径, 使用默认的combined格式

[13:19:32 root@apache ~]#vim /etc/httpd/conf.d/test.conf 

<VirtualHost *:80>
ServerName www.web_81.org
DocumentRoot "/data/html/web_81"
ErrorLog "/data/html/web_81/logs/web_81_error_log" 
CustomLog "/data/html/web_81/logs/web_81_access_log" combined
<directory /data/html/web_81>
Require all granted
</directory>
</VirtualHost>

<VirtualHost *:80>
DocumentRoot "/data/html/web_82"
ServerName www.web_82.org
ErrorLog "/data/html/web_82/logs/web_82_error_log"
CustomLog "/data/html/web_82/logs/web_82_access_log" combined
<directory /data/html/web_82>
Require all granted
</directory>
</VirtualHost>


<VirtualHost *:80>
DocumentRoot "/data/html/web_83"
ErrorLog "/data/html/web_83/logs/web_83_error_log"
CustomLog "/data/html/web_83/logs/web_83_access_log" combined
ServerName www.web_83.org
<directory /data/html/web_83>
Require all granted
</directory>                                                                                                                                                                        
</VirtualHost>

[13:32:34 root@apache ~]#systemctl restart httpd

查看效果

[13:32:43 root@apache ~]#tree /data/html/
/data/html/
├── web_81
│   ├── index.html
│   └── logs
│       ├── web_81_access_log
│       └── web_81_error_log
├── web_82
│   ├── index.html
│   └── logs
│       ├── web_82_access_log
│       └── web_82_error_log
└── web_83
    ├── index.html
    └── logs
        ├── web_83_access_log
        └── web_83_error_log

6 directories, 9 files

22. 压缩

apache默认没有开启压缩功能

服务端开启后, 传数据前会把数据进行压缩, 客户端和服务器会协商压缩算法, 客户端浏览器收到数据会自动解压缩.

注意: 在访问日志中, 显示的数据大小, 是不包括各层头部封装信息的, 只显示数据本身的大小

使用mod_deflate模块压缩页面优化传输速度

[13:38:25 root@apache ~]#ll /etc/httpd/modules/mod_deflate.so
-rwxr-xr-x 1 root root 36720 Nov  4 11:21 /etc/httpd/modules/mod_deflate.so

#将模块加载到配置文件
LoadModule deflate_module modules/mod_deflate.so

#如果是yum安装的httpd, 那么该模块是已经被加载的
00-base.conf:LoadModule deflate_module modules/mod_deflate.so

适用场景:

  • 节约广域网带宽, 但额外消耗服务器端CPU; 同时, 可能有些较老浏览器不支持
  • 压缩适合压缩的资源, 例如文本文件, 有些资源, 压缩效果不高, 而且压缩后很可能大小反而增加

定义压缩级别:

Deflate

案例:

开启压缩指令, 针对www.web_81.org进行压缩

<VirtualHost *:80>
ServerName www.web_81.org
DocumentRoot "/data/html/web_81"
ErrorLog "/data/html/web_81/logs/web_81_error_log"
CustomLog "/data/html/web_81/logs/web_81_access_log" combined
AddOutputFilterByType DEFLATE text/plain # 针对哪种MIME类型进行压缩, 是必须指定项
<directory /data/html/web_81>                                                                                                                                                       
Require all granted
</directory>
</VirtualHost>

重启服务

systemctl restart httpd

准备一个大文件, 放到web_81站点目录下

[14:58:41 root@apache ~]#ll /data/html/web_81/logs/messages.txt -h
-rw------- 1 root root 56M Mar 10 14:58 /data/html/web_81/logs/messages.txt

[14:58:48 root@apache ~]#chmod +r /data/html/web_81/logs/messages.txt  #由于文件默认是只有root能读, 因此还要修改权限

先用curl命令测试结果, 默认curl命令访问是不会被压缩的. 因为curl是个命令端浏览器, 无法像图形化浏览器一样辨别出服务器端是否压缩

[15:00:00 root@client ~]#curl www.web_81.org/logs/messages.txt
10.0.0.85 - - [10/Mar/2021:14:59:59 +0800] "GET /logs/messages.txt HTTP/1.1" 200 58180114 "-" "curl/7.61.1"

如果想让curl支持压缩, 需要加--compressed 选项

[14:50:24 root@client ~]#curl www.web_81.org/testfile.txt --compressed

10.0.0.85 - - [10/Mar/2021:15:03:38 +0800] "GET /logs/messages.txt HTTP/1.1" 200 7921479 "-" "curl/7.61.1"

再用浏览器测试

10.0.0.1 - - [10/Mar/2021:15:02:59 +0800] "GET /logs/messages.txt HTTP/1.1" 200 7921479 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0"
#可以看到,大小变成了7921479 

23. 实现https

注意: SSL是基于IP的地址实现, 单IP的httpd主机, 只能有一个https网站,或者基于一个虚拟主机的https网站. 如果多虚拟主机,访问不同的域名是无法通过https访问的, 即使通过curl -k跳过证书验证, 也是只能访问默认页面. Nginx可以解决该问题.

https通信过程:

1. 客户端发送可供选择的加密方式, 并向服务器请求证书
2. 服务器端发送证书, 以及选定的加密方式发给客户端
3. 客户端取得证书并进行证书验证, 如果信任给其发证书的CA
    a. 验证证书来源合法性: 用CA的公钥解密证书上数字签名
    b. 验证证书的内容的合法性: 完整性验证
    c. 检查证书的有效期限
    d. 检查证书是否被吊销
    e. 证书中拥有者的名字, 与访问的目标主机要一致
4. 客户端生成临时会话密钥(对沉秘钥), 并使用服务器端的公钥加密此数据发给服务器, 完成密钥交换
5. 服务器用此密钥加密用户请求的资源, 响应给客户端

实现apache基于https, 需要安装mod_ssl模块, 安装后, 重启服务, 会自动生成自签名证书和服务器私钥文件, 基于这个自签名证书和私钥, 就可以实现https访问. 但是由于是自签名证书, 因此客户端不会信任.

[16:05:07 root@apache ~]#yum -y install mod_ssl
[16:05:22 root@apache ~]#systemctl restart httpd
[16:06:03 root@apache ~]#ll /etc/pki/tls/private/
total 8
-rw-------  1 root root 1704 Mar 10 16:05 localhost.key
-rw-------. 1 root root 3243 Oct 29 18:20 postfix.key

[16:06:12 root@apache ~]#ss -ntl # httpd会自动开启
State                   Recv-Q                  Send-Q                                    Local Address:Port                                     Peer Address:Port                  
LISTEN                  0                       128                                             0.0.0.0:22                                            0.0.0.0:*                     
LISTEN                  0                       128                                                   *:80                                                  *:*                     
LISTEN                  0                       128                                                [::]:22                                               [::]:*                     
LISTEN                  0                       128                                                   *:443                                                 *:*   
[16:06:33 root@apache ~]#openssl x509 -in /etc/pki/tls/certs/localhost.crt  -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1213888900138231549 (0x10d89985f18766fd)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Unspecified, OU = ca-8641870554608572955, CN = CentOS-8-4, emailAddress = root@CentOS-8-4 # 证书发布者
        Validity
            Not Before: Mar 10 08:05:49 2021 GMT
            Not After : Mar 15 09:45:49 2022 GMT
        Subject: C = US, O = Unspecified, CN = CentOS-8-4, emailAddress = root@CentOS-8-4 # 给哪个域名用的证书, 默认有效期1年

如果是对外公网网站, 需要申请证书, 之后导入ssl.conf配置文件即可

这里用的是我在阿里云申请的免费证书

[16:20:41 root@apache ~]#ll
total 12
-rw-r--r-- 1 root root 1679 Sep 26 21:03 4555747_www.wangxiaoning.com_chain.crt # 上级CA信息
-rw-r--r-- 1 root root 1675 Sep 26 21:03 4555747_www.wangxiaoning.com.key # 私钥
-rw-r--r-- 1 root root 2013 Sep 26 21:03 4555747_www.wangxiaoning.com_public.crt # 证书
[16:20:42 root@apache ~]#mkdir /data/ssl
[16:21:16 root@apache ~]#mv 4* /data/ssl # 将证书放到/data/ssl目录下
[16:21:21 root@apache ~]#ll /data/ssl
total 20
-rw-r--r-- 1 root root 4462 Mar 10 16:19 4555747_www.wangxiaoning.com_apache.zip
-rw-r--r-- 1 root root 1679 Mar 10 16:19 4555747_www.wangxiaoning.com_chain.crt
-rw-r--r-- 1 root root 1675 Mar 10 16:19 4555747_www.wangxiaoning.com.key
-rw-r--r-- 1 root root 2013 Mar 10 16:19 4555747_www.wangxiaoning.com_public.crt

取消之前搭建的虚拟主机, 因为apache的https只能针对一个ip, 不支持虚拟主机

删除虚拟主机配置文件
重启服务测试即可
[16:21:58 root@apache ~]#rm -rf /etc/httpd/conf.d/test.conf 
[16:25:31 root@apache ~]#systemctl restart httpd

apache自带默认的https证书是自签名, 因此访问会提示安全风险

  1. 搭建一个本地站点, www.wangxiaoning.com ; 本地dns解析 10.0.0.84 www.wangxiaoning.com
注意: 证书文件和网站域名一定要匹配
[16:21:24 root@apache ~]#echo 'www.wangxiaoning.com' > /var/www/html/index.html

#Windows /etc/hosts文件
10.0.0.84 www.wangxiaoning.com
  1. 修改ssl配置文件/etc/httpd/conf.d/ssl.conf, 该配置文件会在安装mod_ssl模块, 重启httpd服务后自动生成.

默认证书路径: 默认指向了安装mod_ssl模块后生成的自签名证书和私钥



修改证书路径:

SSLCertificateFile /data/ssl/4555747_www.wangxiaoning.com_public.crt 
SSLCertificateKeyFile /data/ssl/4555747_www.wangxiaoning.com.key
SSLCertificateChainFile /data/ssl/4555747_www.wangxiaoning.com_chain.crt   #chain.crt指的是上级CA信息
  1. 重启服务验证


如果是企业内部网站, 可以自己搭建CA, 自己颁发证书, 节省成本

自建CA一键脚本

#!/bin/bash
CA_SUBJECT="/O=blog/CN=ca.blog.com"   #CA组织
SUBJECT="/C=CN/ST=liaoning/L=anshan/O=blog.org/CN=*.anshanblog.org"  #给哪个域名颁发
SERIAL=1
EXPIRE=203009
FILE=blog

openssl req -x509 -newkey rsa:2048 -subj ${CA_SUBJECT} -keyout ca.key -nodes -days $EXPIRE -out ca.crt

openssl req -newkey rsa:2048 -nodes -keyout ${FILE}.key -subj ${SUBJECT} -out ${FILE}.csr

openssl x509 -req -in ${FILE}.csr -CA ca.crt -CAkey ca.key -set_serial $SERIAL -days ${EXPIRE} -out ${FILE}.crt

chmod 600 ${FILE}.key ca.key

Generating a RSA private key
..............................+++++
.....................................................................+++++
writing new private key to 'ca.key'
-----
Generating a RSA private key
..+++++
...........+++++
writing new private key to 'blog.key'
-----
Signature ok
subject=C = CN, ST = liaoning, L = anshan, O = blog.org, CN = *.anshanblog.org
Getting CA Private Key

[16:40:04 root@apache ~]#ll
total 24
-rw-r--r-- 1 root root 1094 Mar 10 16:39 blog.crt
-rw-r--r-- 1 root root  993 Mar 10 16:39 blog.csr
-rw------- 1 root root 1704 Mar 10 16:39 blog.key
-rw-r--r-- 1 root root 1164 Mar 10 16:39 ca.crt
-rw------- 1 root root 1704 Mar 10 16:39 ca.key
-rw-r--r-- 1 root root  909 Mar 10 16:39 ca.sh

修改ssl.conf配置文件, 指明证书和私钥存放路径

[10:02:35 root@c8prac ~]#vim /etc/httpd/conf.d/ssl.conf 

#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateFile /root/blog.crt   

#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateKeyFile /root/blog.key 
#SSLCertificateChainFile /data/ssl/4555747_www.wangxiaoning.com_chain.crt  # ChainFile注释掉即可

#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt  #如果是自建CA, 那么因为证书直接由根CA颁发, 所以没有上级CA, 那么CA证书文件可以直接写在这里, 如果是互联网申请的CA, 在apache中需要把chain上级CA证书写到ChainFile指令中
SSLCACertificateFile /root/ca.crt

分别修改Windows和Linux客户端的hosts文件, 绑定10.0.0.84本机ip到www.anshanblog.org域名和db.anshanblog.org域名, 因为申请的证书是基于域名的, 因此同域名下的网站都可以使用该证书

10.0.0.84 www.anshanblog.org db.anshanblog.org
systemctl restart httpd

测试访问结果:

#curl命令需要加-k选项才能忽略ssl的证书验证
[16:53:09 root@client ~]#curl -k https://www.anshanblog.org
www.wangxiaoning.com
[17:07:35 root@client ~]#curl -k https://db.anshanblog.org
www.wangxiaoning.com

Windows浏览器访问: 因为是自建CA, 所以客户端不会信任, 需要手动添加CA到信任站点


如何信任ca?

将ca的证书导入客户端, 安装证书到受信任的机构即可

导入后, 有可能会是显示无效, 因此并不是认可授权的的CA

24. URL重定向

URL重定向: 即将http请求的URL转发至另一个URL

https跳转参数: strict-transport-security: max-age=0 #永远跳转, 以秒为单位

用户通过浏览器访问http页面时, 如果服务器支持https, 那么服务器会回复客户端, 本地支持https, 请用https访问. 0是默认值, 永久跳转, 跟的这个数值定义了浏览器在多长时间内(以秒为单位), 再次访问网站, 如果还是用http访问, 那么浏览器会自动补https. 这样下次用户在访问该网站时, 就不用等服务器回复客户端用https访问这一步操作了

[17:07:46 root@client ~]#curl -I http://www.taobao.com
HTTP/1.1 301 Moved Permanently 301永久重定向
Server: Tengine
Date: Wed, 10 Mar 2021 13:37:51 GMT
Content-Type: text/html
Content-Length: 278
Connection: keep-alive
Location: https://www.taobao.com/ #通过客户端浏览器, http已经被重定向到了https, 下次用https访问
Via: cache2.cn1452[,0]
Timing-Allow-Origin: *
EagleId: 7488871616153834710753802e

301-永久重定向, 客户端访问某个URL, 会被重定向到另一个URL, 这个重定向是永久的, 也就是当前访问的URL之后可能不会用了
302-临时重定向, 客户端访问某个URL, 会被重定向到另一个URL, 但是这个重定向是临时的, 也许一段时间后会修改回来

根据不同规划去设置.

301,302 vs strict-transport-security: max-age=0

301,302: 客户端访问一个URL时, 服务器会回复客户端, 请访问另一个URL, 并指明是301还是302. 之后客户端再访问新的URL. 客户端要发两次请求. 整个通信过程是三次交互

strict-transport-security: max-age=0 定义了当服务器支持https时, 如果客户端用http发起请求, 那么服务器会回复客户端本地支持https, 之后客户端在发起https请求, 当下次在访问时, 直接在浏览器内部做307内部跳转, 只要不超过max-age, 从浏览器再次访问http, 会自动访问https, 不会有301/302的在客户端和服务器之间的三次交互过程.

curl 只会显示301或者302但是不会真的跳转, 需要加-L选项才可以真跳转

用URL重定向, redirect缺点: 会出现循环一直跳转到的情况, 造成跳转次数过多而无法访问页面. 这是因为只要访问的是网站的/, 那么无论是通过http还是https访问, 那么都会继续转到https, 造成无线循环, 因此, 需要配合if条件判断, 只将http的访问转发到https上.

实现重定向指令, Redirect [status] URL-path URL

status状态:

  • permanent: 返回永久重定向状态码301, 此重定向信息会进行缓存到磁盘
  • temp: 返回临时重定向状态码302, 此为默认值

配置案例: 实现永久重定向

实现访问当前站点的根目录, 就会被永久重定向到baidu

[21:56:29 root@apache /etc/httpd/conf.d]#vim test.conf


Redirect permanent / https://www.baidu.com  

25. 实现HSTS

http strict transport security, 服务端配置支持HSTS后, 会在给浏览器返回的http首部中携带hsts字段. 浏览器获取到该信息后, 会将所有http访问请求在内部做307跳转到https. 而无需任何网络过程, 实现更高的安全性

用户第一次访问时, 服务器会告诉客户端进行跳转, 在有效期内再次访问时, 浏览器会在内部做307跳转到指定URL

案例:

Header always set Strict-Transport-Security "max-age=31536000"   #回复客户端, 下次访问http时,请直接访问https
RewriteEngine on   #重写访问地址, 直接在浏览器内部做307跳转                                                                                                                                
RewriteRule ^(/.*)$ https://%{HTTP_HOST}$1 [redirect=302] #定义访问网站的根时,就跳转到https, 302临时重定向 

26. sendfile机制

加速功能, 默认开启. 磁盘文件复制到内核关于磁盘的缓冲区, 再直接复制到内核网络缓冲区, 减少内核空间和用户空间的来回切换.

不适合启用sendfile的情况: 如果网站内容不是在服务器本地, 而且通过网络共享存储, 那么就不能用sendfile, 因为sendfile加速的是本地.

设置:

EnableSendfile on|off  #默认开启
举报

相关推荐

0 条评论