标签归档:ssl

Nginx + Frp/Ngrok反向代理Webhook至本地

跟第三方平台打交道,经常需要设置一个接受通知的Webhook,比如微信/Skype的回调。它们要求有一个可以在互联网上访问得了的入口,比如某个域名,如果是在本地开发的话,不好调试。通常使用花生壳来代理本地服务,但是花生壳有一些限制,比如端口。有些域名服务商,比如DNSPOD,Linode,提供相应的API,也可以自己搭建DDNS服务,但是也可能有端口访问限制。Frp/Ngrok都是Go语言开发的内网穿透工具,可以自己部署搭建。Frp是国人开发的一款反向代理软件,可以转发请求给位于NAT后面的机器,支持TCP,UDP,HTTP/HTTPS。Ngrok则是国外的一款内网穿透软件,也支持HTTP/HTTPS转发。这里使用Nginx作为反向代理服务器,接收互联网回调并转发给本地的Frp/Ngrok服务,由它们接收webhook请求并转发至本地开发环境。
前面使用OpenVpn搭建了私有网络,可以在Nginx里面配置转发给目标机器就可以了

vim /etc/nginx/conf.d/100-dev.example.conf

内容如下

server {
    listen 80;
    server_name dev.example.com;
    return 301 https://$host$request_uri;
}

server {

    listen 443;
    server_name dev.example.com;

    ssl_certificate           /etc/letsencrypt/live/example.com/cert.pem;
    ssl_certificate_key       /etc/letsencrypt/live/example.com/privkey.pem;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    location / {
      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;

      proxy_pass          http://10.9.0.2/;
      proxy_redirect off;

    }
}

这里使用了let’s encryt的泛域名证书,官方并没有对应的插件,但是DNSPOD有提供相应的API,第三方开发了一个插件自certbot-dns-dnspod,安装这个插件并且配置Dnspod的API Token:

$ yum install certbot python2-certbot-nginx
$ certbot --nginx
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ pip install certbot-dns-dnspod
$ vim /etc/letsencrypt/dnspod.conf
certbot_dns_dnspod:dns_dnspod_email = "[email protected]"
certbot_dns_dnspod:dns_dnspod_api_token = "123,ca440********"

$ chmod 600 /etc/letsencrypt/dnspod.conf

手动请求证书

$ certbot certonly -a certbot-dns-dnspod:dns-dnspod --certbot-dns-dnspod:dns-dnspod-credentials /etc/letsencrypt/dnspod.conf --server https://acme-v02.api.letsencrypt.org/directory -d example.com -d "*.example.com"
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator certbot-dns-dnspod:dns-dnspod, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for example.com
dns-01 challenge for example.com
Starting new HTTPS connection (1): dnsapi.cn
Waiting 10 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.org

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2019-08-04. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
*/1 * * * * /usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &
 - 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


$ ls -la /etc/letsencrypt/live/example.com/
total 12
drwxr-xr-x 2 root root 4096 May  6 12:06 .
drwx------ 3 root root 4096 May  6 12:06 ..
lrwxrwxrwx 1 root root   34 May  6 12:06 cert.pem -> ../../archive/example.com/cert1.pem
lrwxrwxrwx 1 root root   35 May  6 12:06 chain.pem -> ../../archive/example.com/chain1.pem
lrwxrwxrwx 1 root root   39 May  6 12:06 fullchain.pem -> ../../archive/example.com/fullchain1.pem
lrwxrwxrwx 1 root root   37 May  6 12:06 privkey.pem -> ../../archive/example.com/privkey1.pem
-rw-r--r-- 1 root root  692 May  6 12:06 README

配置证书自动更新

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew

Frp的开发者已经提供了编译好的frp服务端和客户端,下载即可使用。这里使用docker来运行Frp服务,使用这个Dockerfile,更改版本号为0.26.0,并编译

$ docker build . -t frps:0.26
$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
frps                 0.26                8a87cb91d4de        2 hours ago         21.1MB

测试一下SSH代理服务,创建服务端配置文件

mkdir -p frp/conf
vim frp/conf/frps.ini

frps.ini内容

[common]
bind_port = 7000

运行一下frp服务端

#清除先前运行的容器
$ docker rm frp-server
$ docker run --name frp-server -v /root/frp/conf:/conf -p 7000:7000 -p 6000:6000 frps:0.26
2019/04/22 06:41:17 [I] [service.go:136] frps tcp listen on 0.0.0.0:7000
2019/04/22 06:41:17 [I] [root.go:204] Start frps success
2019/04/22 06:41:27 [I] [service.go:337] client login info: ip [110.87.98.82:61894] version [0.26.0] hostname [] os [linux] arch [386]
2019/04/22 06:41:27 [I] [tcp.go:66] [e8783ecea2085e15] [ssh] tcp proxy listen port [6000]
2019/04/22 06:41:27 [I] [control.go:398] [e8783ecea2085e15] new proxy [ssh] success
2019/04/22 06:41:41 [I] [proxy.go:82] [e8783ecea2085e15] [ssh] get a new work connection: [110.*.*.*:61894]

这里映射了2个端口,端口7000是frp服务端监听的端口,以便客户端能够连接上;端口6000是需要服务端监听这个端口,以便提供反向代理服务,比如SSH。如果使用的是腾讯云,相应的端口需要在安全组放行。
客户端直接下对应的包,里面有配置试例。创建本地配置文件frpc.ini如下

[common]
server_addr = 123.*.*.*
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

这个配置即告诉服务端,将服务端的6000端口转发到本地的22端口。本地运行

$ ./frpc -c ./frpc.ini.ssh 
2019/04/22 06:41:27 [I] [service.go:221] login to server success, get run id [e8783ecea2085e15], server udp port [0]
2019/04/22 06:41:27 [I] [proxy_manager.go:137] [e8783ecea2085e15] proxy added: [ssh]
2019/04/22 06:41:27 [I] [control.go:144] [ssh] start proxy success

然后在服务端连接客户端。这里连接的是服务端的6000端口,会被转发给远程(局域网内)主机

[rth@centos72]$ ssh -oPort=6000 vagrant@123.*.*.*
The authenticity of host '[123.*.*.*]:6000 ([123.*.*.*]:6000)' can't be established.
RSA key fingerprint is SHA256:NhBO/PDL***********************.
RSA key fingerprint is MD5:20:70:e2:*:*:*:*:*:*:*:*:*:*:*:*:*.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[123.*.*.*]:6000' (RSA) to the list of known hosts.
vagrant@123.*.*.*'s password:
Last login: Mon Apr 22 06:39:07 2019 from 10.0.2.2
[vagrant@centos64 ~]$ exit
logout
Connection to 123.*.*.* closed.

Frp转发http服务很简单。在conf目录下创建配置frps.ini监听本机来自8080端口的HTTP请求

[common]
bind_port = 7000
vhost_http_port = 8080

[root@VM_1_218_centos frp]# docker run --name frp-server -v /root/frp/conf:/conf -p 7000:7000 -p 8080:8080 frps:0.26
2019/05/06 07:26:28 [I] [service.go:136] frps tcp listen on 0.0.0.0:7000
2019/05/06 07:26:28 [I] [service.go:178] http service listen on 0.0.0.0:8080
2019/05/06 07:26:28 [I] [root.go:204] Start frps success
2019/05/06 07:26:51 [I] [service.go:337] client login info: ip [123.*.*.*:56758] version [0.26.0] hostname [] os [linux] arch [386]
2019/05/06 07:26:51 [I] [http.go:72] [19f60a30aa924343] [web] http proxy listen for host [test.example.com] location []
2019/05/06 07:26:51 [I] [control.go:398] [19f60a30aa924343] new proxy [web] success
2019/05/06 07:27:05 [I] [proxy.go:82] [19f60a30aa924343] [web] get a new work connection: [123.*.*.*:56758]
2019/05/06 07:27:05 [I] [proxy.go:82] [19f60a30aa924343] [web] get a new work connection: [123.*.*.*:56758]
2019/05/06 07:27:06 [I] [proxy.go:82] [19f60a30aa924343] [web] get a new work connection: [123.*.*.*:56758]

然后配置Nginx转发请求

$ vim /etc/nginx/conf.d/100-dev.example.conf

    location / {
      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;

      proxy_pass          http://127.0.0.1:8080/;
      proxy_redirect off;

    }

创建本地web传教客户端配置frpc.ini,将来自服务器dev.example.com:8080端口的HTTP请求转发至本地80端口

[common]
server_addr = 123.*.*.*
server_port = 7000

[web]
type = http
local_port = 80
custom_domains = dev.example.com

运行本地客户端

[root@vagrant-centos64 frp]# ./frpc -c ./frpc.ini
2019/05/06 07:26:51 [I] [service.go:221] login to server success, get run id [19f60a30aa924343], server udp port [0]
2019/05/06 07:26:51 [I] [proxy_manager.go:137] [19f60a30aa924343] proxy added: [web]
2019/05/06 07:26:51 [I] [control.go:144] [web] start proxy success
2019/05/06 07:27:37 [E] [control.go:127] work connection closed, EOF
2019/05/06 07:27:37 [I] [control.go:228] control writer is closing
2019/05/06 07:27:37 [I] [service.go:127] try to reconnect to server...

访问dev.example.com既可以看到本地web服务器页面。Frp还可以代理其他请求,也有在它基础上二次加工提供基于token认证的转发服务。
Ngrok 2.0以后不再开源,只能使用1.3版本的搭建。这里使用docker-ngrok来构建。Ngrok构建需要SSL证书,复制刚才生成的letsencypt证书并更改server.sh

$ git clone https://github.com/hteen/docker-ngrok
$ cp /etc/letsencrypt/live/example.com/fullchain.pem myfiles/base.pem
$ cp /etc/letsencrypt/live/example.com/fullchain.pem myfiles/fullchain.pem
$ cp /etc/letsencrypt/live/example.com/privkey.pem myfiles/privkey.pem

$ vim server.sh
#!/bin/sh
set -e

if [ "${DOMAIN}" == "**None**" ]; then
    echo "Please set DOMAIN"
    exit 1
fi

if [ ! -f "${MY_FILES}/bin/ngrokd" ]; then
    echo "ngrokd is not build,will be build it now..."
    /bin/sh /build.sh
fi


${MY_FILES}/bin/ngrokd -tlsKey=${MY_FILES}/privkey.pem -tlsCrt=${MY_FILES}/fullchain.pem -domain="${DOMAIN}" -httpAddr=${HTTP_ADDR} -httpsAddr=${HTTPS_ADDR} -tunnelAddr=${TUNNEL_ADDR}

构建Ngrok镜像

[root@VM_1_218_centos docker-ngrok]# docker build -t ngrok:1.3 .
[root@VM_1_218_centos docker-ngrok]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ngrok                1.3                 dc70190d6377        13 seconds ago      260MB
frps                 0.26                8a87cb91d4de        2 hours ago         21.1MB
alpine               latest              cdf98d1859c1        12 days ago         5.53MB

然后交叉编译生成Linux/Mac/Windows平台的客户端

$ rm -rf assets/client/tls/ngrokroot.crt
$ cp /etc/letsencrypt/live/example.com/chain.pem assets/client/tls/ngrokroot.crt
$ rm -rf assets/server/tls/snakeoil.crt
$ cp /etc/letsencrypt/live/example.com/cert.pem assets/server/tls/snakeoil.crt
$ rm -rf assets/server/tls/snakeoil.key
$ cp /etc/letsencrypt/live/example.com/privkey.pem assets/server/tls/snakeoil.key
$ GOOS=linux GOARCH=amd64 make release-client
$ GOOS=windows GOARCH=amd64 make release-client
$ GOOS=darwin GOARCH=amd64 make release-client

