Debian 12 apt update GPG error: NO_PUBKEY

debian 11 版本更新 到 12,update出现两个错误。

,Hit:5 https://packages.microsoft.com/debian/12/prod bookworm InRelease

Err:5 https://packages.microsoft.com/debian/12/prod bookworm InRelease
The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY EB3E94ADBE1229CF

W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: https://packages.microsoft.com/debian/12/prod bookworm InRelease: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY EB3E94ADBE1229CF

解决办法:

1 下载 https://packages.microsoft.com/config/debian/12/prod.list 替换 /etc/apt/sources.list.d/microsoft-prod.list

2 直接修改 /etc/apt/sources.list.d/microsoft-prod.list 为以下内容:

deb [arch=amd64,arm64,armhf signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/debian/12/prod bookworm main

Hit:6 https://packages.sury.org/php bookworm InRelease

W: https://packages.sury.org/php/dists/bookworm/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.
W: Failed to fetch https://packages.microsoft.com/debian/12/prod/dists/bookworm/InRelease The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY EB3E94ADBE1229CF
W: Some index files failed to download. They have been ignored, or old ones used instead.

解决办法,执行以下命令:

sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg

powershell相关

查看别名

  • 使用Get-Command查看Alias的命令: Get-Command -CommandType Alias
  • 查看此Session中已经设定的所有别名:Get-Aliasgal
  • 查看某别名的原命令,如ls的原命令:Get-Alias ls
  • 查看某原命令的别名,如Get-ChildItem的别名:Get-Alias -Definition Get-ChildItem
  • 按属性获取别名:Get-Alias | Where-Object {$_.Options -Match "ReadOnly"}

Windows 中的兼容性别名

PowerShell 具有多个别名,使 UNIX 和 cmd.exe 用户可以在 Windows 中使用熟悉的命令。 下表显示了常用命令、相关的 PowerShell cmdlet 和 PowerShell 别名:

cmd.exe命令UNIX 命令PowerShell CmdletPowerShell 别名
cdchdircdSet-Locationslcdchdir
clsclearClear-Hostcls clear
copycpCopy-Itemcpicpcopy
deleraserdrmdirrmRemove-Itemrideleraserdrmrmdir
dirlsGet-ChildItemgcidirls
echoechoWrite-Outputwrite echo
mdmkdirNew-Itemni
movemvMove-Itemmimovemi
popdpopdPop-Locationpopd
pwdGet-Locationglpwd
pushdpushdPush-Locationpushd
renmvRename-Itemrniren
typecatGet-Contentgccattype

 备注

此表中的别名特定于 Windows。 某些别名在其他平台上不可用。 这是为了使本机命令能够在 PowerShell 会话中工作。 例如,未在 macOS 或 Linux 上将 ls 定义为 PowerShell 别名,以便运行本机命令而不是 Get-ChildItem

Windows 下GUI编辑工具 PowerShell ISE

单击“开始”,选择“Windows PowerShell”,然后单击“Windows PowerShell ISE”。 或者,可以在任何命令外壳或“运行”框中键入内容。powershell_ise.exe

Linux下安装 powershell

如果你已安装 .NET Core SDK,则可以轻松地安装 PowerShell 作为 .NET 全局工具

sh复制

dotnet tool install --global PowerShell

dotnet 工具安装程序将 ~/.dotnet/tools 添加到 PATH 环境变量中。 但是,当前运行的 shell 没有更新的 PATH。 应该可以通过键入 pwsh 从新 shell 启动 PowerShell。

systemctl is-enabled 检查服务是否开启自启动

systemctl 命令之后有很多选项和命令。罗列几个常用的命令。

#service --status-all

#列出全部服务
systemctl list-units --type=service

#查看一个服务的状态,列出有没有正在执行、开机时是否启动等信息。
systemctl status 服务名.service

#开启服务自启动,下次开机服务启动
systemctl enable 服务名.service

#禁用服务自启动,下次开机时,服务不会被启动
systemctl disable 服务名.service

#检查一个服务是否正在运行
systemctl is-active 服务名.service

#检查一个服务的设置,是否为自启动的
systemctl is-enabled 服务名.service


systemctl [command] [unit]

systemctl start  #立刻启动后面接的 unit。
systemctl stop  #立刻关闭后面接的 unit。
systemctl restart  #重启动服务,先关闭再启动的意思。
systemctl reload  #不关闭 unit 的情况下,重新载入配置文件,让设置生效。
systemctl kill  #杀死一个服务的所有子进程。
systemctl show  #列出 unit 的配置。
systemctl mask  #注销 unit,注销后你就无法启动这个 unit 了。
systemctl unmask  #取消对 unit 的注销。

systemctl daemon-reload #重新加载服务配置文件

如何从 Debian 10 (Buster) 升级到 Debian 11 (Bullseye)

先查看确认Debian的版本

cat /etc/os-release
cat /etc/debian_version
lsb_release -a

更新包存储库:

将 /etc/apt/sources.list 文件中的 buster 关键字替换为 bullseye

sudo sed -i 's/buster/bullseye/g' /etc/apt/sources.list

或者直接去这个地址生成一个sources.list文件,保存下来替换:

https://mirrors.ustc.edu.cn/repogen/

之后先更新下系统的软件包列表:

sudo apt update

再下一步,执行最小系统更新 upgrade --without-new-pkgs

执行完整的系统升级将删除系统中保留的大量软件包。因此,分两阶段的方法将 Debian 10 升级到 Debian 11。先进行最小升级,之后再进行完全升级。

在最小更新将只升级当前软件包,而不安装新软件包或删除现有软件包。执行以下命令:

sudo apt upgrade --without-new-pkgs

在此过程中,如果屏幕出现选择提示,要求重新启动系统服务或保留或删除配置选项。 一般都单击“是”,按回车键继续。

此步升级完成后,我们执行完整的系统升级(full-upgrade)将系统升级到 Debian 11。会安装 Debian 11 附带的最新软件包并解决依赖问题。

sudo apt full-upgrade

会再出现几次提示。比如Openssh提示做什么操作。选择了保留当前安装的选项,确定ok下一步。

等待完全升级完成,就可以重新启动系统了。

重启后,再查看系统发行版本信息。已经升级至Debian 11(bulleye)

cat /etc/os-release
cat /etc/debian_version
lsb_release -a

另外,wsl 下默认安装的debian执行“lsb_release -a”查看发行版本,会提示:“lsb_release: command not found”

需要执行安装 lsb_release

apt-get install -y lsb-release

VPS下检测虚拟化方式的工具

imvirt

http://micky.ibh.net/~liske/imvirt.html

virt-what

https://people.redhat.com/~rjones/virt-what/

另外,wsl下执行“lsb_release -a”查看发行版本,会提示:“lsb_release: command not found”

执行命令安装 lsb_release

apt-get install -y lsb-release

解决wsl两个子系统同时登录ssh,以及ping,sftp权限的问题

重装了windows的linux子系统,从wsl到wsl2,安装了一个kali,一个debian(其实这两个装一个就行了)

试试能不能ssh,发现没ssh服务,先安装

sudo apt install openssh-server
sudo systemctl start ssh

之后ssh上去之后,想改ssh端口,发现sftp编辑sshd_config文件提示“Permission denied”。给sshd_config加上权限,还不行,发现原来是sftp-server没权限。。。加上权限,可以编辑文件了。

sudo chmod u+s /usr/lib/openssh/sftp-server

设置ssh自启动

sudo systemctl enable ssh

查看子系统IP地址,ping自己一下也是没权限。加上权限

sudo chmod u+s /usr/bin/ping

然后同时开了kali,debian两个子系统的CMD窗口。查看ip,竟然两个子系统ip地址是一样的?没搞明白,怎么选择登录另一个子系统?是不是不能同时登录两个子系统呢?

先测试一下,打开两个子系统(顺序是先kali,再Debian),ssh登录22端口,连到的是第一个打开的子系统kali。再修改子系统kali的ssh端口到2022,再连22端口,连接失败,sudo service ssh restart 重启子系统Debian的ssh服务,再连22端口,Debian就连上了。这样两台子系统就可以同时ssh登录。

———————————————————————-

#如果Debian 中service 命令不存在,先安装 sysvinit-utils 包.

sudo apt-get install sysvinit-utils

如果已经安装,先在~/.bashrc 中添加 $PATH

PATH=$PATH:/usr/sbin

重启bash,service命令就可用了。

 service --status-all

Openwrt 一次自动更新全部软件包

1.使用 opkg 命令更新

opkg update
opkg upgrade luci 
opkg list-upgradable | grep luci- | cut -f 1 -d ' ' | xargs opkg upgrade

在ssh下,先“opkg update”,获取更新。之后再更新“ luci-” 开头的包。如果 要全部无条件更新,就去掉过滤“ grep luci- |”

2 使用 opkg-upgrade.sh 更新(推荐)

https://github.com/tavinus/opkg-upgrade

使用sh脚本更新,需要 curl 或 wget,使用Https链接的话,还需要SSL支持。

注意:curl / wget 可能会因为缺少 SSL 证书而失败。
您可以使用以下命令选择忽略证书检查:

curl -k
wget --no-check-certificate

或者,您将需要修复您的安装。
请注意,SSL支持会占用相当多的存储空间。/etc/ssl/certs/ca-certificates.crt

#这应该足以使SSL工作:

opkg install ca-certificates openssl-util

#如果您仍有问题,这可能是一种解决方法:

mkdir -p -m0755 /etc/ssl/certs && curl -k -o /etc/ssl/certs/ca-certificates.crt -L http://curl.haxx.se/ca/cacert.pem
  • 安装到当前目录,使用./opkg-upgrade.sh 执行:
# 根据使用 wget curl ,是否SSL,选择对应命令执行。

# using wget with SSL
wget 'https://raw.githubusercontent.com/tavinus/opkg-upgrade/master/opkg-upgrade.sh' -O "opkg-upgrade.sh" && chmod 755 "opkg-upgrade.sh"

# using wget WITHOUT SSL
wget --no-check-certificate 'https://raw.githubusercontent.com/tavinus/opkg-upgrade/master/opkg-upgrade.sh' -O "opkg-upgrade.sh" && chmod 755 "opkg-upgrade.sh"

# using curl with SSL
curl -L 'https://raw.githubusercontent.com/tavinus/opkg-upgrade/master/opkg-upgrade.sh' -o "opkg-upgrade.sh" && chmod 755 "opkg-upgrade.sh"

# using curl WITHOUT SSL
curl -k -L 'https://raw.githubusercontent.com/tavinus/opkg-upgrade/master/opkg-upgrade.sh' -o "opkg-upgrade.sh" && chmod 755 "opkg-upgrade.sh"
# 执行更新
./opkg-upgrade.sh
  • (推荐)安装到系统(无需.sh扩展):/usr/sbin/opkg-upgrade
# 根据使用 wget curl ,是否SSL,选择对应命令执行。

# using wget with SSL
wget 'https://raw.githubusercontent.com/tavinus/opkg-upgrade/master/opkg-upgrade.sh' -O "/usr/sbin/opkg-upgrade" && chmod 755 "/usr/sbin/opkg-upgrade"

# using wget WITHOUT SSL
wget --no-check-certificate 'https://raw.githubusercontent.com/tavinus/opkg-upgrade/master/opkg-upgrade.sh' -O "/usr/sbin/opkg-upgrade" && chmod 755 "/usr/sbin/opkg-upgrade"

# using curl with SSL
curl -L 'https://raw.githubusercontent.com/tavinus/opkg-upgrade/master/opkg-upgrade.sh' -o "/usr/sbin/opkg-upgrade" && chmod 755 "/usr/sbin/opkg-upgrade"

# using curl WITHOUT SSL
curl -k -L 'https://raw.githubusercontent.com/tavinus/opkg-upgrade/master/opkg-upgrade.sh' -o "/usr/sbin/opkg-upgrade" && chmod 755 "/usr/sbin/opkg-upgrade"
# 执行更新
opkg-upgrade

将更新命令加入自定义菜单

可以先安装 luci-app-commands

opkg install luci-app-commands

安装后,就可在luci的系统菜单中

使用自定义命令进行更新,一键就直接执行,更方便!如下图

这样就可以在 luci 界面,使用opkg-upgrade一键更新所有软件包了!

解决 snap 更新依赖关系错误

yum update , snap 更新出错。就解决如下,注意修改版本号

正在解决依赖关系
–> 正在检查事务
—> 软件包 snap-confine.x86_64.0.2.45.3.1-1.el7 将被 升级
—> 软件包 snap-confine.x86_64.0.2.47.1-1.el7 将被 更新
—> 软件包 snapd.x86_64.0.2.45.3.1-1.el7 将被 升级
—> 软件包 snapd.x86_64.0.2.47.1-1.el7 将被 更新
—> 软件包 snapd-selinux.noarch.0.2.45.3.1-1.el7 将被 升级
—> 软件包 snapd-selinux.noarch.0.2.47.1-1.el7 将被 更新
–> 正在处理依赖关系 selinux-policy-base >= 3.13.1-268.el7,它被软件包 snapd-selinux-2.47.1-1.el7.noarch 需要
–> 解决依赖关系完成
错误:软件包:snapd-selinux-2.47.1-1.el7.noarch (epel)
需要:selinux-policy-base >= 3.13.1-268.el7
已安装: selinux-policy-targeted-3.13.1-266.el7_8.1.noarch (@updates)
selinux-policy-base = 3.13.1-266.el7_8.1
可用: selinux-policy-minimum-3.13.1-266.el7.noarch (base)
selinux-policy-base = 3.13.1-266.el7
可用: selinux-policy-minimum-3.13.1-266.el7_8.1.noarch (updates)
selinux-policy-base = 3.13.1-266.el7_8.1
可用: selinux-policy-mls-3.13.1-266.el7.noarch (base)
selinux-policy-base = 3.13.1-266.el7
可用: selinux-policy-mls-3.13.1-266.el7_8.1.noarch (updates)
selinux-policy-base = 3.13.1-266.el7_8.1
可用: selinux-policy-targeted-3.13.1-266.el7.noarch (base)
selinux-policy-base = 3.13.1-266.el7
您可以尝试添加 –skip-broken 选项来解决该问题
您可以尝试执行:rpm -Va –nofiles –nodigest


首先:

package-cleanup --cleandupes
yumdownloader snapd-selinux-2.47.1-1.el7.noarch

之后:

rpm --force --nodeps -ivh snapd-selinux-2.47.1-1.el7.noarch.rpm

准备中… ################################# [100%]
正在升级/安装…
1:snapd-selinux-2.47.1-1.el7 ################################# [100%]

再次 yum update 成功!

openEuler-20.03-LTS 配置repo更新源

openEuler-20.03-LTS 更新出错
修改配置repo更新源
openEuler 与 华为云中的 EulerOS 不是同一个发行版本??

今天下载了华为的openEuler。装在电脑虚拟机里。

yum update 发现没有配置repo,于是想把Repo源换成华为的,按照 华为云操作 https://mirrors.huaweicloud.com/

在/etc/yum.repos.d目录下,创建文件EulerOS.repo,设置为

[base]
name=EulerOS-2.0SP5 base
baseurl=http://mirrors.huaweicloud.com/euler/2.5/os/x86_64/
enabled=1
gpgcheck=1
gpgkey=http://mirrors.huaweicloud.com/euler/2.5/os/RPM-GPG-KEY-EulerOS

然后update。显示出错:

[root@Euler ~]# yum update
Last metadata expiration check: 0:18:26 ago on 2020年04月14日 星期二 22时18分26秒
Error:
 Problem 1: cannot install both perl-Compress-Raw-Zlib-1:2.061-4.x86_64 and perl
  - package perl-IO-Compress-2.081-6.oe1.noarch requires perl(Compress::Raw::Zli
  - cannot install the best update candidate for package perl-Compress-Raw-Zlib-
  - problem with installed package perl-IO-Compress-2.081-6.oe1.noarch
 Problem 2: package perl-Time-HiRes-4:1.9725-3.x86_64 requires perl(:MODULE_COMP
  - cannot install both perl-4:5.16.3-285.h2.x86_64 and perl-4:5.28.0-434.oe1.x8
  - cannot install both perl-4:5.16.3-285.h4.x86_64 and perl-4:5.28.0-434.oe1.x8
  - cannot install both perl-4:5.16.3-285.h3.x86_64 and perl-4:5.28.0-434.oe1.x8
  - cannot install the best update candidate for package perl-Time-HiRes-1.9760-
  - problem with installed package perl-4:5.28.0-434.oe1.x86_64
 Problem 3: package python-2.7.5-58.h13.x86_64 obsoletes python2 provided by pyt
  - package python2-debug-2.7.16-15.oe1.x86_64 requires python2 = 2.7.16-15.oe1,
  - cannot install the best update candidate for package python2-2.7.16-15.oe1.x
  - problem with installed package python2-debug-2.7.16-15.oe1.x86_64
 Problem 4: package qemu-img-10:1.5.3-156.5.h2.x86_64 requires libiscsi.so.2()(6
  - cannot install both libiscsi-1.9.0-6.x86_64 and libiscsi-1.18.0-6.oe1.x86_64
  - cannot install the best update candidate for package qemu-img-2:4.0.1-11.oe1
  - problem with installed package libiscsi-1.18.0-6.oe1.x86_64
 Problem 5: package python2-debug-2.7.16-15.oe1.x86_64 requires python2-devel =
  - package python2-2.7.16-15.oe1.x86_64 requires libpython2.7_d.so.1.0()(64bit)
  - package python-devel-2.7.5-58.h13.x86_64 obsoletes python2-devel provided by
  - package python2-tkinter-2.7.16-15.oe1.x86_64 requires python2 = 2.7.16-15.oe
  - cannot install the best update candidate for package python2-devel-2.7.16-15
  - problem with installed package python2-tkinter-2.7.16-15.oe1.x86_64
(try to add '--allowerasing' to command line to replace conflicting packages or

如上面所示,update 总是出错。

然后换成 EulerOS-2.0SP3 base ,SP2,SP1 都是依然出错。

最后在 文档的 “系统安装”中找到一个 repo源 的链接:https://openeuler.org/zh/docs/20.03_LTS/docs/Releasenotes/%E7%B3%BB%E7%BB%9F%E5%AE%89%E8%A3%85.html

正确的repo源地址是:http://repo.openeuler.org/openEuler-20.03-LTS/OS/x86_64/

/etc/yum.repos.d/EulerOS.repo 配置为:

[base]
name=openEuler-20.03-LTS base
baseurl=https://repo.openeuler.org/openEuler-20.03-LTS/OS/x86_64/
enabled=1
gpgcheck=1
gpgkey=https://repo.openeuler.org/openEuler-20.03-LTS/OS/x86_64/RPM-GPG-KEY-openEuler

之后再次update成功!

yum clean all
yum makecache
yum update

openEuler-20.03-LTS base                                                                                                                                                            36 kB/s | 2.7 MB     01:18
Last metadata expiration check: 0:00:56 ago on 2020年04月14日 星期二 23时17分46秒.
Dependencies resolved.
Nothing to do.
Complete!

原因在于: openEuler 与 华为云中的 EulerOS 是两个不同的发行版本!!!

免费SSL证书 – Let’s Encrypt 与 certbot 延期

给网站加了SSL,用的 Let’s Encrypt 。后来看有效期只有90天,官网推荐用 certbot  延期,开始感觉挺麻烦,但看到一篇文章,写的很好,转贴留存一下!

文章出自:https://ksmx.me/letsencrypt-ssl-https/

现在用 Let’s EncryptStartSSL 的免费证书有效期是1年,1年后需要手动更换。配置过程还挺麻烦的。

更推荐 Let’s Encrypt,虽然有效期只有3个月,但可以用 certbot 自动续期,完全不受影响。而且 Let’s Encrypt 因为有了 certbot 这样的自动化工具,配置管理起来非常容易。

生成 Let’s Encrypt 证书

Let’s Encrypt 证书生成不需要手动进行,官方推荐 certbot 这套自动化工具来实现。3步轻松搞定:

  1. 下载安装 certbot (Let’s Encrypt项目的自动化工具)
  2. 创建配置文件
  3. 执行证书自动化生成命令

下面的教程运行在 Arch Linux 上,其他操作系统也大同小异。你可以在 certbot 网站上,选择你的 Web Server 和 操作系统,就能看到对应的安装和配置教程。

1. 下载安装 certbot

在 Arch Linux 上,安装很简单:

$ sudo pacman -Syu
$ sudo pacman -S certbot

2. 创建配置文件

先创建存放配置文件的文件夹:

$ sudo mkdir /etc/letsencrypt/configs

编辑配置文件:

$ sudo vim /etc/letsencrypt/configs/example.com.conf

把 example.com 替换成自己的域名,配置文件内容:

# 写你的域名和邮箱
domains = example.com
rsa-key-size = 2048
email = your-email@example.com
text = True

# 把下面的路径修改为 example.com 的目录位置
authenticator = webroot
webroot-path = /var/www/example

这里需要解释一下,上面配置文件用了 webroot 的验证方法,这种方法适用于已经有一个 Web Server 运行中的情况。certbot 会自动在 /var/www/example 下面创建一个隐藏文件 .well-known/acme-challenge ,通过请求这个文件来验证 example.com 确实属于你。外网服务器访问 http://www.example.com/.well-known/acme-challenge ,如果访问成功则验证OK。

我们不需要手动创建这个文件,certbot 会根据配置文件自动完成。

3. 执行证书自动化生成命令

一切就绪,我们现在可以运行 certbot 了。

$ sudo certbot -c /etc/letsencrypt/configs/example.com.conf certonly

## 片刻之后,看到下面内容就是成功了
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem.

如果运行顺利,所有服务器所需要的证书就已经生成好了。他们被放在了 /etc/letsencrypt/live/example.com/ 下:

$ ls /etc/letsencrypt/live/example.com/
cert.pem #server cert only
privkey.pem #private key
chain.pem #intermediates
fullchain.pem #server cert + intermediates

配置 Nginx 加入证书

到这里已经成功一大半了,只需要配置 Nginx 支持刚刚生成的证书。而且这个配置有最佳实践可以参考,访问:Mozilla SSL Configuration Generator,这是 Mozilla 搞得一个 HTTPS 配置文件自动生成器,支持 Apache,Nginx 等多种服务器。按照这个配置文件,选择 Intermediate 的兼容性。这里生成的配置文件是业界最佳实践和结果,让 Nginx 打开了各种增加安全性和性能的参数。

默认配置文件是这样的:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /path/to/signed_cert_plus_intermediates;
    ssl_certificate_key /path/to/private_key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /path/to/dhparam.pem;

    # intermediate configuration. tweak to your needs.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

    resolver <IP DNS resolver>;

    ....
}

请根据自己的服务配置修改和添加内容,重点只需要关注6行

server {
	listen 443 ssl http2;
	....
	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	ssl_dhparam /etc/nginx/ssl/dhparam.pem;

	ssl_trusted_certificate /etc/letsencrypt/live/example.com/root_ca_cert_plus_intermediates;

	resolver <IP DNS resolver>;
	....
}

这6行中,部分文件还不存在,逐个说明。

首先是第一行 listen 443 ssl http2; 作用是启用 Nginx 的 ngx_http_v2_module 模块 支持 HTTP2,Nginx 版本需要高于 1.9.5,且编译时需要设置 --with-http_v2_module 。Arch Linux 的 Nginx 安装包中已经编译了这个模块,可以直接使用。如果你的 Linux 发行版本中的 Nginx 并不支持这个模块,可以自行 Google 如何加上。

ssl_certificate 和 ssl_certificate_key ,分别对应 fullchain.pem 和 privkey.pem,这2个文件是之前就生成好的证书和密钥。

ssl_dhparam 通过下面命令生成:

$ sudo mkdir /etc/nginx/ssl
$ sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

(可选)ssl_trusted_certificate 需要下载 Let’s Encrypt 的 Root Certificates,不过根据 Nginx 官方文档 所说,ssl_certificate 如果已经包含了 intermediates 就不再需要提供 ssl_trusted_certificate,这一步可以省略:

$ cd /etc/letsencrypt/live/example.com
$ sudo wget https://letsencrypt.org/certs/isrgrootx1.pem
$ sudo mv isrgrootx1.pem root.pem
$ sudo cat root.pem chain.pem > root_ca_cert_plus_intermediates

resolver 的作用是 “resolve names of upstream servers into addresses”, 在這個配置中,resolver 是用來解析 OCSP 服務器的域名的,建议填写你的 VPS 提供商的 DNS 服务器,例如我的 VPN 在 Linode,DNS服务器填写:

resolver 106.187.90.5 106.187.93.5;

Nginx 配置完成后,重启后,用浏览器测试是否一切正常。

$ sudo systemctl restart nginx

这时候你的站点应该默认强制使用了 HTTPS,并且浏览器地址栏左边会有绿色的小锁:

自动化定期更新证书

Let’s Encrypt 证书有效期是3个月,我们可以通过 certbot 来自动化续期。

在 Arch Linux 上,我们通过 systemd 来自动执行证书续期任务。

$ sudo vim /etc/systemd/system/letsencrypt.service
[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --agree-tos
ExecStartPost=/bin/systemctl reload nginx.service

然后增加一个 systemd timer 来触发这个服务:

$ sudo vim /etc/systemd/system/letsencrypt.timer
[Unit]
Description=Monthly renewal of Let's Encrypt's certificates

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

启用服务,开启 timer:

$ sudo systemctl enable letsencrypt.timer
$ sudo systemctl start letsencrypt.timer

上面两条命令执行完毕后,你可以通过 systemctl list-timers 列出所有 systemd 定时服务。当中可以找到 letsencrypt.timer 并看到运行时间是明天的凌晨12点。

在其他 Linux 发行版本中,可以使用 crontab 来设定定时任务,自行 Google 吧。

用专业在线工具测试你的服务器 SSL 安全性

Qualys SSL Labs 提供了全面的 SSL 安全性测试,填写你的网站域名,给自己的 HTTPS 配置打个分。

如果你完全按照我上面教程配置,遵循了最佳实践,你应该和我一样得分是 A+