Mengakses server web DNAT'ted dari dalam LAN

12

Saya memiliki jaringan kecil dengan router, yang memelihara koneksi ke Internet, server dan beberapa workstation di jaringan lokal.

Peta jaringan

Server dimaksudkan untuk diakses dari Internet, dan ada beberapa entri DNAT yang diatur dalam iptables router, seperti ini:

-A PREROUTING -i ppp0 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10

Paket eksternal datang ke router melalui ppp0antarmuka, dan yang internal berasal br-lan, yang sebenarnya termasuk sakelar dan adaptor WLAN. Masalahnya adalah, sementara akses eksternal berfungsi dengan baik, mencoba mengakses server dari dalam LAN dengan IP eksternal yang diselesaikan DNS (ditugaskan untuk ppp0) gagal.

Satu-satunya solusi yang saya dapat ciptakan adalah menambahkan entri statis ke router /etc/hostsmenunjuk ke IP internal, tetapi karena tidak ada wildcard (dan saya memiliki setidaknya tiga domain tingkat atas yang ditugaskan untuk sistem itu, tidak menghitung puluhan subdomain), itu agak renyah dan cenderung gagal. Bisakah Anda menyarankan sesuatu yang lebih baik?

Saya hanya menemukan pertanyaan ini , yang tidak terlalu membantu.

Jika itu relevan, router menjalankan OpenWRT 10.03 Kamikaze dengan dnsmasq.

whitequark
sumber
Apa versi OpenWRT?
Corey S.
@Corey 10,03 Stabil, tapi itu tidak ada hubungannya dengan openwrt sendiri, bukan?
whitequark

Jawaban:

3

Saya terkejut bahwa setelah hampir 8 tahun, tidak ada yang menjelaskan bagaimana melakukan ini dengan cara yang benar menggunakan sistem konfigurasi UCI yang digunakan secara default di OpenWRT.

Jawaban Steven Monday benar, namun menggunakan iptablesperintah secara langsung, yang merupakan lapisan lebih rendah dari sistem konfigurasi UCI, dan sebaiknya tidak disentuh oleh sebagian besar pengguna OpenWRT jika memungkinkan.

Cara yang benar untuk mengakses server internal melalui IP publik / kombo port dari host internal lain di UCI adalah dengan mengaktifkan opsi konfigurasi di reflectionbawah setiap target DNAT tertentu dalam file /etc/config/firewall. Perilaku ini didokumentasikan di sini .

Sebagai contoh:

config redirect option target 'DNAT' option src 'wan' option dest 'lan' option proto 'tcp' option src_dport '44322' option dest_ip '192.168.5.22' option dest_port '443' option name 'apache HTTPS server' option reflection '1'

Catatan: Menurut dokumentasi OpenWRT yang ditunjukkan, reflectiondiaktifkan secara default. Dalam pengujian saya, ini tidak terjadi.

vittorio88
sumber
15

Saya menghapus jawaban asli saya, karena saya tidak sepenuhnya yakin bahwa itu benar. Sejak itu saya punya waktu untuk mengatur jaringan virtual VMs untuk mensimulasikan jaringan yang dimaksud. Berikut adalah seperangkat aturan firewall yang berfungsi untuk saya (dalam iptables-saveformat, hanya untuk nattabel):

-A PREROUTING -d 89.179.245.232/32 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10
-A POSTROUTING -s 192.168.2.0/24 -o ppp0 -j MASQUERADE
-A POSTROUTING -s 192.168.2.0/24 -d 192.168.2.10/32 -p tcp -m multiport --dports 22,25,80,443 -j MASQUERADE

POSTROUTINGAturan pertama adalah cara langsung berbagi koneksi internet dengan LAN. Saya meninggalkannya di sana untuk kelengkapan.

The PREROUTINGAturan dan kedua POSTROUTINGaturan bersama-sama membangun Nat yang tepat, sehingga koneksi ke server melalui alamat IP eksternal bisa terjadi, terlepas dari apakah koneksi berasal dari luar atau dari dalam LAN. Ketika klien pada LAN terhubung ke server melalui alamat IP eksternal, server melihat koneksi berasal dari alamat IP internal router (192.168.2.1).

Menariknya, ternyata ada beberapa variasi aturan POSTROUTING kedua yang juga berfungsi. Jika target diubah ke -j SNAT --to-source 192.168.2.1, efeknya (tidak mengherankan) sama dengan MASQUERADE: server melihat koneksi dari klien LAN lokal berasal dari alamat IP internal router. Di sisi lain, jika target diubah menjadi -j SNAT --to-source 89.179.245.232, maka NAT masih berfungsi, tetapi kali ini server melihat koneksi dari klien LAN lokal berasal dari alamat IP eksternal router (89.179.245.232).

Akhirnya, perhatikan bahwa Anda asli PREROUTING/ DNATaturan dengan -i ppp0tidak bekerja, karena aturan tidak pernah sesuai paket yang datang dari klien LAN (karena mereka tidak memasuki router melalui ppp0interface). Akan memungkinkan untuk membuatnya bekerja dengan menambahkan PREROUTINGaturan kedua hanya untuk klien LAN internal, tetapi itu akan menjadi tidak valid (IMO) dan masih perlu merujuk secara eksplisit ke alamat IP eksternal.

Sekarang, bahkan setelah meletakkan "hairpin NAT" (atau "loopback NAT", atau "refleksi NAT", atau apa pun yang orang suka menyebutnya) solusi secara rinci, saya masih percaya bahwa solusi DNS split-horizon - -dengan klien eksternal yang memutuskan untuk IP eksternal dan klien internal yang memutuskan untuk IP internal --- akan menjadi rute yang lebih baik untuk diambil. Mengapa? Karena lebih banyak orang memahami cara kerja DNS daripada memahami cara kerja NAT, dan sebagian besar membangun sistem yang baik memilih untuk menggunakan bagian yang dapat dipelihara. Pengaturan DNS lebih mungkin dipahami, dan dengan demikian dipelihara dengan benar, daripada pengaturan NAT yang misterius (IMO, tentu saja).

Steven Monday
sumber
Ini berfungsi dengan baik, terima kasih banyak! Saya setuju bahwa pengaturan DNS lebih baik, tetapi Anda tidak dapat meneruskan port yang berbeda pada IP eksternal yang sama ke mesin yang berbeda di LAN dengannya. Pokoknya, saya satu-satunya yang akan mempertahankan pengaturan ini, jadi tidak apa-apa.
whitequark
Saya senang mendengar ini berhasil untuk Anda!
Steven Senin
Apa itu "IMO"? Organisasi Meteor Internasional www.imo.net?
Jonathan Komar
@ macmadness86 IMO == Dalam Pendapat Saya
Steven Monday
3

Solusi umum adalah mengarahkan host internal Anda di server DNS lokal yang mengembalikan alamat "internal" yang benar untuk nama host ini.

Solusi lain - dan kami menggunakan ini di mana saya bekerja pada firewall Cisco kami - adalah menulis ulang tanggapan DNS pada firewall yang sesuai dengan alamat-alamat ini. Saya tidak berpikir ada alat untuk Linux yang melakukan ini sekarang.

Anda harus dapat mengkonfigurasi perutean pada gateway Anda untuk melakukan hal yang benar. Anda mungkin perlu mengonfigurasi server untuk mengetahui alamat ip yang dipetakan secara eksternal (mis. Dengan menetapkannya ke antarmuka dummy). Dengan konfigurasi ini, komunikasi dari satu sistem internal ke sistem internal lainnya - menggunakan alamat "eksternal" - akan melalui router.

larsks
sumber
Hmm. Jadi, apakah Anda menyarankan menambahkan IP eksternal ke antarmuka server dan kemudian mengkonfigurasi router sehingga akan meneruskan semua paket ke IP eksternal yang berasal dari dalam LAN ke server itu? Menarik, saya akan segera mengujinya.
whitequark
Bisakah Anda menyarankan konfigurasi? Saya mencoba ini:, ip rule add to 89.179.245.232 dev br-lan table 10; ip route add 89.179.245.232 via 192.168.2.10 dev br-lan table 10dan tidak berfungsi.
whitequark
Apa yang ada di tabel routing 10? Pada server internal, Anda mungkin ingin mereka memiliki alamat 192.168.xx lokal (untuk berkomunikasi secara lokal) dan alamat publik (sebagai alias) pada antarmuka utama mereka.
larsks
2

Apa yang Anda minta lakukan disebut NAT Loopbackdan mengharuskan Anda menambahkan aturan SNAT sehingga paket yang berasal dari LAN Anda ke Server Anda akan kembali melalui router:

