Aturan IPTables untuk mengizinkan koneksi SSH yang masuk

11

Tujuan skrip ini adalah hanya mengizinkan lalu lintas melalui VPN, kecuali untuk localhost <-> localhost dan lalu lintas SSH yang masuk. Tetapi ketika saya menjalankan skrip melalui SSH saya terputus dan dipaksa untuk me-restart vm. Apa yang salah dengan skrip saya?

#!/bin/bash
iptables -F

#Allow over VPN
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A OUTPUT -o tun+ -j ACCEPT

#Localhost
iptables -A INPUT -s 127.0.0.1/8 -j ACCEPT
iptables -A OUTPUT -d 127.0.0.1/8 -j ACCEPT

#VPN
iptables -A INPUT -s 123.123.123.123 -j ACCEPT
iptables -A OUTPUT -d 123.123.123.123 -j ACCEPT

#SSH
iptables -A INPUT -p tcp --dport ssh -j ACCEPT

#Default Deny
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
Steven
sumber

Jawaban:

10

Rantai keluaran bertanggung jawab atas semua paket yang keluar.

Skrip Anda hanya memungkinkan paket keluar ke antarmuka terowongan, localhost, dan host jarak jauh di 123.123.123.123.

Jika Anda terhubung ke server dengan cara yang memerlukan daemon SSH untuk mengirim paket ke tujuan selain salah satu di atas, lalu lintas tidak akan diizinkan untuk keluar.

Untuk mengizinkan paket keluar dari daemon SSH Anda ke klien SSH Anda perlu menambahkan aturan berikut:

iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

Anda mungkin juga ingin menambahkan kriteria IP tujuan ke aturan di atas, jika Anda hanya menghubungkan dari satu lokasi. Aturan ini harus datang sebelum aturan 'DROP apa pun' utama untuk rantai output.

hellodanylo
sumber
+1 Ini akan berfungsi dan lebih spesifik daripada menggunakan aturan yang dibuat dan terkait (membuatnya lebih atau kurang bermanfaat tergantung pada konteksnya).
goldilocks
Keduanya jawaban yang bagus, saya sudah belajar banyak! Saya menguji jawaban @SkyDan dan bekerja dengan baik!
Steven
Nitpick: rantai output tidak bertanggung jawab atas paket yang diteruskan .
Björn Lindqvist
13

#SSHAturan Anda menyiratkan ssh adalah bentuk komunikasi satu arah, padahal sebenarnya tidak. Data sedang dikirim dan dikembalikan.

Cara normal untuk menangani ini, karena Anda tidak dapat mengetahui nomor port di sisi klien terlebih dahulu, adalah untuk mengizinkan koneksi yang dianggap "didirikan" atau "terkait" dengan koneksi yang dibuat. Untuk melakukan ini Anda perlu:

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Sebelum DROPaturan Anda (dan lebih disukai di bagian atas, karena aturan diproses secara berurutan dan keduanya akan berlaku untuk sebagian besar paket).

Ada penjelasan tentang bagaimana koneksi TCP menjadi DIDIRIKAN di sini ; pada dasarnya, fakta server membalas paket yang diizinkan oleh #SSH INPUTaturan Anda membuatnya begitu.

goldilocks
sumber
1
Ini tidak akan berfungsi. Paket mapan berarti kedua arah untuk koneksi TCP yang diberikan telah terlihat. Jika Anda hanya menambahkan aturan ini, paket keluar pertama masih akan diblokir.
hellodanylo
2
@SkyDan Ini referensi untuk itu . Perhatikan pada diagram bahwa ketika server mengirim syn / ack kembali ke klien setelah menerima syn pembukaan, koneksi dibuat artinya iptables akan membiarkan paket balasan melalui: "Setelah ia melihat satu paket (SYN), ia menganggap koneksi sebagai BARU. Setelah melihat paket kembali (SYN / ACK), itu menganggap koneksi sebagai ESTABLISHED. " -> lagi: iptables melihat paket kembali yang ingin dikirim oleh server, mengatur koneksi yang sudah dibuat, dan membiarkan balasan lewat.
goldilocks
1
Oke, saya mengerti mengapa itu akan berhasil. Agak tidak jelas, karena orang iptables hanya berbicara tentang melihat paket di kedua arah, bukan sepatah kata pun tentang paket handshake TCP menjadi pengecualian. Terima kasih untuk referensi!
hellodanylo
2
@SkyDan Bahkan, logika tidak hanya berlaku untuk tcp - saya salah -p tcpmembuat perbedaan dalam hal ini, dan melihat penjelasan UDP di halaman berikutnya (itu sama). Intinya adalah bahwa server membalas tanpa mengetahui apakah iptables akan mengizinkannya atau tidak, dan ketika iptables menerima balasan itu dari server pada sistem lokal , ia sekarang melihat lalu lintas di kedua arah (meskipun klien belum), mempertimbangkan koneksi terjalin, dan biarkan jawabannya keluar. "Teknis" di sini bergantung pada firewall yang berada di tengah-tengah kedua pihak.
goldilocks
1
Anda benar di sana. Seseorang mungkin harus memasukkan informasi ini ke dalam iptables man.
hellodanylo