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: