Добрый день, уважаемые читатели. Хотел бы поделиться своим способом решения одной замысловатой задачи.
Допустим, имеется хост, по какой-либо причине недоступный на территории России. Доступ к этому хосту необходимо обеспечивать из небольшой локальной сети. Для решения проблемы есть возможность воспользоваться виртуальной машиной с FreeBSD 12, размещенной в облаке Microsoft Azure.
Конфигурация маршрутизатора Cisco:
!
crypto keyring MyTo
pre-shared-key address YYY.YYY.YYY.YYY key MyMegaKey
!
crypto isakmp policy 10
encr aes 256
authentication pre-share
group 2
!
crypto isakmp invalid-spi-recovery
crypto isakmp keepalive 120 20 periodic
crypto isakmp nat keepalive 20
crypto isakmp profile MyTo
keyring MyTo
match identity address YYY.YYY.YYY.YYY 255.255.255.255
initiate mode aggressive
!
!
crypto ipsec transform-set MyNet esp-aes 256 esp-sha-hmac
!
crypto ipsec profile MyTo
set transform-set MyNet
set pfs group2
set isakmp-profile MyTo
!
interface Tunnel10
description --- To ---
ip address 10.255.200.5 255.255.255.252
ip mtu 1400
ip tcp adjust-mss 1360
tunnel source Vlan1
tunnel mode ipsec ipv4
tunnel destination YYY.YYY.YYY.YYY
tunnel protection ipsec profile MyTo
!
!
router rip
version 2
redistribute static route-map RIP
passive-interface default
no passive-interface Vlan1
network 10.0.0.0
no auto-summary
!
ip forward-protocol nd
no ip http server
no ip http secure-server
ip flow-top-talkers
top 20
sort-by bytes
!
ip route 8.8.8.8 255.255.255.255 10.255.200.6
!
ip prefix-list RIP seq 100 permit 8.8.8.8/32
Так как туннель настраивается в уже существующем окружении, то нет возможности использовать crypto-map(это сильно облегчило бы задачу) и в качестве протокола динамической маршрутизации используется RIP. Я не стал поднимать на удаленном хосте quagga, а ограничился редистрибуцией маршрутов из статики на Cisco.
Приведу свои файлы конфигурации FreeBSD. Так как у нас туннель, а оба устройства имеют приватные адреса, то соответствующая запись в SPD определяются как 0.0.0.0/0, это приводит к тому, что ВЕСЬ трафик на стороне FreeBSD начинает заворачиваться в туннель. Для создания SPD приходится пользоваться racoon ( строка generate_policy on;
), а ipsec.conf будет служить нам для формирования списка исключений хостов, трафик к которым НЕ БУДЕТ заворачиваться в туннель. В примере ниже, в туннель не будет завернут для адреса 8.8.8.8
[root@srv /usr/local/etc/racoon]# cat ipsec.conf
flush;
spdflush;
spdadd -4 10.229.33.4/32 8.8.8.8/32 any -P out none;
spdadd -4 8.8.8.8/32 10.229.33.4/32 any -P in none;
[root@srv /usr/local/etc/racoon]# cat racoon.conf
path pre_shared_key "/usr/local/etc/racoon/key.txt";
log notify;
padding {
maximum_length 20;
randomize off;
strict_check off;
exclusive_tail off;
}
listen {
isakmp 10.229.33.4 [500];
isakmp_natt 10.229.33.4 [4500];
}
remote XXX.XXX.XXX.XXX {
exchange_mode aggressive,main;
nat_traversal on;
my_identifier address YYY.YYY.YYY.YYY;
peers_identifier address 10.255.200.2;
lifetime time 86400 sec;
dpd_delay 20;
dpd_retry 120;
doi ipsec_doi;
situation identity_only;
passive off;
proposal_check obey;
generate_policy on;
proposal {
encryption_algorithm aes 256;
authentication_method pre_shared_key;
hash_algorithm sha1;
dh_group 2;
}
}
sainfo anonymous
{
encryption_algorithm aes 256;
authentication_algorithm hmac_sha1;
pfs_group 2;
compression_algorithm deflate;
}
[root@srv /usr/local/etc/racoon]# cat /etc/rc.conf
hostname="srv"
ifconfig_hn0="DHCP"
ifconfig_hn0_ipv6="inet6 accept_rtadv"
sshd_enable="YES"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"
waagent_enable="YES"
syslogd_enable="YES"
syslogd_flags="-ss"
cloned_interfaces="gre0"
ifconfig_gre0="10.255.200.6 10.255.200.5 netmask 255.255.255.255 link0 tunnel 10.229.33.4 XXX.XXX.XXX.XXX"
static_routes="remotelan"
route_remotelan="-net 10.255.0.0/16 10.255.200.5"
gateway_enable="YES"
# Enable PF
pf_enable="YES"
pflog_enable="YES"
pflog_logfile="/var/log/pf.log"
pflogd_enable="YES"
pfsync_enable="YES"
ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/usr/local/etc/racoon/ipsec.conf"
racoon_enable="YES"
racoon_flags="-f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log"
С такими настройками туннель устанавливается, только толку от него не много. Посмотрим на диагностику соединения:
[root@srv /usr/local/etc/racoon]# racoonctl show-sa isakmp
Destination Cookies Created
XXX.XXX.XXX.XXX.60548 ca6587371be0d32e:5e1b0688d9b899e9 2019-09-26 14:10:08
[root@srv /usr/local/etc/racoon]# racoonctl show-sa ipsec
10.229.33.4[4500] XXX.XXX.XXX.XXX[60548]
esp-udp mode=tunnel spi=3340752182(0xc71fd536) reqid=0(0x00000000)
E: aes-cbc 1b1b434f 6307f876 ef9eab5e ddadaab6 fc1e7681 965bb341 8b00c751 2b6e0795
A: hmac-sha1 370b608e c0c928c8 ac1058a9 10c59cc7 50cd5599
seq=0x000009a3 replay=4 flags=0x00000000 state=mature
created: Sep 26 14:10:09 2019 current: Sep 26 14:33:35 2019
diff: 1406(s) hard: 3600(s) soft: 2880(s)
last: Sep 26 14:10:11 2019 hard: 0(s) soft: 0(s)
current: 357656(bytes) hard: 0(bytes) soft: 0(bytes)
allocated: 2467 hard: 0 soft: 0
sadb_seq=1 pid=50504 refcnt=1
XXX.XXX.XXX.XXX[60548] 10.229.33.4[4500]
esp-udp mode=tunnel spi=172050126(0x0a4146ce) reqid=0(0x00000000)
E: aes-cbc 67f31bd3 60bc9040 103cd5d7 f6d30031 876921cc 0da3ca18 f2048c9e f9e620e5
A: hmac-sha1 8455336c d0b1de88 bac3c433 88298de6 34c064c6
seq=0x00000000 replay=4 flags=0x00000000 state=mature
created: Sep 26 14:10:09 2019 current: Sep 26 14:33:35 2019
diff: 1406(s) hard: 3600(s) soft: 2880(s)
last: Sep 26 14:10:11 2019 hard: 0(s) soft: 0(s)
current: 162564(bytes) hard: 0(bytes) soft: 0(bytes)
allocated: 2492 hard: 0 soft: 0
sadb_seq=0 pid=50504 refcnt=1
[root@srv /usr/local/etc/racoon]# setkey -DP
8.8.8.8[any] 10.229.33.4[any] any
in none
spid=1740 seq=3 pid=50892 scope=global
refcnt=1
0.0.0.0/0[any] 0.0.0.0/0[any] any
in ipsec
esp/tunnel/XXX.XXX.XXX.XXX-10.229.33.4/require
created: Sep 26 14:10:09 2019 lastused: Sep 26 14:33:41 2019
lifetime: 3600(s) validtime: 0(s)
spid=1741 seq=2 pid=50892 scope=global
refcnt=2
10.229.33.4[any] 8.8.8.8[any] any
out none
spid=1739 seq=1 pid=50892 scope=global
refcnt=1
0.0.0.0/0[any] 0.0.0.0/0[any] any
out ipsec
esp/tunnel/10.229.33.4-XXX.XXX.XXX.XXX/require
created: Sep 26 14:10:09 2019 lastused: Sep 26 14:33:41 2019
lifetime: 3600(s) validtime: 0(s)
spid=1742 seq=0 pid=50892 scope=global
refcnt=3
Для того, чтобы мы могли достигать целевой хост, для чего всё и затевалось, через FreeBSD, нам необходимо настроить NAT и межсетевой экран:
######################################
# macros
######################################
# Define the external/public interface
ext_if="hn0"
# Define the internal LAN interface
int_if="gre0"
# Define a list of services to allow traffic for
tcp_services="{ 22 }"
udp_services="{ 500, 4500 }"
# Define what types of ICMP to allow
icmp_types="echoreq"
######################################
# options
######################################
set block-policy return
set loginterface $ext_if
set skip on lo
scrub in
######################################
# nat/rdr
######################################
# Handle the NAT forwarding for the LAN
nat on $ext_if inet from !($ext_if) -> ($ext_if:0)
######################################
# filter rules
######################################
# Block all incoming
block in
# Allow outgoing and keep state
pass out keep state
# The antispoof mechanism protects against activity from spoofed or forged IP addresses
antispoof quick for { lo $int_if }
# Allow requests for our ports/services defined in the $tcp_services macro above to the server
pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services
pass in on $ext_if inet proto udp from any to ($ext_if) port $udp_services
pass out on $ext_if inet proto tcp to any port $tcp_services keep state
# Allow the defined ICMP types
pass in inet proto icmp all icmp-type $icmp_types
# Allow all internal traffic
pass from ($int_if) to any keep state
pass quick on $int_if no state
В качестве теоретического упражнения (ни в коем случае не для решения практических задач обхода каких-либо то ни было блокировок!) был написан скрипт, который может брать неструктурированную базу IP адресов, например, базу адресов, заблокированных на территории РФ и генерировать два конфигурационных файла, ipsec.conf для FreeBSD и cisco.conf для Cisco примерно такого содержания:
...
spdadd -4 10.229.33.4/32 59.106.0.0/16 any -P out none;
spdadd -4 59.106.0.0/16 10.229.33.4/32 any -P in none;
...
...
ip route 89.163.0.0 255.255.0.0 10.255.200.6
ip prefix-list RIP seq 4296 permit 89.163.0.0/16
...
Обращаю ваше внимание, что на момент написания статьи в базе РКН было 1605333 адресов. Для того, чтобы не разорвало таблицу маршрутизации Cisco, в скрипте есть возможность суммаризации по маске, что дает 4518 сетей /16
Ссылка на скрипт https://github.com/MixaSg/tracery_stone