
ähnlich zuDasCloudflare-Blogbeitrag, ich versuche, Nginx mit einem transparenten Socket einzurichten (mit demIP_TRANSPARENT
Socket-Option). Ich möchte dies tun, um einen Reverse-TCP-Proxy zu implementieren, der effektiv an alle Ports bindet.
Die IP_TRANSPARENT
Socket-Option istnicht nativ unterstütztvon Nginx für das Zuhören, also versuche ich, den Socket mit einem zu erstellenSystemd-Socket-Einheitund übergeben Sie es dann an den Nginx-Prozess mithilfe desNGINX
Umgebungsvariable.
Die Sockeleinheit sieht wie folgt aus (unwichtige Zeilen wurden entfernt):
[Socket]
ListenStream=127.0.0.1:1234
Transparent=true
[Install]
WantedBy=sockets.target
Meine Nginx-Serviceeinheit sieht wie folgt aus (unwichtige Zeilen wurden entfernt):
[Service]
# Configure Nginx to use the socket inherited from Systemd
Environment=NGINX=3;
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
Und meiner nginx.conf
lautet wie folgt (unwichtige Zeilen wurden entfernt und dies upstream
ist der Hostname des Upstream-Hosts, zu dem ich einen Proxy verwenden möchte):
stream {
server {
proxy_pass upstream:443
listen 127.0.0.1:1234;
}
}
Nginx läuft auf einer GCP-Compute-Instanz hinter eineminterner Passthrough-Load Balancermit der IP-Adresse 10.11.12.13, also habe ich die folgende iptables-Regel hinzugefügt, um den Datenverkehr auf den transparenten Socket umzuleiten:
iptables -t mangle -I PREROUTING -d 10.11.12.13/32 -p tcp -j TPROXY --on-port=1234 --on-ip=127.0.0.1
Wie beschriebenHier, GCP installiert die lokale Route für den Load Balancer, sodass ich das nicht selbst tun muss. Mit anderen Worten, der folgende Befehl gibt zurück RTNETLINK answers: File exists
:
ip route add local 10.11.12.13/32 dev lo src 127.0.0.1
Der folgende Curl-Befehl bleibt jedoch hängen:
curl https://10.11.12.13
Aus Sicht von curl wird die TCP-Verbindung korrekt hergestellt, beim Überwachen des Nginx-Arbeitsprozesses scheint es jedoch, als würde der accept4
Systemaufruf hängen bleiben.
Beim Ausführen tcpdump
von der Instanz, auf der Nginx ausgeführt wird, wird Folgendes angezeigt:
15.59.51.564902 IP [REDACTED].50028 > 10.11.12.13.443: Flags [S], seq 3519046460, win 65535, options [mss 1320,nop,wscale 6,nop,nop,TS val 3905128064 ecr 0,sackOK,eol], length 0
15.59.51.564973 IP 10.11.12.13.443 > [REDACTED].50028: Flags [S.], seq 2512605282, ack 3519046461, win 28400, options [mss 1420,nop,nop,sackOK,nop,wscale 7], length 0
15.59.51.601898 IP [REDACTED].50028 > 10.11.12.13.443: Flags [.], ack 1, win 4096, length 0
15.59.51.601898 IP [REDACTED].50028 > 10.11.12.13.443: Flags [P.], seq 1:370, ack 1, win 4096, length 369
15.59.51.601898 IP 10.11.12.13.443 > [REDACTED].50028: Flags [.], ack 370, win 231, length 0
So wie ich das verstehe, bedeutet das, dass der Client Daten sendet, der Server dies bestätigt, der Client dann aber keine weiteren Daten sendet, vermutlich weil er eine Antwort vom Server erwartet, die er jedoch nicht erhält. Aus diesem Grund vermute ich, dass Nginx die vom Client gesendeten Daten einfach ignoriert.
Ich hoffe, ich habe genug Kontext bereitgestellt, um das Problem zu verstehen. Ich bin mir nicht sicher, wie ich von hier aus weitermachen soll oder ob bei dem, was ich versuche, etwas grundsätzlich falsch ist. Für jede Hilfe wäre ich sehr dankbar.
Antwort1
Ich habe die Lösung gefundenHierDabei wurde die folgende Option für die Nginx-Serviceeinheit festgelegt:
[Service]
NonBlocking=true
Vermutlich geht Nginx davon aus, dass diese Option beim Erstellen des Listening-Sockets gesetzt ist, sodass die Daten nicht gelesen werden können, wenn Systemd ihnen einen Socket ohne diese gesetzte Option übergibt.