-1

I am currently setting up an OpenBSD firewall, router, and dns server. I've been following various guides online with the bulk of my configuration coming from the OpenBSD site and the pf configuration adapted from another guide.

Here are the main links:

Bridge Setup — https://www.openbsd.org/faq/faq6.html

PF Setup — https://www.openbsd.org/faq/pf/example1.html, https://openbsdrouterguide.net

When trying this out, I have two main issues that I'm not sure how to resolve. The first issue is that the bridge as explained in the OpenBSD guide is not working (no IP to the interface). The WAN port does successfully get an IP from the ISP and I can ping 1.1.1.1 as well as websites like openbsd.org and google.com. However, when I attempt to do a fw_update or a pkg_add to maintain the system, I get an error stating that there is no route to host.

My pf.conf does not load properly because it says there is a syntax error and bridge cannot be assigned an IP. I've looked my pf.conf over and I cannot spot where the syntax error is.

Here is my pf.conf:

# MACROS
pubif = "em0"
bridge = "bridge0"
wifi = "em5"

# TABLES
table <martians> {0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 240.0.0.0/4 255.255.255.255/32}

# RULES
set skip on lo0

# Spoofs
block in from no-route
block in quick from urpf-failed

# Block Non-routes
block in quick on $pubif from <martians> to any
block return out quick on $pubif from any to <martians>

# Default Block
block return in on {$bridge $wifi}
block return in on ! lo0 proto tcp to port 6000:6010
block return out log proto {tcp udp} user _pbuild
block drop in log on $pubif

# Allow ICMP
match in on $pubif inet proto icmp icmp-type {echoreq} tag ICMP_IN
block drop in on $pubif proto icmp
pass in proto icmp tagged ICMP_IN max-pkt-rate 100/10

# Router to Internet
pass out inet from $pubif

# Interfaces to Internet
pass in on {$bridge $wifi}

# Block DNS not originating from server
block return in quick on $bridge proto {udp tcp} to ! $bridge port {53 853}
block return in quick on $wifi proto {udp tcp} to ! $wifi port {53 853}

# Allow LAN
pass out on {$bridge $wifi} inet keep state

# NAT Rules
pass out on $pubif inet from $bridge:network to any nat-to ($pubif)
pass out on $pubif inet from $wifi:network to any nat-to ($pubif)

Here is my unbound.conf:

server:
    interface: 127.0.0.1
    interface: 10.0.0.1
    interface: 10.0.1.1

    access-control: 0.0.0.0/0 refuse
    access-control: ::0/0 refuse
    access-control: 127.0.0.0/8 allow
    access-control: ::1 allow
    access-control: 10.0.0.0/24 allow
    access-control: 10.0.1.0/24 allow

    hide-identity: yes

    hide-version: yes

    prefetch: yes

    private-address: 10.0.0.0/16

    auto-trust-anchor-file: "/var/unbound/db/root.key"
    root-hints: "/var/unbound/db/root.hints"

    cache-min-ttl: 3600
    serve-expired: yes

remote-control:
    control-enable: yes
    control-interface: /var/run/unbound.sock

Here is my dhcpd:

subnet 10.0.0.0 netmask 255.255.255.0 {
    option domain-name-servers 10.0.0.1;
    option routers 10.0.0.1;
    range 10.0.0.32 10.0.0.254;
}
subnet 10.0.1.0 netmask 255.255.255.0 {
    option domain-name-servers 10.0.1.1;
    option routers 10.0.1.1;
    range 10.0.1.32 10.0.1.254;
}

My vether0 inet 10.0.0.1 255.255.255.0 10.0.0.255

my bridge0

add vether0
add em1
add em2
add em3
add em4
up

The bridged interfaces are simply marked as up in their hostname.if and em5 which would connect to the access point is marked with it's own IP to separate it from the rest of the network (10.0.1.1).

rc.conf.local has the following lines:

dhcpd_flags=vether0
unbound_flags=
unbound_timeout=240

At this point, I'm not quite sure what I'm doing wrong. I feel I have followed all instructions. The one area I am most unsure is the vether0 and bridge0. Perhaps I am not doing this correctly? If anyone sees my error, it would appreciate if you can direct me to fixing it.

Thank you

EDIT:

ifconfig -a:

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 32768
    index 8 priority 0 llprio 3
    groups: lo
    inet6 ::1 prefixlen 128
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x8
    inet 127.0.0.1 netmask 0xff000000
em0: flags=808843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,AUTOCONF4> mtu 1500
    lladdr 00:e0:67:2b:a9:ec
    index 1 priority 0 llprio 3
    media: Ethernet autoselect (none)
    status: no carrier
em1: flags=8b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
    lladdr 00:e0:67:2b:a9:ed
    index 2 priority 0 llprio 3
    media: Ethernet autoselect (none)
    status: no carrier
em2: flags=8b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
    lladdr 00:e0:67:2b:a9:ee
    index 3 priority 0 llprio 3
    media: Ethernet autoselect (none)
    status: no carrier
em3: flags=8b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
    lladdr 00:e0:67:2b:a9:ef
    index 4 priority 0 llprio 3
    media: Ethernet autoselect (none)
    status: no carrier
