Squid transparan dengan SSL-Bump untuk Gentoo dengan nft

gambar

Latar Belakang


Baru-baru ini, saya berjanji untuk menerjemahkan firewall pada PC saya dengan iptables yang telah teruji waktu ke nftables baru. Untuk studi yang lebih mendalam tentang tabel nf, saya mengatur sendiri tugas: untuk mengkonfigurasi server proxy transparan (Squid) dengan parsing koneksi terenkripsi (HTTPS) untuk mendistribusikan akses Internet ke mesin virtual, Raspberry Pi PCs, serta ponsel cerdas saya (menjalankan Android) Rilis 6) melalui koneksi nirkabel (menggunakan aplikasi hostapd).


.
, .
, ( , , . .). , , .
,


«Gentoo Linux» «OpenRC».

sys-kernel/gentoo-sources-5.3.1
USE=""
USE-
-net-proxy/squid-4.8
USE="caps ssl ssl-crtd"
dev-libs / openssl-1.1.1c-r1
USE = "asm test zlib"
Aplikasi Nftnet-firewall / nftables-0.9.2
USE = "doc gmp modern_kernel"
Aplikasi ipsys-apps / iproute2-5.2.0-r1
USE = "tutup minimal"
Layanan Penebanganapp-admin / ulogd-2.0.7-r1
USE = "nfct nflog"

Tuning kernel


gambar
Hal yang sama tetapi teks
[*] Networking support --->
Networking options --->
[*] TCP/IP networking
[*] IP: advanced router
[*] IP: policy routing
[*] Network packet filtering framework (Netfilter) --->
[*] Advanced netfilter configuration
Core Netfilter Configuration --->
# ,
[*] Netfilter ingress support
# ,
<*> Netfilter LOG over NFNETLINK interface
<*> Netfilter connection tracking support
<*> Netfilter nf_tables support
<*> Netfilter nf_tables set infrastructure
# ,
[*] Netfilter nf_tables netdev tables support
<*> Netfilter nf_tables conntrack module
# ,
<*> Netfilter nf_tables counter module
# ,
<*> Netfilter nf_tables log module
<*> Netfilter nf_tables masquerade support
<*> Netfilter nf_tables nat module
<*> Netfilter nf_tables socket match support
<*> Netfilter nf_tables tproxy support
IP: Netfilter Configuration --->
[*] IPv4 nf_tables support
# ,
<*> Ethernet Bridge nf_tables support --->


Untuk referensi, saya kutip kutipan dari /usr/src/linux/.config:

CONFIG_NET=y
CONFIG_INET=y
<b>CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y</b>
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_NETLINK=y
CONFIG_NETFILTER_NETLINK_LOG=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_TABLES=y
CONFIG_NF_TABLES_SET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_CT=y
CONFIG_NFT_COUNTER=y
CONFIG_NFT_LOG=y
CONFIG_NFT_MASQ=y
CONFIG_NFT_NAT=y
<b>CONFIG_NFT_SOCKET=y
CONFIG_NFT_TPROXY=y</b>
CONFIG_NF_TABLES_BRIDGE=y

Konfigurasi jaringan


Jika layanan net.lo tidak ditambahkan ke runlevel boot, maka harus ditambahkan di sana:

rc-config add net.lo boot

Dengan cara yang sama, mereka dibuat dan dikonfigurasikan untuk berjalan untuk tingkat standar layanan bersih. br0 (jembatan untuk mesin virtual dan smartphone), bersih. enp0s25 (antarmuka kabel) dan bersih. wlp3s0 (antarmuka nirkabel), misalnya:

ln -s net.lo /etc/init.d/net.br0
rc-config add net.br0 default

File konfigurasi terakhir /etc/conf.d/net dalam contoh kita terlihat seperti ini (minus pengaturan yang tidak terkait dengan tugas kita):

gambar

Hal yang sama tetapi teks
# TProxy
routes_lo='local default dev lo table 3128'

# Qemu bridge
bridge_force_br0=''
mac_br0='XX:XX:XX:XX:XX:XX'
config_br0='192.168.120.1/24'

# Ethernet
config_enp0s25='dhcp'
modules_enp0s25='udhcpc'
dhcp_enp0s25='release nontp'
udhcpc_enp0s25='--retries 8 --timeout 10'
fallback_enp0s25='10.a.b.c/16'
fallback_routes_enp0s25='default via 10.a.0.1'

# Wi-Fi
if [[ -f /var/lib/misc/hostapd ]]; then
  modules_wlp3s0="!ifconfig !iwconfig !wpa_supplicant"
  config_wlp3s0='null'
else
  config_wlp3s0='dhcp'
  modules_wlp3s0='udhcpc'
  wpa_supplicant_wlp3s0='-Dnl80211'
fi

postup() {
  if [ "${IFACE}" == lo ]; then
    ip rule add fwmark 3128 lookup 3128
  fi
  return 0
}


Baris yang disorot menambahkan tabel routing baru, dalam contoh ini di bawah nomor 3128, dan gerbang adalah default untuk itu (antarmuka loopback), dan aturannya adalah sesuai dengan paket yang ditandai dengan firewall dengan nomor label 3128 (angka desimal dalam kedua kasus) dilayani oleh jadwal ini.

Untuk mencegah paket-paket yang dirutekan dibuang karena ketidakcocokan alamat tingkat jaringan (proxy transparan membuat paket tetap utuh!), Tambahkan baris berikut ke /etc/sysctl.conf (atau ubah yang ada):

gambar

Jika Anda perlu menerapkan pengaturan ini sebelum me-reboot, maka Anda juga harus mengaturnya untuk kedua antarmuka jaringan dengan akses Internet:

sysctl net.ipv4.conf.enp0s25.rp_filter=0
sysctl net.ipv4.conf.wlp3s0.rp_filter=0

Pengaturan proxy


Karena port normal (buram) dari server proxy akan diperbaiki ke alamat jembatan ( 192.168.120.1 ), tambahkan baris berikut ke /etc/rc.conf:

rc_squid_need="net.br0"

Pengaturan proxy berikut tidak akan dipertimbangkan dalam artikel ini:

  • Verifikasi identitas pengguna pada port reguler (tidak transparan);
  • ICAP untuk berintegrasi dengan perangkat pencegahan kebocoran data (mis. InfoWatch Traffic Monitor);
  • Membuat kunci enkripsi dan membuat sertifikat.

File konfigurasi /etc/squid/squid.conf pada akhirnya terlihat seperti ini (untuk berjaga-jaga, saya berikan sepenuhnya):

gambar

gambar

Hal yang sama tetapi teks
	#    
1	acl virtual_machines src 192.168.120.0/24
2	acl SSL_ports port 443
	#      HTTPS 
3	acl SSL_ports port 1012        #  badssl.com
	#      HTTPS 
4	acl SSL_ports port 33443       # getcourse.ru  artlinerschool.ru
5	acl Safe_ports port 21         # ftp
6	acl Safe_ports port 80         # http
7	acl Safe_ports port 443        # https
	#     
8	acl Safe_ports port 1012       #  badssl.com
9	acl Safe_ports port 1025-65535 #  
10	acl CONNECT method CONNECT 
11	http_access deny !Safe_ports
12	http_access deny CONNECT !SSL_ports
13	http_access allow localhost manager
14	http_access deny manager
15	http_access allow localhost
	#      -
16	http_access allow virtual_machines
17	http_access deny all
	#   () .   ,       (,   - FTP)
18	http_port 192.168.120.1:3128 ssl-bump options=ALL:NO_SSLv3:NO_TLSv1 cert=/etc/squid/squid.pem
	#      .     «loopback»,         3128,  ,         
19	http_port 127.0.0.1:3129 tproxy
	#      .     «loopback»,         3128,  ,         
20	https_port 127.0.0.1:3130 tproxy ssl-bump options=ALL:NO_SSLv3:NO_TLSv1 cert=/etc/squid/squid.pem
	# -    ,   -
