Tech Tip: TCP/IP Access Using bash

 in

Most of us default to wget, curl, netcat and others when in need of network data from the commandline, not knowing, or perhaps forgetting, that bash often provides the support that we need using redirection from /dev/proto/host/port.

For example:

  $ cat </dev/tcp/time.nist.gov/13

  55103 09-09-29 17:58:55 50 0 0   0.0 UTC(NIST) *

Reads the time in Daytime Protocol (RFC-867) from the NIST Internet Time Service server (documented at tf.nist.gov/service/its.htm).

The Advanced Bash-Scripting Guide includes some more involved examples in chapter 27, covering sending a protocol request, getting web pages, and even UDP use.

Editor's Note: If this does not work for you, make sure to read the comments below, this option is not enabled on all distros (among them, some versions of Ubuntu).

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

works in ubuntu since 9.10

Anonymous's picture

the functionality was added to ubuntu in 9.10. However it's in the bash binary; a ls of /dev/tcp and /dev/udp will turn up nothing -- but if you run strings on the bash binary, you'll see it's been added.

It's worth noting, however, that bash is not the default shell in karmic (9.10), dash is.

So be careful when scripting this to specify bash.

Any one knows why this

Anonymous's picture

Any one knows why this wasn't enabled by default?

netcat or socat instead!

jmtd's picture

I'd recommend using netcat or socat instead. You will end up with something that handle socket closure properly, without any extra work, and is a lot more legible. Certainly rebuilding bash on Debian/Ubuntu is rather over-kill.

Works on Gentoo

FJGreer's picture

Works on Gentoo out of the box!

Even works on Mac (Leopard)

Anonymous's picture

Heh even works on Mac (Leopard) :-)

Ubuntu 9.10

Anonymous's picture

Worked right out of the box on Kubuntu 9.10

Works well on Slackware :)

tomct's picture

Works well on Slackware :)

updated enable bash tcp redirect script

Geert's picture

I've updated the script written by Joseph E. Tole
I tried his script, and it didn't work because I didn't have all dependencies and there was a version change in the resulting .deb
The updated script:

#!/bin/bash
# Written by Joseph E. Tole 09/29/09
#Updated by G. Geurts 09/30/09

# This creates and then changes to a new temporary directory. mktemp should always be used to avoid accidently using an active file/dir.
bash_source="$(/bin/mktemp -d)"
cd "${bash_source}"

# Install the bash source.
apt-get source bash

# Dependencies
# The -y flag causes apt-get to assume you said yes and not prompt for y/n to install
/usr/bin/sudo apt-get build-dep -y bash
/usr/bin/sudo apt-get install -y dpkg-dev fakeroot
cd bash-3.2

# This line changes the rules file which has the configure script options predefined in it. This causes the compile to now include network support.
/bin/sed -e 's/--disable-net-redirections/--enable-net-redirections/' -i debian/rules

# This creates new .deb packages for bash which is several but we only need to install one since the others are copies of what is already installed.
/usr/bin/dpkg-buildpackage -rfakeroot

# Install the .deb. The asterisk is used for architecture independence. In my case it * matches _amd64 but this is different on non 64 bix x86 systems.
/usr/bin/sudo /usr/bin/dpkg -i ../bash_3.2-[45]ubuntu1*.deb

# The line below puts bash on hold within the package manager so that it is not automatically upgraded. If it is then you will lose this functionality.
echo 'bash hold' | /usr/bin/sudo /usr/bin/dpkg --set-selections

Ah right.

jetole's picture

Yeah it was a quick write and I forgot to include fakeroot. Thanks for the update.

Thanks for the script! ALso

geert's picture

Thanks for the script!
ALso there is a version change in the bash source... bash_3.2-[45]ubuntu1*.deb

Greetings,
Geert

You can't complain because

Anonymous's picture

You can't complain because Debain and 'Buntu are broken :)

I already posted the answer for debian/ubuntu!!!

jetole's picture