em4: flags=8b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
    lladdr 00:e0:67:2b:a9:f0
    index 5 priority 0 llprio 3
    media: Ethernet autoselect (none)
    status: no carrier
em5: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    lladdr 00:e0:67:2b:a9:f1
    index 6 priority 0 llprio 3
    media: Ethernet autoselect (none)
    status: no carrier
    inet 10.0.1.1 netmask 0xffffff00 broadcast 10.0.1.255
enc0: flags=0<>
    index 7 priority 0 llprio 3
    groups: enc
    status: active
bridge0: flags=41<UP,RUNNING> mtu 1500
    index 9 llprio 3
    groups: bridge
    priority 32768 hellotime 2 fwddelay 15 maxage 20 holdcnt 6 proto rstp
    em4 flags=3<LEARNING,DISCOVER>
        port 5 ifpriority 0 ifcost 0
    em3 flags=3<LEARNING,DISCOVER>
        port 4 ifpriority 0 ifcost 0
    em2 flags=3<LEARNING,DISCOVER>
        port 3 ifpriority 0 ifcost 0
    em1 flags=3<LEARNING,DISCOVER>
        port 2 ifpriority 0 ifcost 0
    vether0 flags=3<LEARNING,DISCOVER>
        port 10 ifpriority 0 ifcost 0
vether0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    lladdr fe:e1:ba:d0:86:5a
    index 10 priority 0 llprio 3
    groups: vether
    media: Ethernet autoselect
    status: active
    inet 10.0.0.1 netmask 0xffffff00 broadcast 10.0.0.255
pflog0: flags=141<UP,RUNNING,PROMISC> mtu 33136
    index 11 priority 0 llprio 3
    groups: pflog

pfctl -nf /etc/pf.conf:

no IP address found for em0
/etc/pf.conf:33: could not parse host specification
no IP address found for bridge0
/etc/pf.conf:39: could not parse host specification
no IP address found for bridge0:network
/etc/pf.conf:49: could not parse host specification
2
  • This report is incomplete. One needs to understand how your network is configured in order to understand what is/should be going on. Please post at least your interface configuration (ifconfig -a). Also, you can check what the syntax error on pf.conf is by checking the file with pfctl -nf /etc/pf.conf. Please post that as well, if necessary.
    – Zé Loff
    Commented Jun 28, 2022 at 10:51
  • I've added the ifconfig and pfctl. As I mentioned, pf starts up with a syntax error and says that bridge does not have an IP. I don't have it plugged in right now so it shows that same error for em0 as well. When I do plug it in, em0 does receive an IP from my ISP and the only two errors are those referring to bridge0.
    – user474102
    Commented Jun 28, 2022 at 22:00

1 Answer 1

1

Some thoughts/questions:

  1. You can't assign an IP to a bridge, you assign it to one (or more) of the interfaces in it.
  2. For the same reason, you can't filter on a bridge interface.
  3. Why are you bridging the four interfaces? Do you actually want a trunk in broadcast mode instead of a bridge?
  4. If you are bridging the interfaces and want it to have a single IP address, there is no point in creating a separate rules for $wifi (em5). Actually, you aren't assigning an IP to em5, so those rules can't be evaluated.

Try

  1. dropping the vether and the bridge
  2. trunk em1-em5 in broadcast mode (see man trunk) and assign it some IP (e.g. the one you had on vether)
  3. adapt pf.conf, and
  4. make dhcpd listen on it.

If you want to segregate wifi clients (and the AP), don't trunk em5, give it an IP address on a different subnet, add the settings to this subnet to dhcpd.conf and unbound.conf, have dhcpd listen on trunk0 and em5 and then adapt pf.conf. Note that in this case you'll have to add rules to allow traffic between the LAN (trunk0) and the WLAN (em5).

Update:

Instead of trunking the interfaces, try switching from vether to vport and creating a veb instead of a bridge. Then change pf.conf to filter on the vport (not the veb!), and remove the rules for $wifi. And then have dhcpd and unbound listen on vport.

3
  • To answer your questions. The terminology I have seen in reference to grouping LAN interfaces in projects like opnsense and openwrt is bridging. The idea was to have ports 1 to 4 in the same IP range with port 5 handling a separate range for an AP. The OpenBSD documentation in my first link shows that a bridge would accomplish this and then mentions that PF can then filter on the bridge. Perhaps a trunk may be closer to what I want. Ultimately the goal is for communication between LAN devices and segregation of the AP devices. I know I’ll eventually have to add pf rules to segregate the AP
    – user474102
    Commented Jun 29, 2022 at 18:02
  • A veb is a newer form of bridge that appears to be more performant: kernelpanic.life/hardware/openbsd-veb-vs-bridge-benchmarks.html
    – jwillikers
    Commented Mar 5, 2023 at 14:20
  • @jwillikers yes, but there are more differences that just performance, it isn't a different implementation of the same thing. Crucially, veb works on Layer 2, while bridge works on Layer 3. This means that members of veb bridges become independent from the network stack and are "taken over" by the bridge. See the man page for veb for details.
    – Zé Loff
    Commented Mar 6, 2023 at 8:36

You must log in to answer this question.