Category Archives: Networking

Reverse SSH Tunnel

To allow LOCAL_SERVER behind a firewall/NAT/Home Router to be accessible via SSH from a REMOTE_SERVER you can use a ssh tunnel (reverse).

Basically, from your LOCAL_SERVER you forward port 22 (ssh) to another port on REMOTE_SERVER, for example 8000 and you can ssh into your LOCAL_SERVER from the public IP of the REMOTE_SERVER via port 8000.

To do so, you need to run the following from LOCAL_SERVER:

 local-server: ~ ssh -fNR 8000:localhost:22 <user>@<REMOTE_SERVER>

On REMOTE_SERVER you can use netstat -nlpt to check if there is a service listening on port 8000.

Example:

remote-server ~# netstat -nplt | grep 8000
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      1396/sshd: root
tcp6       0      0 :::8000                 :::*                    LISTEN      1396/sshd: root

In this case, the REMOTE_SERVER allows connection from ALL the interfaces (0.0.0.0) to port 8000.
This means that, if the REMOTE_SERVER has IP 217.160.150.123, if you can connect to LOCAL_SERVER from a THIRD_SERVER using the following:

third-server: ~ ssh -p 8000 <user_local_server>@217.160.150.123

NOTE. If you see that the LISTEN connection on REMOTE_SERVER is bound to 127.0.0.1 and not to 0.0.0.0, it is probably related to the setting GatewayPorts set to no in /etc/ssh/sshd_config on REMOTE_SERVER.
Best setting is clientspecified (rather than yes) as per this post.

Set this value to yes and restart sshd service.

With that setting, you can potentially allow only connection from the REMOTE_SERVER to the LOCAL_SERVER, to increase security.
To do so, you need to use the following ssh command from LOCAL_SERVER:

 local-server: ~ ssh -fNR 127.0.0.1:8000:localhost:22 <user>@<REMOTE_SERVER>

With netstat, you’ll see now this:

remote-server:~# netstat -nplt | grep 8000
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      1461/sshd: root

With this forward, you will be able to access LOCAL_SERVER ONLY from the REMOTE_SERVER itself:

remote-server: ~ ssh -p 8000 <user_local_server>@localhost

I hope this helps ūüôā

Happy tunnelling!

Linux WiFi manual setup

You might have faced to have your laptop that doesn’t boot with your nice GUI interface, with Network Manager that handles your wifi connection. Maybe due to a failed update or a broken package.

Well, it happened to me exactly for that reason: some issues with an upgrade. And how can you fix a broken package or dependency without internet connection?

Oooh yes, that’s a nightmare! Thankfully, I found this handy article, which I will list some handy commands, that did help me in restoring the connection on my laptop, allowing me to fix the upgrade and restore its functionality.

NOTE: I had iwconfig and wpasupplicant already installed. If not, I should have downloaded the packages and all their dependencies and manually install them with dpkg -i command

Identify what’s the name of your wifi interface

iwconfig

This should return something like wlp4s0

Guessing that you know already the SSID (e.g. HomeFancyWiFi) of your wifi and the password (e.g. myWiFiPassw0rd), you can run directly this command:

wpa_passphrase HomeFancyWiFi myWiFiPassw0rd | sudo tee /etc/wpa_supplicant.conf
wpa_supplicant -c /etc/wpa_supplicant.conf -i wlp4s0

This will generate the config file, connect to the wifi. Once you see that all works as expected, you could use the -B flag to put the wpa_suppicant in background and release the terminal.

wpa_supplicant -B -c /etc/wpa_supplicant.conf -i wlp4s0

Alternatively, you can move to another tab (ALT+F1,F2,F3… in the text mode console), and run dhcpclient to get an IP and the DNS set.

dhclient wlp4s0

Once done, you can run iwconfig just to verify that the interface has the IP and do some basic network troubleshooting like ping etc to make sure all works, and you can go back to fix your broken upgrade ūüôā

Ubuntu 16.04 – Wake on LAN

I have struggled a bit trying to understand while my Ubuntu 16.04 wasn’t waking up with the common¬†

etherwake

  commad.

I found the solution on this link:

you should disable Default option in Network-Manager GUI and enable only the Magic option. If you try this, then you should check if everything is ok opening the shell and issuing this command:

sudo ethtool *<your_eth_device_here>*

You should see the line:

Wake-on: g

If it’s not¬†g¬†but¬†d¬†or something else, something could be wrong.

Once done that, and verified with the command 

