2015-01-27 4 views
14

Ich habe eine Anwendung (Server) auf Port 8080 zu hören. Ich möchte in der Lage sein, Port 80 an es weiterleiten, so dass http://localhost löst meine Anwendung (auf localhost:8080).Wie lokale Portweiterleitung mit iptables

Dies sollte für jede Portzuordnung verallgemeinert werden (z. B. 80:8080 =>P_src:P_target) und Best Practices für moderne * nix-Maschinen (z. B. Ubuntu) verwenden.

N.B. Dies geschieht alles lokal, so dass keine Verbindungen von irgendjemand außer localhost akzeptiert werden müssen.

+2

Die Leute scheinen diese Frage nicht zu mögen ... Wenn Sie abstimmen, erklären Sie bitte, warum. –

+0

Ehrlich sieht wirklich gut für mich aus. Klare Frage, fast vollständige Erklärung. – erikbwork

+1

Keine Programmierfrage. Prolly sollte nach Unix oder Serverfault verschoben werden. – Bacon

Antwort

14

Also nach viel herum suchen, fand ich die Antwort verwendet Iptables, Einrichten eines NAT und die eingebauten PREROUTING und OUTPUT.

Zunächst müssen Sie die Portweiterleitung aktiviert haben:

echo "1" > /proc/sys/net/ipv4/ip_forward

Dann müssen Sie die folgenden Regeln zu Ihrer iptables NAT-Tabelle hinzufügen, Ihre eigenen Werte für ${P_src} mit und ${P_target}:

iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport ${P_src} -j REDIRECT --to ${P_target}` 
iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport ${P_src} -j REDIRECT --to ${P_target}` 

Wenn Sie die Regeln entfernen möchten, müssen Sie einfach den -D-Schalter anstelle von -A für jede Regel verwenden.

Ich baue ein nettes kleines Skript für das Hinzufügen und Entfernen von Zuordnungen.

#!/bin/bash 
# 
# API: ./forwardPorts.sh add|rm p1:p1' p2:p2' ... 
# 
# Results in the appending (-A) or deleting (-D) of iptable rule pairs that 
# would otherwise facilitate port forwarding. 
# 
# E.g 
# sudo iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to 8080 
# sudo iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to 8080 
# 

if [[ $# -lt 2 ]]; then 
    echo "forwardPorts takes a state (i.e. add or rm) and any number port mappings (e.g. 80:8080)"; 
    exit 1; 
fi 

case $1 in 
    add) 
     append_or_delete=A;; 
    rm) 
     append_or_delete=D;; 
    *) 
     echo "forwardPorts requires a state (i.e. add or rm) as it's first argument"; 
     exit 1; ;; 
esac 

shift 1; 

# Do a quick check to make sure all mappings are integers 
# Many thanks to S.O. for clever string splitting: 
# http://stackoverflow.com/questions/918886/how-do-i-split-a-string-on-a-delimiter-in-bash 
for map in "[email protected]" 
do 
    IFS=: read -a from_to_array <<< "$map" 
    if [[ ! ${from_to_array[0]} =~ ^-?[0-9]+$ ]] || [[ ! ${from_to_array[1]} =~ ^-?[0-9]+$ ]]; then 
     echo "forwardPorts port maps must go from an integer, to an integer (e.g. 443:4443)"; 
     exit 1; 
    fi 
    mappings[${#mappings[@]}]=${map} 
done 

# We're shooting for transactional consistency. Only manipulate iptables if all 
# the rules have a chance to succeed. 
for map in "${mappings[@]}" 
do 
    IFS=: read -a from_to_array <<< "$map" 
    from=${from_to_array[0]} 
    to=${from_to_array[1]} 

    sudo iptables -t nat -$append_or_delete PREROUTING -s 127.0.0.1 -p tcp --dport $from -j REDIRECT --to $to 
    sudo iptables -t nat -$append_or_delete OUTPUT -s 127.0.0.1 -p tcp --dport $from -j REDIRECT --to $to 
done 

exit 0;