2018-09-22阿里云 ECS 服务器 CentOS 7.4 搭建 LAMP WordPress 环境:SSL

SSL 证书的安装

推荐使用的证书安装方式是 Let’s Encrypt 提供的 Certbot 自动脚本。(旧版本的 Certbot 称为 letsencrypt or letsencrypt-auto)

Certbot : 只支持 Unix-base 的系统,即 Linux 、Ubuntu、MacOS 等

阿里云的 SSL 证书,但现在已经没有免费的了。
腾讯云的 SSL 证书,不知道以后会不会收费了。

先去 Certbot 的官网:https://certbot.eff.org/

Certbot

意思就是在 什么 系统上使用 什么 HTTP 服务器,因为我的系统是 CentOS 7.4 所以选择 CentOS/RHEL 7 ,HTTP 服务器我选择的是 Apache 。( HTTP 服务器这块通常是选择 Apache 或者 Nginx 。)

Step 01

我的 CentOS 不是 EC2 实例

[root@~]# cat /sys/devices/virtual/dmi/id/product_uuid 
8113ECEB-...

如果没有 dmi 文件夹,就安装

[root@~]# sudo yum -y install dmidecode 

如果 UUID 是 ec2 开头的,就要运行以下两行指令

[root@~]# yum -y install yum-utils
[root@~]# yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional

Step 02

安装 Certbot

[root@~]# sudo yum -y install python2-certbot-apache
......
Total                                                                                                                                4.6 MB/s | 876 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python2-certbot-0.26.1-2.el7.noarch                                                                                                               1/4 
  Installing : certbot-0.26.1-2.el7.noarch                                                                                                                       2/4 
  Installing : 1:mod_ssl-2.4.6-80.el7.centos.1.x86_64                                                                                                            3/4 
  Installing : python2-certbot-apache-0.26.1-1.el7.noarch                                                                                                        4/4 
  Verifying  : certbot-0.26.1-2.el7.noarch                                                                                                                       1/4 
  Verifying  : python2-certbot-0.26.1-2.el7.noarch                                                                                                               2/4 
  Verifying  : 1:mod_ssl-2.4.6-80.el7.centos.1.x86_64                                                                                                            3/4 
  Verifying  : python2-certbot-apache-0.26.1-1.el7.noarch                                                                                                        4/4

Installed:
  python2-certbot-apache.noarch 0:0.26.1-1.el7                                                                                                                       

Dependency Installed:
  certbot.noarch 0:0.26.1-2.el7                    mod_ssl.x86_64 1:2.4.6-80.el7.centos.1                    python2-certbot.noarch 0:0.26.1-2.el7                   

Complete!

查看安装

[root@~]# ls /etc/ | grep "python"
python

[root@~]# yum list installed | grep "certbot"
certbot.noarch                      0.26.1-2.el7                    @epel       
python2-certbot.noarch              0.26.1-2.el7                    @epel       
python2-certbot-apache.noarch       0.26.1-1.el7                    @epel 

[root@~]# ls /etc/ | grep "letsencrypt"
letsencrypt

[root@~]# whereis certbot
certbot: /usr/bin/certbot

Step 03

开始生成 SSL 证书

[root@~]# sudo certbot --apache

如果 sudo certbot --apache 出错了:

[root@~]# sudo certbot --apache
Traceback (most recent call last):
  File "/bin/certbot", line 9, in <module>
    load_entry_point('certbot==0.26.1', 'console_scripts', 'certbot')()
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 570, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2751, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2405, in load
    return self.resolve()
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2411, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 18, in <module>
    from certbot import account
  File "/usr/lib/python2.7/site-packages/certbot/account.py", line 18, in <module>
    from acme import messages
  File "/usr/lib/python2.7/site-packages/acme/messages.py", line 7, in <module>
    from acme import challenges
  File "/usr/lib/python2.7/site-packages/acme/challenges.py", line 11, in <module>
    import requests
  File "/usr/lib/python2.7/site-packages/requests/__init__.py", line 58, in <module>
    from . import utils
  File "/usr/lib/python2.7/site-packages/requests/utils.py", line 32, in <module>
    from .exceptions import InvalidURL
  File "/usr/lib/python2.7/site-packages/requests/exceptions.py", line 10, in <module>
    from .packages.urllib3.exceptions import HTTPError as BaseHTTPError
  File "/usr/lib/python2.7/site-packages/requests/packages/__init__.py", line 95, in load_module
    raise ImportError("No module named '%s'" % (name,))
ImportError: No module named 'requests.packages.urllib3'

按以下命令操作,修复问题

[root@~]# cd /usr/lib/python2.7/site-packages/urllib3/packages/
[root@~]# sudo rm -rf ssl_match_hostname*
[root@~]# yum -y install python-urllib3.noarch

具体操作细节

[root@~]# cd /usr/lib/python2.7/site-packages/urllib3/packages/
[root@packages]# ls -la
total 48
drwxr-xr-x 4 root root 4096 Sep  3 18:23 .
drwxr-xr-x 5 root root 4096 Sep  3 18:23 ..
drwxr-xr-x 2 root root 4096 Oct 15  2017 backports
-rw-r--r-- 1 root root   74 Aug  7  2014 __init__.py
-rw-r--r-- 1 root root  275 Sep  3 18:15 __init__.pyc
-rw-r--r-- 1 root root 8935 Aug  7  2014 ordered_dict.py
-rw-r--r-- 1 root root 9868 Oct 15  2017 ordered_dict.pyc
lrwxrwxrwx 1 root root   12 Sep  3 18:23 six.py -> ../../six.py
lrwxrwxrwx 1 root root   13 Sep  3 18:23 six.pyc -> ../../six.pyc
lrwxrwxrwx 1 root root   13 Sep  3 18:23 six.pyo -> ../../six.pyo
drwxr-xr-x 2 root root 4096 Oct 15  2017 ssl_match_hostname
lrwxrwxrwx 1 root root   34 Sep  3 18:11 ssl_match_hostname;5b8d08dd -> ../../backports/ssl_match_hostname
lrwxrwxrwx 1 root root   34 Sep  3 18:20 ssl_match_hostname;5b8d0afa -> ../../backports/ssl_match_hostname
lrwxrwxrwx 1 root root   34 Sep  3 18:23 ssl_match_hostname;5b8d0b99 -> ../../backports/ssl_match_hostname

[root@packages]# sudo rm -rf ssl_match_hostname*
[root@packages]# sudo yum update python-urllib3.noarch
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Package(s) python-urllib3.noarch available, but not installed.
No packages marked for update
[root@izwz9dnfbgdn5tleje5eitz packages]# yum -y install python-urllib3.noarch
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package python-urllib3.noarch 0:1.10.2-5.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

==============================================================================================================
 Package                       Arch                  Version                        Repository           Size
==============================================================================================================
Installing:
 python-urllib3                noarch                1.10.2-5.el7                   base                102 k

Transaction Summary
==============================================================================================================
Install  1 Package

Total download size: 102 k
Installed size: 378 k
Downloading packages:
python-urllib3-1.10.2-5.el7.noarch.rpm                                                 | 102 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python-urllib3-1.10.2-5.el7.noarch                                                         1/1 
  Verifying  : python-urllib3-1.10.2-5.el7.noarch                                                         1/1 

Installed:
  python-urllib3.noarch 0:1.10.2-5.el7                                                                        

Complete!

重新运行 sudo certbot --apache

[root@~]# sudo certbot --apache
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): xxx@gmail.com // 如果有国外的邮箱,尽量使用国外,防止国内邮箱收件缓慢,
                       // 而且有时候会出现一些国内邮箱收不到件的问题。
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: 

直接用浏览器打开 https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf 就可以把文件下载下来;

直接用浏览器打开 https://acme-v02.api.letsencrypt.org/directory 可以查看里面的内容。这个文件是 ACME v2 的时候需要用到的,现在生成的证书是 ACME 的,ACME v2 后面会有介绍

{
  "OjTRjMzrdVo": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417",
  "keyChange": "https://acme-v02.api.letsencrypt.org/acme/key-change",
  "meta": {
    "caaIdentities": [
      "letsencrypt.org"
    ],
    "termsOfService": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf",
    "website": "https://letsencrypt.org"
  },
  "newAccount": "https://acme-v02.api.letsencrypt.org/acme/new-acct",
  "newNonce": "https://acme-v02.api.letsencrypt.org/acme/new-nonce",
  "newOrder": "https://acme-v02.api.letsencrypt.org/acme/new-order",
  "revokeCert": "https://acme-v02.api.letsencrypt.org/acme/revoke-cert"
}

我们继续,填入 a/A 同意就可以了

......
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: a
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing 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. // 大意:问你要不要把 Let's Encrypt 项目的工作的内容,发送到你的电子邮箱中去。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y // 这个看你自己了,我选 y 原因是,我选择了使用这个项目,我得了解这个项目,才能防止出现不可预估的问题。
Starting new HTTPS connection (1): supporters.eff.org
No names were found in your configuration files. Please enter in your domain
name(s) (comma and/or space separated)  (Enter 'c' to cancel): deepppixel.com  // 输入你的域名
Obtaining a new certificate
Resetting dropped connection: acme-v02.api.letsencrypt.org
Resetting dropped connection: acme-v02.api.letsencrypt.org
Performing the following challenges:
http-01 challenge for deepppixel.com
Cleaning up challenges
Unable to find a virtual host listening on port 80 which is currently needed for Certbot to prove to the CA that you control your domain. Please add a virtual host for port 80.

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

