Using samba securely with stunnel

    技术2024-11-23  16

    Changelog 2005-05-13First version2005-05-15Added Windows instructions.2005-05-16Rewrote insturctions for stunnel 4.xx2005-05-30Added advice to use openvpn

    Using samba securely with stunnel

    NOTICE: I recently discovered solution called openvpn and found that installing and configuring it is jut as easy - or more easier - than stunnel. Thus I recommend you to try openvpn first since it is more powerful solution. These instructions is left to 'net for people really wanting to use stunnel.

    Introduction

    I have traditionally used NFS protocol in my home network to get grasp to my files stored in fileserver. From outside I have simply used SFTP by hand. However, I recently got laptop and wireless network and had to reconsider how to do file sharing (or any communications to my server, but this article covers only file sharing). Let's see things we need to consider:

    Security - altough I use WPA/AES encryption in wireless connections I came to conclusion that I must encrypt traffic also in application layer. This is because added security (WPA/EAS should be secure enough, but...) and of course I can accept neighbours, friends, etc. to my wireless net after everything between my laptop and server is encrypted in application level too. VLAN's would of course be solution also). Accessibility - I take my laptop with me to various places from where I may have network connection and perhaps I want to transfer files from my fileserver. Traditionally I have used sftp for this but hey, it would be great if I would not have to mind where I am and I could still see my shares.

    Great then, what can I do? I searched file sharing protocols but did not find any usable protocols having encryption capabilities or protocols were too complicated (distributed etc.). Also I wanted that I won't need to patch kernel or something like that. Basically it menas that I must tunnel some non-ecnrypting protocol over encrypted tunnel to my server. And it left me only two choices: NFS and SMB/CIFS. I have never liked NFS since it is somehow complicated and unpredictable because portmapper and have problem with UIDs & GIDs and needs extra daemons to fix these problems etc. So one choice is left, SMB/CIFS. SMB protocol does not support file permissions etc. but I found that latest kernels and sambas supports CIFS protocol (used natively beginning from Windows 2000) and POSIX extensions for it. So it's possible to use file permissions with CIFS! Should be even possible to use Windows as fileserver and still use POSIX extensions. Great, lets use SMB/CIFS then! I have used previously SMB with Linux<->Linux/Windows connections and everything have worked smoothly (unlike Windows<->Windows connections :-) so I expected everything to work without any hazzle. And so happened. But before we go further, let's see feature matrix I created (X marks better feature):

     NFSSMBCIFSFile permissionsX XPerformanceX  Simplicity (for user) XXSecurity   

    SMB/CIFS loses only in performance and I am not sure if its even true nowadays with much computing power and samba evolved (if someone would do some benchmarks, I would gladly to hear). So choice is SMB/CIFS.

    Then we need to consider what technique we use to tunnel file shares. I found that there are basicly three to choose from: SSH tunnel, SSL tunnel and VPN. I disregarded VPN instantly since it would need kernel patching and I think its somehow overkill. I don't say that VPN would be poor choice - it actally can be great choice but I think I can get away more easily with SSL/SSH tunneling.

    Then we need to consider if it is SSH or SSL tunneling. Advantage of SSH tunneling is that every computer should have SSH installed already and tunnel is easily created. However with SSH you need user account to which log in for creating tunnel and I somehow dislike that even when you could create dummy acoount and DSA key for logins. Also SSH tunnel would need some kind of monitoring software which monitors that tunnels are up and data flowing so with same effor you could install SSL tunneling software which will handle tunnel and authentication for estabilishing tunnel etc. But probably this choise was mady by intuition. Let's sum this up:

     SSLSSHVPNSimplicityXX SecurityXXXExpandability  X

    Setupping SAMBA

    You need SMB/CIFS support in your kernel for you CLIENT machines. Most stock kernels probably have support already copmiled in so you can ignore this if you haven't compiled your own kernel. And if you have you also are capable to add support on your own. Se lets go on.

    You need samba installed to your SERVER for acting as SMB/CIFS server. For my distro, apt-get install samba installs everything needed, same should be case with your distribution with it's own utilities. Then you need to configure samba and create few shares (don't pay attention to CIFS right now, create just some basic shares). Configuring samba should be easy, please refer sambas and your distirbutions documentation. Some distors may have even some kind of GUI for configurin samba.

    However when configuring samba there should be some security issues needing our attention. I heavily recommend that you separate samba password from your login passwords (preferrably use smart card for login and disable passwords for login completely) and use strong random passwords for scenario cracker is able to contact your samba server. If cracker is able to sniff your sambas password (don't know how good is password encryption in SMB-protocol), he still can't login to your SERVER.

    Setupping stunnel

    NOTICE: This document covers up stunnel version 4.xx since it is current development version and I found it somehow more advanced. In Debian GNU/Linux package is called stunnel4.

    You need software called 'stunnel' installed for your CLIENT and SERVER. Probably you can use apt-get or similiar utility also here. In very last case you can compile stunnel on your own but you must have much knowhow to do it and then you probably won't need to read this document in first case... If your utility won't create x509 private keys & certificates for you, you must do this manually. Please also notice that tarball of stunnel contains example key/certificate. DON'T USE IT! Make very sure that you get certificate which is generated only for you. Here are quick key/certificate generating instructions:

    cd /etc/stunnel openssl req -new -x509 -nodes -days 365 -out stunnel.pem -keyout stunnel.pem chmod 600 stunnel.pem dd if=/dev/random of=temp_file count=2 openssl dhparam -rand temp_file 512 >> stunnel.pem ln -sf stunnel.pem `openssl x509 -noout -hash < stunnel.pem`.0 rm temp_file

    Please see stunnels documentation if you are not familiar with certificates and private/public keys. Also please protect these keys from outsiders because if cracker can access your private key then SSL tunnel is cracked instantly.

    For now, everyone can actually access your SSL tunnel and everyone can pretend to be your SERVER since stunnel defaults not to check trustworthiness of certificates. To fix this, we need to exchange certificates between SERVER and CLIENT and make stunnel to check certificates. Transfer your CLIENT's certifiacte to SERVER and vice versa. Copy file /etc/stunnel/stunnel.pem to other machine to /etc/stunnel/trusted/filename. Filename should be specifially named, you get correct name using command 'openssl x509 -hash -noout -in /etc/ssl/certs/stunnel.pem' for certificate to be copied. Append '.0' to filename. Ie. filename could be aabbccdd.0. AND OPEN THAT FILE TO EDITOR AND DELETE PRIVATE KEY part from it. You will only need certificate part. Client should not know servers private key and vice versa! It could be wise to first crop private keys off and then transfer... Oh and stunnel can be made to check certificates with verify confiuration option. We use verify = 3 in examples below which is most secure level.

    Then you should create configuration files for stunnel. There is two way's to go, run stunnel from inetd so that it will need not to be always on or you can run stunnel as daemon. I choosed to go inetd way, but there are commented sections for daemon -way. Example configuration for CLIENT (/etc/stunnel/cifsc.conf):

    # Paths cert = /etc/stunnel/stunnel.pem key = /etc/stunnel/stunnel.pem CApath = /etc/stunnel/trusted pid = /var/run/stunnel4/stunnel.pid # Security chroot = /var/chroot/stunnel4 setuid = stunnel4 setgid = stunnel4 verify = 3 # Output debug = 7 output = /var/log/stunnel4/stunnel.log # Services client = yes connect = HERE.SERVERS.IP.ADDRESS:60139 service = stunnel_cifsc # Daemon way # [stunnel_cifsc] # accept = 127.0.0.1:2139 # connect = HERE.SERVERS.IP.ADDRESS:60139

    Then one for SERVER (/etc/stunnel/cifsd.conf):

    # Paths cert = /etc/stunnel/stunnel.pem key = /etc/stunnel/stunnel.pem CApath = /etc/stunnel/trusted pid = /var/run/stunnel4/stunnel.pid # Security chroot = /var/chroot/stunnel4 setuid = stunnel4 setgid = stunnel4 verify = 3 # Output debug = 7 output = /var/log/stunnel4/stunnel.log # Services client = no connect = 127.0.0.1:139 service = stunnel_cifsd # Daemon way # [stunnel_cifsd] # accept = 127.0.0.1:2139 # connect = HERE.SERVERS.IP.ADDRESS:60139

    Depending on your distribution, paths can vary. Please see what directories are created for stunnel when installed. If nothing have been created, you can use my paths. But use always your distribtutions pahts if there are. Also in security -part there are distribution specific configuration settings. Debian GNU/Linux did create new user account, stunnel4, under which will be stunnel is ran. It is not good idea tun run stunnel4 as root so check if your distribution did the same. If not, create new account manually for stunnel4 (and follow security instructions found somewhere else :-)

    Also I have set stunnel to chrooted to /var/chroot/stunnel4. It may be parananoidic, but it's easy so why not. Only drawaback is that when you chroot stunnel, you can't directly call samba in inetd-style but instead you must bind samba to listen some TCP port and connect to it. But then again, if you use own user account for stunnel you must do this in any way so I won't teach you inetd-style. Please see documentation of stunnel for it.

    NOTICE: If you chroot stunnel, you must create CApath and pid -paths in chrooted environment and copy trusted certificates exchanged above to those directories too. Also you must make sure, that trusted certificates are readable by stunnel (ie. chown -R stunnel4:stunnel4 /etc/stunnel/trusted).

    Now try to connect, it should work. If not, please see syslog for details. Check that you exchanged certificates correctly and named files correctly. Remeber to use '-a' argument with stunnel as shown in examples or place certificates to default place stunnel is compiled with (may be ie. /usr/local/etc/ssl...).

    Then we need to configure inetd in SERVER to start stunnel when somebody tries to connect to TCP port 60139. Example addition to inetd.conf:

    60139 stream tcp nowait root /usr/sbin/stunnel4 stunnel /etc/stunnel/cifsd.conf

    And then one for CLIENT:

    2139 stream tcp nowait root /usr/sbin/stunnel4 stunnel /etc/stunnel/cifsc.conf

    NOTICE: you must also edit /etc/hosts_allow accordingly, if you use TCP Wrappers (please see man 5 hosts_access). If you use chrooted environment, you must copy those access -files to chrooted ennvironment too. Personally I like not to use TCP wrappers and use only firewall to restrict access, but it's your choise.

    Then restart inetd in both SERVER and CLIENT and try to telent 127.0.0.1 60139 in server and see what happens. Check /var/log/stunnel4/stunnel.log for debug information. If it seems that stunnel is listening, move to CLIENT and try to telnet 127.0.0.1 2139. You should see in CLIENT's log some action and if everything succeeded, you also should see something to happen in SERVER's log. If EVERYTHING succeeded you also should see some action in samba's logs. In that case, try to access your share from your CLIENT:

    mount -t smbfs -o username=user,password=pass,port=2139 //127.0.0.1/sharename /mnt/sharename

    If not succeeded, please see SERVER's and CLIENT's debug logs to get idea what went wrong. Common pitfall is to use TCP wrappers with stunnel but not add needed line to hosts.allow. In SERVER there should be line 'stunnel:ALL' in /etc/hosts.allow. Also samba must be listning port 139 in SERVER already. You can start samba also from inetd or you can use it standalone - it won't matter. If mounting succeeded then congrats! You can fire up sniffit, read few text files and see how beautiful encrypted data flow is! You can also check that stunnel is really chrooted:

    ps aux locate stunnel from output and check it's pid ls -l /proc/pid/root/ you should only see /etc and /var directories

    Automating this

    Now when you have got everything to work, you probably want everything to be automated. It should be easy, you need to just add mountpoint to /etc/fstab:

    //127.0.0.1/sharename /mnt/sharename smbfs defaults,username=user,password=pass,port=2139,noauto

    Using noauto because automatic mount when booting may not be possible if your netowrk interface has not been yet brung up (ie. my laptops wireless network wil take great ammount of time to wake up) or if you go daemon ay and you stunnel daemon have not been initialized yet. Go inetd -way and see if this is enough without noauto. If not, put mounting command to somewhere in your local commands script.

    CIFS

    When you have succeedd to setup SSL encrypted SMB shares, let's switch to CIFS which supports file permissions etc. It should be easy, just change filesystem type from smbfs to cifs in mounting commands and in fstab. I needed not to do anything else and it worked! If CIFS seems to be valid filesystem but you got no file permissions, it may be that your kernel have CIFS support but without POSIX extensions.

    Remember however that you act under permissions of username specified. Ie. if you mount your share with username foobar, then you are restricted to act as foobar even if you are locally root. Your SERVER sees you as foobar. One could think that using root account for samba would be great way to solve this but don't. If there are remote exploit in samba and you run it as root and everything else goes wrong, cracker could be able to gain root acces to your box. When acting as non-priviledged user, samba drops root priviledges after login.

    Windows

    It is possible that you wan't to use Windows to get grasp of these shares. Stunnel has been ported to Windows so download it. It's tricky to get Windows to play with stunnel since you can't define port for shares in Windows - it's fixed to 139. Also Windows binds port 139 in every network interface with it's services called "computer browser" and "server" so you can't create virtual IP-address for stunnel. You must stop these services and bind stunnel to listen IP-address 127.0.0.2 and re-enable server -service if it's needed (it provides sharing ablity to others). Computer browser seems not to work after starting stunnel :(. Ask Microsoft why you can't define port for shares...

    TODO: more about windows

    Roaming

    TODO: What happens when your IP address changes in fly or network becomes unavailable?

    Benchmarks

    It seems that SSL tunneling will introduce some latency to connections. In example I have media player which clicks every few seconds when playing from tunneled share. Propably it's buffering feature is somehow buggy since data troughput is fast enough.

    TODO: benchmarks with and without ssl encryption

    Routing issues

    If you don't have static IP-addresses in your LAN but insted you get them from our ISP's DHCP-server, then there is great possibility that you get IP-addresses from different subnets for your SERVER and CLIENT. It means that all traffic from your CLIENT to your SERVER goes trough your ISP and it may be very slow depending your net connections speed. This can be solved by using NAT in your LAN. Probably your router (ADSL-box, cable modem etc.) can already do NAT or you can buy separate NAT device your perhaps you can route all your traffic trough your SERVER which does NAT. Other solution is to create alternative private IP-addresses to your CLIENT and SERVER and communicate using those addresses. This, however, requires you to change stunnels IP-address every time you take your laptop from LAN to WAN or vice versa. This could be automated by suitable script.

    If you have NAT, you must create port forward to your SERVER for connections to work. Then you can just enter your public IP address to stunnel and when you are outside your LAN you get forwared to your SERVER and when you are in your LAN, NAT device should still make port forward. Hoewever it seems this won't work always. I have Wireless Access Point Linksys WRT54G (with modified firmware, don't know if it affects) and it is unable to do port forwards when trying to access it's public IP from LAN. Very unlucky. This may be case with other NAT-devices too...

    Final words

    After doing this I have started to think that maybe VPN would be better solution afterall... I mean creating this tunnel took much effort and I could have used that effort for VPN too. It's your choice if you go stunnel or VPN way.

    Also if you can find any errors in this page or come up to mprovements, please conta

    最新回复(0)