Are IPv4 ports separated from IPv6 ports?

Is it possible for a host to have different open ports for IPv4 and IPv6 stack? For example, is it feasible to have the port 22 open only for IPv6 and not for IPv4 and vice versa? Also when I tried to block a port only for IPv6 it had no effect:

ip6tables -A INPUT -p tcp --dport 22 -j REJECT

Solution 1:

Yes, definitely. In fact, there is even a difference between a port on TCP vs that same port on UDP on the same IPv6 address, which is why you specify -p tcp as well.

IPv4 is a different mechanism than IPv6 and they have separate interfaces, with separate IP addresses with separate ports. In fact, you cannot use IPv6 to connect to an IPv4 address unless you have some kind of intermediator in between that does it for you. But such intermediator would simply accept IPv4 then bridge that connection to a new IPv6.

It would also be the same case if you have 2 network cards, both having a different IP address. You would then also have to specify the correct IP address.

But it basically all boils down to this: you have a program that hosts a server, look in its configuration what ports it open, and block according to its ipv4, ipv6 and port usage on either or both tcp or udp.

Solution 2:

Yes, they’re entirely separate. In POSIX, you create sockets using the socket(2) system call, and you pass AF_INET or AF_INET6 to it to choose between IPv4 and IPv6, respectively. Such sockets can use the same port numbers without any interference.

However, Linux has the feature where an IPv6 socket listening on a certain port will also get IPv4 traffic with the source address mapped into the IPv6 address. This can be switched off by setting IPV6_V6ONLY.

Solution 3:

In short

Yes

Note that application doesn't have to bind to both IPv4 and IPv6 so you could do this even without IP tables.

Look at the ListenAddress directive in your sshd config or other application.

Not that you'd want to do this, but it is entirely possible to have an ssh server listening on TCP/IP6 port 22 while a web server listens on TCP/IP4 port 22.

iptables and ip6tables are configured separately.

Note as pointed out in the comments, IP itself does not have ports, but some of the transport protocols most commonly used with it, TCP and UDP, do have ports. This is why iptables requires something like -p tcp before you can filter by port, otherwise port is meaningless.