SSH ingress YAML error

Been trying to set up ssh ingress into my network - I eventually want GitLab to trigger builds on my backend...

Traefik 2.2 is showing that I have a new TCP router and service listening on Port 10022. Status is green.

I then want to setup a file based config to forward the incoming session to SSH on my host. This failed with a KEX error:

>ssh -v steve@ssh.grooms.page -p 10022
OpenSSH_8.1p1, LibreSSL 2.7.3
debug1: Reading configuration data /Users/steve/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 47: Applying options for *
debug1: Connecting to ssh.grooms.page port 10022.
debug1: Connection established.
debug1: identity file /Users/steve/.ssh/id_rsa type 0
debug1: identity file /Users/steve/.ssh/id_rsa-cert type -1
debug1: identity file /Users/steve/.ssh/id_dsa type -1
debug1: identity file /Users/steve/.ssh/id_dsa-cert type -1
debug1: identity file /Users/steve/.ssh/id_ecdsa type -1
debug1: identity file /Users/steve/.ssh/id_ecdsa-cert type -1
debug1: identity file /Users/steve/.ssh/id_ed25519 type -1
debug1: identity file /Users/steve/.ssh/id_ed25519-cert type -1
debug1: identity file /Users/steve/.ssh/id_xmss type -1
debug1: identity file /Users/steve/.ssh/id_xmss-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.1
debug1: kex_exchange_identification: banner line 0: HTTP/1.1 400 Bad Request
debug1: kex_exchange_identification: banner line 1: Content-Type: text/plain; charset=utf-8
debug1: kex_exchange_identification: banner line 2: Connection: close
debug1: kex_exchange_identification: banner line 3:
kex_exchange_identification: Connection closed by remote host

At the same time I see an error in the Traefik log:

traefik                 | time="2020-04-09T12:09:49+02:00" level=error msg="Error occurred during watcher callback: /conf/ssh.yml: yaml: line 8: mapping values are not allowed in this context" providerName=file
traefik                 | time="2020-04-09T12:09:49+02:00" level=error msg="Error occurred during watcher callback: /conf/ssh.yml: yaml: line 8: mapping values are not allowed in this context" providerName=file

This error is produced in pairs every time I save my ssh.yaml file

tcp:
    # Add the router
    routers:
      sshnucnuc:
        rule: HostSNI(`*`)
        entryPoints:
          - ssh
            address: ":10022"
        service: sshnucnuc-svc
        # tls: 
        #   passthrough: true
        #   certresolver: basic
        #   domains:
        #   - main: xyz.page
        #     sans:
        #     - "*.xyz.page"
  
    # Add the service
    services:
      sshnucnuc-svc:
        loadBalancer:
          servers:
          - address: http://192.168.1.138:22

tls:
  options:
    foo:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

How do I have to specify the 10022 inbound port?

regards
Steve

I changed the yaml and got a different error - not sure if this is progress or regress :wink:

tcp:
    # Add the router
    routers:
      sshnucnuc:
        rule: HostSNI(`*`)
        entryPoints:
          ssh:
            address: ":10022"
        service: sshnucnuc-svc
        # tls: 
        #   passthrough: true
        #   certresolver: basic
        #   domains:
        #   - main: xyz.page
        #     sans:
        #     - "*.zyz.page"
  
    # Add the service
    services:
      sshnucnuc-svc:
        loadBalancer:
          servers:
          - address: http://192.168.1.138:22

tls:
  options:
    foo:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

Results in the traefik log:

traefik                 | time="2020-04-09T12:24:23+02:00" level=error msg="Error occurred during watcher callback: /conf/ssh.yml: yaml: unmarshal errors:\n  line 7: cannot unmarshal !!map into []string" providerName=file
traefik                 | time="2020-04-09T12:24:23+02:00" level=error msg="Error occurred during watcher callback: /conf/ssh.yml: yaml: unmarshal errors:\n  line 7: cannot unmarshal !!map into []string" providerName=file

Again the error comes in pairs.

Steve

Hi @stevegroom

Your entrypoint and its address need to be in the static config file, command-line or environment var.

Your router will just reference the entrypoint name.

Thanks' for the feedback - I think I understand what you are saying, but I did not succeed with your suggestion though.

