服务器

我用了一台阿里云服务器,任何能在互联网上被访问到的服务都可以。服务器的 IP 地址是 42.120.40.68。在本地电脑,使用命令行工具可以登录到服务器。Windows 推荐使用 Cmder 作为命令行工具,macOS 用户可以使用系统自带的终端(Terminal)。

ssh wanghao@42.120.40.68

wanghao 是在我的服务器上的某个用户的名字,这个用户是我自己创建的。一开始,你可以使用服务器的超级管理员:root 登录到你的服务器,然后你可以创建新的用户,为用户分配权限等等。

主机名

配置一个主机名,指向服务器的 IP 地址,这个主机名就是访问本地开发环境用的主机名。我让 sandbox.ninghao.net这个主机名指向了我的服务器:42.120.40.68

验证主机名是否已经解析到指定的服务器,可以在命令行下面用 ping 命令测试一下:

→ ping sandbox.ninghao.net
PING sandbox.ninghao.net (42.120.40.68): 56 data bytes

用 ping 命令测试 sandbox.ninghao.net 的时候,返回的 IP 地址就是我的服务器的 IP 地址。

Nginx 代理

在服务器上安装 Nginx,再去配置一台 Nginx 代理服务器。我的服务器操作系统是 CentOS 7.x,安装 Nginx ,执行:

# 安装包含 Nginx 的仓库
sudo yum install epel-release -y

# 安装 Nginx
sudo yum install nginx -y

# 启动 Nginx
sudo systemctl start nginx

# 开机自启动 Nginx
sudo systemctl enable nginx

代理配置

在 Nginx 的配置目录的下面,创建一个新的配置文件,放在 /etc/nginx/conf.d,这个目录是 /etc/nginx/nginx.conf 配置文件里面设置的。配置文件所在的目录可能会有变化,比如有可能在 /etc/nginx/sites-enabled 。具体配置文件所在的目录,你要根据自己的实际情况,检查 Nginx 的主配置,就是 nginx.conf 里面的配置。

/etc/nginx/conf.d/sandbox.ninghao.net.conf:

upstream tunnel {
  server 127.0.0.1:7689;
}

server {
  listen       		    443 ssl;
  server_name               sandbox.ninghao.net;
  ssl                       on;
  client_max_body_size      128m;
  ssl_certificate           /etc/nginx/ssl/sandbox.ninghao.net/214241634170706.pem;
  ssl_certificate_key       /etc/nginx/ssl/sandbox.ninghao.net/214241634170706.key;
  ssl_session_timeout       5m;
  ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers               AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
  ssl_prefer_server_ciphers on;

  location / {
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  Host $http_host;
    proxy_redirect    off;
    expires           off;
    sendfile          off;
    proxy_pass        http://tunnel;
  }
}

上面配置了一台服务器,里面用到了 ssl ,这样服务器就支持使用 https 来传输数据了,这是现代网站或应用并且要做的事情。配置 ssl ,你需要申请 ssl 证书,在阿里云,你可以申请免费的 ssl 证书,或者使用 Let’s Encrypt ,也可以免费申请到证书。

有了证书,就按上面的配置,证书一般有两个文件,把它们存储在服务器上的某个目录的下面,然后分别设置 ssl_certificate 与 ssl_certificate_key 指令的值。

.key 与 .pem 只是证书惯用的文件扩展名,这个扩展名不重要,重要的是文件里面的内容。.key 指的是证书的密钥,.pem 是证书内容。用 Let’s Encrypt 申请的证书,证书文件的扩展名应该是 .cert。

证书密钥

证书密钥文件的扩展名一般是 .key,这个文件里的内容应该作为 Nginx 服务器配置里的 ssl_certificate_key 指令的值。文件里的内容像下面这样:

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAiDnt/zboVuY23iQBYcocvJSewGDol87FoLOquz61L8rNKc5p
...
-----END RSA PRIVATE KEY-----
证书内容

证书内容文件的扩展名一般是 .pem 或者 .cert,文件要作为 Nginx 服务器配置里的 ssl_certificate 指令的值。文件里的内容像下面这样:

-----BEGIN CERTIFICATE-----
MIIFgjCCBGqgAwIBAgIQdtV9VRMTtKBDDfN3UO3ujTANBgkqhkiG9w0BAQsFADCB
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYjCCBEqgAwIBAgIQTEzYoPxP6q4VVKh/CQ7ahzANBgkqhkiG9w0BAQsFADCB
...
-----END CERTIFICATE-----

重新启动

对 Nginx 服务做了新的配置,要重新加载或者重新启动 Nginx 才能让新的配置生效。执行:

# 检查配置文件是否正常
sudo nginx -t

# 重新加载 Nginx
sudo systemctl reload nginx

开发环境

搭建微信支付的开发环境,要保证开发环境可以在互联网上被访问到。因为微信支付系统会通过应用支付的结果,如果开发环境在互联网上不能被访问到,也就收不到这个支付结果。在开发很多其它外部服务的时候,都需要这样做,比如支付宝,微信公众号等等。下面介绍的方法同样适用于搭建开发这些服务的环境。

我用的方法是使用了一台能在互联网上被访问到的服务器,在上面用 Nginx 配置一个代理,把请求转发到服务器的某个端口上。然后用 ssh 在本地跟服务器之间打一个通道,通道用的端口就是配置 Nginx 的时候,设置的上游服务(upstream)的端口。再去设置一个主机名,让它指向服务器,服务器会把请求转发到通道用的端口,这样实际提供服务的就是我们在本地上搭建的开发环境了。