先备份 /etc/letsencrypt 文件夹

[root@~]# cp -rf /etc/letsencrypt/ /etc/.letsencrypt.backup/

[root@~]# ls /etc/.letsencrypt.backup/
accounts  csr  keys  options-ssl-apache.conf  renewal  renewal-hooks

[root@~]# ls /etc/letsencrypt/
accounts  csr  keys  options-ssl-apache.conf  renewal  renewal-hooks

如果出现下面的错误信息,则需要配置 Apache 的虚拟机

Unable to find a virtual host listening on port 80 which is currently needed for Certbot to prove to the CA that you control your domain. Please add a virtual host for port 80.

添加虚拟主机 Apache vhost

我使用的域名是 deepppixel.com,域名要添加解析哦。

我创建的是基于域名的虚拟主机,就是多个域名指向同一个服务器地址。

还有两种方式是:基于 IP 地址 和基于端口。

先创建保存虚拟主机配置的文件夹

// 虚拟主机的配置文件
[root@~]# mkdir -p /etc/httpd/conf/vhost

然后创建域名网站的内容文件夹

// 使用域名方便以后添加新的域名,不会产生冲突,不要随意命名,你会后悔的
[root@~]# mkdir -p /var/www/deepppixel.com

添加域名的 log 日志文件

[root@~]# touch /etc/httpd/logs/deepppixel.com-error_log
[root@~]# touch /etc/httpd/logs/deepppixel.com-access_log

把上面创建的虚拟主机路径添加到 Apache 的配置文件中