Read the comments before you post one. The second comment was me posting a bash script on how to enable this in debian/ubuntu and yet people are still saying it does not work in debian/ubuntu. If it did work I would not have posted the bash script below. Also before you say debian/ubuntu are broken, ubuntu and likely debian too has this option in the actual rules file they use as disabled (instead of just leaving that option as the default someone made the effort to turn it off) so debian/ubuntu did not want this enabled by default and I am sure they have their reasons. I manage debian, ubuntu, RHEL, CentOS and Windows servers and in all honesty I find package management on debian/ubuntu to be far far more complete then RHEL/CentOS since just today I could find fio, iotop and iozone3 in Ubuntu and could not find one in CentOS on the server whose IO speed I wanted to collect stats on so perhaps you should not be so ignorant when you call an OS broken but instead tote valid reasons why one is better then the other.

works like a charm

Anonymous's picture

Works great in CentOS 5.

Not on Debian-based Systems

Anonymous's picture

I tried this on my Ubuntu system and it did not work. So I looked at the bash manpage and saw the following:

NOTE: Bash, as packaged for Debian, does not support using the /dev/tcp and /dev/udp files.

Umm. No.

Anonymous's picture

This is a bash feature that is not present in all systems.

Take Ubuntu 8.10, aka Intrepid Ibex.

In its stock form, but with all current updates, this is what you get when you attempt it:

leif@patroler:~$ cat < /dev/tcp/time.nist.gov/13
bash: /dev/tcp/time.nist.gov/13: No such file or directory

But:
If bash was compiled with --enable-net-redirections, it has the capability of
using a special character device for both TCP and UDP redirections. These
redirections are used identically as STDIN/STDOUT/STDERR. The device entries
are 30,36 for /dev/tcp:

mknod /dev/tcp c 30 36

However, it appears that ubuntu's shell is not compiled with the redirection, as even after performing a mknod as root with correct permissions for the user to rw, this still does not work.

Further research shows this is disabled for most debian distros.

This does need to be enabled at compile time on bash.

jetole's picture

I just wanted to add then Debian and Ubuntu do not have this option as it is not compiled into bash on either of these systems by default. I have included a _quickly_written_ bash script below that will compile and install bash with network support. This works on Ubuntu 8.10 and 9.04 on AMD64 architecture and should work on x86 too and probably any architecture the Debian* system is installed on. Will likely work on any current Debian or Debian clone and if it is not current, then just the version of bash has to change (i.e. where we cd to bash-3.2 directory).

#!/bin/bash
# Written by Joseph E. Tole 09/29/09

# This creates and then changes to a new temporary directory. mktemp should always be used to avoid accidently using an active file/dir.
bash_source="$(/bin/mktemp -d)"
cd "${bash_source}"

# Install the bash source.
apt-get source bash

# Dependencies
# The -y flag causes apt-get to assume you said yes and not prompt for y/n to install
/usr/bin/sudo apt-get build-dep -y bash
/usr/bin/sudo apt-get install -y dpkg-dev
cd bash-3.2

# This line changes the rules file which has the configure script options predefined in it. This causes the compile to now include network support.
/bin/sed -e 's/--disable-net-redirections/--enable-net-redirections/' -i debian/rules

# This creates new .deb packages for bash which is several but we only need to install one since the others are copies of what is already installed.
/usr/bin/dpkg-buildpackage -rfakeroot

# Install the .deb. The asterisk is used for architecture independence. In my case it * matches _amd64 but this is different on non 64 bix x86 systems.
/usr/bin/sudo /usr/bin/dpkg -i ../bash_3.2-4ubuntu1*.deb

# The line below puts bash on hold within the package manager so that it is not automatically upgraded. If it is then you will lose this functionality.
echo 'bash hold' | /usr/bin/sudo /usr/bin/dpkg --set-selections

Some packages missing

kali's picture

Nice script/trick. However on default Ubuntu 8.04 Hardy you will need to manually install some packages before running it, such as:
sudo apt-get install -y fakeroot
sudo apt-get install -y dpkg-dev

Including those 2 lines to the #Dependencies section solved my life.

Thanks!!

This doesn't work on my

Anonymous's picture

This doesn't work on my system.

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix