Goal

Connect samba hosts and ftp hosts securely and automagically using ssl and autofs. It is possible to have authorization with username and password. With samba it is possible to have different passwords for different shares.

Use xinetd to run stunnel and samba to minimize system resources utilization.

At the moment (03/2016) it is not possible to connect samba through vfs and use ssl at the same time due to vfs implementation limitation.

Realization:

Structure of the filesystem where autofs will be watching:

/mnt/remote
    ftp/ (defined in: /etc/auto.master.d/mnt-remote-ftp.autofs)
        host.aa
        host.bb
        ...
    samba/ (defined in: /etc/auto.master.d/mnt-remote-samba.autofs)
        host.cc (magic)
        ...

To make it easy for users links might be made for example in ~/net that points to hosts that we know will work for example:

~/net/ftp.misackovo.eu -> /mnt/remote/ftp/misackovo.eu/www
~/net/webroots/misackovo.eu -> /mnt/remote/samba/misackovo.eu/www

ftp

  • curlftfs to connect remote ftp via ssl
  • $HOME/.netrc store passwords so they do not need to be entered everytime

samba

  • samba vfs does not support connection with encryption enabled (03/2016) so we use stunnel that is automatically launched when we connect to local port (xinetd does that). The whole magic goes like this:

    • access to /mnt/remote/samba/localhost:1391
    • autofs connects to localhost:1391
    • xinetd is listening and contact remote host
    • remote hosts xinetd is listening on port 800 for stunnel which is
      established
    • remote hosts stunnel instance launches samba in foreground
    • profit
  • autofs samba mounting script is customized to be able to use credentials for different sites/mounts stored in a tree structure like this:

    $ ls -1 /etc/auto.smb.credentials
    localhost:1390
    localhost:1390.www
    
    $ cat /etc/auto.smb.credentials/localhost:1390
    username=me
    password=le-pa22w0rd
    

Server configuration

ftp

export FTP_NAME=ftp.misackovo.eu export FTP_HOST=90737.w37.wedos.net export FTP_USER=w90737 export FTP_PASSWORD=Abcd1234.

install curlftpfs autofs mkdir -p /mnt/remote/ftp /etc/auto.mnt-remote-ftp echo “/mnt/remote/ftp /etc/auto.mnt-remote-ftp –timeout=30” > /etc/auto.master.d/remote-ftp.autofs echo “$FTP_NAME -fstype=fuse,allow_other,uid=pi,ssl_control curlftpfs#@${FTP_HOST}” > /etc/auto.mnt-remote-ftp

echo -e “machine ${FTP_HOST}nlogin ${FTP_USER}npassword ${FTP_PASSWORD}”

samba

export SAMBA_USER=sclient
export SAMBA_PASSWORD=password
$ cat /etc/samba/smb.conf-no-encryption

[global]
    netbios name = <hostname>
    # interfaces = 127.0.0.1/8 lo
    bind interfaces only = 127.0.0.2
    server string = This is samba on <hostname>
    unix charset = UTF-8
    workgroup = le-windows
    browseable = yes
    deadtime = 30
    domain master = yes
    encrypt passwords = true
    enable core files = no
    guest account = nobody
    guest ok = no
    invalid users = root
    local master = yes
    map to guest = Bad User
    max protocol = SMB2
    min receivefile size = 16384
    null passwords = yes
    obey pam restrictions = yes
    os level = 20
    passdb backend = smbpasswd
    preferred master = yes
    security = user
    smb encrypt = auto
    smb passwd file = /etc/samba/smbpasswd
    socket options = TCP_NODELAY IPTOS_LOWDELAY
    syslog = 3
    log file = /var/log/samba.log
    use sendfile = yes
    writeable = yes

    load printers = no
    printing = bsd
    printcap name = /dev/null
    disable spoolss = yes

[www]
    path = /var/www
    valid users = admin
    read only = no
    guest ok = no
$ useradd -M -s /bin/false $SAMBA_USER

$ (echo $SAMBA_PASSWORD; echo $SAMBA_PASSWORD) | smbpasswd -a $SAMBA_USER -s

stunnel

xinetd

test

$ telnet localhost 139 #xinetd should run samba

