Categories
Admin Linux Network Technologies

The IT Detetecive Agency: the case of the unreliable FTP

Intro
So one of my power users complains that his FTPs to a particular site fail frequently, but not always. I rolled up my sleeves and set to work. The thing I do best is find the essence of a problem – what is the bare minimum sequence of events that reproduces it. I’m still getting my head around this one and I haven’t cracked the case yet, but I’ve learned about a few obscure packet generation tools.

The details
I may flesh this out later. The essence of the thing is that a packet trace (using tcpdump) shows that randomly no SYN-ACK packet is returned for our SYN packet to the FTP server on port 21. The FTP server resides on the Amazon cloud, but on the West Coast. We are on the East Coast. Not that that matters.

So I learned to reproduce the problem myself with the built-in ftp client. But I wanted even more control.

Packet generation tools
My trajectory went kind of like this:

ftp -> ping -> nmap -> hping3 -> mausezahn (-> scapy)

I had to compile mausezahn but I did manage to get it to work. I guess the developer has passed away. It doesn’t offer complete control over tcp packet generation, but nearly so.

I just discovered scapy. It appears to offer complete control over packet generation, including the tcp options such as mss, but the proof is in the pudding and I haven’t had time to check it out.

See the references fo links to further information about where to find these packages.

Preliminary findings
I began to see that with nmap and hping3 I was getting SYN-ACKs back consistently. What’s the difference between their SYN packets and ftp’s? They don’t use any options whereas my ftp client does.
And that is the essence of the problem. A tcp SYN packet which sets options like SACK, wscale and MSS is not being responded to around 30% of the time. No options set? SYN-ACKs come back 100% of the time. Pings are answered 99 – 100% of the time. mausezahn (mz) allows to set the window size. The window size is irrelevant.

Is it one particular tcp option that is the culprit, or just the fact of using any of them? Unfortunately that’s where you reach the limits of mz. mz only allows you to turn on or off all options. scapy promises to be more granular. So at least with mz by itself I can turn of/off the problem at will. That is getting to the essence of the problem.

Another wrinkle? Only certain source IPs have the problem! I have an identical system using a different ISP and it works all day long.

Conclusion
A lot of work and only modest progress to show for it. I need cooperation of the ftp administrator to do a simultaneous trace. Either the packet never gets to him, or his infrastructure discards it, or he responds but I never see the response. A two-sided trace will narrow down which of these three things is happening.

But I did learn that fine-control packet generation is a bit difficult to come by, which comes as a surprise in this day and age. You have to do some work to get full control over your packets.

I have nos stomach for writing my own C++ code to have total control.

It’s still an open case.

References
nmap.org talks about nmap. nmap is a pretty standard package available for major distributions. But it is not sufficiently configurable.
I’ve written about hping3 before, showing how to compile it.
I used this site for mausezahn source code and documentation.
scapy is well-documented here.

Categories
Internet Mail Spam

enom is the source of recent spam campaigns

Intro
I’m still watching over spam. The latest trend are spam campaigns which have a few characteristics in common perhaps the most interesting of which is that the domains have all been registered at enom.com.

The details
Some other things in common. These recent campaigns fell into two main categories. One set uses domains which are semi-pronounceable. The other are domains which incorporate sensible english words. Both categories have these other features in common.

– brevity (no HTML, for instance)
– valid SPF records (!)
– domains were used for spam almost immediately after having been registered (new domains)

Today’s example

From:        Patriot Survival Plan <Patriot_Survival_Plan@best-survival-plan-types.com> 
To:        <drj@drj.com> 
Date:        05/22/2014 04:22 AM 
Subject:        REVEALED: The Coming Collapse 
 
 
 
--------------------------------------------------------------------------------
 
 
 
 
drj@drj.com
 
Since I exposed this I'm getting a lot of comments. 
 
People are terrified and they are asking me to spread the word even more...
 
So don't miss this because it might be too late for you and your family!
 
Obama's done a lot of stupid things so far, but this one will freeze the blood in your veins!
 
He's been trying hard to keep this from American Patriots... but now his betrayal has finally come to light.
 
And he'll have to pay through the nose for this.
 
But here's a Warning: the effects of Obama's actions will hit you and your family by the end of this year.
 
And they'll hit you like nothing you've ever seen before...
 
So watch this revealing video to know what to expect...
and how to protect against it.
 
-> Watch Blacklisted video now, before it's too late -->                 http://check.best-survival-plan-types.com
 
 
 
 
 
 
 
No_longer_receive_this _Warning :   http://exit.best-survival-plan-types.com
Patriot Survival Plan _405 W. Fairmont Dr. _Tempe, AZ 85282
 
 
 
 
 
First off, there's nothing special 22409526 in the Ironbound. Food in quantity, 22409526not quality. It's amazing how many people 22409526 rate these establishments as excellent. This said, I've always had fun going to these places, 22409526 as long as your dining expectations are gauged accordingly. Therefore, 22409526 my rating reflects those reduced expectations. :)
 
Being a steakhouse, 22409526 one would expect a thorough steak menu such as those at Gallagher's, Luger's, or even Del Frisco's. However, you're not getting true steakhouse fare here; 22409526 it's the Ironbound after all. So, you're getting a less than Prime cut of beef, 22409526 sometimes cooked to your liking.

Whois lookup of best-survival-plan-types.com shows this:

Domain Name: BEST-SURVIVAL-PLAN-TYPES.COM
Registry Domain ID: 1859701370_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.enom.com
Registrar URL: www.enom.com
Updated Date: 2014-05-21 17:26:19Z
Creation Date: 2014-05-22 00:26:00Z
Registrar Registration Expiration Date: 2015-05-22 00:26:00Z
Registrar: ENOM, INC.
Registrar IANA ID: 48
Registrar Abuse Contact Email: abuse@enom.com
Registrar Abuse Contact Phone: +1.4252744500
Reseller: NAMECHEAP.COM
Domain Status: clientTransferProhibited
Registry Registrant ID:
Registrant Name: DONI FOSTER
Registrant Organization: NONE
Registrant Street: 841-4 SPARKLEBERRY LN
Registrant City: COLUMBIA
Registrant State/Province: SC
Registrant Postal Code: 29229
Registrant Country: US
Registrant Phone: +1.8037886966
Registrant Phone Ext:
Registrant Fax: +1.5555555555
Registrant Fax Ext:
Registrant Email: DONIFOSTER73@GMAIL.COM
Registry Admin ID:
Admin Name: DONI FOSTER
Admin Organization: NONE
Admin Street: 841-4 SPARKLEBERRY LN
Admin City: COLUMBIA
Admin State/Province: SC
Admin Postal Code: 29229
Admin Country: US
Admin Phone: +1.8037886966
Admin Phone Ext:
Admin Fax: +1.5555555555
Admin Fax Ext:
Admin Email: DONIFOSTER73@GMAIL.COM
Registry Tech ID:
Tech Name: DONI FOSTER
Tech Organization: NONE
Tech Street: 841-4 SPARKLEBERRY LN
Tech City: COLUMBIA
Tech State/Province: SC
Tech Postal Code: 29229
Tech Country: US
Tech Phone: +1.8037886966
Tech Phone Ext:
Tech Fax: +1.5555555555
Tech Fax Ext:
Tech Email: DONIFOSTER73@GMAIL.COM
Name Server: DNS1.REGISTRAR-SERVERS.COM
Name Server: DNS2.REGISTRAR-SERVERS.COM
Name Server: DNS3.REGISTRAR-SERVERS.COM
Name Server: DNS4.REGISTRAR-SERVERS.COM
Name Server: DNS5.REGISTRAR-SERVERS.COM

See 1) that it was registered yesterday at 17:26:19 Universal Time, and 2) that the registrar is enom?

And the SPF record:

> dig +short txt best-survival-plan-types.com

"v=spf1 a mx ptr ~all"

Actually this domain is a small aberration insofar as it does not have a SPF record with a -all at the end – the others I checked do.

What to do, what to do
Well, I reported the spam to Postini, but I don’t think that has any effect as they are winding down their business.

I am pinning greater hopes on filling out enom’s abuse form. Of course I have no idea what actions, if any, they take. But they claim to take abuse seriously so I am willing to give them their chance to prove that.

enom’s culpability
I don’t feel enom is complicit in this spam. I’m not even sure they can easily stop these rogue operators. But they have to try. Their reputation is at stake. On the Internet there are complaints like this from years ago, that enom domains are spamming.

Every one that comes across my desk I am reporting to them. The time it takes for me to report any individual one isn’t worth the effort compared to the ease of hitting DELETE, but I am hoping to help lead enom to find a pattern in all these goings-on so they can stop these registrations before new ones cause harm – that is why I feel my actions are for the greater good.

Other recently deployed enom domains

Domain

First spam seen

First registered

onlinetncresults.us

8/22

8/21

checkdnconlinesystems.us

8/20

8/20

extremeconcretecoating.com

8/8

8/8

woodsurface.com

8/7

8/7

shorttermloanspecial.com

7/24

7/23

heartattackfighter1.com

6/19

3/2

handle-unsafe-parasites.me

6/10

6/9

best-survivalplan-learn.com

5/28

5/28

survival-plan-days.com

5/27

5/26

only-survival-plan.com

5/20

5/19

local-vehicle-clearance.us

5/19

5/19

ghiused.com

5/14

5/14

pastutmy.com

5/14

5/14

lekabamow.com

5/14

5/14

etc – there are plenty more!

Finally we hear back
Weeks later, on June 14th, I finally received a formal response concerning only-survival-plan.com and local-vehicle-clearance.us.

From: abuse@namecheap.com
Subject: [~OOQ-128-23745]: FW: eNom - Report Abuse - Reference #ABUSE-11116
 
Hello, 
 
Thank you for your email. While the domain name(s) reported is registered with Namecheap, it is hosted with another company. So we cannot check the logs for the domain(s) and confirm if it is involved in sending unsolicited bulk emails. We can only take an action if a report is confirmed by blacklists of trusted anti-spam organizations like SpamHaus or SURBL.
 
Thus, we have initiated a case regarding the following domain(s) blacklisted by trusted anti-spam organizations:
only-survival-plan.com
In case the listing is not removed, the domain(s) will be suspended.
 
The following domain(s) has already been suspended:
local-vehicle-clearance.us
 
Let us also suggest you addressing the issue to the hosting company which servers were involved in email transmission for help with investigating the incident of spam. You may find their IP address in the headers. To find their contact details, please whois this IP address. You may use any public Whois tool like https://www.domaintools.com/ 
 
Kindly let us know if you have any question.
 
-------------------------------
Regards,
Alexander XXX.
Legal & Abuse Department
Namecheap Group
http://www.namecheapgroup.com

Analysis of their response
Reading between the lines, here’s my analysis. There’s some not-well-documented relationship between enom and namecheap.com. I reported the abuse to enom and got a response from namecheap.com. I kind of agree that suspending a domain is a BIG DEAL and a registrar has to be on firm footing to do so. As I write this one Jun 16th, the domains do not yet appear to be suspended. Are you really going to trust Spamhaus to render your judgement? That’s basically one of those extortionist enterprises purportedly offering a take-it-or-leave-it service. If the author of that email was a lawyer, well, their English isn’t the best. That doesn’t provide a lot of confidence in their handling of the matter. And wasn’t my complaint by itself good enough for them to initiate action? I do have to concede the point that the sending of the spam was probably out of their control and probably did come from another hosting company. But it is glib advice to suppose it is that easy to track them down the way they describe. Since they are part of the problem and have the evidence why don’t they follow up with the hosting provider themselves?? There was no mention of my other eight or so formal complaints. So this still seems to be getting an ad hoc one-by-one case treatment and not the, Whoa, we got a problem on our hands and there’s something systemically wrong with what we’re doing here reaction I had hoped to provoke.

Actually I got two responses but with slightly different wording. So they were crafted by hand from some boilerplate text, and yet the person stitching together the boilerplate was sufficiently mindless of the task as to forget they had already just sent me the first email??

So their response is better than a blackhole, but perhaps could be characterized as close to the bare minimum.

I have gotten several other responses from some of my other complaints as well, all saying pretty much the same thing. In August the responses started to look different however.

August responses
Here’s one I received this morning about woodsurface.com, 19 days after my initial complaint:

Hello,
 
This is to inform you that woodsurface.com domain was suspended. It is now pointed to non-resolving nameservers and will be nullrouted once the propagation is over. The domain is locked for modifications in our system.
 
Thank you for letting us know about the issue. 
 
------------------
Regards,
Alexander T.
Legal & Abuse Department
Namecheap.com

Conclusion
I hope my actions spur enom into some action of their own in figuring out where there domain registration requirements are too lax that spammers are taking wholesale advantage of the situation and sullying their reputation.

June, 2014 Update
The storm of spam from enom has subsided. I’m basically not seeing any. Oops. Spoke too soon! New enom-registered domains popped up and created more spam storms (documented in the table above), but not as severe as in the past. I don’t know if our anti-spam filter got better or enom stepped up to the plate and improved their scrutiny of domain registrants. If another spam storm hits us I’ll report back…

