带有nft的Gentoo的SSL-Bump透明鱿鱼

图片

背景


最近,我承诺将经过时间考验的iptables转换为PC上的防火墙,并将其转换为全新的nftable。为了更深入地研究nf表,我为自己设定了任务:配置具有加密连接解析(HTTPS)的透明代理服务器(Squid),以将Internet访问分配给虚拟机,Raspberry Pi PC和我的智能手机(运行Android)第6版)通过无线连接(使用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”
Nft应用网络防火墙/ nftables-0.9.2
USE =“ doc gmp modern_kernel”
IP申请sys-apps / iproute2-5.2.0-r1
USE =“ caps minimum”
记录服务app-admin / 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(虚拟机和智能手机的网桥),net。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中(或更改现有行):

图片

如果需要在重新启动之前应用这些设置,那么您应该另外为两个可以访问Internet的网络接口设置它们:

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"

本文中将不考虑以下代理设置:

  • 验证常规(非透明)端口上的用户身份;
  • 与数据防泄漏设备(例如InfoWatch Traffic Monitor)集成的ICAP;
  • 生成加密密钥并创建证书。

最后,配置文件/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


防火墙设定


在“默认”运行级别上设置nftable和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. 您只能使用具有已知MAC地址的Wi-Fi设备。

最后,配置文件/ 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	}


消费者定制


在PC本身上


为了对透明代理服务器进行更全面的测试,我决定将其用于PC本身上的所有应用程序(除某些例外,稍后会介绍)。

将代理服务器证书添加到共享存储中:

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

更新存储库:

update-ca-certificates

应用程序-Firefox和Chromium Web浏览器不使用通用证书存储,因此应将其添加到这些应用程序的相应存储中。

用以下几行创建配置文件/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 / chrome / 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

我们将代理服务器证书从PC重写到虚拟机:

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

在虚拟机上,我们更新证书:

update-ca-trust extract

在具有不同版本的Microsoft Windows操作系统的虚拟机上


证书被上载到计算机的常规证书存储区(不是用户!)在“受信任的根...”部分中。Firefox Web浏览器不使用公共证书存储,因此应将证书添加到此应用程序的相应存储中。

在具有Raspbian操作系统的Raspberry Pi PC上


没有安装证书,应用程序升级成功。

在装有Android OS的智能手机上


证书已预加载到设备上,然后使用证书管理应用程序进行安装。之后,将要求用户使用图形键或密码来增强进入设备的安全性(如果尚未完成)。

结论


新的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

作者: Shamil SaitovNikodim_Tychoblin

All Articles