$ smbclient -e -u ${SAMBA_USER}%${SAMBA_PASSWORD //localhost/www

Client configuration

export REMOTE_HOST='le.remote.host.sh'
export REMOTE_STUNNEL_PORT=800
export SAMBA_LOCAL_PORT=1392

autofs

$ cat /etc/auto.master.d/mnt-remote-ftp.autofs:
/mnt/remote/ftp /etc/auto.mnt-remote-ftp --timeout=30
$ cat /etc/auto.master.d/mnt-remote-samba.autofs:
/mnt/remote/samba /etc/auto.smbng --timeout=30

stunnel

In case there are both stunnel4 and stunnel3 binaries on your system you need to use stunnel4 or you will get strange ssl errors.

$ cat /etc/stunnel/client-${REMOTE_HOST}-samba.conf
foreground = yes
debug = 7

socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

options = NO_SSLv2
options = NO_SSLv3

[samba-${REMOTE_HOST}]
client = yes
accept = ${SAMBA_LOCAL_PORT}
connect = ${REMOTE_HOST}:${REMOTE_STUNNEL_PORT}

xinetd

$ cat /etc/xinetd.d/stunnel-${REMOTE_HOST}-samba
service stunnel
{
    disable         = yes
    port            = ${REMOTE_STUNNEL_PORT}
    type            = UNLISTED
    flags           = REUSE
    socket_type     = stream
    wait            = no
    user            = root
    server          = /bin/stunnel
    server_args     = /etc/stunnel/client-${REMOTE_HOST}-samba.conf
}

$ systemctl restart xinetd
$ lsof -i :1391

Tests

  • Switch off xinetd if running

  • Check that stunnel will connect to remote host by running (remember that you need to call stunnell4 if stunnel3 also exists):

    $ sudo stunnel /etc/stunnel/client-${REMOTE_HOST}-samba.conf
    2016.03.17 16:53:49 LOG7[5358:139995584534592]: Clients allowed=500
    2016.03.17 16:53:49 LOG5[5358:139995584534592]: stunnel 4.56 on x86_64-redhat-linux-gnu platform
    2016.03.17 16:53:49 LOG5[5358:139995584534592]: Compiled/running with OpenSSL 1.0.1e-fips 11 Feb 2013
    2016.03.17 16:53:49 LOG5[5358:139995584534592]: Threading:PTHREAD Sockets:POLL,IPv6 SSL:ENGINE,OCSP,FIPS Auth:LIBWRAP
    2016.03.17 16:53:49 LOG5[5358:139995584534592]: Reading configuration from file /etc/stunnel/client-ubuntu-samba.conf
    2016.03.17 16:53:49 LOG5[5358:139995584534592]: FIPS mode is enabled
    2016.03.17 16:53:49 LOG7[5358:139995584534592]: Compression not enabled
    2016.03.17 16:53:49 LOG7[5358:139995584534592]: Snagged 64 random bytes from /root/.rnd
    2016.03.17 16:53:49 LOG7[5358:139995584534592]: Wrote 1024 new random bytes to /root/.rnd
    2016.03.17 16:53:49 LOG7[5358:139995584534592]: PRNG seeded successfully
    2016.03.17 16:53:49 LOG6[5358:139995584534592]: Initializing service [samba-ubuntu]
    2016.03.17 16:53:49 LOG7[5358:139995584534592]: SSL options set: 0x01000004
    2016.03.17 16:53:49 LOG5[5358:139995584534592]: Configuration successful
    2016.03.17 16:53:49 LOG7[5358:139995584534592]: Service [samba-ubuntu] (FD=12) bound to 0.0.0.0:1392
    2016.03.17 16:53:49 LOG7[5358:139995584534592]: Created pid file /var/run/stunnel.pid
    ...
    <keeps running in foreground>
    
  • In another terminal check that you can connect with samba client to local port 1392:

    $ smbclient //localhost/www --port=1392 -U samba%password
    
    $ smbclient //localhost/home-pirate --port=1392 -U samba%password
    Domain=[PIRATE] OS=[Unix] Server=[Samba 4.1.6-Ubuntu]
    smb: \> ls
      .                                   D        0  Thu Mar 17 16:41:11 2016
      ..                                  D        0  Thu Mar 17 16:41:11 2016
      .bash_logout                        H      220  Wed Apr  9 03:03:15 2014
      .bashrc                             H     3637  Wed Apr  9 03:03:15 2014
      .profile                            H      675  Wed Apr  9 03:03:15 2014
    
                  64162668 blocks of size 1024. 60388144 blocks available
    smb: \> exit
    $
    
  • You see this in stunnel4 terminal.

    <smbclient connects through tunnel>
    ...
    2016.03.17 17:06:23 LOG7[12301:140054147115072]: Service [samba-ubuntu] accepted (FD=3) from 127.0.0.1:33744
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: Service [samba-ubuntu] started
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: Waiting for a libwrap process
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: Acquired libwrap process #0
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: Releasing libwrap process #0
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: Released libwrap process #0
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: Service [samba-ubuntu] permitted by libwrap from 127.0.0.1:33744
    2016.03.17 17:06:23 LOG5[12301:140054147258112]: Service [samba-ubuntu] accepted connection from 127.0.0.1:33744
    2016.03.17 17:06:23 LOG6[12301:140054147258112]: connect_blocking: connecting 192.168.122.99:800
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: connect_blocking: s_poll_wait 192.168.122.99:800: waiting 10 seconds
    2016.03.17 17:06:23 LOG5[12301:140054147258112]: connect_blocking: connected 192.168.122.99:800
    2016.03.17 17:06:23 LOG5[12301:140054147258112]: Service [samba-ubuntu] connected remote server from 192.168.122.1:52542
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: Remote socket (FD=13) initialized
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SNI: sending servername: ubuntu
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): before/connect initialization
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 write client hello A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 read server hello A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 read server certificate A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 read server key exchange A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 read server done A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 write client key exchange A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 write change cipher spec A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 write finished A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 flush data
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 read server session ticket A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]: SSL state (connect): SSLv3 read finished A
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    1 items in the session cache
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    1 client connects (SSL_connect())
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    1 client connects that finished
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    0 client renegotiations requested
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    0 server connects (SSL_accept())
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    0 server connects that finished
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    0 server renegotiations requested
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    0 session cache hits
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    0 external session cache hits
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    0 session cache misses
    2016.03.17 17:06:23 LOG7[12301:140054147258112]:    0 session cache timeouts
    2016.03.17 17:06:23 LOG6[12301:140054147258112]: SSL connected: new session negotiated
    2016.03.17 17:06:23 LOG6[12301:140054147258112]: Negotiated TLSv1/SSLv3 ciphersuite: ECDHE-RSA-AES256-SHA (256-bit encryption)
    2016.03.17 17:06:23 LOG6[12301:140054147258112]: Compression: null, expansion: null
    2016.03.17 17:06:34 LOG6[12301:140054147258112]: Read socket closed (readsocket)
    2016.03.17 17:06:34 LOG7[12301:140054147258112]: Sending close_notify alert
    2016.03.17 17:06:34 LOG7[12301:140054147258112]: SSL alert (write): warning: close notify
    2016.03.17 17:06:34 LOG6[12301:140054147258112]: SSL_shutdown successfully sent close_notify alert
    2016.03.17 17:06:34 LOG6[12301:140054147258112]: SSL socket closed (SSL_read)
    2016.03.17 17:06:34 LOG7[12301:140054147258112]: Sent socket write shutdown
    2016.03.17 17:06:34 LOG5[12301:140054147258112]: Connection closed: 1471 byte(s) sent to SSL, 1699 byte(s) sent to socket
    2016.03.17 17:06:34 LOG7[12301:140054147258112]: Remote socket (FD=13) closed
    2016.03.17 17:06:34 LOG7[12301:140054147258112]: Local socket (FD=3) closed
    2016.03.17 17:06:34 LOG7[12301:140054147258112]: Service [samba-ubuntu] finished (0 left)
    
  • Check that /etc/auto.smb works correctly with no passwords:

    $ sudo cat /etc/auto.smb.credentials/localhost:1392
    cat: /home/q/auto.smb.credentials/localhost:1392: No such file or directory
    
    $ sudo /etc/auto.smb localhost:1392
    -fstype=cifs,rw,gid=wheel,port=1392 /home-pirate ://localhost/home-pirate
    
    $ sudo grep autofs.smb /var/log/messages
    ...
    Mar 17 17:18:30 kachnicka autofs.smbng: Called with argument: localhost:1392
    Mar 17 17:18:30 kachnicka autofs.smbng: host: localhost port: 1392
    Mar 17 17:18:30 kachnicka autofs.smbng: Using credfile:
    Mar 17 17:18:30 kachnicka autofs.smbng: smbopts: "--port=1392 -N"
    Mar 17 17:18:30 kachnicka autofs.smbng: shares found on localhost: home-pirate
    Mar 17 17:18:30 kachnicka autofs.smbng: Credfile /root/auto.smb.credentials/localhost not found.
    Mar 17 17:18:30 kachnicka autofs.smbng: Credfile /root/auto.smb.credentials/localhost:1392 not found.
    Mar 17 17:18:30 kachnicka autofs.smbng: Credfile /root/auto.smb.credentials/localhost.home-pirate not found.
    Mar 17 17:18:30 kachnicka autofs.smbng: Credfile /root/auto.smb.credentials/localhost:1392.home-pirate not found.
    Mar 17 17:20:05 kachnicka autofs.smbng: Called with argument: localhost:1392/home-pirate
    ...
    
  • Check that /etc/auto.smb finds credentials file if it exists:

    $ cat /etc/auto.smb.credentials/localhost:1392
    username=samba
    password=password
    
    $ /etc/auto.smb localhost:${REMOTE_STUNNEL_PORT}
    /etc/auto.smb localhost:${REMOTE_STUNNEL_PORT}
    -fstype=cifs,rw,gid=wheel,port=${REMOTE_STUNNEL_PORT},credfile=/root/auto.smb.credentials/localhost:${REMOTE_REMOTE_PORT}/www ://localhost/www
    
    $ sudo grep autofs.smb /var/log/messages
    ...
    Mar 17 17:25:36 kachnicka autofs.smbng: Called with argument: localhost:${REMOTE_STUNNEL_PORT}
    Mar 17 17:25:36 kachnicka autofs.smbng: host: localhost port: ${REMOTE_STUNNEL_PORT}
    Mar 17 17:25:36 kachnicka autofs.smbng: Using credfile: /root/auto.smb.credentials/localhost:${REMOTE_STUNNEL_PORT}
    Mar 17 17:25:36 kachnicka autofs.smbng: smbopts: "--port=1392 -A /root/auto.smb.credentials/localhost:1392"
    Mar 17 17:25:36 kachnicka autofs.smbng: shares found on localhost: www
    Mar 17 17:25:36 kachnicka autofs.smbng: Credfile /root/auto.smb.credentials/localhost not found.
    Mar 17 17:25:36 kachnicka autofs.smbng: Found credfile: /root/auto.smb.credentials/localhost:1392
    Mar 17 17:25:36 kachnicka autofs.smbng: Credfile /root/auto.smb.credentials/localhost.home-pirate not found.
    Mar 17 17:25:36 kachnicka autofs.smbng: Credfile /root/auto.smb.credentials/localhost:1392.home-pirate not found.
    ...
    
  • Check that you can connect using smbclient and credentials file:

    $ smbclient //localhost/www \
      --port=${REMOTE_STUNNEL_PORT} \
      -A /etc/auto.smb.credentials/localhost:${SAMBA_LOCAL_PORT}
    Domain=[PIRATE] OS=[Unix] Server=[Samba 4.1.6-Ubuntu]
    smb: \> exit
    $
    
  • Files permission debugging (and facts)
    • the user/group on server is mapped to local user/group with uid=X, gid=Y in the mount command. To change it go to the smbng.auto script.

      Note

      Params worth noting: gid=x, uid=y, noperm

      client$ mount | grep home-pirate # note uid=0, gid=27 (sudo)
      /etc/auto.smbng on /mnt/remote/samba/localhost:1391/home-pirate type autofs (rw,relatime,fd=18,pgrp=1468,timeout=30,minproto=5,maxproto=5,offset) //localhost/home-pirate on /mnt/remote/samba/localhost:1391/home-pirate type cifs (rw,relatime,vers=1.0,cache=strict,username=samba,domain=RPI,uid=0,forceuid,gid=27,forcegid,addr=127.0.0.1,unix,posixpaths,serverino,mapposix,acl,rsize=1048576,wsize=1048576,echo_interval=60,actimeo=1)
      
      client$ ls -ld ~/net/pi/home-pirate/download/finished/
      drwxrws---+ 9 root sudo 0 kvě 16 14:33 /home/q/net/pi/home-pirate/download/finished/
      
    • on the server, the group/user are different and check that the user you use to connect to samba share (user in the credfile) have the correct rights by changing yourself to that user:

      server$ sudo su - www -s /bin/bash
      
      www@server$ ls -ld /home/pirate/download/finished
      drwxrws---+ 9 root pirate 4096 Aug  6 14:32 /home/pirate/download/finished
      
      www@server$ ls -ldn /home/pirate/download/finished
      drwxrws---+ 9 0 5000 4096 Aug  6 14:32 /home/pirate/download/finished
      
      www@server$ touch /home/pirate/download/finished/aa
      
      www@rpi:~/download/finished/moviez$ ls -l ~/download/finished/aa
      -rw-r--r-- 1 samba pirate 0 Aug  6 14:42 /home/pirate/download/finished/aa
      
      client$ ls -l ~/net/pi/home-pirate/download/finished/aa
      -rw-r--r--+ 1 root sudo 0 srp  6 14:42 /home/q/net/pi/home-pirate/download/finished/aa
      
    • only after the above point is resolved check on the client side that your user/group allows you to write:

      client$ touch ~/net/pi/home-pirate/download/finished/aa
      touch: cannot touch '/home/q/net/pi/home-pirate/download/finished/aa': Permission denied
      
      client$ sudo touch ~/net/pi/home-pirate/download/finished/aa
      
      client$ ls -l ~/net/pi/home-pirate/download/finished/aa
      -rw-r--r--+ 1 root sudo 0 srp  6 14:43 /home/q/net/pi/home-pirate/download/finished/aa
      
    • It might happen, that files do get created but their permission does not allow them to be read back (incorrect group for example). It helps to set ‘noperm’ option so local system does not check user rights and the check is done only by the remote system.

Scripts

  • auto.smb – improved version of autofs script that will allow you to have credentials for different sites
  • autofs-client.sh – makes it easy to configure client access

Indices and tables