Linux GRE Tunnel Setup
A

Lead Engineer @ Packetware

Linux GRE Tunnel Setup

Setup Tunnel Manual

This setup will forward all ports and will require 2 IPs on public SERVER A so that you can connect to the public machine doing the tunneling and not be tunneled to protected SERVER B in the case of maintenance.

SERVER A

Make sure IP forwarding is enabled.

echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p 

Create a new tunnel via GRE protocol

ip tunnel add tunnel0 mode gre local SERVER_A_IP remote SERVER_B_IP ttl 255

Add a private subnet to be used on the tunnel

ip addr add 192.168.0.1/30 dev tunnel0

Turn on the tunnel

ip link set tunnel0 up

SERVER B

Create a new tunnel via GRE protocol

ip tunnel add tunnel0 mode gre local SERVER_B_IP remote SERVER_A_IP ttl 255

Add a private subnet to be used on the tunnel

ip addr add 192.168.0.2/30 dev tunnel0

Turn on the tunnel

ip link set tunnel0 up

Create a new routing table

echo '100 GRE' >> /etc/iproute2/rt_tables

Make sure to honor the rules for the private subnet via that table

ip rule add from 192.168.0.0/30 table GRE

Make sure all traffic goes via SERVER A ip

ip route add default via 192.168.0.1 table GRE

Test if the traffic is outgoing through SERVER A

curl http://ipinfo.io --interface tunnel0

Option 1 SERVER A (Individual Ports)

Accept to and from traffic for the private IP of SERVER B

iptables -A FORWARD -d 192.168.0.2 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -s 192.168.0.2 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Setup a portforward of PORT 80 from SERVER A to port 8000 in SERVER_B

iptables -t nat -A PREROUTING -d SERVER_A -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.2:8000

Option 2 SERVER A (All Traffic)

Accept destination traffic for the private IP of SERVER_B

iptables -A FORWARD -d 192.168.0.2 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

All ports on the second IP will be forwarded to SERVER B IP such that all traffic will land on the protected server.

iptables -t nat -A POSTROUTING -s 192.168.0.0/30 ! -o gre+ -j SNAT --to-source SERVER_A_IP_TUNNEL
iptables -t nat -A PREROUTING -d SERVER_A_IP_TUNNEL -j DNAT --to-destination 192.168.0.2

Interfaces / Setup On Boot

SERVER A

Make sure IP forwarding is enabled.

echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p 

Place these into

/etc/network/interfaces

auto tunnel0
iface tunnel0 inet static
  address 192.168.0.1/30
  netmask 255.255.255.252
  pre-up ip tunnel add tunnel0 mode gre remote SERVER_B_IP local SERVER_A_IP_1
  post-up iptables -t nat -A POSTROUTING -s 192.168.0.0/30 ! -o gre+ -j SNAT --to-source SERVER_A_IP_TUNNEL
  post-up iptables -t nat -A PREROUTING -d SERVER_A_IP_TUNNEL -j DNAT --to-destination 192.168.0.2
  post-up iptables -A FORWARD -d 192.168.0.2 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
  post-down ip tunnel del tunnel0

and restart the networking service to activate the config.

systemctl restart networking

SERVER B

Create a new routing table

echo '100 GRE' >> /etc/iproute2/rt_tables

Place these into

/etc/network/interfaces

auto tunnel0
iface tunnel0 inet static
  address 192.168.0.2/30
  netmask 255.255.255.252
  pre-up ip tunnel add tunnel0 mode gre remote SERVER_A_IP_1 local SERVER_B_IP
  post-up ip rule add from 192.168.0.0/30 table GRE
  post-up ip route add default via 192.168.0.1 table GRE
  post-down ip tunnel del tunnel0

and restart the networking service to activate the config.

systemctl restart networking