finish the article
This commit is contained in:
		
					parent
					
						
							
								350f50bdf7
							
						
					
				
			
			
				commit
				
					
						5bdf5d30df
					
				
			
		
					 1 changed files with 57 additions and 85 deletions
				
			
		| 
						 | 
					@ -6,9 +6,9 @@ author: ungleich
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
twitter_handle: ungleich
 | 
					twitter_handle: ungleich
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
_hidden: yes
 | 
					_hidden: no
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
_discoverable: no
 | 
					_discoverable: yes
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
abstract:
 | 
					abstract:
 | 
				
			||||||
How to redirect traffic from all (tcp/udp) ports to another port.
 | 
					How to redirect traffic from all (tcp/udp) ports to another port.
 | 
				
			||||||
| 
						 | 
					@ -16,111 +16,83 @@ And why one would want to do that...
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
body:
 | 
					body:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## The problem
 | 
					## Motivation
 | 
				
			||||||
 | 
					 | 
				
			||||||
Let's say you have a service running on a specific port, for instance
 | 
					 | 
				
			||||||
[wireguard](https://www.wireguard.com/) on **port 51820**, but you
 | 
					 | 
				
			||||||
would like to accept packets on **any** port and have it received by
 | 
					 | 
				
			||||||
your application.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
As you might know we are [big fans of
 | 
					 | 
				
			||||||
nftables](https://ungleich.ch/de/cms/ungleich-blog/2018/08/19/iptables-vs-nftables/),
 | 
					 | 
				
			||||||
so we will use nftables to achieve this goal.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Why would one want this?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
There are a variety of reasons for doing this, including the
 | 
					 | 
				
			||||||
"because we can" case. However at
 | 
					 | 
				
			||||||
[ungleich](https://ungleich.ch) we have a real world use case: We
 | 
					 | 
				
			||||||
provide an [IPv6 VPN](https://ipv6vpn.ch) as a service to our
 | 
					 | 
				
			||||||
customers. This service is based on wireguard and is configured to
 | 
					 | 
				
			||||||
listen on port 51820.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Sometimes networks (like hotels or airports) block or filter
 | 
					Sometimes networks (like hotels or airports) block or filter
 | 
				
			||||||
outgoing traffic and thus prevent our customers to be connected by
 | 
					outgoing traffic and thus prevent you to connect to where you want to
 | 
				
			||||||
IPv6. Obviously this is not what we or our customers want.
 | 
					connect to.
 | 
				
			||||||
 | 
					Here at [ungleich](https://ungleich.ch) we are travelling quite a lot,
 | 
				
			||||||
 | 
					but we always want to be able to access the servers of
 | 
				
			||||||
 | 
					[Data Center Light](https://datacenterlight.ch), so that we can
 | 
				
			||||||
 | 
					maintain them from everywhere in the world, so we needed a way to
 | 
				
			||||||
 | 
					ensure that we have some way of connecting to them, even if the
 | 
				
			||||||
 | 
					network disallows traffic to the ssh port (tcp/22).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## A solution based on nftables
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As you might know we are
 | 
				
			||||||
 | 
					[big fans of
 | 
				
			||||||
 | 
					nftables](https://ungleich.ch/de/cms/ungleich-blog/2018/08/19/iptables-vs-nftables/)
 | 
				
			||||||
 | 
					and this hotel/airport problem motivated us to once again checkout
 | 
				
			||||||
 | 
					what we can achieve just with nftables.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Typically these networks will still allow outgoing traffic on
 | 
					Typically these networks will still allow outgoing traffic on
 | 
				
			||||||
*some ports*, but we don't know *which ports*.
 | 
					*some ports*, but we don't know *which ports*.
 | 
				
			||||||
Thus we will enable wireguard on *all ports*. Simple idea, isn't it?
 | 
					So instead of guessing which port we should bind SSH to,
 | 
				
			||||||
 | 
					we will just use nftables to make ssh available on
 | 
				
			||||||
 | 
					*all TCP ports*. Simple idea, isn't it?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## How it works
 | 
					## How it works
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To achieve our goal we need to tell nftables to take the traffic that
 | 
					To achieve our goal we need to tell nftables to take the traffic that
 | 
				
			||||||
goes to any port that is not our target port, to be redirected to our
 | 
					goes to any port that is not our target port, to be redirected to our
 | 
				
			||||||
target part. If you have other services running on the host, you might
 | 
					target part. If you have other services running on the host, you might
 | 
				
			||||||
want to adjust this logic.
 | 
					want to adjust this logic though (see below). The following
 | 
				
			||||||
 | 
					nftables snippet will already do the job:
 | 
				
			||||||
In nftables we have a lot of freedom naming and creating our own
 | 
					 | 
				
			||||||
chains
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TO FIX HERE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ALSO maybe include only incoming packets modification or is it part of prerouting?!
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
table ip nat {
 | 
					 | 
				
			||||||
	chain prerouting {
 | 
					 | 
				
			||||||
		type nat hook prerouting priority filter; policy accept;
 | 
					 | 
				
			||||||
		udp dport != 51820 jump vpnredirect
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chain postrouting {
 | 
					 | 
				
			||||||
		type nat hook postrouting priority srcnat; policy accept;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chain vpnredirect {
 | 
					 | 
				
			||||||
		udp dport != 51820 redirect to :51820
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## More sophisticated
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
[17:51:31] vpn-2a0ae5c1:~# cat /etc/nftables.conf
 | 
					 | 
				
			||||||
#!/usr/sbin/nft -f
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
flush ruleset
 | 
					flush ruleset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
table ip nat {
 | 
					table ip nat {
 | 
				
			||||||
	chain prerouting {
 | 
						chain prerouting {
 | 
				
			||||||
		type nat hook prerouting priority -101;
 | 
							type nat hook prerouting priority 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		# SSH works
 | 
					 | 
				
			||||||
		#tcp dport != 22 redirect to 22
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		# wireguard doesn't
 | 
					 | 
				
			||||||
		#udp dport != 51820 redirect to 51820
 | 
					 | 
				
			||||||
		#
 | 
					 | 
				
			||||||
		tcp dport != 22 jump port_redirect
 | 
					 | 
				
			||||||
		udp dport != 51820 jump port_redirect
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chain port_redirect {
 | 
					 | 
				
			||||||
		counter comment "redirecting"
 | 
					 | 
				
			||||||
		log prefix "port redir: "
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		# SSH works
 | 
					 | 
				
			||||||
		tcp dport != 22 redirect to 22
 | 
							tcp dport != 22 redirect to 22
 | 
				
			||||||
 | 
					 | 
				
			||||||
		# wireguard doesn't
 | 
					 | 
				
			||||||
		udp dport != 51820 redirect to 51820
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	chain postrouting {
 | 
						chain postrouting {
 | 
				
			||||||
		type nat hook postrouting priority -101;
 | 
							type nat hook postrouting priority 0;
 | 
				
			||||||
		counter comment "other side nat"
 | 
					 | 
				
			||||||
		log prefix "port post-redir: "
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can save this as nftables.conf and run
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## List of sites
 | 
					```
 | 
				
			||||||
 | 
					nft -f nftables.conf
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You find the current list of sites on
 | 
					to see it working on your system.
 | 
				
			||||||
[via-ipv6.com](https://via-ipv6.com). If you would like to have
 | 
					
 | 
				
			||||||
another site added, just ping me on [IPv6.chat](https://IPv6.chat).
 | 
					After applying this, we can use `ssh -p <port>` to choose any port and
 | 
				
			||||||
 | 
					connect to our server:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					ssh -p 80 serverX.placeY.ungleich.ch
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Using specific ranges or ports only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you have other services running on the system, you might want to
 | 
				
			||||||
 | 
					restrict the ports to be used for ssh. You can either use **sets**
 | 
				
			||||||
 | 
					(nftables syntax: *{ a, b, c, ... }*) or **intervals**
 | 
				
			||||||
 | 
					(nftables syntax: *X - Y*) as follows.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
							tcp dport 2000-4000 redirect to :ssh
 | 
				
			||||||
 | 
							tcp dport {23, 25, 80, 443 } redirect to :ssh
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## More of it?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you are interested in more of this, we invite you to join our
 | 
				
			||||||
 | 
					[open infrastructure chat on chat.ungleich.ch](https://chat.ungleich.ch).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue