Skip to content

ping (ICMP) blocked? No problem, enter hping!

When traveling while working we often find ourselves using networks that have certain restrictions. For example, many free WiFi hotspots will block things like ICMP echo requests (ping) which makes things a bit difficult when you are trying to figure out problems with connectivity, where packet loss is occurring, and what is reachable and what is not. Enter hping, a TCP/IP utility that can do far more than the name suggests.

First an example using standard ping (ICMP):

ping -c1 http://www.google.com
PING http://www.google.com (172.217.14.228) 56(84) bytes of data.

— http://www.google.com ping statistics —
1 packets transmitted, 0 received, 100% packet loss, time 0ms


As we can see in the above output, we never got a reply. Is the network down in between? Is there a firewall that’s blocking our requests? We don’t know.. So let’s take a look at using hping to send a TCP packet, instead of ICMP, to port 80 on a well known website:

sudo hping -c 1 -S -p 80 http://www.google.com
Password:
HPING http://www.google.com (wlp2s0 172.217.14.228): S set, 40 headers + 0 data bytes
len=44 ip=172.217.14.228 ttl=127 id=13972 sport=80 flags=SA seq=0 win=11680 rtt=51.0 ms

— http://www.google.com hping statistic —
1 packets tramitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 51.0/51.0/51.0 ms


Ah-ha! We got a reply! So TCP connections to port 80 at least are not blocked. We can work with that (hint this is where having your own custom, configurable OpenVPN server comes in handy: configure it to answer on port 80 and you are back to work).

Breakdown of the options used: as with the standard ping tool, the “-c” flag tells it we only want to send N count requests. In this example we are only sending one (1) request. Without this command line flag, hping (and ping) will ping non-stop until you stop it with ctrl-c. The next flag is “-S” which sets the SYN flag as by default it will not be set by hping. The “-p” flag tells hping we want to send our request to a specific port, in the above example we use port 80 which is the standard non-SSL webserver port. The last option is the hostname or IP address we want to interact with (www.google.com in our example.)

I am going to try something new and use a terminal utility named asciinema to record the examples above. Please let me know what you think: Watch a video of the above example made with asciinema!

Client PPtP Connection From A VM

I encountered an issue recently with trying to make a PPtP connection from a Linux VM as the client to a remote commercial device or server where the GRE packets were being dropped. The same PPtP credentials worked on another server that is bare metal. This lead me speculate that the issue might be something between the routing devices and the client. After a bit of investigative work with wireshark I discovered the GRE packets were in fact getting to the virtualization host but not to the guest VM. I suspect this issue may be present with other types of virtualization software, but to be clear this particular VM host is running KVM/QEMU.

It has been a while (read: years) since I’ve done much with PPtP beyond just using it. Adding a configuration that was working on another server to this particular system I discovered the connection would not complete much to my dismay. Looking at what ppp logged to the system log revealed it never got a proper GRE reply. Well, there were a lot of things in the log but the one that stood out looked like this:

warn[decaps_hdlc:pptp_gre.c:204]: short read (-1): Input/output error


After a bit of Googling and reading the documentation for pptp-client I decided re-try the setup on the previously mentioned working system and watch the log closely for further clues. Where the second system was failing the original system sailed right past and worked fine. My next attempt was to look at what connections the first system had going which lead to me realize and make a mental connection to the documentation/Googling had revealed about PPtP using protocol 47 (GRE) on TCP port 1723 for the control. Watching another attempt on the second system showed the outgoing request for GRE but nothing coming back. Repeating the last test but watching for incoming GRE on the host showed that it was being received but not being passed on to the guest VM. Looking at my options I discovered that there is a whole set of modules and a kernel configuration option to allow forwarding of PPtP.

The missing pieces to the puzzle include adding a line to your sysctl.conf:

net.netfilter.nf_conntrack_helper=1


Then loading these kernel modules:

nf_conntrack_proto_gre
nf_nat_proto_gre
nf_conntrack_pptp
nf_nat_pptp


As soon as these were in place PPtP started working as expected in the guest VM. What started out as a mystery turned out to be a fairly simple solution. While there are probably not a lot of people still using PPtP these days, it is a better alternative to using a proprietary VPN client.

Creating Your Own Encrypted File “Safe”

I often think about, no scratch that – I often worry about what would happen if my laptop was stolen or fell into “evil” hands. I mean there isn’t a lot on any of my machines that could be misused as most things are locked down. My Internet-based accounts such as my Google account require two factor authentication, important files are backed up, etc. However, there are special files, and here I’m specifically thinking about SSH private keys, that should never be out of my control. My solution is fairly simple: create an encrypted file that can be mounted as a loopback device.

The first step is deciding how much speed we are going to need as we cannot directly resize our encrypted file once it is created. If we later need more storage (or less) our only option is to create a new one and copy the contents of the old (mounted) safe to the new one. I use mine to store my entire ~/.ssh, ~/.gpg, and a few other files so my needs are fairly small. All of my files together account for less than 100MB, but knowing that I might want to expand later I decided on 1GB.

If we are using ext2/3/4, xfs, and probably a few other filesystems we can use fallocate to reserve our disk space. I say probably a few others as I know of at least one it doesn’t work on which is zfs.

fallocate -l 1G safe.img


The next step is to create an encrypted device on our new blank image:

cryptsetup luksFormat safe.img


During this step you will be prompted for a password and this is really the only weak spot (bugs not withstanding) in the entire setup. Make sure your password is long enough to make brute force unreasonably long and make sure it cannot be aided with any of the known dictionaries floating around. I made mine 31 characters long because it is long enough to make brute force unprofitable.

Once the encrypted data is written, we can proceed to opening the device:

cryptsetup open safe.img


You will be prompted to enter your password each time you open it so make sure you are using a trusted keyboard (i.e. not wireless).

The next step is to create a filesystem on our new safe:

mkfs.ext4 /dev/mapper/safe


Now, finally, we can mount it and start using it!

mount /dev/mapper/safe /mnt/safe


At this point you should be able to add files into your safe as if were any other mounted device.

Once you are done using your safe, don’t forget to unmount it and close it so that no-one can access it:

umount /mnt/safe

cryptsetup close safe


So now we know how to create, open, and close the device, but what sorts of things are good for storing in there? Well as previously mentioned I store my entire ~/.ssh/ directory in my safe. I moved the directory into /mnt/safe/ and then created a symlink from there to ~/.ssh which allows me to use everything I normally would (ssh, mosh, scp, etc.) without having to reconfigure anything.

What to do next is up to you, but I do tot trust the quality of USB thumb drives out there these days. So I opted to stick my safe on my local hard drive and include it in my backup scheme.