Giter Site home page Giter Site logo

mendhak / docker-http-https-echo Goto Github PK

View Code? Open in Web Editor NEW
603.0 5.0 133.0 870 KB

Docker image that echoes request data as JSON; listens on HTTP/S, useful for debugging.

Home Page: https://code.mendhak.com/docker-http-https-echo/

License: MIT License

JavaScript 23.82% Shell 70.56% Dockerfile 5.62%
docker web-debug echo-server https

docker-http-https-echo's Introduction

pulls Docker Image Version (latest semver) GitHub Workflow Status

mendhak/http-https-echo is a Docker image that can echo various HTTP request properties back to client in the response, as well as in the Docker container logs. It comes with various options that can manipulate the response output, see the table of contents for a full list.

browser

The image is available on Docker Hub: mendhak/http-https-echo:33 The image is available on Github Container Registry: ghcr.io/mendhak/http-https-echo:33

Please do not use the :latest tag as it will break without warning, use a specific version instead.

This image is executed as non root by default and is fully compliant with Kubernetes or Openshift deployment.

Basic Usage

Run with Docker

docker run -p 8080:8080 -p 8443:8443 --rm -t mendhak/http-https-echo:33

Or run with Docker Compose

docker-compose up

Then, issue a request via your browser or curl, and watch the response, as well as container log output.

curl -k -X PUT -H "Arbitrary:Header" -d aaa=bbb https://localhost:8443/hello-world

Choose your ports

You can choose a different internal port instead of 8080 and 8443 with the HTTP_PORT and HTTPS_PORT environment variables.

In this example I'm setting http to listen on 8888, and https to listen on 9999.

 docker run -e HTTP_PORT=8888 -e HTTPS_PORT=9999 -p 8080:8888 -p 8443:9999 --rm -t mendhak/http-https-echo:33

With docker compose, this would be:

my-http-listener:
    image: mendhak/http-https-echo:33
    environment:
        - HTTP_PORT=8888
        - HTTPS_PORT=9999
    ports:
        - "8080:8888"
        - "8443:9999"

Use your own certificates

The certificates are at /app/fullchain.pem and /app/privkey.pem.

You can use volume mounting to substitute the certificate and private key with your own.

my-http-listener:
    image: mendhak/http-https-echo:33
    ports:
        - "8080:8080"
        - "8443:8443"
    volumes:
        - /etc/ssl/certs/ssl-cert-snakeoil.pem:/app/fullchain.pem
        - /etc/ssl/private/ssl-cert-snakeoil.key:/app/privkey.pem

You can use the environment variables HTTPS_CERT_FILE and HTTPS_KEY_FILE to define the location of existing certificate and private key inside container.

Decode JWT header

If you specify the header that contains the JWT, the echo output will contain the decoded JWT. Use the JWT_HEADER environment variable for this.

docker run -e JWT_HEADER=Authentication -p 8080:8080 -p 8443:8443 --rm -it mendhak/http-https-echo:33

Now make your request with Authentication: eyJ... header (it should also work with the Authentication: Bearer eyJ... schema too):

 curl -k -H "Authentication: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" http://localhost:8080/

And in the output you should see a jwt section.

Disable ExpressJS log lines

In the log output set the environment variable DISABLE_REQUEST_LOGS to true, to disable the specific ExpressJS request log lines. The ones like ::ffff:172.17.0.1 - - [03/Jan/2022:21:31:51 +0000] "GET /xyz HTTP/1.1" 200 423 "-" "curl/7.68.0". The JSON output will still appear.

docker run --rm -e DISABLE_REQUEST_LOGS=true --name http-echo-tests -p 8080:8080 -p 8443:8443 -t mendhak/http-https-echo:33

Do not log specific path

Set the environment variable LOG_IGNORE_PATH to a path you would like to exclude from verbose logging to stdout. This can help reduce noise from healthchecks in orchestration/infrastructure like Swarm, Kubernetes, ALBs, etc.

 docker run -e LOG_IGNORE_PATH=/ping -p 8080:8080 -p 8443:8443 --rm -t mendhak/http-https-echo:33

With docker compose, this would be:

my-http-listener:
    image: mendhak/http-https-echo:33
    environment:
        - LOG_IGNORE_PATH=/ping
    ports:
        - "8080:8080"
        - "8443:8443"

JSON payloads and JSON output

If you submit a JSON payload in the body of the request, with Content-Type: application/json, then the response will contain the escaped JSON as well.

For example,

curl -X POST -H "Content-Type: application/json" -d '{"a":"b"}' http://localhost:8080/

Will contain a json property in the response/output.

    ...
    "xhr": false,
    "connection": {},
    "json": {
        "a": "b"
    }
}

No newlines

You can disable new lines in the log output by setting the environment variable LOG_WITHOUT_NEWLINE. For example,

docker run -e LOG_WITHOUT_NEWLINE=true -p 8080:8080 -p 8443:8443 --rm -t mendhak/http-https-echo:33

Send an empty response

You can disable the JSON output in the response by setting the environment variable ECHO_BACK_TO_CLIENT. For example,

docker run -e ECHO_BACK_TO_CLIENT=false -p 8080:8080 -p 8443:8443 --rm -t mendhak/http-https-echo:33

Custom status code

Use x-set-response-status-code to set a custom status code.

You can send it as a header:

curl -v -H "x-set-response-status-code: 401" http://localhost:8080/

You can send it as a querystring parameter:

curl -v http://localhost:8080/some/path?x-set-response-status-code=401

That will cause the reponse status code to be:

 HTTP/1.1 401 Unauthorized

Set response Content-Type

Use x-set-response-content-type to set the Content-Type of the response.

You can send it as a header:

curl -H "X-Set-Response-Content-Type: text/plain" -kv https://localhost:8443/

You can send it as a querystring parameter:

curl  -kv https://localhost:8443/path?x-set-response-content-type=text/plain

This will cause the response content type to be:

< Content-Type: text/plain; charset=utf-8

Add a delay before response

Use x-set-response-delay-ms to set a custom delay in milliseconds. This will allow you to simulate slow responses.

You can send it as a header:

curl -v -H "x-set-response-delay-ms: 6000" http://localhost:8080/

You can send it as a querystring parameter:

curl -v http://localhost:8080/some/path?x-set-response-delay-ms=6000

Only return body in the response

Use the querystring parameter, response_body_only=true to get just the request body in the response, none of the associated metadata.

curl -s -k -X POST -d 'cauliflower' http://localhost:8080/a/b/c?response_body_only=true

The output will be 'cauliflower'.

Include environment variables in the response

You can have environment variables (that are visible to the echo server's process) added to the response body. Because this could contain sensitive information, it is not a default behavior.

Pass the ECHO_INCLUDE_ENV_VARS=1 environment variable in.

docker run -d --rm -e ECHO_INCLUDE_ENV_VARS=1 --name http-echo-tests -p 8080:8080 -p 8443:8443 -t mendhak/http-https-echo:33

Then do a normal request via curl or browser, and you will see the env property in the response body.

Setting CORS(Cross-Origin Resource Sharing) headers in the response

Enable CORS headers in response by setting the environment variable CORS_ALLOW_ORIGIN to the list of allowed origins. CORS configuration can be further fine-tuned by using the following environment variables:

  • CORS_ALLOW_METHODS: List of Http methods allowed.
  • CORS_ALLOW_HEADERS: List of headers allowed.
  • CORS_ALLOW_CREDENTIALS: Comma-separated list of origin URLs from which the policy allows credentials to be sent.

None of these CORS settings can be set without setting the CORS_ALLOW_ORIGIN first. By default, they will all be missing when only the CORS_ALLOW_ORIGIN is set and need to be explicitly specified alongside CORS_ALLOW_ORIGIN.

Client certificate details (mTLS) in the response

To get client certificate details in the response body, start the container with MTLS_ENABLE=1 environment variable. When passing a client certificate, the details about that certificate can be echoed back in the response body. The client certificate will not be validated.

For example, invoke using curl, passing a certificate and key.

curl -k --cert cert.pem --key privkey.pem  https://localhost:8443/

The response body will contain details about the client certificate passed in.

If you browse to https://localhost:8443/ in Firefox, you won't get prompted to supply a client certificate unless you have an imported certificate by the same issuer as the server. If you need browser prompting to work, you'll need to follow the 'use your own certificates' section. Firefox needs the imported certificate to be in a PKCS12 format, so if you have a certificate and key already, you can combine them using

openssl pkcs12 -export -in cert.pem -inkey privkey.pem -out certpkcs12.pfx

Prometheus Metrics

To expose http performance metrics, set the PROMETHEUS_ENABLED environment variable to true, the metrics will be available at /metrics. This uses the express-prom-bundle middleware

You can configure these metrics using the following variables:

Variable Description Default Value
PROMETHEUS_ENABLED Toggles on the prometheus middleware false
PROMETHEUS_METRICS_PATH The path at which the metrics will be visible /metrics
PROMETHEUS_WITH_PATH Partitions the metrics by the requested path false
PROMETHEUS_WITH_METHOD Partitions the metrics by HTTP method true
PROMETHEUS_WITH_STATUS Partitions the metrics by HTTP status true
PROMETHEUS_METRIC_TYPE Sets the type of metric, histogram or summary summary

Please check the middleware documentation for more details.

Screenshots

Curl output

curl

docker logs output

dockerlogs

Building

docker build -t mendhak/http-https-echo .

Run some tests to make sure features are working as expected.

./tests.sh

To create a new image on Docker Hub, I need to create a tag and push it.

git tag -s 16
git push --tags

Changelog

See the changelog

docker-http-https-echo's People

Contributors

ash0ne avatar bjw-s avatar dependabot[bot] avatar err0r500 avatar kurounin avatar mabrarov avatar marcinfalkowski avatar mendhak avatar mxcoder avatar natexcvi avatar scprek avatar slonka avatar solsson avatar sylvaindd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

docker-http-https-echo's Issues

Please allow monetary contributions for this project

I've been hammering my head for a whole day trying to make a 3rd party application written in Erlang to work behind a reverse proxy when everything looked just fine an the application logging was enough at best

This container did help me to understand what this app was expecting to see and how... and oddly how much (it didn't like multiple values on the X-Forwarded-* headers) xD

I'll happily pay for a coffee/beer is you provide a way for doing this ;)

purpose

just curious, but is there an additional benefit in using this tool, from dev perspective, as opposed to just using netcat/socat?

$ printf "%s\n"   "HTTP/1.0 200 OK"  "" \
    | docker run -i --rm --name test -p 8080:80 alpine:3.10 nc -lp 80 &
$ echo '{ "key": "value" }' | curl -D- -d@- localhost:8080
HTTP/1.0 200 OK

POST / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.54.0
Accept: */*
Content-Length: 18
Content-Type: application/x-www-form-urlencoded

{ "key": "value" }
$ 

[bug] Docker logs emit invalid JSON with nested double quotes and braces

Hey @mendhak, something messes with the escaping of the payloads and makes the logged JSON invalid. Here is the emitted log:

httpecho_1      | -----------------
httpecho_1      | { path: '/',
httpecho_1      |   headers:
httpecho_1      |    { host: 'httpecho:8888',
httpecho_1      |      'user-agent': 'Alertmanager/0.21.0',
httpecho_1      |      'content-length': '905',
httpecho_1      |      'content-type': 'application/json' },
httpecho_1      |   method: 'POST',
httpecho_1      |   body: '{"receiver":"generic","status":"firing","alerts":[{"status":"firing","labels":{"alertname":"WhatEver","foo_bar_qux":"foo_moo_zoom","severity":"warning"},"annotations":{"description":"A Prometheus job has disappeared\\\\n  VALUE = 2\\\\n  LABELS: map[]","summary":"Prometheus job missing (instance )"},"startsAt":"2020-11-03T17:09:36.14925565Z","endsAt":"0001-01-01T00:00:00Z","generatorURL":"http://9e6d80bea9ef:9090/graph?g0.expr=vector%282%29+%3E+vector%281%29\\u0026g0.tab=1","fingerprint":"d57ff78af6ac95e8"}],"groupLabels":{"alertname":"WhatEver"},"commonLabels":{"alertname":"WhatEver","foo_bar_qux":"foo_moo_zoom","severity":"warning"},"commonAnnotations":{"description":"A Prometheus job has disappeared\\\\n  VALUE = 2\\\\n  LABELS: map[]","summary":"Prometheus job missing (instance )"},"externalURL":"http://1217896f2a1d:9093","version":"4","groupKey":"{}:{alertname=\\"WhatEver\\"}","truncatedAlerts":0}\n',
httpecho_1      |   cookies: undefined,
httpecho_1      |   fresh: false,
httpecho_1      |   hostname: 'httpecho',
httpecho_1      |   ip: '::ffff:172.18.0.3',
httpecho_1      |   ips: [],
httpecho_1      |   protocol: 'http',
httpecho_1      |   query: {},
httpecho_1      |   subdomains: [],
httpecho_1      |   xhr: false,
httpecho_1      |   os: { hostname: '1b549382c54e' },
httpecho_1      |   connection: { servername: undefined } }
httpecho_1      | ::ffff:172.18.0.3 - - [03/Nov/2020:17:10:06 +0000] "POST / HTTP/1.1" 200 1451 "-" "Alertmanager/0.21.0"

If you go ahead and copy paste the payload body into a validator you will get an error.

Parse error on line 35:
...":"{}:{alertname=\\"WhatEver\\"}",  "tr
-----------------------^
Expecting 'EOF', '}', ':', ',', ']', got 'undefined'

Is this expected or fixable? Or is there another way to get the "real" payload? I want to use your docker image to get payloads for testing stuff

If you want to reproduce my setup simply run docker-compose up with the set of files attached in the zip. You will have to wait 2 minutes for the request to arrive

docker-compose.zip


Here is the payload I would expect:

{
  "receiver": "generic",
  "status": "firing",
  "alerts": [
    {
      "status": "firing",
      "labels": {
        "alertname": "WhatEver",
        "foo_bar_qux": "foo_moo_zoom",
        "severity": "warning"
      },
      "annotations": {
        "description": "A Prometheus job has disappeared\\n  VALUE = 2\\n  LABELS: map[]",
        "summary": "Prometheus job missing (instance )"
      },
      "startsAt": "2020-11-03T17:51:36.14925565Z",
      "endsAt": "0001-01-01T00:00:00Z",
      "generatorURL": "http://9e6d80bea9ef:9090/graph?g0.expr=vector%282%29+%3E+vector%281%29&g0.tab=1",
      "fingerprint": "d57ff78af6ac95e8"
    }
  ],
  "groupLabels": {
    "alertname": "WhatEver"
  },
  "commonLabels": {
    "alertname": "WhatEver",
    "foo_bar_qux": "foo_moo_zoom",
    "severity": "warning"
  },
  "commonAnnotations": {
    "description": "A Prometheus job has disappeared\\n  VALUE = 2\\n  LABELS: map[]",
    "summary": "Prometheus job missing (instance )"
  },
  "externalURL": "http://1217896f2a1d:9093",
  "version": "4",
  "groupKey": "{}:{alertname=\"WhatEver\"}",
  "truncatedAlerts": 0
}

Use Github action as CI/CD

The current "build passing" badge is actually not a CI/CD but a link to the Docker hub page.
As you've already coded some tests, you should implement Github action as CI/CD for this project.
Then protect PRs with this CI/CD.

Pass response status code via query string or path

Will be nice if it will be possible to pass response code not only by HTTP headers but by query string or path

Motivation: at moment I'm playing with nginx ingress, in its annotations I can pass URL only nothing else 🤷‍♂️

Seems like it will require really small change here, something like:

const setResponseStatusCode = parseInt(req.headers["x-set-response-status-code"] || req.query["x-set-response-status-code"], 10)

feature: add opencontainers label to the docker image

Request: Make distributed docker image contain org.opencontainers.image.source label for easy reference back to this repository when mendhak/http-https-echo image gets updates.

We are building a custom image off of mendhak/http-https-echo, and we are using automatic tools to update the version of that base image, and those tools can create better pull request with more metadata if this is found is standardised labels.

It is some other pre-defined OCI keys, but org.opencontainers.image.source should be the correct one.

Option to change log format to JSON

First off, thank you for putting in the work. This is a super helpful project.


I would appreciate it if it was possible to enable an option besides LOG_WITHOUT_NEWLINE and DISABLE_REQUEST_LOGS to have one line per request in the log output formatted as JSON.

One of the reasons is that I don't use the logs on the host machine directly. They might get scraped and processed out of order by Loki, so they might not end up next to each other. The second reason is that it would be simpler to parse them when they had the same format.

Would it be possible to add TZ environment variables?

I don't know how to set the time zone variable, an example that works is mariadb:latest, amazoncorretto:21

this is example docker-compose.yaml:

version: '3.8'
  server-a:
    container_name: server-a
    image: mendhak/http-https-echo
    environment:
      TZ: Europe/Warsaw
    ports:
      - "8091:8080"

Expose prometheus/statsd metrics

Would be amazing if this tool would support the option to expose its own metrics, like:

  • uptime
  • total requests
  • total requests per status
  • total requests per path
  • requests per second
  • requests per second per status
  • requests per second per path
  • latency (and percentiles)
    I'll check how difficult would it be to do it with some exporter, but maybe someone else has an easier approach.

Http header case should be preserved.

Currently all headers are lower cased, e.g. Content-Type -> content-type.

I know that headers are case insensitive, but they should be case preserving.

Some faulty servers depend on a certain case and it would be nice to echo back exactly what was sent.

Could this server accept http2?

It looks like http2 is not supported, do you have any plan to add this feature?

yutongli@yutongli:~$ curl -k https://localhost:8443 -v --http2
*   Trying 127.0.0.1:8443...
* Connected to localhost (127.0.0.1) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=US; ST=Utah; L=Provo; O=ACME Tech Inc; CN=my.example.com
*  start date: Nov 23 07:59:02 2021 GMT
*  expire date: Apr  9 07:59:02 2049 GMT
*  issuer: C=US; ST=Utah; L=Provo; O=ACME Signing Authority Inc; CN=example.com
*  SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.
> GET / HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.79.1
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK

always got connection reset

i ran the docker using readme commands, but when curl anything using local or external ip i always got 'connection reset'. if not run then it is connection refused, which means the docker is sort of 'working'.

Not working on Openshift.

Hi, the last image is not working anymore on Openshift 4.

internal/fs/utils.js:308
    throw err;
    ^

Error: EACCES: permission denied, open 'privkey.pem'
    at Object.openSync (fs.js:476:3)
    at Object.readFileSync (fs.js:377:35)
    at Object.<anonymous> (/app/index.js:73:22)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47 {
  errno: -13,
  syscall: 'open',
  code: 'EACCES',
  path: 'privkey.pem'
}

Here is the deploymentConfig I use (Ansible code)

- name: Create http-echo deployment
  k8s:
    kubeconfig: "{{ ocp_ignition_file_path }}/auth/kubeconfig"
    state: present
    namespace: "{{ project_name }}"
    definition:
      kind: DeploymentConfig
      apiVersion: v1
      metadata:
        labels:
          app: "{{ project_name }}"
        name: "{{ project_name }}-deployment"
        annotations:
          description: An http echo service
          template.alpha.openshift.io/wait-for-ready: 'true'
      spec:
        selector:
          name: "http-echo"
        template:
          metadata:
            labels:
              name: "http-echo"
          spec:
            containers:
              - name: "http-echo"
                image: "mendhak/http-https-echo" # https://github.com/mendhak/docker-http-https-echo
                env:
                  - name: HTTP_PORT
                    value: "8000"
                  - name: HTTPS_PORT
                    value: "9000"
                ports:
                  - containerPort: 80
                    protocol: TCP
        replicas: 1
        strategy:
          type: Recreate
        paused: false
        revisionHistoryLimit: 2
        minReadySeconds: 0
    wait: yes
    wait_condition:
      type: Available
      status: True

I tried as well with the "issue-14-non-root" tag.

JSON log as single line

Hi and thank you for this image!

It would be great if the JSON in the log could be either disabled completely (just like the express logs) or configured to be printed compressed (as a single line) instead of pretty printed over multiple lines.

I have it running in an orchestrated environment and logs shipped to loggly, so a single line per request would be better.

Provide alternate image registry to Docker Hub

Since Docker Hub has been applying rate limits on image pulls for a while now, and their more recent move to scrap free teams I feel that Docker Hub is becoming more and more hostile towards the OSS/hobbyist community.

I would like to propose providing GitHub Container Registry as an alternative (or completely switching over to it) for the project.

Would you be open to this? If so, I'd be willing to write up a PR to implement.

Show details of incoming mTLS Authentication/Client Certificates

First of all: Awesome project :)

I just recently stumbled across a use case where I wanted to debug a reverse proxy and see whether it properly forwards mTLS authentication/SSL client certificates correctly. However, the http-https-echo server doesn't say/print that information as far as I could tell. Maybe I overlooked something or used it wrong?

Output similar to this would be expected:

{
  "mtls": true,
  "mtls-details": {
    "common-name": "something",
    "authority-common-name": "something else"
  }
}

Custom response codes

Hi,

would you accept a PR that makes it possible to set a custom status code? It could be triggered by a header (e.g. x-set-response-status-code: 503) or a special path /status-code/503.

This would be useful in integration tests in our project Envoy-Control: https://github.com/allegro/envoy-control/blob/835a72e920024722ce02a5ab8630be357f4b971b/envoy-control-tests/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/config/service/HttpsEchoContainer.kt#L10

If it's ok I'd create a PR.

Force a request to sleep for a period of time

This is an awesome testing utility, thanks so much. We use it a lot for testing our k8s proxy logic (nginx/haproxy etc.) If it could expand to allow a custom header to cause a sleep period for a given request, it would provide the ability to also test features of proxies like request queuing and server bottlenecking.

Node base image insecure

Docker base image outdated and insecure

The node:9.2-alpine tag has not been updated in several years (3), resulting in a significant amount of accumulated potential security issues in the resulting image. Anchore grype reports the following:

NAME               INSTALLED  FIXED-IN  VULNERABILITY        SEVERITY 
chownr             1.0.1                CVE-2017-18869       Low       
cryptiles          3.1.2      4.1.2     GHSA-rq8g-5pc5-wrhr  High      
cryptiles          3.1.2                CVE-2018-1000620     Critical  
debug              2.6.8      2.6.9     GHSA-gxpj-cx7g-858c  Low       
debug              2.6.8                CVE-2017-16137       Medium    
deep-extend        0.4.2      0.5.1     GHSA-hr2v-3952-633q  Low       
dot-prop           4.1.1      4.2.1     GHSA-ff7x-qrg7-qggm  High      
dot-prop           4.1.1                CVE-2020-8116        High      
editor             1.0.0                CVE-2015-0903        High      
extend             3.0.1      3.0.2     GHSA-qrmc-fj45-qfc2  Medium    
extend             3.0.1                CVE-2018-16492       Critical  
fstream            1.0.11     1.0.12    GHSA-xf7w-r453-m56c  High      
fstream            1.0.11               CVE-2019-13173       High      
hoek               4.2.0      4.2.1     GHSA-jp4x-w63m-7wgm  Medium    
http-proxy-agent   2.0.0      2.1.0     GHSA-8w57-jfpm-945m  High      
https-proxy-agent  2.1.0      2.2.3     GHSA-pc5p-h8pf-mvwp  High      
https-proxy-agent  2.1.0      2.2.0     GHSA-8g7p-74h8-hg48  High      
https-proxy-agent  2.1.0                CVE-2018-3739        Critical  
lodash             3.10.1     4.17.19   GHSA-p6mc-m468-83gw  Low       
lodash             3.10.1     4.17.11   GHSA-x5rq-j2xg-h7qm  Medium    
lodash             3.10.1     4.17.11   GHSA-4xc9-xhrj-v574  High      
lodash             3.10.1     4.17.12   GHSA-jf85-cpcp-j695  High      
lodash             3.10.1     4.17.5    GHSA-fvqr-27wr-82fm  Low       
lodash             3.10.1               CVE-2018-3721        Medium    
lodash             3.10.1               CVE-2018-16487       Medium    
lodash             3.10.1               CVE-2019-1010266     Medium    
lodash             3.10.1               CVE-2019-10744       Critical  
lodash             3.10.1               CVE-2020-8203        High      
mem                1.1.0      4.0.0     GHSA-4xcv-9jjx-gfj3  Low       
minimist           1.2.0      1.2.3     GHSA-vh95-rmgr-6w4m  Low       
minimist           1.2.0                CVE-2020-7598        Medium    
minimist           0.0.8      0.2.1     GHSA-7fhm-mqm4-2wp7  Medium    
minimist           0.0.8      0.2.1     GHSA-vh95-rmgr-6w4m  Low       
minimist           0.0.8                CVE-2020-7598        Medium    
npm                5.5.1      6.14.6    GHSA-93f3-23rq-pjfp  Low       
npm                5.5.1      6.13.3    GHSA-m6cx-g6qm-p2cx  Low       
npm                5.5.1      6.13.3    GHSA-x8qc-rrcw-4r46  Low       
npm                5.5.1      6.13.4    GHSA-4328-8hgf-7wjr  Low       
npm-user-validate  1.0.0      1.0.1     GHSA-xgh6-85xh-479p  Low       
npm-user-validate  1.0.0                CVE-2020-7754        High      
rc                 1.2.1                CVE-2014-1936        High      
slash              1.0.0                CVE-2002-1647        Medium    
sshpk              1.13.1     1.13.2    GHSA-2m39-62fm-q8r3  High      
sshpk              1.13.1               CVE-2018-3737        High      
ssri               4.1.6      5.2.2     GHSA-325j-24f4-qv5x  Medium    
ssri               4.1.6                CVE-2018-7651        Medium    
stringstream       0.0.5      0.0.6     GHSA-mf6x-7mm4-x2g7  Medium    
tar                2.2.1      2.2.2     GHSA-j44m-qm6p-hp7m  High      
tar                2.2.1                CVE-2007-4476        High      
tar                4.0.1      4.4.2     GHSA-j44m-qm6p-hp7m  High      
tar                4.0.1                CVE-2007-4476        High      
yargs-parser       7.0.0      13.1.2    GHSA-p9pc-299p-vxgp  Low       
yargs-parser       7.0.0                CVE-2020-7608        Medium    
yarn               1.3.2      1.17.3    GHSA-wqfc-cr59-h64p  High      
yarn               1.3.2      1.22.0    GHSA-5xf4-f2fq-f69j  Medium    
yarn               1.3.2                CVE-2019-10773       High      
yarn               1.3.2                CVE-2019-5448        High      
yarn               1.3.2                CVE-2019-15608       Medium    
yarn               1.3.2                CVE-2020-8131        High      

A few, notable editor and tar are likely false positives, but the majority are actually present in the node base image, and absent in more recent tags.

Error: EACCES: permission denied, open 'privkey.pem'

I was consuming this image in one of our tests and since the latest update it stopped working.
The test is quite simple: make a request to the app and check the returned response. But instead, the pod is in a CrashLoopBackOff state and shows the following logs:

internal/fs/utils.js:308
    throw err;
    ^
Error: EACCES: permission denied, open 'privkey.pem'
    at Object.openSync (fs.js:476:3)
    at Object.readFileSync (fs.js:377:35)
    at Object.<anonymous> (/app/index.js:67:22)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47 {
  errno: -13,
  syscall: 'open',
  code: 'EACCES',
  path: 'privkey.pem'
}

Our setup cannot allow images to run as root, therefore this wouldn't be a valid solution.

Error for requests with gzip content encoding and json content type

Request headers:

headers = {
    'content-type': 'application/json',
    'charset': 'utf-8',
    'content-encoding': 'gzip',
}

Output in console:

SyntaxError: Unexpected token ▼ in JSON at position 0
    at JSON.parse (<anonymous>)
    at /app/index.js:48:22
    at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)
    at next (/app/node_modules/express/lib/router/route.js:137:13)
    at next (/app/node_modules/express/lib/router/route.js:131:14)
    at next (/app/node_modules/express/lib/router/route.js:131:14)
    at next (/app/node_modules/express/lib/router/route.js:131:14)
    at next (/app/node_modules/express/lib/router/route.js:131:14)
    at next (/app/node_modules/express/lib/router/route.js:131:14)
    at next (/app/node_modules/express/lib/router/route.js:131:14)

EACCES: permission denied, open 'privkey.pem'

I am trying to use my own created certs.

docker run --user node -p 8080:8080 -p 8443:8443 -v /etc/ssl/certs/fullchain.pem:/app/fullchain.pem -v /etc/ssl/private/privkey.pem:/app/privkey.pem --rm -t mendhak/http-https-echo:26
node:internal/fs/utils:347
throw err;
^

Error: EACCES: permission denied, open 'privkey.pem'
at Object.openSync (node:fs:590:3)
at Object.readFileSync (node:fs:458:35)
at Object. (/app/index.js:124:22)
at Module._compile (node:internal/modules/cjs/loader:1155:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1209:10)
at Module.load (node:internal/modules/cjs/loader:1033:32)
at Function.Module._load (node:internal/modules/cjs/loader:868:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:22:47 {
errno: -13,
syscall: 'open',
code: 'EACCES',
path: 'privkey.pem'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.