119 lines
3.2 KiB
Markdown
119 lines
3.2 KiB
Markdown
title: How to redirect all ports to one port with nftables
|
|
---
|
|
pub_date: 2019-11-07
|
|
---
|
|
author: ungleich
|
|
---
|
|
twitter_handle: ungleich
|
|
---
|
|
_hidden: no
|
|
---
|
|
_discoverable: yes
|
|
---
|
|
abstract:
|
|
How to redirect traffic from all (tcp/udp) ports to another port.
|
|
And why one would want to do that...
|
|
---
|
|
body:
|
|
|
|
## Motivation
|
|
|
|
Sometimes networks (like hotels or airports) block or filter
|
|
outgoing traffic and thus prevent you to connect to where you want to
|
|
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).
|
|
|
|
To be able to do so from anywhere in the world, we needed to
|
|
ensure that we have some way of connecting to them, even if the
|
|
network filters traffic to the ssh port (tcp/22).
|
|
|
|
While our main motivation was to enable ssh, the example below can be
|
|
adjusted to any service, including http, https, smtp, ...
|
|
|
|
## 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
|
|
*some ports*, but we don't know *which ports*.
|
|
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
|
|
|
|
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
|
|
target part. If you have other services running on the host, you might
|
|
want to adjust this logic though (see below). The following
|
|
nftables snippet will already do the job:
|
|
|
|
```
|
|
flush ruleset
|
|
|
|
table ip nat {
|
|
chain prerouting {
|
|
type nat hook prerouting priority 0;
|
|
|
|
tcp dport != 22 redirect to 22
|
|
}
|
|
chain postrouting {
|
|
type nat hook postrouting priority 0;
|
|
}
|
|
}
|
|
```
|
|
|
|
You can save this as nftables.conf and run
|
|
|
|
```
|
|
nft -f nftables.conf
|
|
```
|
|
|
|
to see it working on your system.
|
|
|
|
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
|
|
```
|
|
|
|
(just replace the *tcp dport != ...* line above)!
|
|
|
|
## A note on ports
|
|
|
|
Over time you will see that there are some ports which are more likely
|
|
to be open, even if the network filters your traffic. Some well known
|
|
ports for this are:
|
|
|
|
* 80: regular http traffic
|
|
* 53: DNS, uses UDP by default, but TCP is also part of the standard
|
|
* 443: usually has encrypted https traffic
|
|
* 783: smtp submission port for sending out emails
|
|
|
|
Of course, if the filtering uses deep packet inspection, this will
|
|
fail, but then there are other solutions for that... stay tuned!
|
|
|
|
|
|
## 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).
|