iptables rules for cups printer discovery
I'm wondering whether there are iptables rules that will permit cups snmp printer discovery to operate without creating a serious security risk.
Cups printer discovery works by sending a broadcast from a high numbered port (a different one each time) to the snmp port (161) of every device on the local network. Printers are then supposed to send back replies from their port 161 to the high numbered port on the computer that the broadcast came from. Since the replies are to a broadcast, they are not treated as ESTABLISHED or RELATED by iptables rules. My question is really whether there is some way of identifying replies to such a broadcast, so that I don't have to let through all udp packets from port 161 of any machine on the local network to all high numbered ports on my machine, at any time, which looks as if it might be unsafe, especially when I can't be certain that the local network is absolutely secure against break-ins.
Thanks.
Quoted 3 lines · Stephen Isard
I'm wondering whether there are iptables rules that will permit cups snmp printer discovery to operate without creating a serious security risk.
CUPS does not actually use SNMP, does it? The way I have seen its output are regular UDP transmissions from and to port 631, without any replies (much like most NBT packets).
-d 192.168.0.255 -p udp --dport 631
Quoted 5 lines · Jan Engelhardt jengelh-at-medozas.de |netfilter|
CUPS does not actually use SNMP, does it? The way I have seen its output are regular UDP transmissions from and to port 631, without any replies (much like most NBT packets).
-d 192.168.0.255 -p udp --dport 631
It does that too, but yes, recent (I'm not sure since when) cups also uses snmp. The port 631 transmissions are for finding other computers that share their printers. Snmp is used for finding standalone printers with their own ip addresses on your local network. See http://www.cups.org/documentation.php/network.html#SNMP
Quoted 6 lines · Stephen Isard
Quoted 4 lines · Jan Engelhardt jengelh-at-medozas.de |netfilter|
CUPS does not actually use SNMP, does it? The way I have seen its output are regular UDP transmissions from and to port 631, without any replies (much like most NBT packets).
Quoted 6 lines
Quoted 1 line
-d 192.168.0.255 -p udp --dport 631
It does that too, but yes, recent (I'm not sure since when) cups also uses snmp. The port 631 transmissions are for finding other computers that share their printers. Snmp is used for finding standalone printers with their own ip addresses on your local network.
Makes sense. It is only natural that the reply packet is not associated with the original connection, because the sender address is not 192.168.0.255. You could write a layer-4 connection tracker that observes packets to 192.168.0.255:631, verifies that they are of SNMP nature (or not verify at all and Just Do It), and then instantiate a new expectation, therefore making replies matching -m conntrack --ctstate RELATED.
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 9 lines · Jan Engelhardt jengelh-at-medozas.de |netfilter|
Quoted 5 lines · Stephen Isard
Quoted 2 lines
You could write a layer-4 connection tracker
Maybe you could, but I'm not sure that I could :-) At what level would this operate? Kernel?
Kernel. Parallel to things like
nf_conntrack_ftp.
Mm. I'm sure it would be educational to try, but I think I may just do my printer discovery by social engineering - ask the departmental computing officers for the ip numbers.
Quoted 1 line · Stephen Isard
I'm wondering whether there are iptables rules that will permit cups snmp printer discovery to operate without creating a serious security risk.
I wonder if you could not use the "recent" match extension to ""remember when a cups broadcast has gone through. If there is a reply packet from a unicast IP going back to a unicast host that has recently sent a broadcast packet.
I suppose you would have to set / update a recent list every time a unicast source sends a broadcast (high -> low port) to the service in question. That way you could allow the reply (low -> high port) from a unicast source to the unicast destination that recently sent a broadcast.
This type of rule should help by not having to allow all traffic from the source port through.
Grant. . . .
Quoted 8 lines · Grant Taylor
Quoted 3 lines · Stephen Isard
I'm wondering whether there are iptables rules that will permit cups snmp printer discovery to operate without creating a serious security risk.
I wonder if you could not use the "recent" match extension to ""remember when a cups broadcast has gone through.
Nope that would not work because the source and destination addresses are flipped on return packets, and then you even have the .255 thing.
That smells like a feature request - me to the rescue! (I think that would be much preferable over having a ton of connection helpers)
Quoted 1 line · Jan Engelhardt
Nope that would not work because the source and destination addresses are flipped on return packets, and then you even have the .255 thing.
Ah. I forgot about the fact that recent only dealt with the source IP and that you could not specify source or dest in the set / update / check parameters to recent. :(
Quoted 1 line
That smells like a feature request - me to the rescue! (I think that would be much preferable over having a ton of connection helpers)
*nod* It would be very nice to be able to specify whether or not the given recent list is suppose to use the source or dest IP. I wonder if it would be possible to add a new flag that indicates act on the destination IP. That way it would be possible to default to just source like it currently is but still be able to specify dest when desired. I suppose to make things clean it would be better to add a flag to indicate source and use that flag as the default when no flag is specified.
Grant. . . .
Quoted 7 lines · Grant Taylor
Quoted 2 lines · Jan Engelhardt
Nope that would not work because the source and destination addresses are flipped on return packets, and then you even have the .255 thing.
Ah. I forgot about the fact that recent only dealt with the source IP and that you could not specify source or dest in the set / update / check parameters to recent. :(
You can specify --rsrc/--rdest (patch just merged that documents them). But somehow I am not sure...
-A INPUT -d 192.168.0.255 -p udp --dport 161 -m recent --name snmp --rsrc --set
-A OUTPUT -p udp --sport 161 -m recent --name snmp --rdest --rcheck
Try?
Quoted 1 line · Jan Engelhardt
You can specify --rsrc/--rdest (patch just merged that documents them).
So the options did exist, but they were undocumented?
Review
Quoted 4 lines
(quoted diff) +0
-3-A INPUT -d 192.168.0.255 -p udp --dport 161 -m recent --name snmp --rsrc --set -A OUTPUT -p udp --sport 161 -m recent --name snmp --rdest --rcheck
*nod* That is the general idea.
So I take it that the default is --rsrc but you can specify --rdest and act on the destination IP for all options of recent, i.e. --update and --remove too?
Grant. . . .
Quoted 4 lines · Grant Taylor
Quoted 1 line · Jan Engelhardt
You can specify --rsrc/--rdest (patch just merged that documents them).
So the options did exist, but they were undocumented?
Correct. Blame it on ...
commit f33c46140f0e0a230aba5d739ce40cb14e066b13
Author: Jonas Berlin <[email protected]> Date: Fri Apr 1 06:54:23 2005 +0000
Quoted 10 lines
Review
Quoted 4 lines
(quoted diff) +0
-3-A INPUT -d 192.168.0.255 -p udp --dport 161 -m recent --name snmp --rsrc --set -A OUTPUT -p udp --sport 161 -m recent --name snmp --rdest --rcheck*nod* That is the general idea.
So I take it that the default is --rsrc but you can specify --rdest and act on the destination IP for all options of recent, i.e. --update and --remove too?
Right. It seems that when done cleverly, you can mix --rsrc and --rdest for a given --name even.
On Thu, 14 Aug 2008, Jan Engelhardt jengelh-at-medozas.de |netfilter| wrote:
...
Quoted 10 lines
You can specify --rsrc/--rdest (patch just merged that documents them). But somehow I am not sure...
(quoted diff) +0
-4-A INPUT -d 192.168.0.255 -p udp --dport 161 -m recent --name snmp --rsrc --set -A OUTPUT -p udp --sport 161 -m recent --name snmp --rdest --rcheckTry?
I've tried, but my system doesn't seem to like --rsrc/--rdest.
Just to make sure I'm not completely confused, you've made a typo and reversed INPUT and OUTPUT, right? That is, I think we want --set to happen on output when we broadcast to the destination port 161.
After making that adjustment, when I try to load the rules, I get an error message:
Applying iptables firewall rules: iptables-restore v1.3.5: Unknown arg `--rsrc'
This is on Scientific Linux 5.2 with its latest kernel, 2.6.18-92.1.10.el5. So do I need a much more recent kernel? If so, I can set up a virtual machine for a test. Can you recommend a reasonably lightweight distribution that would serve? Obviously it needs a fairly recent cups as well. The latest KNOPPIX?
Can you comment on my understanding of the "recent" rules as set out below?
"-m recent --set" stores an address, just as an address, not marked as source or dest. This address is taken from either the source or destination address of a packet, depending on the use of --rsrc/--rdest. In order for the rules to do what we want them to, the address has to include the port number as well as the ip address.
"-m recent --rcheck" looks to see whether the stored address is the same as either the source or destination address on a packet, depending on the use of --rsrc/--rdest.
If that is correct and the port is stored as part of the address, then the logic of your rules looks good to me. If the port isn't stored, then all we are storing is the address of our own interface and we match any packet coming in from a port 161. That's still an improvement because we only let in the packets during a relatively short window after a broadcast, but it's not quite what we'd really like.
By the way, googling around for help on this issue, I came across a forum thread from 2004 discussing the same problem with respect to samba. Evidently samba uses the same broadcast/response tactic. Unfortunately the thread seemed to peter out without resolution. But is there an approved firewall setup for samba these days? (I don't use samba myself.) If so, maybe we could adapt it.
Quoted 8 lines · Stephen Isard
Quoted 6 lines · Jan Engelhardt jengelh-at-medozas.de |netfilter|
You can specify --rsrc/--rdest (patch just merged that documents them). But somehow I am not sure...
-A INPUT -d 192.168.0.255 -p udp --dport 161 -m recent --name snmp --rsrc --set
Quoted 7 lines
Quoted 4 lines
-A OUTPUT -p udp --sport 161 -m recent --name snmp --rdest --rcheck
Try?
I've tried, but my system doesn't seem to like --rsrc/--rdest. Applying iptables firewall rules: iptables-restore v1.3.5: Unknown arg `--rsrc'
Oh it's --rsource not --rsrc. But --rdest is correct.
Quoted 4 lines
Just to make sure I'm not completely confused, you've made a typo and reversed INPUT and OUTPUT, right? That is, I think we want --set to happen on output when we broadcast to the destination port 161.
Oh yeah, depends on which side you are looking at. I was assuming, from what you told me, that a standalone printer spews SNMP to a broadcast address and a Linux box replies, but now it looks like that hardly makes sense ;-)
Quoted 2 lines
This is on Scientific Linux 5.2 with its latest kernel, 2.6.18-92.1.10.el5. So do I need a much more recent kernel?
Nope, this is fine.
Quoted 2 lines
Can you recommend a reasonably lightweight distribution that would serve? Obviously it needs a fairly recent cups as well. The latest KNOPPIX?
I am of course biased, so you will only hear openSUSE 11 from me. The default minimal install is like ~500 M but one can strip it down to like 300 (fits on a CF card!) by throwing out unneeded pkgs and translation files.
Quoted 9 lines
Can you comment on my understanding of the "recent" rules as set out below?
"-m recent --set" stores an address, just as an address, not marked as source or dest. This address is taken from either the source or destination address of a packet, depending on the use of --rsrc/--rdest. In order for the rules to do what we want them to, the address has to include the port number as well as the ip address.
Correct.
Quoted 3 lines
"-m recent --rcheck" looks to see whether the stored address is the same as either the source or destination address on a packet, depending on the use of --rsrc/--rdest.
Correct.
Quoted 1 line
If that is correct and the port is stored as part of the address,
The port is not stored, since in common sense, it is not part of the address. An (address,port) tuple is however not stored.
Quoted 7 lines
then the logic of your rules looks good to me. If the port isn't stored, then all we are storing is the address of our own interface and we match any packet coming in from a port 161. That's still an improvement because we only let in the packets during a relatively short window after a broadcast, but it's not quite what we'd really like.
Quoted 5 lines
By the way, googling around for help on this issue, I came across a forum thread from 2004 discussing the same problem with respect to samba. Evidently samba uses the same broadcast/response tactic. Unfortunately the thread seemed to peter out without resolution. But is there an approved firewall setup for samba these days? (I don't use samba myself.) If so, maybe we could adapt it.
If by approved you mean what distributions use, then that's something simple along the lines of
-A INPUT -p udp --dport 137:139 -j ACCEPT
Quoted 1 line
Oh it's --rsource not --rsrc. But --rdest is correct.
Ok! Now I find the printers. (I also had to stick -j ACCEPT at the ends of the lines. You were probably taking that for granted.)
Quoted 4 lines
I was assuming,
from what you told me, that a standalone printer spews SNMP to a broadcast address and a Linux box replies, but now it looks like that hardly makes sense ;-)
No, the printers don't spew. They sit there demurely waiting for broadcasts.
Quoted 2 lines
The port is not stored, since in common sense, it is not part of the address. An (address,port) tuple is however not stored.
Assuming you really mean that last "not", then my description
Quoted 6 lines
Quoted 6 lines
If the port isn't
stored, then all we are storing is the address of our own interface and we match any packet coming in from a port 161. That's still an improvement because we only let in the packets during a relatively short window after a broadcast, but it's not quite what we'd really like.
seems to apply. So if a bad guy knew how take advantage of udp broadcasts to arbitrary high numbered ports, he could sit there waiting for a cups broadcast and then send his evil packets from his port 161 to whichever of my ports he wanted. Fortunately, such broadcasts will not be very frequent, since once the printers are discovered, there is no need to rediscover them until something changes. But still it would be better to match the broadcast port number. A new feature?
Quoted 5 lines
Quoted 1 line
But is there an approved firewall setup for samba these days? (I don't use samba myself.) If so, maybe we could adapt it.
If by approved you mean what distributions use, then that's something simple along the lines of
-A INPUT -p udp --dport 137:139 -j ACCEPT
Hmm. That doesn't seem to address the issue at all. Maybe samba has changed, or I was misunderstanding.
Thanks for your help!
Quoted 1 line · Stephen Isard
Ok! Now I find the printers. (I also had to stick -j ACCEPT at the ends of the lines. You were probably taking that for granted.)
Good!
Quoted 2 lines
Assuming you really mean that last "not", then my description
seems to apply. So if a bad guy knew how take advantage of udp broadcasts to arbitrary high numbered ports, he could sit there waiting for a cups broadcast and then send his evil packets from his port 161 to whichever of my ports he wanted. Fortunately, such broadcasts will not be very frequent, since once the printers are discovered, there is no need to rediscover them until something changes. But still it would be better to match the broadcast port number. A new feature?
If you are worried about someone else spoofing an IP in your recent list, look in to the --rttl option to have the recent list remember the TTL values of packets and require them to be the same. This way if some jerk off who is more hops away from you is trying to pretend to be you, his traffic will appear to be at a different TTL than yours. This is not fool proof, but it will sure help reduce the risk of exposure that you are referring to.
Grant. . . .
Quoted 1 line · Grant Taylor
If you are worried about someone else spoofing an IP in your recent list, look in to the --rttl option to have the recent list remember the TTL values of packets and require them to be the same. This way if some jerk off who is more hops away from you is trying to pretend to be you, his traffic will appear to be at a different TTL than yours. This is not fool proof, but it will sure help reduce the risk of exposure that you are referring to.
Thanks, Grant.
I don't think any spoofing is required. I had in mind someone who had gained access to my local network (not simple, but not out of the question) and who was essentially pretending to be a printer by sending packets from his port 161 immediately following a cups broadcast. I'm not worried about people without access to the local network because they wouldn't see the broadcast that opens the "recent" time window.
Am I fussing over nothing here? Is it clear that much harm can be done by getting upd packets through my firewall to arbitrary high numbered ports? Denial of service is probably not a big issue because of the short time window.
Quoted 1 line · Stephen Isard
Thanks, Grant.
*nod*
Quoted 1 line
I don't think any spoofing is required. I had in mind someone who had gained access to my local network (not simple, but not out of the question) and who was essentially pretending to be a printer by sending packets from his port 161 immediately following a cups broadcast. I'm not worried about people without access to the local network because they wouldn't see the broadcast that opens the "recent" time window.
Um, if they have gotten a system in to your LAN I think you have bigger problems. If this is a real concern, I'd suggest that you look in to 802.1x (port) authentication.
Also remember that you can adjust the length of time for the "recent" window. You can probably also mitigate the window by looking for the closing connection (at least with TCP) and do a --remove to clear the connection from the recent list.
Quoted 1 line
Am I fussing over nothing here? Is it clear that much harm can be done by getting upd packets through my firewall to arbitrary high numbered ports? Denial of service is probably not a big issue because of the short time window.
I don't think you are fussing over nothing, but you certainly should consider other things first. Now if you have already considered the other things, then by all means, continue discussing here. ;)
Grant. . . .
Quoted 1 line
Um, if they have gotten a system in to your LAN I think you have bigger problems. If this is a real concern, I'd suggest that you look in to 802.1x (port) authentication.
This is a large university department where students and visitors use the lan. The computing officers are highly competent and doing their best to provide security, but, as you know, it's a constant battle.
Quoted 1 line
Also remember that you can adjust the length of time for the "recent" window.
Right.
Quoted 1 line
You can probably also mitigate the window by looking for the closing connection (at least with TCP)
This particular case involves udp.
Thanks for your advice.
Quoted 1 line · Stephen Isard
This is a large university department where students and visitors use the lan. The computing officers are highly competent and doing their best to provide security, but, as you know, it's a constant battle.
Sounds like it is time to divide the different access networks up in to smaller pieces and route between them. Make sure that you do some sanity checking (filtering) as part of the routing process too. Try to help prevent spoofing as close to the edge as possible. ;)
Quoted 1 line
This particular case involves udp.
*nod*
Quoted 1 line
Thanks for your advice.
You are welcome.
Grant. . . .
Quoted 3 lines · Stephen Isard
"-m recent --set" stores an address, just as an address, not marked as source or dest. This address is taken from either the source or destination address of a packet, depending on the use of --rsrc/--rdest. In order for the rules to do what we want them to, the address has to include the port number as well as the ip address.
"-m recent --rcheck" looks to see whether the stored address is the same as either the source or destination address on a packet, depending on the use of --rsrc/--rdest.
The default is to use --rsource if neither --rsource or --rdest are specified.
Quoted 1 line
By the way, googling around for help on this issue, I came across a forum thread from 2004 discussing the same problem with respect to samba. Evidently samba uses the same broadcast/response tactic. Unfortunately the thread seemed to peter out without resolution. But is there an approved firewall setup for samba these days? (I don't use samba myself.) If so, maybe we could adapt it.
There is now a connection tracking helper in the kernel specifically meant to help some NetBIOS traffic.
Grant. . . .