CentOS 6.8服务器给Apache下的站点配置Let’s Encrypt 证书

我们有几个站点,之前用的wosign的免费SSL证书,最近在Chrome中查看站点,都提示是不安全的站点,应该是wosign的不佳的国际声誉连累的。
于是决定换成Let’s Encrypt证书。方法不难,参看:官方文档

有几个注意点:

如果用自动化的配置certbot-auto的话,它会自动找 /etc/httpd/conf.d 文件夹下面的站点配置文件,但只对配置文件里面仅配置了一个80端口的情况有效,如果您的一个配置文件里面配置了多个80端口的站点,则不能自动识别。另外,如果已经自行配置了ssl站点(443端口的virtualhost)的话,也不会再自动识别为需要配置的站点。

我自动化配置了两个站点,先将原来的的配置文件里面的ssl配置(443端口的virtualhost)注释掉了。然后用certbot-auto,选择了识别出来的这两个站点,然后一切自动运行,提示证书生成,且生成了新的配置文件,文件名 www.example.com-le-ssl.conf。

这时候访问网站,是一片空白,服务器端没有输出任何东西。事实证明,自动生成的这个https站点的配置还是有一些问题的:

1,没有指定DocumentRoot;

2,整个配置文件用了<IfModule mod_ssl.c></IfModule>,但其实本机的环境里面没有包含这样的文件,而mod_ssl确实是启用的,在/etc/httpd/modules/文件夹下可以看到有mod_ssl.so。因此果断注释掉了IfModule的语句(本以为也可改为IfModule nod_ssl.so,但发现不起作用),再次打开,网站成功显示,且证书确实已更新为letsencrypt证书。

为基于Docker的Gitlab服务器配置Let’s Encrypt颁发的SSL证书

继之前跨服务器迁移基于Docker的Gitlab之后,这两天又配置了该Gitlab服务器的HTTPS协议,以增加安全性。SSL证书方面,为了一劳永逸,选择Let’s Encrypt解决方案,用CertBot作为ACME的客户端。

服务器是CentOS 7.2 运行着17.03.1版本的Docker,Gitlab容器(基于OMNIBUS的镜像)是9.1.1版本。

文件存储的映射方面,Gitlab的配置及数据,均被映射到了宿主机的/srv/gitlab/文件夹。

首先是要修改Gitlab的external_url,将http://gitlab.example.com 改为 https://gitlab.example.com。具体既可以修改gitlab的配置文件gitlab.rb,也可以删除容器以后,用新的external_url作为命令参数,创建新的容器,此处不详述。

重新运行gitlab以后,暂时是访问不到的,因为需要放置SSL证书。证书位置默认在容器内的/etc/gitlab/ssl/目录,对应的宿主服务器上的地址就是/srv/gitlab/config/ssl/目录。如果这时候放置有效的gitlab.example.com.crt和gitlab.example.com.key文件。就会发现https站点可以访问了。为了访问方便,本机gitlab容器的端口映射之前已经配置成了http是80,https是443。这时候也注意到一件事情:如果访问http站点,会自动307重定向到https站点。

下面配置Letsencrypt证书,这里需要做三件事:

1,安装certbot,配置服务器以便获取证书;
2,安装证书到gitlab容器;
3,自动续期证书以及自动安装证书;

第一件事,参照官方文档安装并配置certbot。按官方推荐,选择webroot插件的方式。这里的要点是,需要在http://gitlab.example.com站点下创建特定的文件夹,以便certbot放置随机生成的文件,来验证你的网站控制权。

这时候,需要先修改gitlab容器的端口映射配置,让出80端口,然后在宿主机上配置nginx服务器(当然也可以是apache或者其他),配置http:/gitlab.example.com站点,并放置用来验证网站控制权的/.well-known目录。当然,考虑到gitab站点的真正内容应该基于https访问,因此可以对http站点的其他内容设置301重定向。

本机的nginx里面该站点的配置如下供参考:

server {
    listen      80;
    server_name gitlab.example.com;

    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
        root    /usr/share/nginx/html;
    }

    location = /.well-known/acme-challenge/ {
        return 404;
    }

    location / {
         return 301 https://gitlab.example.com;
    }
}

第二件事,将/etc/letsencrypt/live/gitlab.example.com 文件夹下的fullchain.pem 和 privkey.pem复制到/srv/gitlab/config/ssl/文件夹下且分别命名为gitlab.example.com.crt 和gitlab.example.com.key;

第三件事,如果需要certbot自动续期ssl,只要在cron里面设置自动执行如下语句:

05 12 * * * certbot renew
10 12 * * * cp -u /etc/letsencrypt/live/gitlab.example.com/fullchain.pem /srv/gitlab/config/ssl/gitlab.example.com.crt
11 12 * * * cp -u /etc/letsencrypt/live/gitlab.example.com/privkey.pem /srv/gitlab/config/ssl/gitlab.example.com.key

这里要注意,certbot生成的文件有三个,经过我测试,拷贝证书文件的时候,如果是将cert.pem拷贝成gitlab.example.com.crt,虽然从浏览器访问该https://gitlab站点没问题,但git 做clone、checkout等操作的时候,却会报错:

SSL certificate problem: unable to get local issuer certificate

经测试,用fullchain.pem文件就可以。
当时碰到这个问题的时候,花了点时间,网上的解决办法多半是关掉Git的SSL校验功能,属于不求甚解。现在看来,这种某个特定网站的SSL报错,且证书发行者又是比较常见的发行者的情况,多半是证书文件有问题。

