OpenResty AES 函数密钥生成原理

最近遇到一个场景,需要在 OpenResty 里使用 AES 对数据进行加密。但是看了一下官方提供的 AES 库,如果数据密码的话,并没有返回实际使用的 key 和 IV,因此查看了一下源码,研究了一下 key 生成的方式,方便其他语言使用。

密钥生成逻辑的核心代码在这:

function _M.new(self, key, salt, _cipher, _hash, hash_rounds, iv_len, enable_padding)

...

    local _hash = _hash or hash.md5
    local hash_rounds = hash_rounds or 1

...

        if C.EVP_BytesToKey(_cipher.method, _hash, salt, key, #key,
              (更多…)

无痛解决 TeslaMate 访问 OpenStreetMap API 的问题

TeslaMate 是一款特斯拉汽车专用的增强工具,使用了破解的官方 App 的 API,将车机记录的大量信息进行了导出和展示,极大的增强了特斯拉车主的使用体验。

但是由于一些原因,中国特斯拉的汽车的数据都是存放在中国大陆,且不允许境外 IP 访问。因此,中国车主想要使用 TeslaMate,则必须在境内部署相关的服务。

不过,境内部署虽然可以解决访问 Tesla API 的问题,却也带来了新的问题,就是调用境外 API 的时候会出现错误,导致部分功能无法使用。

具体来说,TeslaMate 使用了 OpenStreetMap 提供的 API,用来将经纬度坐标转换为地名。然而,OpenStreetMap 的域名在境内是无法访问的,因此会导致解析坐标点的时候出现失败,导致在 Grafana 的 Drives(行程) 面板不显示行程的起止地址。

为了解决这个问题,我首先想到了设置 (更多…)

Nginx 诡异 SSL_PROTOCOL_ERROR 问题排查

这两天在检查一台 Nginx 配置的时候,遇到了一个极端诡异的问题。一段很通用的配置,配在这个服务器上,就会 100% 导致 Chrome 报 ERR_SSL_PROTOCOL_ERROR 。但是这段配置非常的通用,是用 Mozilla 提供的工具生成的。

而且在 iPhone 的 Safari 上访问又是完全正常的,服务器日志也看不到任何错误。看到的请求相应码也是完全正确的 200 。

先贴出配置:

# https://mozilla.github.io/server-side-tls/ssl-config-generator/
    listen 443 ssl http2;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate (更多…)

nginx rewrite 的一个小坑

今天在配置 Nginx 的时候写了这么一个 location

location /a {
    rewrite /a/(.*) /$1 break;
    ...
}

然后发现当我直接访问 /a 的时候,rewrite 并没有生效,后端收到的还是 /a 而不是我想象中的 / 。想了想可能是结尾 / 的问题,于是这样改:

location /a {
    rewrite /a(.*) $1 break;
    ...
}

结果新的问题来了,由于这样匹配到的 $1 是空的,所以 Nginx 报错了,the rewritten URI has a zero length

所以这种情况下只好这么写:

location /a/ {
    rewrite /a(.*) $1 break;
    ...
}

注意第一行的末尾 / 。这种情况下,访问 /a 会被 (更多…)

Nginx 配置 ECC RSA 双证书

Config Nginx for parallel ECC and RSA Certificate

先决条件

Nginx 1.11.0 以上

OpenSSL 1.0.2 以上

申请证书

首先申请 ECC 证书,这个不多说,很多方法都可以,大部分 CA 现在也都可以签署。生成 CSR 的命令是:

openssl ecparam -out 证书名.key -name prime256v1 -genkey && openssl req -new -key 证书名.key -nodes -out 证书名.csr

拿到证书之后,还是像之前一样将中级 CA 拼接在证书后面,得到给 Nginx 使用的 domain-cert.crt

配置 Nginx

首先是将两个证书链都加入 Nginx 的配置文件:

ssl_certificate     example.com.rsa.crt;
ssl_certificate_key (更多…)

Nginx 配置 403 Error Page

今天遇到一个很有意思的问题,就是给 Nginx 配置 403 时候的错误页面。因为这台 Nginx 针对访问 IP 做了一些限制,所以需要给无权限访问的用户展示一个友好的界面。

一开始我的设置是这么写的:

...
allow 10.0.0.0/24;
allow 192.168.0.0/24;
deny 1.2.3.4;
deny 2.3.4.5;

error_page 403 /403.html;
...

可是实际使用发现,无论如何 Nginx 展示的都是内置 Hard Code 进去的那个 404 页面,并不是我想让他展示的友好的界面。

在排除了各种文件权限之类的错误之后,我 Google 了一下发现,这个真正的原因在于前面配置的 deny 不仅 deny 掉了正常页面的访问,同时也将对 /404.html 页面的访问也 deny 掉了。

所以正确的配置是加上下面几句:

location (更多…)

使用 Nginx 反代 Apache 安装 WordPress

最近由于原先博客主机极度不稳定,所以准备了很久,准备进行主机迁移。由于迁移前的环境和迁移后还是有较大的区别,整体架构也不太一样,所以在这里说说迁移过程中遇到的问题。

环境对比

原主机 新主机
操作系统 CentOS 6 CentOS 7
Web 服务器 Apache 2.2 Openresty 1.9.7 + Apache 2.4
PHP 版本 5.5 5.6
其他 SELinux

SELinux

很多人为了省事,在拿到主机的第一时间就直接禁用了 SELinux。不过在学习了一段时间之后,我发现其实 SELinux 是一个很好的保护机器的手段。

这里简单列举几个需要注意的 SELinux 的配置:

 

httpd_can_network_connect_db boolean (更多…)

什么是 ALPN(应用层协议协商) What is ALPN (Application-Layer Protocol Negotiation)

在没有启用 ALPN 的时候,加载一个 HTTP/2 页面的步骤是:

Without ALPN, the steps to load a HTTP/2 page would be like:

  1. TLS 握手 (TLS handshake)
  2. 浏览器/客户端 发送带有 “Upgrade: h2c” 头的 HTTP/1.1 请求 (Browser/Client speaks HTTP/1.1 to server with “Upgrade: h2c” Header)
  3. 服务器回复 101 Switching 并将链接升级至 HTTP2 (Server responds with 101 Switching to upgrade to HTTP2)
  4. 现在服务器和客户端采用 HTTP2 协议交流 (Now they talks via HTTP2)

在启用了 (更多…)

SSL 双向认证的一个小问题

最近一直在研究 SSL 双向认证,工作中也经常用到。然后今天遇到了一个非常奇怪的问题,那就是就算配置了

ssl_verify_client optional_no_ca

客户端的访问仍然会失败,证书认证仍然不过。调试了半天,发现了两个问题,那就是:
1. optional_no_ca 并不会像 off 一样放过所有请求,而是对于提交了证书的请求,如果证书验证不过就会握手出错
2. 对于下面这个配置项的设置存在错误:

ssl_verify_depth 1

经过查找资料,找到了这个选项相关的一些说明。(注:以下实验均在 Nginx 和 Apache2.2 上同时进行过)

The depth actually is the maximum number of intermediate certificate issuers, i.e. the number of CA certificates (更多…)