ethtool <myNetinterface> | grep "Wake-on:" 

¬†, all started to work again ūüôā

 

Bridge / Bond interfaces CentOS/RedHat

Just few notes about how to bridge or bond network interfaces in CentOS/RedHat systems

# Install the required packages

yum install bridge-utils


BRIDGE
------

/etc/sysconfig/network-scripts/

#ifcfg-br0
DEVICE=br0
TYPE=Bridge
IPADDR=192.168.1.1
NETMASK=255.255.255.0
ONBOOT=yes
BOOTPROTO=none
NM_CONTROLLED=no
DELAY=0

#ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
HWADDR=AA:BB:CC:DD:EE:FF
BOOTPROTO=none
ONBOOT=yes
NM_CONTROLLED=no
BRIDGE=br0


#### USE SCREEN!!
service network restart 

================================
BOND >>> 2 or more eth interfaces!
----

#ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
USERCTL=no
SLAVE=yes
MASTER=bond0
BOOTPROTO=none
HWADDR=AA:BB:CC:DD:EE:FF
NM_CONTROLLED=no

#ifcfg-eth1
DEVICE=eth1
TYPE=Ethernet
USERCTL=no
SLAVE=yes
MASTER=bond0
BOOTPROTO=none
HWADDR=AA:BB:CC:DD:EE:FF
NM_CONTROLLED=no

#ifcfg-bond0
DEVICE=bond0
ONBOOT=yes
BONDING_OPTS='mode=1 miimon=100'
BRIDGE=br0
NM_CONTROLLED=no

#ifcfg-br0
DEVICE=br0
ONBOOT=yes
TYPE=Bridge
IPADDR=192.168.1.1
NETMASK=255.255.255.0
NM_CONTROLLED=no


# ifup bond0
#### USE SCREEN!!
# service network restart 


==========================

For DHCP and not static

DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes

 

Sources:

Linux Firewall notes

IPTABLES GENERIC

>> Allow port 80 ONLY to private interface for Cloud Load Balancer
-A INPUT -i eth1 -p tcp -m conntrack --ctstate NEW -m tcp --dport 80 -j ACCEPT

>> Block whole subnet
# iptables -I INPUT -s xxx.xxx.xxx.0/24 -j DROP

>> Allow specific IP only
iptables -I INPUT -p tcp -s YourIP --dport 22 -j ACCEPT

>> Delete rules

iptables -vnL --line-numbers

iptables -D <chain> /et<rule_number>
iptables -D INPUT 4

-A INPUT -s <SOURCE_NETWORK/32> -p tcp -m tcp --dport 21 -m comment --comment "FTP port open" -j ACCEPT
-A INPUT -s <SOURCE_NETWORK/32> -p tcp -m multiport --dports 60000:65000 -m comment --comment "FTP passive mode ports" -j ACCEPT

 


UBUNTU – UFW

service ufw status

ufw allow 80

ufw allow from <IP> to any port <port>

>> Allow network range
ufw allow 192.168.1.0/24

>> Delete rule
ufw status numbered
ufw delete <rule_number>

>> Allow port 80 only on eth1
ufw allow in on eth1 to [eth1 ip addr] port 80 proto tcp
# ufw allow from <SOURCE_IP>&nbsp;to any port 25
Rule added

# ufw delete allow from <SOURCE_IP> to any port 25
Rule deleted

ufw insert 1 allow from <ip address>

ufw deny from <ip address>
ufw deny from <ip address/24>

https://help.ubuntu.com/community/UFW

 


CENTOS / RH – Firewalld

Saved rules in: /etc/sysconfig/iptables

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="<SOURCE_IP>" port port="10000" protocol="tcp" accept'

firewall-cmd --reload

firewall-cmd --list-all

firewall-cmd --add-service http --permanent
firewall-cmd --add-service https --permanent
systemctl restart firewalld.service
firewall-cmd --list-services

>> Add manual rule in firewalld

firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -s 192.168.3.0/24 -m comment --comment "NFS Network" -j ACCEPT

>> Remove manual added rule in firewalld
vim /etc/firewalld/direct.xml

 

Remote port forwarding via SSH

Imagine that you¬†want to access a specific port on a remote server from your local machine. Basically, a “remote port forwarding”.

This remote server is not accessible directly from internet. It is NAT’d behind firewall.
To access the remote server you need to connect firstly to a remote bastion server (accessible from internet) and from there, you will be able to access the server.
Your current machine is also within restricted network and unable to ssh out. You can ssh into a local bastion server only. From this local bastion you can ssh out.

