Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[Solved] Q: How to use a raw socket to send hand crafted...
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Networking & Security
View previous topic :: View next topic  
Author Message
therealjrd
Tux's lil' helper
Tux's lil' helper


Joined: 18 May 2006
Posts: 120

PostPosted: Thu Jul 15, 2021 10:25 pm    Post subject: [Solved] Q: How to use a raw socket to send hand crafted... Reply with quote

This is likely not really a gentoo issue, but y'all have been so helpful with other questions I've had, I bet somebody here will have useful ideas.

I have a wierd use case for which I'm trying to write a little software widget. I have some devices on my network which ignore DHCP's handed out DNS server address, and just go straight to google. The names they need to resolve are internal only, google won't resolve them. I hacked my firewall such that if it sees DNS traffic from those devices to google, those packets get redirected to my internal server. That works for some of them, but some reject the reply, because it comes from an internal server, not 8.8.8.8. So to handle those, I've written a little thing which receives the DNS traffic, rewrites the sender address to be itself, forwards it to my internal DNS, captures the reply, rewrites that sender address to make it look like it came from google, and sends it back to the device. That's the background to this little saga.

The problem I have is that when my widget sends its rewritten packet to my DNS server, nothing happens. Wireshark reveals that the packet arrives. It appears to have all the right values, including the IP and UDP headers. I'm setting the checksums. The widget uses a (PF_INET, SOCK_RAW, IPPROTO_UDP) socket for both sending and receiving. I'm setting sockopt IP_HDRINCL to 1. I've tried powerdns and dnsmasq on the receiving end, on the off chance that something in the app layer is silently throwing input on the floor, but neither one sees anything incoming. It's acting like something in the network stack is disliking something about my packet, and refusing to deliver it.

Granted this is a somewhat twisted solution. I thought it would be a quick hack, but I've spent a day on it, and I'm still missing something. I'd be happy to hear about a better overall solution for my use case, but I'd also like to understand why my little hack isn't working.

Thanks in advance for any hints.


Last edited by therealjrd on Fri Jul 16, 2021 6:45 pm; edited 1 time in total
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Thu Jul 15, 2021 10:55 pm    Post subject: Reply with quote

Try to find out where your UDP packets get lost. A good point to start is
Code:
netstat -s -u

Run this command, send a DNS request and check whether the packet counters increase (UDP packets received, UDP packet receive errors).

You may want to read this article: https://www.programmersought.com/article/22141065280/

Are there any messages in the log files of your DNS servers?
Back to top
View user's profile Send private message
therealjrd
Tux's lil' helper
Tux's lil' helper


Joined: 18 May 2006
Posts: 120

PostPosted: Fri Jul 16, 2021 1:56 am    Post subject: Reply with quote

mike155 wrote:
Try to find out where your UDP packets get lost. A good point to start is
Code:
netstat -s -u



Thank you!

That command reveals UDP receive errors which correlate exactly to what I'm sending.

I read the referenced article. Some parts don't seem relevant, but the bit about checksums does. My current theory is that I mis-transcribed the 1's complement checksum algorithm, and am generating bogus values there. I can follow up on that tomorrow.
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21633

PostPosted: Fri Jul 16, 2021 2:01 am    Post subject: Reply with quote

There may be an easier solution. A Linux firewall can not only filter traffic, it can also rewrite the headers. A common use case for home users is to have the firewall NAT outbound traffic so that it appears to come from their single public IP, rather than the private range IP assigned to the individual hosts on the LAN. Netfilter can also change the destination address, so that traffic originally destined for that public IP is instead further routed to a specific internal host. Your use case is a bit backward of that, but the principals should hold. I think you could use the firewall to DNAT traffic that was destined for Google to instead go to your internal host, then SNAT the responses to claim to be from Google. If you do this, and it works, then the Linux kernel would handle the details around checksums.

Or you could raise a support case with the vendor who sold you garbage that doesn't understand DHCP properly. ;) If they can't even get that right, I wouldn't be surprised if they managed to include at least a few security vulnerabilities too.
Back to top
View user's profile Send private message
pietinger
Moderator
Moderator


Joined: 17 Oct 2006
Posts: 4149
Location: Bavaria

PostPosted: Fri Jul 16, 2021 4:06 am    Post subject: Reply with quote

Hu wrote:
I think you could use the firewall to DNAT traffic that was destined for Google to instead go to your internal host, then SNAT the responses to claim to be from Google.

I also think you could use DNAT, but usually you dont need an additional SNAT-rule, because all the answer packets will be also rewritten from the dnat-netfilter-rule (because netfilter uses stateful inspection).

You would need an extra SNAT if you want doing something like this: https://serverfault.com/questions/205040/accessing-the-dnatted-webserver-from-inside-the-lan
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Fri Jul 16, 2021 11:30 am    Post subject: Reply with quote

therealjrd wrote:
That command reveals UDP receive errors which correlate exactly to what I'm sending.


When your widget talks to the DNS server: why do you want to calculate the checksum in your program? Use a UDP datagram socket and let the kernel calculate the checksum.

Code:
dns_socket_fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
Back to top
View user's profile Send private message
therealjrd
Tux's lil' helper
Tux's lil' helper


Joined: 18 May 2006
Posts: 120

PostPosted: Fri Jul 16, 2021 6:44 pm    Post subject: Reply with quote

mike155 wrote:
therealjrd wrote:
That command reveals UDP receive errors which correlate exactly to what I'm sending.


When your widget talks to the DNS server: why do you want to calculate the checksum in your program? Use a UDP datagram socket and let the kernel calculate the checksum.

Code:
dns_socket_fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );


, , , except that part of the use case is that the eventual reply packet, which goes back to the errant device, needs to have a sender address of google (8.8.8.8 or whatever). I couldn't find a way to do that sticking strictly to regular UDP socket semantics. Since I was going to need to rewrite some headers, I just wrote it as a man in the middle which rewrites in both directions.

I finally figured out what I was doing wrong. The simple mistake was that I had muffed the size to the checksum of the IP header. The trickier one was that when I read the spec the first time, I misunderstood how the UDP pseudo header needs to be set up. It took me some more headscratching with wireshark, and reading the spec and examples some more, to get it right. So now my widget is working. Yay!

Hu, in principle you're right about the stupid vendors. I'm just not optimistic about them paying attention, or caring. I've found 2 vendors so far which do this. I got on the phone with one of their support people. He seemed not to understand what I was talking about, or why it was a bug. He refused to even open a case.

Part of why I have my network set up the way it is, is because of the security concern you cite. Some of these devices are IP cameras. I shudder to think what they might be doing if I gave them access to the rest of the network :)

Thanks to all who chimed in. Setting the title to "Solved".
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Networking & Security All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum