====== IPSec for FreeBSD's jails communication ====== **Abstract**: Here we assume we have two FreeBSD hosts, **A** using public IP 1.1.1.1 and internal virtual net 192.168.3.0 for jails, and **B** using public IP 2.2.2.2 and internal net 192.168.6.0 for jails. We need hosts and jails to communicate together, preferably in a crypted way. ===== Preparation on both hosts ===== * [[http://www.freebsd.org/doc/en/books/handbook/kernelconfig-building.html|Compile]] a custom kernel with the following additional options options IPSEC options IPSEC_FILTERTUNNEL device crypto * Install [[http://www.kame.net/racoon/|racoon]] # cd /usr/ports/sysutils/ipsec-tools/ # make install ===== Steps to follow on each host ===== ==== On host A ==== === Configuration === == /etc/rc.conf == cloned_interfaces="gif0" ifconfig_gif0="inet 192.168.3.1 192.168.6.1 tunnel 1.1.1.1 2.2.2.2" static_routes="internalnet2" route_internalnet2="-net 192.168.6.0/24 192.168.6.1" ipv6_ifconfig_gif0="2001:db8:ab01::1 2001:db8:ab02::1 prefixlen 128" ipv6_static_routes="b" ipv6_route_b="2001:db8:ab02::1 -interface gif0" ipsec_enable="YES" ipsec_program="/usr/local/sbin/setkey" ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot racoon_flags="-l /var/log/racoon.log && echo -n 'racoon'" racoon_enable="yes" gateway_enable="YES" == /usr/local/etc/racoon/setkey.conf == #!/sbin/setkey -f flush; spdflush; spdadd 192.168.3.0/24 192.168.6.0/24 any -P out ipsec esp/tunnel/1.1.1.1-2.2.2.2/require; spdadd 192.168.6.0/24 192.168.3.0/24 any -P in ipsec esp/tunnel/2.2.2.2-1.1.1.1/require; spdadd 2001:db8:ab01::/64 2001:db8:ab02::/64 any -P out ipsec esp/tunnel/2001:db8:ab01::1-2001:db8:ab02::1/require; spdadd 2001:db8:ab02::/64 2001:db8:ab01::/64 any -P out ipsec esp/tunnel/2001:db8:ab02::1-2001:db8:ab01::1/require; == /usr/local/etc/racoon/psk.txt == # /usr/local/etc/racoon/psk.txt # IPv4/v6 addresses # 2.2.2.2 myfookinunforgettablepassword 2001:db8:ab02::1 myfookinunforgettablepassword == /usr/local/etc/racoon/racoon.conf == path pre_shared_key "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file log notify; #log verbosity setting: set to 'notify' when testing and debugging is complete padding # options are not to be changed { maximum_length 20; randomize off; strict_check off; exclusive_tail off; } timer # timing options. change as needed { counter 5; interval 20 sec; persend 1; # natt_keepalive 15 sec; phase1 30 sec; phase2 15 sec; } listen # address [port] that racoon will listening on { isakmp 1.1.1.1 [500]; isakmp 2001:db8:ab01::1 [500]; } remote 2.2.2.2 [500] { exchange_mode main,aggressive; doi ipsec_doi; situation identity_only; my_identifier address 1.1.1.1; peers_identifier address 2.2.2.2; lifetime time 8 hour; passive off; proposal_check obey; nat_traversal off; generate_policy off; proposal { encryption_algorithm blowfish; hash_algorithm md5; authentication_method pre_shared_key; lifetime time 30 sec; dh_group 1; } } remote 2001:db8:ab02::1 [500] { exchange_mode main,aggressive; doi ipsec_doi; situation identity_only; my_identifier address 1.1.1.1; peers_identifier address 2.2.2.2; lifetime time 8 hour; passive off; proposal_check obey; nat_traversal off; generate_policy off; proposal { encryption_algorithm blowfish; hash_algorithm md5; authentication_method pre_shared_key; lifetime time 30 sec; dh_group 1; } } sainfo (address 192.168.3.0/24 any address 192.168.6.0/24 any) # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp) { # $network must be the two internal networks you are joining. pfs_group 1; lifetime time 36000 sec; encryption_algorithm blowfish,3des,des; authentication_algorithm hmac_md5,hmac_sha1; compression_algorithm deflate; } sainfo (address 192.168.6.0/24 any address 192.168.3.0/24 any) # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp) { # $network must be the two internal networks you are joining. pfs_group 1; lifetime time 36000 sec; encryption_algorithm blowfish,3des,des; authentication_algorithm hmac_md5,hmac_sha1; compression_algorithm deflate; } sainfo address 2001:db8:ab01::/64 any address 2001:db8:ab02::/64 any # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp) { # $network must be the two internal networks you are joining. pfs_group 1; lifetime time 36000 sec; encryption_algorithm blowfish,3des,des; authentication_algorithm hmac_md5,hmac_sha1; compression_algorithm deflate; } sainfo address 2001:db8:ab02::/64 any address 2001:db8:ab01::/64 any # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp) { # $network must be the two internal networks you are joining. pfs_group 1; lifetime time 36000 sec; encryption_algorithm blowfish,3des,des; authentication_algorithm hmac_md5,hmac_sha1; compression_algorithm deflate; } === Start === == Manual startup == # ifconfig gif0 create # ifconfig gif0 192.168.3.1 192.168.6.1 # ifconfig gif0 tunnel 1.1.1.1 2.2.2.2 # ifconfig gif0 inet6 2001:db8:ab01::1 2001:db8:ab02::1 prefixlen 128 # route add 192.168.6.0 192.168.6.1 255.255.255.0 # route add -inet6 2001:db8:ab02:: -interface gif0 # /etc/rc.d/ipsec start # /usr/local/etc/rc.d/racoon start == Automatic startup == # reboot :-) ==== On host B ==== == /etc/rc.conf == cloned_interfaces="gif0" ifconfig_gif0="inet 192.168.6.1 192.168.3.1 tunnel 2.2.2.2 1.1.1.1" static_routes="internalnet1" route_internalnet1="-net 192.168.3.0/24 192.168.3.1" ipv6_ifconfig_gif0="2001:db8:ab02::1 2001:db8:ab01::1 prefixlen 128" ipv6_static_routes="a" ipv6_route_a="2001:db8:ab01::1 -interface gif0" ipsec_enable="YES" ipsec_program="/usr/local/sbin/setkey" ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot racoon_flags="-l /var/log/racoon.log && echo -n 'racoon'" racoon_enable="yes" gateway_enable="YES" == /usr/local/etc/racoon/setkey.conf == #!/sbin/setkey -f flush; spdflush; spdadd 192.168.6.0/24 192.168.3.0/24 any -P out ipsec esp/tunnel/2.2.2.2-1.1.1.1/require; spdadd 192.168.3.0/24 192.168.6.0/24 any -P in ipsec esp/tunnel/1.1.1.1-2.2.2.2/require; spdadd 2001:db8:ab02::/64 2001:db8:ab01::/64 any -P out ipsec esp/tunnel/2001:db8:ab02::1-2001:db8:ab01::1/require; spdadd 2001:db8:ab01::/64 2001:db8:ab02::/64 any -P out ipsec esp/tunnel/2001:db8:ab01::1-2001:db8:ab02::1/require; == /usr/local/etc/racoon/psk.txt == # /usr/local/etc/racoon/psk.txt # IPv4/v6 addresses # 1.1.1.1 myfookinunforgettablepassword 2001:db8:ab01::1 myfookinunforgettablepassword == /usr/local/etc/racoon/racoon.conf == path pre_shared_key "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file log notify; #log verbosity setting: set to 'notify' when testing and debugging is complete padding # options are not to be changed { maximum_length 20; randomize off; strict_check off; exclusive_tail off; } timer # timing options. change as needed { counter 5; interval 20 sec; persend 1; # natt_keepalive 15 sec; phase1 30 sec; phase2 15 sec; } listen # address [port] that racoon will listening on { isakmp 2.2.2.2 [500]; isakmp 2001:db8:ab02::1 [500]; } remote 1.1.1.1 [500] { exchange_mode main,aggressive; doi ipsec_doi; situation identity_only; my_identifier address 2.2.2.2; peers_identifier address 1.1.1.1; lifetime time 8 hour; passive off; proposal_check obey; nat_traversal off; generate_policy off; proposal { encryption_algorithm blowfish; hash_algorithm md5; authentication_method pre_shared_key; lifetime time 30 sec; dh_group 1; } } remote 2001:db8:ab01::1 [500] { exchange_mode main,aggressive; doi ipsec_doi; situation identity_only; my_identifier address 2.2.2.2; peers_identifier address 1.1.1.1; lifetime time 8 hour; passive off; proposal_check obey; nat_traversal off; generate_policy off; proposal { encryption_algorithm blowfish; hash_algorithm md5; authentication_method pre_shared_key; lifetime time 30 sec; dh_group 1; } } sainfo (address 192.168.3.0/24 any address 192.168.6.0/24 any) # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp) { # $network must be the two internal networks you are joining. pfs_group 1; lifetime time 36000 sec; encryption_algorithm blowfish,3des,des; authentication_algorithm hmac_md5,hmac_sha1; compression_algorithm deflate; } sainfo (address 192.168.6.0/24 any address 192.168.3.0/24 any) # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp) { # $network must be the two internal networks you are joining. pfs_group 1; lifetime time 36000 sec; encryption_algorithm blowfish,3des,des; authentication_algorithm hmac_md5,hmac_sha1; compression_algorithm deflate; } sainfo address 2001:db8:ab02::/64 any address 2001:db8:ab01::/64 any # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp) { # $network must be the two internal networks you are joining. pfs_group 1; lifetime time 36000 sec; encryption_algorithm blowfish,3des,des; authentication_algorithm hmac_md5,hmac_sha1; compression_algorithm deflate; } sainfo address 2001:db8:ab01::/64 any address 2001:db8:ab02::/64 any # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp) { # $network must be the two internal networks you are joining. pfs_group 1; lifetime time 36000 sec; encryption_algorithm blowfish,3des,des; authentication_algorithm hmac_md5,hmac_sha1; compression_algorithm deflate; } === Start === == Manual startup == # ifconfig gif0 create # ifconfig gif0 192.168.6.1 192.168.3.1 # ifconfig gif0 tunnel 2.2.2.2 1.1.1.1 # ifconfig gif0 inet6 2001:db8:ab02::1 2001:db8:ab01::1 prefixlen 128 # route add 192.168.3.0 192.168.3.1 255.255.255.0 # route add -inet6 2001:db8:ab01:: -interface gif0 # /etc/rc.d/ipsec start # /usr/local/etc/rc.d/racoon start == Automatic startup == # reboot :-) ===== Testing ===== on host A, run the following command: # tcpdump -i re0 host 2.2.2.2 and dst 1.1.1.1 * example of unencrypted traffic (ping) from B to A, on public IPs 23:24:42.762845 IP 2.2.2.2 > 1.1.1.1: ICMP echo request, id 37718, seq 1, length 64 23:24:43.791147 IP 2.2.2.2 > 1.1.1.1: ICMP echo request, id 37718, seq 2, length 64 * example of encrypted traffic (ping) from B to A, on private IPs 23:27:51.035045 IP 2.2.2.2 > 1.1.1.1: ESP(spi=0x0601db40,seq=0xaf3), length 116 23:27:52.063482 IP 2.2.2.2 > 1.1.1.1: ESP(spi=0x0601db40,seq=0xaf4), length 116