21	always_direct allow all
	#    ,   
22	acl BrokenButTrustedServers dstdomain "/etc/squid/selfsigned.txt"
	#      ,   
23	sslproxy_cert_error allow BrokenButTrustedServers
24	sslproxy_cert_error deny all
	#       TLS
25	tls_outgoing_options min-version=1.2
	#    
26	acl blocked ssl::server_name "/etc/squid/blocked_domains.txt"
	#   ,    -   (          SSL)
27	acl fragile dstdomain "/etc/squid/fragile_domains.txt"
28	acl step1 at_step SslBump1
29	ssl_bump peek step1
	#     
30	ssl_bump terminate blocked
	#       ,    -  
31	ssl_bump splice fragile
	#     ,  
32	ssl_bump bump all
	#    
33	sslcrtd_program /usr/libexec/squid/security_file_certgen -s /var/lib/squid/ssl -M 4MB
34	cache_dir rock /var/cache/squid-r 512 max-size=32768
35	cache_dir aufs /var/cache/squid 512 64 1024 min-size=32768
36	coredump_dir /var/tmp/squid
37	refresh_pattern    ^ftp:          1440 20% 10080
38	refresh_pattern -i (/cgi-bin/|\?) 0    0%  0
39	refresh_pattern    .              0    20% 4320
40	memory_replacement_policy heap GDSF
41	cache_replacement_policy LFUDA
42	maximum_object_size 32 MB
43	logfile_rotate 3
44	debug_options ALL,1,rotate=3
45	cache_mem 512 MB
46	visible_hostname host.shadow.amn
47	udp_incoming_address 127.0.0.1
48	pinger_enable off


Pengaturan firewall


Siapkan layanan nftables dan ulogd pada level run "default" (yang terakhir diperlukan untuk pemberitahuan paket):

rc-config add nftables default
rc-config add ulogd default

Karena akan ada jembatan di pengaturan firewall, tambahkan baris berikut ke /etc/rc.conf:

rc_nftables_need="net.br0"

Agar pemberitahuan berfungsi di /etc/sysctl.conf, Anda harus menambahkan baris berikut:

net.netfilter.nf_log.2 = nfnetlink_log

Agar file konfigurasi ada di folder / etc / nftables, kami membuat perubahan berikut di /etc/conf.d/nftables:

NFTABLES_SAVE="/etc/nftables/rules-save"

Untuk mencegah perubahan sementara agar tidak disimpan di file konfigurasi, buat perubahan lain ke /etc/conf.d/nftables:

SAVE_ON_STOP="no"

Saya akan menjelaskan tugas yang diberikan ke firewall:

  1. Aturan default di semua rantai tabel filter ip harus menghapus paket (bahkan di rantai output!). Demikian pula untuk tabel filter netdev;
  2. Pertukaran dalam bentuk apa pun, kecuali untuk IPv4 dan pertukaran layanan terkait (misalnya, ARP), ditekan sesegera mungkin (baik IPv4 maupun IPSec tidak digunakan);
  3. Paket multicast IPv4 juga dihapus sedini mungkin;
  4. Untuk melindungi ponsel cerdas Android (saat terhubung ke jembatan menggunakan aplikasi hostapd), pertukaran siaran yang dilakukan oleh mesin virtual yang berjalan di bawah sistem operasi Microsoft Windows tidak boleh ditransmisikan ke antarmuka nirkabel.
  5. Anda hanya dapat menggunakan perangkat Wi-Fi kami dengan alamat MAC yang dikenal.

File konfigurasi / etc / nftables / rules-save pada akhirnya terlihat seperti ini (minus sebagian besar penjelasan):

gambar

gambar

gambar

gambar

gambar

gambar

Hal yang sama tetapi teks
1	#!/sbin/nft -f
	#  ,     
2	define icmp_types = { destination-unreachable, time-exceeded, parameter-problem, echo-request, echo-reply }
3	define host = 192.168.120.1
4	define br = br0
5	define my_br_mac = XX:XX:XX:XX:XX:XX
6	define eth = enp0s25
7	define my_eth_mac = YY:YY:YY:YY:YY:YY
8	define wifi = wlp3s0
9	define my_wifi_mac = WW:WW:WW:WW:WW:WW
10	define my_phone = TT:TT:TT:TT:TT:TT
11	define virtual_machines = 192.168.120.0/24
12	define privileged_vm = { 192.168.120.22, 192.168.120.129 }
13	define dhcp_client = 192.168.120.224/27
14	define transmission_port = 51413
15	define no_track = { microsoft-ds, ms-wbt-server }
16	define vm_ssh = 192.168.120.70
17	define infowatch_pc = { 10.a.0.0/16, 10.h.0.0/16 }
18	define infowatch_my = 10.a.b.c
19	define squid_normal = 3128
20	define squid_transp = 3129
21	define squid_trassl = 3130
22	define sslvpn.infowatch.com = 46.148.194.86
23	define files.infowatch.ru = 178.16.25.15
24	define iwprint.infowatch.ru = 10.d.e.f
25	define s163.getcourses.ru = 95.213.153.163
26	define tls-v1-2.badssl.com = 104.154.89.105
27	flush ruleset
28	table ip raw {
29	  chain prerouting {
30	    type filter hook prerouting priority -300;
	    #      ,          
31	    meta l4proto { tcp, udp } th dport $transmission_port notrack
32	    tcp sport $no_track ip saddr != $iwprint.infowatch.ru notrack
33	    ip saddr { $sslvpn.infowatch.com, $files.infowatch.ru } tcp sport https notrack
34	  }
35	}
36	table ip filter {
37	  chain input {
38	    type filter hook input priority 0; policy drop;
	    #         ,        «loopback»
39	    iif lo accept
	    #   ICMP       ,       ICMP
40	    icmp type $icmp_types accept
	    #   
41	    ct state invalid counter drop
	    #   ,     (SACK)  TCP.        ,       
42	    tcp flags syn tcp option maxseg size < 999 counter drop
	    #   Bittorrent,         31
43	    iif $eth meta l4proto { tcp, udp } th dport $transmission_port accept
	    #  ,  ,       ,      
44	    tcp flags & (syn | ack) == syn ct state untracked log prefix "Untracked:" group 2 counter counter drop
	    #    ,        32
45	    tcp sport $no_track accept
	    #    ,        33
46	    ip saddr { $sslvpn.infowatch.com, $files.infowatch.ru } tcp sport https accept
	    #     ,   3128 ( )
47	    iif $br ip saddr $virtual_machines mark set 3128 counter accept
	    #       ,      ()  -
48	    iif $br ip daddr $host ip saddr $virtual_machines tcp dport { domain, http, microsoft-ds, nfs, $squid_normal } accept
	    #     
49	    ct state { established, related } accept
	    #       ,   
50	    iif $br udp dport { domain, bootps, tftp, 4011 } counter accept
	    #    ,        ,   (.  38)
51	    counter comment "  "
52	  }
53	  chain output {
54	    type filter hook output priority 100; policy drop;
	    #         ,        «loopback»
55	    oif lo accept
	    #   ICMP       ,       ICMP
56	    icmp type $icmp_types counter accept
	    #          (   48  50)
57	    oif { $eth, $wifi } udp dport . udp sport { bootps . bootpc } counter accept
58	    oif $br ip saddr $host ip daddr { $dhcp_client, 255.255.255.255 } udp sport . udp dport { bootps . bootpc } counter accept
59	    oif $br ip saddr $host ip daddr $virtual_machines udp sport { domain, tftp } counter accept
60	    oif $br ip saddr $host ip daddr $virtual_machines tcp sport { domain, http, microsoft-ds } accept
	    #  -           .      HTTPS   ,            
61	    oif $br ip daddr $virtual_machines tcp sport { http, https, 1012 } counter accept
	    #      ,     ,    1024
62	    meta l4proto { tcp, udp } th sport >= 1025 accept
	    #    ,        ,   (.  54)
63	    counter comment "  "
64	  }
65	  chain forward {
66	    type filter hook forward priority 0; policy drop;
	    #        (MTU)
67	    tcp flags syn tcp option maxseg size set rt mtu counter
	    #         
68	    iif $br ip daddr != $host meta l4proto { tcp, udp } th dport domain drop
	    #      ( -)      ,     ,  ,   .    ,      ( 80  443)     -,    divert         forward (  66  81).  ,   96      ,      80  443
69	    iif $br ip saddr { $privileged_vm, $dhcp_client } accept
70	    oif $br ip daddr { $privileged_vm, $dhcp_client } accept
	    #    ,        ,   (.  66)
71	    counter comment "  "
72	  }
	  #    «   • »     HTTPS  ,   443
73	  set nonstandard_https {
74	    type ipv4_addr . inet_service;
75	    elements = {
76	      $s163.getcourses.ru . 33443, #   artlinerschool.ru
77	      $tls-v1-2.badssl.com . 1012, #   badssl.com
78	  }
79	}
80	  chain divert {
81	    type filter hook prerouting priority -150; policy accept;
	    #   3128 (. .)   TCP,   ,    (  -)
82	    meta l4proto tcp socket transparent 1 mark set 3128 accept
	    #   3128 (. .)   TCP   ,   80.      -
83	    ip daddr != { 127.0.0.1, $host } tcp dport http tproxy to 127.0.0.1:$squid_transp mark set 3128 counter accept
	    #   3128 (. .)   TCP   ,   443.      -
84	    ip daddr != { 127.0.0.1, $host } tcp dport https tproxy to 127.0.0.1:$squid_trassl mark set 3128 counter accept
	    #    3128 (. .)   TCP        nonstandard_https (.  76  77  ).      -
85	    ip daddr . tcp dport @nonstandard_https tproxy to 127.0.0.1:$squid_trassl mark set 3128 counter accept
86	  }
87	}
88	table ip nat {
89	  chain prerouting {
90	    type nat hook prerouting priority 0; policy accept;
	    #               SSH
91	    iif $eth ip daddr $infowatch_my ip saddr $infowatch_pc tcp dport ssh counter dnat $vm_ssh
92	  }
93	  chain postrouting {
94	    type nat hook postrouting priority 100; policy accept;
	    #      ,   -,         .  -     UID  GID 
95	    oif { $eth, $wifi } ip saddr $virtual_machines skuid . skgid { squid . squid } counter masquerade
	    #      ,     ,  ,     , (   69  70).     ,    ,       HTTPS .           nonstandard_https (.  76  77  ).
96	    oif { $eth, $wifi } ip saddr { $privileged_vm, $dhcp_client } tcp dport != { http, https } log prefix "NAT:" group 2 counter masquerade
97	  }
98	}
	