August, 2014
enom-generated spam is back!

References
My most popular spam-fighting article describes how to defeat Chinese-language spam.
A new type of spam that uses Google search results for link laundering is described here.

Categories
Admin Linux Network Technologies

Querying AD via LDAP – reference documentation

Intro
Suppose you managed to stuff the user’s ID into the description field of every computer object. Then independently the name of the computer object appears in a log such as a web server log and you want to know the user associated with that.

These examples show how to get at that description field from the computer object name.

The details

ldapsearch is a useful tool. I have two versions of it installed on Windows 7 and different Unix/Linux versions. The syntax is slightly different in all cases. Let’s assume the AD domain DRJOHNSAD is mapped to DNS domain drjohnsad.drjohns.net, and the user is drj. Then we have:

Linux
> ldapsearch -h drjohnsad.drjohns.net -b dc=drjohnsad,dc=drjohns,dc=net -D ‘drjohnsad\drj’ -W cn=computerName description

The -W switch prompts for the password. That is a nice switch, and not available in all versions of ldapsearch. If not, use -w password instead. drjohnsad\drj needs the single quote to prevent the “\” character from being treated as a special character by the shell. Windows doesn’t need that.

Windows 7 CMD Window

Oracle-provided ldapsearch

> ldapsearch -h drjohnsad.drjohns.net -b dc=drjohnsad,dc=drjohns,dc=net -D drjohnsad\drj -q cn=computerName description

So -q is used to prompt for a password instead of Linux’s -W.

Lotus Notes ldapsearch

> ldapsearch -h drjohnsad.drjohns.net -b dc=drjohnsad,dc=drjohns,dc=net -D drjohnsad\drj -w password cn=computerName description

You gotta put in the password on the command line.

Of course Windows also has applications which can be used for ldap queries in a GUI, but I don’t use them.

Conclusion
The syntax for a simple ldap query against an AD domain controller is shown.

Categories
Admin Web Site Technologies

Getting WebDav to work through Basic Authentication and HTTP

Intro
What I’m about to describe is not a recommended setup, but if like me you’re dealing with legacy infrastructure, well, sometimes you just gotta make things work as they are.

So imagine on your Intranet you have a WebDAV server running HTTP, not HTTPS, and using Basic Authentication. And you want to work with the files on a Windows 7 workstation. Read on to see how we got this combination to play nice together.

The details
First I gave myself access to a WebDAV resource on the server.

Being a Unixy type of guy, I then tried a Linux command-line program. I chose cadaver. See the webdav.org site for other clients.

I had to compile and install cadaver but that was no problem. Here is my test session:

> cadaver http://iwwwd.drj.com/webdav.ear/
Authentication required for CORP LDAP webDAV on server `iwwwd.drj.com’:
Username: drj
Password:
dav:/webdav.ear/> ls
Listing collection `/webdav.ear/’: succeeded.
Coll: drJ Application.ear 0 Sep 17 2012
Coll: drj app Application.ear 0 Nov 30 2013

dav:/webdav.ear/>

So, in other words, it worked! cadaver is kind of nice because it puts you into a shell and has commands similar to FTP, so it is a (mostly) familiar environment.

Now why was my Windows 7 PC giving me such a hard time?

Windows 7 by default only allows for Basic authentication against HTTPS webDAV servers.

To enable Basic authentication on the client computer, follow these steps:
1) Click Start , type regedit in the Start Search box, and then click regedit.exe in the Programs list.
2) Locate and then click the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters
3) Double-click the BasicAuthLevel registry key.
4) In the Value data box, type 2, and then click OK.
5) Exit Registry Editor, and then restart the computer.

More info can be found in this Microsoft knowledge base article: http://support.microsoft.com/kb/841215

http-webdav

Conclusion
Though not recommended for security reasons, it’s good to know there is a way to map a webdav drive when just HTTP (not HTTPS) is being used.

Categories
Network Technologies Proxy

The IT Detective Agency: The case of the purloined packet

Intro
Someone in the org notices that laptops can’t connect to our VPN concentrator when using Verizon MiFi. An investigation ensues and culprits are found. Read on for the details…

The details

Some background
The laptops are configured to use an explicit PAC file (proxy auto-config) for proxy access to the Internet. It works great when they’re on the Intranet. There were some initial bumps in the road, so we found the best results (as determined by using normal ISPs such as CenturyLink) for successful sign-on to VPN and establishing the tunnel was to create a dummy service on the Internet for the PAC file server. The main thing that does is send a RESET packet every time someone requests a PAC file. In that way the laptop knows that it should quickly give up on retrieving the PAC file and just use direct Internet connections for its initial connection to the VPN concentrator. OK?

So with that background, this current situation will make more sense. sometime after we developed that approach someone from the organization came along and tried to connect to VPN using a Verizon MiFi device. Although in the JunOS client it shows Connected in actual fact no tunnel is ever established so it does not work.

Time for to try some of our methodical testing to get to the bottom of this. Fortunately my friend has a Verizon MiFi jetpack, so I hooked myself up. Yup, same problem. It shows me connected but I haven’t been issued a tunnel IP (as ipconfig shows) and I am not on the internal network.

Next test – no PAC file
Then I turned off use of a PAC file and tried again. I connected and brought up a tunnel just fine!

Next test – PAC file restored, use of normal ISP

Then I restored the PAC file setting and tried my regular ISP, CenturyLink. I connected just fine!

Next test – try with a Verizon Hotspot

I tried my Verizon phone’s Hotspot. It also did not work!

I performed these tests several times to make sure there weren’t any flukes.

I also took traces of all these tests. To save myself time I won’t share the traces here like I normally do, but describe the relevant bits that I feel go into the heart of this case.

The heart of the matter
When the laptop is bringing up the VPN tunnel there is always at least one and usually several requests for the PAC file (assuming we’re in a mode where PAC file is in use). Remember I said above that the PAC file on the Internet is “served” by a dummy server that all it does is respond to every request (at TCP level every SYN) with a RST (reset)?

Well, that’s exactly what I saw on the laptop trace when using CenturyLink. But is not what I saw when using either Verizon MiFi or HotSpot. No, in the Verizon case the laptop is sent a (SYN,ACK). So the laptop in that case finishes the TCP handshake with an ACK and then makes a full HTTP request for the PAC file (which of course it never receives).

Well, that is just wrong because now the laptop thinks there’s a chance that it might get the PAC file if it just waits around long enough, or something like that.

