Techniques — Simple Linux networking
|
Back to techniques
https://rcardinal.ddns.net/techniques/linuxnet.html
|
Based on Ubuntu 10.04 (a variety of Debian Linux).
sudo ufw default deny # sudo ufw allow http # for web servers; this is port 80 # sudo ufw allow https # for web servers; this is port 443 sudo ufw allow ssh # this is port 22 sudo ufw logging on sudo ufw enable sudo ufw status
# Interface information netstat -i -e # Info for "eth0" sudo ethtool eth0 # Other diagnostics netstat --tcp [--listening] [--numeric] [--programs] nmap -v localhost
sudo apt-get install sendemail sendEmail \ -s EMAILSITE.DOMAIN \ -xu USERNAME \ -xp PASSWORD \ -o tls=yes \ -f "NICE-SENDER-NAME <REPLY-TO-ADDR>" \ -t "TO-USER-NICE-NAME <SEND-TO-ADDR>" \ -u "SUBJECT" \ -m "MESSAGE"
For example: you have a public-facing host with SSH access, called publichost; you have a private (e.g. conventional ISP) host called privatehost; you want to be able to log in to privatehost from publichost.
autossh
package./usr/local/bin/autossh_tunnel_publichost
on privatehost and run /usr/local/bin/autossh_tunnel_publichost start
regularly (e.g. every 10 minutes) from privatehost's /etc/crontab
. That gets the connection going. Download as autossh_tunnel_PUBLICHOST or see below:
#! /bin/sh # # Author: Andreas Olsson <andreas@arrakis.se> # Version: @(#)autossh_tunnel.foo 0.1 27-Aug-2008 andreas@arrakis.se # Modified by RNC 14/10/9 # # For each tunnel; make a uniquely named copy of this template. ## SETTINGS # # autossh monitoring port (needs to be unique on publichost) MPORT=5124 ### amend as necessary # the ssh tunnel to setup (also needs to be unique on publichost) TUNNEL="-R 5024:localhost:22" ### amend the "5024" bit as necessary # remote user RUSER="myusername" ### amend as necessary # remote server RSERVER="publichost" ### amend as necessary # keyfile KEYFILE="/home/myusername/.../mykeyfile" ### amend to point to a real SSH private key (which will be accepted by publichost for this username) # You must use the real autossh binary, not a wrapper. DAEMON=/usr/lib/autossh/autossh # ## END SETTINGS PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin NAME=`basename $0` PIDFILE=/var/run/${NAME}.pid SCRIPTNAME=/etc/init.d/${NAME} DESC="the tunnel" test -x $DAEMON || exit 0 #RNC# export AUTOSSH_PORT=${MPORT} export AUTOSSH_PIDFILE=${PIDFILE} #RNC# ASOPT=${TUNNEL}" -f -N "${RUSER}"@"${RSERVER} ASOPT="-M "${MPORT}" -N -f -i "${KEYFILE}" "${TUNNEL}" "${RUSER}"@"${RSERVER} # Function that starts the daemon/service. d_start() { start-stop-daemon --start --quiet --pidfile $PIDFILE \ --exec $DAEMON -- $ASOPT if [ $? -gt 0 ]; then echo -n " not started (or already running)" else sleep 1 start-stop-daemon --stop --quiet --pidfile $PIDFILE \ --test --exec $DAEMON > /dev/null || echo -n " not started" fi } # Function that stops the daemon/service. d_stop() { start-stop-daemon --stop --quiet --pidfile $PIDFILE \ --exec $DAEMON \ || echo -n " not running" } case "$1" in start) echo -n "Starting $DESC: $NAME" d_start echo "." ;; stop) echo -n "Stopping $DESC: $NAME" d_stop echo "." ;; restart) echo -n "Restarting $DESC: $NAME" d_stop sleep 1 d_start echo "." ;; *) echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2 exit 3 ;; esac exit 0
ssh localhost -p 5024
(assuming you kept the main port as 5024 in your copy of the script).To generate a public/private SSH keypair, and authorize it:
# ON LOCAL: ssh-keygen -t rsa -f /home/thisuser/.ssh/localhost-to-remotehost-rsync-key # ... enter a blank passphrase if you want to use unattended operation # ... makes localhost-to-remotehost-rsync-key (PRIVATE = LOCAL) and localhost-to-remotehost-rsync-key.pub (PUBLIC = REMOTE) # ... now ensure the private key (without the .pub extension) is only readable by the user # ... then move the public key to the remote host: scp /home/thisuser/.ssh/localhost-to-remotehost-rsync-key.pub remoteuser@remotehost:/home/remoteuser/ # ON REMOTE: log in by hand (ssh remoteuser@remotehost), then: cd ~ if [ ! -d .ssh ]; then mkdir .ssh ; chmod 700 .ssh ; fi mv localhost-to-remotehost-rsync-key.pub .ssh/ cd .ssh/ if [ ! -f authorized_keys ]; then touch authorized_keys ; chmod 600 authorized_keys ; fi cat localhost-to-remotehost-rsync-key.pub >> authorized_keys # ON LOCAL: DO THIS MANUALLY ONCE (SO THAT THE REMOTE HOST GETS ADDED TO THE known_hosts DATABASE): ssh remoteuser@remotehost # ... should now authenticate with the keyfile # Now you're ready for automated operation. But...
Can now restrict operation further using .ssh/authorized_keys
on the remote. For details see this helpful CU Engineering page. You can restrict the valid hosts that this key will work for. Additionally, you can restrict the commands it can run. If you intend to run it as root (which you should avoid if it is not absolutely necessary), then you should restrict as much as possible, including the IP addresses allowed and the functions allowed through SSH. For example, (1) in /etc/ssh/sshd_config
, specify PermitRootLogin forced-commands-only
(as opposed to the better default of PermitRootLogin no
); (2) in your /root/.ssh/authorized_keys
file, have lines like e.g.
from="myvalidhost.myvaliddomain",command="/usr/local/bin/validate_ssh_command",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa the_key_itself root@myservername
... then have a /usr/local/bin/validate_ssh_command
script (downloadable as validate_ssh_command or see below) that only allows certain things through, e.g. this for rsync and unison:
#!/bin/sh case "$SSH_ORIGINAL_COMMAND" in *\&*) echo "Rejected" ;; *\(*) echo "Rejected" ;; *\{*) echo "Rejected" ;; *\;*) echo "Rejected" ;; *\<*) echo "Rejected" ;; *\`*) echo "Rejected" ;; rsync\ --server*) $SSH_ORIGINAL_COMMAND ;; unison\ *) $SSH_ORIGINAL_COMMAND ;; *) echo "Rejected" ;; esac
When things go wrong, open a temporary port on the server and use
/usr/sbin/sshd -d -p PORTNUM
on the server to watch what's
happening, and ssh HOST -p PORTUM -v -v
on the client.
Create the following script as /usr/local/bin/watch_web_page
. In /etc/crontab
, run it regularly, passing it (1) a URL, (2) a temporary file where it can keep a copy of the web page, and (3) a program to run if the page changes (e.g. to e-mail you about it). Download as watch_web_page or see below:
#!/bin/sh # $1 = URL to watch. # $2 = File to use for temporary storage of a copy. # $3 = Program to run (with URL as parameter) when watched page changes. # RNC, 18 June 2010. URL=$1 FILEONE=$2 FILETWO=$FILEONE.new PROGRAM=$3 if [ -f $FILEONE ]; then echo "Page previously stored." wget -O $FILETWO $URL >/dev/null 2>&1 && ( echo "Web page fetched using wget." ) || ( echo "Failed to fetch web page."; exit 1 ) cmp $FILEONE $FILETWO && ( echo "No change to page." ) || ( echo "Page changed."; $PROGRAM $URL ) rm $FILEONE mv $FILETWO $FILEONE else echo "Page not previously stored." wget -O $FILEONE $URL >/dev/null 2>&1 && ( echo "Web page fetched using wget." ) || ( echo "Failed to fetch web page."; exit 1 ) fi exit 0
rsnapshot
.rsync
.unison
.
Where possible, synchronize user-to-user. Where the backup system has to be able to cope with files owned by any user/group with any permission, use root.
# mount: sshfs hostname:/directory/ temp/ # unmount: fusermount -u temp/
The prototypical problem: someone needs help with their home Windows computer but has Internet access via a conventional broadband ISP; their computer is therefore not directly accessible to the wider Internet. You have access to a decent machine (viz., a UNIX-based computer with a static IP address). We'll call the computers winbox
and linuxbox
. Prerequisites:
sudo apt-get install xvnc4viewer
to install if necessary.The simplest of the three methods for the Windows user (no PuTTY required). The VNC server has to be on the Windows machine (because that's the one we want to look at). However, the VNC server can initiate the connection to the viewer (which is helpful if the VNC server is on a machine with a dynamic and inaccessible IP address, while the viewer is on a proper static IP address).
linuxbox
. For example (if you use the UFW firewall): sudo ufw allow 5500
— to reverse this after the session, you can use e.g. sudo ufw delete allow 5500
or sudo ufw deny 5500
.xvnc4viewer -listen # 5500 is the default port, though can also use vncviewer -listen [port]
linuxbox:5500
. For example, with RealVNC:
linuxbox
(e.g. myhost.mydept.myuniv.ac.uk
) in the "Viewer" box provided and then clicking OK.In this method, we connect the same way round (server on the Windows box initiates the connection to the viewer on the Linux host), but we tunnel it through SSH, so only port 22 (SSH) needs to be exposed to the outside world by the Linux host.
xvnc4viewer -listen # 5500 is the default port, though can also use vncviewer -listen [port]
winbox:5500
to linuxbox:5500
(5500 is the default "listening viewer" VNC port). This is local port forwarding:
putty -ssh username@linuxbox -L 5500:linuxbox:5500Type
localhost
exactly, but replace linuxbox
with the IP address of your Linux host (e.g. myhost.mydept.myuniv.ac.uk
). You'll need to provide the password for username@linuxbox to complete the login and set up the SSH tunnel.
localhost:5500
(which is, of course, winbox:5500
tunnelled securely to linuxbox:5500
). For example, with RealVNC:
localhost
(exactly) in the "Viewer" box provided and then clicking OK.In this method, the VNC connection is initiated by the viewer. To make the server visible to the viewer, it needs to be tunnelled via an SSH connection (which is initiated by the Windows box in our hypothetical situation).
linuxbox:5900
to winbox:5900
(5900 is the default VNC server port). This is remote port forwarding:
putty -ssh username@linuxbox -R 5900:localhost:5900Type
localhost
exactly, but replace linuxbox
with the IP address of your Linux host (e.g. myhost.mydept.myuniv.ac.uk
). You'll need to provide the password for username@linuxbox to complete the login and set up the SSH tunnel.
xvnc4viewer localhost # 5900 is the default port, though can also use vncviewer host:display# (where port = display# + 5900)You'll need to provide the VNC password for winbox to complete the login and start the VNC session.
Desktop: Unix / custom. Settings: Run...: /usr/bin/xfce4-session
. Options: New virtual desktop.
See http://funwithlinux.wordpress.com/2009/05/22/sharing-ubuntu-host-printer-with-windows-xp-running-in-virtualbox/ and http://machine-cycle.blogspot.com/2008/11/sharing-cups-pdf-printer-over-ipp.html. There's no need to open port 631 on your firewall, as the Linux host will see requests from the VirtualBox guest OS as being local.