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
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
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 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 IT Operational Excellence Linux Network Technologies Raspberry Pi

Screaming Streaming on the Raspberry Pi

Intro
The Raspberry Pi plus camera is just irresistible fun. But I had a strong motivation to get it to work the way I wanted it to as well: a First robotics team that was planning on using it for vision for the drive team. So of course those of us working on it wanted to offer something with a real-time view of the field with a fast refresh rate and good (though not necessarily perfect) reliability. Was it all possible? Before starting I didn’t know. In fact I started the season in January not knowing the team would want to use a Raspberry Pi, much less that there was a camera for it! But we were determined to push through the obstacles and share my love of the Pi with students. Eventually we found a way.

The details
Well, we sure made a lot of missteps along the way, that’s why I’m excited to write this article to help others avoid some of the pain points. It needs to be fleshed out some more, but this post will be expanded to become a litany of what didn’t work – and that list is pretty long! All of it borrowed from well-meaning people on various Internet sites.

The essence of the solution is the quick start page – I always search for Raspberry pi camera quick start to find it – which basically has the right idea, but isn’t fleshed out enough. So raspivid + nc + a PC with netcat (nc) and mplayer will do the trick. Below I provide a tutorial on how to get it all to work.

Additional requirement
Remember I wanted to make this almost fool-proof. So I wanted the Pi to be like a passive device that doesn’t need more than a one-time configuration. Power-up and she’s got to be ready. Cut power and re-power, it better be ready once more. No remote shell logins, no touching it. That’s what happens when it’s on the robot – it suddenly gets powered up before the match.

Here is the startup script I created that does just that. I put it in /etc/init.d/raspi-vid:

#! /bin/sh
# /etc/init.d/raspi-vid
# 2/2014
 
# The following part always gets executed.
echo "This part always gets executed"
 
# The following part carries out specific functions depending on arguments.
case "$1" in
  start)
    echo "Starting raspi-vid"
# -n means don't show preview on console; -rot 180 to make image right-side-up
# run a loop because this command dies unless it can connect to a listener
    while /bin/true; do
# if acting as client do this. Probably it's better to act as server however
# try IPs of the production PC, test PC and home PC
#      for IP in 10.31.42.5 10.31.42.6 192.168.2.2; do
#        raspivid -n -o - -t 9999999 -rot 180 -w 640 -h 480 -b 800000 -fps 15|nc $IP 80
#      done
#
# act as super-simple server listening on port 443 using nc
# -n means don't show preview on console; -rot 180 to make image right-side-up
# -b (bitrate) of 1000000 (~ 1 mbit) seems adequate for our 640x480 video image
# so is -fps 20 (20 frames per second)
# To view output fire up mplayer on a PC. I personally use this command on my PC:
# c:\apps\netcat\nc 192.168.2.100 443|c:\apps\smplayer\mplayer\mplayer -ontop -fps 60 -vo gl -cache 1024 -geometry 600:50 -noborder -msglevel all=0 -
      raspivid -n -o - -t 9999999 -rot 180 -w 640 -h 480 -b 1000000 -fps 20|nc  -l 443
# this nc server craps out after each connection, so just start up the next server automatically...
      sleep 1;
    done
    echo "raspi-vid is alive"
    ;;
  stop)
    echo "Stopping rasip-vid"
    pkill 'raspi-?vid'
    echo "raspi-vid is dead"
    ;;
  *)
    echo "Usage: /etc/init.d/rasip-vid {start|stop}"
    exit 1
    ;;
esac
 
exit 0

I made it run on system startup thusly:

$ cd /etc/init.d; sudo chmod +x raspi-vid; sudo update-rc.d raspi-vid defaults

Of course I needed those extra packages, mplayer and netcat:

$ sudo apt-get install mplayer netcat

Actually you don’t really need mplayer, but I frequently used it simply to study the man pages which I never did figure out how to bring up on the Windows installation.

On the PC I needed mplayer and netcat to be installed. At first I resisted doing this, but in the end I caved. I couldn’t meet all my requirements without some special software on the PC, which is unfortunate but OK in our circumstances.

I also bought a spare camera to play with my Pi at home. It’s about $25 from newark.com, though the shipping is another $11! If you’re an Amazon Prime member that’s a better bet – about $31 when I looked the other day. Wish I had seen that earlier!

I guess I used the links provided by the quick start page for netcat and mplayer, but I forget. As I was experimenting, I also installed smplayer. In fact I ended up using the mplayer provided by smplayer. That may not be necessary, however.

A word of caution about smplayer
smplayer, if taken from the wrong source (see references for correct source), will want to modify your browser toolbar and install adware. Be sure to do the Expert install and uncheck everything. Even so it might install some annoying game which can be uninstalled later.

Lack of background
I admit, I am no Windows developer! So this is going to be crude…
I relied on my memory of some basics I picked up over the years, plus analogies to bash shell programming, where possible.

I kept tweaking a batch file on my desktop. So I associated notepad to my Send To menu. Briefly, you type

shell:sendto

where it says Search programs and files after clicking the Start button. Then drag a copy of notepad from c:\windows\notepad into the window that popped up.

Now we can edit our .bat file to our heart’s content.

So I created a mplayer.bat file and saved it to my desktop. Here are its contents.

if not "%minimized%"=="" goto :minimized
set minimized=true
start /min cmd /C "%~dpnx0"
goto :EOF
:minimized
rem Anything after here will run in a minimized window
REM DrJ 2/2014
rem 
rem very simple mplayer batch file to play output from a Raspberry Pi video stream
rem
rem Use the following line to set up a server
REM c:\apps\netcat\nc -L -p 80|c:\apps\smplayer\mplayer\mplayer -fps 30 -vo gl -cache 1024 -msglevel all=0 -

rem Set up as client with this line...
rem put in loop because I want it to start up whenever there is something listening on port 80 on the server
 
:loop

 
rem this way we are acting as a client - this is more how you'd expect and want things to work
c:\apps\netcat\nc 192.168.2.102 443|c:\apps\smplayer\mplayer\mplayer -ontop -fps 60 -vo gl -cache 1024 -geometry 600:50 -noborder -msglevel all=0 -

rem stupid trick to sleep for about a second. Boy windows shell is lacking...
ping 127.0.0.1 -n 2 -w 1000 > NUL
 
goto loop

A couple notes about what is specific to my installation. I like to install programs to c:\apps so I know I installed them by hand. So that’s why smplayer and netcat were put there. Of course 192.168.2.102 is my Pi’s IP address on my home network. In this post I describe how to set a static IP address for your Pi. We also found it useful to have the CMD Window minimize itself after starting up and running in the background, so the I discovered that the lines on the top allow that to happen.

The results
With the infinite loops I programmed either Pi or mplayer.bat can be launched first – there is no necessary and single order to do things in. So it is a more robust solution than that outlined in the quick start guide.
Most of my other approaches suffered from lag – delay in displaying a live event. Some other suggested approaches had quite large lag in fact. The lag from the approach I’ve outlined above is only 0.2 s. So it feels real-time. It’s great. Below I outline a novel method (novel to me anyways) of measuring lag precisely.
Many of my other approaches also suffered from a low refresh rate. You’d specify some decent number of frames per second, but in actual fact you’d get 1 -2 fps! That made for choppy and laggy viewing. With the approach above there is a full 20 frames per second so you get the feel of true motion. OK, fast motions are blurred a bit, but it’s much better than what you get with any solution involving raspistill: frame updates every 0.6 s and nothing you do can speed it up!
Many Internet video examples showed off high-resolution images. I had a different requirement. I had to keep the bandwidth usage tamped down and I actually wanted a smaller image, not larger because the robot driver has a dashboard to look at.
I chose an unconventional port, tcp port 443, for the communication because that is an allowed port in the competition. The port has to match up in raspi-vid and mplayer.bat. Change it to your own desired value.

Limitations
Well, this is a one-client at a time solution, for starters! did I mention that nc makes for a lousy server?
Even with the infinite looping, things do get jammed up. You get into situation where you need to kill the mplayer CMD window to get things going again.
I would like to have gotten the lag down even further, but haven’t had time to look into it.
Begin a video amateur I am going to make up my own terms! This solution exhibits a phenomenon I call convergence. What that means is that once the mplayer window pops up, which takes a few seconds, what it’s displaying shows a big lag – about 10 seconds. But then it speeds along through the buffered frames and converges with real-time. This convergence takes slightly more than 10 seconds. So if you need instant-on and real-time, you’re not getting it with this solution!

What no one told us
I think we were all so excited to get this little camera for the Pi no one bothers to talk about the actual optical properties of the thing! And maybe they should. because even if it is supposedly based on a cellphone camera, I don’t know which cellphone, certainly not the one from my Samsung Galaxy S3. The thing is (and I admit someone else first pointed this out to me) that it has a really small field-of-view. I measured it as spreading out only 8.5″ at a 15″ distance – that works out to only 31.6 degrees! See what I mean? And I don’t believe there are any tricks or switches to make that larger – that’s dictated by the optics of the lens. This narrow field-of-view may make it unsuitable for use as security camera or many other projects, so bear that in mind. If I put my Samsung next to it and look at the same view its field of view is noticeably larger, perhaps closer to 45 degrees.

Special Insights
At some point I realized that the getting started guide put things very awkwardly in making the PC the server and the Pi the client. You normally want things the other way around, like it would be for an ethernet camera! So my special insight was to realize that nc could be used in the reverse way they had documented it to switch client/server roles. nc is still a lousy “server,” if you can call it that, but hey, the price is right.

Fighting lag
To address the convergence problem mentioned above I chose a frame rate much higher on the viewer than on the camera. The higher this ratio the faster convergence occurs. So I have a 3:1 ratio: 60 fps on mplayer and 20 fps on raspivid. The PC does not seem to strain from the small bit of extra cpu cycles this may require. I think if you have an exact fps match you never get convergence, so this small detail alone could convince you that raspivid is always laggy when in fact it is more under your control than you realized.

Even though with the video quality such as it is there probably is no real difference between 10 fps and 20 fps, I chose 20 fps to reduce lag. After all, 10 fps means an image only every 100 msec, so on average by itself it introduces a lag of half that, 50 msec. Might as well minimize that by increasing the fps to make this a negligble contributor to lag.

Measuring lag
Take a smartphone with a stopwatch app which displays large numbers. Put that screen close up to the Pi camera. Arrange it so that it is next to your PC monitor so both the smartphone and the monitor are in your field of view simultaneously. Get mplayer.bat running on your PC and move the video window close to the edge of the monitor by the smartphone.

Now you can see both the smartphone screen as well as the video of the smartphone screen running the stopwatch (I use Swiss Army Knife) so you can glance at both simultaneously and quantify the lag. But it’s hard to look at both rapidly moving images at the same time, right? So what you do is get a second camera and take a picture of the two screens! We did this Saturday and found the difference between the two to be 0.2 s. To be more scientific several measurements ought to be taken and results avergaed and hundredths of seconds perhaps should be displayed (though I’m not sure a still picture could capture that as anything other than a blur).

mplayer strangeness on Dell Inspiron desktop
I first tried mplayer on an HP laptop and it worked great. It was a completely different story on my Dell Inspiron 660 home desktop however. There that same mplayer command produced this result:

...
VO: [directx] 640x480 => 640x480 Packed YUY2
FATAL: Cannot initialize video driver.
 
FATAL: Could not initialize video filters (-vf) or video output (-vo).
 
 
Exiting... (End of file)

So this was worrisome. I happened on the hint to try -vo gl and yup, it worked. Supposedly it makes for slower video so maybe on PCs where this trick is not required lag could be reduced.

mplayer personal preferences
I liked the idea of a window without a border (-noborder option) – so the only way to close it out is to kill the CMD window, which helps keep them in sync. Running two CMD windows doesn’t produce such good results!

I also wanted the window to first pop-up in the upper right corner of the screen, hence the -geometry 600:50

And I wanted the video screen to always be on top of other windows, hence the -ontop switch.

I decided the messages about cache were annoying and unimportant, hence the message suppression provided by the -msglevel all=0 switch.

Simultaneously recording and live streaming
I haven’t played with this too much, but I think the unix tee command works for this purpose. So you would take your raspivid line and make it something like:

raspivid -n -o – -t 9999999 -rot 180 -w 640 -h 480 -b 1000000 -fps 20|tee /home/pi/video-`date +%Y%h%d-%H%M`|nc -l 443

and you should get a nice date-and-time-stamped output file while still streaming live to your mplayer! Tee is an under-appreciated command…

Conclusion
I have tinkered with the Pi until I got its camera display to be screaming fast on my PC. I’ve shown how to do this and described some limitations.

Next Act?
I’m contemplating superimposing a grid with tick marks over the displayed video. This will help the robot driver establish their position relative to fixed elements on the field. This may be possible by integrating, for instance, openCV, for which there is some guidance out there. But I fear the real-time-ness may greatly suffer. I’ll post if I make any significant progress!
Update: I did get it to work, and the lag was an issue as suspected. Read about it here.

References and related
First Robotics is currently in season as I write this. The competition this year is Aerial Assist. More on that is at their web site, http://www3.usfirst.org/roboticsprograms/frc
Raspberry Pi camera quick start is a great place to get started for newbies.
Setting one or more static IP addresses on your Pi is documented here.
How not to set up your Pi for real-time video will be documented here.
How to get started on your Pi without a dedicated monitor is described here.
Finally, how to overlay a grid onto your video output (Yes, I succeeded to do it!) is documented here.
Correct source for smplayer for Windows.

Categories
Network Technologies Raspberry Pi

Making the Raspberry Pi camera look like an Axis ethernet camera

Intro
I can’t add much to this excellent guide:

http://blog.miguelgrinberg.com/post/how-to-build-and-run-mjpg-streamer-on-the-raspberry-pi

except a few customizations and suggestions.

I think we will be able to manage to make the Raspberry Pi + its camera behave like an Axis ethernet camera. This can be useful for First Robotics. But I haven’t proven it out yet, I’m just anticipating it can be done.

I will also mention there is a better way to get real-time true motion video (see the references) and there are sure a lot of ways to not even come close – I know because I tried a bunch of dead-ends before I hit on a good way to do this! I will try to share some of my failures so others can avoid things like vlc, motion, raspi-still, etc.

The details
The Axis camera (I think its model 206) sends output via MJPG (motion JPEG). The Raspberry Pi camera can be made to do the same, with a little tweak here and there.

For instance the mjpg-streamer’s default port is 8080, but you can change it to 80, just like the Axis camera.

Instead of

$ LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i “input_file.so -f /tmp/stream -n pic.jpg” -o “output_http.so -w /usr/local/www”

do this:

$ LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i “input_file.so -f /run/shm -n pic.jpg” -o “output_http.so -p 80 -w /usr/local/www”

You’d better make sure you don’t have an apache server or something else listening on port 80, however.

Our enemy – lag
Although this command provides some helpful insights into the efficient running of raspi-still:

$ raspistill –nopreview -w 640 -h 480 -q 5 -o /run/shm/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &

it is not sufficient by itself to eliminate all lag, unfortunately. I think the -q switch is a big help, however. In my testing lag seems to be under a second. So, ok, but nothing to write home about. But it’s easy to make it worse than that….

I settled on this testing methodology to get more precise results about lag and frames per second (fps). I held my smartphone with its stopwatch app running next to the computer screen, with the Pi camera close and pointed at the phone. So in my field of view could see the actual phone plus the phone image from the Pi on the laptop. This test was very helpful in illuminating what is going on in fact.

No matter how many fps I requested (e.g., 10 fps by setting -tl 100) the best I can do is a frame every 0.6 seconds (1.6 fps). Because of the stopwatch app I know this pretty precisely! The other interesting thing is that contrary to what i thought prior to doing this more quantitative test, the lag actually isn’t all that bad! It’s maybe 0.2 s. What made the lag seem larger is that you often get “unlucky” and your motion seems delayed because there are so few frames per second repainting the screen.

To be continued…

Other bad approaches
Suuposedly, i was assured, true motion video can be achieved following this recipe. It uses a package called motion. There is no use of either raspistill or raspivid, which is probably a good thing. I have to yet try this out – I just learned about it. Apparently it also solves the lag problem, at least at a low frame rate. This turned out to be one of those dead ends for me. Yes it more-or-less works, but not in real-time and not providing smooth motion.

References
I finally achieved true motion video and documented it in great detail in this post.

Categories
Admin Network Technologies Raspberry Pi

Basic networking: creating a virtual IP in Debian Linux

Intro
A quick Internet search showed a couple top-level matches that didn’t quite work for me, so I’m documenting how I got my multiple IP assignments on one interface to stick. This was work done for my Raspberry Pi, but it should apply to any Debian Linux system.