在服务器上运行Ngrok服务,将8090端口请求转发给容器的80端口,并且映射容器的4443端口到服务器的7000端口,以便客户端连接

[root@VM_1_218_centos docker-ngrok]# docker run --name ngrok -e DOMAIN='example.com' -p 8090:80 -p 8091:443 -p 7000:4443 -v /root/docker-ngrok/myfiles:/myfiles ngrok:1.3 /bin/sh /server.sh
[09:18:21 UTC 2019/05/07] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[09:18:21 UTC 2019/05/07] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:80
[09:18:21 UTC 2019/05/07] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:443
[09:18:21 UTC 2019/05/07] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443
[09:18:21 UTC 2019/05/07] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
[09:18:27 UTC 2019/05/07] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [tun:18e8cd42] New connection from 123.*.*.*:50529
[09:18:27 UTC 2019/05/07] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [tun:18e8cd42] Waiting to read message
[09:18:27 UTC 2019/05/07] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [tun:18e8cd42] Reading message with length: 125
[09:18:27 UTC 2019/05/07] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [tun:18e8cd42] Read message {"Type":"Auth","Payload":{"Version":"2","MmVersion":"1.7","User":"","Password":"","OS":"linux","Arch":"amd64","ClientId":""}}
[09:18:27 UTC 2019/05/07] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [ctl:18e8cd42] Renamed connection tun:18e8cd42
[09:18:27 UTC 2019/05/07] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [ctl] Registered control with id 1957f20b9b3ce3b76c7d8fc8b16276ed
[09:18:27 UTC 2019/05/07] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [ctl:18e8cd42] [1957f20b9b3ce3b76c7d8fc8b16276ed] Writing message: {"Type":"AuthResp","Payload":{"Version":"2","MmVersion":"1.7","ClientId":"1957f20b9b3ce3b76c7d8fc8b16276ed","Error":""}}
[09:18:27 UTC 2019/05/07] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [ctl:18e8cd42] [1957f20b9b3ce3b76c7d8fc8b16276ed] Writing message: {"Type":"ReqProxy","Payload":{}}
[09:18:27 UTC 2019/05/07] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [ctl:18e8cd42] [1957f20b9b3ce3b76c7d8fc8b16276ed] Waiting to read message

将刚才编译的客户端下载下来,创建grok.cfg,连接服务器的7000端口

server_addr: "example.com:7000"
trust_host_root_certs: false

指定要监听的域名,及本地web端口

./ngrok -config=ngrok.cfg -subdomain=dev 9010

ngrok                                                                                                                                                                                                                                                         (Ctrl+C to quit)
                                                                                                                                                                                                                                                                              
Tunnel Status                 online                                                                                                                                                                                                                                          
Version                       1.7/1.7                                                                                                                                                                                                                                         
Forwarding                    http://dev.flexkit.cn -> 127.0.0.1:9010                                                                                                                                                                                                         
Forwarding                    https://dev.flexkit.cn -> 127.0.0.1:9010                                                                                                                                                                                                        
Web Interface                 127.0.0.1:4040                                                                                                                                                                                                                                  
# Conn                        2                                                                                                                                                                                                                                               
Avg Conn Time                 46.84ms                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                                                              


HTTP Requests                                                         
-------------                                                         
                                                                      
GET /teams                    200 OK                   

请求dev.example.com即可以访问到本机9010端口的web服务。
附:ZeroTier是一个软件定义网络(SDN)软件,可以免费组建私有网络,当然也可以用来转发服务器请求至本地。

参考链接::
CentOS7搭建ngrok服务器
inconshreveable/ngrok
hteen/ngrok
搭建自己的 Ngrok 服务器, 并与 Nginx 并存
使用Docker部署Ngrok实现内网穿透
Laravel DDNS package,可代替花生壳之类的软件
通过DNSPod API实现动态域名解析
借助dnspod-api定时更新域名解析获取树莓派公网ip
使用Let’s Encrypt生成通配符SSL证书
Letsencrypt使用DNSPOD验证自动更新证书
在 OpenWrt 环境下使用 DnsPod 来实现动态域名解析
利用ssh反向代理以及autossh实现从外网连接内网服务器
How To Configure Nginx with SSL as a Reverse Proxy for Jenkins

Let’s encrypt

最近域名主机双双到期了,原来的服务商建议域名迁出,于是转移到了Godaddy,过程很顺利。主机迁到了linode,一个是因为它便宜,另一个是因为想给自己的网站加个SSL证书。
首先是服务器环境Apache, PHP, MaraiDB(MySQL)的配置。 linode 创建主机很简单,点点就好了,然后可以去启动机器,设置SSH访问。

yum update
yum install httpd php php-cli php-mbstring php-pdo php-mysql php-gd php-tidy

启动Apache

systemctl start httpd.service
systemctl enable httpd.service

然后直接访问你的服务器ip,可以看到默认的欢迎界面

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'
curl 1.139.x.x

CentOS 7目前默认不提供Mysql Server,而是Mariadb。MySQL的命令行仍然可以使用并兼容, PHP仍然可以使用PDO及MySQL扩展访问它。

yum install mariadb-server mariadb
systemctl start mariadb

然后设置管理员密码及安全设置

mysql_secure_installation

开机启动Mariadb服务

systemctl enable mariadb.service

可以在/var/www/html目录下创建一个测试脚本来验证安装情况

<?php
phpinfo();

WordPress则是从原本的数据库全部导出,文件全部打包回来。
在Linode上创建对应的数据库,用户及导入脚本

MariaDB [(none)]> CREATE database courages_wordpress;

MariaDB [(none)]> CREATE USER courages_wp IDENTIFIED BY '*************';

MariaDB [(none)]> grant all privileges on courages_wordpress.* to courages_wp@localhost identified by '*************';

导入数据库

mysql -uroot -p courages_wordpress < /tmp/wordpress.sql

将文件解压并复制到/var/www/html目录