The main point is that Verizon – probably with the best intentions – has messed with our TCP packets and the laptop’s behavior is so different as a result that it breaks this application.

I’m still thinking about what to do. I doubt Verizon, being a massive organization, is likely to change their ways, but we’ll see. UPDATE. After a few weeks and poor customer support from Verizon, they want to try some more tests. Verizon refuses to engage in a discussion at a technical level with us and ignores all our technical points in this open case. They don’t agree or disagree, but simply ignore it. Then they cherry pick some facts which support their preconceived notion of the conclusion. “It work with the PAC file turned off so the only change is on your end” is pretty much an exact quote from their “support.”

We also asked Verizon for all their ranges so we could respond differently to Verizon users, but they also ignored that request.

In particular What Verizon is doing amounts to WAN optimization.

UPDATE – a test with Sprint
I got a chance to try yet a different Telecom ISP: Sprint. I expected it to work because we don’t have any complaints, and indeed it did. I tested with a Sprint aircard someone lent me. But the surprising thing – indeed amazing thing – is how it worked. Sprint also clobbers those RST packets from when the laptop if fetching the PAC file. They also turn them into SYN,ACKs. But they carry the deceit one step further. When the laptop then does the GET request, they go so far as to fake the server response! They respond with a short 503 server fail status code! The laptop makes a few attempts to get the PAC file, always getting these 503 responses and then it gives up and it is happy to establish the VPN tunnelled connection at that point! So this has got me thinking…

April, 2014 update
Verizon actually did continue to work with us. They asked us the IP of our external PAC file server, never revealing what they were going to do with that information. Then we provided them phone numbers of Verizon devices we wished to test with. As an aside did you know that a Verizon MiFi Jetpack has a phone number? It does. Just log into it at my.jetpack and it will be displayed.

So I tried the Jetpack after they did their secret things, and, yes, VPN now works. But we are not helpless. I also traced that session, and in particular the packets to and from the PAC file webserver. Yes, they are coming back to my laptop as RSTs. I tested a second time, because once can be a fluke. Same thing: successful connection and RST packets as we wanted them to be.

Now we just need the fix to be generalized to all Verizon devices.

May 2014 update
Finally, finally, on May 6th we got the word that the fix has been rolled out. They are “bypassing” the IPs of our PAC file webservers, which means we get to see the RST packets. I tested an aircard and a Verizon hotspot and all looked good. VPN was established and RST packets were observed.

Case finally closed.

Conclusion
Verizon has done some “optimizations” which clobber our RST packets. It is probably pre-answering SYNs, with ACKs, which under ordinary circumstances probably helps performance. But it is fatal to creating an SSL VPN tunnel with the JunOS client configured with a PAC file. Sprint optimizes as well, but in such a way that things actually work. Verizon actually worked with us, at their own slow pace and secretive methodology, and changed how they handled those packets and things began to work correctly.

References
The next two links are closely related to this current issue.
The IT Detective Agency: How We Neutralized Nasty DNS Clobbering Before it Could Bite Us.
The IT Detective Agency: Browsing Stopped Working on Internet-Connected Enterprise Laptops

Categories
Admin Network Technologies Raspberry Pi Security

Bridging with the Raspberry Pi

Intro
Now I’m into playing with networking stuff on the Pi. So for a small investment I got a USB to ethernet adapter – $25 from Amazon. My first few experiments with it – turning it into a bridge – were largely successful.

The details
You need the bridge-utils package:

$ sudo apt-get install bridge-utils

For me it was easiest to connect to my Pi via the Wifi adapter I have on it (see this post describing how I used that to make a router). Then I could blow up the wired ethernet without disrupting my connection.

The first thing I noticed after plugging in the adapter is that it was automagically recognized and, for instance, the ifconfig -a command now shows an eth1 device. So no device driver needed to be installed, which was pretty sweet.

Listing the USB devices now looks like this:

$ lsusb

Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 0b95:1780 ASIX Electronics Corp. AX88178
Bus 001 Device 005: ID 7392:7811 Edimax Technology Co., Ltd EW-7811Un 802.11n Wireless Adapter [Realtek RTL8188CUS]

In short I want to take my two wired ports, eth0 and eth1, bridge them and send real traffic through them to see what happens. Bridging here means connecting two separate networks at a layer-2 level, so MAC addresses are proxied through the bridge and layer-3 communications occur transparently over the bridge as if it weren’t even there.

So…

$ sudo brctl addbr br0

creates a bridge named br0.

$ sudo brctl addif br0 eth0
$ sudo brctl addif br0 eth1

Adds those two physical ports to the bridge.

By the way I got all this from this reliable Linux Foundation source.

Now if I got it right, I should be able to unplug any wired device and put the Pi in between the switch and the device, no matter what its network is!

So I plugged my PC into one port, the other port into the switch the PC had been plugged into, and…

Well, for instance, showmacs output looks like this:

$ sudo brctl showmacs br0

port no mac addr                is local?       ageing timer
  1     00:00:00:0c:c8:1f       no                 1.30
  1     00:01:00:02:c8:1f       no               197.23
  2     00:02:cf:80:cc:99       no                 0.07
  2     00:90:a9:bb:3d:76       no                 0.94
  1     5e:00:00:fb:c8:1f       no               134.11
  1     5e:00:00:fd:c8:1f       no                57.49
  1     5e:7f:ff:fa:c8:1f       no                29.55
  2     64:66:b3:3b:bd:51       no                12.34
  1     8c:ae:4c:ff:27:69       yes                0.00
  2     b8:27:eb:dd:21:03       yes                0.00
  1     c8:1f:66:00:63:fe       no                 0.15

00:02:cf:80:cc:99 belongs to my upstream router, which is plugged into eth0, so I conclude that port 2 is eth0 and port 1 must be eth1. Maybe the port number was determined by the order in which I added the interface to the bridge?

Then I ran speedtest on my PC – there was no measurable slowdown in speed.

I loaded up the Pi with a cpu-intensive job:

$ yes > /dev/null

and re-ran speedtest. Still no hit to performance.

A brief review
I don’t think everyone will have appreciated what we’ve accomplished so let me review. We have created a passive, stealth man-in-the-middle (MITM) device with a management interface!

There are lots of uses for that, some not so noble. A more nefarious usage would be to connect up to a device and record all traffic passing back and forth to it (tcpdump -i br0). But there are also lots of good things we can achieve as well. For instance, Intrusion Detection System or Intrusion Prevention System (IDS/IPS). Firewall. Transparent proxy filter. IDS/IPS may be possible with Snort. I have to ask one of my security pals if that’s still the popular open source choice for IPS. Five years ago it was the package of choice.

What’s on my plate
Now I’d like to tinker with the Pi so that I can in fact slow down traffic and emulate slower connections! But I don’t know how yet…

I need to show how to make the bridging permanent using /etc/network/interfaces file.

To be continued…

Categories
Admin Internet Mail Linux

Sendmail: getting mailertable, smarttable and virtusertable to play nice together

Intro
Remember when I posted about some obscure but cool sendmail features? Well in that posting I mentioned having trouble with a catch-all mailertable entry co-existing with a smarttable. I recently got an incentive to work through that and I am sharing my results here. Plus use of virtusertable thrown in for good measure.

The setup
I have a Secure Mail Gateway (SMGW). Some of my users use it, most do not. So for the few who do I wish to divert my outgoing mail, if it sent by one of them, to the SMGW1. Everything else that’s outbound gets forwarded to an Internet-facing relay2. And for inbound mail I also want to divert their email over to it so it can do S/MIME or PGP decryption3. All other inbound emails should go to my native email system4.

So consider the outbound stream, requirement 1. Sender-based routing. That’s the normal thing in sendmail. That’s why you use smarttable, which Andrzej Filip has developed. See my references for more details on that. But my mailertable has a catch-all entry like:

.              relay:emgw.drj.com

I found if I got rid of this entry my smarttable entries began to work, but they stopped working if I put it back. I rolled up my sleeves and tried to understand ruleset 0. I became pretty convinced that mailertable runs before smarttable, and that if mailertable made a successful lookup of the recipie4nt domain that’s it. You’re done. Then I read a very brief comment in Andrzej’s writeup of smarttable. He bascially said mailertable runs first, and I guess form that brief comment you’re supposed to know that this setup I am trying will never work. And yet I have a colleague with a similar setup who says it does work, which got my competitive juices flowing – if the other guy can do it, then I know it can be done and I can do it as well! I knew I had to eliminate the catch-all entry, but still needed a catch-all feature. What to do? Fudge DNS to the point where all TLDs have a fake MX entry pointing at my external mail server?? Sounds too kludgy.

I was reading here and there in the Sendmail book and the cf/README file when SMARTHOST caught my eye. A smarthost can be defined to deliver all email to a specified relay. I always viewed it as an alternative to the mailertable, where you can specify much more specific delivery rules. But maybe they could co-exist? Mailertable for domain-specific delivery instructions, and smarthost for everything else? Yes, you can indeed do that! And with the catchall entry gone from mailertable does smarttable begin to work? Yes! It does! So our outbound stream is in good shape and all requirements are met. Each user of the SMGW is entered in the smarttable:

user1@drj.com    relay:smgw.drj.com
user2@drj.com    relay:smgw.drj.com
etc.

The mc configuration for smarthost looks like this:

dnl smarthost: to take care of the everything-else delivery case - DrJ 2/28/14
define(`SMART_HOST',`internet-facing-relay.drj.com')

Inbound
For inbound we can use virtusertable to rewrite the user domain to a fictional domain, then a mailertable entry which describes that this fictional domain should be routed over to the SMGW! Like this.

Virtusertable

user1@drj.com   user1@drj.com.smgw
user2@drj.com   user2@drj.com.smgw
etc

and

Mailertable

drj.com   relay:native-mail-system-gw.drj.com
.smgw     relay:smgw.drj.com

Although this sounded good on paper, I found it was not enough by itself. In addition I needed to throw in a virtuser domain file which included the domain drj.com.

The mc configuration for virtusertable and virtuserdomain look like this.

dnl
dnl add virtusertable to do recipient re-writing to accomodate SMGW routing -DrJ 3/3/14
FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable')dnl
dnl virtuser domain file location - DrJ 2/27/14
VIRTUSER_DOMAIN_FILE(`/etc/mail/virtuserdomains')dnl

virtuserdomains is a standard text file which contains drj.com.

Testing
It is helpful to know how to debug this stuff. Smarttable is probably the hardest. Here’s how to see the before and after effect that smarttable has:

$ sendmail -Csendmail-test.cf -bt<<END
> 3,0 addr@gmail.com
> .Dfuser1@drj.com
> 3,0 addr@gmail.com
> END

The 3,0 lines show the result of running rulesets 3 and 0, I guess. The .Df…line defines the sender, so the last 3,0 line shows how delivery to the sender is now altered if the defined sender exists in the smarttable table.

Regular addresses can be tested with the same -bt switch if you want to see the gory details, or simply -bv:

$ sendmail -Csendmail-test.cf -bt< 3,0 regularaddr@gmail.com
> END

$ sendmail -Csendmail-test.cf -bv regularaddr@gmail.com

It’s assumed you put your sendmail config in sendmail-test.cf to not interfere with production.

Even if all the tests succeed, what I found is that smarthost did not take effect dynamically. I needed to re-start sendmail.

Conclusion
By digging into the innards of sendmail we learned enough to see how things should work together and found that it is indeed possible for smarttable, virtusertable and mailertable to peacefully co-exist, but only with a helping of smarthost and virtuserdomains!

References
I describe smarttable here.
Andrzej’s smarttable page is here.

Categories
Admin Linux Network Technologies Raspberry Pi

Using your Raspberry Pi as a router

Intro
Most Raspberry Pi router HowTos describe how to make the Pi act like an Access Point. That can be very useful, and kind of tricky. Here I’ve turned wireless and wired network roles around and show how to make it route traffic from a wired LAN over its WiFi connection.

I bought the EDIMAX nano USB adapter to play around with wireless on my Pi. It wasn’t long before the network lover in me realized, Hey I got an ethernet port on one end, a wireless on the other – that sounds like a potential router – let’s have some fun! So I hooked up my cantankerous Sony Blueray player to it. The thing has always been touchy about using wireless but it also has a wired LAN connection option – in a room where I don’t have a wired ethernet network available. Enter the routing Pi…

WiFi on the Pi
There are many ways to get the thing going. The important thing to note is that this EDIMAX is tested and is known to be compatible with the Raspberry Pi. I guess they even included the appropriate driver for it, because there is no need at any time to read the mini-CD that the EDIMAX comes with and try to pull of, or worse, compile, a Linux driver like I initially feared. I think you merely need to do one of these numbers:

$ sudo apt-get update

to ensure you have the latest of everything on your Pi and that includes the driver for this WiFi adapter.

Also note that the Pi, being a tiny computer, is perfectly complemented by this nano adapter. The thing is so tiny you barely have enough surface area to pull it out of the USB slot.

As I said there are probably many ways to get your WiFi going. Being a command line lover I present that way, and even then there are alternative setups to choose from, of which I present only one here.

If you do one of these numbers:

$ cd /etc/network; sudo nano interfaces

I would recommend to add a line towards the top:

auto wlan0

and at the bottom:

# following http://antael.blogspot.com/2013/01/wifi-is-live-and-kicking.html
# to see Wifi signal strength and available signals run iwlist wlan0 scan
#allow-hotplug wlan0
iface wlan0 inet static
wpa-ssid 
wpa-psk 
wpa-key_mgmt WPA-PSK
address 192.168.0.90
gateway 192.168.0.254
netmask 255.255.255.0
broadcast 192.168.0.255

substitute the name of your WiFi SSID and the password (WPA Pre-Shared Key) in place of <MYSSID> and <MYSSIDPASSWORD>.

I prefer static IPs to dynamic ones. That way I ssh to the IP and it is the same every time.

As I am setting up a router this is not my complete interfaces file, just the part I want to emphasize for now. The complete file is listed below.

A word on what we are setting out to do – our network architecture

OK. So I am going to put the Pi next to the Blueray Player. The Pi will connect to my TP-LINK WiFi network. The Pi’s ethernet interface will connect to the LAN port on the Blueray player using a standard ethernet patch cable (these days it is not necessary to use a crossover cable as there’s always a device that auto-senses how it is wired). I will create a new network for this interface on the Pi, and make sure I’ve assigned a valid IP on this network to the Blueray player. The network I choose is 10.31.42.0/24 – something completely different from anything I may already have in use at home.

The Blueray player can also be assigned a static IP address. I give it 10.31.42.13 and the Pi I assign 10.31.42.11. The gateway of the Blueray player is our routing Pi, so that makes the gateway IP 10.31.42.11.

But I have another requirement: I want to conveniently put the Pi back on my wired home network in case something goes wrong with wireless. so I want to keep its valid static IP (192.168.2.100) which it used to have when it was wired to my switch. The way to accomplish all this is to use virtual IPs on the eth0 interface. See the full /etc/network/interfaces file below which shows eht0 still assigned to IP 192.168.2.200, but as well a virtual interface eth0:0 assigned to 10.31.42.11.

Convenient way to test things
Initially I was focused on the architecture I’ve outline above and getting all my interfaces up and running. And I could run, for instance,

$ sudo service networking restart

to make my changes to the interfaces file be dynamically enabled, and I can do a

$ ifconfig -a

to show all my interfaces, their IPs and other information. And I especially like

$ iwlist wlan0 scan

to show the available WiFi networks and their signal strength. But how do I know that routing is working?? Here’s how. You know the ping command, right? Normally you do

$ ping 8.8.8.8

to show you can reach the Internet. Why? because that’s a valid IP address on the Internet that responds to PING – thank you Google – and it’s easy to remember!

But since our default route is out of our WiFi-connected interface, the IP it picks for the source of that PING is the IP assigned to wlan0, namely 192.168.0.90. There’s no Pi-routing involved in that so far. But now, you can choose a different source IP for your pings. So we pick our new virtual IP, 10.31.42.11 like this:

$ ping -I 10.31.42.11 8.8.8.8

but instead of a nice result like

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_req=1 ttl=44 time=172 ms
64 bytes from 8.8.8.8: icmp_req=2 ttl=44 time=92.7 ms
64 bytes from 8.8.8.8: icmp_req=3 ttl=44 time=69.6 ms
64 bytes from 8.8.8.8: icmp_req=4 ttl=44 time=70.6 ms
64 bytes from 8.8.8.8: icmp_req=5 ttl=44 time=70.3 ms
64 bytes from 8.8.8.8: icmp_req=6 ttl=44 time=70.5 ms
^C
--- 8.8.8.8 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5006ms
rtt min/avg/max/mdev = 69.676/91.121/172.740/37.409 ms

we don’t get much encouragement:

PING 8.8.8.8 (8.8.8.8) from 10.31.42.11 : 56(84) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3000ms

The ^C above means <CTRL-C> was typed in at the keyboard.

So we’re seeing 100% packet loss and we can safely conclude no routing is occurring. By the way, as a reality and typo check on this approach, try to specify as source your wlan0 IP, as in

$ ping -I 192.168.0.90 8.8.8.8

This should work.

Turn on routing
I feared it would be mess to get routing turned on, but it turns out to be pretty tidy, considering. Probably your Pi is already enabled for routing. Mine was. Just

$ cat /proc/sys/net/ipv4/ip_forward

and make sure the value is 1. That means it is set up to do routing. If you’re not so lucky and you have 0, enable routing:

$ sudo sysctl -w net.ipv4.ip_forward=1

But of course there’s more we have to do or else our source ping would have worked!

We need to turn on network address translation. This is the part I was worried about, never having done it before on Linux, but only with expensive products like commercial firewalls. But it’s really not bad at all.

I created a file iptables-NAT in the home directory of the pi user with these contents:

#!/bin/sh
# This is a one-time script - DrJ
# 2/2014
# explained nicely in http://www.karlrupp.net/en/computer/nat_tutorial
# and seems to even work!
 
# flush old iptables stuff. Need to specify nat table specifically
iptables -t nat -F
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
 
# make it permanent
#/usr/sbin/service iptables save
 
# list it
iptables -t nat -L
 
# persist it:
 
iptables-save &gt; /etc/iptables.conf
 
# note that in /etc/network/interfaces we added this line to read in
# iptables.conf upon reboot:
# pre-up iptables-restore &lt; /etc/iptables.conf

and ran it:

$ cd; sudo ./iptables-NAT

It outputs this:

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
 
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
 
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
 
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  anywhere             anywhere

Now run our source ping:

$ ping -I 10.31.42.11 8.8.8.8

PING 8.8.8.8 (8.8.8.8) from 10.31.42.11 : 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_req=1 ttl=44 time=76.3 ms
64 bytes from 8.8.8.8: icmp_req=2 ttl=44 time=71.4 ms
^C
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 71.471/73.922/76.373/2.451 ms

Voila! It worked. We now are NATing our source address of 10.31.42.11 to our wlan IP of 192.168.0.90 before sending the packet along to the next router. But as skeptics, we’d like to see some more empirical proof that all that is really happening. You can. Here’s how using tcpdump.

The thing is that tcpdump doesn’t have full access to pre-processing, it only has “post processing” access. So we need to hook up the Pi to a device we are going to route traffic for, in my case the Sony Blueray player. I don’t have much control, but I can do a network diagnostics which I know tries to reach the configured DNS server (because it complained that it could not reach the DNS server 8.8.8.8 during one of my early tests. So tee up tcpdump to monitor all interfaces’ traffic to 8.8.8.8 like this:

$ sudo tcpdump -n -i any host 8.8.8.8

Then run ping (or a DNS query) to 8.8.8.8 on that device, and voila, this is the result:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
20:22:09.041922 IP 10.31.42.13.54693 &gt; 8.8.8.8.53: 5+ A? m.root-servers.net. (36)
20:22:09.042144 IP 192.168.0.90.54693 &gt; 8.8.8.8.53: 5+ A? m.root-servers.net. (36)
20:22:09.163618 IP 8.8.8.8.53 &gt; 192.168.0.90.54693: 5 1/0/0 A 202.12.27.33 (52)
20:22:09.163777 IP 8.8.8.8.53 &gt; 10.31.42.13.54693: 5 1/0/0 A 202.12.27.33 (52)

The -i any switch told it to listen on all interfaces. Unfortunately the output doesn’t show which interface, but you can easily deduce it. the traffic comes in from my Blueray player at 10.31.42.13 on eth0, and then leaves the Pi on wlan0 having had its source IP translated to 192.168.0.90. And the reverse happens to the response from 8.8.8.8. In fact I see from this tcpdump output that the Blueray player does not do a PING, it does an actual DNS query to 8.8.8.8. Makes sense since it is a DNS server.

Be persistent
But a reboot will undo this nice NATing we have achieved. Try it. So we have to find a way to make our iptables entry persist across reboots. I’m sure there are many ways to do this. I liked this one. You add this line to the end of your interfaces file:

pre-up iptables-restore &lt; /etc/iptables.conf

And of course we already anticipated this manner of proceeding in our iptables-NAT file when we included this line at the bottom:

iptables-save &gt; /etc/iptables.conf

Now reboot again, and try that source ping as the first command you issue. Now it should work.

Ready for the real test
Now I can hook up my Blueray player with some confidence that at least the networking should be working. Assign its IP (10.31.42.13 as mentioned above), its gateway (the Pi’s eth0:0 virtual IP, namely 10.31.42.11 in our example), a DNS server (8.8.8.8, of course!) and see if:

– we can ping 10.31.42.13 from the Pi
– the Blueray player’s network tester shows OK (there aren’t many fine debugging utilities, just this single “network test”)

If the Blueray player can’t reach the configured DNS server then it its test fails.

Why this big long explanation for something that no one else in the world wants to do?
All this sounds like a very, very specific application that doesn’t apply to anyone else. But once you understand some of the core networking principles involved that I’ve touched on here, you will begin to realize that this can be very easily generalized to something much more applicable and powerful: a full-blown replacement for a standard wireless router such as my TP-LINK nano router. After all, we’ve set up almost all the utilities and facilities that you get from a standard router (NATing and routing), perhaps with one glaring exception: a DHCP service. I personally didn’t want one, but nothing prevents you from setting that up on the wired side. I give some suggestions below on how to do that in the next section.

A few words on a DHCP service
I did get that running on the Pi as well, though for an entirely different purpose. I used dnsmasq:

$ sudo apt-get install dnsmasq

and I think if you edit /etc/dnsmasq.conf and put these lines at the bottom:

interface=eth0
dhcp-range=10.31.42.14,10.31.42.254,10h
dhcp-option=3,10.31.42.11

I think you will pretty much have a working DHCP service as well and could use that instead of assigning static IPs.

What I fear about the DHCP service – and I think I have seen this – is that if I put the Pi back to the wired network, its DHCP server competes with the normal router’s DHCP service, and I start to lose connectivity to my devices! So be careful. If devices like your PC start to pick up 10.31.42.x addresses on a network where 192.168.2.x is expected, there could be some connectivity troubles ahead until you disconnect the Pi!

Finally, the full /etc/network/interfaces file

auto lo
auto eth0
auto eth0:0
auto wlan0
 
iface lo inet loopback
# DrJ change: make IP static
# somewhat inspired by http://www.techiecorner.com/486/how-to-setup-static-ip-in-debian/ - DrJ 1/8/13
#iface eth0 inet dhcp
iface eth0 inet static
address 192.168.2.100
#gateway  192.168.2.1
netmask 255.255.255.0
network 192.168.2.0
broadcast 192.168.2.255
 
# for network 3142
iface eth0:0 inet static
address 10.31.42.11
netmask 255.255.255.0
network 10.31.42.0
broadcast 10.31.42.255
 
# following http://antael.blogspot.com/2013/01/wifi-is-live-and-kicking.html
# to see Wifi signal strength and available signals run iwlist wlan0 scan
#allow-hotplug wlan0
iface wlan0 inet static
wpa-ssid 
wpa-psk 
wpa-key_mgmt WPA-PSK
address 192.168.0.90
gateway 192.168.0.254
netmask 255.255.255.0
broadcast 192.168.0.255
# wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
#iface default inet dhcp
 
# to read in iptable configuration. See ~pi/iptables-NAT
# added - DrJ 3/2/14
pre-up iptables-restore &lt; /etc/iptables.conf

Conclusion
Yes, we got our Pi to act as a router, and it wasn’t too bad. We demonstrated it for this specific application, but also showed how the simple addition of a DHCP service would make this a very general solution.
Did it help with the problem at hand – getting smoother streaming on the Sony Blueray player? Well, actually, yes, it did seem to help.

References and related

An idea for temporarily replacing a busted home router with a Raspberry Pi router which uses your hotspot is described in this article.

Getting started on a Pi without a dedicated console is described here.
A look at playing around with real-time video using the Pi’s camera is described here.
A more esoteric project, using the Pi to monitor your home’s Internet/power connection, is presented here.
Turning your Raspberry Pi into a transparent networking bridge is described here.
Interested to run some real networking protocols on your Pi like RIP, OSPF or BGP? I suggest to look into Quagga. Quagga is a networking suite. In full disclosure I haven’t had time or motivation to experiment with it myself (yet).

Categories
Admin Linux

Linux command line tips

Intro
I love the Linux command line. I don’t know how to categorize the tips I have collected so I’m dumping them here for the time being.

The newer netstat
In the old days I used to constantly do

$ netstat -an|grep LISTEN|grep <PORT>

to see what tcp ports I had processes listening on. While that is very helpful, it doesn’t tell you the listening process. A better approach:

$ lsof -i tcp:<PORT>

where is 22, 80 or whatever you want to look for. lsof does show the process.

Repeat last argument

I am constantly doing things like

$ grep <string> <big-file> > /tmp/results

and then I want to have a look at that file but I don’t want to type in

$ more /tmp/results

so what do I do?

I type this to give me the last argument:

$ more !$

My fingers have memorized that pattern and so I do it without conscious thought, and you’re holding down the SHIFT key so it can be typed very quickly.

But sometimes I can’t wait to type even that. I want to collect the grep results into a file in case there were a lot of matches, but I also want to see the matching results on my screen as soon as they are available. What do I do? Use tee, as in:

$ grep <string> <big-filez> |tee /tmp/results|more

Cool, huh?

More Obscure stuff
A cool blog with lots of good, obscure tips, generally more technical than the ones above, is https://die-computerhilfe.de/blog

To be continued…

Conclusion

Categories
Linux Raspberry Pi

Superimposing a grid on your raspivid output

Intro
In my previous post I outlined how to get real-time video from your Raspberry Pi with its camera, and to make it somewhat robust. In the conclusion I mentioned that it would be nice to superimpose (overlay) a grid over that image, and speculated that openCV might be just the tool to do it. Here I demonstrate how I have done it, and what compromises I had to make along the way.

The details
Well, let’s talk about why I didn’t go the openCV route. I began to bring down the source code for raspivid and raspistill, as outlined in this series of blog posts. And I did get it to compile, but it’s a lot of packages to bring down, and then I still needed to add in the openCV stuff. He provided one example of a hacked source file, but for raspistill, and I needed raspivid which is slightly different. Then there was cmake to master – I have no idea never having used it before. And then I would have needed to figure out openCV, which in turn might require programming in C++, which I have only the most basic skills. And then after all that, my fear was that it would slow down the video to the point where we would lose the real-time aspect! So the barriers were many, the risk was great, the reward not that great.

Logic dictates there should be another way
I reasoned as follows. Windows display graphics. Something decides what pixels to display, and this is true for every window, including mplayer. So if you can get control of what decides how to draw pixels in Windows we can draw our grid on the client side in Windows rather than on the encoder side on the Pi. So I looked for a way to superimpose an image using mplayer. Though they don’t use that term, I soon was drawn to what sounded similar, a -vf (video filter) switch with post-processing capability. I don’t know how to bring up the mplayer documentation in Windows, but on the Pi it’s just

$ man mplayer

and you’ll get a whole long listing. Under -vf are different filters, non of which sounded very promising. then I came across geq (general equation). That sounded pretty good to me. I searched for examples on the web and came across this very helpful discussion of how to use it, with examples.

So, off I went. A lot of the stuff I tried initially didn’t work. Then, when it did work, it lost the real-time feature that’s so important to us. Or the convergence to real-time took too long. I finally settled on this string for my mplayer:

mplayer -vf geq=p(X\,Y)*(1-gt(mod(X/SW\,100)\,98))*(1-gt(mod(Y/SH\,100)\,98)) -ontop -fps 27 -vo gl -cache 1024 -geometry 600:50 -noborder -msglevel all=0 -

in combination with these switches on raspivid:

raspivid -n -o - -t 9999999 -rot 180 -w 560 -h 420 -b 1000000 -fps 9

And, voila, my grid of black lines appears at 100 pixel intervals. Convergence is about 30 seconds and we have preserved the real-timeyness of the video!

But it as a series of compromises and tuning that got me there. For my desired 640 x 480 video I could get real-time video at about 7 fps (frame per second). I think my PC, a Dell Insipron 660, just can’t keep up at higher fps. Because when you think about it, it’s got to do calculations for each and every pixel, which must introduce quite some overhead. Perhaps things will go better on PCs that don’t need the -vo gl switch of mplayer which I have to use on my Dell display. So I kept the pixels per second constant and calculated what area I would have to shrink the picture to to increase the fps to a value that gave me sufficient real-timeyness. I decided there was a small but noticeable difference between 7 fps and 9 fps.

So

pixels/second = fps * Area,

so keeping that constant,

7 fps * A7 = 9 fps * A9

A = w*h = w*((3/4)*w)

So after some math you arrive at:

w9 = w7*sqrt(7/9) = 640 * 0.935 ~ 560 pixels

and h9 = w9*3/4 = 420 pixels

And that worked out! So a slightly smaller width gives us fewer pixels to have to calculate, and allows us to converge to real-time and have almost unnoticeable lag.

What we have now
One the Pi the /etc/init.d/raspi-vid now includes this key line:

raspivid -n -o - -t 9999999 -rot 180 -w 560 -h 420 -b 1000000 -fps 9|nc  -l 443

and on my PC the key line in my .bat file now looks like this:

c:\apps\netcat\nc 192.168.0.90 443|c:\apps\smplayer\mplayer\mplayer -vf geq=p(X\,Y)*(1-gt(mod(X/SW\,100)\,98))*(1-gt(mod(Y/SH\,100)\,98)) -ontop -fps 27 -vo gl -cache 1024 -geometry 600:50 -noborder -msglevel all=0 -

For the full versions of the files, and more discussion about the switches I chose, go back to my previous article about screaming streaming on the Pi, and just substitute in these lines in the obvious place. Adjust the IP to your Pi’s IP address.

No tick marks?
My original goal was to innlude tick marks, but I see given the per-pixel calculations required that that’s gonna be a lot more complicated and could only further slow us down (or force us to reduce the picture size further). So for now I think I’ll stop here.

A word on YUV coloring
I am much more comfortable with RGB, but that seems not to be used in Pi video stream. I guess raspivid encodes using YUV. I haven’t mastered the representation of YUV, but here’s a couple words on it anyways! I’m sure it’s related to YCbCr, which is described here. So because groups of pixels share a color, if you change the function above to mod(X/SW\,101),99), for instance, you get alternating green and black grid lines as you go from even to odd pixels. That is my vague understanding at this point. I learned just enough to get my black grid lines but no more…

Unsolved Mystery
Although the approach outlined above does generally work and can be real-time, I find that it also gets laggy when i leave the room and there is no motion. I’m not sure why. Then I introduce motion and it converges again to real-time. I don’t think this behaviour was so noticeable before I added the grid lines, but I need more tests.

Conclusion
We’ve shown how to overlay a black grid on the video output of our Raspberry Pi, while keeping the stream real-time with almost unnoticeable lag.

Conclusion
We have managed to overlay a black grid on our video using built-in functionality of mplayer. It appreciably slows things down. so your mileage may vary depending on your hardware.

References
The original Screaming Streaming on the Raspberry Pi article.