Reverse SSH tunnel from a firewalled host

You have an SSH server A behind a firewall that you wish to connect to. You have no control over the firewall but has an account on an open SSH server B on the internet outside the firewall. You can setup a reverse tunnel from A to B so that you can connect to A through B from anywhere.

In the SSH configuration file A:~/.ssh/config, add the following section

Host b-tun
	HostName B
	ServerAliveInterval 30
	ExitOnForwardFailure yes
	RemoteForward 8822 localhost:22

Afterward, you can create the reverse tunnel on A by running ssh -Nf b-tun. and login with your credential on B or setup key authentication for automatic login. If the tunnel has been created successfully, you can now connect to the port 8822 of localhost on B to login to A, e.g., ssh -p 8822 localhost. If you have access to the nc command on B, you can add the section below to the ~/.ssh/config on a machine outside the firewall:

Host A
	ProxyCommand ssh -qax B 'nc -w 600 localhost 8822'
	ServerAliveInterval 30

You will then be able to connect to A with a simple ssh A on that machine.

You can also make the creation of the reverse tunnel automatic by creating a systemd unit, say, ~/.config/systemd/user/b-tun.service with the content

[Unit]
Description=Create SSH tunnel through B
After=network-online.target

[Service]
Type=idle
ExecStart=/usr/bin/ssh -N b-tun
RestartSec=39
Restart=always

[Install]
WantedBy=default.target

and start the process with systemctl --user start b-tun.service. You may need to enable unattended job for the user on A with loginctl enable-linger user as the root on A. To make the service start on boot automatically, you need to enable it with systemctl --user enable b-tun.service.

Certificate for courier esmtpd

To enable SSL/TLS support for the ESMTP, you need to have a server certificate. Usually, the installation process of the package in a Linux distribution will create a default, self-signed certificate for you. However, if you want to create a proper certificate for your site, following is some simple steps to do so.

First, you need to generate a key for your server if you don’t already have one:

openssl genrsa -out server.key 2048

With that key, you can then generate a certificate request:

openssl req -new -key server.key -out server.csr

If you did not customize your openssl.cnf configuration file, the above command will prompt you for the details of identify for the server in the certificate. Answer all questions as you please except for the common name “CN”, which should be the host name to connect to your server.

Now, you need to get a Certificate Authority to sign your request. For example, if you have a demoCA setup for your openssl installation, you can do:

openssl ca -config openssl.cnf -policy policy_anything -out server.crt -infiles server.csr

This results in the certificate file server.crt. You then can combine the server key and certificate files to create the certificate file for the courier mail server.

cat server.key server.crt > esmtpd.pem

This used to be sufficient. However, the newer version (0.73) of courier requires a “DH parameters” block in the certificate file. This can be generated and appended with:

openssl dhparam 1024 >> esmtpd.pem

Now, you can point the “TLS_CERTFILE” in all the configuration files to the certificate esmtpd.pem and restart your server.

Example: data preprocessing with BASH

Case situation

I have run some batch jobs on a cluster to process data files for different systems (msc, ms, sh, rd) and parameters (i and w). The files are in different subdirectories:

