OpenVPN in bridging mode can do exactly this. I have used it extensively in this mode for similar purposes. To the network, it is indistinguishable from a switch that happens to have two ports in separate locations.
There is no need for special hardware. Any machine running Linux that has 2 NICs can do this. There are also some router distros, such as Vyatta, that will support this. You might be able to use something like DD-WRT as well but I am not sure about that one.
This is how I do it with openSUSE as the distro. It might be a little easier with something like Vyatta, but I've done this a bunch of times and it works perfectly:
Pick one machine to be a server. Perform the following tasks on that machine:
Set up easy-rsa for key management (It's stored under /usr/share/openvpn/easy-rsa/2.0/ in openSUSE, but I make a copy under /etc/openvpn instead of using it in that location):
cd <easy_rsa location>
Edit the vars file and set the KEY_* params
. vars
./clean-all
./build-dh
./pkitool --initca
./pkitool --server mybridge-server
./pkitool mybridge-client
Create a bridge interface by creating the file /etc/sysconfig/network/ifcfg-mybridge, where you can substitute whatever name you want for mybridge:
BOOTPROTO='none'
BRIDGE='yes'
BRIDGE_FORWARDDELAY='0'
BRIDGE_PORTS='eth1'
BRIDGE_STP='off'
STARTMODE='auto'
2a. I am assuming that you will have eth1 as the "internal" interface here. You can actually set it up such that the server only uses a single NIC, which is actually what I would normally do in this situation, but I'm trying to keep it somewhat simple. If you want to try this, create the bridge as above, put eth0 in BRIDGE_PORTS instead and copy the IP information from the ifcfg-eth0 to ifcfg-mybridge. Then delete ifcfg-eth0, since your bridge will the primary interface
Create an /etc/openvpn/mybridge-server.conf (assuming you made a copy of easy-rsa):
port 1194
proto udp
dev mytun
dev-type tap
mode server
tls-server
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/mybridge-server.crt
key /etc/openvpn/easy-rsa/keys/mybridge-server.key
dh /etc/openvpn/easy-rsa/keys/dh1024.pem
keepalive 10 600
comp-lzo
fast-io
user nobody
group nogroup
persist-key
persist-tun
script-security 2
up mybridge-up.sh
status /var/run/openvpn/mybridge-server-status
verb 3
Create the mybridge-up.sh file in /etc/openvpn to ensure that the openVPN interface is added to the bridge when it starts:
#!/bin/bash
# Called with these args:
# tap_dev tap_mtu link_mtu ifconfig_local_ip ifconfig_netmask [ init | restart ]
/sbin/ip link set $1 up
/sbin/brctl addif mybridge $1
Ensure that openVPN starts on boot, and start/restart everything:
chkconfig --add openvpn
rcnetwork restart
rcopenvpn start
At this point, you will have a bridge interface called mybridge, containing the eth1 and mytun interfaces. Like any switch, Ethernet frames are passed through only if the destination mac is present on the other side
Now you can set up the client side:
Create a bridge interface just like on the server by creating the file /etc/sysconfig/network/ifcfg-mybridge:
BOOTPROTO='none'
BRIDGE='yes'
BRIDGE_FORWARDDELAY='0'
BRIDGE_PORTS='eth1'
BRIDGE_STP='off'
STARTMODE='auto'
Copy the ca.crt, mybridge-client.crt, and mybridge-client.key files to the client machine. I will use /etc/openvpn/keys/ in my example
Create an /etc/openvpn/mybridge-client.conf:
proto udp
dev mytun
dev-type tap
client
remote hostname_or_ip_of_server 1194
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/mybridge-client.crt
key /etc/openvpn/keys/mybridge-client.key
float
resolv-retry infinite
nobind
comp-lzo
fast-io
user nobody
group nogroup
persist-key
persist-tun
script-security 2
up mybridge-up.sh
verb 3
Copy or create the mybridge-up.sh file from the server in /etc/openvpn
Just like on the server, ensure that openVPN starts on boot, and start/restart everything:
chkconfig --add openvpn
rcnetwork restart
rcopenvpn start
After all of that, any machines on either side will be able to talk to each other as if they were on the same physical segment. You could even serve DHCP from one side if you wanted, or remotely perform configuration of devices that come out of the box with pre-configured static IP addresses.