zoukankan      html  css  js  c++  java
  • https 自签名SSL证书

    介绍

    TLS或称传输层安全性,及其前身SSL(代表安全套接字层)是用于将正常流量包装在受保护的加密包装中的Web协议。

    使用这种技术,服务器可以在服务器和客户端之间安全地发送流量,而不会被外部各方拦截。证书系统还可以帮助用户验证他们正在连接的站点的身份。

    在本教程中,我们将向您展示如何设置自签名SSL证书,以便与Ubuntu 16.04服务器上的Nginx Web服务器一起使用。

    注意:自签名证书将加密服务器与任何客户端之间的通信。但是,由于Web浏览器不包含任何受信任的证书颁发机构的签名,因此用户无法使用该证书自动验证服务器的身份。

    如果您没有与服务器关联的域名以及加密Web界面不面向用户的实例,则可能需要使用自签名证书。

    准备

    在开始之前,您应该为非root用户配置sudo权限。您可以按照Ubuntu 16.04的初始服务器设置了解如何设置此类用户帐户。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器

    您还需要安装Nginx Web服务器。如果您想在服务器上安装整个LEMP(Linux,Nginx,MySQL,PHP)堆栈,可以按照我们在Ubuntu 16.04设置LEMP的教程进行操作。

    如果您只是想要Nginx Web服务器,您可以按照我们的指南在Ubuntu 16.04安装Nginx

    完成准备内容后,请继续以下操作。

    第一步:创建SSL证书

    TLS / SSL通过使用公共证书和私钥的组合来工作。SSL密钥在服务器上保密。它用于加密发送给客户端的内容。SSL证书与请求内容的任何人公开共享。它可用于解密由关联的SSL密钥签名的内容。

    我们可以在一个命令中使用OpenSSL创建自签名密钥和证书对:

    sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt

    您将被问到一系列问题。在我们讨论之前,让我们看看我们发出的命令中发生了什么:

    • openssl:这是用于创建和管理OpenSSL证书,密钥和其他文件的基本命令行工具。
    • req:此子命令指定我们要使用X.509证书签名请求(CSR)管理。“X.509”是SSL和TLS为其密钥和证书管理所遵循的公钥基础结构标准。我们想要创建一个新的X.509证书,所以我们使用这个子命令。
    • -x509:通过告诉实用程序我们要创建自签名证书而不是生成证书签名请求(通常会发生)来进一步修改上一个子命令。
    • -nodes:这告诉OpenSSL跳过用密码保护我们的证书的选项。当服务器启动时,我们需要Nginx能够在没有用户干预的情况下读取文件。密码短语会阻止这种情况发生,因为我们必须在每次重启后输入密码。
    • -days 365:此选项设置证书被视为有效的时间长度。我们在这里设置了一年。
    • -newkey rsa:2048:这指定我们要同时生成新证书和新密钥。我们没有创建在上一步中签署证书所需的密钥,因此我们需要将其与证书一起创建。该rsa:2048部分告诉它制作一个2048位长的RSA密钥。
    • -keyout:这一行告诉OpenSSL在哪里放置我们正在创建的生成的私钥文件。
    • -out:这告诉OpenSSL在哪里放置我们正在创建的证书。

    如上所述,这些选项将创建密钥文件和证书。我们将询问有关我们服务器的一些问题,以便将信息正确地嵌入到证书中。

    适当填写提示。 最重要的一行是Common Name (e.g. server FQDN or YOUR name)那一行。您需要输入与服务器关联的域名,或者是您服务器的公共IP地址。

    整个提示将如下所示:

    OutputCountry Name (2 letter code) [AU]:US
    State or Province Name (full name) [Some-State]:New York
    Locality Name (eg, city) []:New York City
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc.
    Organizational Unit Name (eg, section) []:Ministry of Water Slides
    Common Name (e.g. server FQDN or YOUR name) []:server_IP_address
    Email Address []:admin@your_domain.com

    您创建的两个文件都将放在/etc/ssl目录的相应子目录中。

    在我们使用OpenSSL的同时,我们还应该创建一个强大的Diffie-Hellman组,用于与客户协商Perfect Forward Secrecy

    我们可以通过输入以下内容来执行:

    sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

    这可能需要几分钟,但一旦完成,您将拥有一个强大的DH组/etc/ssl/certs/dhparam.pem,我们可以在我们的配置中使用。

    第二步:配置Nginx以使用SSL

    我们在/etc/ssl目录下创建了密钥和证书文件。现在我们只需要修改我们的Nginx配置就可以利用它们。

    我们将对配置进行一些调整。

    1. 我们将创建一个包含SSL密钥和证书文件位置的配置代码段。
    2. 我们将创建一个包含强SSL设置的配置代码段,可以在将来与任何证书一起使用。
    3. 我们将调整我们的Nginx服务器块来处理SSL请求并使用上面的两个片段。

    这种配置Nginx的方法将允许我们保持干净的服务器块并将常见配置段放入可重用模块中。

    创建指向SSL密钥和证书的配置代码段

    首先,让我们在/etc/nginx/snippets目录中创建一个新的Nginx配置代码段。

    为了正确区分此文件的目的,我们称之为self-signed.conf

    sudo nano /etc/nginx/snippets/self-signed.conf

    在这个文件中,我们只需要将ssl_certificate指令设置为我们的证书文件和ssl_certificate_key相关的密钥。在我们的教程中,是这样设置的:

    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

    添加这些行后,保存并关闭该文件。

    使用强加密设置创建配置代码段

    接下来,我们将创建另一个片段,用于定义一些SSL设置。这将使Nginx具有强大的SSL密码套件,并启用一些有助于保证我们的服务器安全的高级功能。

    我们将设置的参数可以在将来的Nginx配置中重用,因此我们将为该文件指定一个通用名称:

    sudo nano /etc/nginx/snippets/ssl-params.conf

    链接到上述网站的建议设置提供了强大的安全性。有时,这是以更高的客户端兼容性为代价的。如果您需要支持较旧的客户端,可以通过单击标记为“是的,给我一个与旧版/旧版软件一起使用的密码套件”的页面上的链接来访问该列表。该列表可以替换下面复制的项目。

    您使用哪种配置的选择在很大程度上取决于您需要支持的内容。它们都将提供很大的安全性。

    出于我们的目的,我们可以完整地复制提供的设置。我们只需要进行一些小的修改。

    首先,我们将为上游请求添加我们首选的DNS解析器。我们将使用Google。我们还将继续将ssl_dhparam设置为指向我们之前生成的Diffie-Hellman文件。

    最后,您应花点时间阅读HTTP严格传输安全性或HSTS,特别是有关“预加载”功能的信息。预加载HSTS可提高安全性,但如果意外启用或启用错误,可能会产生较大影响。在本教程中,我们不会预加载设置,但如果您确定了解其含义,则可以对其进行修改:

    # from https://cipherli.st/
    # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
    ​
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_ecdh_curve secp384r1;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    # Disable preloading HSTS for now.  You can use the commented out header line that includes
    # the "preload" directive if you understand the implications.
    #add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    ​
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

    由于我们使用的是自签名证书,因此不会使用SSL部署。Nginx只会输出警告,为我们的自签名证书禁用部署,并继续正常运行。

    完成后保存并关闭文件。

    调整Nginx配置以使用SSL

    现在我们已经有了我们的代码片段,我们可以调整我们的Nginx配置来启用SSL。

    我们将在本教程中假设您正在使用目录/etc/nginx/sites-available中的default服务器块文件。如果您使用的是其他服务器块文件,请在以下命令中替换它的名称。

    在我们继续之前,让我们备份当前的服务器块文件:

    sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak

    现在,打开服务器块文件进行调整:

    sudo nano /etc/nginx/sites-available/default

    在里面,您的服务器块可能像这样:

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
    ​
        # SSL configuration
    ​
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
    ​
        . . .

    我们将修改此配置,以便将未加密的HTTP请求自动重定向到加密的HTTPS中。这为我们的网站提供了最佳安全性。如果要同时允许HTTP和HTTPS流量,请使用后面的备用配置。

    我们将把配置分成两个独立的块。在第一个listen指令之后,我们将添加一个server_name指令,设置为服务器的域名,或者是IP地址。然后,我们将设置重定向到我们将要创建的第二个服务器块中。之后,我们将关闭这个短块:

    注意:我们将使用302重定向,直到我们确认一切正常。接下来,我们可以将其更改为永久301重定向。

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name server_domain_or_IP;
        return 302 https://$server_name$request_uri;
    }
    ​
        # SSL configuration
    ​
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
    ​
        . . .

    接下来,我们需要在下面直接启动一个新的服务器块以包含剩余的配置。我们可以取消注释使用443端口的两个listen指令。我们可以添加http2到这些行,以便在此块中启用HTTP / 2。接下来,我们只需要包含我们设置的两个代码段文件:

    注意:您可能只有一个 listen指令,其中包含每个IP版本和端口组合的default_server修饰符。如果您为这些端口启用了其他default_server设置的服务器块,则必须从其中一个块中删除修饰符。

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name server_domain_or_IP;
        return 302 https://$server_name$request_uri;
    }
    ​
    server {
    ​
        # SSL configuration
    ​
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;
        include snippets/self-signed.conf;
        include snippets/ssl-params.conf;
    ​
        . . .

    完成后保存并关闭文件。

    (备用配置)允许HTTP和HTTPS流量

    如果您想要或需要同时允许加密和未加密内容,则必须以不同方式配置Nginx。如果可以避免,通常不建议这样做,但在某些情况下可能是必要的。基本上,我们只要将两个单独的服务器块压缩为一个块并删除重定向:

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;
    ​
        server_name server_domain_or_IP;
        include snippets/self-signed.conf;
        include snippets/ssl-params.conf;
    ​
        . . .

    完成后保存并关闭文件。

    第三步:调整防火墙

    如果ufw启用了防火墙,则必须按照本教程准备 中的建议,调整设置以允许SSL流量。幸运的是, ufw在安装时注册了一些Nginx配置文件。

    我们可以通过输入以下内容来查看可用的配置文件

    sudo ufw app list

    您应该看到如下列表:

    Available applications:
      Nginx Full
      Nginx HTTP
      Nginx HTTPS
      OpenSSH

    您可以输入以下内容来查看当前设置:

    sudo ufw status

    它可能看起来像这样,这意味着只允许HTTP流量进入Web服务器:

    OutputStatus: active
    ​
    To                         Action      From
    --                         ------      ----
    OpenSSH                    ALLOW       Anywhere
    Nginx HTTP                 ALLOW       Anywhere
    OpenSSH (v6)               ALLOW       Anywhere (v6)
    Nginx HTTP (v6)            ALLOW       Anywhere (v6)

    为了进一步允许HTTPS流量,我们可以允许“Nginx Full”配置文件,然后删除冗余的“Nginx HTTP”配置文件限额:

    sudo ufw allow 'Nginx Full'
    sudo ufw delete allow 'Nginx HTTP'

    您的状态现在应该如下所示:

    sudo ufw status
    OutputStatus: active
    ​
    To                         Action      From
    --                         ------      ----
    OpenSSH                    ALLOW       Anywhere
    Nginx Full                 ALLOW       Anywhere
    OpenSSH (v6)               ALLOW       Anywhere (v6)
    Nginx Full (v6)            ALLOW       Anywhere (v6)

    第四步:启用Nginx中的更改

    现在我们已经进行了更改并调整了防火墙,我们可以重新启动Nginx以实现我们的新更改。

    首先,我们应该检查以确保我们的文件中没有语法错误。我们可以通过输入以下内容来执行:

    sudo nginx -t

    如果一切顺利,您将得到如下结果:

    Outputnginx: [warn] "ssl_stapling" ignored, issuer certificate not found
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

    注意开始前的警告。如前所述,由于我们的自签名证书无法使用SSL装订,因此此特定设置会发出警告。这是预期的,我们的服务器仍然可以正确加密连接。

    如果输出与上述内容匹配,则配置文件没有语法错误。我们可以安全地重启Nginx以实现我们的更改:

    sudo systemctl restart nginx

    第五步:测试加密

    现在,我们已准备好测试我们的SSL服务器。

    打开Web浏览器,然后在地址栏输入 https:// 及服务器的域名或IP:

    https://server_domain_or_IP

    由于我们创建的证书未由您的某个浏览器的受信任证书颁发机构签名,因此您可能会看到一个可怕的警告,如下所示:

    这是预期和正常的。我们只对证书的加密方面感兴趣,而不是对主机真实性的第三方验证感兴趣。单击“高级”,然后提供链接以继续进入您的主机:

    你应该被带到你的网站。如果你在浏览器地址栏中查看,你会看到一个带有“x”的锁。在这种情况下,这只意味着无法验证证书。它仍在加密您的连接。

    如果您使用两个服务器块配置Nginx,自动将HTTP内容重定向到HTTPS,您还可以检查重定向是否正常运行:

    http://server_domain_or_IP

    如果这结果是相同的图标,这意味着您的重定向工作正常。

    第六步:更改为永久重定向

    如果您的重定向工作正常并且您确定只想允许加密流量,则应修改Nginx配置以使重定向永久化。

    再次打开服务器块配置文件:

    sudo nano /etc/nginx/sites-available/default

    找到return 302并将其更改为return 301

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name server_domain_or_IP;
        return 301 https://$server_name$request_uri;
    }
    ​
    . . .

    保存并关闭文件。

    检查配置是否存在语法错误:

    sudo nginx -t

    准备好后,重新启动Nginx以使重定向永久化:

    sudo systemctl restart nginx

    https://cloud.tencent.com/developer/article/1346683

  • 相关阅读:
    Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor
    Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security
    IdentityServer4 And AspNetCore.Identity Get AccessToken 问题
    Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute
    Java Spring Boot VS .NetCore (七) 配置文件
    Java Spring Boot VS .NetCore (六) UI thymeleaf vs cshtml
    Java Spring Boot VS .NetCore (五)MyBatis vs EFCore
    Java Spring Boot VS .NetCore (四)数据库操作 Spring Data JPA vs EFCore
    Java Spring Boot VS .NetCore (三)Ioc容器处理
    Java Spring Boot VS .NetCore (二)实现一个过滤器Filter
  • 原文地址:https://www.cnblogs.com/aaron-agu/p/10560659.html
Copyright © 2011-2022 走看看