99	table bridge filter {
  #   №5:     Wi-Fi   
100	  chain input {
    type filter hook input priority -200; policy accept;
    iif $wifi ether saddr != $my_phone counter drop
  }
  #   №4:    ,    IPv4,      
  chain forward {
101	    type filter hook forward priority -200; policy accept;
102	    oif $wifi ether type arp accept
103	    oif $wifi ip protocol { icmp, tcp, udp } ip daddr != 192.168.120.255 accept
104	    oif $wifi drop
105	  }
  #   №5:   Wi-Fi     
106	  chain output {
    type filter hook input priority 200; policy accept;
    oif $wifi ether daddr != $my_phone counter drop
  }
}
	#   №2:     ,    IPv4
107	table netdev filter {
108	  chain enp0s25 {
109	    type filter hook ingress device enp0s25 priority 0; policy drop;
110	    ether type arp accept
111	    ether daddr $my_eth_mac ip protocol { icmp, tcp, udp, gre } accept
112	  }
113	  chain wlp3s0 {
114	    type filter hook ingress device wlp3s0 priority 0; policy drop;
	    #  ARP  EAPOL  ,        
115	    ether type { arp, 0x888e } accept
	    #       ,         ,   
116	    ether daddr { $my_br_mac, $my_wifi_mac, ff:ff:ff:ff:ff:ff } ip protocol { icmp, tcp, udp, gre } accept
117	  }
118	}