As long as you have access to the 2 bastions servers, you will be able to run the following script.

+-------------------------------+                  +-------------------------------+
|                               |                  |                               |
| +--------+         +--------+ |                  | +--------+         +--------+ |
| | LOCAL  |         | LOCAL  | |                  | | REMOTE |         | REMOTE | |
| | MACHINE| +-----> | BASTION| +---> INTERNET +---> | BASTION| +-----> | SERVER | |
| |        |         |        | |                  | |        |         |        | |
| +--------+         +--------+ |                  | +--------+         +--------+ |
|                               |                  |                               |
+-------------------------------+                  +-------------------------------+

The script points/links a local_port on your local machine to the ssh port of the remote bastion, via your local bastion.
After that, it will connect the remote port or the remote server to a new_local_port, ssh’ing via local_port.

Example below shows a way to have the VNC port 5900 available locally on port 5910.
I’m using port 8888 as local port.
Local Bastion ssh port is 8022.
Remote Bastion ssh port is 9022.

Example:

ssh -N -f -p 8022 -L8888:remote_bastion:9022 local_bastion_user@local_bastion
ssh -N -f -p 8888 -L5910:remote_server:5900 remote_bastion_user@localhost

 

And here a full script:

#!/bin/bash
#
# ============================================ #
# PORT FORWARD from CURRENT_HOST to DEST_HOST  #
# via LOC_BASTION and REMOTE_BASTION           #
# ============================================ #
#
# The scripts creates an SSH tunnel connecting
# the local port TUN_LOC_PORT to the REMOTE_BASTION ssh port
# via LOC_BASTION.
# After that, it forwards the remote port DEST_FW_PORT to
# DEST_FW_PORT using the ssh tunnel just created.
#
###########################################################

LOC_BASTION_HOST=""
LOC_BASTION_USER=""
LOC_BASTION_SSH_PORT=""

REMOTE_BASTION_HOST=""
REMOTE_BASTION_USER=""
REMOTE_BASTION_SSH_PORT=""

DEST_HOST=""
DEST_USER=""
DEST_FW_PORT="5900"

TUN_LOC_PORT="8888"
LISTENING_LOC_PORT=""

############################################################

CHECK_TUNS=$(ps aux | grep "[s]sh -N -f -p $LOC_BASTION_SSH_PORT -L$TUN_LOC_PORT:$REMOTE_BASTION_HOST:$REMOTE_BASTION_SSH_PORT $LOC_BASTION_USER@$LOC_BASTION_HOST" | awk '{print $2}')

N_TUNS=$(echo $CHECK_TUNS | wc -l)

create_tunnel(){
  # Create a connection between localhost:$TUN_LOC_PORT to MIDDLE_BOX:SSH_PORT
  # It will ask for MIDDLE_BOX's password
  # -N -f keep the connection open in background executing No commands
  ssh -N -f -p $LOC_BASTION_SSH_PORT -L$TUN_LOC_PORT:$REMOTE_BASTION_HOST:$REMOTE_BASTION_SSH_PORT $LOC_BASTION_USER@$LOC_BASTION_HOST
  echo "Created new tunnel"
}

check_tunnel(){
nc -w 1 -z localhost $TUN_LOC_PORT > /dev/null 2>&1
}

reset_tunnel() {
for PID in $CHECK_TUNS; do
   kill -9 $PID > /dev/null 2>&1
   echo "Found multiple tunnels. Killed all."
done
}


# Hidden function. Add 'cleanup' as argument to close all the tunnels
[ "$1" == "cleanup" ] && reset_tunnel && exit 0

if [ $N_TUNS -eq 0 ] ; then
   create_tunnel
elif [ $N_TUNS -eq 1 ] ; then
   check_tunnel
   if [ $? -eq 0 ] ; then
      echo "Tunnel already up and running"
   else
      reset_tunnel
      create_tunnel
   fi
else
   reset_tunnel
   create_tunnel
fi


CHECK_PORT_FWD=$(ps aux | grep -q "[s]sh -N -f -p $TUN_LOC_PORT -L$LISTENING_LOC_PORT:$DEST_HOST:$DEST_FW_PORT -l $REMOTE_BASTION_USER localhost")
if [ $? -eq 0 ] ; then
   echo "Port forward already created. Remote port $DEST_FW_PORT should be accessible on localhost port $LISTENING_LOC_PORT"
   exit 0
 else
   # This will create 'link' between $DEST_FW_PORT from $DEST_HOST to $TUN_LOC_PORT on localhost
   echo "Creating link between $DEST_FW_PORT to $TUN_LOC_PORT on localhost via $DEST_HOST"
   ssh -N -f -p $TUN_LOC_PORT -L$LISTENING_LOC_PORT:$DEST_HOST:$DEST_FW_PORT -l $REMOTE_BASTION_USER localhost
   echo "You can now access $DEST_FW_PORT listening on $DEST_HOST from localhost on port $LISTENING_LOC_PORT."
fi

 

Physically restart Sky router via Raspberry Pi

I have a Sky Hub router, the SR102 (black). Previously I had the white version as well.
Nice routers, pretty stable, but badly locked. You can change the SID of your wifi, change the password… not either sure if you can do a proper port forwarding. So… perfect for my mum,¬†but a pain for whoever wants a little bit of extra control.

I had already an ASUS RT-N16 with DD-WRT firmware¬†so I used the DMZ function on the Sky router to have some sort of “link” of the public IP of my broadband directly on the WAN interface of the router. In this way it’s like that is my ASUS router that does the connection and I can play as freely as I want, without caring much about the Sky router.

However, it happens that sometimes you need to give a full reboot to the main Sky router. And maybe do this automatically or via command line/script. And here it’s when things are getting more complicated.

The Sky Hub router allows you to reboot it via HTTP. Using the DMZ anyway will bypass the router itself and forward all the requests to the ASUS router. Also, I have never liked the idea to expose my router management page to the Internet, but I rather prefer to connect via SSH on a Raspberry Pi and issue commands from the terminal (telnet/ssh).

So, beside my multiple attempts to find a way to curl the button on the page, I had to find an alternative way to makes this happen. Of course, it didn’t help either to call the Sky Helpline asking if there was a remote possibility to have telnet enabled.

After a bit of talks on Facebook with some friends, here the solution: Remote Controlled Sockets with Pi-mote

Yes. If I can’t reboot from¬†inside, let’s to that from¬†outside!

The process was pretty straight forward.

First of all, I had to turn off my Raspberry Pi, and plug the¬†“little green piece of board” as mentioned in here

After that, I’ve turned the pi on again, and installed the required packages. Happily I found that there is now the python library available for¬†energenie, so I have installed them as well, making my life easier ūüôā

apt-get install python-rpi.gpio python-pip
pip install energenie

Once done, I have created these two basic script and I have run one a time, to configure the socket plugs.

Make sure to plug the ONE SOCKET PLUG A TIME and run the relative script.

You can find more information in the previous PDF, but these sockets learn who they are based on which commands they are receiving during the learning mode (enabling keeping the green button pressed for about 5 seconds when switched off). So if you run the first script with both plugs connected and in learning mode, they will do exactly the same, and unless you want to control two sockets at the same time, better to follow the instructions ūüôā

Script to configure the first socket:

from energenie import switch_on, switch_off
from time import sleep

# turn the first plug socket ON and then OFF
switch_on(1)
sleep(5)
switch_off(1)

 

Script to configure the second socket:

from energenie import switch_on, switch_off
from time import sleep

# turn the second plug socket ON and then OFF
switch_on(2)
sleep(5)
switch_off(2)

 

And now, my simple script to make… “the magic”: plugs.py

from energenie import switch_on, switch_off
from time import sleep
import sys

if len(sys.argv) == 1:
    print "Use:\n# python plug.py <plug_ID> <ON/OFF>\ne.g. # python plug.py 1 ON"
    exit(1)

else:
    plug = sys.argv[1]
    status = sys.argv[2]

if status.lower() == 'on':
   switch_on(int(plug))
else:
   switch_off(int(plug))

You can use this script to control any sockets (up to 4 – hardware limitation).

And here a bash wrapper (I’m not really good in python sorry) that calls plugs.py and restart the router:¬†restart_sky_router

#!/bin/bash

# This script requires plug.py script

if [ "$EUID" -ne 0 ]
  then echo "Please run as root or use 'sudo'"
  exit
fi

echo "Switching OFF and then ON the physical socket"


# Uses ENERGENIE Radio controlled Sockets
python plug.py 1 off
sleep 10
python plug.py 1 on

 

Now, I can have my Nagios system to check for the speed as documented here and eventually issue restart_sky_router script to see if it fixes the issue. Or simply be able to have a command to integrate in your scripts!