使用自签发的SSL证书来加密nginx与后端服务器的通讯

这个问题很有意思,说起来还是由于可恶的GFW. 我目前使用一台阿里云华南的服务器来服务国内客户,然后用一台阿里云HKB 的服务器 + CDN 来服务国外客户. 但是郁闷的是,HKB 的服务器,nginx运行一会就回出现502 bad gateway,但是把HKB 的业务放在其他的服务商那里,就不会出现这个问题, 而且如果你不是用80端口,也不会出现这个问题

这个debug了将近一个星期才猛然间意识到,这也许是因为GFW 和阿里云盾的敏感词过滤系统,强制TCP 触发RST标志,造成502 connection reset

目前看来唯一的办法就是上https, 也就是说要secure data transfer between nginx and its upstream。。。我发现对我来说,还是英语描述比较完整

在这种情况下,nginx 的 upstream 要是用https, 但是因为只是作为内部数据传输,因此可以不用去买SSL证书,直接用self signed 的证书就可以了.

nginx 的官方,有一篇比较权威的教程:

https://www.nginx.com/resources/admin-guide/nginx-https-upstreams/

但是说实话,这个比较复杂,用的是SSL 的双面认证,类似于国内的网上银行的验证方式,而对于我们这种情况,只需要单向认证就可以了. 也就是说只需要在 后端的nginx 的服务器上安装自签发的SSL证书即可,前端nginx 配置调整为proxy_pass https.

关于如何给nginx安装自签发的ssl 证书,国内的教程也比较多,但是大部分都是先自建CA key crt,再签发,比较麻烦, 类似于这样:

http://blog.creke.net/762.html

这样做比较适合双向SSL认证

一个简单的方式可以借助下面的blog提到的方式:

http://blog.topspeedsnail.com/archives/3768

下面简单说下:

现在很多网站都使用https进行加密通讯及对网络服务器身份的鉴定。这遍文章介绍怎么在Nginx web服务上设置自签名SSL证书。由于不是由权威机构发布的证书,它(自签名证书)不能确认网络服务器身份,但是它可以对通信进行加密。

自签名证书适合个人或公司内部使用,如果要对外提供web服务,最好购买权威机构发布的证书。在github上有一个项目叫Let’s Encrypt,可以使用它签发免费的证书,并且大多数web浏览器都信任它。

创建SSL证书

我们可以创建一个目录用来存放所有SSL相关文件,在/etc/nginx下创建:

创建 SSL密钥和证书文件:

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

我们来看一看上面命令各个选项的意思:

openssl:这是创建和管理OpenSSL密钥、证书和其它文件的命令行工具
req:指定使用X.509证书签名要求(CSR)
-x509:创建自签名证书,而不生成签名请求
-nodes:证书不使用密码,我们需要Nginx能直接读取文件,在重启Nginx时,不用输入密码
-days 365::证书的有效时间,这里是一年
-newkey rsa:2048:同时生成一个新证书和新密钥,RSA密钥长度:2048位
-keyout:密钥生成的路径
-out:证书生成的路径
执行上面命令,需要回答一系列问题。其中,最重要的一个问题是Common Name (e.g. server FQDN or YOUR name),输入你的域名。这里可以使用泛解析. 如果没有域名的话,使用ip地址。

这样就会生产key 和 crt

一个简单的nginx配置例子:

server {
 listen 80 default_server;
 listen [::]:80 default_server ipv6only=on;
 
 listen 443 ssl;
 
 root /usr/share/nginx/html;
 index index.html index.htm;
 
 server_name your_domain.com;
 ssl_certificate /etc/nginx/ssl/nginx.crt;
 ssl_certificate_key /etc/nginx/ssl/nginx.key;
 
 location / {
 try_files $uri $uri/ =404;
 }
}

discuz x3.2 启动SSL

这是一篇别的地方看到的文章,把所有需要修改的地方都说了,很有借鉴意义,这里就转载过来做个记录

————————————————————————————————————————————–

Discuz! X3.2 本身对 HTTPS 的支持很有限,程序本身支持,但还有很多地方需要调整和修改的。
站点全部链接默认 HTTPS ,无任何 HTTP 链接通过 301 跳转到 HTTPS 。 浏览器显示绿色安全标志,无“不安全内容”提示。

具体来说,我们需要从以下 6 个方面来实现我们最终的效果。

服务器前端程序的配置
一般来说,大家多使用 Nginx 作为前端程序,关于 Nginx 开启 HTTPS 的教程,网上有很多教程,可以参考这篇文章:

