1

I'm writing a script to extract information from BusyBox v1.25.1/Linux 2.6.36/router where the user can simply run the script and copy/paste the output into a submission form to request support. The script it's essentially a list of commands like route, ifconfig, etc. Because of the busybox implication I'm restricted to /bin/sh.

I'm trying to find a smart way to automatically mask all the public IP addresses only from the output. Replace the full IP would be already good but if it's possible I would be looking for a command to pipe at the end of each command (even an internal function) to simply replace let's say the first two octects e.g. 80.80.80.80 with XX.XX.80.80

A nice to have feature would be to replace the same number of digits to retain formatting where possible. e.g.

8.8.8.8=X.X.X.X 80.80.8.8=XX.XX.X.X 180.180.80.8=XXX.XXX.XX.X

practical example:

root@router:/proc# route | filtering-goes-here Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface XX.XX.168.1 * 255.255.255.255 UH 0 0 0 vlan2 172.16.9.0 * 255.255.255.0 U 0 0 0 br1 10.10.9.0 * 255.255.255.0 U 0 0 0 br0 10.114.126.0 * 255.255.254.0 U 0 0 0 tun11 XX.XX.168.0 * 255.255.252.0 U 0 0 0 vlan2 10.10.0.0 * 255.255.0.0 U 0 0 0 tinc 127.0.0.0 * 255.0.0.0 U 0 0 0 lo default cpc86269 0.0.0.0 UG 0 0 0 vlan2

Thanks!!

rs232
  • 105
  • 1
  • 10

1 Answers1

1

Does a sed script like this work for you?

$ cat filter.sed
s|\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\)|___\1___\2___\3___\4|g
s|___[0-9]|___X|g
s|___X[0-9]|___XX|g
s|___XX[0-9]|___XXX|g
s|___||g

Here is an example run,

$ echo "111.22.3.44" | sed -f filter.sed
XXX.XX.X.XX

This is going to convert all IP addresses of the form a.b.c.d into equivalent width x.x.x.x pattern. If you need to skip some IP addresses those would need exclusion rules in the script.

If the ___ pattern is part of your possible output in the context used here, you would need to change to a different 'context' that is not possible in the input to the script.

Update: for public IP masking
Try this sed script replacement to the above basic one.

s|\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)|__#\1.\2.\3.\4|g
s|#0\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|0\1|g
s|#10\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|10\1|g
s|#127\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|127\1|g
s|#255\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|255\1|g
s|#\(22[4-9]\)\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|\1\2|g
s|#\(23[0-8]\)\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|\1\2|g
s|#169\.254\(\.[0-9]\+\.[0-9]\+\)|169.254\1|g
s|#192\.168\(\.[0-9]\+\.[0-9]\+\)|192.168\1|g
s|#\(172\.1[6789]\)\(\.[0-9]\+\.[0-9]\+\)|\1\2|g
s|#\(172\.2[0-9]\)\(\.[0-9]\+\.[0-9]\+\)|\1\2|g
s|#\(172\.3[01]\)\(\.[0-9]\+\.[0-9]\+\)|\1\2|g
s|__#\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\)|___\1___\2___\3___\4|g
s|___[0-9]|___X|g
s|___X[0-9]|___XX|g
s|___XX[0-9]|___XXX|g
s|___||g
s|__||g

Note: This will also x-out the netmasks with one exception. I've not added 240.0.0.0 to the list.

Update2: If you want to just mask the first IP-address on each line
This is for a route output case where the first column is IP addresses.
Replace the first line in the updated sed script with,

s|^\(\s*\)\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)|\1__#\2.\3.\4.\5|g

On OPs suggestion, leaving also the mask-for-private-IPs script here