tar -xzvf backup.tar.gz
cp -R backup/public_html/* /var/www/html/*
chown -R apache:apache /var/www/html

更改Apache设置AllowOverride 为all,以便支持WordPress的链接重定向。

vim /etc/httpd/conf/httpd.conf

<Directory "/var/www/html">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options
    # for more information.
    #
    Options Indexes FollowSymLinks

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    AllowOverride All

    #
    # Controls who can get stuff from this server.
    #
    Require all granted
</Directory>

重启Apache

systemctl restart httpd.service

在linode的DNS manager那里新增一个新的domain,在服务器列表里面选中对应的服务器就可以了,然后就可以看到对应的域名解析信息。
域名转移会要求一个key,从原注册商那里解锁并获得,在Godday输入Key后,它会发邮件与你确认,然后将DNS域名服务器改为linode的域名服务器就好了。

Let’s Encrypt提供免费90天的SSL证书,如果证书到期了就需要再次更新下。如果你有shell权限,它推荐使用Cerbot来安装和更新证书。CentOS 7 + Apache的安装非常简单。首先安装EPEL源,要不然找不到对应的安装包

yum install epel-release
yum install certbot-apache
certbot --authenticator webroot --installer apache

设置一下域名,网站目录及域名重定向

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer apache
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): <[email protected]>
Starting new HTTPS connection (1): acme-v01.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-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(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 EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: 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): courages.us
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for courages.us
Input the webroot for courages.us: (Enter 'c' to cancel): /var/www/html
Waiting for verification...
Cleaning up challenges

We were unable to find a vhost with a ServerName or Address of courages.us.
Which virtual host would you like to choose?
(note: conf files with multiple vhosts are not yet supported)
-------------------------------------------------------------------------------
1: ssl.conf                       |                       | HTTPS | Enabled
-------------------------------------------------------------------------------
Press 1 [enter] to confirm the selection (press 'c' to cancel): 1
Deploying Certificate for courages.us to VirtualHost /etc/httpd/conf.d/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
Created redirect file: le-redirect-courages.us.conf
Rollback checkpoint is empty (no changes made?)

-------------------------------------------------------------------------------
Congratulations! You have successfully enabled https://courages.us

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

在浏览器访问一下域名即有小绿钥匙。可以在/etc/httpd/conf.d/ssl.conf查看相应的SSL证书配置

<VirtualHost _default_:443>
ServerName courages.us
SSLCertificateFile /etc/letsencrypt/live/courages.us/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/courages.us/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/courages.us/chain.pem
</VirtualHost>

由于证书在90天后即将失效,可以加入crontab自动更新

certbot renew --dry-run
crontab -e

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew 

另外一种更新证书的方法是使用acme.sh,不依赖python,同样支持DNS验证,并且还可以获取其他CA颁发的证书,比如ZeroSSL
安装acme。sh脚本非常简单

➜ ~ curl https://get.acme.sh | sh -s [email protected]
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1032 0 1032 0 0 608 0 --:--:-- 0:00:01 --:--:-- 608
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 216k 100 216k 0 0 104k 0 0:00:02 0:00:02 --:--:-- 104k
[2023年 04月 07日 星期五 22:11:22 CST] Installing from online archive.
[2023年 04月 07日 星期五 22:11:22 CST] Downloading https://github.com/acmesh-official/acme.sh/archive/master.tar.gz
[2023年 04月 07日 星期五 22:11:25 CST] Extracting master.tar.gz
[2023年 04月 07日 星期五 22:11:26 CST] It is recommended to install socat first.
[2023年 04月 07日 星期五 22:11:26 CST] We use socat for standalone server if you use standalone mode.
[2023年 04月 07日 星期五 22:11:26 CST] If you don't use standalone mode, just ignore this warning.
[2023年 04月 07日 星期五 22:11:26 CST] Installing to /root/.acme.sh
[2023年 04月 07日 星期五 22:11:26 CST] Installed to /root/.acme.sh/acme.sh
[2023年 04月 07日 星期五 22:11:26 CST] Installing alias to '/root/.zshrc'
[2023年 04月 07日 星期五 22:11:26 CST] OK, Close and reopen your terminal to start using acme.sh
[2023年 04月 07日 星期五 22:11:26 CST] Installing alias to '/root/.cshrc'
[2023年 04月 07日 星期五 22:11:26 CST] Installing alias to '/root/.tcshrc'
[2023年 04月 07日 星期五 22:11:26 CST] Installing cron job
[2023年 04月 07日 星期五 22:11:26 CST] Good, bash is found, so change the shebang to use bash as preferred.
[2023年 04月 07日 星期五 22:11:28 CST] OK
[2023年 04月 07日 星期五 22:11:28 CST] Install success!

这里采用DNS验证获取证书,设置一下DNS厂商信息,比如DNSPOD,默认获取ZeroSSL证书,可以通过–server letsencrypt切换

➜ ~ export DP_Id="95731"
➜ ~ export DP_Key="***"
➜ ~ acme.sh --issue --dns dns_dp -d example.com -d "*.example.com"
[2023年 04月 07日 星期五 22:14:24 CST] Using CA: https://acme.zerossl.com/v2/DV90
[2023年 04月 07日 星期五 22:14:24 CST] Create account key ok.
[2023年 04月 07日 星期五 22:14:24 CST] No EAB credentials found for ZeroSSL, let's get one
[2023年 04月 07日 星期五 22:14:29 CST] Registering account: https://acme.zerossl.com/v2/DV90
[2023年 04月 07日 星期五 22:14:38 CST] Registered
[2023年 04月 07日 星期五 22:14:38 CST] ACCOUNT_THUMBPRINT='AY5noJZbSullM7fVQOnluxQJmWiiKJHl0vzVsYwwGsg'
[2023年 04月 07日 星期五 22:14:38 CST] Creating domain key
[2023年 04月 07日 星期五 22:14:38 CST] The domain key is here: /root/.acme.sh/example.com_ecc/example.com.key
[2023年 04月 07日 星期五 22:14:38 CST] Multi domain='DNS:example.com
[2023年 04月 07日 星期五 22:14:39 CST] Getting domain auth token for each domain
[2023年 04月 07日 星期五 22:14:56 CST] Getting webroot for domain='example.com'
[2023年 04月 07日 星期五 22:14:56 CST] Getting webroot for domain='*.example.com'
[2023年 04月 07日 星期五 22:14:56 CST] Adding txt value: q-pQccpOPbYbC4h_veQTSvj2OgUpgg9kBUFpms9fa9k for domain: _acme-challenge.example.com
[2023年 04月 07日 星期五 22:14:57 CST] Adding record
[2023年 04月 07日 星期五 22:14:57 CST] The txt record is added: Success.
[2023年 04月 07日 星期五 22:15:01 CST] Let's check each DNS record now. Sleep 20 seconds first.
[2023年 04月 07日 星期五 22:15:23 CST] You can use '--dnssleep' to disable public dns checks.
[2023年 04月 07日 星期五 22:15:23 CST] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[2023年 04月 07日 星期五 22:15:23 CST] Checking example.com for _acme-challenge.example.com
[2023年 04月 07日 星期五 22:15:23 CST] Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 35
[2023年 04月 07日 星期五 22:15:27 CST] Domain example.com '_acme-challenge.example.com' success.
[2023年 04月 07日 星期五 22:15:34 CST] All success, let's return
[2023年 04月 07日 星期五 22:15:34 CST] Verifying: example.com
[2023年 04月 07日 星期五 22:15:46 CST] Processing, The CA is processing your order, please just wait. (1/30)
[2023年 04月 07日 星期五 22:15:51 CST] Success
[2023年 04月 07日 星期五 22:15:51 CST] Verifying: *.example.com
[2023年 04月 07日 星期五 22:15:55 CST] Processing, The CA is processing your order, please just wait. (1/30)
[2023年 04月 07日 星期五 22:16:28 CST] Success
[2023年 04月 07日 星期五 22:16:28 CST] Removing DNS records.
[2023年 04月 07日 星期五 22:16:28 CST] Removing txt: q-pQccpOPbYbC4h_veQTSvj2OgUpgg9kBUFpms9fa9k for domain: _acme-challenge.example.com
[2023年 04月 07日 星期五 22:16:30 CST] Removed: Success
[2023年 04月 07日 星期五 22:16:34 CST] Verify finished, start to sign.
[2023年 04月 07日 星期五 22:16:35 CST] Lets finalize the order.
[2023年 04月 07日 星期五 22:16:40 CST] Order status is processing, lets sleep and retry.
[2023年 04月 07日 星期五 22:16:40 CST] Retry after: 15
[2023年 04月 07日 星期五 22:17:00 CST] Downloading cert.
[2023年 04月 07日 星期五 22:17:00 CST] Le_LinkCert='https://acme.zerossl.com/v2/DV90/cert/pcAU9PLEoObR7xYPTb9x7w'
[2023年 04月 07日 星期五 22:17:03 CST] Cert success.
-----BEGIN CERTIFICATE-----
MIIELzCCA7agAwIBAgIRAOO4Gyu...
QRwR2SSrAlEIeJXua7aYyyEEJQ==
-----END CERTIFICATE-----
[2023年 04月 07日 星期五 22:17:03 CST] Your cert is in: /root/.acme.sh/example.com_ecc/example.com.cer
[2023年 04月 07日 星期五 22:17:03 CST] Your cert key is in: /root/.acme.sh/example.com_ecc/example.com.key
[2023年 04月 07日 星期五 22:17:03 CST] The intermediate CA cert is in: /root/.acme.sh/example.com_ecc/ca.cer
[2023年 04月 07日 星期五 22:17:03 CST] And the full chain certs is there: /root/.acme.sh/example.com_ecc/fullchain.cer

最后安装证书

➜  ~ acme.sh --install-cert -d example.com -d "*.example.com"--key-file /etc/letsencrypt/live/example.com/privkey.pem --fullchain-file /etc/letsencrypt/live/example.com/chain.pem --reloadcmd "systemctl restart nginx"
[2023年 04月 07日 星期五 23:00:13 CST] The domain 'example.com' seems to have a ECC cert already, lets use ecc cert.
[2023年 04月 07日 星期五 23:00:13 CST] Installing key to: /etc/letsencrypt/live/example.com/privkey.pem
[2023年 04月 07日 星期五 23:00:13 CST] Installing full chain to: /etc/letsencrypt/live/example.com/chain.pem
[2023年 04月 07日 星期五 23:00:13 CST] Run reload cmd: systemctl restart nginx
[2023年 04月 07日 星期五 23:00:13 CST] Reload success

以后就可以自动更新了

➜  ~  crontab -l  | grep acme 
26 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

最近登录后台发现WordPress提示升级到PHP 7.3,按照它的指示

在CentOS 7上升级PHP5.4 到PHP 7.3很简单:
首先安装Remi和EPEL仓库

yum install wget
wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm
rpm -Uvh remi-release-7.rpm 
rpm -Uvh epel-release-latest-7.noarch.rpm

yum install yum-utils

启用remi-php73的源,yum update升级会自动升级PHP及扩展

[root@li846-239 ~]# yum-config-manager --enable remi-php73
[root@li846-239 ~]# yum repolist
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.linode.com
 * epel: kartolo.sby.datautama.net.id
 * extras: mirrors.linode.com
 * remi-php73: mirror.xeonbd.com
 * remi-safe: mirror.xeonbd.com
 * updates: mirrors.linode.com
repo id                                                                                                   repo name                                                   status
base/7/x86_64                                                                                             CentOS-7 - Base                                              10,019
epel/x86_64                                                                                               Extra Packages for Enterprise Linux 7 - x86_64               13,051
extras/7/x86_64                                                                                           CentOS-7 - Extras                                               385
remi-php73                                                                                                Remi's PHP 7.3 RPM repository for Enterprise Linux 7 - x86_64   305
remi-safe                                                                                                 Safe Remi's RPM repository for Enterprise Linux 7 - x86_64    3,188
updates/7/x86_64                                                                                          CentOS-7 - Updates                                            1,511
repolist: 28,825


yum update -y

检查PHP版本,重启Apache

[root@li846-239 ~]# php -v
PHP 7.3.4 (cli) (built: Apr  2 2019 13:48:50) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.4, Copyright (c) 1998-2018 Zend Technologies
[root@li846-239 ~]# systemctl restart httpd

也可以禁用对应PHP版本的源,选择性升级PHP到对应版本

yum-config-manager --disable remi-php72

顺便升级下php-mcrypt和ZipArchive

yum install php-mcrypt
yum install php-pecl-zip

参考链接:
How To Install Linux, Apache, MySQL, PHP (LAMP) stack On CentOS 7
How to enable EPEL repository?
How to Secure Your Server
Introduction to FirewallD on CentOS
How to Upgrade PHP 5.6 to PHP 7.2 on CentOS VestaCP