The details
This was work done for my Raspberry Pi, but it should apply to any Debian Linux host. I made my file /etc/network/interfaces look as follows:

auto lo
auto eth0
auto eth0:0
 
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
 
# virtual IP on eth0
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

I think the key statement which is missing on some people’s examples are the lines at the top of the file:

auto lo
auto eth0
auto eth0:0

When I didn’t have those I was finding that my primary IP was defined upon reboot, but not my virtual IP, although the virtual IP could be dynamically created with a simple

sudo ifup eth0:0

Still, I wanted it to survive a reboot and adding the auto lines did the trick.

Conclusion
A few of the pages you will find on the Internet may give incomplete information on how to configure virtual IPs in Debian Linux. The approach outlined above should work. Additional virtual IPs would just require sections like eth0:1, eth0:2, etc modelled after what was done for eth0:0

References
I present some basic information on one way to get started on the Pi without an external monitor (yes, it can be done) here!
If you think you like networking, you will learn a lot of useful tips in this posting which describes how to turn your Raspberry Pi into a full-blown router.

Categories
Network Technologies

How we got a little extra oomph from our firewall cluster, and why this trick no longer works for us

Intro
I was a running some Checkpoint firewalls in a cluster. In fact it’s been that way for years and years. At some point you get comfortable and forget to challenge and understand how it was set up. In this case re-examining the setup rewarded us with temporary survival as we were able to offload the primary member. Read on for the details…

The details
This firewall cluster included an active/standby pairing – a Nokia cluster with no state sync. The active firewall, an older model, was often hitting 99% or even 100% cpu usage on a daily basis. Dropped packets were correlated with these cpu spikes, and time-sensitive protocols, especially SIP used by IP phones, suffered mightily. Call quality often degraded, or the call was altogether dropped.

Some other relevant facts in this case: these firewalls were not doing NAT, they were acting more like routers with a firewall function. There are a handful of key servers behind them, like a VPN concentrator, a proxy, a Juniper ISG VPN concentrator, etc. On the external side was an Internet router, also under our control.

So the breakthrough was in revisiting what makes them active/passive in the first place. We weren’t relying on Checkpoint clustering. We used VRRP, defined through a Voyager setup. Then we set up our routing on all protected devices to use these VRRP IPs for their default routes. It all worked great until more and more usage crept in and then complaints started rolling in.

Upgrading costs $$ and the procurement cycle takes some time. What to do immediately, if anything?

The loudest complaints were from users of the Juniper ISG SSL VPN concentrators, who ran VOIP over those connections. What I realized (which of course is obvious in hindsight), is that this device could have all its traffic routed to the standby firewall where there was no cpu load whatsoever, and leave everything else on the active firewall.

How we did it
This was accomplished by adjusting the default route of the ISG to use the physical IP of the standby firewall, as opposed to the VRRP IP. Then, to avoid asymmetric routing, a host route was defined on the Internet router for this ISG, using as gateway the physical external IP of the standby firewall (again as opposed to the external VRRP IP.)

How it worked
It worked like a charm. We were well below our Internet link capacity, after all. So the master firewall was really the chokepoint for this voice traffic. Once we got it onto this unused firewall all the complaints stopped.

This is of course just a stop-gap measure because of course now we have no redundancy if we lose one of the firewalls. But meanwhile we’ve bought some time and kept the work-from-home users running smoothly. The master firewall still hits 99% cpu, but not quite as frequently. It’s difficult to find a true root cause, but an upgrade is definitely in order. Acceleration is already in place.

Why it won’t work for you – Checkpoint Cluster
Fast-forward five years and I tried this same trick which has served me well over the years. No worky. Why? Well these days we’ve switched to use of a Checkpoint Cluster with SYNC. In a Checkpoint cluster the secondary firewall will not forward traffic. In fact a firewall guy was the first to inform me of that. I didn’t believe him so I went ahead and configured it anyway. Sure enough, it simply didn’t work.

So for us, this trick has played itself out. But we used it multiple times during the five years it was available to us.

Conclusion
By re-visiting some old design principles were we able to get a little more mileage out of our firewalls and buy ourselves some time until we can do a planned upgrade.

Categories
Network Technologies

The IT Detective Agency: Why our forwarding vserver doesn’t route

Intro
F5 BigiP appliances are very versatile networking appliances. But sometimes you gotta know what you are doing!

The details
We set up a load-balanced Radius service using the same subnet for the radius servers as the load balancer itself. Setting up this service is moderately tricky. You have to set the default route of the Radius servers to be the load balancer, and on the load balancer SNAT (which I prefer to translate as “source NAT,” though technically it is “secure NAT”) and NAT should be disabled. And there are two services, AAA and audit (UDP ports 1812 and 1813).

So everything’s a bit different when all you'[re used to is creating load-balanced pools for web servers.

So with this setup an incoming packet comes in, its source is preserved, but its destination is NAT’d to the radius server by the load balancer. In the response, the source is the radius server. That gets NAT’d to the IP of the load-balanced service. So there are two stages for incoming request packets (pre- and -post NAT) and two for the responses. Here’s a trace which shows all this:

12:10:41.259073 IP drj-wlc-nausresea055-01.drj.com.filenet-rpc > radius.drj.com.radius: RADIUS, Access Request (1), id: 0x30 length: 260
12:10:41.259086 IP drj-wlc-nausresea055-01.drj.com.filenet-rpc > wusandradaa01.drjad.drj.net.radius: RADIUS, Access Request (1), id: 0x30 length: 260
12:10:41.259735 IP wusandradaa01.drjad.drj.net.radius > drj-wlc-nausresea055-01.drj.com.filenet-rpc: RADIUS, Access Reject (3), id: 0x30 length: 44
12:10:41.259745 IP radius.drj.com.radius > drj-wlc-nausresea055-01.drj.com.filenet-rpc: RADIUS, Access Reject (3), id: 0x30 length: 44

So all is good, right? Except that now we have a default route from the Radius server to the load balancer and so all response traffic is going through the load balancer, even things not related to Radius, such as a packets from an RDP session.

So we defined a forwarding_vserver to make the BigIP act as a router:

A forwarding vserver is a virtual server of type Forwarding (IP). In the bigip.conf file it looks like this:

virtual forwarding_vserver {
   ip forward
   destination any:any
   mask 0.0.0.0
   profiles route_friendly_fastL4 {}
}

But it doesn’t work! Packets from the Radius server come to the load balancer, and then they get source NAT’d to the floating self-IP of the load balancer. That’s no good. In TCP your response packets have to come from the IP you connected to! For simple PINGs you kind of get away with it, but with a warning. In TCP your PC will send a RST (reset) packet every time it gets a response packet with the wrong source IP, even if the other information is correct.

The solution
With the help of someone who understands snat auto-maps better than I do (evidently), I got the tip that I have a global snat-automap enabled, which is doing this. That’s how I’ve always run these LTMs (Local Traffic Managers). I had forgotten why or how I did it. Well the snat-automap pretty mcuh applies to all my other load-balanced services so I can’t simply chuck it. And I don’t have another subnet handy for use so I can’t simply exclude one of my vlans. They suggested that it could be turned off on my forwarding_vserver with an irule! Who would have figured? So I created a very simple irule:

# Turn off snat, i.e., for us in our forwarding_vserver
# inspired by https://devcentral.f5.com/wiki/iRules.snat.ashx
# DrJ, 11/2013
when CLIENT_ACCEPTED {
         snat none
}

and applied it to my forwarding_vserver, which now looks like this:

virtual forwarding_vserver {
   ip forward
   destination any:any
   mask 0.0.0.0
   rules snat-none
   profiles route_friendly_fastL4 {}
}

And voila, the LTM now routes those packets correctly without any address translation! And the Radius service still does its translations as desired.

Case closed!

Conclusion
We learned a little about F5 BigIPs today. The frustrating thing about the documentation is that they don’t really cover actual use cases so they introduce configuration settings without fully explaining why you would want to use them.

For the curious, the forwarding_vserver is accomodating an asymmetric routing situation. Incoming RDP (remote desktop protocol) packets get sent directly from a Cisco router to the Radius server. It’s just the response packets that flow from the Radius server, to the LTM, to the Cisco router.

References and related
In this post I show why a basic virtual server might not be working – a kind of rookie mistake we’ve all probably made at some point!
This post shows some non-trivial iRule examples.