[megoldva] Host:80/443 port forwarding VirtualBox Guest:80/443

Sziasztok!

Adott egy Debian 9 szerver publikus IP-vel, rajta VirtualBoxban fut 3 másik szerver.
Az egyik VBox-on Apache fut, ezt kellene a publikus IP-n keresztül elérnem a net felől.
NAT hálózat van beállítva mindhárom virtuális gépnek, egymást is és a külvilágot is látják.
Az 1024 feletti portokat Portforwandiggal szépen ki tudom nyitogatni a Hoston és átirányítom a megfelelő virtuális gép megfelelő portjára.
Sajnos azonban a *nix rendszereken a userként futó VirtualBox nem nyithat 1024 alatti portot a hoston.
Megoldás lenne, ha a VirtualBoxot root-ként futtatnám, de ettől fázom,ez lenne a legvlgső megoldás.
Találtam olyan tippet, hogy a hostra tegyek fel egy másik Apache-ot és proxyzzam át a 80-as portoto pl. a 8080-ra, amit a VirtualBox portforwandinggal átirányítok a guest 80-as portjára.
Azt nem tudom, ez működne-e a 443-as porttal is vajon? Egyáltalán jó ez a parasztos megoldás?
Találtam utalást authbind-ra, esetleg ez lenne a legegyszerűbb?
A legjobb lenne, ha iptables-szel, vagy ufw-vel, vagy bármilyen tűzfalmegoldással át tudnám irányítani a host:80-at és a host:443:at a 192.168.0.102:80-ra ill. 443-ra.

TL;DR
A szerver IP mondjuk 111.222.33.44, a guest IP 192.168.0.102
szerver port 80, 443 -> guest 80, 443

Kérdés: ezt hogyan kell megtenni NAT hálózatnál?

 

Megoldás: https://hup.hu/comment/2265376#comment-2265376

Köszi mindenkinek!

Hozzászólások

vmi ilyesmi lenne:
iptables -A PREROUTING -t nat -i enp1s0 -p tcp --dport 80 -j DNAT --to 192.168.0.102:80
iptables -A FORWARD -p tcp -d 192.168.0.102 --dport 80 -j ACCEPT

Sajnos nem működik.

# ufw status
Status: active

To Action From
-- ------ ----
443/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere

# nmap publicip
mégsem mutatja a nyitott portot

Ha mondjuk a 192.168.0.101-ről nyitom meg böngészőből a 192.168.0.102-t, akkor működik.
Ha a netről próbálom meg, akkor időtullépés.

Nem a NAT kavar be?

Az ufw.log utolsó sora ez:
Sep 11 16:54:56 server kernel: [17163.190159] [UFW BLOCK] IN=eno1 OUT= MAC={MACADDRESS} SRC={ÉnIPCímem} DST={SzerverIPCíme} LEN=60 TOS=0x00 PREC=0x00 TTL=51 ID=62146 DF PROTO=TCP SPT=45226 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0

A DPT 8080 az a HTTP cache, de olyat én sehol nem akartam megadni/nem adtam meg

Szerk.: /etc/ufw/applications.d/ufw-webserver fájlban van egy ilyen bekezdés:

[WWW Cache]
title=Web Server (8080)
description=Web Server (8080)
ports=8080/tcp

Ez lehet a ludas?

Nem kell látszania a belső hálózatnak, ez a NAT így működik, teljesen normális, hogy nem válaszolnak a NAT mögötti gépek a pingre, mivel el se jut hozzájuk (visszafelé már nem lenne gond, csak odafelé nem megy a dolog).

A route megoldás lenne, de felesleges, mert nem az a cél, az csak bosszant legfeljebb téged, hogy nem tudod pingelni a belső gépeket.

Miért választottál NAT-ot? Nincs elég publikus IP-d? Biztonságosabbnak érzed a gépeket NAT mögött?

> ha nem eri el a halozatot, nem tudja tovabbitani a csomagokat
Dehogynem. Arra van a port forwarding NAT esetén. A gond itt az, hogy 1024 alatti portok esetén jelen konfigurációban nem megy a portok továbbítása.

> hogy ered el a virtual gepet igy?
A VirtualBox kezelőfelületén keresztül.

Muszáj 80-as és 443-as portokat használnod a NAT mögötti szerveren, amelyiken az Apache fut? Ha átteszed 1024 fölé mindkettőt (pl. 80 helyett 8088, 443 helyett 40443), akkor azzal áthidalnád a meglévő problémát, igaz, lenne helyette más: a böngészőben http esetén kellene a cím után írni :8088-at, https esetén meg :40443-at, de ez azért nem olyan borzasztó, csak közölni kell a dolgot az érintettekkel.

Megnéztem az authbind-ot is.
Mivel csak egyszeri hozzáférést biztosít a megadott portokhoz, ez sem egyszerű.
Minden reboot után automatikusan indulnak a VM-ek, de authbind nélkül.

Senki nem futtat webszervert virtuális gépben, ami a 80-as és a 443-as portokon figyel?