跨服务器迁移基于Docker的Gitlab

这两天将gitlab从内网迁移到了外网,以便更好的与外部合作伙伴及客户进行协作。

两台服务器都是 CentOS 7.2,Docker上运行的OMNIBUS版本的gitlab容器。迁移的步骤在网上有不少人记录,有的直接拷贝数据文件和配置文件的,有的是通过gitlab的备份命令来将数据备份,再用恢复命令的。由于这个容器版本的数据与配置都在/srv/gitlab文件夹下面,我就采取了第一种方式,步骤大约是这样的:

1,新服务器上安装Docker环境,配置一切,gitlab跑起来,只不过是一个新的站点而已,如何安装可以参考我这篇文章

2,关停旧服务器,然后将配置与数据文件拷贝到新服务器;

3,新服务器关停原容器,将拷贝过来的服务器配置到容器的数据与配置文件夹中去,然后开起来;

4,以上每一步都做到的话,其实就可以了。

但是实际上还是有点曲折,容易遇到坑,迁移的几个要点记录如下:

1,尽量保证新老服务器上的Docker版本一致,这是出于保险起见。不过本人操作过程中其实有不一致的情况,差了前后一个版本(新服务器的高一个版本,正好是操作的这两天出来的,当时没注意到。),没出问题,毕竟gitlab 容器本来就支持通过拉取latest的镜像来构建新版本gitlab,新版本第一次启动的时候会自动对数据进行migration。

2,新服务器上搭建环境的时候,注意看swap分区是否有创建,没有的话,需要创建,参见我这篇文章

3,从旧服务器拷贝文件到新服务器,要注意文件的权限,尤其是owner会变化,导致新服务器跑不起来。原因是gitlab那些数据文件实际上是容器内的postgreSQL、redis等多个组件各自读写的,具有不同的owner。但通过SFTP或者SCP等方式传到新服务器后,owner变成了操作传输动作的账号。这是一个挺大的坑,很多地方都没有明确提到这一点,也没有特别说明如何解决,后来在官方文档里面某一页的末尾处看到提到了一句,笼统的说遇到文件权限问题时候可以运行如下命令:

sudo docker exec gitlab update-permissions
sudo docker restart gitlab

确实执行之后,问题就解决了。

顺便说一下,当时遇到这个文件权限问题的时候,症状是gitlab容器不停的重启,也没法命令行连进去执行命令。通过查看gitlab日志文件夹,发现reconfigure和sshd两个文件夹有日志产出。其中reconfigure文件夹里面的日志,有提到文件操作权限出错的问题。可惜具体报错信息没有记录下来。

升级PHP7.1后微信支付SDK遇到的一个bug

把PHP版本从5.3.3升级到7.1之后(操作系统版本CentOS 6.8, Apache 2.4),Web应用出现微信支付不能确认的问题。

查看日志,发现微信支付回调程序报错:

undefined index : HTTP_RAW_POST_DATA

网上搜索了一下,知道了答案。在我们所引用的微信商户API的支付SDK(v3版本,下载下来的文件名为WxpayAPI_php_v3.zip)中,WxPay.Api.php 的notify方法中有如下赋值调用:

//获取通知的数据
//$xml = $GLOBALS[‘HTTP_RAW_POST_DATA’];

因为这种取值方式在php5.6之后有可能取不到值(在php7之后的版本中已经弃用),故改为下句:
$xml = isset($GLOBALS[‘HTTP_RAW_POST_DATA’]) ? $GLOBALS[‘HTTP_RAW_POST_DATA’] : file_get_contents(“php://input”);

问题得到有效解决。参考如下链接:

https://secure.php.net/manual/zh/reserved.variables.httprawpostdata.php

http://stackoverflow.com/questions/9553168/undefined-variable-http-raw-post-data

同时,网上也有文章指出该SDK的其它一些错误,可参考:

http://www.cnblogs.com/xxoome/p/5705583.html

安装测试osTicket

从github 上clone 了osTicket v1.10 ,在本地Windows 10环境下安装。是Nginx + php-cgi的开发环境。

配置好php站点后在浏览器中打开。结果第一步安装就报错:

core: Unknown or invalid schema signature xxxxxxxx……….

根据网上文章(参考:https://github.com/osTicket/osTicket/issues/511),知道是换行符的问题,重新从github下载了zip文件,覆盖了原来的代码,然后重新开始安装,一切正常。

CentOS6.8 下升级php5.3.3 到php7.1

阿里云的ECS,从centos 6.5 镜像安装的,后来升到了6.8。PHP版本一直太低,PHP 5.3.3,对laravel也不支持,ThinkPHP5也不支持,就想干脆升到PHP 7.1吧。

其实没什么,就是先要启用remi源。然后卸载5.3.3, yum remove php* ,然后安装php71及一堆相关配件。

中间曾经虚惊一场,安装完后重启httpd,发现php文件没有被解析,直接输出了PHP代码。当时估计是php插件没安装全,当时有篇帖子里面有一个安装脚本,于是直接copy过来安装了一遍。然后就好了。

是周日晚上操作的,子夜开始操作,凌晨三点半左右才弄好睡觉。可惜当时没记录下来具体漏掉没安装的是哪个包,现在回忆也想不起来了。