[cjj@gust pattern]$ ls d-*/*.spd
d-msc/i275w042526.spd d-ms/i285w025017.spd d-rd/i295w042812.spd
d-msc/i280w040241.spd d-ms/i290w023034.spd d-sh/i275w051138.spd
d-msc/i285w036791.spd d-ms/i295w020787.spd d-sh/i280w047315.spd
d-msc/i290w031925.spd d-rd/i270w065151.spd d-sh/i285w043415.spd
d-msc/i295w026791.spd d-rd/i275w060475.spd d-sh/i290w039589.spd
d-ms/i270w034433.spd d-rd/i280w055777.spd d-sh/i295w035791.spd
d-ms/i275w030644.spd d-rd/i285w051257.spd
d-ms/i280w027133.spd d-rd/i290w046948.spd
[cjj@gust pattern]$

While, the output files are in the current directory:

[cjj@gust pattern]$ ls *.o*
i270w034433.spd.o172489  i275w060475.spd.o172496  i285w036791.spd.o172486
i270w065151.spd.o172495  i280w027133.spd.o172491  i290w023034.spd.o172493
i275w030644.spd.o172490  i280w040241.spd.o172485  i290w031925.spd.o172487
i275w042526.spd.o172484  i285w025017.spd.o172492  i295w026791.spd.o172488
[cjj@gust pattern]$

The format of the output log files are as follows:

[cjj@gust pattern]$ cat i270w034433.spd.o172489
MinTemplateNumber =  3
JT =  5
JN =  1
spikeResolution =  2
Number of initial spike patterns have been found : 562
ans = Creating surrogate data
ans = Creating time jittering surrogate data
ans = Creating neuron jittering surrogate data
Number of spike patterns have been valid by checking with sorrogate : 542
Number of spike patterns have been ruled out because of having less complex : 205
Number of valid spike patterns have been found : 337
[cjj@gust pattern]$

Problem task

Gather the stats in the log files as those marked in red.

Solution 1

This is done with a one-liner:

[cjj@gust pattern]$ for i in d-*/*.spd;do n=${i%/*};n=${n#d-};s=${i#*/};if [ -f ${s}.o* ];then w=${s%.spd};w=${w#*w}; echo ${n} ${s:1:2}.${s:3:1} $((1${w:0:2}-100)).${w:2} `grep ':' ${s}.o* | awk '{print $NF}'`;fi;done > matching_stat.txt

which can be broken down to:

for i in d-*/*.spd;do
n=${i%/*}
n=${n#d-}
s=${i#*/}
if [ -f ${s}.o* ];then
w=${s%.spd}
w=${w#*w}
echo ${n} ${s:1:2}.${s:3:1} $((1${w:0:2}-100)).${w:2} `grep ':' ${s}.o* | awk '{print $NF}'`
fi
done > matching_stat.txt

The data file generated is:

[cjj@gust pattern]$ cat matching_stat.txt 
msc 27.5 4.2526 81 75 22 53
msc 28.0 4.0241 237 217 103 114
msc 28.5 3.6791 393 371 156 215
msc 29.0 3.1925 335 322 132 190
msc 29.5 2.6791 445 437 144 293
ms 27.0 3.4433 562 542 205 337
ms 27.5 3.0644 1037 1006 331 675
ms 28.0 2.7133 1141 1093 341 752
ms 28.5 2.5017 1325 1274 462 812
ms 29.0 2.3034 1652 1609 747 862
rd 27.0 6.5151 1031 953 313 640
rd 27.5 6.0475 1042 963 345 618
[cjj@gust pattern]$

Remote system upgrade (with grub and bmc-watchdog)

IPMI is a very very powerful tool for system administrators, especially those telecommuting ones. It’s serial over LAN (SOL) support eliminates the need to personally sit in front of a server to do any pre-network operations, including reconfiguring the BIOS settings. However, it does require (A) an additional IP address to access the IPMI network interface from the Internet; or, when no additional IP can be allocated, (B) the access to a second server on the same LAN (not necessarily with administrator privilege). When either (A) or (B) is available, you can theoretically do anything remotely including fresh installation of an operation system (starting, for example, with a network boot and/or a remote drive).

Unfortunately, one of my recent situation allowed neither (A) nor (B). So, the first installation had no option but to be done by on-site personnel. But, once a networked system was up and running with a working grub boot manager, I could remotely install a new system on an unused (or a large enough swap) partition and test it out with the “boot once” support of grub. On a Debian based system with grub-2, this involves

  • changing the value of “GRUB_DEFAULT” in /etc/default/grub to “saved”,
  • running “update-grub”,
  • editing /boot/grub/grub.cfg to make an entry for the new system (if it was not discovered correctly by grub-probe),
  • running “grub-reboot” for the entry, and
  • rebooting the machine.

However, in most cases, you are bound to make some mistakes in the new system and fail to recover network contact to the server until an on-site person can hit the reset button of the machine for you.

Lucky for me, the BMC of the IPMI on the server did have a working watchdog timer. Therefore, I could setup the timer with enough time and start it before rebooting the machine. That way, if the new system worked, I could login to the server through the Internet and stopped the timer. But, if the new system got stuck, the watchdog would do a hard reset on the machine after the time ran out and returned to the original working system… no more waiting for on-site personnel. The actual command I used to setup the timer is bmc-watchdog from freeipmi:

  • bmc-watchdog -s -u 4 -p 0 -a 1 -F -P -L -S -O -i 900

One can consult the man page for the meaning of these options. Simply, this sets up 15 minutes on the timer for a hard reset, which can be checked with

  • bmc-watchdog -g

started with

  • bmc-watchdog -r

and stopped with

  • bmc-watchdog -y

(While, theoretically, one can achieve the same result with ipmitool, it did not work for me on the specific system.)

Building driver for AverMedia A827 on Linux kernel 2.6.38

Vendor: AVerMedia
Product: AVerTV Hybrid Volar HX
Model: A827

This is a Analog+DVB-T USB TV receiver with official support for Linux up until 2009-11-26. The latest driver can be downloaded from the product page above.

The “Normal” automatic process of installing the driver fails for 2.6.38 kernel. Using the “Expert” process to extract the driver source code to a selected location allows one to compile the driver manually and track down the problems. First, the function calls for mutex initialization are gone and should be replaced with those of semaphore initialization. Second, the Teletext support is also gone and should be eliminated from the driver source code. These fixes are summarized in this patch.

However, compiling the driver with “make” results in the WARNINGs that the symbols “param_array_get” and “param_array_set” are undefined. This is due a prebuilt object file, “aver/osdep_dvb.o_shipped”, that was built with an older version of kernel. Building this file requires some internal header files from kernel source tree that are not normally available in, e.g., linux-headers or kernel-headers packages. Provided that the kernel source tree for building the running kernel is installed/available in the system, the shipped object file can be removed. After this, the “make” command can complete without incidence. Installing the drivers (“averusbh826d.ko”  “h826d.ko”) to the module directory, e.g., “/lib/modules/2.6.38/kernel/drivers/media/dvb/dvb-usb” and updating the module dependency with “depmod -a”, the adapter seems to work normally afterwards.

Non-interactive ssh password auth

There are situations where only password authentication is allowed on a remote SSH server. And, it may be desirable to have non-interactive password entry even under interactive terminal sessions, e.g., running git, rsync, etc. through ssh. However, OpenSSH makes this difficult by requiring interactive keyboard entry whenever there is an associated tty to the process. While it is possible to bypass this with an expect script, the easiest solution is sshpass.

New Monitor

The old monitor suddenly went dark without warning. We went out and got a Samsung 205BW which features an 1680×1050 resolution. However, the on board VIA KM400 video card of my machine does not find any of the modelines gathered by DDC and refused to run at the optimal resolution. Luckily this post by Hendrik on the userforum at openchrome.org saved the day. The modeline mentioned on the page simply worked for me as posted. Many thanks to Hendrik!