https://aotu.io/notes/2016/08/16/nginx-https/
Discuz 判断服务器是否使用 SSL 的修补和完善
 Discuz 判断服务器是否使用 SSL 的代码不适合 Nginx+CGI 的情况,即 PHP-FPM 。这个时候我们需要修改以下文件:
 Discuz 采用 $_SERVER[‘ HTTPS ’] 的方式来判断 SSL ,但是因为服务器 架构问题( nginx+php-fpm ),无法采用这种方式识别,所以需要对 Discuz 程序进行一些调整(使用 $_SERVER[‘ SERVER_PORT ’] 来判断)。 source/class/discuz/discuz_application.php (约第 187 行处): 查找:
 $_G['isHTTPS'] = ($_SERVER['HTTPS'] && strtolower($_SERVER['HTTPS']) != 'off') ? true : false;
 修改为:
 $_G['isHTTPS'] = ($_SERVER['SERVER_PORT'] == 443 || $_SERVER['HTTPS'] && strtolower($_SERVER['HTTPS']) != 'off') ? true : false;
uc_server/avatar.php (约第 13 行处):
 查找:
 define('UC_API', strtolower(($_SERVER['HTTPS'] == 'on' ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'))));
 修改为:
 define('UC_API', strtolower(($_SERVER['SERVER_PORT'] == 443

除去非 HTTPS 内容避免提示”不安全内容“
Source/plugin/manyou/Service/DiscuzTips.php ,最后的那段 JS 加载脚本删除就行。
非楼主层如果有点评,那么点评者头像不是 HTTPS 开头,也需要修改一个文件来适配: template/default/forum/viewthread_node_body.htm (约 180 行),搜索 div class=”psta vm”>,将下面一行注释掉或者删除。
打开浏览器,使用开发者工具或者查看源码逐一排查加载的非 HTTPS 资源并修改。

后台设置的修改完善
在后台还有一些设置,可能会干扰 https 的使用
后台 >全局 > 站点 URL ,改为 https 开头的
后台 > 站长 > UCenter 设置 > UCenter 访问地址,修改为 https 开头的
UCenter 后台 > 应用管理 > 应用的主 URL ,修改为 https 开头。修改后可能会显示通讯失败,如果 UC 和论坛程序安装在同一机器,此失败可无视,实测可以和 UC 正常通讯不影响(测试是否正常通讯程序的 Bug ),如果 UC 和论坛程序不在一台机器上,有可能不能通讯。 另外在 后台 > 全局 > 域名设置 中的一些设置也可能使 https 失效,如果更新缓存后论坛默认连接还是 HTTP ,请删除 后台 > 全局 > 域名设置 > 应用域名 > 默认 里面的默认域名(一般去 forum.php 尾巴这里会有内容,为了 HTTPS 请删除)。

模板的调整
主要在模板的 foot.html 以及 header.html 等文件中,使用工具逐一排查模板文件中写死的 HTTP 链接,修改为 HTTPS 。

数据库的调整
在论坛这种交互社区中,经常回复发帖时会有出现主域名的链接,在没有 HTTPS 之前,链接都是 HTTP 开头,这个时候,我们需要修改数据库,运行下面的 mysql 命令更新数据库,将 HTTP 替换为 HTTPS :
进入 DZ 后台:站长 – 数据库 – 升级

UPDATE pre_forum_post SET message=REPLACE(message,’http://www.repaik.com‘,’https://www.repaik.com‘);
请将 www.repaik.com 替换为自己的域名

需要注意的是,出于安全考虑, Discuz 后台默认情况下禁止 SQL 语句直接执行,只能使用常用 SQL 当中的内容,如果想自己随意书写 SQL 升级语句,需要将程序文件 config/config_global.php 当中的$_config[admincp][runquery] 设置修改为 1 。

阿里云ECS这是个大坑

从来不用国内的服务,但是没有办法,为了速度还是只能在国内找,矮子里挑个高的,只能选择阿里云。。。但是随之而来的是各种大坑。。

ECS 封掉了25端口,也就是说你不能在上面创建任何邮件服务器。。。阿里云工单的回答是,只能使用阿里云云邮箱或者第三方,需要修改代码。。。

修改你妹妹啊。。我是直接用bash 调用postfix做发件服务,没有代码。。。

找了一晚上加一上午,目前最好的办法就是使用qq 的免费企业邮箱。。但是qq 比较鬼的是。。他在文档中没有标明有587端口。。但是你确可以使用这个端口。。。465 是ssl 端口,这样配置起来会比较麻烦。。

首先是创建qq的免费企业邮箱,得到smtp 信息

smtp:  smtp.exmail.qq.com:587

TLS

然后在centos 里面安装postfix 和 sasl 模块

sudo yum install postfix cyrus-sasl cyrus-sasl-lib cyrus-sasl-plain -y

编辑 /etc/postfix/main.cf, 然后加上

relayhost = [smtp.exmail.qq.com]:587

smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_use_tls = yes
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
smtp_sender_dependent_authentication = yes
smtp_generic_maps = hash:/etc/postfix/generic

在/etc/postfix/sasl_passwd 里面写用户名和密码, 比如说用户名为 [email protected], 密码为iamhippo, 那么就这么写:

[smtp.exmail.qq.com]:587 [email protected]:iamhippo

在/etc/postfix/generic 要重写mail from 的地址,假如你的hostname 是i.iamhippo.com, 那么就可以写成:

@i.iamhippo.com [email protected]

 

最后就是生成hash 数据库了:

postmap /etc/postfix/sasl_passwd
postmap /etc/postfix/generic
chmod 600 /etc/postfix/sasl_passwd*

然后我们只需要重启postfix,就大功告成

service postfix restart

nginx 隐藏版本version

现在我旗下的网站基本全部都转移到nginx了,但是nginx 出现40X 和 50x 的错误的时候,经常会显示版本号,这让我很不爽

无意间看到某个nginx站点出问题的时候,竟然不显示版本号。 google 了一下,原来nginx 有个命令叫做server_tokens, 把它设置为off 即可

 

Syntax: server_tokens on | off | build | string;
Default: 
server_tokens on;
Context: http, server, location

CentOS 6 安装SmokePing教程

smokeping是对IDC网络质量,稳定性等最好的检测工具,包括常规的 ping,dig,echoping,curl等,可以 监视 www 服务器性能,监视 dns 查询性能,监视 ssh 性能等。Smokeping是rrdtool的作者Tobi Oetiker的作品,所以底层也是 rrdtool 做支持。smokeping是一个很老的开源项目了,不过考虑到现网以下两方面的需求,感觉还是有必要部署的。1、针对虚拟化平台主机重启速度较快,普通的监控平台可能敏感度不够;2、业务和网络部门经常有对网络质量和页面访问速度对比的需求。

smokeping安装前,可以参考官方安装页面:

http://oss.oetiker.ch/smokeping/doc/smokeping_install.en.html

具体要求如下:

RRDtool 1.2.x or later
FPing (optional)
EchoPing (Optional)
Curl (Optional)
dig (Optional)
SSH (Optional)
Webserver
Perl 5.8.8 or later(对应的模块如下)
 FCGI
 CGI, CGI::Fast
 Config::Grammar
 LWP
 Socket6 (optional)
 Net::Telnet (optional)
 Net::OpenSSH (optional)
 Net::DNS (optional)
 Net::LDAP (optional)
 IO::Socket::SSL (optional)
 Authen::Radius (optional)

更多

/etc/fstab 详细说明

/etc/fstab 是专门用配置挂载硬盘的文件

语法为:

[Device] [Mount Point] [File System Type] [Options] [Dump] [Pass]

详细解释为:

<device>

The device/partition (by /dev location or UUID) that contain a file system.

<mount point>

The directory on your root file system (aka mount point) from which it will be possible to access the content of the device/partition (note: swap has no mount point). Mount points should not have spaces in the names.

<file system type>

Type of file system 

<options>

Mount options of access to the device/partition (see the man page for mount).

<dump>

Enable or disable backing up of the device/partition (the command dump). This field is usually set to 0, which disables it.

<pass num>

Controls the order in which fsck checks the device/partition for errors at boot time. The root device should be 1. Other partitions should be 2, or 0 to disable checking.

第一列和第二列的device 和 mount point 顾名思义,就是你想要挂载的device  和挂载的位置.

device 有两种表示方式,可以用/dev/xdx 之类的location 或者 硬件的UUID 来表示,硬件的UUID 可以用blkid 来查询

第三列的file system type 也很好理解,这里一般有auto, vfat( for FAT partition), ntfs or ntfs-3g( for NTFS partition), ext4 or ext3 or ext2 or jfs,  udf or iso9660 ( for CD/DVD), swap

第四列的option,一般用默认的defaults,但是也可以使用下面的option:

sync/async - All I/O to the file system should be done (a)synchronously.
auto - The filesystem can be mounted automatically (at bootup, or when mount is passed the -a option). This is really unnecessary as this is the default action of mount -a anyway.
noauto - The filesystem will NOT be automatically mounted at startup, or when mount passed -a. You must explicitly mount the filesystem.
dev/nodev - Interpret/Do not interpret character or block special devices on the file system.
exec / noexec - Permit/Prevent the execution of binaries from the filesystem.
suid/nosuid - Permit/Block the operation of suid, and sgid bits.
ro - Mount read-only.
rw - Mount read-write.
user - Permit any user to mount the filesystem. This automatically implies noexec, nosuid,nodev unless overridden.
nouser - Only permit root to mount the filesystem. This is also a default setting.
defaults - Use default settings. Equivalent to rw, suid, dev, exec, auto, nouser, async.
_netdev - this is a network device, mount it after bringing up the network. Only valid with fstype nfs.

第五列 dump,dump 是linux 系统中的一个备份工具,用0 来表示不备份这个区,1 表示备份。这里不适合长篇大论来讨论dump 和 fsck ,但是通过查看/etc/fstab 的例子可以看到,第五列的选项一般为0

第六列 fsck 表示fsck 是否会check这个区,一般用1 来表示根分区, 2 表示其他的分区;0表示不检查

对于第5,6列来说,

/ 一般为1 1

swap 一般为 0 0

其他分区一般为1 2

云硬盘可谓0 2