产品定价 立即试用
社区版
在 CentOS/RHEL 上为 ThingsBoard 安装 HAProxy 负载均衡器
入门 文档 指南 安装 架构 API 常见问题
目录

在 CentOS/RHEL 上为 ThingsBoard 安装 HAProxy 负载均衡器

This guide describes how to install HAProxy with Let’s Encrypt as a service. This is possible in case you are hosting ThingsBoard in the cloud and have a valid DNS name assigned to your instance.

前置条件

RHEL/CentOS 8/9,已为实例分配有效的DNS名称。网络设置需允许通过80端口(HTTP)和443端口(HTTPS)的连接。

要开放80和443端口,请执行以下命令:

1
2
3
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
sudo firewall-cmd --zone=public --add-port=443/tcp --permanent
sudo firewall-cmd --reload

步骤1. 通过SSH连接到ThingsBoard实例

以下是AWS的示例命令,供参考:

1
$ ssh -i <PRIVATE-KEY> ec2-user@<PUBLIC_DNS_NAME>

或咨询您的云服务提供商了解其他选项。

步骤2. 安装HAProxy负载均衡器包

执行以下命令安装HAProxy包:

1
sudo dnf -y install haproxy 

执行以下命令启用服务自动启动:

1
sudo systemctl enable haproxy

步骤3. 安装Certbot包

执行以下命令安装Certbot包:

1
sudo dnf -y install ca-certificates certbot

步骤4. 安装默认自签名证书

执行以下命令安装默认自签名证书:

(请完整复制粘贴以下命令)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
cat <<EOT | sudo tee /usr/bin/haproxy-default-cert
#!/bin/sh

set -e

HA_PROXY_DIR=/usr/share/tb-haproxy
CERTS_D_DIR=\${HA_PROXY_DIR}/certs.d
TEMP_DIR=/tmp

PASSWORD=\$(openssl rand -base64 32)
SUBJ="/C=US/ST=somewhere/L=someplace/O=haproxy/OU=haproxy/CN=haproxy.selfsigned.invalid"

KEY=\${TEMP_DIR}/haproxy_key.pem
CERT=\${TEMP_DIR}/haproxy_cert.pem
CSR=\${TEMP_DIR}/haproxy.csr
DEFAULT_PEM=\${HA_PROXY_DIR}/default.pem

if [ ! -e \${HA_PROXY_DIR} ]; then
  mkdir -p \${HA_PROXY_DIR}
fi

if [ ! -e \${CERTS_D_DIR} ]; then
  mkdir -p \${CERTS_D_DIR}
fi


# Check if default.pem has been created
if [ ! -e \${DEFAULT_PEM} ]; then
  openssl genrsa -des3 -passout pass:\${PASSWORD} -out \${KEY} 2048 &> /dev/null
  sleep 1
  openssl req -new -key \${KEY} -passin pass:\${PASSWORD} -out \${CSR} -subj \${SUBJ} &> /dev/null
  sleep 1
  cp \${KEY} \${KEY}.org &> /dev/null
  openssl rsa -in \${KEY}.org -passin pass:\${PASSWORD} -out \${KEY} &> /dev/null
  sleep 1
  openssl x509 -req -days 3650 -in \${CSR} -signkey \${KEY} -out \${CERT} &> /dev/null
  sleep 1
  cat \${CERT} \${KEY} > \${DEFAULT_PEM}
  echo \${PASSWORD} > \${HA_PROXY_DIR}/password.txt
fi
EOT

执行以下命令:

1
2
3
sudo chmod +x /usr/bin/haproxy-default-cert
touch ~/.rnd
sudo haproxy-default-cert

步骤5. 配置HAProxy负载均衡器

执行以下命令创建HAProxy负载均衡器配置文件:

(请完整复制粘贴以下命令)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
cat <<EOT | sudo tee /etc/haproxy/haproxy.cfg
#HA Proxy Config
global
 ulimit-n 500000
 maxconn 99999
 maxpipes 99999
 tune.maxaccept 500

 log 127.0.0.1 local0
 log 127.0.0.1 local1 notice

 ca-base /etc/ssl/certs
 crt-base /etc/ssl/private

 ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
 ssl-default-bind-options no-sslv3

defaults

 log global

 mode http

 timeout connect 5000ms
 timeout client 50000ms
 timeout server 50000ms
 timeout tunnel  1h    # timeout to use with WebSocket and CONNECT

 default-server init-addr none

frontend http-in
 bind *:80 alpn h2,http/1.1

 option forwardfor

 http-request add-header "X-Forwarded-Proto" "http"

 acl letsencrypt_http_acl path_beg /.well-known/acme-challenge/

 redirect scheme https if !letsencrypt_http_acl { env(FORCE_HTTPS_REDIRECT) -m str true }

 use_backend letsencrypt_http if letsencrypt_http_acl

 default_backend tb-backend

frontend https_in
  bind *:443 ssl crt /usr/share/tb-haproxy/default.pem crt /usr/share/tb-haproxy/certs.d/ ciphers ECDHE-RSA-AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM alpn h2,http/1.1

  option forwardfor

  http-request add-header "X-Forwarded-Proto" "https"

  default_backend tb-backend

backend letsencrypt_http
  server letsencrypt_http_srv 127.0.0.1:8090

backend tb-backend
  balance leastconn
  option tcp-check
  option log-health-checks
  server tb1 127.0.0.1:8080 check inter 5s
  http-request set-header X-Forwarded-Port %[dst_port]
EOT

步骤6. 配置Edge TLS通信(可选)

ThingsBoard支持通过TLS/SSL上的gRPC连接保护平台与Edge实例间的连接。

我们将使用HAProxy作为Edge与平台间TLS连接的终止点。

首先,需将平台Edge连接默认绑定端口改为7071。这样可将HAProxy配置为监听默认7070端口,并将连接转发至平台的7071端口。

请执行以下命令更新平台上的Edge绑定端口:

1
2
3
4
sudo sh -c 'cat <<EOL >> /etc/thingsboard/conf/thingsboard.conf

export EDGES_RPC_PORT=7071
EOL'

应用变更后需重启ThingsBoard平台:

1
sudo systemctl restart thingsboard

接下来,执行以下命令将TLS配置添加到HAProxy配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo sh -c 'cat <<EOL >> /etc/haproxy/haproxy.cfg

# Edge gRPC TLS (optional)
listen grpc_front
    bind *:7070 ssl crt /usr/share/tb-haproxy/default.pem crt /usr/share/tb-haproxy/certs.d/ ciphers ECDHE-RSA-AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM alpn h2,http/1.1
    mode tcp

    option clitcpka
    option tcplog

    default_backend grpc_backend 

backend grpc_backend
    mode tcp
    server grpc 127.0.0.1:7071
EOL'

步骤7. 配置Certbot与Let’s Encrypt

执行以下命令创建Certbot与Let’s Encrypt的配置文件和辅助脚本:

(请完整复制粘贴以下命令)

1
2
3
4
sudo mkdir -p /usr/local/etc/letsencrypt \
&& sudo mkdir -p /usr/share/tb-haproxy/letsencrypt \
&& sudo rm -rf /etc/letsencrypt \
&& sudo ln -s /usr/share/tb-haproxy/letsencrypt /etc/letsencrypt
1
2
3
4
5
6
7
8
cat <<EOT | sudo tee /usr/local/etc/letsencrypt/cli.ini
authenticator = standalone
agree-tos = True
http-01-port = 8090
tls-sni-01-port = 8443
non-interactive = True
preferred-challenges = http-01
EOT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat <<EOT | sudo tee /usr/bin/haproxy-refresh
#!/bin/sh

HA_PROXY_DIR=/usr/share/tb-haproxy
LE_DIR=/usr/share/tb-haproxy/letsencrypt/live
DOMAINS=\$(ls -I README \${LE_DIR})

# update certs for HA Proxy
for DOMAIN in \${DOMAINS}
do
 cat \${LE_DIR}/\${DOMAIN}/fullchain.pem \${LE_DIR}/\${DOMAIN}/privkey.pem > \${HA_PROXY_DIR}/certs.d/\${DOMAIN}.pem
done

# restart haproxy
exec service haproxy restart
EOT
1
2
3
4
5
cat <<EOT | sudo tee /usr/bin/certbot-certonly
#!/bin/sh

/usr/bin/certbot certonly -c /usr/local/etc/letsencrypt/cli.ini "\$@"
EOT
1
2
3
4
5
cat <<EOT | sudo tee /usr/bin/certbot-renew
#!/bin/sh

/usr/bin/certbot -c /usr/local/etc/letsencrypt/cli.ini renew "\$@"
EOT
1
sudo chmod +x /usr/bin/haproxy-refresh /usr/bin/certbot-certonly /usr/bin/certbot-renew

步骤8. 安装证书自动续期定时任务

执行以下命令创建证书自动续期定时任务:

(请完整复制粘贴以下命令)

1
2
3
4
5
6
7
8
9
10
11
12
13
cat <<EOT | sudo tee /etc/cron.d/certbot
# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot && perl -e 'sleep int(rand(3600))' && certbot -c /usr/local/etc/letsencrypt/cli.ini -q renew && haproxy-refresh
EOT

步骤9. 重启 HAProxy负载均衡器

最后重启HAProxy负载均衡器服务以使更改生效:

1
sudo service haproxy restart

步骤10. 使用Let’s Encrypt生成证书

执行以下命令前,请勿忘记替换your_domainyour_email

1
sudo certbot-certonly --domain your_domain --email your_email

步骤11. 刷新HAProxy配置

最后重启HAProxy:

1
sudo haproxy-refresh