OpenBSD Firewall / VPN using IPsec (site-to-site)
OpenBSD Firewall / VPN using IPsec (site-to-site)
This document will guide you through a very simple site-to-site VPN setup.
A lot of the same information can be found in the vpn(8) manual.
A few assumptions will be made here:
* You are using OpenBSD as the Firewall / Gateway / VPN endpoint at each site.
* Each box has two interfaces (int_if & ext_if).
* The "Authentication=" passphrase in both isakmpd.conf files match.
* 1 Static Public IP address and 1 Static Private IP address are assigned to each box.
* Machine A has the following IP addresses:
* Public = A.B.C.D
* Private = 10.1.1.1 (10.1.1.0 Network)
* Machine B has the following IP addresses:
* Public = W.X.Y.Z
* Private = 192.168.1.1 (192.168.1.0 Network)
---------------------------------------------------------------------------
AUTOMATED KEYING USING PRE-SHARED SECRETS
1. Create /etc/isakmpd/isakmpd.conf for machine A (change W.X.Y.Z and Authentication= accordingly):
# Incoming phase 1 negotiations are multiplexed on the source IP
# address. Phase 1 is used to set up a protected channel just
# between the two gateway machines. This channel is then used for
# the phase 2 negotiation traffic (i.e. encrypted & authenticated).
[Phase 1]
W.X.Y.Z= peer-machineB
# 'Phase 2' defines which connections the daemon should establish.
# These connections contain the actual "IPsec VPN" information.
[Phase 2]
Connections= VPN-A-B
# ISAKMP phase 1 peers (from [Phase 1])
[peer-machineB]
Phase= 1
Transport= udp
Address= W.X.Y.Z
Configuration= Default-main-mode
Authentication= change_this_to_your_secret
# IPSEC phase 2 connections (from [Phase 2])
[VPN-A-B]
Phase= 2
ISAKMP-peer= peer-machineB
Configuration= Default-quick-mode
Local-ID= machineA-internal-network
Remote-ID= machineB-internal-network
# ID sections (as used in [VPN-A-B])
[machineA-internal-network]
ID-type= IPV4_ADDR_SUBNET
Network= 10.1.1.0
Netmask= 255.255.255.0
[machineB-internal-network]
ID-type= IPV4_ADDR_SUBNET
Network= 192.168.1.0
Netmask= 255.255.255.0
# Main and Quick Mode descriptions (as used by peers and connections)
[Default-main-mode]
DOI= IPSEC
EXCHANGE_TYPE= ID_PROT
Transforms= 3DES-SHA,BLF-SHA
[Default-quick-mode]
DOI= IPSEC
EXCHANGE_TYPE= QUICK_MODE
Suites= QM-ESP-3DES-SHA-SUITE
2. chmod 600 /etc/isakmpd/isakmpd.conf for machine A
3. Create /etc/isakmpd/isakmpd.conf for machine B (change A.B.C.D and Authentication= accordingly):
# Incoming phase 1 negotiations are multiplexed on the source IP
# address. Phase 1 is used to set up a protected channel just
# between the two gateway machines. This channel is then used for
# the phase 2 negotiation traffic (i.e. encrypted & authenticated).
[Phase 1]
A.B.C.D= peer-machineA
# 'Phase 2' defines which connections the daemon should establish.
# These connections contain the actual "IPsec VPN" information.
[Phase 2]
Connections= VPN-B-A
# ISAKMP phase 1 peers (from [Phase 1])
[peer-machineA]
Phase= 1
Transport= udp
Address= A.B.C.D
Configuration= Default-main-mode
Authentication= change_this_to_your_secret
# IPSEC phase 2 connections (from [Phase 2])
[VPN-B-A]
Phase= 2
ISAKMP-peer= peer-machineA
Configuration= Default-quick-mode
Local-ID= machineB-internal-network
Remote-ID= machineA-internal-network
# ID sections (as used in [VPN-A-B])
[machineA-internal-network]
ID-type= IPV4_ADDR_SUBNET
Network= 10.1.1.0
Netmask= 255.255.255.0
[machineB-internal-network]
ID-type= IPV4_ADDR_SUBNET
Network= 192.168.1.0
Netmask= 255.255.255.0
# Main and Quick Mode descriptions (as used by peers and connections)
[Default-main-mode]
DOI= IPSEC
EXCHANGE_TYPE= ID_PROT
Transforms= 3DES-SHA,BLF-SHA
[Default-quick-mode]
DOI= IPSEC
EXCHANGE_TYPE= QUICK_MODE
Suites= QM-ESP-3DES-SHA-SUITE
4. chmod 600 /etc/isakmpd/isakmpd.conf for machine B
5. Create the same /etc/isakmpd/isakmpd.policy for both machine A and machine B:
Keynote-version: 2
Authorizer: "POLICY"
Conditions: app_domain == "IPsec policy" &&
esp_present == "yes" &&
esp_enc_alg != "null" -> "true";
6. chmod 600 /etc/isakmpd/isakmpd.policy for both machine A and machine B
7. Create /etc/pf.conf for machine A (change macros accordingly):
# macros
int_if = "fxp0"
ext_if = "fxp1"
icmp_types = "{ echorep, echoreq, timex, unreach }"
# GATEWAY_A = Machine A External IP
# GATEWAY_B = Machine B External IP
# NETWORK_A = Machine A Internal Network
# NETWORK_B = Machine B Internal Network
GATEWAY_A = "A.B.C.D/32"
GATEWAY_B = "W.X.Y.Z/32"
NETWORK_A = "10.1.1.0/24"
NETWORK_B = "192.168.1.0/24"
# scrub
scrub in all
# nat/rdr
nat on $ext_if from $int_if:network to any -> $ext_if
# filter rules
block in log on { enc0, fxp1 } all
block out on { enc0, fxp1 } all
pass quick on lo0 all
pass in on $ext_if inet proto icmp from any to $ext_if icmp-type $icmp_types keep state
pass in on $int_if from $int_if:network to any keep state
pass out on $int_if from any to $int_if:network keep state
pass out on $ext_if proto tcp all modulate state
pass out on $ext_if proto { udp, icmp } all keep state
# VPN Rules
# Passing in encrypted traffic from security gateways
pass in quick on $ext_if proto esp from $GATEWAY_B to $GATEWAY_A
pass out quick on $ext_if proto esp from $GATEWAY_A to $GATEWAY_B
# Need to allow ipencap traffic on enc0.
pass in quick on enc0 proto ipencap all
# Passing in traffic from the designated subnets.
pass in quick on enc0 from $NETWORK_B to $NETWORK_A
pass out quick on enc0 from $NETWORK_A to $NETWORK_B
# Passing in isakmpd(8) traffic from the security gateways
pass in quick on $ext_if proto udp from $GATEWAY_B to $GATEWAY_A port isakmp
pass out quick on $ext_if proto udp from $GATEWAY_A to $GATEWAY_B port isakmp
8. Create /etc/pf.conf for machine B (change macros accordingly):
# macros
int_if = "fxp0"
ext_if = "fxp1"
icmp_types = "{ echorep, echoreq, timex, unreach }"
# GATEWAY_B = Machine B External IP
# GATEWAY_A = Machine A External IP
# NETWORK_B = Machine B Internal Network
# NETWORK_A = Machine A Internal Network
GATEWAY_B = "W.X.Y.Z/32"
GATEWAY_A = "A.B.C.D/32"
NETWORK_B = "192.168.1.0/24"
NETWORK_A = "10.1.1.0/24"
# scrub
scrub in all
# nat/rdr
nat on $ext_if from $int_if:network to any -> $ext_if
# filter rules
block in log on { enc0, fxp1 } all
block out on { enc0, fxp1 } all
pass quick on lo0 all
pass in on $ext_if inet proto icmp from any to $ext_if icmp-type $icmp_types keep state
pass in on $int_if from $int_if:network to any keep state
pass out on $int_if from any to $int_if:network keep state
pass out on $ext_if proto tcp all modulate state
pass out on $ext_if proto { udp, icmp } all keep state
# VPN Rules
# Passing in encrypted traffic from security gateways
pass in quick on $ext_if proto esp from $GATEWAY_A to $GATEWAY_B
pass out quick on $ext_if proto esp from $GATEWAY_B to $GATEWAY_A
# Need to allow ipencap traffic on enc0.
pass in quick on enc0 proto ipencap all
# Passing in traffic from the designated subnets.
pass in quick on enc0 from $NETWORK_A to $NETWORK_B
pass out quick on enc0 from $NETWORK_B to $NETWORK_A
# Passing in isakmpd(8) traffic from the security gateways
pass in quick on $ext_if proto udp from $GATEWAY_A to $GATEWAY_B port isakmp
pass out quick on $ext_if proto udp from $GATEWAY_B to $GATEWAY_A port isakmp
9. Uncomment #net.inet.ip.forwarding=1 in /etc/sysctl.conf on both machine A and machine B
10. Add the following in /etc/rc.conf.local on both machine A and machine B:
isakmpd_flags=""
pf=YES
11. Reboot both machines
TESTING CONNECTIVITY / SECURITY
12. Simple ping test
- From any client on NETWORK_A, ping any alive host on NETWORK_B
- From any client on NETWORK_B, ping any alive host on NETWORK_A
13. Run netstat -r on both machines, you should see a similar output as this under the "Encap:" section:
- Machine A:
Encap:
Source Port Destination Port Proto SA(Address/Proto/Type/Direction)
192.168.1/24 0 10.1.1/24 0 0 W.X.Y.Z/50/use/in
10.1.1/24 0 192.168.1/24 0 0 W.X.Y.Z/50/require/out
- Machine B:
Encap:
Source Port Destination Port Proto SA(Address/Proto/Type/Direction)
10.1.1/24 0 192.168.1/24 0 0 A.B.C.D/50/use/in
192.168.1/24 0 10.1.1/24 0 0 A.B.C.D/50/require/out
14. Run tcpdump -i enc0 , you should see a similar output when pinging hosts on the opposite network:
- Client behind machine A pinging client behind machine B [Note the (authentic,confidential) and (encap)]:
09:59:12.550519 (authentic,confidential): SPI 0xae955d33: 10.1.1.106 > 192.168.1.3: icmp: echo request (encap)
09:59:12.601795 (authentic,confidential): SPI 0x4e0409e9: 192.168.1.3 > 10.1.1.106: icmp: echo reply (encap)
- Client behind machine B pinging client behind machine A [Note the (authentic,confidential) and (encap)]:
09:59:13.540813 (authentic,confidential): SPI 0xae955d33: 192.168.1.3 > 10.1.1.106: icmp: echo request (encap)
09:59:13.638618 (authentic,confidential): SPI 0x4e0409e9: 10.1.1.106 > 192.168.1.3: icmp: echo reply (encap)
15. Finished
Joel Gudknecht
photohaus@gmail.com
20041122