From ff7fdf435056439b11922a197c7a5174072d07be Mon Sep 17 00:00:00 2001 From: Ivan Schaller Date: Thu, 13 Apr 2023 19:42:09 +0200 Subject: [PATCH 1/2] update Dockerfile and README. And add maxmind example Signed-off-by: Ivan Schaller --- Dockerfile | 62 ++++++++++++++++--- README.md | 33 ++++++---- examples/docker-simple/docker-compose.yml | 10 +-- .../docker-simple/docker-compose_maxmind.yml | 36 +++++++++++ 4 files changed, 114 insertions(+), 27 deletions(-) create mode 100644 examples/docker-simple/docker-compose_maxmind.yml diff --git a/Dockerfile b/Dockerfile index e845f8c..629cb73 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,62 @@ -FROM golang AS build +FROM golang:1.20.3-alpine3.17 AS build -RUN mkdir /endlessh -ADD . /endlessh -WORKDIR /endlessh -RUN go mod tidy -RUN go build -o endlessh . +# environment settings +ARG GOOS="linux" \ + CGO_ENABLED="0" -FROM gcr.io/distroless/base +# copy files to container +COPY . "/tmp/endlessh-go/" +# set build workdir +WORKDIR "/tmp/endlessh-go/" + +# build app +RUN \ + go mod tidy \ + && go build -o "endlessh-go" + + +FROM alpine:3.17 + +# labels LABEL org.opencontainers.image.title=endlessh-go LABEL org.opencontainers.image.description="Endlessh: an SSH tarpit" LABEL org.opencontainers.image.vendor="Shizun Ge" LABEL org.opencontainers.image.licenses=GPLv3 -COPY --from=build /endlessh/endlessh /endlessh + +# install packages +RUN \ + echo "**** installing base packages ****" \ + && apk update \ + && apk --no-cache add \ + ca-certificates \ + bash \ + procps \ + tzdata + +# prepare container +RUN \ + echo "**** create default user ****" \ + && addgroup -S -g 2000 abc \ + && adduser -S -D -H -s /bin/bash -u 2000 -G abc abc + +# cleanup installation +RUN \ + echo "**** cleanup ****" \ + && rm -rf \ + /tmp/* \ + /var/cache/apk/* \ + /var/tmp/* + +# copy files to container +COPY --from=build "/tmp/endlessh-go/endlessh-go" "/usr/local/bin/" + +# ssh / prometheus port EXPOSE 2222 2112 -USER nobody -ENTRYPOINT ["/endlessh"] + +USER abc + +ENTRYPOINT ["/usr/local/bin/endlessh-go"] + CMD ["-logtostderr", "-v=1"] diff --git a/README.md b/README.md index 7685a7a..2ff4e76 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ go build . Alternatively, you can use the [docker image](https://hub.docker.com/r/shizunge/endlessh-go): ``` -sudo docker run -d -p 2222:2222 shizunge/endlessh-go -logtostderr -v=1 +docker run -d -p 2222:2222 shizunge/endlessh-go -logtostderr -v=1 ``` It listens to port `2222` by default. @@ -33,6 +33,8 @@ Then you can try to connect to the endlessh server. Your SSH client should hang ssh -p 2222 localhost ``` +The default container user has uid/gid 2000. + If you want log like the [C implementation](https://github.com/skeeto/endlessh), you need to set both CLI arguments `-logtostderr` and `-v=1`, then the log will go to stderr. You can set different log destinations via CLI arguments. Also check out [examples](./examples/README.md) for the setup of the full stack. @@ -50,7 +52,7 @@ Usage of ./endlessh-go -enable_prometheus Enable prometheus -geoip_supplier string - Supplier to obtain Geohash of IPs. Possible values are "off", "ip-api", "freegeoip", "max-mind-db" (default "off") + Supplier to obtain Geohash of IPs. Possible values are "off", "ip-api", "max-mind-db" (default "off") -host string SSH listening address (default "0.0.0.0") -interval_ms int @@ -83,18 +85,26 @@ Usage of ./endlessh-go comma-separated list of pattern=N settings for file-filtered logging ``` +## Using privileged ports (<1024) + +If you want to run the image with privileged ports (below 1025), you need to set the container user to root: + +```yml +user: root +``` + ## Metrics Endlessh-go exports the following Prometheus metrics. -| Metric | Type | Description | -|--------------------------------------|-------|--------------| -| endlessh_client_open_count_total | count | Total number of clients that tried to connect to this host. | -| endlessh_client_closed_count_total | count | Total number of clients that stopped connecting to this host. | -| endlessh_sent_bytes_total | count | Total bytes sent to clients that tried to connect to this host. | -| endlessh_trapped_time_seconds_total | count | Total seconds clients spent on endlessh. | -| endlessh_client_open_count | count | Number of connections of clients.
Labels:
| -| endlessh_client_trapped_time_seconds | count | Seconds a client spends on endlessh.
Labels:
| +| Metric | Type | Description | +| ------------------------------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| endlessh_client_open_count_total | count | Total number of clients that tried to connect to this host. | +| endlessh_client_closed_count_total | count | Total number of clients that stopped connecting to this host. | +| endlessh_sent_bytes_total | count | Total bytes sent to clients that tried to connect to this host. | +| endlessh_trapped_time_seconds_total | count | Total seconds clients spent on endlessh. | +| endlessh_client_open_count | count | Number of connections of clients.
Labels:
| +| endlessh_client_trapped_time_seconds | count | Seconds a client spends on endlessh.
Labels:
| The metrics is off by default, you can turn it via the CLI argument `-enable_prometheus`. @@ -102,7 +112,7 @@ It listens to port `2112` and entry point is `/metrics` by default. The port and The endlessh-go server stores the geohash of attackers as a label on `endlessh_client_open_count`, which is also off by default. You can turn it on via the CLI argument `-geoip_supplier`. The endlessh-go uses service from [ip-api](https://ip-api.com/), which may enforce a query rate and limit commercial use. Visit their website for their terms and policies. -You could also use an offline GeoIP database from [MaxMind](https://www.maxmind.com) by setting `-geoip_supplier` to *max-mind-db* and `-max_mind_db` to the path of the database file. +You could also use an offline GeoIP database from [MaxMind](https://www.maxmind.com) by setting `-geoip_supplier` to _max-mind-db_ and `-max_mind_db` to the path of the database file. ## Dashboard @@ -114,7 +124,6 @@ The dashboard visualizes data for the selected time range. The IP addresses are clickable and link you to the [ARIN](https://www.arin.net/) database. - ## Contacts If you have any problems or questions, please contact me through a [GitHub issue](https://github.com/shizunge/endlessh-go/issues) diff --git a/examples/docker-simple/docker-compose.yml b/examples/docker-simple/docker-compose.yml index 3d0185a..b711fd5 100644 --- a/examples/docker-simple/docker-compose.yml +++ b/examples/docker-simple/docker-compose.yml @@ -1,5 +1,6 @@ version: '3.5' services: + endlessh: container_name: endlessh image: shizunge/endlessh-go:latest @@ -13,16 +14,14 @@ services: networks: - example_network ports: - # SSH port - - 2222:2222 - # Prometheus metrics port - - 127.0.0.1:2112:2112 + - 2222:2222 # SSH port + - 127.0.0.1:2112:2112 # Prometheus metrics port prometheus: image: prom/prometheus:latest container_name: prometheus restart: always - command: + command: - --config.file=/etc/prometheus/prometheus.yml - --storage.tsdb.path=/prometheus - --storage.tsdb.retention.time=45d @@ -55,6 +54,7 @@ services: networks: example_network: + volumes: prometheus: grafana_var: diff --git a/examples/docker-simple/docker-compose_maxmind.yml b/examples/docker-simple/docker-compose_maxmind.yml new file mode 100644 index 0000000..c5fd7a7 --- /dev/null +++ b/examples/docker-simple/docker-compose_maxmind.yml @@ -0,0 +1,36 @@ +version: "3" +services: + + endlessh: + container_name: endlessh + image: shizunge/endlessh-go:latest + restart: unless-stopped + #user: root + command: + - "-logtostderr" + - "-v=1" + - "-geoip_supplier=max-mind-db" + - "-max_mind_db=/geo-data/GeoLite2-City.mmdb" + networks: + - example_network + ports: + - 2222:2222 # SSH port + - 127.0.0.1:2112:2112 # Prometheus metrics port + volumes: + - ./geo-data/:/geo-data/:ro # geoip data + + geoipupdate: + image: ghcr.io/maxmind/geoipupdate:v5 + container_name: geoipupdate + restart: unless-stopped + security_opt: [ "no-new-privileges:true" ] + volumes: + - ./geo-data/:/usr/share/GeoIP/ + environment: + - GEOIPUPDATE_EDITION_IDS=GeoLite2-City + - GEOIPUPDATE_FREQUENCY=72 + - GEOIPUPDATE_ACCOUNT_ID=xxxxxx + - GEOIPUPDATE_LICENSE_KEY=xxxxxx + +networks: + example_network: From a112241c76196a34add1595c8578bba9b5f18bb0 Mon Sep 17 00:00:00 2001 From: Ivan Schaller Date: Mon, 17 Apr 2023 17:06:42 +0200 Subject: [PATCH 2/2] make wanted changes Signed-off-by: Ivan Schaller --- Dockerfile | 62 +++---------------- README.md | 26 +++----- examples/README.md | 13 ++++ examples/docker-maxmind/README.md | 16 +++++ .../docker-compose.yml} | 0 5 files changed, 47 insertions(+), 70 deletions(-) create mode 100644 examples/docker-maxmind/README.md rename examples/{docker-simple/docker-compose_maxmind.yml => docker-maxmind/docker-compose.yml} (100%) diff --git a/Dockerfile b/Dockerfile index 629cb73..e845f8c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,62 +1,20 @@ -FROM golang:1.20.3-alpine3.17 AS build +FROM golang AS build -# environment settings -ARG GOOS="linux" \ - CGO_ENABLED="0" +RUN mkdir /endlessh +ADD . /endlessh +WORKDIR /endlessh +RUN go mod tidy +RUN go build -o endlessh . -# copy files to container -COPY . "/tmp/endlessh-go/" +FROM gcr.io/distroless/base -# set build workdir -WORKDIR "/tmp/endlessh-go/" - -# build app -RUN \ - go mod tidy \ - && go build -o "endlessh-go" - - -FROM alpine:3.17 - -# labels LABEL org.opencontainers.image.title=endlessh-go LABEL org.opencontainers.image.description="Endlessh: an SSH tarpit" LABEL org.opencontainers.image.vendor="Shizun Ge" LABEL org.opencontainers.image.licenses=GPLv3 - -# install packages -RUN \ - echo "**** installing base packages ****" \ - && apk update \ - && apk --no-cache add \ - ca-certificates \ - bash \ - procps \ - tzdata - -# prepare container -RUN \ - echo "**** create default user ****" \ - && addgroup -S -g 2000 abc \ - && adduser -S -D -H -s /bin/bash -u 2000 -G abc abc - -# cleanup installation -RUN \ - echo "**** cleanup ****" \ - && rm -rf \ - /tmp/* \ - /var/cache/apk/* \ - /var/tmp/* - -# copy files to container -COPY --from=build "/tmp/endlessh-go/endlessh-go" "/usr/local/bin/" - -# ssh / prometheus port +COPY --from=build /endlessh/endlessh /endlessh EXPOSE 2222 2112 - -USER abc - -ENTRYPOINT ["/usr/local/bin/endlessh-go"] - +USER nobody +ENTRYPOINT ["/endlessh"] CMD ["-logtostderr", "-v=1"] diff --git a/README.md b/README.md index 2ff4e76..2a00126 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,6 @@ Then you can try to connect to the endlessh server. Your SSH client should hang ssh -p 2222 localhost ``` -The default container user has uid/gid 2000. - If you want log like the [C implementation](https://github.com/skeeto/endlessh), you need to set both CLI arguments `-logtostderr` and `-v=1`, then the log will go to stderr. You can set different log destinations via CLI arguments. Also check out [examples](./examples/README.md) for the setup of the full stack. @@ -85,26 +83,18 @@ Usage of ./endlessh-go comma-separated list of pattern=N settings for file-filtered logging ``` -## Using privileged ports (<1024) - -If you want to run the image with privileged ports (below 1025), you need to set the container user to root: - -```yml -user: root -``` - ## Metrics Endlessh-go exports the following Prometheus metrics. -| Metric | Type | Description | -| ------------------------------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| endlessh_client_open_count_total | count | Total number of clients that tried to connect to this host. | -| endlessh_client_closed_count_total | count | Total number of clients that stopped connecting to this host. | -| endlessh_sent_bytes_total | count | Total bytes sent to clients that tried to connect to this host. | -| endlessh_trapped_time_seconds_total | count | Total seconds clients spent on endlessh. | -| endlessh_client_open_count | count | Number of connections of clients.
Labels:
  • `ip`: IP of the client
  • `country`: Country of the IP
  • `location`: Country, Region, and City
  • `geohash`: Geohash of the location
| -| endlessh_client_trapped_time_seconds | count | Seconds a client spends on endlessh.
Labels:
  • `ip`: IP of the client
| +| Metric | Type | Description | +|--------------------------------------|-------|--------------| +| endlessh_client_open_count_total | count | Total number of clients that tried to connect to this host. | +| endlessh_client_closed_count_total | count | Total number of clients that stopped connecting to this host. | +| endlessh_sent_bytes_total | count | Total bytes sent to clients that tried to connect to this host. | +| endlessh_trapped_time_seconds_total | count | Total seconds clients spent on endlessh. | +| endlessh_client_open_count | count | Number of connections of clients.
Labels:
  • `ip`: IP of the client
  • `country`: Country of the IP
  • `location`: Country, Region, and City
  • `geohash`: Geohash of the location
| +| endlessh_client_trapped_time_seconds | count | Seconds a client spends on endlessh.
Labels:
  • `ip`: IP of the client
| The metrics is off by default, you can turn it via the CLI argument `-enable_prometheus`. diff --git a/examples/README.md b/examples/README.md index 58ab558..50c95f1 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,6 +1,19 @@ # Examples +> The default container user has uid 65534. + ## docker-simple An example how to setup endlessh-go, Prometheus, and Grafana using [docker compose](https://docs.docker.com/compose/). +## docker-maxmind + +An example how to setup endlessh-go with the Maxmind GeoIP Database. + +### Using privileged ports (<1024) on docker + +If you want to run the image with privileged ports (below 1025), you need to set the container user to root: + +```yml +user: root +``` diff --git a/examples/docker-maxmind/README.md b/examples/docker-maxmind/README.md new file mode 100644 index 0000000..3dff00d --- /dev/null +++ b/examples/docker-maxmind/README.md @@ -0,0 +1,16 @@ +## docker compose + +This is an example how to setup endlessh-go with the Maxmind GeoIP Database using [docker compose](https://docs.docker.com/compose/). The reference of the compose file can be found [here](https://docs.docker.com/compose/compose-file/). + +To start the stack, in the _examples_ folder, run: + +``` +sudo docker-compose up -d +``` + +The GeoIP Database will be saved in a mounted volume in: `./geo-data`. And the endlessh-go container will use this database to do the location lookups. + +This example exposes the following ports. Except the SSH port, you should not expose other ports to public without protections (not included in this example) in production. + +- **2222**: The SSH port. You may test endlessh-go by running `ssh -p 2222 localhost`. Your SSH client should hang. View the log of endlessh-go by running `sudo docker logs endlessh`. +- **2112**: The Prometheus metrics exported by endlessh-go. Go to [http://localhost:2112/metrics](http://localhost:2112/metrics) in your web browser to view the metrics. diff --git a/examples/docker-simple/docker-compose_maxmind.yml b/examples/docker-maxmind/docker-compose.yml similarity index 100% rename from examples/docker-simple/docker-compose_maxmind.yml rename to examples/docker-maxmind/docker-compose.yml