Sunday, June 23, 2013

Autosnort-CentOS progress -- SELinux, ROR, passenger, and Snorby all working in Harmony

I've been working pretty hard on getting The CentOS autosnort build up to par with the Debian and Ubuntu autosnort builds, and for the most part, I'm nearing the end of the road there.

Aside from work and my regular everyday life, I've been spending my weekends mostly working on getting Snorby to run on CentOS with SELinux enabled. I'm a firm believer that in this day and age you shouldn't have to turn off SELinux to make your application work.

According to Wikipedia, SELinux has been around since the year 2000 and mainlined into the 2.6 kernel since 2003. It's been close to over ten years since SELinux was rolled out. Turning it off isn't a solution. It's a work-around, and pardon my french, an incredibly shitty and lazy work-around at that.

Now, I've made it no secret that I do not like ROR at all. This could be for a number of reasons -- I'm a newb programmer, I haven't developed webapps, I don't know what I'm talking about -- take your pick. Do not take this as a personal attack if you love ROR for one reason or another. Ruby OTOH has given us pretty interesting things, such as the Metasploit Framework.

In troubleshooting this how to get Snorby and SELinux to behave I had to learn how to write SELinux policy modules. As a side note, I would like to thank whoever on github posted this gist:

The code that I am dropping below is HEAVILY based on this individual's work getting passenger to work under SELinux without turning it off. I don't know who you are, but I salute you.

Let me give you a bit of background. SELinux is incredibly modular, there are several different ways you can tell SELinux to allow an application to do certain things, access certain resources, etc. You can use chcon to tell SELinux to allow a process to access files (think of this as another layer on top of the file access controls that we all know and love with chmod/chown), there are booleans you can set that, almost windows registry-like tell SELinux to allow a process to be able to interact with a mysql database or connect over the network.

Then there is the ability to write your own modules via selinux development tools to load into SELinux and in turn load into the kernel. You would generally do this if the application is very complex and needs to get its hands into a lot of places.

The research I did on this over the weekend varied. Most places suggest just running the application over and over again -- each iteration, just running audit2allow to determine what it is that httpd wants access to and building a policy module out of it.

I kept doing this, and more and more things would be allowed, then of course, the next thing in the way would break. It felt like dependency hell all over again.

Eventually I found that block of code by someone who had apparently been here before and decided to iterate through audit2allow probably hundreds of times to develop a single policy for passenger. I took it, ran with it, and improved it. Over the last few evenings I expanded upon it, and finally got Snorby to a point to where it will run with 0 errors and full functionality with SELinux enforcing and in targeted mode.

Have a look; I'll be posting this code to github soon, but I wanted to copy it here just to give you an idea of what the hell this application has access to on your system:

### begin code ###
module passenger 1.0;

# Not an expert at SELinux module building, but this is similar to library declarations in C programming -- these are things that the module needs to be able to do and contexts the module needs to be able to understand/communicate with