# Modified version that limits to first IP on each line prefixed with whitespace.
s|^\(\s*\)\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)|\1___#\2.\3.\4.\5|g
# Basic version that operates on all IP strings in the input.
#s|\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)|___#\1.\2.\3.\4|g
#
s|\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)|___#\1.\2.\3.\4|g
s|___#0\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|___0\1|g
s|___#10\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|___10\1|g
s|___#127\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|___127\1|g
s|___#255\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|___255\1|g
s|___#224\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|___224\1|g
s|___#\(22[4-9]\)\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|___\1\2|g
s|___#\(23[0-8]\)\(\.[0-9]\+\.[0-9]\+\.[0-9]\+\)|___\1\2|g
s|___#169\.254\(\.[0-9]\+\.[0-9]\+\)|___169.254\1|g
s|___#192\.168\(\.[0-9]\+\.[0-9]\+\)|___192.168\1|g
s|___#\(172\.1[6789]\)\(\.[0-9]\+\.[0-9]\+\)|___\1\2|g
s|___#\(172\.2[0-9]\)\(\.[0-9]\+\.[0-9]\+\)|___\1\2|g
s|___#\(172\.3[01]\)\(\.[0-9]\+\.[0-9]\+\)|___\1\2|g
s|___\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\)|___\1___\2___\3___\4|g
s|___[0-9]|___X|g
s|___X[0-9]|___XX|g
s|___XX[0-9]|___XXX|g
s|___#||g
s|___||g
nik
  • 7,100
  • 2
  • 25
  • 30
  • I was trying to restrict the masking to public IP addresses only. – rs232 Mar 15 '20 at 10:24
  • I've updated with a more detailed `sed` version in my answer. If you don't want the `netmask` column to be 'masked-out' you can tweak the first line of the script to make the IP address selection more biased. I am adding one more update for that now. – nik Mar 15 '20 at 10:49
  • 1
    This is impressive :-o The only thing is: it is applying the mask to private IPs and not public as far as I can tell? e.g. my public router IP is left exposed, so the logic should be reversed, also no need to mask netmasks... – rs232 Mar 15 '20 at 13:18
  • `:-)` My bad! I was trying out the inverse since it was easier to check and lost-track of that twist. Try the fixed version now. – nik Mar 15 '20 at 15:13
  • wow spot on !!! – rs232 Mar 15 '20 at 15:20
  • 1
    P.S. I would leave here documented even your prev version as somebody might want to filter private IPs only. – rs232 Mar 15 '20 at 15:44
  • Done. Have also sneaked in a fix for the Multicast IPs which I overlooked earlier. – nik Mar 15 '20 at 15:49
  • Since you're so fast... :-D I'm wondering if it's possible to apply the masking filters you've created (public range) to the first two octects only? so `81.82.83.84` would be masked `XX.XX.83.84` Sometimes you do want to know the ending IP and knowing at least the last two octects can really help without compromising the privacy. Thanks!! – rs232 Mar 16 '20 at 07:40
  • Sure. Try commenting out the last two lines with `X` in the sed script. – nik Mar 16 '20 at 08:03
  • I'm not sure I fully understand the last suggestion. Are you saying to quote these two lines? `s|___X[0-9]|___XX|g` and `s|___XX[0-9]|___XXX|g` ? – rs232 Mar 16 '20 at 08:45
  • Never mind just found it: `s|___\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\)|___\1___\2___\3___\4|g` into `s|__#\([0-9]\+\.\)\([0-9]\+\)|___\1___\2|g` Thanks!!!! – rs232 Mar 16 '20 at 08:49
  • You are on the right track. My cursory suggestion was incorrect (it would just change the numbers partly). However, I'll suggest you edit your solution into this form: `s|__#\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\)|___\1___\2\3\4|g`. That way you won't mask numbers like `123.45` which are not IP addresses. – nik Mar 17 '20 at 05:22
  • The solution you provided is perfect thank you!!! I have now opened a second request, pretty much identical but to mask FQDNs: https://serverfault.com/questions/1007097/mask-fqdns-from-any-command-output-for-diagnostic – rs232 Mar 17 '20 at 10:26