Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPv6 is not supported under this link-layer type #83

Open
BitBlit88 opened this issue Mar 20, 2022 · 6 comments
Open

IPv6 is not supported under this link-layer type #83

BitBlit88 opened this issue Mar 20, 2022 · 6 comments

Comments

@BitBlit88
Copy link

Hello,

I tried to add IPv6 support to my knockd service using knockd version 0.8.

Here is my /etc/knockd.conf:
[options]
UseSyslog
Interface = venet0

[SSH]
sequence = 1234,5678,9012
seq_timeout = 5
start_command = ufw allow from %IP% to any port 22 proto tcp
tcpflags = syn
cmd_timeout = 10
stop_command = ufw delete allow from %IP% to any port 2 proto tcp

and ifconfig:
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 1000 (Local Loopback)
RX packets 632682 bytes 121494481 (121.4 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 632682 bytes 121494481 (121.4 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

venet0: flags=211<UP,BROADCAST,POINTOPOINT,RUNNING,NOARP> mtu 1500
inet 127.0.0.1 netmask 255.255.255.255 broadcast 0.0.0.0 destination 127.0.0.1
inet6 2a01:xxx:xxx:xxx:xxx:xxx:xxx:xxx prefixlen 128 scopeid 0x0
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 0 (UNSPEC)
RX packets 80663 bytes 6564767 (6.5 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 37029 bytes 15021778 (15.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

venet0:0: flags=211<UP,BROADCAST,POINTOPOINT,RUNNING,NOARP> mtu 1500
inet 81.yyy.yyy.yyy netmask 255.255.255.255 broadcast 81.yyy.yyy.yyy destination 81.yyy.yyy.yyy
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 0 (UNSPEC)

If I try to knock via IPv6 I get the following message in syslog:
knockd[23619]: IPv6 is not supported under this link-layer type

Ipv4 doesn't work neither with this configuration.

If I change the config to

[options]
UseSyslog
Interface = venet0:0

Ipv4 works but Ipv6 doesn't because venet0:0 is only bound to an IPv4 address.

How could I get IPv4 and IPv6 get working?

@TDFKAOlli
Copy link
Contributor

TDFKAOlli commented Mar 20, 2022

Hi @BitBlit88 ,

the problem output comes from here:

} else if(ip->ip_v == 6) {

That means that the sniffer detected an IPv6 IP packet and now tries to handle it. But there is an issue with setting 'ip6' which is checked in the very next line.

if(ip6 == NULL) {

Here it is set:

ip6 = (struct ip6_hdr*)(packet + sizeof(struct ether_header));

So that the case of 'if(lltype == DLT_EN10MB)'. Anyhow there are two other cases where 'ip6' is not properly set in the 'elseif' cases here:
ip = (struct ip*)((u_char*)packet + 16);

and here:
ip = (struct ip*)((u_char*)packet);

I guess you now have one of the ifelse-cases and thereby ip6 pointer is not properly set and knockd bails out with the error logile you have seen.

I fixed it in my fork here:
https://github.com/TDFKAOlli/knock/blob/58a2ed4585af7c7bd9b19bfd82e3f2fa522c0a42/src/knockd.c#L1662
and here:
https://github.com/TDFKAOlli/knock/blob/58a2ed4585af7c7bd9b19bfd82e3f2fa522c0a42/src/knockd.c#L1666
but I couldn't test it, cause I never run into those lines. Anyhow you can try to patch your version and test or create a pull request for this repository.

@BitBlit88
Copy link
Author

Hi @TDFKAOlli,

your fix works very well.
But I have still the problem that either IPv4 or IPv6 works but not both together.
Unfortunately my provider forces to set IPv6 on interface "venet0:0" and IPv4 on interface "venet0".
I think knockd can't listen on two interfaces. The only solution I see is running two instances of knockd listening on different interfaces or some kind of network bonding.

@TDFKAOlli
Copy link
Contributor

@BitBlit88 ,
good to head it is working 😄
Can you create a pull request? I guess it can help others too.
And yes, multiple interface support is not yet there. I thought in the past about trying to add it, but in the end it seems I didn't needed it enough to start working on it 😉 . But I guess your proposal of running two knockd processes would work.

@TDFKAOlli
Copy link
Contributor

TDFKAOlli commented Mar 20, 2022

Hey @BitBlit88 ,
I just read this about pcap:

pcap_open_live() is used to obtain a packet capture handle to look at packets on the network. device is a string that specifies the network device to open; on Linux systems with 2.2 or later kernels, a device argument of "any" or NULL can be used to capture packets from all interfaces.

Written here: https://www.tcpdump.org/manpages/pcap_open_live.3pcap.html

So it might work that you simply use "any" as interface in the knockd config. (Or you add a config to use any in pcap_open_live()).
The drawback is, it really listens then to any interface, not only the the two interfaces you want it to listen too. But that might be o.k.

EDIT: Ah, no, one more change is needed, here:

if((strcmp(ifa->ifa_name, o_int) == 0) && (ifa->ifa_addr->sa_family == AF_INET || (ifa->ifa_addr->sa_family == AF_INET6 && !o_skipIpV6))) {

This is fetching the IP-address of the interface, but checks for the interface name. I guess it should be changed so it matched either the interface name or "any" and in both cases fetches the IP-address.

@BitBlit88
Copy link
Author

Hi @TDFKAOlli,

you are great! Thanks for pointing this out.

I change the line to
if((strcmp(ifa->ifa_name, o_int) == 0 || strcmp("any", o_int) == 0) && (ifa->ifa_addr->sa_family == AF_INET || (ifa->ifa_addr->sa_family == AF_INET6 && !o_skipIpV6))) {

and modified "knockd.conf" to
Interface = any

Now both IPv4 and Ipv6 works.
I will cherry pick your changes with the above code and make a pull request.

@TDFKAOlli
Copy link
Contributor

No prob, came to my mind just now. Before I thought about parsing a list of interfaces and then spawning several knockds for it so to handle each interface by an own thread... This "any" is much more simpler and would do in most cases I guess. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants