SSH tunneling

A SSH tunnel provides an encrypted tunnel using a SSH protocol connection. It can be used to exchange data over a network through an encrypted channel or to bypass some firewall restrictions.

To set up a SSH tunnel, a given port on a machine need to be forwarded. Ports can be forwarded in three ways: local, remote or dynamic.

Local

Say you’re on a private network which doesn’t allow connections to a specific server. To get around the problem, you can create a tunnel through a server which is not on your private network:

ssh -L [local-port]:[remote-host]:[remote-port] user@remoteserver

-L stands for local port forwarding; you’re forwarding local port 9000 to [remote-host]:[remote-port]

Remote

Say you need to give someone access to your client machine over an encrypted tunnel. Before establishing a connection your need to edit /etc/ssh/sshd_config, add GatewayPorts yes and restarting sshd.

ssh -R [remote-port]:localhost:[local-port] user@remoteserver

Dynamic

In this case, port forwarding turns your SSH client into a SOCKS proxy server. Every program need to be configured to use the proxy server. SOCKS is a protocol that redirects every Internet connection through a proxy server:

ssh -D 1080 [server]

1080 is the standard SOCKS port but you can use any port number; the SOCKS proxy will stop when you close your SSH session.

Solaris 11: DNS client configuration

In Solaris 11, /etc/resolv.conf is managed via SMF (Service Management Framework).

root@solaria:~# cat /etc/resolv.conf

#
# _AUTOGENERATED_FROM_SMF_V1_
#
# WARNING: THIS FILE GENERATED FROM SMF DATA.
# DO NOT EDIT THIS FILE. EDITS WILL BE LOST.
# See resolv.conf(4) for details.

nameserver 8.8.8.8

View existing DNS configuration

svccfg -s network/dns/client listprop config
config                      application        
config/value_authorization astring     solaris.smf.value.name-service.dns.client
config/nameserver          net_address 8.8.8.8

Update existing DNS configuration

svccfg -s network/dns/client setprop config/nameserver = net_address: "(208.67.222.222 208.67.220.220)"

Export DNS configuration

svcadm refresh dns/client

This command will build a new /etc/resolv.conf based on the new settings:

nscfg export svc:/network/dns/client:default

Pass a bash array as an argument

I have a bash script in which I’m using an array to get a list of files and I needed to pass the content of this array as an argument, to send an email to some users.

This is the array:

RAW_LIST="$(echo "ls -1 /download")"
declare -a LIST
readarray -t LIST <<<"${RAW_LIST}"

This is how I passed the array to bash:

printf %"s\n"  "${LIST[@]:1}" | /bin/mail -s "$SUBJECT" "$EMAIL"

Trailing :1 in the array will consider all the elements after element [0] as, in this specific case, it'd be ls -1, pretty useless sending it to the user.

Recover GRUB in CentOS 7

To recover GRUB, you’ll need the OS ISO image, in this case CentOS 7, and boot from it.

From the ISO menu, choose Trobleshooting -> Rescue a CentOS system and then 1) Continue; the system will be mounted under /mnt/sysimage.

To make your system the root environment run:

chroot /mnt/sysimage

Identify GRUB installation:

ls /sbin | grep grub

Install GRUB:

/sbin/grub2-install /dev/sdX

Exit and reboot.

Script: receive files via SFTP

In the past days I had to write a script to download files from a remote server using an SFTP connection; this script will be run by cron.

The goal was to download the files on my server and delete them on the remote machine after being downloaded.

I used an array to get the list of the current files on the remote server and a for-loop to download them.

#!/bin/bash
# 
# 20180801
#
# Receive files via SFTP


LOGFILE=/var/tmp/receivefiles.$(date -I).log
echo "START: $(date)" >>$LOGFILE

# Connection data
HOST='XXX.XXX.XXX.XXX'
PORT='22'
USER='mashiny'

# Where to download files
cd /home/mashiny/download

# File list
LIST_RAW="$(echo "ls -1 /out" | sftp -oPort=$PORT $USER@$HOST 2>/dev/null)"
declare -a LIST
readarray -t LIST <<<"${LIST_RAW}"

if   [[ "${#LIST[@]}" -lt 1 ]]; then
    echo "Unknown error in SFTP connection" >>$LOGFILE
    exit 1
elif [[  "${#LIST[@]}" -lt 2 ]]; then
    echo "No files to download" >>$LOGFILE
    exit 0
fi

# Connection via SFTP and download files
for FILE in "${LIST[@]:1}"
do
    # Download
    echo "get $FILE" | sftp -oPort=$PORT $USER@$HOST &>/dev/null
    [ $? -ne 0 ] && echo "$FILE download failed" >>$LOGFILE && continue
    echo "$FILE downloaded" >>$LOGFILE

    # Delete on remote dir
    echo "rm $FILE" | sftp -oPort=$PORT $USER@$HOST &>/dev/null
    [ $? -ne 0 ] && echo "$FILE not removed" >>$LOGFILE && continue
    echo "$FILE removed" >>$LOGFILE
done

echo "END:   $(date)" >>$LOGFILE
exit 0

Configure an IP address in Solaris 11

ipadm create-addr is used to assign an IP address to an interface. Its syntax:

ipadm create-addr -T address-type -a address/netmask addrobj

-T address-type refers to static, dhcp or addrconf (for automatically generated IPv6 addresses).

addrobj is an identifier for the unique IP used in the system.

dladm show-phys
LINK              MEDIA                STATE      SPEED  DUPLEX    DEVICE
net0              Ethernet             up         1000   full      e1000g0

Static IP

ipadm create-ip net0

ipadm create-addr -T static -a 10.0.2.15/24 net0/v4

ipadm show-addr
ADDROBJ           TYPE     STATE        ADDR
lo0/v4            static   ok           127.0.0.1/8
net0/v4           static   ok           10.0.2.15/24

Dynamic IP

ipadm create-ip net0

ipadm create-addr -T dhcp net0/v4

ipadm show-addr
ADDROBJ           TYPE     STATE        ADDR
lo0/v4            static   ok           127.0.0.1/8
net0/v4           dhcp     ok           10.8.29.188/24

CIFS: mount error(112): Host is down

When trying to mount a Windows share using mount, I ran into this problem:

mount -v -t cifs -o username=username,password=password //hostname/sharename /mnt
mount.cifs kernel mount options: ip=XXX.XXX.XXX.XXX,unc=\\hostname\sharename,user=username,prefixpath=sharename,pass=********
mount error(112): Host is down

In my case, the error was due to a protocol mismatch when trying to mount the share: in the latest versions of Windows Server, SMBv1 is disabled.

To reach this conclusion, I ran smbclient in debug mode:

smbclient -L //hostname/sharename -U username -d 3
protocol negotiation failed: NT_STATUS_CONNECTION_RESET

To overcome this issue, I specified the protocol when using mount:

mount -t cifs -o username=username,password=password,vers=3.0 //hostname/sharename /mnt

If you want to use smbclient, add the -m option:

smbclient -L //hostname/sharename -U username -m SMB3

Mounting a Windows share using CIFS

Windows shares can be mounted using cifs option:

mount -t cifs -o username=username,password=password //hostname/sharename /mnt

By default, Windows shares are mounted with 0777 permissions in Linux.

You can change the default permissions using dir_mode and file_mode options in mount:

mount -t cifs -o username=username,password=password,dir_mode=0755,file_mode=0755 //hostname/sharename /mnt

To make the mount persistent, add the entry to /etc/fstab:

//hostname/sharename    /mountpoint   cifs  _netdev,username=username,password=password,dir_mode=0755,file_mode=0755,uid=500,gid=500 0 0