09.03.2024, 00:48 Uhr
Kann man ein ProxyScript deklarativ erstellen?
Ich habe in letzter Zeit beruflich viel mit der Erzeugung und Anpassung von PAC-Dateien zu tun.
Wikipedia: Proxy auto-config
Grundsätzlich ist es dabei schon einmal eine gute Idee, wenn man die PAC-Dateien in einem Repository ablegt, sodass man Änderungen nachvollziehen kann.
Noch besser ist es, wenn man sie vor dem Einsatz testet. Beispielsweise mit Python und PyPAC
Nun hab ich mich aber gefragt, ob man das ProxyScript auch aus einer Deklaration heraus erstellen könnte, beispielsweise mit einer YAML-Datei. Das hätte den Vorteil, dass Kollegen die Ausnahmen leichter pflegen können. Sie müssten dafür kein JavaScript mehr verstehen.
Da ich Python mag, habe ich genau das mal mit Python versucht. Zu finden ist der Code bei Github. https://github.com/73h/paccreator
Eine YAML-Datei sieht nun beispielsweise so aus. Man erfasst die Proxies und die entsprechenden Ziele. Dann benötigt man noch einen Default-Proxy und den Rest macht Python.
example.yaml:
description: My proxy script
version: 1.0
proxies:
- description: take the direct route
route: DIRECT
tags:
- default # default proxy
targets:
- .example.com
- description: take the proxy route
route: PROXY company.example.com
targets:
- example.com
- foo.example.com
- 93.184.0.0/16
Mit wenigen Zeilen Python, kann man nun den Inhalt der PAC-Datei erzeugen.
import os
from paccreator import PacCreator
p = PacCreator()
with open(os.path.join("example.yaml"), "r") as f:
p.load_from_yaml(f.read())
print(p.output())
Und das Ergebnis sieht dann so aus. Das geschulte Auge erkennt vielleicht die Besonderheit, dass es eine Überschneidung der Ziele gibt. Das wird sogar beachtet und entsprechend umsortiert. So ist die Bedingung auf .example.com nach unten gerutscht. Würde sie als erstes kommen, würde sie auch foo.example.com schlucken. Auch die Übersetzung der Netzmaske 93.184.0.0/16 erleichtert die Pflege.
Das Ergebnis - example.pac:
function FindProxyForURL(url, host) {
host = host.toLowerCase();
if (
localHostOrDomainIs(host, "example.com")
|| localHostOrDomainIs(host, "foo.example.com")
|| isInNet(host, "93.184.0.0", "255.255.0.0")
) { return "PROXY company.example.com"; }
if (
dnsDomainIs(host, ".example.com")
) { return "DIRECT"; }
return "DIRECT";
}
Mein Fazit nach ein paar Stunden Arbeit. Es geht und ich werde den Ansatz weiter verfolgen. Klar ist aber auch, das man hier nicht alles oder jede Varianz abbilden kann. Dennoch wird es für die meisten Proxy-Skripte reichen denke ich.