MockServer:模拟外部 http/https 响应拒绝 80/443 上的连接

MockServer: Mocking external http/https response refuses connection on 80/443

我试图实现的是模拟 google oauth2 端点的响应。 这是我的设置:

# docker-compose.yml
version: '3.8'

services:
  busybox:
    image: yauritux/busybox-curl:latest
    command: tail -f /dev/null
    networks:
      - our-network

  api-mock:
    image: mockserver/mockserver
    networks:
      our-network:
        aliases:
          - oauth2.googleapis.com
    environment:
      MOCKSERVER_INITIALIZATION_JSON_PATH: /api-mock/expectations_init.json
      MOCKSERVER_WATCH_INITIALIZATION_JSON: 'true'
    volumes:
      - ./api-mock/:/api-mock
    ports:
      - 1080:1080

networks:
  our-network:

我们的 Mockserver 期望

# ./api-mock/expectations_init.json
[
  {
    "httpRequest": {
      "method": "GET",
      "path": "/token",
      "secure": true
    },
    "httpResponse": {
      "statusCode": 200,
      "body": "Hello World - secure"
    }
  },
  {
    "httpRequest": {
      "method": "GET",
      "path": "/token",
      "secure": false
    },
    "httpResponse": {
      "statusCode": 200,
      "body": "Hello World"
    }
  }
]

我的项目结构

Whosebug
    - ./api-mock
        - expectations_init.json
    - docker-compose.yml

为了运行这个最小的例子只是运行

docker-compose up -d

查看模拟服务器的仪表板

localhost:1080/mockserver/dashboard

我期望的工作是:

docker exec Whosebug_busybox_1 curl -k https://oauth2.googleapis.com/token
# curl: (7) Failed connect to oauth2.googleapis.com:443; Connection refused

有效的是:

docker exec Whosebug_busybox_1 curl -k https://oauth2.googleapis.com:1080/token
# Hello World - secure

此处相同,预计有效:

docker exec Whosebug_busybox_1 curl -k http://oauth2.googleapis.com/token
# curl: (7) Failed connect to oauth2.googleapis.com:80; Connection refused

以及什么有效:

docker exec Whosebug_busybox_1 curl -k http://oauth2.googleapis.com:1080/token
# Hello World

为了在不通过端口的情况下获得响应,我错过了什么配置,因为我无法控制 URL 供应商代码正在调用什么。我在 mockserver 的文档中找不到关于这个用例的任何提示来实现这一点。也许这是 docker/docker-compose?

的问题

此致

问题不在 docker-compose 而在模拟服务器图像中。由于它是在没有 root 权限的情况下执行的,因此它不能使用端口 80,但它始终在端口 1080 上启动(查看 https://www.mock-server.com/where/docker.html#run_docker_container 了解更多信息)。

您可以通过启动 docker 映像来更改端口:

docker run --rm --name mockserver mockserver/mockserver -serverPort 1090

这会让你在端口 1090 上拥有图像 运行ning(这不是你想要的)或者你可以强制容器以根用户身份 运行 并将端口更改为 80 . 例如

docker run --user root --rm --name mockserver mockserver/mockserver -serverPort 80

无论如何,可能有充分的理由不为此使用 root。我从来没有用过这个软件所以我真的不能说。

然后您可以轻松地将命令移植为 docker-compose 格式

此设置效果很好,尤其是使用模拟服务器转发请求时:

nginx-vhosts:

server {
    listen 80 default;

    location / {
        return 418;
    }
}

server {
    listen 443 ssl;

    ssl_certificate /etc/ssl/certs/local.pub.pem;
    ssl_certificate_key /etc/ssl/private/local.key.pem;
    ssl_session_cache shared:SSL:16m;
    ssl_session_timeout 10m;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers RC4:HIGH:!aNULL:!MD5:!kEDH;
    ssl_prefer_server_ciphers on;

    location / {
        return 418;
    }
}

docker-compose.yml

version: '3.8'

services:
  nginx:
    build:
      context: .
      dockerfile: docker/nginx/Dockerfile
    networks:
      - our-network

  busybox:
    image: yauritux/busybox-curl:latest
    command: tail -f /dev/null
    networks:
      - our-network

  api-mock: *api-mock
    image: mockserver/mockserver
    user: root
    command: -serverPort 80
    networks:
      our-network:
        aliases:
          - oauth2.googleapis.com
    environment:
      MOCKSERVER_INITIALIZATION_JSON_PATH: /api-mock/expectations_init.json
      MOCKSERVER_WATCH_INITIALIZATION_JSON: 'true'
    volumes:
      - ./api-mock/:/api-mock
    ports:
      - 1080:80

  api-mock-secure:
    <<: *api-mock
    command: -serverPort 443
    ports:
      - 1081:443

networks:
  our-network:

expectations_init.json

[
  {
    "httpRequest": {
      "method": "GET",
      "path": "/token",
      "headers": {
        "Host": [ "oauth2.googleapis.com" ]
      },
      "secure": true
    },
    "httpResponse": {
      "statusCode": 200,
      "body": "Hello World - secure\n"
    }
  },
  {
    "httpRequest": {
      "method": "GET",
      "path": "/token",
      "headers": {
        "Host": [ "oauth2.googleapis.com" ]
      },
      "secure": false
    },
    "httpResponse": {
      "statusCode": 200,
      "body": "Hello World\n"
    }
  },
  {
    "httpRequest": {
      "secure": false
    },
    "httpForward": {
      "host": "nginx",
      "port": 80,
      "scheme": "HTTP"
    }
  },
  {
    "httpRequest": {
      "secure": true
    },
    "httpForward": {
      "host": "nginx",
      "port": 443,
      "scheme": "HTTPS"
    }
  }
]

感谢 Stefano