Krypterad Filserver med FreeBSD

Här tänkte jag visa lite om hur man sätter upp en krypterad filserver med enkla verktyg som är helt gratis och som alla finns i FreeBSD operativsystemet. Servern ska kunna överföra filer med scp, sftp och vanlig okrypterad ftp, allt detta ska köras i en chrootad miljö på FreeBSD. Detta betyder att alla servertjänster körs som i ett fängelse och kan inte nå resten av systemet. För att avrunda hela vårt krypteringstema så ska vi även köra allt på en krypterad partition med hjälp av GEOM ELI modulen i FreeBSD kärnan.

Konfigurera FreeBSD

Detta är inte så ingående för jag antar de flesta apor med en hjärna klarar av detta. Jag tänkte bara nämna att jag oftast använder Custom valet i menyn för att installera FreeBSD. Sedan brukar jag oftast göra en 250MB stor / partition och stoppa in resten på /usr, /var och /tmp. Ni behöver oftast inte så mycket utrymme för /var eftersom där finns mest loggfiler som roteras regelbundet, jag brukar ge /var 500MB för att vara på säkra sidan men notera att FreeBSD handboken säger 250MB. Bind brukar som standard lagra sina zonfiler på /var partitionen i nyare FreeBSD versioner men det är tveksamt att någon av er som läser den här artikeln har så många zonfiler att detta skulle utgöra ett problem.

I vilket fall som helst så kan det se ut så här när ni är färdiga.

 # df -h
 Filesystem    Size    Used   Avail Capacity  Mounted on
 /dev/da0a     243M     55M    168M    25%    /
 devfs         1.0K    1.0K      0B   100%    /dev
 /dev/da0e     484M    318K    445M     0%    /tmp
 /dev/da0f     6.5G    3.7G    2.3G    62%    /usr
 /dev/da0d     484M     14M    432M     3%    /var

Beroende på hur ni valde att göra så klart.

En annan sak jag ville nämna i den här biten av artikeln är att jag oftast installerar FreeBSD med Custom Distribution där jag för det mesta endast väljer base, kernel, src/sys och man. Detta är allt jag anser att man behöver, jag gör till och med så här på de arbetsstationer jag installerat. Hela den här biten av artikeln var mest för att någon kanske lär sig installera FreeBSD bättre tack vare detta men även för att jag anser att man oftast inte behöver installera mer i ett standardsystem och jag ser ofta servrar med all möjlig onödig skit installerad på dom.

Det var egentligen allt jag hade att säga om installationen, som sagt var detta ingen grundlig genomgång av att installera FreeBSD utan bara lite råd.

Kompilera om FreeBSD med GEOM ELI och Kvota

För att kompilera FreeBSD med GEOM ELI så går vi in i /usr/src/sys katalogen och kompilerar om kärnan med lite extra alternativ. Det kan se ut så här.

 cd /usr/src/sys/`uname -m`/conf
 cp GENERIC server
 vi server

Nu redigerar vi konfigurationsfilen för vår FreeBSD kärna som vi kallar server. Jag gör en kopia av GENERIC kärnan för att det är bekvämt och bra att ha kvar en kopia av originalkärnan lokalt på maskinen. I konfigurationsfilen för kärnan ändrar vi inte mycket, först kan vi ändra ident alternativet ni hittar nära början av filen, detta ska helst vara samma som filnamnet och därför ändrar vi det från GENERIC till server. Det kan se ut ungefär så här.

 # more server
 machine         sparc64
 cpu             SUN4U
 ident           server
 [..]

Det beror på er maskin men ident raden ser likadan ut överallt. Nu går vi till slutet av filen och lägger till följande alternativ.

 # more server
 [..]
 options         QUOTA
 options         GEOM_ELI
 device          crypto

Det första alternativet är används för att aktivera kvota i filsystemet, detta är helt frivilligt men jag tänker gå igenom hur ni aktiverar kvota för en användare så att den användaren inte kan skriva mer än vad ni bestämmer på filsystemet.

Det andra och tredje alternativet aktiverar GEOM_ELI modulen samt crypto modulen, dessa krävs för att kryptera filsystemet.

Ni kompilerar sedan om kärnan.

 config server
 cd ../compile/server
 make make depend;make;make install

Det kan ta lite tid att kompilera och installera kärnan men så fort det är färdigt startar ni om er maskin. Har ni följt mina instruktioner så kommer det inte vara några problem men om kärnan för någon märklig anledning inte vill starta efter ni kompilerat om den så kan ni trycka på en tangent i boot menyn för att få upp kommandoraden. Där skriver ni sedan följande för att starta er gamla kärna som har kopierats och sparats för just en sån här situation.

 boot /boot/kernel.old

Då startas den kärnan ni hade innan ni kompilerade och installerade om er senaste kärna.

Konfigurera GEOM ELI

Nu när vi konfigurerar GEOM ELI har jag bara ett par saker att säga först, jag tänker konfigurera krypteringen så att partitionen måste aktiveras och monteras manuellt. Jag föredrar detta för servrar eftersom man oftast inte har dom hos sig eller har möjlighet att skriva in lösenordet för eli när systemet startar. Det är dock möjligt att aktivera och montera krypterade partitioner både genom att ange lösenordet när systemet startar och genom att inte använda ett lösenord. Jag tycker inte om metoden som inte använder lösenord eftersom det endast krävs att någon får tag på er nyckel för att läsa datan. Vill ni ha mer information om detta så kan ni ta en titt på Referenser.

Det första vi gör är att skapa en nyckel och anger ett lösenord som ska användas varje gång vi ska montera partitionen.

 dd if=/dev/random of=/root/da1d.key bs=64 count=1
 geli init -s 4096 -K /root/da1d.key /dev/da1d

Efter att ni skapat nyckeln och angett lösenordet två gånger så ska ni aktivera geli enheten.

 geli attach -k /root/da1d.key /dev/da1d

Detta gör ni även varje gång ni ska montera enheten. Detta kommandot skapar en ny enhet som i detta fallet heter da1d.eli och ni hittar den i /dev katalogen. Detta är enheten som ni sedan monterar och även kör fsck på för att kontrollera filsystemet. Detta måste göras manuellt ibland.

Nu skapar vi filsystemet på geli enheten.

 dd if=/dev/random of=/dev/da1d.eli bs=1m
 newfs /dev/da1d.eli

Efter detta kan vi montera enheten.

 mount /dev/da1d.eli /home.1

Ni ska nu kunna se den nya geli enheten med df kommandot.

 # df -h
 Filesystem       Size    Used   Avail Capacity  Mounted on
 /dev/da0a        243M     55M    168M    25%    /
 devfs            1.0K    1.0K      0B   100%    /dev
 /dev/da0e        484M    318K    445M     0%    /tmp
 /dev/da0f        6.5G    3.7G    2.3G    62%    /usr
 /dev/da0d        484M     14M    432M     3%    /var
 /dev/da1d.eli    8.3G    8.0K    7.7G     0%    /home.1

Som ni ser så görs alla operationer på .eli enheten, även fsck.

Konfigurera Kvota

För att aktivera kvota när systemet startar lägger vi till följande rader i /etc/rc.conf filen. Observera att den andra raden är helt frivillig, jag har den inte personligen och den anger att kvotan för alla användare inte ska kontrolleras när systemet startar. Detta tar lite tid och kan sakta ner systemets uppstart.

 enable_quotas="YES"
 check_quotas="NO"

Här har vi aktiverat kvota för användare och grupper på /usr, /tmp och /home.1 filsystemen. Ni får aktivera det på de filsystem ni anser behöver kvota. Det viktigaste är vårt /home.1 filsystem som vi ska använda för våra servertjänster. De andra filsystemen är mest exempel på hur det ska se ut.

 # more /etc/fstab
 # Device               Mountpoint      FStype  Options                         Dump    Pass#
 /dev/da0b              none            swap    sw                              0       0
 /dev/da0a              /               ufs     rw                              1       1
 /dev/da0e              /tmp            ufs     rw,userquota,groupquota         2       2
 /dev/da0f              /usr            ufs     rw,userquota,groupquota         2       2
 /dev/da0d              /var            ufs     rw                              2       2
 /dev/ad1d              /home.1         ufs     rw,noauto,userquota,groupquota  2       2
 /dev/cd0               /cdrom          cd9660  ro,noauto                       0       0

Observera alternativet jag aktiverat på vår /home.1 partition, noauto betyder att en inte ska monteras automatiskt av systemet när det startar. Detta är viktigt för oss eftersom vi inte vill behöva skriva in geli lösenordet för den krypterade partitionen varje gång systemet startar. Detta har vi valt att göra efter starten istället. Detta är även varför jag inkluderade alternativet check_quotas och satte det till NO tidigare så att kvota programmen inte flippar ur när de försöker kolla kvota på en partition som inte är monterad. Jag tror nog den bara hoppas över då men det är bra att veta.

Chroot

I hela den här biten av artikeln så använder jag en variabel jag definerat för att slippa skriva sökvägen till mitt planerade fängelse hela tiden. Variabeln heter $JAIL och defineras i tcsh på det här viset.

 setenv JAIL /jail

Den är smidig att använda så definera den gärna när ni börjar följa artikeln och skapa ert eget fängelse.

Chroot är en term som härstammar från UNIX världen och är en funktion som introducerades till BSD genom 4.2BSD systemet. Ni hittar manualen för chroot i del två av FreeBSD manualerna, FreeBSD System Calls Manual.

Nu ska vi konfigurera en chroot-miljö som vi kan kalla för ett feängelse eftersom FreeBSD har en funktion som på engelska heter jails, detta är vad vi ska använda.

Att skapa ett fängelse i FreeBSD är ganska enkelt men att köra program som är beroende av olika bibliotek och katalogstrukturer är lite svårare, det kräver att allt som programmet behöver finns inuti katalogen vi använder som fängelse. Ni måste komma ihåg att programmet inte kommer att kunna gå utanför sitt fängelse.

Det finns många metoder där ute för att bygga ett fängelse och ärligt talat har jag bara hittat en metod som jag tycker om under alla min år med FreeBSD och det är inte metoden som beskrivs i handboken. FreeBSD handboken vill att ni använder deras make system och bygger ett helt FreeBSD system från /usr/src med DESTDIR som ni använder för att bygga hela systemet i en viss katalog. Detta är snabbt, enkelt och kan till och med låta er använda ports inuti ert jail. När jag först skulle bygga ett fängelse hade jag dock inte något behov för att ha ett så stort FreeBSD system i fängelset. Därför gjorde jag det med den metod jag nu ska beskriva. Jag bygger fängelset utifrån vilka program jag ska köra i det, och inget mer. Alltså kopierar jag in allt som OpenSSH behöver i mitt fängelse och kör igång det. Detta betyder en jävla massa skrivande och därför har jag gjort ett script som sköter allt åt er. Först ska vi dock gå igenom allt lite manuellt så att ni lär er vad som pågår.

Det självklara är ju katalogstrukturen i fängelset, den måste stämma överens med systemets katalogstruktur. Vi kan dock ta några genvägar som gör livet enklare för oss, till exempel så måste vi inte kopiera in alla bibliotek i deras motsvarandde sökväg i fängelset. Detta tack vare att program kan söka av alla bibliotekssökvägar när de startar så ett bibliotek som ligger i /usr/lib kan lätt kopieras till /lib i fängelset och fortfarande fungera.

Alla program har ett antal krav på olika bibliotek som de programmerades med, för att ta reda på vilka vi behöver installera i vårt fängelse så kan vi använda strings kommandot.

 # /bin/sh -c 'for i in `strings /usr/sbin/sshd | \
   grep  -E ^lib[^[:space:]]+$`;do find /lib /usr/lib /usr/local/lib -name $i -type f -print;done'
 [..]
 /usr/lib/libasn1.so.8
 /usr/lib/libcom_err.so.3
 /usr/lib/libroken.so.8
 /lib/libcrypto.so.4
 /lib/libcrypt.so.3
 /lib/libc.so.6

För att installera biblioteken kör vi bara -exec install -C {} $JAIL/lib \; istället för -print i find kommandot.

Denna metoden med strings kommandot är bra för vi kan ta reda på vilka bibliotekskrav program som är kompilerade statiskt har. Vi ska dock inte ha några statiskt kompilerade program i vårt fängelse för den här artikeln så vi tar en enklare metod med ldd programmet.

 # ldd /usr/sbin/sshd | awk '/ => / {print $3}' | xargs -J %file install -C %file $JAIL/lib

Nu kräver inte OpenSSH bara bibliotek utan även lite systemenheter som random och null, därför ska vi montera devfs i fängelset. Detta är den katalogstruktur ni oftast hittar i /dev katalogen på ert FreeBSD system. Vi ska dock inte låta internerna i fängelset få tillgång till alla enheter eftersom det kan låta dom fuska sig ut ur fängelset så vi använder fördefinerade devfs regler. I filen /etc/defaults/devfs.rules hittar ni en fördefinerad regel som har nummer 4 och är skapad just för ett fängelse. Den tillåter endast de enheter som interner inte kan använda för att komma ut ur sitt fängelse. Anledningen till varför vi inte bara tar null och random enheterna är att jag planerar lite annat för det här fängelset senare men eftersom denna artikeln handlar om openssh så behöver ni endast alla random enheter och null enheten.

 mount_devfs devfs $JAIL/dev
 devfs -m $JAIL/dev rule -s 4 applyset

Bygga Fängelset

Nu när jag pratat lite om vad som händer så ska vi faktiskt köra scriptet och skapa vårt fängelse. Här har ni scriptet som sköter allt åt er, spara detta med rättigheterna 755 så ni kan exekvera det.

  1. #!/bin/sh
  2.  
  3. JAIL=$1
  4. PROGRAM=$2
  5. MAN="Usage: $0 <directory> [program]"
  6.  
  7. if [ ! $JAIL ]; then
  8. echo "$MAN"
  9. exit
  10. fi
  11.  
  12. #echo "Making jail structure for `basename $PROGRAM` in $JAIL"
  13. `which mkdir` $JAIL
  14. `which mkdir` $JAIL/bin
  15. `which mkdir` $JAIL/lib
  16. `which mkdir` $JAIL/libexec
  17. `which mkdir` $JAIL/etc
  18. `which mkdir` $JAIL/dev
  19. `which mkdir` -p $JAIL/var/empty
  20. `which mkdir` $JAIL/var/run
  21. `which chmod` 555 $JAIL/var/empty
  22. `which chflags` schg $JAIL/var/empty
  23.  
  24. if [ $PROGRAM ]; then
  25. #echo "Installing required libs"
  26. `which ldd` $PROGRAM | `which awk` '/ => / {print $3}' | \
  27. `which xargs` -J %files `which install` -C %files $JAIL/lib
  28.  
  29. #echo "Installing required binary files"
  30. `which install` -C $PROGRAM $JAIL/bin
  31. `which install` -C /libexec/ld-elf.so.* $JAIL/libexec
  32. fi
  33.  
  34. #echo "Mounting devfs in jail"
  35. `which mount_devfs` devfs $JAIL/dev
  36.  
  37. #echo "Applying ruleset to devfs mount"
  38. DEVFS_RULES="hide
  39. path *random* unhide
  40. path null unhide
  41. path zero unhide
  42. path crypto unhide
  43. path 'ptyp*' unhide
  44. path 'ptyq*' unhide
  45. path 'ptyr*' unhide
  46. path 'ptys*' unhide
  47. path 'ptyP*' unhide
  48. path 'ptyQ*' unhide
  49. path 'ptyR*' unhide
  50. path 'ptyS*' unhide
  51. path 'ttyp*' unhide
  52. path 'ttyq*' unhide
  53. path 'ttyr*' unhide
  54. path 'ttys*' unhide
  55. path 'ttyP*' unhide
  56. path 'ttyQ*' unhide
  57. path 'ttyR*' unhide
  58. path 'ttyS*' unhide
  59. path fd unhide
  60. path 'fd/*' unhide
  61. path stdin unhide
  62. path stdout unhide
  63. path stderr unhide"
  64. echo $DEVFS_RULES | `which devfs` -m $JAIL/dev rule apply -
  65.  
  66. #echo "Creating user database"
  67. `which install` -C `which nologin` $JAIL/bin
  68. echo 'root:*:0:0::0:0:Charlie &:/var/empty:/bin/nologin' > $JAIL/etc/master.passwd
  69. `which pwd_mkdb` -p -d $JAIL/etc $JAIL/etc/master.passwd
  70.  
  71. cd $JAIL/var
  72. ln -s ../tmp tmp

Ni kör scriptet på kommandoraden som root.

 chmod +x makejail.sh
 ./makejail.sh /jail /usr/sbin/sshd

Får ni felmeddelanden eller för någon anledning skulle vilja börja om så får ni inte glöma att $JAIL/var/empty har ch-flaggan schg så att root inte kan ta bort filen, därför måste ni köra följande kommando för att kunna ta bort empty katalogen.

 chflags noschg $JAIL/var/empty

Konfigurera OpenSSH

Scriptet gör inte allt åt er så nu måste ni kopiera konfigurationsfilerna för OpenSSH och redigera dom lite.

 cp -rp /etc/ssh $JAIL/etc/
 vi $JAIL/etc/ssh/sshd_config

Vad ni har i sshd_config filen är upp till er och era behov men följande inställningar bör ni ändra.

 PasswordAuthentication no
 ChallengeResponseAuthentication no 
 UsePAM no 
 AllowTcpForwarding no 
 X11Forwarding no 
 PrintMotd yes
 PrintLastLog no
 Subsystem sftp /libexec/sftp-server

Ska ni endast använda sftp så rekommenderar jag att stänga av motd, banner och lastlog eftersom dessa kan göra sftp förvirrad när de skriver ut text. När ni är färdiga är det dags att skapa nycklar för ssh. Glöm inte att ändra sökvägen till sftp eftersom vi endast har /libexec i fängelset.

 ssh-keygen -N '' -t dsa -f $JAIL/etc/ssh/ssh_host_dsa_key
 ssh-keygen -N '' -t rsa -f $JAIL/etc/ssh/ssh_host_rsa_key

Glöm inte att kopiera in sftp-server filen i ert fängelse också.

 install -C /usr/libexec/sftp-server $JAIL/libexec

Till sist ska vi lägga till ssh användaren och en användare vi kan logga in med i användardatabasen för vårt fängelse. Det första vi behöver är ett lösenord eftersom vi ska lägga till användaren med vipw verktyget, vi använder openssl för att skapa lösenordet.

 openssl passwd -l 12345
 vipw -d $JAIL/etc

Nu lägger vi in två rader i användardatabasen, den första är sshd användaren som behövs av OpenSSH och den andra är vår användare som vi senare ska kunna logga in med. För att lägga till fler användare så upprepar ni bara det här steget.

 sshd:*:22:22::0:0:Secure Shell Daemon:/var/empty:/bin/nologin
 swehack:$1$ZpRDR9S/$XVy4ilWzde1sQs/JMHiPs.:1001:1001::0:0:User &:/usr/home/swehack:/libexec/sftp-server

Den sista raden för användaren kan ni ändra så den passar er, jag har valt att lägga användarnas kataloger i /usr och gett använddaren sftp-server som skal.

Nu skapar vi bara användarens katalog så ska vi snart starta OpenSSH i vårt vängelse.

 mkdir -p $JAIL/usr/home/swehack

Starta OpenSSH

Innan vi startar vårt fängelse med jail kommandot så behöver vi en ip-adress att binda fängelset till. Denna ip-adressen måste vara ett alias på ert system.

 ifconfig hme0 inet 192.168.0.101 netmask 255.255.255.255 alias

Ni startar OpenSSH med jail kommandot så här.

 jail $JAIL war.swehack.se 192.168.0.101 /bin/sshd -4

Som ni ser så måste ni ange ett hostnamn för ert fängelse.

Nu är det alltså färdigt och ni kan börja sätta rättigheter i ert fängelse. Skapa lite kataloger och sätt ägare på katalogerna så ni kan använda kvotan. Saknar ni något i den här artikeln så kan ni alltid kontakta mig via http://swehack.se/ webbsidan.