Kustomisasi konsumen


Di PC itu sendiri


Untuk tes yang lebih menyeluruh dari server proxy transparan, saya memutuskan untuk menggunakannya untuk semua aplikasi (dengan beberapa pengecualian, lebih lanjut tentang itu nanti) pada PC itu sendiri.

Tambahkan sertifikat server proxy ke toko bersama:

mkdir -p /usr/local/share/ca-certificates
cp /etc/squid/squid.pem /usr/local/share/ca-certificates/squid.crt

Perbarui repositori:

update-ca-certificates

Aplikasi - Firefox dan browser web Chromium tidak menggunakan toko sertifikat umum, jadi itu harus ditambahkan ke toko yang sesuai dari aplikasi ini.

Buat file konfigurasi /etc/env.d/38proxy dengan baris berikut:

http_proxy=http://192.168.120.1:3128
https_proxy=http://192.168.120.1:3128
ftp_proxy=http://192.168.120.1:3128

Perbarui variabel lingkungan:

env-update

Setelah memasukkan kembali pengaturan akan diterapkan ke semua aplikasi.

Tentang pengecualian:

  1. Untuk berjaga-jaga, mari kita tinggalkan browser web Chromium, itu akan selalu terhubung ke jaringan secara langsung, tanpa server proxy, untuk ini kita akan mengubah file konfigurasi / etc / chromium / default dengan cara ini:

    CHROMIUM_FLAGS="--enable-seccomp-sandbox —no-proxy-server"
  2. Di hadapan variabel lingkungan https_proxy, aplikasi xfreerdp mencoba untuk terhubung melalui server proxy, jadi tambahkan baris berikut ke file konfigurasi shell:

    alias xfreerdp='https_proxy= xfreerdp'
  3. Aplikasi youtube-dl tidak dapat memverifikasi sertifikat, mungkin karena sifat toko sertifikat Python. Solusi permanen belum ditemukan, jadi tambahkan baris berikut ke file konfigurasi shell:

    alias youtube-dl='youtube-dl --no-check-certificate'

Di Red Hat Enterprise Linux OS 6 dan 7 mesin virtual


Di mesin virtual, aktifkan sertifikat PEM:

update-ca-trust force-enable

Kami menulis ulang sertifikat server proxy dari PC ke mesin virtual:

scp squid.crt root@192.168.120.66:/etc/pki/ca-trust/source/anchors/

Di mesin virtual kami memperbarui sertifikat:

update-ca-trust extract

Pada mesin virtual dengan sistem operasi Microsoft Windows edisi yang berbeda


Sertifikat diunggah ke toko sertifikat umum mesin (bukan pengguna!) Di bagian "Root Tepercaya ...". Peramban web Firefox tidak menggunakan toko sertifikat umum, jadi sertifikat tersebut harus ditambahkan ke toko aplikasi yang sesuai.

Pada PC Raspberry Pi dengan Raspbian OS


Pembaruan aplikasi berhasil tanpa menginstal sertifikat.

Di ponsel cerdas dengan OS Android


Sertifikat dimuat sebelumnya ke perangkat, lalu dipasang menggunakan aplikasi manajemen sertifikat. Setelah itu, pengguna akan diminta untuk meningkatkan keamanan memasuki perangkat (jika belum dilakukan) menggunakan kunci grafis atau kata sandi.

Kesimpulan


Linux firewall baru (nft) adalah contoh yang bagus dari perangkat lunak gratis yang berjalan baik dengan Squid, standar de facto dari server proxy gratis.

Sumber utama


1. http://wiki.squid-cache.org/Features/Tproxy4
2. /usr/src/linux/Documentation/networking/tproxy.txt
3. http://wiki.nftables.org
4. nft (8)
5. https://www.bounca.org/tutorials/install_root_certificate.html

Penulis: Shamil SaitovNikodim_Tychoblin

All Articles