Hi there,
What is my problem
DHCP reply routing path is not correct, see Tcpdump Section below, and the port forward rule can not work.
What have I done
I've setup an ipsec interface (ipsec0, it is a tun device), and give this interface a static ip:
# ip link show ipsec0
26: ipsec0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1400 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 500
link/none
# ip addr show ipsec0
26: ipsec0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1400 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 192.168.100.1/24 brd 192.168.100.255 scope global ipsec0
valid_lft forever preferred_lft forever
inet6 fd22:1389:8072:100::1/64 scope global
valid_lft forever preferred_lft forever
DHCP server is also setup like this:
config dnsmasq
......
list interface 'ipsec0'
......
config dhcp 'ipsec0'
option interface 'ipsec0'
option start '100'
option limit '200'
option leasetime '12h'
option dhcpv4 'server'
option ra 'server'
option dhcpv6 'server'
Below is strongswan's dhcp config:
# cat /etc/strongswan.d/charon/dhcp.conf
dhcp {
# Always use the configured server address.
force_server_address = yes
# Derive user-defined MAC address from hash of IKE identity and send client
# identity DHCP option.
identity_lease = yes
# Interface name the plugin uses for address allocation.
interface = ipsec0
# Interface name the plugin uses to bind its receive socket.
# interface_receive = charon.plugins.dhcp.interface
# Whether to load the plugin. Can also be an integer to increase the
# priority of this plugin.
load = yes
# DHCP server unicast or broadcast IP address.
server = 192.168.100.255
# Use the DHCP server port (67) as source port when a unicast server address
# is configured.
use_server_port = no
}
Problem and logs
Now I am dailing into this vpn site and there are problems in ipsec's log, the dhcp request dont receive reply, but dnsmasq shows it is replied:
Sat Dec 27 14:45:38 2025 daemon.info ipsec: 14[CFG] sending DHCP DISCOVER for 7b:b7:bb:ca:ad:6f to 192.168.100.1
Sat Dec 27 14:45:38 2025 daemon.info dnsmasq-dhcp[1]: DHCPDISCOVER(ipsec0) 7b:b7:bb:ca:ad:6f
Sat Dec 27 14:45:38 2025 daemon.info dnsmasq-dhcp[1]: DHCPOFFER(ipsec0) 192.168.100.114 7b:b7:bb:ca:ad:6f
Sat Dec 27 14:45:40 2025 daemon.info ipsec: 06[MGR] ignoring request with ID 5, already processing
Sat Dec 27 14:45:41 2025 daemon.info ipsec: 14[CFG] sending DHCP DISCOVER for 7b:b7:bb:ca:ad:6f to 192.168.100.1
Tcpdump result and problem reasons
I've done some sniffer works, and now I understanding why this happend, BUT I DONT KNOW HOW TO RESOLVE IT:
14:03:16.004177 ipsec0 Out IP 192.168.100.1.68 > 192.168.100.255.67: BOOTP/DHCP, Request from 7b:b7:bb:ca:ad:6f, length 268
14:03:17.004601 ipsec0 Out IP 192.168.100.1.68 > 192.168.100.255.67: BOOTP/DHCP, Request from 7b:b7:bb:ca:ad:6f, length 268
14:03:19.005029 ipsec0 Out IP 192.168.100.1.68 > 192.168.100.255.67: BOOTP/DHCP, Request from 7b:b7:bb:ca:ad:6f, length 268
14:03:19.049906 lo In IP 192.168.100.1.67 > 192.168.100.1.67: BOOTP/DHCP, Reply, length 300
14:03:19.050842 lo In IP 192.168.100.1.67 > 192.168.100.1.67: BOOTP/DHCP, Reply, length 300
14:03:19.051684 lo In IP 192.168.100.1.67 > 192.168.100.1.67: BOOTP/DHCP, Reply, length 300
14:03:22.005457 ipsec0 Out IP 192.168.100.1.68 > 192.168.100.255.67: BOOTP/DHCP, Request from 7b:b7:bb:ca:ad:6f, length 268
14:03:22.006596 lo In IP 192.168.100.1.67 > 192.168.100.1.67: BOOTP/DHCP, Reply, length 300
14:03:26.005888 ipsec0 Out IP 192.168.100.1.68 > 192.168.100.255.67: BOOTP/DHCP, Request from 7b:b7:bb:ca:ad:6f, length 268
14:03:26.006872 lo In IP 192.168.100.1.67 > 192.168.100.1.67: BOOTP/DHCP, Reply, length 300
tcpdump shows the request (port 68 --> port 67) has sent to broadcast address (192.168.100.255), but the reply is routing to a wrong path, the traffic goes to the same ip and same port (???).
I tried port forward rules
I've setup a DNAT rule, but it seems useless:
# cat /etc/config/firewall
config redirect
option target 'DNAT'
option name 'VPN DHCP DNAT'
list proto 'udp'
option src 'ipsec0'
option src_dport '67'
option dest_port '68'
option dest 'ipsec0'
option src_port '67'
option family 'any'
option reflection '0'
The rule is a little confusing, but it said like below on openwrt's luci firewall web interface:
Match: incoming IPv6 and IPv6, protocol UDP, from ipsec0, port 67, to this device, port 67.
Action: forward to ipsec0, port 68