【问题标题】:Docker Compose with Traefik and Mosquitto - Secure Websocket IssueDocker Compose 与 Traefik 和 Mosquitto - 安全 Websocket 问题
【发布时间】:2023-03-19 11:48:01
【问题描述】:

我已经转了整整一天的时间来试图弄清楚这一点。我对 Traefik 还是比较陌生。目标是在云中建立一个安全的 MQTT 代理。问题是我可以使用任何使用mqtts://broker.mydomain.com:8883 的MQTT 客户端进行连接,但是当我需要通过wss://broker.mydomain.com:9001 使用websockets 时,我就没有运气了。

docker-compose.yml

version: "3.6"

networks:
  traefik-global-proxy:
    name: "traefik-global-proxy"

services:

  traefik:
    image: "traefik:v2.2"
    container_name: "traefik"
    networks:
      - traefik-global-proxy
    ports:
      - "80:80"
      - "443:443"
      - "8883:8883"
      - "9001:9001"
    volumes:
      # - "./traefik/traefik.toml:/etc/traefik/traefik.toml"
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./logs:/logs"
    command:
      - "--log.level=DEBUG"
      - "--api=true"
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--accesslog=true"
      - "--accesslog.filepath=/logs/access.log"

      # Entrypoints
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.mqtt.address=:8883"
      - "--entrypoints.websocket.address=:9001"

      # Redirect http to https
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https" # Let's encrypt configuration
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.email=email@domain.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.broker.mydomain.com`)
        && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
      - "traefik.http.routers.dashboard.middlewares=auth"
      # echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
      - "traefik.http.middlewares.auth.basicauth.users=username:REDACTED"

  mqtt:
    image: "eclipse-mosquitto"
    container_name: "mosquitto"
    networks:
      - traefik-global-proxy
    restart: always
    expose:
      - "8883"
      - "9001"
    volumes:
      - "./mosquitto/config:/mosquitto/config/"
      - "./logs:/logs"
      - "./data:/data"
    labels:
      - "traefik.enable=true"

      - "traefik.http.routers.mqtt.rule=Host(`broker.mydomain.com`)"
      - "traefik.http.routers.mqtt.entrypoints=websecure"
      - "traefik.http.routers.mqtt.tls.certresolver=letsencrypt"
      - "traefik.http.services.mqtt.loadbalancer.server.port=9001"

      - "traefik.tcp.routers.mqtt.rule=HostSNI(`broker.mydomain.com`)"
      - "traefik.tcp.routers.mqtt.entrypoints=mqtt"
      - "traefik.tcp.routers.mqtt.tls.certresolver=letsencrypt"
      - "traefik.tcp.services.mqtt.loadbalancer.server.port=8883"

mosquitto.conf

listener 8883 0.0.0.0
protocol mqtt

listener 9001 0.0.0.0
protocol websockets

allow_anonymous true
password_file /mosquitto/config/mosquitto.password

persistence true
persistence_file /data/mosquitto.db

log_dest file /logs/mosquitto.log

这是使用 vue create mqtt-vue 创建的独立 Vue 测试,但未成功:

App.vue

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png" />
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
import mqtt from "mqtt";

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data: () => ({
    connection: {
      host: "broker.mydomain.com",
      port: 9001,
      protocol: "wss",
      username: "USERNAME",
      password: "PASSWORD",
      endpoint: "/",

      clean: true, // Set to false to receive QoS 1 and 2 messages while offline
      connectTimeout: 3 * 1000,
      reconnectPeriod: 1 * 1000,
      // clientId: `my-client-${uuidv4().substring(0, 8)}`,
      keepalive: 30,
    },
    client: {
      connected: false,
    },
  }),
  mounted() {
    console.log("MOUNTED");
    const { host, port, endpoint, ...options } = this.connection;

    const connectUrl = `wss://${host}:${port}${endpoint}`;
    console.log(connectUrl, options);
    this.client = mqtt.connect(connectUrl, options);
    this.client.on("connect", this._onConnect);
    this.client.on("error", (error) => {
      console.warn("Connection failed", error);
    });
  },
  methods: {
    _onConnect() {
      console.log("onConnect", this.client.connected);
    },
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

任何帮助将不胜感激。我一定是在做一些愚蠢的事情。它只是不适合我。希望有人能指出这个问题,我和其他人可以在未来从这篇文章中学习。

【问题讨论】:

  • 只是尝试一下,删除 endpoint 或将其设置为 /mqtt,因为这是 MQTT over WebSockets 的预期路径
  • 我相信traefik.http.routers.mqtt.entrypoints=websecure 表示 traefik 将使用端口 443 进行 websocket 连接,但您正在尝试连接端口 9001;更改端口或使用traefik.http.routers.mqtt.entrypoints=websocket
  • 你是我的英雄!我不敢相信我没有看到。希望上面的完整示例以及您建议的解决方案对将来的人们有所帮助。

标签: vue.js websocket mqtt


【解决方案1】:

根据 cmets traefik.http.routers.mqtt.entrypoints=websecure 意味着 traefik 将使用端口 443 进行 websocket 连接(由于 entrypoints.websecure.address=:443)。

您正在尝试连接端口 9001;更改端口或使用traefik.http.routers.mqtt.entrypoints=websocket

不幸的是,traefik 配置文件可能很难读取/调试!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多