الحبار الشفاف مع SSL-Bump لـ Gentoo مع nft

صورة

خلفية


في الآونة الأخيرة ، تعهدت بترجمة جدار الحماية على جهاز الكمبيوتر الخاص بي مع iptables التي تم اختبارها عبر الزمن إلى nftables الجديدة تمامًا. لإجراء دراسة أكثر تفصيلاً للجداول nf ، قمت بتعيين المهمة بنفسي: لتكوين خادم وكيل شفاف (Squid) مع تحليل اتصال مشفر (HTTPS) لتوزيع الوصول إلى الإنترنت على الأجهزة الافتراضية وأجهزة الكمبيوتر "Raspberry Pi" بالإضافة إلى هاتفي الذكي (الذي يعمل بنظام Android الإصدار السادس) عبر اتصال لاسلكي (باستخدام تطبيق 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"
تطبيق Nftnet-firewall / nftables-0.9.2
USE = "doc gmp modern_kernel"
تطبيق IPsys-apps / iproute2-5.2.0-r1
USE = "قبعات صغيرة"
خدمة التسجيلمشرف التطبيق / ulogd-2.0.7-r1
USE = "nfct nflog"

توليف النواة


صورة
نفس الشيء ولكن النص
[*] 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 --->


كمرجع ، أقتبس مقتطفًا من /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

تكوين شبكة


إذا لم تتم إضافة خدمة net.lo إلى مستوى تشغيل التمهيد ، فيجب إضافتها هناك:

rc-config add net.lo boot

بنفس الطريقة ، يتم إنشاؤها وتكوينها للتشغيل على المستوى الافتراضي لخدمة الشبكة. br0 (جسر للآلات الافتراضية والهواتف الذكية) ، صافي. enp0s25 (واجهة سلكية) وصافي. wlp3s0 (واجهة لاسلكية) ، على سبيل المثال:

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

يبدو ملف التكوين النهائي /etc/conf.d/net في مثالنا كما يلي (باستثناء الإعدادات غير المتعلقة بمهمتنا):

صورة

نفس الشيء ولكن النص
# 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
}


تضيف الأسطر المميزة جدول توجيه جديد ، في هذا المثال تحت الرقم 3128 ، وتكون البوابة هي الافتراضية (واجهة الاسترجاع) ، والقاعدة وفقًا للحزم التي تم وضع علامة عليها بواسطة جدار الحماية برقم الملصق 3128 (الأرقام العشرية في كلتا الحالتين) ستكون يخدمه هذا الجدول.

لمنع تجاهل الحزم الموجهة بسبب عدم تطابق العناوين على مستوى الشبكة (يعمل الخوادم الوكيلة الشفافة على إبقاء الحزم كما هي!) ، أضف الأسطر التالية إلى /etc/sysctl.conf (أو قم بتغيير الحزم الحالية):

صورة

إذا كنت بحاجة إلى تطبيق هذه الإعدادات قبل إعادة التشغيل ، ثم يجب عليك أيضًا تعيينها لكل من واجهات الشبكة مع الوصول إلى الإنترنت:

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

إعدادات الوكيل


نظرًا لأنه سيتم إصلاح المنفذ العادي (غير الشفاف) للخادم الوكيل إلى عنوان الجسر ( 192.168.120.1 ) ، أضف السطر التالي إلى /etc/rc.conf:

rc_squid_need="net.br0"

لن يتم النظر في إعدادات الوكيل التالية في هذه المقالة:

  • التحقق من هوية المستخدمين في منفذ عادي (غير شفاف) ؛
  • التكامل مع ICAP مع جهاز منع تسرب البيانات (مثل InfoWatch Traffic Monitor) ؛
  • توليد مفاتيح التشفير وإنشاء شهادة.

يبدو ملف التكوين /etc/squid/squid.conf في النهاية كما يلي (فقط في حال أعطيته بالكامل):

صورة

صورة

نفس الشيء ولكن النص
	#    
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


إعداد جدار الحماية


قم بإعداد خدمات nftables و ulogd على مستوى التشغيل "الافتراضي" (هذا الأخير مطلوب لإعلام الحزمة):

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

نظرًا لأنه سيكون هناك جسر في إعدادات جدار الحماية ، أضف السطر التالي إلى /etc/rc.conf:

rc_nftables_need="net.br0"

لكي يعمل الإخطار في /etc/sysctl.conf ، يجب عليك إضافة السطر التالي:

net.netfilter.nf_log.2 = nfnetlink_log

بحيث يكون ملف التكوين في المجلد / etc / nftables ، نقوم بإجراء التغيير التالي في /etc/conf.d/nftables:

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

لمنع حفظ التغييرات المؤقتة في ملف التكوين ، قم بإجراء تغيير آخر على /etc/conf.d/nftables:

SAVE_ON_STOP="no"

سأصف المهام المعينة لجدار الحماية:

  1. يجب أن تزيل القواعد الافتراضية في جميع سلاسل جدول عامل تصفية IP الحزم (حتى في سلسلة الإخراج!). وبالمثل لجداول مرشح netdev ؛
  2. يتم حظر التبادل من أي نوع ، باستثناء IPv4 وتبادل الخدمات ذات الصلة (على سبيل المثال ، ARP) في أقرب وقت ممكن (لا يتم استخدام IPv4 أو IPSec) ؛
  3. تتم أيضًا إزالة حزم IPv4 للإرسال المتعدد في أقرب وقت ممكن ؛
  4. لحماية الهاتف الذكي الذي يعمل بنظام Android (عند الاتصال بالجسر باستخدام تطبيق hostapd) ، يجب ألا يتم إرسال تبادل البث الذي يتم بواسطة الأجهزة الافتراضية التي تعمل تحت نظام تشغيل Microsoft Windows إلى الواجهة اللاسلكية.
  5. يمكنك فقط استخدام أجهزة Wi-Fi مع عناوين MAC المعروفة.

يبدو ملف التكوين / etc / nftables / Rules-save في النهاية كما يلي (ناقص معظم التفسيرات):

صورة

صورة

صورة

صورة

صورة

صورة

نفس الشيء ولكن النص
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	}


تخصيص المستهلك


على جهاز الكمبيوتر نفسه


لإجراء اختبارات أكثر شمولاً لخادم وكيل شفاف ، قررت استخدامه لجميع التطبيقات (مع بعض الاستثناءات ، والمزيد حول ذلك لاحقًا) على جهاز الكمبيوتر نفسه.

أضف شهادة الخادم الوكيل إلى المخزن المشترك:

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

تحديث المستودع:

update-ca-certificates

التطبيقات - لا تستخدم متصفحات الويب Firefox و Chromium متجر شهادات مشتركًا ، لذلك يجب إضافتها إلى المتجر المقابل لهذه التطبيقات.

قم بإنشاء ملف التكوين /etc/env.d/38proxy مع الأسطر التالية:

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

تحديث متغيرات البيئة:

env-update

بعد إعادة الدخول ، سيتم تطبيق الإعدادات على جميع التطبيقات.

حول الاستثناءات:

  1. فقط في حالة ، دعنا نترك متصفح الويب Chromium ، وسوف يتصل دائمًا بالشبكة مباشرة ، بدون خادم وكيل ، لذلك سنقوم بتغيير ملف التكوين / etc / chromium / default بهذه الطريقة:

    CHROMIUM_FLAGS="--enable-seccomp-sandbox —no-proxy-server"
  2. في وجود متغير بيئة https_proxy ، يحاول تطبيق xfreerdp الاتصال عبر خادم وكيل ، لذا أضف السطر التالي إلى ملف تكوين shell:

    alias xfreerdp='https_proxy= xfreerdp'
  3. يتعذر على تطبيق youtube-dl التحقق من الشهادة ، ربما بسبب طبيعة مخزن شهادات Python. لم يتم العثور على حل دائم حتى الآن ، لذا أضف السطر التالي إلى ملف تكوين shell:

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

على Red Hat Enterprise Linux OS 6 و 7 أجهزة افتراضية


على الجهاز الظاهري ، قم بتمكين شهادات PEM:

update-ca-trust force-enable

نعيد كتابة شهادة الخادم الوكيل من الكمبيوتر إلى الجهاز الظاهري:

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

على الجهاز الظاهري نقوم بتحديث الشهادة:

update-ca-trust extract

على الأجهزة الافتراضية التي تعمل بأنظمة تشغيل Microsoft Windows بإصدارات مختلفة


يتم تحميل الشهادة إلى مخزن الشهادات العام للجهاز (وليس المستخدم!) في قسم "الجذور الموثوقة ...". لا يستخدم متصفح الويب Firefox متجر شهادات مشتركًا ، لذلك يجب إضافة الشهادة إلى المتجر المقابل لهذا التطبيق.

على جهاز كمبيوتر Raspberry Pi بنظام Raspbian OS


تمت ترقية التطبيق بنجاح بدون تثبيت شهادة.

على الهواتف الذكية التي تعمل بنظام التشغيل Android


يتم تحميل الشهادة مسبقًا على الجهاز ، ثم يتم تثبيتها باستخدام تطبيق إدارة الشهادة. بعد ذلك ، سيُطلب من المستخدم تعزيز أمان إدخال الجهاز (إذا لم يكن قد تم بالفعل) باستخدام مفتاح رسومي أو كلمة مرور.

استنتاج


يعد جدار حماية Linux الجديد (nft) مثالًا رائعًا للبرامج المجانية التي تتوافق بشكل جيد مع Squid ، وهو المعيار الفعلي لخادم وكيل مجاني.

المصادر الأولية


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

المؤلف: شامل سايتوفNikodim_Tychoblin

All Articles