Intelligente Lösungen
in neuer Dimension

VPN für Arme

Für manche von unseren Webservern und Services wollen wir extra strenge Zugriffsrestriktionen. Bislang verwende ich dazu relativ häufig statische IP-Adressen:

  • Statische IP-Adressen von ausgewählten Mitarbeitern
  • … und Kunden
  • Sonderzugriffe via SSH

Das Setup ist relativ unflexibel, wir brauchen was besseres!

Grundidee

Es bleibt grundsätzlich bei der Limitierung bezogen auf die IP-Adresse. Man kann seine eigene IP-Adresse mit SSH-Aufruf registrieren und freischalten lassen.

Ablauf

  1. Du hast keinen Zugriff auf DP-GIT(EA)
  2. Du führst einmalig diesen SSH-Befehl aus: ssh register-my-ip-address@our-company.tld start
  3. Nun hast Du Zugriff auf DP-GIT(EA)
  4. Wenn Du mit Deiner Arbeit fertig bist, dann sperrst Du den Zugriff wieder mit: ssh register-my-ip-address@our-company.tld stop

Technik

  • Nur ausgewählte SSH-Schlüssel sind freigeschaltet für den Zugriff auf register-my-ip-address@our-company.tld
  • Freischaltung erfolgt via .ssh/authorized_keys
  • Es ist fest das Skript “register-my-ip-address.sh” hinterlegt, andere Kommandos können nicht ausgeführt werden
  • Das Skript
    1. Ermittelt die IP-Adresse des Aufrufers
    2. Vermerkt diese IP-Adresse als “freizuschaltend für 9 Stunden”
    3. Setzt den Vormerker: IP-Adresse in 9 Stunden sperren
    4. Schaltet die IP-Adresse frei

Bekannte Defizite:

  • Folgeaufrufe löschen den Vormerker nicht, die IP-Adresse wird auf jeden Fall gesperrt!
  • Wenn mehrere Personen die gleiche IP-Adresse nutzen, dann kommt es zu ungewollten Überlagerungen
  • Verbindungen gehen verloren, wenn der Server durchgestartet wird. Jeder muß dann erneut die Freischaltung per SSH-Aufruf aktivieren
  • Wenn sich Deine IP-Adresse im laufenden Betrieb ändert, dann mußt Du Dich frisch freischalten lassen

Skripte

_rmip-parameters.sh

Hier werden einige globale Parameter festgelegt:

1
2
3
4
5
6
RANDOM="$({ date; ps waux; } | sha256sum | cut -d" " -f1)"
RMI_FOLDER="/var/spool/register-my-ip-address"
CURRENT="${RMI_FOLDER}/current"  
PROCESSED="${RMI_FOLDER}/processed"
IPTABLES_CHAIN="RMIP_INPUT"
IPDB="${CURRENT}/ipdb.csv" 

register-my-ip-address.sh

Dies ist das Skript zum Vormerken der IP-Adresse:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/bin/sh
BN="$(basename "$0")"
D="$(dirname "$0")"

MODE="start"
USERID="$1"
INTERVAL="$2"
MAPPED_IP_ADDRESS="$3"

parseSshOriginalCommand () {
  echo "${SSH_ORIGINAL_COMMAND}"|cut -d" " -f"$1"
}

if [ -z "${SSH_CLIENT}" ]; then
    echo >&2 "${BN}: Kann Deine IP-Adresse leider nicht ermitteln -> ABBRUCH!"
    exit 1
fi

IP_ADDRESS="$(echo "${SSH_CLIENT}"| cut -d" " -f1)"
TS="$(date "+%Y-%m-%d %H:%M:%S")"

if [ "$(parseSshOriginalCommand 1)" = "stop" ]; then
  MODE=stop
fi

echo "Dein Benutzer:    ${USERID}"
echo "Dein Wunsch:      ${MODE}"

if [ "${MODE}" = "start" ]; then
  if [ "${IP_ADDRESS}" = "${MAPPED_IP_ADDRESS}" ]; then
    echo "Du bist bereits freigeschaltet, diese Anfrage wird ignoriert!"
    exit 1
  fi
  echo "Deine IP-Adresse: ${IP_ADDRESS} -> ${MAPPED_IP_ADDRESS}"
  echo "Zeitstempel:      ${TS}"
  echo "Intervall:        ${INTERVAL}"
fi

if [ "${MODE}" = "stop" ]; then
  echo "Freischaltung für Deine IP-Adresse wird gestoppt!"
  echo "Verbindung für Kollegen aus gleichem Netz wird gekappt!"
fi

sudo "${D}/_rmip-register-ip-address.sh" "${MODE}" "${USERID}" "${INTERVAL}" "${MAPPED_IP_ADDRESS}" "${IP_ADDRESS}"

_rmip-register-ip-address.sh

Trägt die IP_ADDRESS ein bei

  • INPUT: -j ACCEPT -p tcp --source ${IP_ADDRESS}
  • FORWARD: -j ACCEPT -p tcp --source ${IP_ADDRESS}
  • -t INPUT: -j SNAT -p tcp --source ${IP_ADDRESS} --to-source ${MAPPED_IP_ADDRESS}

Zusätzlich wird ein Job vorgemerkt für die Ausführung in 9 Stunden zum Zurücksetzen dieser Änderungen.

/etc/sudoers oder /etc/sudoers.d/register-my-ip-address.conf

1
register-my-ip-address ALL=NOPASSWD: /usr/local/bin/_rmip-register-ip-address.sh

Einrichtung

  • Anmelden am Rechner
  • Benutzer einrichten: adduser --gecos "VPN fuer Arme" --disabled-password --disabled-login register-my-ip-address
  • Script ablegen: /usr/local/bin/register-my-ip-address.sh
  • Verzeichnis anlegen: ~register-my-ip-address/.ssh
    • mkdir ~register-my-ip-address/.ssh
    • chown register-my-ip-address.register-my-ip-address ~register-my-ip-address/.ssh
    • chmod 700 ~register-my-ip-address/.ssh
  • Datei anlegen: ~register-my-ip-address/.ssh/authorized_keys
    • touch ~register-my-ip-address/.ssh/authorized_keys
    • chown register-my-ip-address.register-my-ip-address ~register-my-ip-address/.ssh/authorized_keys
    • chmod 600 ~register-my-ip-address/.ssh/authorized_keys
  • Für jeden Benutzer:
    • SSH-Schlüssel bereitstellen lassen
    • Eintrag in authorized_keys erstellen: command="/usr/local/bin/register-my-ip-address.sh 'username' '+9hours' 'mapped-ip-address'" pubkey
  • Beispiel: root:~# cat >>~register-my-ip-address/.ssh/authorized_keys command="/usr/local/bin/register-my-ip-address.sh 'uli' '+9hours' '192.168.0.42'" sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5...Wztib6Q68t5GwNIlxoYlhAAAABHNzaDo= uli-solokey-fuer-dp

Test

Start in den Morgen

Ich arbeite wie üblich und “vergesse” die Freischaltung. Ich versuche, meinen GIT-Zwischenstand abzugleichen:

1
2
uli:~$ git pull
fatal: konnte nicht auf 'https://eWefo.our-company.tld/gitbucket/git/dp/dp-octopress.git/' zugreifen: The requested URL returned error: 403

Die Fehlermeldung zeigt an, dass die Freischaltung fehlt. Analoge Fehlermeldungen erscheinen auch im Browser!

Freischaltung aktivieren

Ich führe von meinem lokalen Rechner aus diese Abfragen durch:

1
2
3
4
5
6
uli:~$ ssh register-my-ip-address@eWefo.our-company.tld start
Dein Benutzer:    uli
Deine IP-Adresse: 92.88.122.31 -> 10.10.20.2
Zeitstempel:      2021-03-12 09:05:06
Intervall:        +9hours
Connection to eWefo.our-company.tld closed.

Erneuter Abgleich

Nach der Freischaltung führe ich den GIT-Abgleich erneut durch:

1
2
uli:~$ git pull
Bereits aktuell.

Es klappt!

Freischaltung deaktivieren

Führe von Deinem lokalen Rechner aus diese Abfragen durch:

1
2
3
4
5
uli:~$ ssh register-my-ip-address@eWefo.our-company.tld stop
Dein Benutzer:    uli
Dein Wunsch:      stop
Freischaltung für Deine IP-Adresse wird gestoppt!
Verbindung für Kollegen aus gleichem Netz wird gekappt!

Finaler Abgleich

Ich führe den GIT-Abgleich erneut durch und erwarte eine Fehlermeldung:

1
2
uli:~$ git pull
fatal: konnte nicht auf 'https://eWefo.our-company.tld/gitbucket/git/dp/dp-octopress.git/' zugreifen: The requested URL returned error: 403

Die Fehlermeldung erscheint, alles OK!

Sicherheitsabwägungen

  • Bei kleinen Netzwerken wie sie in den typischen Home-Office-Szenarien vorkommen ist das Setup relativ unkritisch. Ein Parallelnutzer in diesem Netz hat netzwerk-technisch einen Zugang zu unserem Server, praktisch muß er sich aber immer noch anmelden.
  • Problematisch wird’s, wenn jemand einen “großen” Proxy-Server verwendet oder ein sehr großes NAT und dieses dann freigeschaltet wird. Aktuell können wir das ausschließen!
  • Unschön ist, wenn jemand nach Abschluß seiner Arbeitszeit vergisst, den Zugang wieder zu sperren. Hier müssen wir noch nacharbeiten!
  • Wir brauchen einen “offenen SSH-Zugang” auf “register-my-ip-address@eWefo.our-company.tld”. Da der Zugang nur per SSH-Schlüssel möglich ist und wir diese strikt unter Verschluß halten, können wir einen Mißbrauch ausschließen.

Historie und Anmerkung

  • 2021-03-14: Veröffentlicht, Start und Stop
  • 2021-03-06: Erste Version