-A POSTROUTING -p tcp -s 192.168.2.0/24 -d 192.168.2.10 -m multiport --dports 22,25,80,443 -j SNAT --to-source 89.179.245.232
SiegeX
sumber
Sayangnya, itu tidak berhasil. Saya awalnya melewatkan -i ppp0opsi dalam aturan saya yang dimaksud, karena itu ditangani oleh rantai lain; aturan ini akan mencegah perutean paket yang berasal dari LAN (dan jika saya mengaktifkannya, paket akan pergi dari sumber yang salah dan akan ditolak).
whitequark
Sudahkah Anda mencobanya? Ini hanya akan mempengaruhi paket-paket dari LAN Anda ke IP server Anda pada port-port yang sangat spesifik.
SiegeX
Ya saya lakukan. (Dan saya mencoba mengubah aturan pertama juga). Misalnya penggalian mengirim paket ke 192.168.2.1 # 53, dan kemudian mendapat balasan yang tidak terduga dari 192.168.2.10 # 53, dengan atau tanpa aturan Anda.
whitequark
0

komentar larsks tentang hosting versi internal dari namespace \ domain umumnya adalah cara saya menangani masalah ini di masa lalu. Tentu saja, Anda memerlukan server DNS secara internal untuk melakukan ini.

CurtM
sumber
Ya, saya sudah menulis bahwa saya menggunakan dnsmasq. Adakah ide untuk mengatur substitusi otomatis?
whitequark
Saya tidak tahu apa-apa tentang OpenWRT dan Kamikaze, tetapi berdasarkan apa yang saya baca - bagaimana jika Anda menambahkan yang berikut ke /etc/dnsmasq.conf "cname = ext-hostname.domain.com, int-hostname.domain.com"
CurtM
Yah, sejauh yang saya bisa menentukan, dnsmasq cnametidak mendukung topeng, dan dengan demikian tidak berlaku bagi saya karena jumlah subdomain.
whitequark
0

Saya datang dengan solusi berikut untuk memungkinkan jaringan tamu saya terhubung ke port yang diteruskan dari jaringan saya ke jaringan LAN. Skrip ini ditempatkan di bagian "Jaringan -> Firewall -> Aturan Kustom" saya:

# lookup the public IP (DDNS resolves to this)
wanip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

# Guest network to LAN
# srcname is the guest network name, this needs to match for iptables
srcname=guest
# CIDR notation of guest and lan networks
srcnet=192.168.15.0/24
tgtnet=192.168.10.0/24
# router (openwrt) IP on lan network
tgtrouter=192.168.10.1
# host on lan network where ports are normally forwarded
tgthost=192.168.10.5
# ports to forward as a list or range
tcpports=8080,9090
udpports=12345

prechain=prerouting_${srcname}_rule
postchain=postrouting_${srcname}_rule

# reset the tables to prevent duplicate rules
iptables -t nat -F ${prechain}
iptables -t nat -F ${postchain}

iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP SNAT" -j SNAT --to-source ${tgtrouter}
iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP SNAT" -j SNAT --to-source ${tgtrouter}

Untuk mendukung reboot, saya perlu menjalankan yang berikut dari baris perintah ssh di openwrt (jika tidak, saya percaya ada kondisi balapan di mana beberapa aturan ditambahkan dan kemudian dibilas selama reboot):

uci set firewall.@include[0].reload="1"
uci commit firewall

Refleksi NAT adalah pengaturan untuk koneksi dalam jaringan LAN untuk dirinya sendiri, tetapi tidak untuk jaringan lain jika Anda telah membuat beberapa antarmuka untuk mengisolasi lalu lintas. Saya mencoba mengonfigurasi aturan penerusan dari antarmuka web, tetapi itu mengirim semua lalu lintas ke port dari jaringan tamu ke host LAN tersebut. Di atas hanya memotong permintaan ke WAN IP, bukan semua lalu lintas jaringan.

DNS internal dapat digunakan sebagai pengganti ini, tetapi hanya jika semua port forward hanya pergi ke satu host. Jika Anda memiliki beberapa host tempat Anda meneruskan berbagai port, Anda dapat mengulangi aturan untuk port yang berbeda ke tgthostIP dan port yang berbeda.

BMitch
sumber
Di kernel saat ini ada conntrackmodul pertandingan. Dan yang Anda butuhkan untuk menyelesaikan masalah ini adalah dengan menggunakan aturan tunggal seperti itu:iptables -t nat -A POSTROUTING --dst <lan-net> ! --src <lan-gw-ip> -m conntrack --ctstate DNAT --ctorigdst <wan-gw-ip> -j MASQUERADE
Anton Danilov
@AntonDanilov bagus, saya suka itu. Aturan yang saya gunakan didasarkan dari refleksi aturan NAT yang sudah ada di OpenWRT untuk koneksi dari subnet yang sama. Tidak yakin apakah mereka punya alasan lain selain itu mungkin ditulis sebelum conntrack tersedia.
BMitch