[root@~]# vim /etc/httpd/conf/httpd.conf
......
# vhost
Include conf/vhost/*.conf

开始添加虚拟主机文件

[root@~]# vim /etc/httpd/conf/vhost/deepppixel.com.conf
<VirtualHost 私网 IP:80>
    ServerName deepppixel.com
    ServerAlias deepppixel.com *.deepppixel.com
    DocumentRoot "/www/deepppixel.com"
    ErrorLog "/logs/deepppixel.com-error_log"
    CustomLog "/logs/deepppixel.com-access_log"
    <Directory "/www/deepppixel.com">
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>

检查 httpd.conf 是否有错

[root@~]# httpd -t
// 没有找到文件夹
AH00112: Warning: DocumentRoot [/www/deepppixel.com] does not exist 
// CustomLog 后面需要跟 两个或三个参数
AH00526: Syntax error on line 7 of /etc/httpd/conf/vhost/deepppixel.com.conf:
CustomLog takes two or three arguments, a file name, a custom log format string or format name, and an optional "env=" or "expr=" clause (see docs) 

出现了两个错误,修改如下

  2 <VirtualHost 私网 IP:80>
  3     ServerName deepppixel.com
  4     ServerAlias deepppixel.com *.deepppixel.com
    // 修改的 AH00112
  5     DocumentRoot "/var/www/deepppixel.com"
  6     ErrorLog "logs/deepppixel.com-error_log"
    // 修改的 AH00526
  7     CustomLog "logs/deepppixel.com-access_log" "%h %l %u %t \"%r\" %>s %b"
  8     <Directory "/www/deepppixel.com">
  9         Options Indexes FollowSymLinks
 10         AllowOverride None
 11         Require all granted
 12     </Directory>
 13 </VirtualHost>

重新检查即可

[root@~]# httpd -t
Syntax OK

重启 Apache 服务器

[root@~]# systemctl restart httpd.service

刷新网页,啊哦

403

首先,在没有配置虚拟机的时候,我们的网站是直接访问 var/www/html/ 下的文件,但是 Apache 在配置虚拟机后会直接访问虚拟机的配置,而忽略默认的配置信息;也就是说现在网站是直接访问 /var/www/deepppixel.com 目录下的文件的,但是下面什么也没有。

开始修复问题

// 权限没问题
[root@~]# ls -la /var/www/
total 20
drwxr-xr-x   5 root root 4096 Sep 13 16:44 .
drwxr-xr-x. 20 root root 4096 Sep  5 11:54 ..
drwxr-xr-x   2 root root 4096 Jun 27 21:49 cgi-bin
drwxr-xr-x   2 root root 4096 Sep 13 16:44 deepppixel.com
drwxr-xr-x   2 root root 4096 Sep 13 16:14 html
lrwxrwxrwx   1 root root   15 Sep  7 12:38 public -> /vagrant/public

// 开始创建 index.html 首页文件
[root@~]# touch /var/www/deepppixel.com/index.html

[root@~]# echo 'Apache HTTP Server... deepppixel.com Hello World !' > /var/www/deepppixel.com/index.html

[root@~]# cat /var/www/deepppixel.com/index.html
Apache HTTP Server... deepppixel.com Hello World !

[root@~]# systemctl restart httpd.service
403 ok

重新运行 sudo certbot --apache 指令

[root@~]# sudo certbot --apache
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: deepppixel.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 

我们刚才配置的虚拟机已经识别出来了

1: deepppixel.com

我们这里只有一个选项,所以填 1

......
blank to select all options shown (Enter 'c' to cancel):  1
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for deepppixel.com
Waiting for verification...
Cleaning up challenges
Created an SSL vhost at /etc/httpd/conf/vhost/deepppixel.com-le-ssl.conf
Deploying Certificate to VirtualHost /etc/httpd/conf/vhost/deepppixel.com-le-ssl.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// 不重定向 HTTP 到 HTTPS 
1: No redirect - Make no further changes to the webserver configuration.
// 全部把 HTTP 重定向到 HTTPS,并禁止 HTTP 的访问
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 

看看新的问题,我们是要做 HTTPS 的,所以直接选择 2

......
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting vhost in /etc/httpd/conf/vhost/deepppixel.com.conf to ssl vhost in /etc/httpd/conf/vhost/deepppixel.com-le-ssl.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://deepppixel.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=deepppixel.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/deepppixel.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/deepppixel.com/privkey.pem
   Your cert will expire on 2018-12-12. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - 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

如果你也看到了以上的信息 Congratulations! You have successfully enabled https://deepppixel.com 那么你成功了。证书就保存在 /etc/letsencrypt/live/deepppixel.com/ 下面

现在刷新你的网页

https

现在查看一个证书 ( Chrome 浏览器 )

https

因为 SSL 证书默认 90 天有效,所以要自己过期前更新证书,以下使用自动更新,每一天的半夜会自动运行更新操作

[root@~]# 0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew 

你是不是已经认为完了呢?

当然还没有啦!现在创建的只是 ACME 证书,现在最新的是 ACME v2 可以支持通配符 *.deepppixel.com

Step 04

我在 Certbot-DNS 里面选择了一个可以使用第三方登录的 DNS 插件,你也可以自行选择你喜欢的 DNS 。

我一开始选择的插件是 certbot-dns-cloudxns 但是要实名认证,其实没什么,只是实名认证老是提示信息错误没有具体原因,多次尝试无果,客服无果后,只能更换一个了。

我现在选用的是 certbot-dns-cloudflare ,先注册再看下面的图片,进行选择。

【图-01】中,红色框那里是可以跳转到一次添加多个域名的功能,这里只演示添加一个,所以我们填上面的框框,再点击确认。

图-01 Cloudflare - Web Performance & Security

【图-01】Add Site 后,直接 next 【图-02】再选择付费项 【图-03】,我选的是免费,之后它会自动加载你之前在注册商那边对应的域名所添加的 HTTP 解析记录【图-04】,如果还想增加解析,可以自行增加。

图-02 Cloudflare - Web Performance & Security next
图-03 Cloudflare - Web Performance & Security money
图-04 Cloudflare - Web Performance & Security 解析

直接点击 help 【图-05】选择 other 就会跳转到【图-06】按照 Setp 1 / 2 去域名注册服务商那里修改 DNS,我的域名是在腾讯那里注册的,所以我得去腾讯那里修改,修改方法【图-07】,修改完成后再回到 Cloudflare【图-06】点击 i`m done 即可。

图-05 Cloudflare - Web Performance & Security help nameservers
图-06 Cloudflare - Web Performance & Security 改 namexxx 步骤.jpg
图-07 cloudflare nameservers

完成修改后 点击 I`m done 后,会出现【图-08】。我们做那么多的目的就是要拿到 API key ,滚动到下面找到 Get your API Key 【图-09】(图8和图9是同一个页面),点开后进入 My Profile 滚动到最下面找到 API Keys 【图-10】点击 view 就可以拿到 API Keys 了。

这里有两个 API Keys ,Origin 是在公共服务器上使用的,我这边是个人的服务器,所以选择 Global 的 Keys。

图-08 Cloudflare - Web Performance & Security done
图-09 Cloudflare - Web Performance & Security api get
图-10 My Profile _ Cloudflare - Web Performance & Security

Step 05

开始进行 DNS 的安装

先安装 Certbot DNS 插件

yum 查找

[root@~]# yum search dns-cloudflare dns-cloudxns dns-digitalocean dns-dnsimple dns-dnsmadeeasy dns-google dns-linode dns-luadns dns-nsone dns-ovh dns-rfc2136 dns-route53
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * remi-php72: mirrors.tuna.tsinghua.edu.cn
 * remi-safe: mirrors.tuna.tsinghua.edu.cn
 * webtatic: uk.repo.webtatic.com
======================================== N/S matched: dns-cloudflare =========================================
python2-certbot-dns-cloudflare.noarch : Cloudflare DNS Authenticator plugin for Certbot

========================================= N/S matched: dns-cloudxns ==========================================
python2-certbot-dns-cloudxns.noarch : CloudXNS DNS Authenticator plugin for Certbot

======================================= N/S matched: dns-digitalocean ========================================
python2-certbot-dns-digitalocean.noarch : DigitalOcean DNS Authenticator plugin for Certbot

========================================= N/S matched: dns-dnsimple ==========================================
python2-certbot-dns-dnsimple.noarch : DNSimple DNS Authenticator plugin for Certbot

======================================== N/S matched: dns-dnsmadeeasy ========================================
python2-certbot-dns-dnsmadeeasy.noarch : DNS Made Easy DNS Authenticator plugin for Certbot

========================================== N/S matched: dns-google ===========================================
python2-certbot-dns-google.noarch : Google Cloud DNS Authenticator plugin for Certbot

========================================== N/S matched: dns-linode ===========================================
python2-certbot-dns-linode.noarch : Linode DNS Authenticator plugin for Certbot

========================================== N/S matched: dns-luadns ===========================================
python2-certbot-dns-luadns.noarch : LuaDNS Authenticator plugin for Certbot

=========================================== N/S matched: dns-nsone ===========================================
python2-certbot-dns-nsone.noarch : NS1 DNS Authenticator plugin for Certbot

============================================ N/S matched: dns-ovh ============================================
python2-certbot-dns-ovh.noarch : OVH DNS Authenticator plugin for Certbot

========================================== N/S matched: dns-rfc2136 ==========================================
python2-certbot-dns-rfc2136.noarch : RFC 2136 DNS Authenticator plugin for Certbot

========================================== N/S matched: dns-route53 ==========================================
python2-certbot-dns-route53.noarch : Route53 DNS Authenticator plugin for Certbot

  Name and summary matches mostly, use "search all" for everything.

或 pip 查找

[root@izwz9dnfbgdn5tleje5eitz ~]# pip search certbot | grep "certbot-dns-"
certbot-dns-luadns (0.27.1)              - LuaDNS Authenticator plugin for Certbot
certbot-dns-alwaysdata (0.24.0)          - Alwaysdata DNS Authenticator plugin for Certbot
certbot-dns-cloudflare (0.27.1)          - Cloudflare DNS Authenticator plugin for Certbot
certbot-dns-cloudxns (0.27.1)            - CloudXNS DNS Authenticator plugin for Certbot
certbot-dns-conoha (0.1.0)               - ConoHa DNS Authenticator plugin for certbot.
certbot-dns-digitalocean (0.27.1)        - DigitalOcean DNS Authenticator plugin for Certbot
certbot-dns-dnsimple (0.27.1)            - DNSimple DNS Authenticator plugin for Certbot
certbot-dns-dnspod (0.1.0)               - DNSPOD DNS Authenticator plugin for Certbot
certbot-dns-linode (0.27.1)              - Linode DNS Authenticator plugin for Certbot
certbot-dns-netcup (0.27.0.dev4)         - netcup DNS Authenticator plugin for Certbot
certbot-dns-nsone (0.27.1)               - NS1 DNS Authenticator plugin for Certbot
certbot-dns-openstack (0.0.1)            - OpenStack DNS Authenticator plugin for Certbot
certbot-dns-ovh (0.27.1)                 - OVH DNS Authenticator plugin for Certbot
certbot-dns-route53 (0.27.1)             - Route53 DNS Authenticator plugin for Certbot
certbot-dns-google (0.27.1)              - Google Cloud DNS Authenticator plugin for Certbot
certbot-dns-rfc2136 (0.27.1)             - RFC 2136 DNS Authenticator plugin for Certbot
certbot-dns-sakuracloud (0.27.1)         - Sakura Cloud DNS Authenticator plugin for Certbot
certbot-dns-dnsmadeeasy (0.27.1)         - DNS Made Easy DNS Authenticator plugin for Certbot
certbot-dns-gehirn (0.27.1)              - Gehirn Infrastracture Service DNS Authenticator plugin for Certbot
certbot-dns-cpanel (0.2.0)               - certbot plugin to allow acme dns-01 authentication of a name managed in cPanel.

查看 certbot 的插件表

[root@~]# certbot plugins
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* apache
Description: Apache Web Server plugin - Beta
Interfaces: IAuthenticator, IInstaller, IPlugin
Entry point: apache = certbot_apache.entrypoint:ENTRYPOINT

* standalone
Description: Spin up a temporary webserver
Interfaces: IAuthenticator, IPlugin
Entry point: standalone = certbot.plugins.standalone:Authenticator

* webroot
Description: Place files in webroot directory
Interfaces: IAuthenticator, IPlugin
Entry point: webroot = certbot.plugins.webroot:Authenticator
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

安装方案一: yum

yum 安装 certbot-dns-cloudflare

[root@~]# yum -y install python2-certbot-dns-cloudflare
......
Total                                                                         1.7 MB/s | 281 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python2-zope-interface-4.0.5-0.el7.noarch                                                  1/5 
  Installing : libyaml-0.1.4-11.el7_0.x86_64                                                              2/5 
  Installing : PyYAML-3.10-11.el7.x86_64                                                                  3/5 
  Installing : python2-cloudflare-2.1.0-2.el7.noarch                                                      4/5 
  Installing : python2-certbot-dns-cloudflare-0.26.1-1.el7.noarch                                         5/5 
  Verifying  : python2-cloudflare-2.1.0-2.el7.noarch                                                      1/5 
  Verifying  : libyaml-0.1.4-11.el7_0.x86_64                                                              2/5 
  Verifying  : PyYAML-3.10-11.el7.x86_64                                                                  3/5 
  Verifying  : python2-certbot-dns-cloudflare-0.26.1-1.el7.noarch                                         4/5 
  Verifying  : python2-zope-interface-4.0.5-0.el7.noarch                                                  5/5 

Installed:
  python2-certbot-dns-cloudflare.noarch 0:0.26.1-1.el7                                                        

Dependency Installed:
  PyYAML.x86_64 0:3.10-11.el7                         libyaml.x86_64 0:0.1.4-11.el7_0                        
  python2-cloudflare.noarch 0:2.1.0-2.el7             python2-zope-interface.noarch 0:4.0.5-0.el7            

Complete!

重新查看 Certbot 的插件列表会报错

[root@site-packages]# certbot plugins
An unexpected error occurred:
DistributionNotFound: The 'cloudflare>=1.5.1' distribution was not found and is required by the application
Please see the logfile '/tmp/tmpdXjGyi' for more details.

错误信息提示找不到 cloudflare,去除报错

[root@~]# yum -y install python2-cloudflare 

重新查看 Certbot 的插件列表

[root@~]# certbot plugins
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* apache
Description: Apache Web Server plugin - Beta
Interfaces: IAuthenticator, IInstaller, IPlugin
Entry point: apache = certbot_apache.entrypoint:ENTRYPOINT

* dns-cloudflare
Description: Obtain certificates using a DNS TXT record (if you are using
Cloudflare for DNS).
Interfaces: IAuthenticator, IPlugin
Entry point: dns-cloudflare =
certbot_dns_cloudflare.dns_cloudflare:Authenticator

* standalone
Description: Spin up a temporary webserver
Interfaces: IAuthenticator, IPlugin
Entry point: standalone = certbot.plugins.standalone:Authenticator

* webroot
Description: Place files in webroot directory
Interfaces: IAuthenticator, IPlugin
Entry point: webroot = certbot.plugins.webroot:Authenticator
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

安装方案二:pip

使用 pip 安装 certbot-dns-cloudflare

[root@~]# pip search certbot-dns-cloudflare | grep "certbot-dns-cloudflare"
certbot-dns-cloudflare (0.27.1)                       - Cloudflare DNS Authenticator plugin for Certbot

[root@~]# pip install certbot-dns-cloudflare
......
Installing collected packages: jsonlines, cloudflare, certbot-dns-cloudflare
  Running setup.py install for cloudflare ... done
Successfully installed certbot-dns-cloudflare-0.27.1 cloudflare-2.1.0 jsonlines-1.2.0

安装完成后重新查看 Certbot 的插件列表

[root@~]# certbot plugins
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* apache
Description: Apache Web Server plugin - Beta
Interfaces: IAuthenticator, IInstaller, IPlugin
Entry point: apache = certbot_apache.entrypoint:ENTRYPOINT

* dns-cloudflare
Description: Obtain certificates using a DNS TXT record (if you are using
Cloudflare for DNS).
Interfaces: IAuthenticator, IPlugin
Entry point: dns-cloudflare =
certbot_dns_cloudflare.dns_cloudflare:Authenticator

* standalone
Description: Spin up a temporary webserver
Interfaces: IAuthenticator, IPlugin
Entry point: standalone = certbot.plugins.standalone:Authenticator

* webroot
Description: Place files in webroot directory
Interfaces: IAuthenticator, IPlugin
Entry point: webroot = certbot.plugins.webroot:Authenticator
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

还有 pip 的问题,我一开始的时候用 pip 可以安装成功,为了演示我删除了,重新安装的时候提示 TypeError: cannot concatenate 'str' and 'NoneType' objects 就是很奇怪的问题,python 本身没有问题,所以我重新移除了 pip , 再安装 pip ,用 pip 安装 certbot-dns-cloudflare 就可以了。【可能是因为我的 pip 是从低版本直接升级引起的问题,这个错误信息官方提示已经修复过了,还有的话,肯定是 pip 自己的问题了】

移除 pip,并重新安装

[root@~]# yum list installed | grep "pip"
yum list installed *pip
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * remi-php72: mirrors.tuna.tsinghua.edu.cn
 * remi-safe: mirrors.tuna.tsinghua.edu.cn
 * webtatic: uk.repo.webtatic.com
Installed Packages
python2-pip.noarch                                                                 8.1.2-6.el7                                                                  @epel
[root@~]# yum remove python2-pip
[root@~]# yum search pip | grep 'python.*\-pip'
python-django-pipeline.noarch : An asset packaging library for Django
python2-pip.noarch : A tool for installing and managing Python 2 packages
python34-pip.noarch : A tool for installing and managing Python3 packages

选择相应的 Python 版本,安装即可

[root@~]# yum -y install python2-pip

如果 pip 安装 cloudflare 最后的安装信息是

......
Installing collected packages: certbot-dns-cloudflare
Successfully installed certbot-dns-cloudflare-0.27.1

证明还没有安装完成,还需要安装一些依赖

[root@~]# pip install cloudflare jsonlines

安装方案三:python [不推荐]

直接使用 git 下载到本地,再使用 python 安装

[root@~]# git clone https://github.com/certbot/certbot/
[root@~]# cd certbot/certbot-dns-cloudflare
[root@~]# python setup.py install

如果你上面没有安装成功,就要检查一下 Certbot 使用的版本啦!

[root@~]# head /usr/bin/certbot
#!/usr/bin/python2
......

我这边是 Python 2.x ,所以没有问题,如果检查出来是 Python 3 要注意版本问题,反过来道理也是一样的,反正就要用同一个版本的 Python 。

利用 API Keys 构建 ini 文件,首先创建一个隐藏的文件夹方便管理,再构建文件

[root@~]# mkdir -p ~/.secrets/certbot

[root@~]# vim ~/.secrets/certbot/cloudflare.ini

ini 文件中输入以下内容

# Cloudflare API credentials used by Certbot
dns_cloudflare_email = xxx@xxx.com // 你注册 Cloudflare 的邮箱
dns_cloudflare_api_key = API Keys    // 上面得到的 API Keys

使用 Certbot 进行配置和安装

[root@~]# certbot -a dns-cloudflare -i apache --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini --dns-cloudflare-propagation-seconds 60 -d "*.deepppixel.com" -d deepppixel.com --server https://acme-v02.api.letsencrypt.org/directory
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-cloudflare, Installer apache
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
You have an existing certificate that contains a portion of the domains you
requested (ref: /etc/letsencrypt/renewal/deepppixel.com.conf)

It contains these names: deepppixel.com

You requested these names for the new certificate: *.deepppixel.com,
deepppixel.com.

Do you want to expand and replace this existing certificate with the new
certificate?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(E)xpand/(C)ancel: 

由于我们有了 ACME 的证书,所以会有覆盖和扩展的问题。

先解释一下先(可以直接复制下面的指令粘贴运行的)

[root@~]# certbot \
  -a dns-cloudflare \
  -i apache \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
  --dns-cloudflare-propagation-seconds 60 \
  -d "*.deepppixel.com" \
  -d deepppixel.com \
  --server https://acme-v02.api.letsencrypt.org/directory

-a dns-cloudflare: 使用 certbot-dns-cloudflare DNS 插件,要改成你安装的 DNS 哦;

-i apache: 因为我们使用的是 Apache HTTP Server , 所以使用 Apache;

--dns-cloudflare-credentials: API Keys 的文件路径;

--dns-cloudflare-propagation-seconds 60: DNS 超时时间,默认就是 10s 可以不写;

-d "*.deepppixel.com":添加的域名,这个就是通配符的域名;

-d deepppixel.com: 裸域名;

--server https://acme-v02.api.letsencrypt.org/directory: 指定使用 ACME v2 ,如果不写就是 ACME (v1) 。

OK ! 继续,选择 e

......
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(E)xpand/(C)ancel: e
Renewing an existing certificate
Resetting dropped connection: acme-v02.api.letsencrypt.org
Performing the following challenges:
dns-01 challenge for deepppixel.com
dns-01 challenge for deepppixel.com
Unsafe permissions on credentials configuration file: /root/.secrets/certbot/cloudflare.ini
Starting new HTTPS connection (1): api.cloudflare.com
Starting new HTTPS connection (1): api.cloudflare.com
Waiting 60 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges
Starting new HTTPS connection (1): api.cloudflare.com
Starting new HTTPS connection (1): api.cloudflare.com

Which VirtualHosts would you like to install the wildcard certificate for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: File: /etc/httpd/conf/vhost/deepppixel.com-le-ssl.conf
Addresses: xxx:443
Names: deepppixel.com, *.deepppixel.com
HTTPS: Yes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 

看到这个信息 Waiting 60 seconds for DNS changes to propagate 不要胡乱操作,等就行了。

喜提新坑 Unsafe permissions on credentials configuration file: /root/.secrets/certbot/cloudflare.ini

先键入 c 取消操作

......
blank to select all options shown (Enter 'c' to cancel): c
No vhost exists with servername or alias for domain *.deepppixel.com. No vhost was selected. Please specify ServerName or ServerAlias in the Apache config.
No vhost selected

IMPORTANT NOTES:
 - Unable to install the certificate
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/deepppixel.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/deepppixel.com/privkey.pem
   Your cert will expire on 2018-12-13. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"

需要修改 ini 的文件权限,修改权限

[root@~]# chmod 600 ~/.secrets/certbot/cloudflare.ini

重新运行指令

[root@~]# certbot -a dns-cloudflare -i apache --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini --dns-cloudflare-propagation-seconds 60 -d "*.deepppixel.com" -d deepppixel.com --server https://acme-v02.api.letsencrypt.org/directory
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-cloudflare, Installer apache
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Cert not yet due for renewal

You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/deepppixel.com.conf)

What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Attempt to reinstall this existing certificate
// 用已经存在的证书重新安装
2: Renew & replace the cert (limit ~5 per 7 days)
// 更新或替换证书(只保存5~7天)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 

我们选择 2,又回到上面取消的步骤

......
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Renewing an existing certificate
Performing the following challenges:
dns-01 challenge for deepppixel.com
dns-01 challenge for deepppixel.com
Starting new HTTPS connection (1): api.cloudflare.com
Starting new HTTPS connection (1): api.cloudflare.com
Waiting 60 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges
Starting new HTTPS connection (1): api.cloudflare.com
Starting new HTTPS connection (1): api.cloudflare.com

Which VirtualHosts would you like to install the wildcard certificate for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: File: /etc/httpd/conf/vhost/deepppixel.com-le-ssl.conf
Addresses: xxx:443
Names: deepppixel.com, *.deepppixel.com
HTTPS: Yes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 

如果有两个以上的话,如:1:Filexxx 2:Filexxx 3: Filexxx ... 可以使用 1 空格 3 的方式只安装 1 和 3 ,如果想全部安装就直接 Enter 回车就可以了。因为我只有一个,所以我选择 1 并回车。

继续

......
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
Deploying Certificate to VirtualHost /etc/httpd/conf/vhost/deepppixel.com-le-ssl.conf
Deploying Certificate to VirtualHost /etc/httpd/conf/vhost/deepppixel.com-le-ssl.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 

上面的提示信息是不是很熟悉啊,直接选择 2 就可以啦

......
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Enhancement redirect was already set.
Enhancement redirect was already set.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Your existing certificate has been successfully renewed, and the new certificate
has been installed.

The new certificate covers the following domains: https://*.deepppixel.com and
https://deepppixel.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=*.deepppixel.com
https://www.ssllabs.com/ssltest/analyze.html?d=deepppixel.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/deepppixel.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/deepppixel.com/privkey.pem
   Your cert will expire on 2018-12-13. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - 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

直接刷新你的 https://www.deepppixel.com 网页,就可以啦!

重新查看一下证书

acme v2.jpg

当然也可以使用上面提到的网址 https://www.ssllabs.com/ssltest/analyze.html?d=你的的域名 去测试 SSL ,可以看到更多的信息。

SSL Server Test (Powered by Qualys SSL Labs)
SSL Server Test_ www.deepppixel.com (Powered by Qualys SSL Labs)

要等待它 100% complete 之后就会出现,下面还有很多信息的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容