Ha nincs különösebb indok, hogy virtualboxot használj, akkor javaslom az ilyen problémák elkerülésére használj KVM/libvirtet. Virt managerrel kb ugyanolyan egyszerű kezelni, távolról is eléred, és kb elég a felhasználót felvenni a libvirt csoportjába hogy megfelelő jogosultságai legyenek. Plusz nem kell hozzá semmilyen extra toolt, kernel modult, etc. telepíteni. Persze libvirtes megoldásnál is olyan hálózatot kell beállítani, ami nem natol, tehát nem az user mode network-öt, ami többnyire a default.

Van egy scriptem, ami akár működhetne is, de valami nem jó még.

#!/bin/sh
SYSCTL="/sbin/sysctl -w" 
IPT="/sbin/iptables"
IPTS="/sbin/iptables-save"
IPTR="/sbin/iptables-restore"

INET_IFACE="eno1"
INET_ADDRESS="1.2.3.4"

LOCAL_IFACE="vboxnet0"
LOCAL_IP="192.168.0.1"
LOCAL_NET="192.168.0.0/24"
LOCAL_BCAST="192.168.0.255"

Windows="192.168.0.100"
Linux="192.168.0.102"

Host_SSH=12345
Ext_SSH=23456
Ext_RDP=34567

LO_IFACE="lo"
LO_IP="127.0.0.1"

if [ "$1" = "save" ]
then
    echo -n "Saving firewall to /etc/sysconfig/iptables ... "
    $IPTS > /etc/sysconfig/iptables
    echo "done"
    exit 0
elif [ "$1" = "restore" ]
then
    echo -n "Restoring firewall from /etc/sysconfig/iptables ... "
    $IPTR < /etc/sysconfig/iptables
    echo "done"
    exit 0
fi
echo "Loading kernel modules ..."
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
if [ "$SYSCTL" = "" ]
then
    echo "1" > /proc/sys/net/ipv4/ip_forward
else
    $SYSCTL net.ipv4.ip_forward="1"
fi
if [ "$SYSCTL" = "" ]
then
    echo "1" > /proc/sys/net/ipv4/tcp_syncookies
else
    $SYSCTL net.ipv4.tcp_syncookies="1"
fi
if [ "$SYSCTL" = "" ]
then
    echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
else
    $SYSCTL net.ipv4.conf.all.rp_filter="1"
fi
if [ "$SYSCTL" = "" ]
then
    echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
else
    $SYSCTL net.ipv4.icmp_echo_ignore_broadcasts="1"
fi
if [ "$SYSCTL" = "" ]
then
    echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route
else
    $SYSCTL net.ipv4.conf.all.accept_source_route="0"
fi
if [ "$SYSCTL" = "" ]
then
    echo "1" > /proc/sys/net/ipv4/conf/all/secure_redirects
else
    $SYSCTL net.ipv4.conf.all.secure_redirects="1"
fi
if [ "$SYSCTL" = "" ]
then
    echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
else
    $SYSCTL net.ipv4.conf.all.log_martians="1"
fi
echo "Flushing Tables ..."
$IPT -P INPUT ACCEPT
$IPT -P FORWARD ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P OUTPUT ACCEPT
$IPT -t mangle -P PREROUTING ACCEPT
$IPT -t mangle -P OUTPUT ACCEPT
$IPT -F
$IPT -t nat -F
$IPT -t mangle -F
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X
if [ "$1" = "stop" ]
then
    echo "Firewall completely flushed!  Now running with no firewall."
    exit 0
