Apakah mungkin untuk memblokir akses jaringan (keluar) dari satu proses?
localhost
(ke mesin yang sama) untuk melakukan pekerjaan mereka.
Apakah mungkin untuk memblokir akses jaringan (keluar) dari satu proses?
localhost
(ke mesin yang sama) untuk melakukan pekerjaan mereka.
Jawaban:
Dengan Linux 2.6.24+ (dianggap eksperimental hingga 2.6.29), Anda dapat menggunakan ruang nama jaringan untuk itu. Anda perlu mengaktifkan 'namespace jaringan' di kernel ( CONFIG_NET_NS=y
) dan util-linux dengan unshare
alat ini.
Kemudian, memulai proses tanpa akses jaringan sesederhana:
unshare -n program ...
Ini menciptakan ruang nama jaringan kosong untuk proses. Artinya, dijalankan tanpa antarmuka jaringan, termasuk tanpa loopback . Dalam contoh di bawah ini kami menambahkan -r untuk menjalankan program hanya setelah ID pengguna dan grup yang efektif saat ini telah dipetakan ke yang superuser (hindari sudo):
$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable
Jika aplikasi Anda membutuhkan antarmuka jaringan, Anda dapat mengatur yang baru:
$ unshare -n -- sh -c 'ip link set dev lo up; ping 127.0.0.1'
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=32 time=0.066 ms
Perhatikan bahwa ini akan membuat loopback lokal baru . Artinya, proses spawned tidak akan dapat mengakses port terbuka host 127.0.0.1
.
Jika Anda perlu mendapatkan akses ke jaringan asli di dalam namespace, Anda dapat menggunakan nsenter
untuk memasukkan namespace lainnya.
Contoh berikut berjalan ping
dengan namespace jaringan yang digunakan oleh PID 1 (ditentukan melalui -t 1
):
$ nsenter -n -t 1 -- ping -c4 example.com
PING example.com (93.184.216.119) 56(84) bytes of data.
64 bytes from 93.184.216.119: icmp_seq=1 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=2 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=3 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=4 ttl=50 time=139 ms
--- example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 134.621/136.028/139.848/2.252 ms
unshare -n
tampaknya membuang "Operasi tidak diizinkan" tanpa root
hak istimewa, apa pun yang saya lewatkan tentang hal itu?
sudo unshare -n
mewarisi hak root. Karena saya memerlukan sudo untuk menelepon unshare, saya bertanya-tanya bagaimana saya bisa memastikan bahwa program yang dipanggil tidak memiliki hak root.
sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'
@ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
Linux memiliki fitur yang disebut ruang nama jaringan yang memungkinkan Anda untuk secara esensial memiliki beberapa tumpukan jaringan pada mesin yang sama, dan menetapkan satu untuk suatu program saat menjalankannya. Ini adalah fitur yang biasanya digunakan untuk wadah, tetapi Anda juga dapat menggunakannya untuk mencapai apa yang Anda inginkan.
ip netns
Sub - perintah mengelolanya. Membuat namespace jaringan baru tanpa akses apa pun itu mudah, itu adalah status default namespace baru:
root@host:~# ip netns add jail
Sekarang, jika Anda beralih ke namespace itu, Anda dapat mengonfigurasinya dengan cukup mudah. Anda mungkin ingin memunculkan lo di dalamnya, dan hanya itu:
root@host:~# ip netns exec jail /bin/bash
root@host:~# ip addr add 127.0.0.1/8 dev lo
root@host:~# ip link set dev lo up
root@host:~# exit
Sekarang ketika Anda ingin menjalankan perintah Anda tanpa jaringan, Anda jalankan saja di penjara itu:
root@host:~# ip netns exec jail su user -c 'ping 8.8.8.8'
connect: Network is unreachable
Jaringan, seperti yang diinginkan, tidak dapat dijangkau. (Anda dapat melakukan semua jenis hal menarik sebagai tumpukan jaringan terpisah termasuk iptables
aturan, dll.)
sudo ip
mengeksekusi perintah ip, begitu saya menjadi bash, saya hanya mengeksekusi su someuser
untuk mendapatkan shell unprivileged untuk pengguna 'pengguna'.
Anda bisa menggunakan iptables dan memindahkan proses itu ke dalam cgroup:
mkdir /sys/fs/cgroup/net_cls/block
echo 42 > /sys/fs/cgroup/net_cls/block/net_cls.classid
iptables -A OUTPUT -m cgroup --cgroup 42 -j DROP
echo [pid] > /sys/fs/cgroup/net_cls/block/tasks
/sys/fs/cgroup/net_cls/tasks
(tidak ada 'blok' di jalur)
Ya, dengan profil apparmor yang disesuaikan, yaitu
/usr/bin/curl {
...
# block ipv4 acces
deny network inet,
# ipv6
deny network inet6,
# raw socket
deny network raw,
}
Tetapi dengan cara itu, Anda perlu membuat daftar file yang diizinkan untuk diakses juga, seluruh prosedur bisa sedikit rumit. Dan lihat dokumen bantuan di sini
Anda dapat menggunakan kotak pasir firejail (harus bekerja pada kernel dengan fitur seccomp).
Untuk menggunakannya lakukan saja
firejail --noprofile --net=none <path to executable>
--noprofile
menonaktifkan sandbox default
--net=none
menonaktifkan jaringan
Saya percaya bahwa sebagian besar distro sudah menyediakan paket tetapi bahkan jika mereka tidak firjail sebenarnya tidak memiliki dependensi selain membangun toolchain dan namespace / seccomp enabled kernel.
Ada beberapa fitur bagus lain dari firejail yang dapat ditunjukkan firejail --help
sehubungan dengan jaringan (seperti hanya menyediakan antarmuka loopback atau memblokir ip / dns dll) tetapi ini harus melakukan pekerjaan. Itu juga doesn't require root
.
Anda tidak dapat melakukannya dengan iptables saja. Fitur ini secara singkat ada , tetapi tidak dapat dibuat untuk bekerja dengan andal dan ditinggalkan.
Jika Anda dapat menjalankan proses sebagai ID pengguna khusus, iptables dapat melakukannya dengan owner
modul:
iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP
Lihat contoh di Iptables: mencocokkan lalu lintas keluar dengan conntrack dan pemilik. Bekerja dengan tetes aneh , aturan iptables / pf hanya mengizinkan aplikasi / pengguna XY?
Jika Anda dapat menjalankan proses dalam wadahnya sendiri, Anda dapat membuat firewall wadah itu secara mandiri (bahkan membuatnya benar-benar terputus dari jaringan).
Modul keamanan dapat memfilter akses proses ke fitur jaringan. Jawaban warl0ck memberi contoh dengan AppArmor.
Solusi 1: Firewall:
Kita dapat menggunakan firewall seperti Douane atau Opensnitch TAPI aplikasi tersebut tidak 100% efisien atau dalam tahap awal pengembangan (memiliki banyak bug, dll. Hingga 2019)
Solusi 2: Kernel MAC:
Kernel Mac dapat digunakan sebagai firewall yang paling dikenal adalah Tomoyo , SELinux dan AppArmor Solusi ini adalah yang terbaik ketika datang ke stabilitas dan efisiensi (solusi firewall) tetapi sebagian besar waktu pengaturan ini entah bagaimana rumit.
Solusi 3: Firejail:
Firejail dapat digunakan untuk memblokir akses jaringan untuk suatu aplikasi yang tidak memerlukan root apa pun yang bisa diuntungkan oleh pengguna
firejail --noprofile --net=none command-application
Solusi 4: Batalkan Berbagi
Unshare dapat memulai aplikasi pada namespace yang berbeda tanpa jaringan tetapi ini membutuhkan solusi root firejail melakukan hal yang persis sama tetapi tidak memerlukan root
unshare -r -n application-comand
Solusi 5: Proksi:
Salah satu solusinya adalah proksi aplikasi ke proxy nol / palsu . Kita bisa menggunakan tsocks atau proxybound . Berikut ini beberapa detail tentang pengaturan
Solusi 6: Iptables:
Solusi mudah lainnya adalah iptables, bisa jadi pengaturan untuk memblokir aplikasi
groupadd no-internet
grep no-internet /etc/group
useradd -g no-internet username
usermod -a -G no-internet userName
tanyakan:sudo groups userName
nano /home/username/.local/bin/no-internet
chmod 755 /home/username/.local/bin/no-internet
#!/bin/bash
sg no-internet "$@"
iptables -I OUTPUT 1 -m owner --gid-owner no-internet -j DROP
4. Periksa, misalnya di Firefox dengan menjalankan:
no-internet "firefox"
5. Jika Anda ingin membuat pengecualian dan mengizinkan suatu program untuk mengakses jaringan lokal :
iptables -A OUTPUT -m owner --gid-owner no-internet -d 192.168.1.0/24 -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner no-internet -d 127.0.0.0/8 -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP
6. Jadikan permanen
Salah satu cara untuk menerapkan aturan iptables saat boot adalah dengan menambahkan aturan sebagai layanan dengan systemd
cat /usr/lib/systemd/system/nonet.service
[Unit]
Description=Nonet group iptable update
After=network.target
After=xsession.target
After=iptables.service
After=shorewall.service
[Service]
Type=oneshot
RemainAfterExit=true
StandardOutput=journal
ExecStart=/bin/bash /home/user/Scripts/Nonet.iptables.sh
sg no-internet
untuk saat ini.
Tergantung pada apa distro yang Anda gunakan, tetapi itu adalah fitur yang biasanya termasuk dalam sistem MAC OS. Seperti yang dinyatakan sebelumnya, Ubuntu atau AppArmor SuSE dapat melakukan ini. Jika Anda menggunakan RHEL, Anda dapat mengonfigurasi SELinux untuk mengizinkan atau menolak akses ke nomor port tertentu berdasarkan label proses eksekusi. Ini semua bisa saya temukan setelah beberapa googling cepat tetapi mungkin ada lebih banyak sumber daya online jika Anda melihat lebih keras dan itu memberi Anda ide umum.
Anda dapat menggunakan seccomp-bpf untuk memblokir beberapa panggilan sistem. Misalnya mungkin ingin memblokirsocket
panggilan sistem untuk mencegah proses membuat soket FD.
Saya menulis contoh persetujuan ini yang mencegah socket
panggilan sistem untuk bekerja menggunakan libseccomp. Ringkasannya adalah (tanpa memeriksa kesalahan):
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_arch_add(ctx, SCMP_ARCH_NATIVE);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(socket), 1, SCMP_CMP(0, SCMP_CMP_EQ, pf));
seccomp_load(ctx);
execvp(argv[1], argv+1);
Ini tidak membutuhkan hak root.
Namun, kotak pasir lengkap jauh lebih kompleks sehingga Anda tidak boleh menggunakan perintah ini untuk memblokir program yang tidak kooperatif / jahat.
Anda bisa menggunakan program baris perintah yang disebut "proxychains" dan coba salah satu dari kemungkinan berikut:
Setel yang digunakannya ...
Saya belum mengujinya sendiri jadi saya tidak tahu apakah itu berfungsi ...