My docker-compose.yml file has the command entry - "--entrypoints.ssh.address=:10022" as well as ports: - "10022:10022

The ssh.yaml file without the :address now gives: level=info msg="Skipping same configuration" providerName=file

Obviously I have a conflict with the static entry.

Here is the docker-compose.yaml treafik service:

#########################################################
  #########################################################
  ##
  ## TRAEFIK
  ## The official v2.2 Traefik docker image
  ## The Cloud Native Edge Router
  ##
  #########################################################
  #########################################################
  traefik:
    
    image: traefik:v2.2
    container_name: traefik
    command: 
#     - --accesslog=true
      - "--log.level=INFO"
      - "--ping=false"
#     - "--ping.entrypoint=pingport"

      - "--api"
#     - "--api.insecure=true # Enables the web UI"

      # Define the ports Traefik listens on
      - "--entrypoints.web.address=:80" #Declares the web entrypoint in Traefik
      - "--entrypoints.websecure.address=:443" #Declares the websecure entrypoint in Traefik
      - "--entrypoints.apiport.address=:8080" #Declares the webapi entrypoint in Traefik
      - "--entrypoints.pingport.address=:8081"
      - "--entrypoints.ssh.address=:10022"

#     Enable a tls challenge named "basic"
      - "--certificatesresolvers.basic.acme.email=${CF_API_EMAIL}"
      - "--certificatesresolvers.basic.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.basic.acme.dnschallenge.provider=cloudflare"
#     - "--certificatesresolvers.basic.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"

      - "--global.sendAnonymousUsage=true"

      # Providers
      # Tell Traefik to listen to docker
      - "--providers.docker=true" 
      - "--providers.docker.exposedbydefault=false"
      
      - "--providers.file.directory=/conf"
      - "--providers.file.watch=true"
      
      - "--tracing=true"
      - "--tracing.serviceName=traefik"
      - "--tracing.jaeger=true"
      - "--tracing.jaeger.samplingServerURL=http://localhost:5778/sampling"
      - "--tracing.jaeger.samplingType=const"
      - "--tracing.jaeger.traceContextHeaderName=uber-trace-id"
      - "--tracing.jaeger.collector.endpoint=http://jaeger-collector:14268/api/traces?format=jaeger.thrift"
      - "--tracing.jaeger.samplingParam=1.0"

    environment:
      TZ: "Europe/Zurich"
      CF_API_EMAIL: ${CF_API_EMAIL}
      CF_DNS_API_TOKEN: ${CF_DNS_API_TOKEN}
      CF_ZONE_API_TOKEN: ${CF_ZONE_API_TOKEN}

    ports:
      - "10022:10022"
      - "80:80"
      - "443:443"
      - "8080:8080" # The Web UI (enabled by --api.insecure=true)

    volumes:
      # So that Traefik can listen to the Docker events
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./letsencrypt:/letsencrypt"
      - "./conf:/conf"

    networks:
      - traefik

    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"

      # Define the URL to access this app
      - "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAINNAME}`)"

      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.tls.certresolver=leresolver"
      - "traefik.http.routers.traefik.entrypoints=websecure"

      # Forward authentication to keycloak for logon
      - "traefik.http.routers.traefik.middlewares=keycloakForwardAuth@docker"
#      # Authentication
#      - "traefik.http.routers.traefik.middlewares=usersfile@file"

#      - "traefik.http.routers.traefik.service=traefik"
#      - "traefik.http.services.traefik.loadbalancer.server.port=4181"

      # Global Redirect HTTP to HTTPS
      - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=websecure"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"

      # Certificate name and san
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.traefik.tls.certresolver=basic"
      - "traefik.http.routers.traefik.tls.domains[0].main=${DOMAINNAME}"
      - "traefik.http.routers.traefik.tls.domains[0].sans=*.${DOMAINNAME}"

    restart: always

I feel I am getting code blind :frowning:
The traefik log is not showing any parse error - all I get now are two lines after saving any conf/*yml file:

traefik                 | time="2020-04-09T14:42:59+02:00" level=info msg="Skipping same configuration" providerName=file
traefik                 | time="2020-04-09T14:42:59+02:00" level=info msg="Skipping same configuration" providerName=file

And the router is no longer showing on the dashboard.

(regrets not checking in my work earlier).

Steve

did you solve this? having the same problem...