fi
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
echo "Create and populate custom rule chains ..."
$IPT -N bad_packets
$IPT -N bad_tcp_packets
$IPT -N icmp_packets
$IPT -N udp_inbound
$IPT -N udp_outbound
$IPT -N tcp_inbound
$IPT -N tcp_outbound
$IPT -A bad_packets -p ALL -i $INET_IFACE -s $LOCAL_NET -j LOG --log-prefix "fp=bad_packets:2 a=DROP "
$IPT -A bad_packets -p ALL -i $INET_IFACE -s $LOCAL_NET -j DROP
$IPT -A bad_packets -p ALL -m state --state INVALID -j LOG --log-prefix "fp=bad_packets:1 a=DROP "
$IPT -A bad_packets -p ALL -m state --state INVALID -j DROP
$IPT -A bad_packets -p tcp -j bad_tcp_packets
$IPT -A bad_packets -p ALL -j RETURN
$IPT -A bad_tcp_packets -p tcp -i $LOCAL_IFACE -j RETURN
$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "fp=bad_tcp_packets:1 a=DROP "
$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "fp=bad_tcp_packets:2 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "fp=bad_tcp_packets:3 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix "fp=bad_tcp_packets:4 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "fp=bad_tcp_packets:5 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "fp=bad_tcp_packets:6 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "fp=bad_tcp_packets:7 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
$IPT -A bad_tcp_packets -p tcp -j RETURN
$IPT -A icmp_packets --fragment -p ICMP -j LOG --log-prefix "fp=icmp_packets:1 a=DROP "
$IPT -A icmp_packets --fragment -p ICMP -j DROP
$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j DROP
$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
$IPT -A icmp_packets -p ICMP -j RETURN
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 137 -j DROP
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 138 -j DROP
$IPT -A udp_inbound -p UDP -j RETURN
$IPT -A udp_outbound -p UDP -s 0/0 -j ACCEPT
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port $Host_SSH -j ACCEPT
$IPT -A tcp_inbound -p TCP -j RETURN
$IPT -A tcp_outbound -p TCP -s 0/0 -j ACCEPT
echo "Process INPUT chain ..."
$IPT -A INPUT -p ALL -i $LO_IFACE -j ACCEPT
$IPT -A INPUT -p ALL -j bad_packets
$IPT -A INPUT -p ALL -d 224.0.0.1 -j DROP
$IPT -A INPUT -p ALL -i $LOCAL_IFACE -s $LOCAL_NET -j ACCEPT
$IPT -A INPUT -p ALL -i $LOCAL_IFACE -d $LOCAL_BCAST -j ACCEPT
$IPT -A INPUT -p UDP -i $LOCAL_IFACE --source-port 68 --destination-port 67 -j ACCEPT
$IPT -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p TCP -i $INET_IFACE -j tcp_inbound
$IPT -A INPUT -p UDP -i $INET_IFACE -j udp_inbound
$IPT -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets
$IPT -A INPUT -m pkttype --pkt-type broadcast -j DROP
$IPT -A INPUT -j LOG --log-prefix "fp=INPUT:99 a=DROP "
echo "Process FORWARD chain ..."
$IPT -A FORWARD -p ALL -j bad_packets
$IPT -A FORWARD -p tcp -i $LOCAL_IFACE -j tcp_outbound
$IPT -A FORWARD -p udp -i $LOCAL_IFACE -j udp_outbound
$IPT -A FORWARD -p ALL -i $LOCAL_IFACE -j ACCEPT
$IPT -A FORWARD -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -p tcp -i $INET_IFACE --destination-port 80 --destination $Linux -j ACCEPT 
$IPT -A FORWARD -p tcp -i $INET_IFACE --destination-port 443 --destination $Linux -j ACCEPT 
$IPT -A FORWARD -p tcp -i $INET_IFACE --destination-port $Ext_RDP --destination $Windows -j ACCEPT 
$IPT -A FORWARD -p tcp -i $INET_IFACE --destination-port $Ext_SSH --destination $Linux -j ACCEPT 
$IPT -A FORWARD -j LOG --log-prefix "fp=FORWARD:99 a=DROP "
echo "Process OUTPUT chain ..."
$IPT -A OUTPUT -m state -p icmp --state INVALID -j DROP
$IPT -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LO_IFACE -j ACCEPT
$IPT -A OUTPUT -p ALL -s $LOCAL_IP -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LOCAL_IFACE -j ACCEPT
$IPT -A OUTPUT -p ALL -o $INET_IFACE -j ACCEPT
$IPT -A OUTPUT -j LOG --log-prefix "fp=OUTPUT:99 a=DROP "
echo "Load rules for nat table ..."
$IPT -t nat -A PREROUTING -p tcp -i $INET_IFACE --destination-port 80 -j DNAT --to-destination $Linux
$IPT -t nat -A PREROUTING -p tcp -i $LOCAL_IFACE --destination-port 80 --destination $INET_ADDRESS -j DNAT --to-destination $Linux
$IPT -t nat -A PREROUTING -p tcp -i $INET_IFACE --destination-port 443 -j DNAT --to-destination $Linux
$IPT -t nat -A PREROUTING -p tcp -i $LOCAL_IFACE --destination-port 443 --destination $INET_ADDRESS -j DNAT --to-destination $Linux
$IPT -t nat -A PREROUTING -p tcp -i $INET_IFACE --destination-port $Ext_RDP -j DNAT --to-destination $Windows
$IPT -t nat -A PREROUTING -p tcp -i $LOCAL_IFACE --destination-port $Ext_RDP --destination $INET_ADDRESS -j DNAT --to-destination $Windows
$IPT -t nat -A PREROUTING -p tcp -i $INET_IFACE --destination-port $Ext_SSH -j DNAT --to-destination $Linux
$IPT -t nat -A PREROUTING -p tcp -i $LOCAL_IFACE --destination-port $Ext_SSH --destination $INET_ADDRESS -j DNAT --to-destination $Linux
$IPT -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_ADDRESS
$IPT -t nat -A POSTROUTING -o $LOCAL_IFACE -j SNAT --to-source $INET_ADDRESS

Átnéznétek, mi lehet a gond?
A net felől csak a host_ssh port van nyitva, a többi nmap-pal nem látszik.
Kívülről a "Host_SSH", "Ext_SSH", "Ext_RDP", a 80 és a 443 portoknak kellene nyitva lenniük.
Az Ext_SSH -> 192.168.0.102:22 -re,
Ext_RDP -> 192.168.0.100:3389 -re,
80 -> 192.168.0.102:80 -ra,
443 -> 192.168.0.102:443 -ra kellene átirányítani.

A 192.168.0.0/24 Host-only network, interfész: vboxnet0