first commit
This commit is contained in:
@@ -0,0 +1,295 @@
|
|||||||
|
# svc-proxy – Proxy für systemd-Dienste
|
||||||
|
|
||||||
|
`svc-proxy` legt fest, über welchen Proxy ein systemd-Dienst seine Verbindungen
|
||||||
|
aufbaut. Bedienen lässt es sich auf zwei Wegen:
|
||||||
|
|
||||||
|
- **ncurses-Menü**: listet alle Dienste auf. Man wählt einen aus und trägt die Daten bequem ein.
|
||||||
|
- **Kommandozeile**: für Skripte, Ansible, Provisionierung usw.
|
||||||
|
|
||||||
|
Es gibt einen **globalen Proxy**. Alle Felder, die man bei einem Dienst leer lässt,
|
||||||
|
übernehmen den globalen Wert. Explizit gesetzte Werte beim Dienst gelten vorrangig.
|
||||||
|
Benutzername und Kennwort sind optional; ohne sie wird der Proxy ohne Anmeldung genutzt.
|
||||||
|
|
||||||
|
Abhängigkeiten: nur `python3` (≥ 3.6) mit den Standardmodulen. `curses` ist bei
|
||||||
|
Debian/Ubuntu/RHEL im Python-Paket enthalten.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo install -m 0755 svc-proxy /usr/local/sbin/svc-proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
Danach `sudo svc-proxy` (Menü) oder `svc-proxy --help` (Hilfe).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Funktionsweise
|
||||||
|
|
||||||
|
Für jeden konfigurierten Dienst werden zwei Dateien erzeugt:
|
||||||
|
|
||||||
|
| Datei | Inhalt | Rechte |
|
||||||
|
|-------|--------|--------|
|
||||||
|
| `/etc/systemd/system/<dienst>.d/50-svc-proxy.conf` | Drop-in mit `EnvironmentFile=` | 0644 |
|
||||||
|
| `/etc/svc-proxy/env/<dienst>.env` | die eigentlichen Proxy-Variablen | 0600 |
|
||||||
|
|
||||||
|
Die Konfiguration selbst (global + alle Dienste) liegt in
|
||||||
|
`/etc/svc-proxy/config.json` (0600). Die Drop-ins und Env-Dateien werden daraus
|
||||||
|
generiert und sollten nicht von Hand bearbeitet werden.
|
||||||
|
|
||||||
|
Gesetzt werden die Variablen
|
||||||
|
|
||||||
|
```
|
||||||
|
http_proxy https_proxy ftp_proxy all_proxy no_proxy
|
||||||
|
HTTP_PROXY HTTPS_PROXY FTP_PROXY ALL_PROXY NO_PROXY
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Warum `EnvironmentFile=` und nicht `Environment=`?**
|
||||||
|
> Werte aus `Environment=` kann jeder Benutzer mit `systemctl show <dienst>`
|
||||||
|
> auslesen, also auch ein Proxy-Kennwort. Die Env-Datei ist nur für root lesbar.
|
||||||
|
|
||||||
|
Sonderzeichen in Benutzername/Kennwort (z.B. `@`, `:`, `/`) werden automatisch
|
||||||
|
URL-kodiert.
|
||||||
|
|
||||||
|
### Wichtige Einschränkung
|
||||||
|
|
||||||
|
Der Proxy wirkt nur bei Programmen, die die Proxy-Umgebungsvariablen auswerten.
|
||||||
|
Das tun die meisten (curl, wget, apt, pip, Python `requests`/`urllib`, Go, Node
|
||||||
|
mit passenden Libs, Docker-Daemon, containerd, Git, ...). Programme, die die
|
||||||
|
Variablen ignorieren (z.B. viele Java-Anwendungen ohne `-Dhttp.proxyHost`),
|
||||||
|
müssen anders konfiguriert werden. Eine Netzwerk-Sperre ist das nicht: Ein
|
||||||
|
Programm *kann* den Proxy umgehen.
|
||||||
|
|
||||||
|
SOCKS-Proxys (`socks5://`, `socks5h://`) werden ebenfalls in alle Variablen
|
||||||
|
geschrieben. Das funktioniert z.B. mit curl und Go. Manche Programme verstehen in
|
||||||
|
`http_proxy` aber nur `http://`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vererbung: Dienst ↔ global
|
||||||
|
|
||||||
|
Felder: **Typ, Host, Port, Benutzer, Kennwort, No-Proxy**
|
||||||
|
|
||||||
|
| Feld beim Dienst | Ergebnis |
|
||||||
|
|---|---|
|
||||||
|
| Typ / Host / Port / No-Proxy leer | globaler Wert |
|
||||||
|
| Typ / Host / Port / No-Proxy gesetzt | Wert des Dienstes |
|
||||||
|
| Benutzer leer **und** Host leer | globale Zugangsdaten |
|
||||||
|
| Benutzer leer, **eigener Host** | Proxy **ohne** Anmeldung |
|
||||||
|
| Benutzer gesetzt | Benutzer + Kennwort des Dienstes |
|
||||||
|
|
||||||
|
Die Sonderregel für Benutzer/Kennwort verhindert, dass globale Zugangsdaten an
|
||||||
|
einen fremden Proxy geschickt werden.
|
||||||
|
|
||||||
|
Ändert man den globalen Proxy, werden alle Dienste, die ihn ganz oder teilweise
|
||||||
|
erben, automatisch neu geschrieben. Wird der globale Proxy gelöscht, verlieren
|
||||||
|
Dienste ohne eigenen Host ihren Proxy. Ihre Konfiguration bleibt aber gespeichert
|
||||||
|
und wird wieder aktiv, sobald ein globaler Proxy gesetzt ist.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ncurses-Menü
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo svc-proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
svc-proxy 1.0.0 – Proxy für systemd-Dienste
|
||||||
|
Global: http://max:****@proxy.firma.local:3128 No-Proxy: localhost,127.0.0.1,::1
|
||||||
|
220 Dienste
|
||||||
|
Dienst Status Proxy
|
||||||
|
G cron.service active global → http://max:****@proxy.firma.local:3128
|
||||||
|
E* docker.service active eigen → socks5h://10.1.1.1:1080
|
||||||
|
nginx.service inactive
|
||||||
|
...
|
||||||
|
↑↓ Wählen Enter Bearbeiten g Global Entf Proxy entfernen / Filter c Nur konfigurierte ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Markierungen: **G** = nutzt globalen Proxy, **E** = eigene Werte,
|
||||||
|
**\*** = in dieser Sitzung geändert (Neustart noch offen).
|
||||||
|
|
||||||
|
### Tasten in der Liste
|
||||||
|
|
||||||
|
| Taste | Funktion |
|
||||||
|
|---|---|
|
||||||
|
| ↑ ↓ / Bild↑ Bild↓ / Pos1 Ende | Dienst wählen |
|
||||||
|
| Enter | Proxy des Dienstes bearbeiten |
|
||||||
|
| g | globalen Proxy bearbeiten |
|
||||||
|
| Entf / d | Proxy vom Dienst entfernen |
|
||||||
|
| / | Filter (Name oder Beschreibung), Esc löscht den Filter |
|
||||||
|
| c | nur konfigurierte Dienste anzeigen (an/aus) |
|
||||||
|
| r | gewählten Dienst sofort neu starten |
|
||||||
|
| F5 | Dienstliste neu einlesen |
|
||||||
|
| F1 / ? | Hilfe |
|
||||||
|
| q / F10 | Beenden |
|
||||||
|
|
||||||
|
### Tasten im Formular
|
||||||
|
|
||||||
|
| Taste | Funktion |
|
||||||
|
|---|---|
|
||||||
|
| Tab / ↑ ↓ | Feld wechseln |
|
||||||
|
| ← → / Leertaste | Proxy-Typ wählen (beim Dienst gibt es zusätzlich „global“) |
|
||||||
|
| Enter | nächstes Feld bzw. Schaltfläche auslösen |
|
||||||
|
| F2 | Speichern |
|
||||||
|
| Strg+U | Feld leeren |
|
||||||
|
| Esc | Abbrechen |
|
||||||
|
|
||||||
|
Leere Felder zeigen grau den globalen Wert an. Unter dem Formular steht live die
|
||||||
|
Proxy-URL, die sich ergibt. Ungültige Eingaben werden nicht gespeichert.
|
||||||
|
|
||||||
|
Nach jedem Speichern läuft `systemctl daemon-reload`. Beim Beenden erscheint eine
|
||||||
|
Liste der geänderten Dienste: Diese kann man an- und abwählen und neu starten lassen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kommandozeile
|
||||||
|
|
||||||
|
```
|
||||||
|
svc-proxy [BEFEHL] [OPTIONEN]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Befehl | Beschreibung |
|
||||||
|
|---|---|
|
||||||
|
| *(keiner)* / `tui` | Menü starten |
|
||||||
|
| `list [--all]` | konfigurierte Dienste (mit `--all`: alle Dienste) |
|
||||||
|
| `show [DIENST]` | effektive Werte eines Dienstes inkl. Herkunft; ohne DIENST: global |
|
||||||
|
| `global [FELDER]` | globalen Proxy setzen/ändern; ohne FELDER: anzeigen |
|
||||||
|
| `global --clear` | globalen Proxy löschen |
|
||||||
|
| `set DIENST... [FELDER] [--reset]` | Proxy für Dienst(e) setzen/ändern |
|
||||||
|
| `unset DIENST...` / `unset --all` | Proxy entfernen |
|
||||||
|
| `apply` | alle Drop-ins aus der Konfiguration neu erzeugen |
|
||||||
|
| `help`, `-h`, `--help` | Hilfe mit Beispielen |
|
||||||
|
|
||||||
|
### Felder
|
||||||
|
|
||||||
|
| Option | Bedeutung |
|
||||||
|
|---|---|
|
||||||
|
| `--proxy URL` | komplette URL, z.B. `http://user:pass@proxy:3128`; setzt Typ, Host, Port, Benutzer, Kennwort |
|
||||||
|
| `--type TYP` | `http`, `https`, `socks5`, `socks5h`, `socks4` |
|
||||||
|
| `--host HOST` | Hostname / IP |
|
||||||
|
| `--port PORT` | 1–65535 |
|
||||||
|
| `--user NAME` | Benutzername |
|
||||||
|
| `--password PW` | Kennwort (in `ps` sichtbar!) |
|
||||||
|
| `--password-stdin` | Kennwort aus der Standardeingabe lesen (empfohlen) |
|
||||||
|
| `--no-proxy LISTE` | Ausnahmen, kommagetrennt |
|
||||||
|
|
||||||
|
- Bei `set` und `global` werden **nur die angegebenen Felder** geändert, der Rest bleibt.
|
||||||
|
- Leerer Wert leert ein Feld: `--user ""`.
|
||||||
|
- `set DIENST --reset` leert vorher alle Felder, der Dienst nutzt danach komplett den globalen Proxy.
|
||||||
|
- Ein neuer Dienst ohne Felder (`set DIENST`) nutzt den globalen Proxy.
|
||||||
|
- Dienstnamen ohne Endung bekommen automatisch `.service` angehängt.
|
||||||
|
- Beim ersten Setzen des globalen Proxys ist No-Proxy standardmäßig `localhost,127.0.0.1,::1`.
|
||||||
|
|
||||||
|
### Neustart und Reload
|
||||||
|
|
||||||
|
| Option | Wirkung |
|
||||||
|
|---|---|
|
||||||
|
| *(nichts)* | im Terminal Nachfrage `[j/N]`; ohne Terminal (Cron, Skript) kein Neustart |
|
||||||
|
| `--restart` | geänderte Dienste ohne Nachfrage neu starten |
|
||||||
|
| `--no-restart` | nicht neu starten, nicht fragen |
|
||||||
|
| `--no-reload` | kein `systemctl daemon-reload` |
|
||||||
|
|
||||||
|
Neu gestartet wird mit `systemctl try-restart`, also nur Dienste, die gerade laufen.
|
||||||
|
Gestoppte Dienste werden nicht gestartet.
|
||||||
|
|
||||||
|
### Weitere Optionen
|
||||||
|
|
||||||
|
| Option | Bedeutung |
|
||||||
|
|---|---|
|
||||||
|
| `--config-dir DIR` | anderes Konfigurationsverzeichnis (Standard `/etc/svc-proxy`) |
|
||||||
|
| `--systemd-dir DIR` | anderes Ziel für Drop-ins (Standard `/etc/systemd/system`) |
|
||||||
|
| `-V`, `--version` | Version |
|
||||||
|
|
||||||
|
Mit `--config-dir`/`--systemd-dir` läuft das Skript auch ohne root. Das ist
|
||||||
|
praktisch zum Testen, z.B. zusammen mit `--no-reload`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Beispiele
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Menü
|
||||||
|
sudo svc-proxy
|
||||||
|
|
||||||
|
# Globaler Proxy ohne Anmeldung
|
||||||
|
sudo svc-proxy global --proxy http://proxy.firma.local:3128
|
||||||
|
|
||||||
|
# Globaler Proxy mit Anmeldung, Kennwort nicht in der Prozessliste
|
||||||
|
echo 'geheim' | sudo svc-proxy global --proxy http://proxy:3128 --user max --password-stdin
|
||||||
|
# oder aus einer Datei / einem Secret-Store
|
||||||
|
sudo svc-proxy global --user max --password-stdin < /root/proxy.pw
|
||||||
|
|
||||||
|
# Ausnahmen für den globalen Proxy
|
||||||
|
sudo svc-proxy global --no-proxy localhost,127.0.0.1,::1,.firma.local,10.0.0.0/8
|
||||||
|
|
||||||
|
# Mehrere Dienste nutzen den globalen Proxy, sofort neu starten
|
||||||
|
sudo svc-proxy set docker containerd nginx --restart
|
||||||
|
|
||||||
|
# Eigener SOCKS-Proxy ohne Anmeldung für einen Dienst
|
||||||
|
sudo svc-proxy set myapp --proxy socks5h://10.1.1.1:1080
|
||||||
|
|
||||||
|
# Nur anderer Host, Port/Typ/No-Proxy kommen vom globalen Proxy,
|
||||||
|
# keine Anmeldung (eigener Host ohne Benutzer)
|
||||||
|
sudo svc-proxy set backup --host proxy2.firma.local
|
||||||
|
|
||||||
|
# Nur den Port ändern
|
||||||
|
sudo svc-proxy set myapp --port 1081 --no-restart
|
||||||
|
|
||||||
|
# Zurück auf den globalen Proxy
|
||||||
|
sudo svc-proxy set myapp --reset
|
||||||
|
|
||||||
|
# Entfernen
|
||||||
|
sudo svc-proxy unset myapp --restart
|
||||||
|
sudo svc-proxy unset --all --no-restart
|
||||||
|
|
||||||
|
# Anzeigen
|
||||||
|
sudo svc-proxy list
|
||||||
|
sudo svc-proxy list --all
|
||||||
|
sudo svc-proxy show docker
|
||||||
|
sudo svc-proxy show # globaler Proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
Beispielausgabe von `show`:
|
||||||
|
|
||||||
|
```
|
||||||
|
Dienst: ssh.service
|
||||||
|
Status: active
|
||||||
|
Modus: eigene Werte (leere Felder = global)
|
||||||
|
Proxy-Typ http (global)
|
||||||
|
Host other.proxy (dienst)
|
||||||
|
Port 3128 (global)
|
||||||
|
Benutzer - (dienst)
|
||||||
|
Kennwort - (dienst)
|
||||||
|
No-Proxy localhost,127.0.0.1,::1 (global)
|
||||||
|
Proxy-URL: http://other.proxy:3128
|
||||||
|
```
|
||||||
|
|
||||||
|
### Automatisierung (z.B. Ansible)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Proxy für Docker setzen
|
||||||
|
ansible.builtin.shell: >
|
||||||
|
svc-proxy global --proxy http://proxy.firma.local:3128 --no-restart &&
|
||||||
|
svc-proxy set docker.service --restart
|
||||||
|
```
|
||||||
|
|
||||||
|
Rückgabewert: `0` bei Erfolg, `1` bei Fehler (ungültige Eingabe, fehlende Rechte,
|
||||||
|
fehlgeschlagener Neustart).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prüfen, ob es wirkt
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl cat docker.service # zeigt das Drop-in
|
||||||
|
sudo cat /proc/$(systemctl show -p MainPID --value docker)/environ | tr '\0' '\n' | grep -i proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deinstallation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo svc-proxy unset --all --restart
|
||||||
|
sudo rm -rf /etc/svc-proxy /usr/local/sbin/svc-proxy
|
||||||
|
```
|
||||||
Binary file not shown.
Reference in New Issue
Block a user