Wartungstunnel

Wenn man einmal einen Reverse-SSH-Tunnel braucht

Vorbereitungen auf dem Host, welche als Endpunkt für den Tunnel dient, z.B. der Salt-Master

mkdir /srv/salt/mtunnel
useradd -m -r -d /var/lib/mtunnel mtunnel
mkdir /var/lib/mtunnel/.ssh
ssh-keygen -q -t ed25519 -N "" -f /var/lib/mtunnel/.ssh/id_ed25519 -C "mtunnel@salt-master.local"
cp /var/lib/mtunnel/.ssh/id_ed25519.pub /var/lib/mtunnel/.ssh/authorized_keys
cp /var/lib/mtunnel/.ssh/id_ed25519 /srv/salt/mtunnel/
chown -R mtunnel:mtunnel /var/lib/mtunnel/
chmod 0700 /var/lib/mtunnel/.ssh
chmod 0600 /var/lib/mtunnel/.ssh/*
/srv/salt/mtunnel/init.sls
#
# Create a mtunnel user
#
mtunnel:
  group.present: []
  user.present:
    - fullname: Maintenance SSH Reverse Tunnel
    - shell: /usr/sbin/nologin
    - home: /var/lib/mtunnel
    - createhome: true
    - system: true
    - groups:
      - mtunnel

ssh-dir:
  file.directory:
    - name: /var/lib/mtunnel/.ssh
    - user: mtunnel
    - group: mtunnel
    - mode: 0700
    - require:
      - user: mtunnel

#
# Deploy a pre-generated priv key from the salt-master
#
priv-key:
  file.managed:
    - name: /var/lib/mtunnel/.ssh/id_ed25519
    - source: salt://mtunnel/id_ed25519
    - user: mtunnel
    - group: mtunnel
    - mode: 0600
    - require: 
      - file: ssh-dir

#
# Create a default config read later by systemd
#
mtunnel-default:
  file.managed:
    - name: /etc/default/mtunnel.conf
    - require:
      - file: priv-key
    - contents: |
        PORT={{ pillar['mtunnel']['port'] }}
        HOST={{ pillar['mtunnel']['host'] }}

mtunnel-service-file:
  file.managed:
    - name: /etc/systemd/system/mtunnel.service
    - require:
      - file: mtunnel-default
    - contents: |
        [Unit]
        Description=Create a reverse SSH Tunnel for maintenance
        After=network.target

        [Service]
        EnvironmentFile=/etc/default/mtunnel.conf
        ExecStart=/usr/bin/ssh -NT \
          -o ServerAliveInterval=60 \
          -o StrictHostKeyChecking=no \
          -o ExitOnForwardFailure=yes \
          -R ${PORT}:localhost:22 ${HOST}
        RestartSec=5
        Restart=always
        User=mtunnel
        Group=mtunnel

        [Install]
        WantedBy=multi-user.target

mtunnel.service:
  service.dead:
    - enable: False

{% if pillar['mtunnel']['http_proxy'] is defined %}
corkscrew:
  pkg.installed: []

{% if pillar['mtunnel']['http_proxy_user'] is defined %}
cork-auth:
  file.managed:
    - name: ~/.ssh/cork.auth
    - contents: {{pillar['mtunnel']['http_proxy_user']}}:{{pillar['mtunnel']['http_proxy_password']}}
ssh-conf:
  file.managed:
    - name: /var/lib/mtunnel/.ssh/config
    - contents: |
        Host *
             ProxyCommand /usr/bin/corkscrew {{pillar['mtunnel']['http_proxy']}} {{pillar['mtunnel']['http_proxy_port']}} %h %p ~/.ssh/cork.auth
    - require:
      - file: cork-auth
{% else %}
ssh-conf:
  file.managed:
    - name: /var/lib/mtunnel/.ssh/config
    - contents: |
        Host *
             ProxyCommand /usr/bin/corkscrew {{pillar['mtunnel']['http_proxy']}} {{pillar['mtunnel']['http_proxy_port']}} %h %p
{%endif %}
{% endif %}

Beispiel Pillar (hostspezifisch, Type file_tree)

/srv/pillar/hosts/minion1/mtunnel
host: 192.168.3.136
port: 2222
http_proxy: 192.168.3.136
http_proxy_port: 8888

Tunnel vorbereiten und starten

salt minion1 state.apply mtunnel
salt minion1 service.start mtunnel
netstat -tulpen|grep sshd.*mtunnel
salt minion1 service.stop mtunnel

Last updated