require {
        type init_t;
        type initrc_t;
        type system_cronjob_t;
        type mysqld_t;
        type usr_t;
        type syslogd_t;
        type system_dbusd_t;
        type abrt_dump_oops_t;
        type dhcpc_t;
        type kernel_t;
        type auditd_t;
        type udev_t;
        type mysqld_safe_t;
        type postfix_pickup_t;
        type sshd_t;
        type crond_t;
        type getty_t;
        type anon_inodefs_t;
        type httpd_tmp_t;
        type devpts_t;
        type user_devpts_t;
        type httpd_sys_script_t;
        type security_t;
        type httpd_t;
        type unconfined_t;
        type selinux_config_t;
        type hi_reserved_port_t;
        type httpd_sys_content_t;
        type httpd_sys_rw_content_t;
        type var_t;
        type cert_t;
        type postfix_qmgr_t;
        type postfix_master_t;
        class file { getattr read create append write execute execute_no_trans open };
        class process { siginh signal noatsecure rlimitinh setpgid getsession };
        class unix_stream_socket { read write shutdown };
        class chr_file { read write append ioctl };
        class capability { setuid dac_override chown fsetid setgid fowner sys_nice sys_resource sys_ptrace kill };
        class fifo_file { setattr create getattr unlink };
        class sock_file { write getattr setattr create unlink };
        class lnk_file { read getattr };
        class udp_socket name_bind;
        class dir { write read search add_name getattr };

#This stuff below is more of an access control list -- these are things the contexts below are requesting to be able to do in order to run properly.
#============= httpd_sys_script_t ==============
allow httpd_sys_script_t abrt_dump_oops_t:dir { search getattr };
allow httpd_sys_script_t abrt_dump_oops_t:file { read open };
allow httpd_sys_script_t anon_inodefs_t:file { read write };
allow httpd_sys_script_t auditd_t:dir { search getattr };
allow httpd_sys_script_t auditd_t:file { read open };
allow httpd_sys_script_t cert_t:dir { search getattr };
allow httpd_sys_script_t cert_t:file { read getattr };
allow httpd_sys_script_t cert_t:lnk_file read;
allow httpd_sys_script_t crond_t:dir { search getattr };
allow httpd_sys_script_t crond_t:file { read open };
allow httpd_sys_script_t devpts_t:chr_file { read write };
allow httpd_sys_script_t dhcpc_t:dir { search getattr };
allow httpd_sys_script_t dhcpc_t:file { read open };
allow httpd_sys_script_t getty_t:dir { search getattr };
allow httpd_sys_script_t getty_t:file { read open };
allow httpd_sys_script_t httpd_sys_content_t:fifo_file setattr;
allow httpd_sys_script_t httpd_sys_content_t:sock_file { create unlink setattr };
allow httpd_sys_script_t httpd_sys_rw_content_t:file { execute execute_no_trans };
allow httpd_sys_script_t httpd_t:dir { search getattr };
allow httpd_sys_script_t httpd_t:file { read open };
allow httpd_sys_script_t httpd_t:unix_stream_socket { read write };
allow httpd_sys_script_t httpd_tmp_t:fifo_file setattr;
allow httpd_sys_script_t httpd_tmp_t:sock_file { write create unlink setattr };
allow httpd_sys_script_t init_t:dir { search getattr };
allow httpd_sys_script_t init_t:file { read open };
allow httpd_sys_script_t initrc_t:dir { search getattr };
allow httpd_sys_script_t initrc_t:file { read open };
allow httpd_sys_script_t kernel_t:dir { search getattr };
allow httpd_sys_script_t kernel_t:file { read open };
allow httpd_sys_script_t mysqld_safe_t:dir { search getattr };
allow httpd_sys_script_t mysqld_safe_t:file { read open };
allow httpd_sys_script_t mysqld_t:dir { search getattr };
allow httpd_sys_script_t mysqld_t:file { read open };
allow httpd_sys_script_t postfix_master_t:dir { search getattr };
allow httpd_sys_script_t postfix_master_t:file { read open };
allow httpd_sys_script_t postfix_pickup_t:dir { search getattr };
allow httpd_sys_script_t postfix_pickup_t:file { read open };
allow httpd_sys_script_t postfix_qmgr_t:dir { search getattr };
allow httpd_sys_script_t postfix_qmgr_t:file { read open };
allow httpd_sys_script_t self:capability { setuid chown fsetid setgid fowner dac_override sys_nice sys_resource sys_ptrace kill };
allow httpd_sys_script_t self:process { setpgid getsession };
allow httpd_sys_script_t sshd_t:dir { search getattr };
allow httpd_sys_script_t sshd_t:file { read open };
allow httpd_sys_script_t syslogd_t:dir { search getattr };
allow httpd_sys_script_t syslogd_t:file { read open };
allow httpd_sys_script_t system_cronjob_t:dir getattr;
allow httpd_sys_script_t system_dbusd_t:dir { search getattr };
allow httpd_sys_script_t system_dbusd_t:file { read open };
allow httpd_sys_script_t udev_t:dir { search getattr };
allow httpd_sys_script_t udev_t:file { read open };
allow httpd_sys_script_t unconfined_t:dir { search getattr };
allow httpd_sys_script_t unconfined_t:file { read open };
allow httpd_sys_script_t unconfined_t:process signal;
allow httpd_sys_script_t user_devpts_t:chr_file { read write append ioctl };
allow httpd_sys_script_t usr_t:file execute;
allow httpd_sys_script_t var_t:dir { write read add_name };
allow httpd_sys_script_t var_t:file { read getattr create append };
#============= httpd_t ==============
allow httpd_t hi_reserved_port_t:udp_socket name_bind;
allow httpd_t httpd_sys_content_t:fifo_file { create unlink getattr setattr };
allow httpd_t httpd_sys_content_t:sock_file { getattr unlink setattr };
allow httpd_t httpd_sys_script_t:process { siginh rlimitinh noatsecure };
allow httpd_t httpd_sys_script_t:unix_stream_socket { read write shutdown };
allow httpd_t httpd_tmp_t:fifo_file { create unlink getattr setattr };
allow httpd_t httpd_tmp_t:sock_file { getattr unlink setattr };
allow httpd_t security_t:dir search;
allow httpd_t self:capability { fowner fsetid };
allow httpd_t selinux_config_t:dir search;
allow httpd_t var_t:file { read getattr };
allow httpd_t var_t:lnk_file { read getattr };

### end code ###

Admittedly there are a number of things above that make sense that Snorby would need access to -- sockets, file execution, making its own fifos, managing its own files and process execution options, etc. but then there are other things that just made me go WTF. Why does the webapp need access to crond? to getty sessions? pts? sshd? cronjobs? files and directories under the unconstrained context? dhcp files? auditd files?

I could be blowing this entirely out of proportion, but I worked with snortreport, BASE and aaval, and there were a minimal number of things I had to enable to get each of those interfaces to work under SELinux. Maybe PHP is just better integrated into SELinux, or maybe SELinux knows that PHP is beyond hope and doesn't even try to constrain it. I don't know, but reading through the module and seeing what it has access to is kinda crazy to me.

Okay, so now that I'm off my soapbox, you're probably wondering when to expect a code push for CentOS.

The answer is: soon. I know that's not the answer you all want to hear, but it's the best I can give right now -- The rewrite of the main script is mostly done. At this point, I'm working on re-writing the child shell scripts, prettying them up, and also ensuring that Snorby plays nice.

I'm going to re-iterate again, that this isn't any sort of a personal attack on any developer of any web interface, or against any platform, just my (probably ill-informed) opinion based on my observations.

Until next time,


Addendum: I thought I would add a note stating that the I've posted the code above into an SELinux module that is available via autosnort's github under the CentOS autosnort directory, in a subdirectory called  "PolicyModules". the directory contains passenger.te as well as a PolicyModulesNotes.txt file that details how to actually compile the passenger.te file into an SELinux module. This is for those who may not necessary care to use autosnort, may not care to use Snorby, but may need some help trying to figure out what accesses Ruby, Rails, and Passenger want on SELinux enabled systems.

I hope that it is some help to the Linux community.

Friday, June 14, 2013

New Autosnort Release, support for more distros and much more!


Lots to talk about, so let's get started.

I finally got around to finishing testing for the new, improved, and much cleaned up build of Autosnort that I had been hyping for a little while. For those who didn't see the last blog post, or the screen shot, I've done a bit of housekeeping with Autosnort.

Instead of puking the output for every single command all over the screen buffer, Autosnort's output has been significantly minimized and cleaned up where it could be cleaned up. Output is now very metasploit-like:

[*] are things that the script is doing
[*] are things the user should pay attention to
[*] are successful results
[*] are unsuccessful results

"Okay, so what if something goes wrong? All I have is a generic 'something went wrong' comment." Well, instead of hoping whatever you need was caught in the screen buffer, autosnort now logs the output of the ENTIRE installation to /var/log/autosnort_install.log, and /var/log/[interface you chose to install here -- for example, snort_install.log], So now, instead of having to hope the screen buffer caught the relevant bits of a problem with my script, you now have an entire log of what the script was actually doing for review, or to send to me to debug the script and get it to work properly.

The script will now actually tell you where I installed things, instead of you having to hunt and guess (sorry about that..)

Additionally, this release sees support for Ubuntu 13.04 and Debian 7. Currently in the process of Verifying support for Kali Linux (Backtrack's newer, younger sibling), but since it's all supposed to based off Debian and follows the Debian software methodology, it should be pretty straightforward.

The child installer scripts all got this little makeover, and as previously mentioned also have logging built in, and write to their own log files in /var/log.

The only thing of note that changed here in addition to the minimizing of output would be that I finally added a prompt to run Aanval's BPU processes on boot via rc.local. That's something I've been meaning to do for a while.

So now that this is over with, the next step would be for me to focus on Getting CentOS updated -- Snorby and the cleaned up autosnort script. That is next up on my plate before enabling anymore features on any platform. period.

After that is finished, here's what I'd like to focus on:

- All web interfaces should have SSL/HTTPS enabled by default. No exceptions.
- Remove database/barebone sensors should have a method to secure database transactions to the "Master Console"
+ some point way far down the line, I want to begin experimenting with p0f. The project has recently gotten some new blood (as mentioned in a recent shmoocon), and there are some interesting possibilities I can think of where p0f and snort could play incredibly well off of one another:
--have p0f run for a set period of time, sample traffic off the network, fingerprint operating systems and write results to a database
--script something out that takes the database results and helps write frag3/stream5 reassembly policies based off p0f results.

Same as always, the scripts are available via The Autosnort Github Repo

That's about it for now. Happy snorting, hope you enjoy the new release!


Friday, June 7, 2013

Autosnort: MSF edition

Working on some changes to Autosnort.

After seeing Darkoperator's MSF Installer script, I wanted to change how Autosnort operates a little bit.

You see, one of the cool things about metasploit is that It will log to hell and back if things are or are not working, but while you're actually running it, It only tells you what you need to know:
 "This is what I'm trying to do right now"
"This good thing happened"
"This bad thing happened"
"This is something to be aware of."

Keeping this in mind, and heavily ganking the notification printing code from darkoperator, in combination with a crazy named pipe trick I found via stack overflow, I'm changing how autosnort presents information.

As it stands currently, Autosnort, to put it bluntly, pukes all over the terminal/screen buffer. If something exploded in a bloody mess or failed to install correctly, you may see it and may be able to capture it in a screen shot and report it back to me, or you may not. Digital gods only know.

The way I've re-written the script, the only thing that gets printed to the screen are status messages indicating what the script is doing, good/bad messages to let you know if something failed or succeeded, and notifications that are sort of a "I need your input here" or "Pay attention to this!"

Apt-get (with the exception of the mysql-server installation that REQUIRES user input), configuration, compiler and all other output is redirected to log files.

For those of you who like seeing autosnort puke all over the screen or actually seeing what's going on behind the scenes, I found a nifty hack via stack overflow that uses mkfifo and named pipe magic to log everything from the script into a log file. No more running script to log output, no more screenshots, if you have a problem, you can e-mail me the output from the main autosnort script and/or the child interface installation scripts.

As of right now, I'm piloting this out on Debian, and it just looks slick. So far, I have the main script re-written and snorby's installation script re-written in this format. The other interface installers should fall in line easily enough, Snorby is the most complicated install I scripted out.

I haven't officially released either scripts out to github because I'm working on a couple other issues as well:

-- Support for both Debian 6 AND Debian 7 in the autosnort-debian main script
The only problem I'm seeing here at this point is that (for barnyard2) installs in three different places in Debian 6 32/64 and Debian 7 32/64:
/usr/lib (Deb 6 32 and 64 bit)
/usr/lib/i386-linux-gnu (Deb 7 32)
/usr/lib/x86_64-linux-gne (Deb 7 64)

so I'm testing out a work-around involving the 'find' command and 'dirname' to fix this once and for all.

-- Support for Ubuntu 13.04
It's a short-term release, but some want to see support for it. It also appears to have an issue finding

My theory is, if I can get find/dirname tested/working on Debian 6/7, likely I can get it to work between Ubuntu 12 and 13.04, hell I might be able to merge the Debian and Ubuntu autosnort scripts into a single script (since this was one of slight differences between the two).

So there's that.

I'm going to try and include a screenshot down here to preview what to expect, but so far, Blogger has somehow managed to not get my photos attached to my blog posts every time I've tried to use them.

First try:

Second try:
Via my twitter

Saturday, June 1, 2013

Not snort-related, but a good thing to know: How to tunnel VNC over SSH

So, this isn't strictly snort or autosnort related, but I figured I would post it anyhow. I primarily use SSH to manage my autosnort testing sensors in my virtual environment, but I also use vnc over SSH to manage my Attack system (A Kali Linux box -- was formerly Backtrack 5 r3) and thought I would share my experience on how to set up vnc server over SSH and have it look somewhat decent.

I've found a blog post here and a blog post there about how to tunnel VNC over ssh, but nothing really comprehensive. So I thought I'd share my knowledge on the bits of wisdom I've found strewn all over the net. If you have anything to contribute, or anything to add, please do so.

To begin, VNC is old and insecure; It encrypts absolutely nothing. This is why we're going to wrap it over SSH. In addition to a lack of encryption, VNC4's password functionality only allows 8-character passwords. This means the password can be broken fairly easily, even with a random password.

Tunneling VNC over SSH allows you to use stronger authentication (keys or huge long passwords, or both) in additional to the VNC password, setting up a basic form of multifactor authentication.

Most debian-based distro package sources include vnc server. It can be installed via:

apt-get install vnc4server

Afterwards, you will need to run vnc4server manually or vnc4passwd to specify a password for the current user for using VNC. again, the password can only be 8 chars long.

Additionally, in the user's .vnc folder (e.g. ~/.vnc or /home/[user]/.vnc/ ) is a file entitled xstartup

xstartup must be executable, and looks something like this:

# Uncomment the following two lines for normal desktop:
#exec /etc/X11/xinit/xinitrc

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources

#xsetroot -solid grey
#vncconfig -iconic &
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &

 Change the file to look something like this:

# Uncomment the following two lines for normal desktop:

exec /etc/X11/xinit/xinitrc

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources

#xsetroot -solid grey
#vncconfig -iconic &
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &
startx &;

if the .vnc directory doesn't exist, try running "vnc4server" to start up vnc. This should give you a .vnc directory and the file above. After starting it, immediately kill it via kill -9 or killall vnc4server.

Next, we need to make an init script to start up vnc at boot. I found this init script via

I've made some minor improvements, however. Copy these contents to /etc/init.d/vncserver:

# /etc/init.d/vnc4server
# Some things that run always

touch /var/lock/vnc4server

# Carry out specific functions when asked to by the system
case "$1" in

echo "Starting script vnc4server "
su root -c 'vnc4server -depth 24 -pixelformat RGB888 -localhost -geometry 1440x900 '

echo "Stopping script vnc4server"
su root -c 'killall Xvnc4'

echo "Usage: /etc/init.d/vnc4server {start|stop}"
exit 1


exit 0

The line that is doing the all the work of running the vnc server is this line:

 vnc4server -depth 24 -pixelformat RGB888 -localhost -geometry 1440x900

This line is essentially saying "start the vnc server with 24-bit color depth, with this RGB mapping and a resolution of 1440x900, and only allow it to listen on" (This last part is important! do not forget the -localhost line!) You can change the -geometry line to any resolution you wish, but I had to figure out the -depth and -pixelformat lines on my own, and mainly through trial and error.

next you'll have to make the file executable (chmod u+x /etc/init.d/vncserver)

after making the file executable, run:

update-rc.d vncserver defaults


update-rc.d vncserver start [runlevels you want the server to run on]

finally, the file make the xinitrc file executable. I've found that vnc won't work properly unless this file is executable:

chmod u+x /etc/X11/xinit/xinitrc

The higher the bit depth and resolution, the more packets you need to be able to push over the network (and your SSH tunnel) to keep things running smoothly. For this reason, I recommend that if you're going to use this configuration that it be over a high-speed link, or a local network. try changing the depth to 16, or making the resolution lower if you find the VNC session to be laggy.

So to summarize what we just did above we:

installed vnc4server

set up a vnc password for your user

made an init script for vnc4server

made all necessary preparations to host vnc4 server.

In this section I'll show you how to SSH tunnel to your VNC server either from windows or linux.

We'll start with windows. I use an awesome program called MRemoteNG for managing remote connectivity via a number of remote protocols -- VNC, RDP, SSH, .ICA (citrix), HTTP/HTTPS (xulrunner-- a bit buggy), etc. I can't stress how awesome MRemoteNG is for managing multiple connections. For those worried about having the app store connection information, it also allows you to encrypt the connection configuration files to keep your creds safe.

Download and Install MRemoteNG. Open it up and click Tools::Options:: and click advanced. Click "Launch Putty"

Here is where we're going to configure the portforwarding settings. Under Category, go down to Connections, click the plus sign on SSH, then click tunnels.

This page looks confusing, but it's really simple.

The only things you need to modify are

Source Port: set this to any arbitrary port number you want. Doesn't really matter. Just remember what it is. If you can't remember, you can always come back to this page.

For destination type this in exactly:

The more intrepid may ask "uh.. why am I putting localhost in as the destination?"

Because this is localhost on the REMOTE server (e.g. the system where VNC is listening on loopback ( only. So what this tunnel is saying is:

"After this user has successfully authenticated to me, have the client open up source port:[source port you choose]. If you get a connection on [source port you chose], funnel it over port 22. When it reaches the remote end, connect it to where the VNC server is listening."

Save your putty session by scrolling up, clicking on sessions, putting in a name under "saved sessions" then clicking save. Afterwards, you can close putty.

You'll need to create two mremoteng sessions here:

the first Mremote session, select ssh version tool as the protocol, enter the IP address (user name and/or password if you want) and under PuTTY session, click the drop down and save the session you made.

the second Mremote session, you'll choose VNC as the protocol. Enter the IP address "" and the source port that you entered when you created the putty session above. For the password, enter the password you entered when you ran vnc4passwd or vnc4server previously.

Next, double click on your ssh session in mremoteng, then double click on your localhost VNC session. You should have your remote system's desktop.

If you're doing this over Linux, it's not that much harder to do. Make sure your linux  connecting to the remote SSH (and VNC) server has an ssh client and a vncviewer application of some sort.

Open up a terminal window and type:

ssh -L 5901:localhost:5901 username@[hostname/ipaddress]

The -L line above is the secret sauce and works exactly the same as the what the putty session does:

[Source Port to listen on locally]:[target remote ip address]:[remote port to connect to]

So we tell SSH to open a listener on 5901 if your local workstation gets a connection on 5901, forward it over the SSH connection and send it to 5901 on the remote server's loopback address.

Next, just tell your vnc client to connect to and you're done.

Note: Some of the more intrepid among you may notice that there's now a listener on 6001/tcp. I've searched long and hard for the reasoning behind this. 6001/tcp is the default port for the first X server screen to use when X is told to listen for remote X client connections.

Some of you are probably freaking out. you don't want your server to allow connections to X windows. Don't freak out just yet; Sure enough, if you get NMAP scanned, NMAP will say the port is open. Netcat will connect and promptly get dropped. PuTTY RAW sessions stay open (probably because the remote X server has no idea what the heck the PuTTY RAW session is trying to do.) No remote X clients will be able to connect to the x server. While you are on your vnc session, If you type "xhost" in a terminal window "access control enabled, only authorized clients can connect" should be the response you get. In the olden days, way before even my time, No one thought to tunnel X over SSH. so they would use xhost to authorize remote users to connect to that system's X windows server. The format was usually xhost +{ip address} to allow a remote ip address to connect to your X server. Even more common was for most to just type xhost + (no ip address). This is the same as saying "Allow anyone to connect to my X server". You can probably imagine why this isn't a good idea.

So why am I telling you about this? Because by default, your X server (the one that VNC uses), for some stupid reason  has your X11 X windows server listen on 6001/tcp. From what googling I've done, there's no reason for this, and there's no way to configure X (without modifying the source code) to just listen on localhost. I've tried to find a solution that isn't "turn on your firewall, or just configure firewall rules to block it." That's a work-around, not a solution (A viable work-around, by the way, but not the point.) and I haven't find any (other than the just a firewall rule)

For those of you who aren't firewall gurus, you're in luck. by default, xhost doesn't authorize ANY remote users at all to connect to your X server. That means, as soon as anyone tries to connect to your X server, the session is dropped by X's own authorization system. The bottom line is: Don't freak out; no one is allowed to connect to it. You're safe. But if you know how to make X listen on only, I'd be very interested...

Final Note: On some sshd servers, TCP Forwarding is disabled. TCP forwarding is the magic by which all this tunneling happens. Meaning if it's disabled, then none of this works. Check /etc/ssh/sshd_config if you see the line "AllowTcpForwarding no" it means tcp forward is turned off. Conversely, if it is set to yes, then you're good to go. If you don't see this line in your sshd_config file, then you're good to go as well. It's implicitly allowed by default.